Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc

Issue 2585313002: Propagate MediaStreamTrack video content hints. (Closed)
Patch Set: add tests + fix compile Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_video_webrtc_sink.h" 5 #include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/numerics/safe_conversions.h" 8 #include "base/numerics/safe_conversions.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 // The default number of microseconds that should elapse since the last video 53 // The default number of microseconds that should elapse since the last video
54 // frame was received, before requesting a refresh frame. 54 // frame was received, before requesting a refresh frame.
55 const int64_t kDefaultRefreshIntervalMicros = 55 const int64_t kDefaultRefreshIntervalMicros =
56 base::Time::kMicrosecondsPerSecond; 56 base::Time::kMicrosecondsPerSecond;
57 57
58 // A lower-bound for the refresh interval. 58 // A lower-bound for the refresh interval.
59 const int64_t kLowerBoundRefreshIntervalMicros = 59 const int64_t kLowerBoundRefreshIntervalMicros =
60 base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond; 60 base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond;
61 61
62 webrtc::VideoTrackInterface::ContentHint TranslateContentHint(
63 blink::WebMediaStreamTrack::ContentHintType content_hint) {
64 switch (content_hint) {
65 case blink::WebMediaStreamTrack::ContentHintType::None:
66 return webrtc::VideoTrackInterface::ContentHint::kNone;
67 case blink::WebMediaStreamTrack::ContentHintType::AudioSpeech:
68 case blink::WebMediaStreamTrack::ContentHintType::AudioMusic:
69 NOTREACHED();
mcasas 2016/12/19 19:32:05 Why are these hints causing a NOTREACHED() ? IOW w
pbos 2016/12/19 19:42:09 They should never be settable on a video track. Th
70 break;
71 case blink::WebMediaStreamTrack::ContentHintType::VideoFluid:
72 return webrtc::VideoTrackInterface::ContentHint::kFluid;
73 case blink::WebMediaStreamTrack::ContentHintType::VideoDetailed:
74 return webrtc::VideoTrackInterface::ContentHint::kDetailed;
75 }
76 NOTREACHED();
77 return webrtc::VideoTrackInterface::ContentHint::kNone;
78 }
79
62 } // namespace 80 } // namespace
63 81
64 // Simple help class used for receiving video frames on the IO-thread from a 82 // Simple help class used for receiving video frames on the IO-thread from a
65 // MediaStreamVideoTrack and forward the frames to a WebRtcVideoCapturerAdapter 83 // MediaStreamVideoTrack and forward the frames to a WebRtcVideoCapturerAdapter
66 // on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video 84 // on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video
67 // capturer for libjingle. 85 // capturer for libjingle.
68 class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter 86 class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter
69 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { 87 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
70 public: 88 public:
71 WebRtcVideoSourceAdapter(const scoped_refptr<base::SingleThreadTaskRunner>& 89 WebRtcVideoSourceAdapter(const scoped_refptr<base::SingleThreadTaskRunner>&
72 libjingle_worker_thread, 90 libjingle_worker_thread,
73 const scoped_refptr<WebRtcVideoSource>& source, 91 const scoped_refptr<WebRtcVideoSource>& source,
74 base::TimeDelta refresh_interval, 92 base::TimeDelta refresh_interval,
75 const base::Closure& refresh_callback); 93 const base::Closure& refresh_callback);
76 94
77 // MediaStreamVideoWebRtcSink can be destroyed on the main render thread or 95 // MediaStreamVideoWebRtcSink can be destroyed on the main render thread or
78 // libjingles worker thread since it posts video frames on that thread. But 96 // libjingles worker thread since it posts video frames on that thread. But
79 // |video_source_| must be released on the main render thread before the 97 // |video_source_| must be released on the main render thread before the
80 // PeerConnectionFactory has been destroyed. The only way to ensure that is to 98 // PeerConnectionFactory has been destroyed. The only way to ensure that is to
81 // make sure |video_source_| is released when MediaStreamVideoWebRtcSink() is 99 // make sure |video_source_| is released when MediaStreamVideoWebRtcSink() is
82 // destroyed. 100 // destroyed.
83 void ReleaseSourceOnMainThread(); 101 void ReleaseSourceOnMainThread();
84 102
103 void SetContentHint(blink::WebMediaStreamTrack::ContentHintType content_hint);
104
85 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 105 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
86 base::TimeTicks estimated_capture_time); 106 base::TimeTicks estimated_capture_time);
87 107
88 private: 108 private:
109 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
110
89 void OnVideoFrameOnWorkerThread( 111 void OnVideoFrameOnWorkerThread(
90 const scoped_refptr<media::VideoFrame>& frame); 112 const scoped_refptr<media::VideoFrame>& frame);
91 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; 113
114 void SetContentHintOnWorkerThread(
115 blink::WebMediaStreamTrack::ContentHintType content_hint);
116
92 virtual ~WebRtcVideoSourceAdapter(); 117 virtual ~WebRtcVideoSourceAdapter();
93 118
94 // Called whenever a video frame was just delivered on the IO thread. This 119 // Called whenever a video frame was just delivered on the IO thread. This
95 // restarts the delay period before the |refresh_timer_| will fire the next 120 // restarts the delay period before the |refresh_timer_| will fire the next
96 // time. 121 // time.
97 void ResetRefreshTimerOnMainThread(); 122 void ResetRefreshTimerOnMainThread();
98 123
99 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; 124 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_;
100 125
101 // |render_thread_checker_| is bound to the main render thread. 126 // |render_thread_checker_| is bound to the main render thread.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 DVLOG(3) << "~WebRtcVideoSourceAdapter()"; 179 DVLOG(3) << "~WebRtcVideoSourceAdapter()";
155 DCHECK(!capture_adapter_); 180 DCHECK(!capture_adapter_);
156 // This object can be destroyed on the main render thread or libjingles worker 181 // This object can be destroyed on the main render thread or libjingles worker
157 // thread since it posts video frames on that thread. But |video_source_| must 182 // thread since it posts video frames on that thread. But |video_source_| must
158 // be released on the main render thread before the PeerConnectionFactory has 183 // be released on the main render thread before the PeerConnectionFactory has
159 // been destroyed. The only way to ensure that is to make sure |video_source_| 184 // been destroyed. The only way to ensure that is to make sure |video_source_|
160 // is released when MediaStreamVideoWebRtcSink() is destroyed. 185 // is released when MediaStreamVideoWebRtcSink() is destroyed.
161 } 186 }
162 187
163 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: 188 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
164 ResetRefreshTimerOnMainThread() { 189 ResetRefreshTimerOnMainThread() {
165 DCHECK(render_thread_checker_.CalledOnValidThread()); 190 DCHECK(render_thread_checker_.CalledOnValidThread());
166 if (refresh_timer_.IsRunning()) 191 if (refresh_timer_.IsRunning())
167 refresh_timer_.Reset(); 192 refresh_timer_.Reset();
168 } 193 }
169 194
170 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: 195 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
171 ReleaseSourceOnMainThread() { 196 ReleaseSourceOnMainThread() {
172 DCHECK(render_thread_checker_.CalledOnValidThread()); 197 DCHECK(render_thread_checker_.CalledOnValidThread());
173 // Since frames are posted to the worker thread, this object might be deleted 198 // Since frames are posted to the worker thread, this object might be deleted
174 // on that thread. However, since |video_source_| was created on the render 199 // on that thread. However, since |video_source_| was created on the render
175 // thread, it should be released on the render thread. 200 // thread, it should be released on the render thread.
176 base::AutoLock auto_lock(capture_adapter_stop_lock_); 201 base::AutoLock auto_lock(capture_adapter_stop_lock_);
177 // |video_source| owns |capture_adapter_|. 202 // |video_source| owns |capture_adapter_|.
178 capture_adapter_ = NULL; 203 capture_adapter_ = NULL;
179 video_source_ = NULL; 204 video_source_ = NULL;
180 } 205 }
181 206
207 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::SetContentHint(
208 blink::WebMediaStreamTrack::ContentHintType content_hint) {
209 DCHECK(render_thread_checker_.CalledOnValidThread());
210 libjingle_worker_thread_->PostTask(
211 FROM_HERE,
212 base::Bind(&WebRtcVideoSourceAdapter::SetContentHintOnWorkerThread, this,
213 content_hint));
214 }
215
216 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
217 SetContentHintOnWorkerThread(
218 blink::WebMediaStreamTrack::ContentHintType content_hint) {
219 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
220 base::AutoLock auto_lock(capture_adapter_stop_lock_);
221 if (capture_adapter_)
222 capture_adapter_->SetContentHint(content_hint);
223 }
224
182 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( 225 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
183 const scoped_refptr<media::VideoFrame>& frame, 226 const scoped_refptr<media::VideoFrame>& frame,
184 base::TimeTicks estimated_capture_time) { 227 base::TimeTicks estimated_capture_time) {
185 DCHECK(io_thread_checker_.CalledOnValidThread()); 228 DCHECK(io_thread_checker_.CalledOnValidThread());
186 render_thread_task_runner_->PostTask( 229 render_thread_task_runner_->PostTask(
187 FROM_HERE, 230 FROM_HERE,
188 base::Bind(&WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread, 231 base::Bind(&WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread,
189 this)); 232 this));
190 libjingle_worker_thread_->PostTask( 233 libjingle_worker_thread_->PostTask(
191 FROM_HERE, 234 FROM_HERE,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) { 303 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) {
261 refresh_interval = 304 refresh_interval =
262 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros); 305 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros);
263 } 306 }
264 } 307 }
265 308
266 // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource 309 // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource
267 // by removing the need for and dependency on a cricket::VideoCapturer. 310 // by removing the need for and dependency on a cricket::VideoCapturer.
268 video_source_ = scoped_refptr<WebRtcVideoSource>( 311 video_source_ = scoped_refptr<WebRtcVideoSource>(
269 new rtc::RefCountedObject<WebRtcVideoSource>( 312 new rtc::RefCountedObject<WebRtcVideoSource>(
270 new WebRtcVideoCapturerAdapter(is_screencast), is_screencast, 313 new WebRtcVideoCapturerAdapter(is_screencast, track.contentHint()),
271 needs_denoising)); 314 is_screencast, needs_denoising));
272 315
273 // TODO(pbos): Consolidate the local video track with the source proxy and 316 // TODO(pbos): Consolidate the local video track with the source proxy and
274 // move into PeerConnectionDependencyFactory. This now separately holds on a 317 // move into PeerConnectionDependencyFactory. This now separately holds on a
275 // reference to the proxy object because 318 // reference to the proxy object because
276 // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting. 319 // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting.
277 video_source_proxy_ = 320 video_source_proxy_ =
278 factory->CreateVideoTrackSourceProxy(video_source_.get()); 321 factory->CreateVideoTrackSourceProxy(video_source_.get());
279 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(), 322 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(),
280 video_source_proxy_.get()); 323 video_source_proxy_.get());
281 324
325 video_track_->set_content_hint(TranslateContentHint(track.contentHint()));
mcasas 2016/12/19 19:32:05 Isn't this repeating what's done in l.313?
pbos 2016/12/19 19:42:09 Nope, l.313 is for the adapter.
282 video_track_->set_enabled(track.isEnabled()); 326 video_track_->set_enabled(track.isEnabled());
283 327
284 source_adapter_ = new WebRtcVideoSourceAdapter( 328 source_adapter_ = new WebRtcVideoSourceAdapter(
285 factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval, 329 factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval,
286 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame, 330 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
287 weak_factory_.GetWeakPtr())); 331 weak_factory_.GetWeakPtr()));
288 332
289 MediaStreamVideoSink::ConnectToTrack( 333 MediaStreamVideoSink::ConnectToTrack(
290 track, 334 track,
291 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_), 335 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_),
292 false); 336 false);
293 337
294 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast " 338 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast "
295 << is_screencast; 339 << is_screencast;
296 } 340 }
297 341
298 MediaStreamVideoWebRtcSink::~MediaStreamVideoWebRtcSink() { 342 MediaStreamVideoWebRtcSink::~MediaStreamVideoWebRtcSink() {
299 DCHECK(thread_checker_.CalledOnValidThread()); 343 DCHECK(thread_checker_.CalledOnValidThread());
300 DVLOG(3) << "MediaStreamVideoWebRtcSink dtor()."; 344 DVLOG(3) << "MediaStreamVideoWebRtcSink dtor().";
301 weak_factory_.InvalidateWeakPtrs(); 345 weak_factory_.InvalidateWeakPtrs();
302 MediaStreamVideoSink::DisconnectFromTrack(); 346 MediaStreamVideoSink::DisconnectFromTrack();
303 source_adapter_->ReleaseSourceOnMainThread(); 347 source_adapter_->ReleaseSourceOnMainThread();
304 } 348 }
305 349
306 void MediaStreamVideoWebRtcSink::OnEnabledChanged(bool enabled) { 350 void MediaStreamVideoWebRtcSink::OnEnabledChanged(bool enabled) {
307 DCHECK(thread_checker_.CalledOnValidThread()); 351 DCHECK(thread_checker_.CalledOnValidThread());
308 video_track_->set_enabled(enabled); 352 video_track_->set_enabled(enabled);
309 } 353 }
310 354
355 void MediaStreamVideoWebRtcSink::OnContentHintChanged(
356 blink::WebMediaStreamTrack::ContentHintType content_hint) {
357 DCHECK(thread_checker_.CalledOnValidThread());
358 source_adapter_->SetContentHint(content_hint);
mcasas 2016/12/19 19:32:05 IIUC,WebRtcVideoCapturerAdapter::SetContentHint()
pbos 2016/12/19 19:42:09 We are on the renderer (signalling) thread here. S
359 video_track_->set_content_hint(TranslateContentHint(content_hint));
360 }
361
311 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() { 362 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
312 DCHECK(thread_checker_.CalledOnValidThread()); 363 DCHECK(thread_checker_.CalledOnValidThread());
313 content::RequestRefreshFrameFromVideoTrack(connected_track()); 364 content::RequestRefreshFrameFromVideoTrack(connected_track());
314 } 365 }
315 366
316 rtc::Optional<bool> MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting() 367 rtc::Optional<bool> MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting()
317 const { 368 const {
318 return video_source_->needs_denoising(); 369 return video_source_->needs_denoising();
319 } 370 }
320 371
321 } // namespace content 372 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698