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

Side by Side Diff: media/base/pipeline.cc

Issue 403723006: Make media::AudioRenderer inherit from media::TimeSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: composition 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 | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/base/pipeline.h" 5 #include "media/base/pipeline.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/synchronization/condition_variable.h" 19 #include "base/synchronization/condition_variable.h"
20 #include "media/base/audio_decoder.h" 20 #include "media/base/audio_decoder.h"
21 #include "media/base/audio_renderer.h" 21 #include "media/base/audio_renderer.h"
22 #include "media/base/filter_collection.h" 22 #include "media/base/filter_collection.h"
23 #include "media/base/media_log.h" 23 #include "media/base/media_log.h"
24 #include "media/base/text_renderer.h" 24 #include "media/base/text_renderer.h"
25 #include "media/base/text_track_config.h" 25 #include "media/base/text_track_config.h"
26 #include "media/base/time_delta_interpolator.h" 26 #include "media/base/time_delta_interpolator.h"
27 #include "media/base/time_source.h"
27 #include "media/base/video_decoder.h" 28 #include "media/base/video_decoder.h"
28 #include "media/base/video_decoder_config.h" 29 #include "media/base/video_decoder_config.h"
29 #include "media/base/video_renderer.h" 30 #include "media/base/video_renderer.h"
30 31
31 using base::TimeDelta; 32 using base::TimeDelta;
32 33
33 namespace media { 34 namespace media {
34 35
35 Pipeline::Pipeline( 36 Pipeline::Pipeline(
36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 37 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
37 MediaLog* media_log) 38 MediaLog* media_log)
38 : task_runner_(task_runner), 39 : task_runner_(task_runner),
39 media_log_(media_log), 40 media_log_(media_log),
40 running_(false), 41 running_(false),
41 did_loading_progress_(false), 42 did_loading_progress_(false),
42 volume_(1.0f), 43 volume_(1.0f),
43 playback_rate_(0.0f), 44 playback_rate_(0.0f),
44 interpolator_(new TimeDeltaInterpolator(&default_tick_clock_)), 45 interpolator_(new TimeDeltaInterpolator(&default_tick_clock_)),
45 interpolation_state_(INTERPOLATION_STOPPED), 46 interpolation_state_(INTERPOLATION_STOPPED),
46 status_(PIPELINE_OK), 47 status_(PIPELINE_OK),
47 state_(kCreated), 48 state_(kCreated),
48 audio_ended_(false), 49 audio_ended_(false),
49 video_ended_(false), 50 video_ended_(false),
50 text_ended_(false), 51 text_ended_(false),
51 audio_buffering_state_(BUFFERING_HAVE_NOTHING), 52 audio_buffering_state_(BUFFERING_HAVE_NOTHING),
52 video_buffering_state_(BUFFERING_HAVE_NOTHING), 53 video_buffering_state_(BUFFERING_HAVE_NOTHING),
53 demuxer_(NULL), 54 demuxer_(NULL),
55 time_source_(NULL),
54 underflow_disabled_for_testing_(false) { 56 underflow_disabled_for_testing_(false) {
55 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 57 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
56 media_log_->AddEvent( 58 media_log_->AddEvent(
57 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); 59 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED));
58 interpolator_->SetBounds(base::TimeDelta(), base::TimeDelta()); 60 interpolator_->SetBounds(base::TimeDelta(), base::TimeDelta());
59 } 61 }
60 62
61 Pipeline::~Pipeline() { 63 Pipeline::~Pipeline() {
62 DCHECK(thread_checker_.CalledOnValidThread()) 64 DCHECK(thread_checker_.CalledOnValidThread())
63 << "Pipeline must be destroyed on same thread that created it"; 65 << "Pipeline must be destroyed on same thread that created it";
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 case kPlaying: 375 case kPlaying:
374 // Finish initial start sequence the first time we enter the playing 376 // Finish initial start sequence the first time we enter the playing
375 // state. 377 // state.
376 if (filter_collection_) { 378 if (filter_collection_) {
377 filter_collection_.reset(); 379 filter_collection_.reset();
378 if (!audio_renderer_ && !video_renderer_) { 380 if (!audio_renderer_ && !video_renderer_) {
379 ErrorChangedTask(PIPELINE_ERROR_COULD_NOT_RENDER); 381 ErrorChangedTask(PIPELINE_ERROR_COULD_NOT_RENDER);
380 return; 382 return;
381 } 383 }
382 384
385 if (audio_renderer_)
386 time_source_ = audio_renderer_->GetTimeSource();
387
383 { 388 {
384 PipelineMetadata metadata; 389 PipelineMetadata metadata;
385 metadata.has_audio = audio_renderer_; 390 metadata.has_audio = audio_renderer_;
386 metadata.has_video = video_renderer_; 391 metadata.has_video = video_renderer_;
387 metadata.timeline_offset = demuxer_->GetTimelineOffset(); 392 metadata.timeline_offset = demuxer_->GetTimelineOffset();
388 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 393 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
389 if (stream) { 394 if (stream) {
390 metadata.natural_size = 395 metadata.natural_size =
391 stream->video_decoder_config().natural_size(); 396 stream->video_decoder_config().natural_size();
392 metadata.video_rotation = stream->video_rotation(); 397 metadata.video_rotation = stream->video_rotation();
393 } 398 }
394 metadata_cb_.Run(metadata); 399 metadata_cb_.Run(metadata);
395 } 400 }
396 } 401 }
397 402
398 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 403 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
399 404
400 { 405 {
401 base::AutoLock auto_lock(lock_); 406 base::AutoLock auto_lock(lock_);
402 interpolator_->SetBounds(start_timestamp_, start_timestamp_); 407 interpolator_->SetBounds(start_timestamp_, start_timestamp_);
403 } 408 }
404 409
405 if (audio_renderer_) { 410 if (time_source_)
xhwang 2014/07/22 00:29:28 Once we use WallClockTimeSource, we should be able
scherkus (not reviewing) 2014/07/22 00:30:59 correct! all condition checking for time_source_ w
406 audio_renderer_->SetMediaTime(start_timestamp_); 411 time_source_->SetMediaTime(start_timestamp_);
412 if (audio_renderer_)
407 audio_renderer_->StartPlaying(); 413 audio_renderer_->StartPlaying();
408 }
409 if (video_renderer_) 414 if (video_renderer_)
410 video_renderer_->StartPlaying(); 415 video_renderer_->StartPlaying();
411 if (text_renderer_) 416 if (text_renderer_)
412 text_renderer_->StartPlaying(); 417 text_renderer_->StartPlaying();
413 418
414 PlaybackRateChangedTask(GetPlaybackRate()); 419 PlaybackRateChangedTask(GetPlaybackRate());
415 VolumeChangedTask(GetVolume()); 420 VolumeChangedTask(GetVolume());
416 return; 421 return;
417 422
418 case kStopping: 423 case kStopping:
(...skipping 21 matching lines...) Expand all
440 #endif 445 #endif
441 446
442 void Pipeline::DoSeek( 447 void Pipeline::DoSeek(
443 base::TimeDelta seek_timestamp, 448 base::TimeDelta seek_timestamp,
444 const PipelineStatusCB& done_cb) { 449 const PipelineStatusCB& done_cb) {
445 DCHECK(task_runner_->BelongsToCurrentThread()); 450 DCHECK(task_runner_->BelongsToCurrentThread());
446 DCHECK(!pending_callbacks_.get()); 451 DCHECK(!pending_callbacks_.get());
447 SerialRunner::Queue bound_fns; 452 SerialRunner::Queue bound_fns;
448 { 453 {
449 base::AutoLock auto_lock(lock_); 454 base::AutoLock auto_lock(lock_);
450 PauseClockAndStopRendering_Locked(); 455 PauseClockAndStopTicking_Locked();
451 } 456 }
452 457
453 // Pause. 458 // Pause.
454 if (text_renderer_) { 459 if (text_renderer_) {
455 bound_fns.Push(base::Bind( 460 bound_fns.Push(base::Bind(
456 &TextRenderer::Pause, base::Unretained(text_renderer_.get()))); 461 &TextRenderer::Pause, base::Unretained(text_renderer_.get())));
457 } 462 }
458 463
459 // Flush. 464 // Flush.
460 if (audio_renderer_) { 465 if (audio_renderer_) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 647
643 // Playback rate changes are only carried out while playing. 648 // Playback rate changes are only carried out while playing.
644 if (state_ != kPlaying) 649 if (state_ != kPlaying)
645 return; 650 return;
646 651
647 { 652 {
648 base::AutoLock auto_lock(lock_); 653 base::AutoLock auto_lock(lock_);
649 interpolator_->SetPlaybackRate(playback_rate); 654 interpolator_->SetPlaybackRate(playback_rate);
650 } 655 }
651 656
652 if (audio_renderer_) 657 if (time_source_)
653 audio_renderer_->SetPlaybackRate(playback_rate_); 658 time_source_->SetPlaybackRate(playback_rate_);
654 } 659 }
655 660
656 void Pipeline::VolumeChangedTask(float volume) { 661 void Pipeline::VolumeChangedTask(float volume) {
657 DCHECK(task_runner_->BelongsToCurrentThread()); 662 DCHECK(task_runner_->BelongsToCurrentThread());
658 663
659 // Volume changes are only carried out while playing. 664 // Volume changes are only carried out while playing.
660 if (state_ != kPlaying) 665 if (state_ != kPlaying)
661 return; 666 return;
662 667
663 if (audio_renderer_) 668 if (audio_renderer_)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 return; 748 return;
744 749
745 if (video_renderer_ && !video_ended_) 750 if (video_renderer_ && !video_ended_)
746 return; 751 return;
747 752
748 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_) 753 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_)
749 return; 754 return;
750 755
751 { 756 {
752 base::AutoLock auto_lock(lock_); 757 base::AutoLock auto_lock(lock_);
753 PauseClockAndStopRendering_Locked(); 758 PauseClockAndStopTicking_Locked();
754 interpolator_->SetBounds(duration_, duration_); 759 interpolator_->SetBounds(duration_, duration_);
755 } 760 }
756 761
757 DCHECK_EQ(status_, PIPELINE_OK); 762 DCHECK_EQ(status_, PIPELINE_OK);
758 ended_cb_.Run(); 763 ended_cb_.Run();
759 } 764 }
760 765
761 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream, 766 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream,
762 const TextTrackConfig& config) { 767 const TextTrackConfig& config) {
763 DCHECK(task_runner_->BelongsToCurrentThread()); 768 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 return false; 861 return false;
857 } 862 }
858 863
859 void Pipeline::PausePlayback() { 864 void Pipeline::PausePlayback() {
860 DVLOG(1) << __FUNCTION__; 865 DVLOG(1) << __FUNCTION__;
861 DCHECK_EQ(state_, kPlaying); 866 DCHECK_EQ(state_, kPlaying);
862 DCHECK(WaitingForEnoughData()); 867 DCHECK(WaitingForEnoughData());
863 DCHECK(task_runner_->BelongsToCurrentThread()); 868 DCHECK(task_runner_->BelongsToCurrentThread());
864 869
865 base::AutoLock auto_lock(lock_); 870 base::AutoLock auto_lock(lock_);
866 PauseClockAndStopRendering_Locked(); 871 PauseClockAndStopTicking_Locked();
867 } 872 }
868 873
869 void Pipeline::StartPlayback() { 874 void Pipeline::StartPlayback() {
870 DVLOG(1) << __FUNCTION__; 875 DVLOG(1) << __FUNCTION__;
871 DCHECK_EQ(state_, kPlaying); 876 DCHECK_EQ(state_, kPlaying);
872 DCHECK_EQ(interpolation_state_, INTERPOLATION_STOPPED); 877 DCHECK_EQ(interpolation_state_, INTERPOLATION_STOPPED);
873 DCHECK(!WaitingForEnoughData()); 878 DCHECK(!WaitingForEnoughData());
874 DCHECK(task_runner_->BelongsToCurrentThread()); 879 DCHECK(task_runner_->BelongsToCurrentThread());
875 880
876 if (audio_renderer_) { 881 if (time_source_) {
877 // We use audio stream to update the clock. So if there is such a 882 // We use audio stream to update the clock. So if there is such a
878 // stream, we pause the clock until we receive a valid timestamp. 883 // stream, we pause the clock until we receive a valid timestamp.
879 base::AutoLock auto_lock(lock_); 884 base::AutoLock auto_lock(lock_);
880 interpolation_state_ = INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE; 885 interpolation_state_ = INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE;
881 audio_renderer_->StartRendering(); 886 time_source_->StartTicking();
882 } else { 887 } else {
883 base::AutoLock auto_lock(lock_); 888 base::AutoLock auto_lock(lock_);
884 interpolation_state_ = INTERPOLATION_STARTED; 889 interpolation_state_ = INTERPOLATION_STARTED;
885 interpolator_->SetUpperBound(duration_); 890 interpolator_->SetUpperBound(duration_);
886 interpolator_->StartInterpolating(); 891 interpolator_->StartInterpolating();
887 } 892 }
888 } 893 }
889 894
890 void Pipeline::PauseClockAndStopRendering_Locked() { 895 void Pipeline::PauseClockAndStopTicking_Locked() {
891 lock_.AssertAcquired(); 896 lock_.AssertAcquired();
892 switch (interpolation_state_) { 897 switch (interpolation_state_) {
893 case INTERPOLATION_STOPPED: 898 case INTERPOLATION_STOPPED:
894 return; 899 return;
895 900
896 case INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE: 901 case INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE:
897 audio_renderer_->StopRendering(); 902 time_source_->StopTicking();
xhwang 2014/07/22 00:29:28 This is a bit odd here. Maybe time_source_ should
scherkus (not reviewing) 2014/07/22 00:30:59 yeah it'll get cleaned up
898 break; 903 break;
899 904
900 case INTERPOLATION_STARTED: 905 case INTERPOLATION_STARTED:
901 if (audio_renderer_) 906 if (time_source_)
902 audio_renderer_->StopRendering(); 907 time_source_->StopTicking();
903 interpolator_->StopInterpolating(); 908 interpolator_->StopInterpolating();
904 break; 909 break;
905 } 910 }
906 911
907 interpolation_state_ = INTERPOLATION_STOPPED; 912 interpolation_state_ = INTERPOLATION_STOPPED;
908 } 913 }
909 914
910 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 915 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
911 lock_.AssertAcquired(); 916 lock_.AssertAcquired();
912 if (interpolation_state_ != INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE) 917 if (interpolation_state_ != INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE)
913 return; 918 return;
914 919
915 interpolation_state_ = INTERPOLATION_STARTED; 920 interpolation_state_ = INTERPOLATION_STARTED;
916 interpolator_->StartInterpolating(); 921 interpolator_->StartInterpolating();
917 } 922 }
918 923
919 } // namespace media 924 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698