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

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

Issue 10753021: Move AudioRenderer out of Filter heirarchy. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: docs Created 8 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
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"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 while (!notified_) 54 while (!notified_)
55 cv_.Wait(); 55 cv_.Wait();
56 } 56 }
57 57
58 media::PipelineStatus PipelineStatusNotification::status() { 58 media::PipelineStatus PipelineStatusNotification::status() {
59 base::AutoLock auto_lock(lock_); 59 base::AutoLock auto_lock(lock_);
60 DCHECK(notified_); 60 DCHECK(notified_);
61 return status_; 61 return status_;
62 } 62 }
63 63
64 struct Pipeline::PipelineInitState { 64 struct Pipeline::PipelineInitState {
scherkus (not reviewing) 2012/07/10 03:58:22 I think we can remove this entirely very soon
65 scoped_refptr<AudioDecoder> audio_decoder; 65 scoped_refptr<AudioDecoder> audio_decoder;
66 scoped_refptr<VideoDecoder> video_decoder; 66 scoped_refptr<VideoDecoder> video_decoder;
67 scoped_refptr<AudioRenderer> audio_renderer;
68 scoped_refptr<VideoRenderer> video_renderer; 67 scoped_refptr<VideoRenderer> video_renderer;
69 scoped_refptr<CompositeFilter> composite; 68 scoped_refptr<CompositeFilter> composite;
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 If this is only holding video_renderer now can we
scherkus (not reviewing) 2012/07/17 03:43:00 Not yet because we set pipeline_filter_ to composi
70 }; 69 };
71 70
72 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) 71 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log)
73 : message_loop_(message_loop->message_loop_proxy()), 72 : message_loop_(message_loop->message_loop_proxy()),
74 media_log_(media_log), 73 media_log_(media_log),
75 clock_(new Clock(&base::Time::Now)), 74 clock_(new Clock(&base::Time::Now)),
76 waiting_for_clock_update_(false), 75 waiting_for_clock_update_(false),
77 state_(kCreated), 76 state_(kCreated),
78 creation_time_(base::Time::Now()) { 77 creation_time_(base::Time::Now()) {
79 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 78 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 // Since the byte->time calculation is approximate, fudge the beginning & 446 // Since the byte->time calculation is approximate, fudge the beginning &
448 // ending areas to look better. 447 // ending areas to look better.
449 TimeDelta epsilon = clock_->Duration() / 100; 448 TimeDelta epsilon = clock_->Duration() / 100;
450 if (time_offset < epsilon) 449 if (time_offset < epsilon)
451 return TimeDelta(); 450 return TimeDelta();
452 if (time_offset + epsilon > clock_->Duration()) 451 if (time_offset + epsilon > clock_->Duration())
453 return clock_->Duration(); 452 return clock_->Duration();
454 return time_offset; 453 return time_offset;
455 } 454 }
456 455
456 void Pipeline::DoPause(const base::Closure& done_cb) {
scherkus (not reviewing) 2012/07/10 03:58:22 these DoXXX() methods essentially replicate Compos
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 Wow. This is not as clean as I had hoped. I think
scherkus (not reviewing) 2012/07/17 03:43:00 I played around with this for an hour or so and it
457 base::Closure do_pause = done_cb;
458
459 if (pipeline_filter_) {
scherkus (not reviewing) 2012/07/10 03:58:22 note that pipeline_filter_ ~= video_renderer_ (it'
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 Any reason we shouldn't rename pipeline_filter_ ->
scherkus (not reviewing) 2012/07/17 03:43:00 We have an actual video_renderer_ that we use for
460 do_pause = base::Bind(&Pipeline::RunOnPipelineThread, this, do_pause);
461 do_pause = base::Bind(&Filter::Pause, pipeline_filter_, do_pause);
462 }
463
464 if (audio_renderer_) {
465 do_pause = base::Bind(&Pipeline::RunOnPipelineThread, this, do_pause);
466 do_pause = base::Bind(&AudioRenderer::Pause, audio_renderer_, do_pause);
467 }
468
469 do_pause.Run();
470 }
471
472 void Pipeline::DoFlush(const base::Closure& done_cb) {
Ami GONE FROM CHROMIUM 2012/07/10 17:16:00 Before this CL CompositeFilter::Flush() was parall
scherkus (not reviewing) 2012/07/17 03:43:00 I forget why Flush() was parallel. Possibly as a w
473 base::Closure do_flush = done_cb;
474
475 if (pipeline_filter_) {
476 do_flush = base::Bind(&Pipeline::RunOnPipelineThread, this, do_flush);
477 do_flush = base::Bind(&Filter::Flush, pipeline_filter_, do_flush);
478 }
479
480 if (audio_renderer_) {
481 do_flush = base::Bind(&Pipeline::RunOnPipelineThread, this, do_flush);
482 do_flush = base::Bind(&AudioRenderer::Flush, audio_renderer_, do_flush);
483 }
484
485 do_flush.Run();
486 }
487
488 void Pipeline::DoPlay(const base::Closure& done_cb) {
489 base::Closure do_play = done_cb;
490
491 if (pipeline_filter_) {
492 do_play = base::Bind(&Pipeline::RunOnPipelineThread, this, do_play);
493 do_play = base::Bind(&Filter::Play, pipeline_filter_, do_play);
494 }
495
496 if (audio_renderer_) {
497 do_play = base::Bind(&Pipeline::RunOnPipelineThread, this, do_play);
498 do_play = base::Bind(&AudioRenderer::Play, audio_renderer_, do_play);
499 }
500
501 do_play.Run();
502 }
503
504 void Pipeline::DoStop(const base::Closure& done_cb) {
505 base::Closure do_stop = done_cb;
506
507 if (pipeline_filter_) {
508 do_stop = base::Bind(&Pipeline::RunOnPipelineThread, this, do_stop);
509 do_stop = base::Bind(&Filter::Stop, pipeline_filter_, do_stop);
510 }
511
512 if (audio_renderer_) {
513 do_stop = base::Bind(&Pipeline::RunOnPipelineThread, this, do_stop);
514 do_stop = base::Bind(&AudioRenderer::Stop, audio_renderer_, do_stop);
515 }
516
517 if (demuxer_) {
518 do_stop = base::Bind(&Pipeline::RunOnPipelineThread, this, do_stop);
519 do_stop = base::Bind(&Demuxer::Stop, demuxer_, do_stop);
520 }
521
522 do_stop.Run();
523 }
524
457 void Pipeline::AddBufferedByteRange(int64 start, int64 end) { 525 void Pipeline::AddBufferedByteRange(int64 start, int64 end) {
458 DCHECK(IsRunning()); 526 DCHECK(IsRunning());
459 base::AutoLock auto_lock(lock_); 527 base::AutoLock auto_lock(lock_);
460 buffered_byte_ranges_.Add(start, end); 528 buffered_byte_ranges_.Add(start, end);
461 did_loading_progress_ = true; 529 did_loading_progress_ = true;
462 } 530 }
463 531
464 void Pipeline::AddBufferedTimeRange(base::TimeDelta start, 532 void Pipeline::AddBufferedTimeRange(base::TimeDelta start,
465 base::TimeDelta end) { 533 base::TimeDelta end) {
466 DCHECK(IsRunning()); 534 DCHECK(IsRunning());
(...skipping 11 matching lines...) Expand all
478 natural_size_ = size; 546 natural_size_ = size;
479 } 547 }
480 548
481 void Pipeline::NotifyEnded() { 549 void Pipeline::NotifyEnded() {
482 DCHECK(IsRunning()); 550 DCHECK(IsRunning());
483 message_loop_->PostTask(FROM_HERE, base::Bind( 551 message_loop_->PostTask(FROM_HERE, base::Bind(
484 &Pipeline::NotifyEndedTask, this)); 552 &Pipeline::NotifyEndedTask, this));
485 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); 553 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
486 } 554 }
487 555
488 void Pipeline::DisableAudioRenderer() { 556 void Pipeline::AudioRendererEnded() {
489 DCHECK(IsRunning()); 557 DCHECK(IsRunning());
558 message_loop_->PostTask(FROM_HERE, base::Bind(
559 &Pipeline::NotifyEndedTask, this));
560 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
561 }
490 562
491 // Disable renderer on the message loop. 563 void Pipeline::AudioRendererDisabled() {
564 DCHECK(IsRunning());
492 message_loop_->PostTask(FROM_HERE, base::Bind( 565 message_loop_->PostTask(FROM_HERE, base::Bind(
493 &Pipeline::DisableAudioRendererTask, this)); 566 &Pipeline::AudioRendererDisabledTask, this));
494 media_log_->AddEvent( 567 media_log_->AddEvent(
495 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); 568 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED));
496 } 569 }
497 570
498 // Called from any thread. 571 // Called from any thread.
499 void Pipeline::OnFilterInitialize(PipelineStatus status) { 572 void Pipeline::OnFilterInitialize(PipelineStatus status) {
500 // Continue the initialize task by proceeding to the next stage. 573 // Continue the initialize task by proceeding to the next stage.
501 message_loop_->PostTask(FROM_HERE, base::Bind( 574 message_loop_->PostTask(FROM_HERE, base::Bind(
502 &Pipeline::InitializeTask, this, status)); 575 &Pipeline::InitializeTask, this, status));
503 } 576 }
504 577
505 // Called from any thread. 578 // Called from any thread.
506 void Pipeline::OnFilterStateTransition() { 579 void Pipeline::OnFilterStateTransition() {
scherkus (not reviewing) 2012/07/10 04:02:52 we might be to remove this trampoline since the Do
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 This is an unconditional post though. RunOnPipelin
Ami GONE FROM CHROMIUM 2012/07/10 17:16:00 I agree w/ acolwell and suspect this means RunOnPi
scherkus (not reviewing) 2012/07/17 03:43:00 Done.
507 message_loop_->PostTask(FROM_HERE, base::Bind( 580 message_loop_->PostTask(FROM_HERE, base::Bind(
508 &Pipeline::FilterStateTransitionTask, this)); 581 &Pipeline::FilterStateTransitionTask, this));
509 } 582 }
510 583
511 // Called from any thread. 584 // Called from any thread.
512 // This method makes the PipelineStatusCB behave like a Closure. It 585 // This method makes the PipelineStatusCB behave like a Closure. It
513 // makes it look like a host()->SetError() call followed by a call to 586 // makes it look like a host()->SetError() call followed by a call to
514 // OnFilterStateTransition() when errors occur. 587 // OnFilterStateTransition() when errors occur.
515 // 588 //
516 // TODO: Revisit this code when SetError() is removed from FilterHost and 589 // TODO: Revisit this code when SetError() is removed from FilterHost and
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 812
740 { 813 {
741 base::AutoLock auto_lock(lock_); 814 base::AutoLock auto_lock(lock_);
742 clock_->SetPlaybackRate(playback_rate); 815 clock_->SetPlaybackRate(playback_rate);
743 } 816 }
744 817
745 // Notify |pipeline_filter_| if it has been initialized. If initialization 818 // Notify |pipeline_filter_| if it has been initialized. If initialization
746 // hasn't completed yet, the playback rate will be set when initialization 819 // hasn't completed yet, the playback rate will be set when initialization
747 // completes. 820 // completes.
748 if (pipeline_filter_) { 821 if (pipeline_filter_) {
749 DCHECK(demuxer_);
750 demuxer_->SetPlaybackRate(playback_rate); 822 demuxer_->SetPlaybackRate(playback_rate);
751 pipeline_filter_->SetPlaybackRate(playback_rate); 823 pipeline_filter_->SetPlaybackRate(playback_rate);
752 } 824 }
825
826 if (audio_renderer_)
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 This isn't consistent with the original code. It s
scherkus (not reviewing) 2012/07/17 03:43:00 Done.
827 audio_renderer_->SetPlaybackRate(playback_rate_);
753 } 828 }
754 829
755 void Pipeline::VolumeChangedTask(float volume) { 830 void Pipeline::VolumeChangedTask(float volume) {
756 DCHECK(message_loop_->BelongsToCurrentThread()); 831 DCHECK(message_loop_->BelongsToCurrentThread());
757 if (!running_ || tearing_down_) 832 if (!running_ || tearing_down_)
758 return; 833 return;
759 834
760 if (audio_renderer_) 835 if (audio_renderer_)
761 audio_renderer_->SetVolume(volume); 836 audio_renderer_->SetVolume(volume);
762 } 837 }
(...skipping 24 matching lines...) Expand all
787 SetState(kPausing); 862 SetState(kPausing);
788 seek_timestamp_ = time; 863 seek_timestamp_ = time;
789 seek_cb_ = seek_cb; 864 seek_cb_ = seek_cb;
790 865
791 // Kick off seeking! 866 // Kick off seeking!
792 { 867 {
793 base::AutoLock auto_lock(lock_); 868 base::AutoLock auto_lock(lock_);
794 if (clock_->IsPlaying()) 869 if (clock_->IsPlaying())
795 clock_->Pause(); 870 clock_->Pause();
796 } 871 }
797 pipeline_filter_->Pause( 872 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this));
798 base::Bind(&Pipeline::OnFilterStateTransition, this));
799 } 873 }
800 874
801 void Pipeline::NotifyEndedTask() { 875 void Pipeline::NotifyEndedTask() {
802 DCHECK(message_loop_->BelongsToCurrentThread()); 876 DCHECK(message_loop_->BelongsToCurrentThread());
803 877
804 // We can only end if we were actually playing. 878 // We can only end if we were actually playing.
805 if (state_ != kStarted) { 879 if (state_ != kStarted) {
806 return; 880 return;
807 } 881 }
808 882
(...skipping 19 matching lines...) Expand all
828 // Transition to ended, executing the callback if present. 902 // Transition to ended, executing the callback if present.
829 SetState(kEnded); 903 SetState(kEnded);
830 { 904 {
831 base::AutoLock auto_lock(lock_); 905 base::AutoLock auto_lock(lock_);
832 clock_->EndOfStream(); 906 clock_->EndOfStream();
833 } 907 }
834 908
835 ReportStatus(ended_cb_, status_); 909 ReportStatus(ended_cb_, status_);
836 } 910 }
837 911
838 void Pipeline::DisableAudioRendererTask() { 912 void Pipeline::AudioRendererDisabledTask() {
839 DCHECK(message_loop_->BelongsToCurrentThread()); 913 DCHECK(message_loop_->BelongsToCurrentThread());
840 914
841 base::AutoLock auto_lock(lock_); 915 base::AutoLock auto_lock(lock_);
842 has_audio_ = false; 916 has_audio_ = false;
843 audio_disabled_ = true; 917 audio_disabled_ = true;
844 918
845 // Notify our demuxer that we're no longer rendering audio. 919 // Notify our demuxer that we're no longer rendering audio.
846 demuxer_->OnAudioRendererDisabled(); 920 demuxer_->OnAudioRendererDisabled();
847 921
848 // Start clock since there is no more audio to 922 // Start clock since there is no more audio to
(...skipping 26 matching lines...) Expand all
875 // to the next state if needed. 949 // to the next state if needed.
876 SetState(FindNextState(state_)); 950 SetState(FindNextState(state_));
877 if (state_ == kSeeking) { 951 if (state_ == kSeeking) {
878 base::AutoLock auto_lock(lock_); 952 base::AutoLock auto_lock(lock_);
879 clock_->SetTime(seek_timestamp_, seek_timestamp_); 953 clock_->SetTime(seek_timestamp_, seek_timestamp_);
880 } 954 }
881 955
882 // Carry out the action for the current state. 956 // Carry out the action for the current state.
883 if (TransientState(state_)) { 957 if (TransientState(state_)) {
884 if (state_ == kPausing) { 958 if (state_ == kPausing) {
885 pipeline_filter_->Pause( 959 DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this));
886 base::Bind(&Pipeline::OnFilterStateTransition, this));
887 } else if (state_ == kFlushing) { 960 } else if (state_ == kFlushing) {
888 pipeline_filter_->Flush( 961 DoFlush(base::Bind(&Pipeline::OnFilterStateTransition, this));
889 base::Bind(&Pipeline::OnFilterStateTransition, this));
890 } else if (state_ == kSeeking) { 962 } else if (state_ == kSeeking) {
891 DoSeek(seek_timestamp_); 963 DoSeek(seek_timestamp_);
892 } else if (state_ == kStarting) { 964 } else if (state_ == kStarting) {
893 pipeline_filter_->Play( 965 DoPlay(base::Bind(&Pipeline::OnFilterStateTransition, this));
894 base::Bind(&Pipeline::OnFilterStateTransition, this));
895 } else if (state_ == kStopping) { 966 } else if (state_ == kStopping) {
896 DoStop(base::Bind(&Pipeline::OnFilterStateTransition, this)); 967 DoStop(base::Bind(&Pipeline::OnFilterStateTransition, this));
897 } else { 968 } else {
898 NOTREACHED() << "Unexpected state: " << state_; 969 NOTREACHED() << "Unexpected state: " << state_;
899 } 970 }
900 } else if (state_ == kStarted) { 971 } else if (state_ == kStarted) {
901 FinishInitialization(); 972 FinishInitialization();
902 973
903 // Finally, complete the seek. 974 // Finally, complete the seek.
904 seek_pending_ = false; 975 seek_pending_ = false;
(...skipping 25 matching lines...) Expand all
930 1001
931 void Pipeline::TeardownStateTransitionTask() { 1002 void Pipeline::TeardownStateTransitionTask() {
932 DCHECK(IsPipelineTearingDown()); 1003 DCHECK(IsPipelineTearingDown());
933 switch (state_) { 1004 switch (state_) {
934 case kStopping: 1005 case kStopping:
935 SetState(error_caused_teardown_ ? kError : kStopped); 1006 SetState(error_caused_teardown_ ? kError : kStopped);
936 FinishDestroyingFiltersTask(); 1007 FinishDestroyingFiltersTask();
937 break; 1008 break;
938 case kPausing: 1009 case kPausing:
939 SetState(kFlushing); 1010 SetState(kFlushing);
940 pipeline_filter_->Flush( 1011 DoFlush(base::Bind(&Pipeline::OnTeardownStateTransition, this));
941 base::Bind(&Pipeline::OnTeardownStateTransition, this));
942 break; 1012 break;
943 case kFlushing: 1013 case kFlushing:
944 SetState(kStopping); 1014 SetState(kStopping);
945 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); 1015 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
946 break; 1016 break;
947 1017
948 case kCreated: 1018 case kCreated:
949 case kError: 1019 case kError:
950 case kInitDemuxer: 1020 case kInitDemuxer:
951 case kInitAudioDecoder: 1021 case kInitAudioDecoder:
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 } 1149 }
1080 1150
1081 bool Pipeline::InitializeAudioRenderer( 1151 bool Pipeline::InitializeAudioRenderer(
1082 const scoped_refptr<AudioDecoder>& decoder) { 1152 const scoped_refptr<AudioDecoder>& decoder) {
1083 DCHECK(message_loop_->BelongsToCurrentThread()); 1153 DCHECK(message_loop_->BelongsToCurrentThread());
1084 DCHECK(IsPipelineOk()); 1154 DCHECK(IsPipelineOk());
1085 1155
1086 if (!decoder) 1156 if (!decoder)
1087 return false; 1157 return false;
1088 1158
1089 filter_collection_->SelectAudioRenderer( 1159 filter_collection_->SelectAudioRenderer(&audio_renderer_);
1090 &pipeline_init_state_->audio_renderer); 1160 if (!audio_renderer_) {
1091 if (!pipeline_init_state_->audio_renderer) {
1092 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1161 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1093 return false; 1162 return false;
1094 } 1163 }
1095 1164
1096 pipeline_init_state_->composite->AddFilter( 1165 audio_renderer_->SetHost(this);
scherkus (not reviewing) 2012/07/10 04:02:52 I think SetHost() can go away after we replace ARH
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 I think we should just add the callbacks now. I ca
scherkus (not reviewing) 2012/07/17 03:43:00 Done.
1097 pipeline_init_state_->audio_renderer); 1166 audio_renderer_->Initialize(
1098
1099 pipeline_init_state_->audio_renderer->Initialize(
1100 decoder, 1167 decoder,
1101 base::Bind(&Pipeline::OnFilterInitialize, this), 1168 base::Bind(&Pipeline::OnFilterInitialize, this),
1102 base::Bind(&Pipeline::OnAudioUnderflow, this), 1169 base::Bind(&Pipeline::OnAudioUnderflow, this),
1103 base::Bind(&Pipeline::OnAudioTimeUpdate, this)); 1170 base::Bind(&Pipeline::OnAudioTimeUpdate, this));
1104
1105 audio_renderer_ = pipeline_init_state_->audio_renderer;
1106 return true; 1171 return true;
1107 } 1172 }
1108 1173
1109 bool Pipeline::InitializeVideoRenderer( 1174 bool Pipeline::InitializeVideoRenderer(
1110 const scoped_refptr<VideoDecoder>& decoder) { 1175 const scoped_refptr<VideoDecoder>& decoder) {
1111 DCHECK(message_loop_->BelongsToCurrentThread()); 1176 DCHECK(message_loop_->BelongsToCurrentThread());
1112 DCHECK(IsPipelineOk()); 1177 DCHECK(IsPipelineOk());
1113 1178
1114 if (!decoder) 1179 if (!decoder)
1115 return false; 1180 return false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 if (seek_pending_) { 1246 if (seek_pending_) {
1182 seek_pending_ = false; 1247 seek_pending_ = false;
1183 FinishInitialization(); 1248 FinishInitialization();
1184 } 1249 }
1185 1250
1186 break; 1251 break;
1187 1252
1188 case kStarted: 1253 case kStarted:
1189 case kEnded: 1254 case kEnded:
1190 SetState(kPausing); 1255 SetState(kPausing);
1191 pipeline_filter_->Pause( 1256 DoPause(base::Bind(&Pipeline::OnTeardownStateTransition, this));
1192 base::Bind(&Pipeline::OnTeardownStateTransition, this));
1193 break; 1257 break;
1194 1258
1195 case kStopping: 1259 case kStopping:
1196 case kStopped: 1260 case kStopped:
1197 NOTREACHED() << "Unexpected state for teardown: " << state_; 1261 NOTREACHED() << "Unexpected state for teardown: " << state_;
1198 break; 1262 break;
1199 // default: intentionally left out to force new states to cause compiler 1263 // default: intentionally left out to force new states to cause compiler
1200 // errors. 1264 // errors.
1201 }; 1265 };
1202 } 1266 }
1203 1267
1204 void Pipeline::DoStop(const base::Closure& callback) {
1205 if (demuxer_) {
1206 demuxer_->Stop(base::Bind(
1207 &Pipeline::OnDemuxerStopDone, this, callback));
1208 return;
1209 }
1210
1211 OnDemuxerStopDone(callback);
1212 }
1213
1214 void Pipeline::OnDemuxerStopDone(const base::Closure& callback) {
1215 if (!message_loop_->BelongsToCurrentThread()) {
1216 message_loop_->PostTask(FROM_HERE, base::Bind(
1217 &Pipeline::OnDemuxerStopDone, this, callback));
1218 return;
1219 }
1220
1221 if (pipeline_filter_) {
1222 pipeline_filter_->Stop(callback);
1223 return;
1224 }
1225
1226 callback.Run();
1227 }
1228
1229 void Pipeline::DoSeek(TimeDelta seek_timestamp) { 1268 void Pipeline::DoSeek(TimeDelta seek_timestamp) {
1230 // TODO(acolwell): We might be able to convert this if (demuxer_) into a 1269 // TODO(acolwell): We might be able to convert this if (demuxer_) into a
1231 // DCHECK(). Further investigation is needed to make sure this won't introduce 1270 // DCHECK(). Further investigation is needed to make sure this won't introduce
1232 // a bug. 1271 // a bug.
scherkus (not reviewing) 2012/07/10 03:58:22 FYI I think it's impossible for demuxer_ to be NUL
acolwell GONE FROM CHROMIUM 2012/07/10 16:34:37 Go for it. We'll see if it goes boom.
scherkus (not reviewing) 2012/07/17 03:43:00 Committed separately as r146024.
1233 if (demuxer_) { 1272 if (demuxer_) {
1234 demuxer_->Seek(seek_timestamp, base::Bind( 1273 demuxer_->Seek(seek_timestamp, base::Bind(
1235 &Pipeline::OnDemuxerSeekDone, this, seek_timestamp)); 1274 &Pipeline::OnDemuxerSeekDone, this, seek_timestamp));
1236 return; 1275 return;
1237 } 1276 }
1238 1277
1239 OnDemuxerSeekDone(seek_timestamp, PIPELINE_OK); 1278 OnDemuxerSeekDone(seek_timestamp, PIPELINE_OK);
1240 } 1279 }
1241 1280
1242 void Pipeline::OnDemuxerSeekDone(TimeDelta seek_timestamp, 1281 void Pipeline::OnDemuxerSeekDone(TimeDelta seek_timestamp,
1243 PipelineStatus status) { 1282 PipelineStatus status) {
1244 if (!message_loop_->BelongsToCurrentThread()) { 1283 if (!message_loop_->BelongsToCurrentThread()) {
1245 message_loop_->PostTask(FROM_HERE, base::Bind( 1284 message_loop_->PostTask(FROM_HERE, base::Bind(
1246 &Pipeline::OnDemuxerSeekDone, this, seek_timestamp, status)); 1285 &Pipeline::OnDemuxerSeekDone, this, seek_timestamp, status));
1247 return; 1286 return;
1248 } 1287 }
1249 1288
1289 if (status == PIPELINE_OK && audio_renderer_) {
1290 audio_renderer_->Seek(seek_timestamp, base::Bind(
1291 &Pipeline::OnAudioRendererSeekDone, this, seek_timestamp));
1292 return;
1293 }
1294
1295 OnAudioRendererSeekDone(seek_timestamp, status);
1296 }
1297
1298 void Pipeline::OnAudioRendererSeekDone(base::TimeDelta seek_timestamp,
1299 PipelineStatus status) {
1300 if (!message_loop_->BelongsToCurrentThread()) {
1301 message_loop_->PostTask(FROM_HERE, base::Bind(
1302 &Pipeline::OnAudioRendererSeekDone, this, seek_timestamp, status));
1303 return;
1304 }
1305
1250 PipelineStatusCB done_cb = 1306 PipelineStatusCB done_cb =
1251 base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this); 1307 base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this);
1252 1308
1253 if (status == PIPELINE_OK && pipeline_filter_) { 1309 if (status == PIPELINE_OK && pipeline_filter_) {
1254 pipeline_filter_->Seek(seek_timestamp, done_cb); 1310 pipeline_filter_->Seek(seek_timestamp, done_cb);
1255 return; 1311 return;
1256 } 1312 }
1257 1313
1258 ReportStatus(done_cb, status); 1314 ReportStatus(done_cb, status);
1259 } 1315 }
(...skipping 14 matching lines...) Expand all
1274 1330
1275 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 1331 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
1276 lock_.AssertAcquired(); 1332 lock_.AssertAcquired();
1277 if (!waiting_for_clock_update_) 1333 if (!waiting_for_clock_update_)
1278 return; 1334 return;
1279 1335
1280 waiting_for_clock_update_ = false; 1336 waiting_for_clock_update_ = false;
1281 clock_->Play(); 1337 clock_->Play();
1282 } 1338 }
1283 1339
1340 void Pipeline::RunOnPipelineThread(const base::Closure& closure) {
1341 if (!message_loop_->BelongsToCurrentThread()) {
1342 message_loop_->PostTask(FROM_HERE, base::Bind(
1343 &Pipeline::RunOnPipelineThread, this, closure));
1344 return;
1345 }
1346 closure.Run();
1347 }
1348
1284 } // namespace media 1349 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698