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

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

Issue 294133003: Extract media::Clock::IsPlaying() into media::Pipeline::ClockState enum. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes + rebase Created 6 years, 7 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"
(...skipping 24 matching lines...) Expand all
35 Pipeline::Pipeline( 35 Pipeline::Pipeline(
36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
37 MediaLog* media_log) 37 MediaLog* media_log)
38 : task_runner_(task_runner), 38 : task_runner_(task_runner),
39 media_log_(media_log), 39 media_log_(media_log),
40 running_(false), 40 running_(false),
41 did_loading_progress_(false), 41 did_loading_progress_(false),
42 volume_(1.0f), 42 volume_(1.0f),
43 playback_rate_(0.0f), 43 playback_rate_(0.0f),
44 clock_(new Clock(&default_tick_clock_)), 44 clock_(new Clock(&default_tick_clock_)),
45 waiting_for_clock_update_(false), 45 clock_state_(CLOCK_PAUSED),
46 status_(PIPELINE_OK), 46 status_(PIPELINE_OK),
47 state_(kCreated), 47 state_(kCreated),
48 audio_ended_(false), 48 audio_ended_(false),
49 video_ended_(false), 49 video_ended_(false),
50 text_ended_(false), 50 text_ended_(false),
51 audio_buffering_state_(BUFFERING_HAVE_NOTHING), 51 audio_buffering_state_(BUFFERING_HAVE_NOTHING),
52 video_buffering_state_(BUFFERING_HAVE_NOTHING), 52 video_buffering_state_(BUFFERING_HAVE_NOTHING),
53 demuxer_(NULL), 53 demuxer_(NULL),
54 creation_time_(default_tick_clock_.NowTicks()) { 54 creation_time_(default_tick_clock_.NowTicks()) {
55 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 55 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 &Pipeline::ErrorChangedTask, base::Unretained(this), error)); 290 &Pipeline::ErrorChangedTask, base::Unretained(this), error));
291 291
292 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); 292 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error));
293 } 293 }
294 294
295 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { 295 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
296 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); 296 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds());
297 DCHECK(IsRunning()); 297 DCHECK(IsRunning());
298 base::AutoLock auto_lock(lock_); 298 base::AutoLock auto_lock(lock_);
299 299
300 if (waiting_for_clock_update_ && time < clock_->Elapsed()) 300 if (clock_state_ == CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE &&
301 time < clock_->Elapsed()) {
301 return; 302 return;
303 }
302 304
303 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see 305 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see
304 // http://crbug.com/137973 306 // http://crbug.com/137973
305 if (state_ == kSeeking) 307 if (state_ == kSeeking)
306 return; 308 return;
307 309
308 clock_->SetTime(time, max_time); 310 clock_->SetTime(time, max_time);
309 StartClockIfWaitingForTimeUpdate_Locked(); 311 StartClockIfWaitingForTimeUpdate_Locked();
310 } 312 }
311 313
312 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) { 314 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) {
313 DCHECK(IsRunning()); 315 DCHECK(IsRunning());
314 base::AutoLock auto_lock(lock_); 316 base::AutoLock auto_lock(lock_);
315 317
316 if (audio_renderer_) 318 if (audio_renderer_)
317 return; 319 return;
318 320
319 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see 321 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see
320 // http://crbug.com/137973 322 // http://crbug.com/137973
321 if (state_ == kSeeking) 323 if (state_ == kSeeking)
322 return; 324 return;
323 325
324 DCHECK(!waiting_for_clock_update_); 326 DCHECK_NE(clock_state_, CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE);
325 clock_->SetMaxTime(max_time); 327 clock_->SetMaxTime(max_time);
326 } 328 }
327 329
328 void Pipeline::SetDuration(TimeDelta duration) { 330 void Pipeline::SetDuration(TimeDelta duration) {
329 DCHECK(IsRunning()); 331 DCHECK(IsRunning());
330 media_log_->AddEvent( 332 media_log_->AddEvent(
331 media_log_->CreateTimeEvent( 333 media_log_->CreateTimeEvent(
332 MediaLogEvent::DURATION_SET, "duration", duration)); 334 MediaLogEvent::DURATION_SET, "duration", duration));
333 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); 335 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration);
334 336
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 748
747 SetState(kSeeking); 749 SetState(kSeeking);
748 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime()); 750 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime());
749 seek_cb_ = seek_cb; 751 seek_cb_ = seek_cb;
750 audio_ended_ = false; 752 audio_ended_ = false;
751 video_ended_ = false; 753 video_ended_ = false;
752 text_ended_ = false; 754 text_ended_ = false;
753 755
754 // Kick off seeking! 756 // Kick off seeking!
755 { 757 {
756 if (audio_renderer_)
757 audio_renderer_->StopRendering();
758
759 base::AutoLock auto_lock(lock_); 758 base::AutoLock auto_lock(lock_);
760 if (clock_->IsPlaying()) 759 PauseClockAndStopRendering_Locked();
761 clock_->Pause();
762 clock_->SetTime(seek_timestamp, seek_timestamp); 760 clock_->SetTime(seek_timestamp, seek_timestamp);
763 } 761 }
764 DoSeek(seek_timestamp, base::Bind( 762 DoSeek(seek_timestamp, base::Bind(
765 &Pipeline::OnStateTransition, base::Unretained(this))); 763 &Pipeline::OnStateTransition, base::Unretained(this)));
766 } 764 }
767 765
768 void Pipeline::DoAudioRendererEnded() { 766 void Pipeline::DoAudioRendererEnded() {
769 DCHECK(task_runner_->BelongsToCurrentThread()); 767 DCHECK(task_runner_->BelongsToCurrentThread());
770 768
771 if (state_ != kPlaying) 769 if (state_ != kPlaying)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 return; 813 return;
816 814
817 if (video_renderer_ && !video_ended_) 815 if (video_renderer_ && !video_ended_)
818 return; 816 return;
819 817
820 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_) 818 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_)
821 return; 819 return;
822 820
823 { 821 {
824 base::AutoLock auto_lock(lock_); 822 base::AutoLock auto_lock(lock_);
825 clock_->EndOfStream(); 823 PauseClockAndStopRendering_Locked();
824 clock_->SetTime(clock_->Duration(), clock_->Duration());
826 } 825 }
827 826
828 DCHECK_EQ(status_, PIPELINE_OK); 827 DCHECK_EQ(status_, PIPELINE_OK);
829 ended_cb_.Run(); 828 ended_cb_.Run();
830 } 829 }
831 830
832 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream, 831 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream,
833 const TextTrackConfig& config) { 832 const TextTrackConfig& config) {
834 DCHECK(task_runner_->BelongsToCurrentThread()); 833 DCHECK(task_runner_->BelongsToCurrentThread());
835 // TODO(matthewjheaney): fix up text_ended_ when text stream 834 // TODO(matthewjheaney): fix up text_ended_ when text stream
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) 923 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH)
925 return true; 924 return true;
926 return false; 925 return false;
927 } 926 }
928 927
929 void Pipeline::StartWaitingForEnoughData() { 928 void Pipeline::StartWaitingForEnoughData() {
930 DVLOG(1) << __FUNCTION__; 929 DVLOG(1) << __FUNCTION__;
931 DCHECK_EQ(state_, kPlaying); 930 DCHECK_EQ(state_, kPlaying);
932 DCHECK(WaitingForEnoughData()); 931 DCHECK(WaitingForEnoughData());
933 932
934 if (audio_renderer_)
935 audio_renderer_->StopRendering();
936
937 base::AutoLock auto_lock(lock_); 933 base::AutoLock auto_lock(lock_);
938 clock_->Pause(); 934 PauseClockAndStopRendering_Locked();
939 } 935 }
940 936
941 void Pipeline::StartPlayback() { 937 void Pipeline::StartPlayback() {
942 DVLOG(1) << __FUNCTION__; 938 DVLOG(1) << __FUNCTION__;
943 DCHECK_EQ(state_, kPlaying); 939 DCHECK_EQ(state_, kPlaying);
940 DCHECK_EQ(clock_state_, CLOCK_PAUSED);
944 DCHECK(!WaitingForEnoughData()); 941 DCHECK(!WaitingForEnoughData());
945 942
946 if (audio_renderer_) { 943 if (audio_renderer_) {
947 // We use audio stream to update the clock. So if there is such a 944 // We use audio stream to update the clock. So if there is such a
948 // stream, we pause the clock until we receive a valid timestamp. 945 // stream, we pause the clock until we receive a valid timestamp.
949 base::AutoLock auto_lock(lock_); 946 base::AutoLock auto_lock(lock_);
950 waiting_for_clock_update_ = true; 947 clock_state_ = CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE;
951 audio_renderer_->StartRendering(); 948 audio_renderer_->StartRendering();
952 } else { 949 } else {
953 base::AutoLock auto_lock(lock_); 950 base::AutoLock auto_lock(lock_);
954 DCHECK(!waiting_for_clock_update_); 951 clock_state_ = CLOCK_PLAYING;
955 clock_->SetMaxTime(clock_->Duration()); 952 clock_->SetMaxTime(clock_->Duration());
956 clock_->Play(); 953 clock_->Play();
957 } 954 }
958 955
959 preroll_completed_cb_.Run(); 956 preroll_completed_cb_.Run();
960 if (!seek_cb_.is_null()) 957 if (!seek_cb_.is_null())
961 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 958 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
962 } 959 }
963 960
961 void Pipeline::PauseClockAndStopRendering_Locked() {
962 lock_.AssertAcquired();
963 switch (clock_state_) {
964 case CLOCK_PAUSED:
965 return;
966
967 case CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE:
968 audio_renderer_->StopRendering();
969 break;
970
971 case CLOCK_PLAYING:
972 if (audio_renderer_)
973 audio_renderer_->StopRendering();
974 clock_->Pause();
975 break;
976 }
977
978 clock_state_ = CLOCK_PAUSED;
979 }
980
964 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 981 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
965 lock_.AssertAcquired(); 982 lock_.AssertAcquired();
966 if (!waiting_for_clock_update_) 983 if (clock_state_ != CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE)
967 return; 984 return;
968 985
969 waiting_for_clock_update_ = false; 986 clock_state_ = CLOCK_PLAYING;
970 clock_->Play(); 987 clock_->Play();
971 } 988 }
972 989
973 } // namespace media 990 } // 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