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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 207 } |
208 } | 208 } |
209 | 209 |
210 base::TimeDelta Pipeline::GetCurrentTime() const { | 210 base::TimeDelta Pipeline::GetCurrentTime() const { |
211 base::AutoLock auto_lock(lock_); | 211 base::AutoLock auto_lock(lock_); |
212 return GetCurrentTime_Locked(); | 212 return GetCurrentTime_Locked(); |
213 } | 213 } |
214 | 214 |
215 base::TimeDelta Pipeline::GetCurrentTime_Locked() const { | 215 base::TimeDelta Pipeline::GetCurrentTime_Locked() const { |
216 lock_.AssertAcquired(); | 216 lock_.AssertAcquired(); |
217 base::TimeDelta elapsed = clock_->Elapsed(); | 217 return clock_->Elapsed(); |
218 if (elapsed > duration_) | |
219 return duration_; | |
220 | |
221 return elapsed; | |
222 } | 218 } |
223 | 219 |
224 base::TimeDelta Pipeline::GetBufferedTime() { | 220 base::TimeDelta Pipeline::GetBufferedTime() { |
225 base::AutoLock auto_lock(lock_); | 221 base::AutoLock auto_lock(lock_); |
226 | 222 |
227 // If media is fully loaded, then return duration. | 223 // If media is fully loaded, then return duration. |
228 if (local_source_ || total_bytes_ == buffered_bytes_) { | 224 if (local_source_ || total_bytes_ == buffered_bytes_) { |
229 max_buffered_time_ = duration_; | 225 max_buffered_time_ = clock_->Duration(); |
230 return duration_; | 226 return max_buffered_time_; |
231 } | 227 } |
232 | 228 |
233 base::TimeDelta current_time = GetCurrentTime_Locked(); | 229 base::TimeDelta current_time = GetCurrentTime_Locked(); |
234 | 230 |
235 // If buffered time was set, we report that value directly. | 231 // If buffered time was set, we report that value directly. |
236 if (buffered_time_.ToInternalValue() > 0) | 232 if (buffered_time_.ToInternalValue() > 0) |
237 return std::max(buffered_time_, current_time); | 233 return std::max(buffered_time_, current_time); |
238 | 234 |
239 if (total_bytes_ == 0) | 235 if (total_bytes_ == 0) |
240 return base::TimeDelta(); | 236 return base::TimeDelta(); |
241 | 237 |
242 // If buffered time was not set, we use current time, current bytes, and | 238 // If buffered time was not set, we use current time, current bytes, and |
243 // buffered bytes to estimate the buffered time. | 239 // buffered bytes to estimate the buffered time. |
244 double estimated_rate = duration_.InMillisecondsF() / total_bytes_; | 240 double estimated_rate = |
| 241 clock_->Duration().InMillisecondsF() / total_bytes_; |
245 double estimated_current_time = estimated_rate * current_bytes_; | 242 double estimated_current_time = estimated_rate * current_bytes_; |
246 DCHECK_GE(buffered_bytes_, current_bytes_); | 243 DCHECK_GE(buffered_bytes_, current_bytes_); |
247 base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds( | 244 base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds( |
248 static_cast<int64>(estimated_rate * (buffered_bytes_ - current_bytes_) + | 245 static_cast<int64>(estimated_rate * (buffered_bytes_ - current_bytes_) + |
249 estimated_current_time)); | 246 estimated_current_time)); |
250 | 247 |
251 // Cap approximated buffered time at the length of the video. | 248 // Cap approximated buffered time at the length of the video. |
252 buffered_time = std::min(buffered_time, duration_); | 249 buffered_time = std::min(buffered_time, clock_->Duration()); |
253 | 250 |
254 // Make sure buffered_time is at least the current time | 251 // Make sure buffered_time is at least the current time |
255 buffered_time = std::max(buffered_time, current_time); | 252 buffered_time = std::max(buffered_time, current_time); |
256 | 253 |
257 // Only print the max buffered time for smooth buffering. | 254 // Only print the max buffered time for smooth buffering. |
258 max_buffered_time_ = std::max(buffered_time, max_buffered_time_); | 255 max_buffered_time_ = std::max(buffered_time, max_buffered_time_); |
259 | 256 |
260 return max_buffered_time_; | 257 return max_buffered_time_; |
261 } | 258 } |
262 | 259 |
263 base::TimeDelta Pipeline::GetMediaDuration() const { | 260 base::TimeDelta Pipeline::GetMediaDuration() const { |
264 base::AutoLock auto_lock(lock_); | 261 base::AutoLock auto_lock(lock_); |
265 return duration_; | 262 return clock_->Duration(); |
266 } | 263 } |
267 | 264 |
268 int64 Pipeline::GetBufferedBytes() const { | 265 int64 Pipeline::GetBufferedBytes() const { |
269 base::AutoLock auto_lock(lock_); | 266 base::AutoLock auto_lock(lock_); |
270 return buffered_bytes_; | 267 return buffered_bytes_; |
271 } | 268 } |
272 | 269 |
273 int64 Pipeline::GetTotalBytes() const { | 270 int64 Pipeline::GetTotalBytes() const { |
274 base::AutoLock auto_lock(lock_); | 271 base::AutoLock auto_lock(lock_); |
275 return total_bytes_; | 272 return total_bytes_; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 | 313 |
317 void Pipeline::ResetState() { | 314 void Pipeline::ResetState() { |
318 base::AutoLock auto_lock(lock_); | 315 base::AutoLock auto_lock(lock_); |
319 const base::TimeDelta kZero; | 316 const base::TimeDelta kZero; |
320 running_ = false; | 317 running_ = false; |
321 stop_pending_ = false; | 318 stop_pending_ = false; |
322 seek_pending_ = false; | 319 seek_pending_ = false; |
323 tearing_down_ = false; | 320 tearing_down_ = false; |
324 error_caused_teardown_ = false; | 321 error_caused_teardown_ = false; |
325 playback_rate_change_pending_ = false; | 322 playback_rate_change_pending_ = false; |
326 duration_ = kZero; | |
327 buffered_time_ = kZero; | 323 buffered_time_ = kZero; |
328 buffered_bytes_ = 0; | 324 buffered_bytes_ = 0; |
329 streaming_ = false; | 325 streaming_ = false; |
330 local_source_ = false; | 326 local_source_ = false; |
331 total_bytes_ = 0; | 327 total_bytes_ = 0; |
332 natural_size_.SetSize(0, 0); | 328 natural_size_.SetSize(0, 0); |
333 volume_ = 1.0f; | 329 volume_ = 1.0f; |
334 preload_ = AUTO; | 330 preload_ = AUTO; |
335 playback_rate_ = 0.0f; | 331 playback_rate_ = 0.0f; |
336 pending_playback_rate_ = 0.0f; | 332 pending_playback_rate_ = 0.0f; |
337 status_ = PIPELINE_OK; | 333 status_ = PIPELINE_OK; |
338 has_audio_ = false; | 334 has_audio_ = false; |
339 has_video_ = false; | 335 has_video_ = false; |
340 waiting_for_clock_update_ = false; | 336 waiting_for_clock_update_ = false; |
341 audio_disabled_ = false; | 337 audio_disabled_ = false; |
342 clock_->SetTime(kZero); | 338 clock_->Reset(); |
343 download_rate_monitor_.Reset(); | 339 download_rate_monitor_.Reset(); |
344 } | 340 } |
345 | 341 |
346 void Pipeline::SetState(State next_state) { | 342 void Pipeline::SetState(State next_state) { |
347 if (state_ != kStarted && next_state == kStarted && | 343 if (state_ != kStarted && next_state == kStarted && |
348 !creation_time_.is_null()) { | 344 !creation_time_.is_null()) { |
349 UMA_HISTOGRAM_TIMES( | 345 UMA_HISTOGRAM_TIMES( |
350 "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); | 346 "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); |
351 creation_time_ = base::Time(); | 347 creation_time_ = base::Time(); |
352 } | 348 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 base::TimeDelta Pipeline::GetTime() const { | 440 base::TimeDelta Pipeline::GetTime() const { |
445 DCHECK(IsRunning()); | 441 DCHECK(IsRunning()); |
446 return GetCurrentTime(); | 442 return GetCurrentTime(); |
447 } | 443 } |
448 | 444 |
449 base::TimeDelta Pipeline::GetDuration() const { | 445 base::TimeDelta Pipeline::GetDuration() const { |
450 DCHECK(IsRunning()); | 446 DCHECK(IsRunning()); |
451 return GetMediaDuration(); | 447 return GetMediaDuration(); |
452 } | 448 } |
453 | 449 |
454 void Pipeline::SetTime(base::TimeDelta time) { | 450 void Pipeline::OnAudioTimeUpdate(base::TimeDelta time, |
| 451 base::TimeDelta max_time) { |
| 452 DCHECK(time <= max_time); |
455 DCHECK(IsRunning()); | 453 DCHECK(IsRunning()); |
456 base::AutoLock auto_lock(lock_); | 454 base::AutoLock auto_lock(lock_); |
457 | 455 |
458 // If we were waiting for a valid timestamp and such timestamp arrives, we | 456 if (!has_audio_) |
459 // need to clear the flag for waiting and start the clock. | |
460 if (waiting_for_clock_update_) { | |
461 if (time < clock_->Elapsed()) | |
462 return; | |
463 clock_->SetTime(time); | |
464 StartClockIfWaitingForTimeUpdate_Locked(); | |
465 return; | 457 return; |
466 } | 458 if (waiting_for_clock_update_ && time < clock_->Elapsed()) |
467 clock_->SetTime(time); | 459 return; |
| 460 |
| 461 clock_->SetTime(time, max_time); |
| 462 StartClockIfWaitingForTimeUpdate_Locked(); |
| 463 } |
| 464 |
| 465 void Pipeline::OnVideoTimeUpdate(base::TimeDelta max_time) { |
| 466 DCHECK(IsRunning()); |
| 467 base::AutoLock auto_lock(lock_); |
| 468 |
| 469 if (has_audio_) |
| 470 return; |
| 471 |
| 472 DCHECK(!waiting_for_clock_update_); |
| 473 DCHECK(clock_->Elapsed() <= max_time); |
| 474 clock_->SetMaxTime(max_time); |
468 } | 475 } |
469 | 476 |
470 void Pipeline::SetDuration(base::TimeDelta duration) { | 477 void Pipeline::SetDuration(base::TimeDelta duration) { |
471 DCHECK(IsRunning()); | 478 DCHECK(IsRunning()); |
472 media_log_->AddEvent( | 479 media_log_->AddEvent( |
473 media_log_->CreateTimeEvent( | 480 media_log_->CreateTimeEvent( |
474 MediaLogEvent::DURATION_SET, "duration", duration)); | 481 MediaLogEvent::DURATION_SET, "duration", duration)); |
475 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); | 482 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); |
476 | 483 |
477 base::AutoLock auto_lock(lock_); | 484 base::AutoLock auto_lock(lock_); |
478 duration_ = duration; | 485 clock_->SetDuration(duration); |
479 } | 486 } |
480 | 487 |
481 void Pipeline::SetBufferedTime(base::TimeDelta buffered_time) { | 488 void Pipeline::SetBufferedTime(base::TimeDelta buffered_time) { |
482 DCHECK(IsRunning()); | 489 DCHECK(IsRunning()); |
483 base::AutoLock auto_lock(lock_); | 490 base::AutoLock auto_lock(lock_); |
484 buffered_time_ = buffered_time; | 491 buffered_time_ = buffered_time; |
485 } | 492 } |
486 | 493 |
487 void Pipeline::SetTotalBytes(int64 total_bytes) { | 494 void Pipeline::SetTotalBytes(int64 total_bytes) { |
488 DCHECK(IsRunning()); | 495 DCHECK(IsRunning()); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 | 903 |
897 // Make sure every extant renderer has ended. | 904 // Make sure every extant renderer has ended. |
898 if (audio_renderer_ && !audio_disabled_) { | 905 if (audio_renderer_ && !audio_disabled_) { |
899 if (!audio_renderer_->HasEnded()) { | 906 if (!audio_renderer_->HasEnded()) { |
900 return; | 907 return; |
901 } | 908 } |
902 | 909 |
903 // Start clock since there is no more audio to | 910 // Start clock since there is no more audio to |
904 // trigger clock updates. | 911 // trigger clock updates. |
905 base::AutoLock auto_lock(lock_); | 912 base::AutoLock auto_lock(lock_); |
| 913 clock_->SetMaxTime(clock_->Duration()); |
906 StartClockIfWaitingForTimeUpdate_Locked(); | 914 StartClockIfWaitingForTimeUpdate_Locked(); |
907 } | 915 } |
908 | 916 |
909 if (video_renderer_ && !video_renderer_->HasEnded()) { | 917 if (video_renderer_ && !video_renderer_->HasEnded()) { |
910 return; | 918 return; |
911 } | 919 } |
912 | 920 |
913 // Transition to ended, executing the callback if present. | 921 // Transition to ended, executing the callback if present. |
914 SetState(kEnded); | 922 SetState(kEnded); |
915 { | 923 { |
916 base::AutoLock auto_lock(lock_); | 924 base::AutoLock auto_lock(lock_); |
917 clock_->Pause(); | 925 clock_->EndOfStream(); |
918 clock_->SetTime(duration_); | |
919 } | 926 } |
920 | 927 |
921 if (!ended_callback_.is_null()) { | 928 if (!ended_callback_.is_null()) { |
922 ended_callback_.Run(status_); | 929 ended_callback_.Run(status_); |
923 } | 930 } |
924 } | 931 } |
925 | 932 |
926 void Pipeline::NotifyNetworkEventTask(NetworkEvent type) { | 933 void Pipeline::NotifyNetworkEventTask(NetworkEvent type) { |
927 DCHECK_EQ(MessageLoop::current(), message_loop_); | 934 DCHECK_EQ(MessageLoop::current(), message_loop_); |
928 if (!network_callback_.is_null()) | 935 if (!network_callback_.is_null()) |
(...skipping 11 matching lines...) Expand all Loading... |
940 // initialized yet, OnAudioRendererDisabled() will be called when | 947 // initialized yet, OnAudioRendererDisabled() will be called when |
941 // initialization is complete. | 948 // initialization is complete. |
942 if (pipeline_filter_) { | 949 if (pipeline_filter_) { |
943 DCHECK(demuxer_); | 950 DCHECK(demuxer_); |
944 demuxer_->OnAudioRendererDisabled(); | 951 demuxer_->OnAudioRendererDisabled(); |
945 pipeline_filter_->OnAudioRendererDisabled(); | 952 pipeline_filter_->OnAudioRendererDisabled(); |
946 } | 953 } |
947 | 954 |
948 // Start clock since there is no more audio to | 955 // Start clock since there is no more audio to |
949 // trigger clock updates. | 956 // trigger clock updates. |
| 957 clock_->SetMaxTime(clock_->Duration()); |
950 StartClockIfWaitingForTimeUpdate_Locked(); | 958 StartClockIfWaitingForTimeUpdate_Locked(); |
951 } | 959 } |
952 | 960 |
953 void Pipeline::FilterStateTransitionTask() { | 961 void Pipeline::FilterStateTransitionTask() { |
954 DCHECK_EQ(MessageLoop::current(), message_loop_); | 962 DCHECK_EQ(MessageLoop::current(), message_loop_); |
955 | 963 |
956 // No reason transitioning if we've errored or have stopped. | 964 // No reason transitioning if we've errored or have stopped. |
957 if (IsPipelineStopped()) { | 965 if (IsPipelineStopped()) { |
958 return; | 966 return; |
959 } | 967 } |
960 | 968 |
961 // If we are tearing down, don't allow any state changes. Teardown | 969 // If we are tearing down, don't allow any state changes. Teardown |
962 // state changes will come in via TeardownStateTransitionTask(). | 970 // state changes will come in via TeardownStateTransitionTask(). |
963 if (IsPipelineTearingDown()) { | 971 if (IsPipelineTearingDown()) { |
964 return; | 972 return; |
965 } | 973 } |
966 | 974 |
967 if (!TransientState(state_)) { | 975 if (!TransientState(state_)) { |
968 NOTREACHED() << "Invalid current state: " << state_; | 976 NOTREACHED() << "Invalid current state: " << state_; |
969 SetError(PIPELINE_ERROR_ABORT); | 977 SetError(PIPELINE_ERROR_ABORT); |
970 return; | 978 return; |
971 } | 979 } |
972 | 980 |
973 // Decrement the number of remaining transitions, making sure to transition | 981 // Decrement the number of remaining transitions, making sure to transition |
974 // to the next state if needed. | 982 // to the next state if needed. |
975 SetState(FindNextState(state_)); | 983 SetState(FindNextState(state_)); |
976 if (state_ == kSeeking) { | 984 if (state_ == kSeeking) { |
977 base::AutoLock auto_lock(lock_); | 985 base::AutoLock auto_lock(lock_); |
978 clock_->SetTime(seek_timestamp_); | 986 clock_->SetTime(seek_timestamp_, seek_timestamp_); |
979 } | 987 } |
980 | 988 |
981 // Carry out the action for the current state. | 989 // Carry out the action for the current state. |
982 if (TransientState(state_)) { | 990 if (TransientState(state_)) { |
983 if (state_ == kPausing) { | 991 if (state_ == kPausing) { |
984 pipeline_filter_->Pause( | 992 pipeline_filter_->Pause( |
985 base::Bind(&Pipeline::OnFilterStateTransition, this)); | 993 base::Bind(&Pipeline::OnFilterStateTransition, this)); |
986 } else if (state_ == kFlushing) { | 994 } else if (state_ == kFlushing) { |
987 pipeline_filter_->Flush( | 995 pipeline_filter_->Flush( |
988 base::Bind(&Pipeline::OnFilterStateTransition, this)); | 996 base::Bind(&Pipeline::OnFilterStateTransition, this)); |
(...skipping 18 matching lines...) Expand all Loading... |
1007 // the seek has compelted. | 1015 // the seek has compelted. |
1008 if (playback_rate_change_pending_) { | 1016 if (playback_rate_change_pending_) { |
1009 playback_rate_change_pending_ = false; | 1017 playback_rate_change_pending_ = false; |
1010 PlaybackRateChangedTask(pending_playback_rate_); | 1018 PlaybackRateChangedTask(pending_playback_rate_); |
1011 } | 1019 } |
1012 | 1020 |
1013 base::AutoLock auto_lock(lock_); | 1021 base::AutoLock auto_lock(lock_); |
1014 // We use audio stream to update the clock. So if there is such a stream, | 1022 // We use audio stream to update the clock. So if there is such a stream, |
1015 // we pause the clock until we receive a valid timestamp. | 1023 // we pause the clock until we receive a valid timestamp. |
1016 waiting_for_clock_update_ = true; | 1024 waiting_for_clock_update_ = true; |
1017 if (!has_audio_) | 1025 if (!has_audio_) { |
| 1026 clock_->SetMaxTime(clock_->Duration()); |
1018 StartClockIfWaitingForTimeUpdate_Locked(); | 1027 StartClockIfWaitingForTimeUpdate_Locked(); |
| 1028 } |
1019 | 1029 |
1020 // Start monitoring rate of downloading. | 1030 // Start monitoring rate of downloading. |
1021 int bitrate = 0; | 1031 int bitrate = 0; |
1022 if (demuxer_.get()) { | 1032 if (demuxer_.get()) { |
1023 bitrate = demuxer_->GetBitrate(); | 1033 bitrate = demuxer_->GetBitrate(); |
1024 local_source_ = demuxer_->IsLocalSource(); | 1034 local_source_ = demuxer_->IsLocalSource(); |
1025 streaming_ = !demuxer_->IsSeekable(); | 1035 streaming_ = !demuxer_->IsSeekable(); |
1026 } | 1036 } |
1027 // Needs to be locked because most other calls to |download_rate_monitor_| | 1037 // Needs to be locked because most other calls to |download_rate_monitor_| |
1028 // occur on the renderer thread. | 1038 // occur on the renderer thread. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 return; | 1147 return; |
1138 } | 1148 } |
1139 | 1149 |
1140 demuxer_ = demuxer; | 1150 demuxer_ = demuxer; |
1141 demuxer_->set_host(this); | 1151 demuxer_->set_host(this); |
1142 | 1152 |
1143 { | 1153 { |
1144 base::AutoLock auto_lock(lock_); | 1154 base::AutoLock auto_lock(lock_); |
1145 // We do not want to start the clock running. We only want to set the base | 1155 // We do not want to start the clock running. We only want to set the base |
1146 // media time so our timestamp calculations will be correct. | 1156 // media time so our timestamp calculations will be correct. |
1147 clock_->SetTime(demuxer_->GetStartTime()); | 1157 clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime()); |
1148 } | 1158 } |
1149 | 1159 |
1150 OnFilterInitialize(PIPELINE_OK); | 1160 OnFilterInitialize(PIPELINE_OK); |
1151 } | 1161 } |
1152 | 1162 |
1153 bool Pipeline::InitializeAudioDecoder( | 1163 bool Pipeline::InitializeAudioDecoder( |
1154 const scoped_refptr<Demuxer>& demuxer) { | 1164 const scoped_refptr<Demuxer>& demuxer) { |
1155 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1165 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1156 DCHECK(IsPipelineOk()); | 1166 DCHECK(IsPipelineOk()); |
1157 | 1167 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1235 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1226 return false; | 1236 return false; |
1227 } | 1237 } |
1228 | 1238 |
1229 if (!PrepareFilter(audio_renderer_)) | 1239 if (!PrepareFilter(audio_renderer_)) |
1230 return false; | 1240 return false; |
1231 | 1241 |
1232 audio_renderer_->Initialize( | 1242 audio_renderer_->Initialize( |
1233 decoder, | 1243 decoder, |
1234 base::Bind(&Pipeline::OnFilterInitialize, this), | 1244 base::Bind(&Pipeline::OnFilterInitialize, this), |
1235 base::Bind(&Pipeline::OnAudioUnderflow, this)); | 1245 base::Bind(&Pipeline::OnAudioUnderflow, this), |
| 1246 base::Bind(&Pipeline::OnAudioTimeUpdate, this)); |
| 1247 |
1236 return true; | 1248 return true; |
1237 } | 1249 } |
1238 | 1250 |
1239 bool Pipeline::InitializeVideoRenderer( | 1251 bool Pipeline::InitializeVideoRenderer( |
1240 const scoped_refptr<VideoDecoder>& decoder) { | 1252 const scoped_refptr<VideoDecoder>& decoder) { |
1241 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1253 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1242 DCHECK(IsPipelineOk()); | 1254 DCHECK(IsPipelineOk()); |
1243 | 1255 |
1244 if (!decoder) | 1256 if (!decoder) |
1245 return false; | 1257 return false; |
1246 | 1258 |
1247 filter_collection_->SelectVideoRenderer(&video_renderer_); | 1259 filter_collection_->SelectVideoRenderer(&video_renderer_); |
1248 if (!video_renderer_) { | 1260 if (!video_renderer_) { |
1249 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1261 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1250 return false; | 1262 return false; |
1251 } | 1263 } |
1252 | 1264 |
1253 if (!PrepareFilter(video_renderer_)) | 1265 if (!PrepareFilter(video_renderer_)) |
1254 return false; | 1266 return false; |
1255 | 1267 |
1256 video_renderer_->Initialize( | 1268 video_renderer_->Initialize( |
1257 decoder, | 1269 decoder, |
1258 base::Bind(&Pipeline::OnFilterInitialize, this), | 1270 base::Bind(&Pipeline::OnFilterInitialize, this), |
1259 base::Bind(&Pipeline::OnUpdateStatistics, this)); | 1271 base::Bind(&Pipeline::OnUpdateStatistics, this), |
| 1272 base::Bind(&Pipeline::OnVideoTimeUpdate, this)); |
1260 return true; | 1273 return true; |
1261 } | 1274 } |
1262 | 1275 |
1263 void Pipeline::TearDownPipeline() { | 1276 void Pipeline::TearDownPipeline() { |
1264 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1277 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1265 DCHECK_NE(kStopped, state_); | 1278 DCHECK_NE(kStopped, state_); |
1266 | 1279 |
1267 DCHECK(!tearing_down_ || // Teardown on Stop(). | 1280 DCHECK(!tearing_down_ || // Teardown on Stop(). |
1268 (tearing_down_ && error_caused_teardown_) || // Teardown on error. | 1281 (tearing_down_ && error_caused_teardown_) || // Teardown on error. |
1269 (tearing_down_ && stop_pending_)); // Stop during teardown by error. | 1282 (tearing_down_ && stop_pending_)); // Stop during teardown by error. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 1425 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
1413 lock_.AssertAcquired(); | 1426 lock_.AssertAcquired(); |
1414 if (!waiting_for_clock_update_) | 1427 if (!waiting_for_clock_update_) |
1415 return; | 1428 return; |
1416 | 1429 |
1417 waiting_for_clock_update_ = false; | 1430 waiting_for_clock_update_ = false; |
1418 clock_->Play(); | 1431 clock_->Play(); |
1419 } | 1432 } |
1420 | 1433 |
1421 } // namespace media | 1434 } // namespace media |
OLD | NEW |