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

Side by Side Diff: content/renderer/media/video_track_adapter.cc

Issue 366243003: VideoTrackAdapter: Add passing frames monitor, notify MSVCS -> MSVTrack(s) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Correct handling of 0.0fps frame rate sources Created 6 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/video_track_adapter.h" 5 #include "content/renderer/media/video_track_adapter.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "media/base/video_util.h" 14 #include "media/base/video_util.h"
15 15
16 namespace content { 16 namespace content {
17 17
18 namespace { 18 namespace {
19 19
20 // Amount of frame intervals to wait before considering the source as muted, for
21 // the first frame and under normal conditions, respectively. First frame might
22 // take longer to arrive due to source startup.
23 const float kFirstFrameTimeoutInFrameIntervals = 100.0f;
24 const float kNormalFrameTimeoutInFrameIntervals = 25.0f;
25
20 // Empty method used for keeping a reference to the original media::VideoFrame 26 // Empty method used for keeping a reference to the original media::VideoFrame
21 // in VideoFrameResolutionAdapter::DeliverFrame if cropping is needed. 27 // in VideoFrameResolutionAdapter::DeliverFrame if cropping is needed.
22 // The reference to |frame| is kept in the closure that calls this method. 28 // The reference to |frame| is kept in the closure that calls this method.
23 void ReleaseOriginalFrame( 29 void ReleaseOriginalFrame(
24 const scoped_refptr<media::VideoFrame>& frame) { 30 const scoped_refptr<media::VideoFrame>& frame) {
25 } 31 }
26 32
27 void ResetCallbackOnMainRenderThread( 33 void ResetCallbackOnMainRenderThread(
28 scoped_ptr<VideoCaptureDeliverFrameCB> callback) { 34 scoped_ptr<VideoCaptureDeliverFrameCB> callback) {
29 // |callback| will be deleted when this exits. 35 // |callback| will be deleted when this exits.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } 300 }
295 301
296 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const { 302 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const {
297 DCHECK(io_thread_checker_.CalledOnValidThread()); 303 DCHECK(io_thread_checker_.CalledOnValidThread());
298 return callbacks_.empty(); 304 return callbacks_.empty();
299 } 305 }
300 306
301 VideoTrackAdapter::VideoTrackAdapter( 307 VideoTrackAdapter::VideoTrackAdapter(
302 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) 308 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
303 : io_message_loop_(io_message_loop), 309 : io_message_loop_(io_message_loop),
304 renderer_task_runner_(base::MessageLoopProxy::current()) { 310 renderer_task_runner_(base::MessageLoopProxy::current()),
311 frame_counter_(0),
312 source_frame_rate_(0.0f) {
305 DCHECK(io_message_loop_); 313 DCHECK(io_message_loop_);
306 } 314 }
307 315
308 VideoTrackAdapter::~VideoTrackAdapter() { 316 VideoTrackAdapter::~VideoTrackAdapter() {
309 DCHECK(adapters_.empty()); 317 DCHECK(adapters_.empty());
310 } 318 }
311 319
312 void VideoTrackAdapter::AddTrack(const MediaStreamVideoTrack* track, 320 void VideoTrackAdapter::AddTrack(
313 VideoCaptureDeliverFrameCB frame_callback, 321 const MediaStreamVideoTrack* track,
314 int max_width, 322 VideoCaptureDeliverFrameCB frame_callback,
315 int max_height, 323 int max_width,
316 double min_aspect_ratio, 324 int max_height,
317 double max_aspect_ratio, 325 double min_aspect_ratio,
318 double max_frame_rate) { 326 double max_aspect_ratio,
327 double max_frame_rate,
328 double source_frame_rate,
329 const OnMutedCallback& on_muted_state_callback) {
319 DCHECK(thread_checker_.CalledOnValidThread()); 330 DCHECK(thread_checker_.CalledOnValidThread());
331 // Track monitoring should be scheduled before AddTrackOnIO() so it can find
332 // |adapters_| empty.
333 io_message_loop_->PostTask(
334 FROM_HERE,
335 base::Bind(&VideoTrackAdapter::StartTrackMonitoringOnIO,
336 this, on_muted_state_callback, source_frame_rate));
320 io_message_loop_->PostTask( 337 io_message_loop_->PostTask(
321 FROM_HERE, 338 FROM_HERE,
322 base::Bind(&VideoTrackAdapter::AddTrackOnIO, 339 base::Bind(&VideoTrackAdapter::AddTrackOnIO,
323 this, track, frame_callback, gfx::Size(max_width, max_height), 340 this, track, frame_callback, gfx::Size(max_width, max_height),
324 min_aspect_ratio, max_aspect_ratio, max_frame_rate)); 341 min_aspect_ratio, max_aspect_ratio, max_frame_rate));
325 } 342 }
326 343
327 void VideoTrackAdapter::AddTrackOnIO( 344 void VideoTrackAdapter::AddTrackOnIO(
328 const MediaStreamVideoTrack* track, 345 const MediaStreamVideoTrack* track,
329 VideoCaptureDeliverFrameCB frame_callback, 346 VideoCaptureDeliverFrameCB frame_callback,
(...skipping 23 matching lines...) Expand all
353 adapter->AddCallback(track, frame_callback); 370 adapter->AddCallback(track, frame_callback);
354 } 371 }
355 372
356 void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) { 373 void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) {
357 DCHECK(thread_checker_.CalledOnValidThread()); 374 DCHECK(thread_checker_.CalledOnValidThread());
358 io_message_loop_->PostTask( 375 io_message_loop_->PostTask(
359 FROM_HERE, 376 FROM_HERE,
360 base::Bind(&VideoTrackAdapter::RemoveTrackOnIO, this, track)); 377 base::Bind(&VideoTrackAdapter::RemoveTrackOnIO, this, track));
361 } 378 }
362 379
380 void VideoTrackAdapter::StartTrackMonitoringOnIO(
381 const OnMutedCallback& on_muted_state_callback,
382 double source_frame_rate) {
383 DCHECK(io_message_loop_->BelongsToCurrentThread());
384 // Only trigger monitoring for the first Track.
385 if (!adapters_.empty())
386 return;
387 // If the source does not know the frame rate, set one by default.
388 if (source_frame_rate == 0.0f)
389 source_frame_rate = MediaStreamVideoSource::kDefaultFrameRate;
390 source_frame_rate_ = source_frame_rate;
391 DVLOG(1) << "Monitoring frame creation, first (large) delay: "
392 << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s";
393 io_message_loop_->PostDelayedTask(FROM_HERE,
394 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
395 on_muted_state_callback, frame_counter_),
396 base::TimeDelta::FromSecondsD(kFirstFrameTimeoutInFrameIntervals /
397 source_frame_rate_));
398 }
399
363 void VideoTrackAdapter::RemoveTrackOnIO(const MediaStreamVideoTrack* track) { 400 void VideoTrackAdapter::RemoveTrackOnIO(const MediaStreamVideoTrack* track) {
364 DCHECK(io_message_loop_->BelongsToCurrentThread()); 401 DCHECK(io_message_loop_->BelongsToCurrentThread());
365 for (FrameAdapters::iterator it = adapters_.begin(); 402 for (FrameAdapters::iterator it = adapters_.begin();
366 it != adapters_.end(); ++it) { 403 it != adapters_.end(); ++it) {
367 (*it)->RemoveCallback(track); 404 (*it)->RemoveCallback(track);
368 if ((*it)->IsEmpty()) { 405 if ((*it)->IsEmpty()) {
369 adapters_.erase(it); 406 adapters_.erase(it);
370 break; 407 break;
371 } 408 }
372 } 409 }
373 } 410 }
374 411
375 void VideoTrackAdapter::DeliverFrameOnIO( 412 void VideoTrackAdapter::DeliverFrameOnIO(
376 const scoped_refptr<media::VideoFrame>& frame, 413 const scoped_refptr<media::VideoFrame>& frame,
377 const media::VideoCaptureFormat& format, 414 const media::VideoCaptureFormat& format,
378 const base::TimeTicks& estimated_capture_time) { 415 const base::TimeTicks& estimated_capture_time) {
379 DCHECK(io_message_loop_->BelongsToCurrentThread()); 416 DCHECK(io_message_loop_->BelongsToCurrentThread());
380 TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO"); 417 TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO");
418 ++frame_counter_;
381 for (FrameAdapters::iterator it = adapters_.begin(); 419 for (FrameAdapters::iterator it = adapters_.begin();
382 it != adapters_.end(); ++it) { 420 it != adapters_.end(); ++it) {
383 (*it)->DeliverFrame(frame, format, estimated_capture_time); 421 (*it)->DeliverFrame(frame, format, estimated_capture_time);
384 } 422 }
385 } 423 }
386 424
425 void VideoTrackAdapter::CheckFramesReceivedOnIO(
426 const OnMutedCallback& set_muted_state_callback,
427 uint64 old_frame_counter_snapshot) {
428 DCHECK(io_message_loop_->BelongsToCurrentThread());
429 DVLOG_IF(1, old_frame_counter_snapshot == frame_counter_)
430 << "No frames have passed, setting source as Muted.";
431 set_muted_state_callback.Run(old_frame_counter_snapshot == frame_counter_);
432
433 // Rearm the monitoring while there are active Tracks, i.e. as long as the
434 // owner MediaStreamSource is active.
435 io_message_loop_->PostDelayedTask(FROM_HERE,
436 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
437 set_muted_state_callback, frame_counter_),
438 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals /
439 source_frame_rate_));
440 }
441
387 } // namespace content 442 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698