Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" | 5 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/debug/trace_event.h" | |
| 9 #include "base/location.h" | 10 #include "base/location.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "base/threading/thread_checker.h" | |
| 11 #include "content/renderer/media/native_handle_impl.h" | 13 #include "content/renderer/media/native_handle_impl.h" |
| 12 #include "media/base/bind_to_current_loop.h" | 14 #include "media/base/bind_to_current_loop.h" |
| 13 #include "media/base/video_frame.h" | 15 #include "media/base/video_frame.h" |
| 14 #include "media/base/video_frame_pool.h" | 16 #include "media/base/video_frame_pool.h" |
| 15 #include "media/base/video_util.h" | 17 #include "media/base/video_util.h" |
| 16 #include "third_party/libjingle/source/talk/media/base/videoframe.h" | 18 #include "third_party/libjingle/source/talk/media/base/videoframe.h" |
| 17 | 19 |
| 18 namespace content { | 20 namespace content { |
| 19 | 21 |
| 20 // Internal class used for receiving frames from the webrtc track on a | 22 // Internal class used for receiving frames from the webrtc track on a |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 RemoteVideoSourceDelegate::~RemoteVideoSourceDelegate() { | 66 RemoteVideoSourceDelegate::~RemoteVideoSourceDelegate() { |
| 65 } | 67 } |
| 66 | 68 |
| 67 void MediaStreamRemoteVideoSource:: | 69 void MediaStreamRemoteVideoSource:: |
| 68 RemoteVideoSourceDelegate::SetSize(int width, int height) { | 70 RemoteVideoSourceDelegate::SetSize(int width, int height) { |
| 69 } | 71 } |
| 70 | 72 |
| 71 void MediaStreamRemoteVideoSource:: | 73 void MediaStreamRemoteVideoSource:: |
| 72 RemoteVideoSourceDelegate::RenderFrame( | 74 RemoteVideoSourceDelegate::RenderFrame( |
| 73 const cricket::VideoFrame* frame) { | 75 const cricket::VideoFrame* frame) { |
| 76 TRACE_EVENT0("webrtc", "RemoteVideoSourceDelegate::RenderFrame"); | |
| 74 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( | 77 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( |
| 75 frame->GetElapsedTime() / rtc::kNumNanosecsPerMicrosec); | 78 frame->GetElapsedTime() / rtc::kNumNanosecsPerMicrosec); |
| 76 | 79 |
| 77 scoped_refptr<media::VideoFrame> video_frame; | 80 scoped_refptr<media::VideoFrame> video_frame; |
| 78 if (frame->GetNativeHandle() != NULL) { | 81 if (frame->GetNativeHandle() != NULL) { |
| 79 NativeHandleImpl* handle = | 82 NativeHandleImpl* handle = |
| 80 static_cast<NativeHandleImpl*>(frame->GetNativeHandle()); | 83 static_cast<NativeHandleImpl*>(frame->GetNativeHandle()); |
| 81 video_frame = static_cast<media::VideoFrame*>(handle->GetHandle()); | 84 video_frame = static_cast<media::VideoFrame*>(handle->GetHandle()); |
| 82 video_frame->set_timestamp(timestamp); | 85 video_frame->set_timestamp(timestamp); |
| 83 } else { | 86 } else { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 113 FROM_HERE, | 116 FROM_HERE, |
| 114 base::Bind(&RemoteVideoSourceDelegate::DoRenderFrameOnIOThread, | 117 base::Bind(&RemoteVideoSourceDelegate::DoRenderFrameOnIOThread, |
| 115 this, video_frame, format)); | 118 this, video_frame, format)); |
| 116 } | 119 } |
| 117 | 120 |
| 118 void MediaStreamRemoteVideoSource:: | 121 void MediaStreamRemoteVideoSource:: |
| 119 RemoteVideoSourceDelegate::DoRenderFrameOnIOThread( | 122 RemoteVideoSourceDelegate::DoRenderFrameOnIOThread( |
| 120 scoped_refptr<media::VideoFrame> video_frame, | 123 scoped_refptr<media::VideoFrame> video_frame, |
| 121 const media::VideoCaptureFormat& format) { | 124 const media::VideoCaptureFormat& format) { |
| 122 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 125 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 126 TRACE_EVENT0("webrtc", "RemoteVideoSourceDelegate::DoRenderFrameOnIOThread"); | |
| 123 // TODO(hclam): Give the estimated capture time. | 127 // TODO(hclam): Give the estimated capture time. |
| 124 frame_callback_.Run(video_frame, format, base::TimeTicks()); | 128 frame_callback_.Run(video_frame, format, base::TimeTicks()); |
| 125 } | 129 } |
| 126 | 130 |
| 131 MediaStreamRemoteVideoSource::Observer::Observer( | |
|
perkj_chrome
2014/10/30 12:42:36
I think we should try to create this object on the
tommi (sloooow) - chröme
2014/10/30 20:37:36
Discussed offline
| |
| 132 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 133 webrtc::VideoTrackInterface* track) | |
| 134 : main_thread_(main_thread), track_(track), state_(track->state()) { | |
| 135 track->RegisterObserver(this); | |
| 136 } | |
| 137 | |
| 138 const scoped_refptr<webrtc::VideoTrackInterface>& | |
| 139 MediaStreamRemoteVideoSource::Observer::track() { | |
| 140 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 141 return track_; | |
| 142 } | |
| 143 | |
| 144 webrtc::MediaStreamTrackInterface::TrackState | |
| 145 MediaStreamRemoteVideoSource::Observer::state() const { | |
| 146 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 147 return state_; | |
| 148 } | |
| 149 | |
| 150 MediaStreamRemoteVideoSource::Observer::~Observer() { | |
| 151 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 152 track_->UnregisterObserver(this); | |
| 153 } | |
| 154 | |
| 155 void MediaStreamRemoteVideoSource::Observer::SetSource( | |
| 156 const base::WeakPtr<MediaStreamRemoteVideoSource>& source) { | |
| 157 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 158 DCHECK(!source_); | |
| 159 source_ = source; | |
| 160 } | |
| 161 | |
| 162 void MediaStreamRemoteVideoSource::Observer::OnChanged() { | |
| 163 webrtc::MediaStreamTrackInterface::TrackState state = track_->state(); | |
| 164 main_thread_->PostTask(FROM_HERE, | |
| 165 base::Bind(&MediaStreamRemoteVideoSource::Observer::OnChangedImpl, | |
| 166 this, state)); | |
| 167 } | |
| 168 | |
| 169 void MediaStreamRemoteVideoSource::Observer::OnChangedImpl( | |
| 170 webrtc::MediaStreamTrackInterface::TrackState state) { | |
| 171 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 172 DLOG_IF(ERROR, !source_) << "Dropping a state change event. " << state; | |
|
perkj_chrome
2014/10/30 12:42:35
Can this happen before |source_| have been set?
tommi (sloooow) - chröme
2014/10/30 20:37:36
Only if a unittest is doing something funky. Chan
| |
| 173 if (source_ && state != state_) | |
| 174 source_->OnChanged(state); | |
| 175 state_ = state; | |
| 176 } | |
| 177 | |
| 127 MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource( | 178 MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource( |
| 128 webrtc::VideoTrackInterface* remote_track) | 179 const scoped_refptr<MediaStreamRemoteVideoSource::Observer>& observer) |
| 129 : remote_track_(remote_track), | 180 : observer_(observer), weak_factory_(this) { |
| 130 last_state_(remote_track->state()) { | 181 observer->SetSource(weak_factory_.GetWeakPtr()); |
| 131 remote_track_->RegisterObserver(this); | |
| 132 } | 182 } |
| 133 | 183 |
| 134 MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() { | 184 MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() { |
| 135 remote_track_->UnregisterObserver(this); | 185 DCHECK(CalledOnValidThread()); |
| 136 } | 186 } |
| 137 | 187 |
| 138 void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats( | 188 void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats( |
| 139 int max_requested_width, | 189 int max_requested_width, |
| 140 int max_requested_height, | 190 int max_requested_height, |
| 141 double max_requested_frame_rate, | 191 double max_requested_frame_rate, |
| 142 const VideoCaptureDeviceFormatsCB& callback) { | 192 const VideoCaptureDeviceFormatsCB& callback) { |
| 143 DCHECK(thread_checker_.CalledOnValidThread()); | 193 DCHECK(CalledOnValidThread()); |
| 144 media::VideoCaptureFormats formats; | 194 media::VideoCaptureFormats formats; |
| 145 // Since the remote end is free to change the resolution at any point in time | 195 // Since the remote end is free to change the resolution at any point in time |
| 146 // the supported formats are unknown. | 196 // the supported formats are unknown. |
| 147 callback.Run(formats); | 197 callback.Run(formats); |
| 148 } | 198 } |
| 149 | 199 |
| 150 void MediaStreamRemoteVideoSource::StartSourceImpl( | 200 void MediaStreamRemoteVideoSource::StartSourceImpl( |
| 151 const media::VideoCaptureFormat& format, | 201 const media::VideoCaptureFormat& format, |
| 152 const VideoCaptureDeliverFrameCB& frame_callback) { | 202 const VideoCaptureDeliverFrameCB& frame_callback) { |
| 153 DCHECK(thread_checker_.CalledOnValidThread()); | 203 DCHECK(CalledOnValidThread()); |
| 154 DCHECK(!delegate_.get()); | 204 DCHECK(!delegate_.get()); |
| 155 delegate_ = new RemoteVideoSourceDelegate(io_message_loop(), frame_callback); | 205 delegate_ = new RemoteVideoSourceDelegate(io_message_loop(), frame_callback); |
| 156 remote_track_->AddRenderer(delegate_.get()); | 206 observer_->track()->AddRenderer(delegate_.get()); |
| 157 OnStartDone(MEDIA_DEVICE_OK); | 207 OnStartDone(MEDIA_DEVICE_OK); |
| 158 } | 208 } |
| 159 | 209 |
| 160 void MediaStreamRemoteVideoSource::StopSourceImpl() { | 210 void MediaStreamRemoteVideoSource::StopSourceImpl() { |
| 161 DCHECK(thread_checker_.CalledOnValidThread()); | 211 DCHECK(CalledOnValidThread()); |
| 162 DCHECK(state() != MediaStreamVideoSource::ENDED); | 212 DCHECK(state() != MediaStreamVideoSource::ENDED); |
| 163 remote_track_->RemoveRenderer(delegate_.get()); | 213 observer_->track()->RemoveRenderer(delegate_.get()); |
| 164 } | 214 } |
| 165 | 215 |
| 166 webrtc::VideoRendererInterface* | 216 webrtc::VideoRendererInterface* |
| 167 MediaStreamRemoteVideoSource::RenderInterfaceForTest() { | 217 MediaStreamRemoteVideoSource::RenderInterfaceForTest() { |
| 168 return delegate_.get(); | 218 return delegate_.get(); |
| 169 } | 219 } |
| 170 | 220 |
| 171 void MediaStreamRemoteVideoSource::OnChanged() { | 221 void MediaStreamRemoteVideoSource::OnChanged( |
| 172 DCHECK(thread_checker_.CalledOnValidThread()); | 222 webrtc::MediaStreamTrackInterface::TrackState state) { |
| 173 webrtc::MediaStreamTrackInterface::TrackState state = remote_track_->state(); | 223 DCHECK(CalledOnValidThread()); |
| 174 if (state != last_state_) { | 224 switch (state) { |
| 175 last_state_ = state; | 225 case webrtc::MediaStreamTrackInterface::kInitializing: |
| 176 switch (state) { | 226 // Ignore the kInitializing state since there is no match in |
| 177 case webrtc::MediaStreamTrackInterface::kInitializing: | 227 // WebMediaStreamSource::ReadyState. |
| 178 // Ignore the kInitializing state since there is no match in | 228 break; |
| 179 // WebMediaStreamSource::ReadyState. | 229 case webrtc::MediaStreamTrackInterface::kLive: |
| 180 break; | 230 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); |
| 181 case webrtc::MediaStreamTrackInterface::kLive: | 231 break; |
| 182 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); | 232 case webrtc::MediaStreamTrackInterface::kEnded: |
| 183 break; | 233 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); |
| 184 case webrtc::MediaStreamTrackInterface::kEnded: | 234 break; |
| 185 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 235 default: |
| 186 break; | 236 NOTREACHED(); |
| 187 default: | 237 break; |
| 188 NOTREACHED(); | |
| 189 break; | |
| 190 } | |
| 191 } | 238 } |
| 192 } | 239 } |
| 193 | 240 |
| 194 } // namespace content | 241 } // namespace content |
| OLD | NEW |