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 |