| 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 |