OLD | NEW |
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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } | 190 } |
191 | 191 |
192 void Pipeline::SetState(State next_state) { | 192 void Pipeline::SetState(State next_state) { |
193 if (state_ != kPlaying && next_state == kPlaying && | 193 if (state_ != kPlaying && next_state == kPlaying && |
194 !creation_time_.is_null()) { | 194 !creation_time_.is_null()) { |
195 UMA_HISTOGRAM_TIMES("Media.TimeToPipelineStarted", | 195 UMA_HISTOGRAM_TIMES("Media.TimeToPipelineStarted", |
196 default_tick_clock_.NowTicks() - creation_time_); | 196 default_tick_clock_.NowTicks() - creation_time_); |
197 creation_time_ = base::TimeTicks(); | 197 creation_time_ = base::TimeTicks(); |
198 } | 198 } |
199 | 199 |
200 DVLOG(2) << GetStateString(state_) << " -> " << GetStateString(next_state); | 200 DVLOG(1) << GetStateString(state_) << " -> " << GetStateString(next_state); |
201 | 201 |
202 state_ = next_state; | 202 state_ = next_state; |
203 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); | 203 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); |
204 } | 204 } |
205 | 205 |
206 #define RETURN_STRING(state) case state: return #state; | 206 #define RETURN_STRING(state) case state: return #state; |
207 | 207 |
208 const char* Pipeline::GetStateString(State state) { | 208 const char* Pipeline::GetStateString(State state) { |
209 switch (state) { | 209 switch (state) { |
210 RETURN_STRING(kCreated); | 210 RETURN_STRING(kCreated); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 } | 476 } |
477 | 477 |
478 void Pipeline::DoSeek( | 478 void Pipeline::DoSeek( |
479 base::TimeDelta seek_timestamp, | 479 base::TimeDelta seek_timestamp, |
480 const PipelineStatusCB& done_cb) { | 480 const PipelineStatusCB& done_cb) { |
481 DCHECK(task_runner_->BelongsToCurrentThread()); | 481 DCHECK(task_runner_->BelongsToCurrentThread()); |
482 DCHECK(!pending_callbacks_.get()); | 482 DCHECK(!pending_callbacks_.get()); |
483 SerialRunner::Queue bound_fns; | 483 SerialRunner::Queue bound_fns; |
484 | 484 |
485 // Pause. | 485 // Pause. |
486 if (audio_renderer_) { | |
487 bound_fns.Push(base::Bind( | |
488 &AudioRenderer::Pause, base::Unretained(audio_renderer_.get()))); | |
489 } | |
490 if (text_renderer_) { | 486 if (text_renderer_) { |
491 bound_fns.Push(base::Bind( | 487 bound_fns.Push(base::Bind( |
492 &TextRenderer::Pause, base::Unretained(text_renderer_.get()))); | 488 &TextRenderer::Pause, base::Unretained(text_renderer_.get()))); |
493 } | 489 } |
494 | 490 |
495 // Flush. | 491 // Flush. |
496 if (audio_renderer_) { | 492 if (audio_renderer_) { |
497 bound_fns.Push(base::Bind( | 493 bound_fns.Push(base::Bind( |
498 &AudioRenderer::Flush, base::Unretained(audio_renderer_.get()))); | 494 &AudioRenderer::Flush, base::Unretained(audio_renderer_.get()))); |
499 | 495 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 | 746 |
751 SetState(kSeeking); | 747 SetState(kSeeking); |
752 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime()); | 748 base::TimeDelta seek_timestamp = std::max(time, demuxer_->GetStartTime()); |
753 seek_cb_ = seek_cb; | 749 seek_cb_ = seek_cb; |
754 audio_ended_ = false; | 750 audio_ended_ = false; |
755 video_ended_ = false; | 751 video_ended_ = false; |
756 text_ended_ = false; | 752 text_ended_ = false; |
757 | 753 |
758 // Kick off seeking! | 754 // Kick off seeking! |
759 { | 755 { |
| 756 if (audio_renderer_) |
| 757 audio_renderer_->StopRendering(); |
| 758 |
760 base::AutoLock auto_lock(lock_); | 759 base::AutoLock auto_lock(lock_); |
761 if (clock_->IsPlaying()) | 760 if (clock_->IsPlaying()) |
762 clock_->Pause(); | 761 clock_->Pause(); |
763 clock_->SetTime(seek_timestamp, seek_timestamp); | 762 clock_->SetTime(seek_timestamp, seek_timestamp); |
764 } | 763 } |
765 DoSeek(seek_timestamp, base::Bind( | 764 DoSeek(seek_timestamp, base::Bind( |
766 &Pipeline::OnStateTransition, base::Unretained(this))); | 765 &Pipeline::OnStateTransition, base::Unretained(this))); |
767 } | 766 } |
768 | 767 |
769 void Pipeline::DoAudioRendererEnded() { | 768 void Pipeline::DoAudioRendererEnded() { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 if (state_ != kPlaying) | 920 if (state_ != kPlaying) |
922 return false; | 921 return false; |
923 if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH) | 922 if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH) |
924 return true; | 923 return true; |
925 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) | 924 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) |
926 return true; | 925 return true; |
927 return false; | 926 return false; |
928 } | 927 } |
929 | 928 |
930 void Pipeline::StartWaitingForEnoughData() { | 929 void Pipeline::StartWaitingForEnoughData() { |
| 930 DVLOG(1) << __FUNCTION__; |
931 DCHECK_EQ(state_, kPlaying); | 931 DCHECK_EQ(state_, kPlaying); |
932 DCHECK(WaitingForEnoughData()); | 932 DCHECK(WaitingForEnoughData()); |
933 | 933 |
934 if (audio_renderer_) | 934 if (audio_renderer_) |
935 audio_renderer_->Pause(); | 935 audio_renderer_->StopRendering(); |
936 | 936 |
937 base::AutoLock auto_lock(lock_); | 937 base::AutoLock auto_lock(lock_); |
938 clock_->Pause(); | 938 clock_->Pause(); |
939 } | 939 } |
940 | 940 |
941 void Pipeline::StartPlayback() { | 941 void Pipeline::StartPlayback() { |
| 942 DVLOG(1) << __FUNCTION__; |
942 DCHECK_EQ(state_, kPlaying); | 943 DCHECK_EQ(state_, kPlaying); |
943 DCHECK(!WaitingForEnoughData()); | 944 DCHECK(!WaitingForEnoughData()); |
944 | 945 |
945 if (audio_renderer_) { | 946 if (audio_renderer_) { |
946 audio_renderer_->Play(); | |
947 | |
948 base::AutoLock auto_lock(lock_); | |
949 // We use audio stream to update the clock. So if there is such a | 947 // We use audio stream to update the clock. So if there is such a |
950 // stream, we pause the clock until we receive a valid timestamp. | 948 // stream, we pause the clock until we receive a valid timestamp. |
| 949 base::AutoLock auto_lock(lock_); |
951 waiting_for_clock_update_ = true; | 950 waiting_for_clock_update_ = true; |
| 951 audio_renderer_->StartRendering(); |
952 } else { | 952 } else { |
953 base::AutoLock auto_lock(lock_); | 953 base::AutoLock auto_lock(lock_); |
| 954 DCHECK(!waiting_for_clock_update_); |
954 clock_->SetMaxTime(clock_->Duration()); | 955 clock_->SetMaxTime(clock_->Duration()); |
955 clock_->Play(); | 956 clock_->Play(); |
956 } | 957 } |
957 | 958 |
958 preroll_completed_cb_.Run(); | 959 preroll_completed_cb_.Run(); |
959 if (!seek_cb_.is_null()) | 960 if (!seek_cb_.is_null()) |
960 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 961 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
961 } | 962 } |
962 | 963 |
963 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 964 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
964 lock_.AssertAcquired(); | 965 lock_.AssertAcquired(); |
965 if (!waiting_for_clock_update_) | 966 if (!waiting_for_clock_update_) |
966 return; | 967 return; |
967 | 968 |
968 waiting_for_clock_update_ = false; | 969 waiting_for_clock_update_ = false; |
969 clock_->Play(); | 970 clock_->Play(); |
970 } | 971 } |
971 | 972 |
972 } // namespace media | 973 } // namespace media |
OLD | NEW |