Chromium Code Reviews| 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 27 matching lines...) Expand all Loading... | |
| 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 total_bytes_(0), | 42 total_bytes_(0), |
| 43 volume_(1.0f), | 43 volume_(1.0f), |
| 44 playback_rate_(0.0f), | 44 playback_rate_(0.0f), |
| 45 clock_(new Clock(&default_tick_clock_)), | 45 clock_(new Clock(&default_tick_clock_)), |
| 46 waiting_for_clock_update_(false), | 46 waiting_for_clock_update_(false), |
| 47 status_(PIPELINE_OK), | 47 status_(PIPELINE_OK), |
| 48 has_audio_(false), | |
| 49 has_video_(false), | |
| 50 state_(kCreated), | 48 state_(kCreated), |
| 49 initial_natural_size_(), | |
| 51 audio_ended_(false), | 50 audio_ended_(false), |
| 52 video_ended_(false), | 51 video_ended_(false), |
| 53 text_ended_(false), | 52 text_ended_(false), |
| 54 audio_disabled_(false), | 53 audio_disabled_(false), |
| 55 demuxer_(NULL), | 54 demuxer_(NULL), |
| 56 creation_time_(default_tick_clock_.NowTicks()) { | 55 creation_time_(default_tick_clock_.NowTicks()) { |
| 57 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); | 56 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); |
| 58 media_log_->AddEvent( | 57 media_log_->AddEvent( |
| 59 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); | 58 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); |
| 60 } | 59 } |
| 61 | 60 |
| 62 Pipeline::~Pipeline() { | 61 Pipeline::~Pipeline() { |
| 63 DCHECK(thread_checker_.CalledOnValidThread()) | 62 DCHECK(thread_checker_.CalledOnValidThread()) |
| 64 << "Pipeline must be destroyed on same thread that created it"; | 63 << "Pipeline must be destroyed on same thread that created it"; |
| 65 DCHECK(!running_) << "Stop() must complete before destroying object"; | 64 DCHECK(!running_) << "Stop() must complete before destroying object"; |
| 66 DCHECK(stop_cb_.is_null()); | 65 DCHECK(stop_cb_.is_null()); |
| 67 DCHECK(seek_cb_.is_null()); | 66 DCHECK(seek_cb_.is_null()); |
| 68 | 67 |
| 69 media_log_->AddEvent( | 68 media_log_->AddEvent( |
| 70 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); | 69 media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); |
| 71 } | 70 } |
| 72 | 71 |
| 73 void Pipeline::Start(scoped_ptr<FilterCollection> collection, | 72 void Pipeline::Start(scoped_ptr<FilterCollection> collection, |
| 74 const base::Closure& ended_cb, | 73 const base::Closure& ended_cb, |
| 75 const PipelineStatusCB& error_cb, | 74 const PipelineStatusCB& error_cb, |
| 76 const PipelineStatusCB& seek_cb, | 75 const PipelineStatusCB& seek_cb, |
| 77 const BufferingStateCB& buffering_state_cb, | 76 const HaveMetadataCB& have_metadata_cb, |
| 77 const base::Closure& preroll_completed_cb, | |
| 78 const base::Closure& duration_change_cb) { | 78 const base::Closure& duration_change_cb) { |
| 79 base::AutoLock auto_lock(lock_); | 79 base::AutoLock auto_lock(lock_); |
| 80 CHECK(!running_) << "Media pipeline is already running"; | 80 CHECK(!running_) << "Media pipeline is already running"; |
| 81 DCHECK(!buffering_state_cb.is_null()); | 81 running_ = true; |
| 82 | 82 |
| 83 running_ = true; | 83 filter_collection_ = collection.Pass(); |
| 84 task_runner_->PostTask(FROM_HERE, base::Bind( | 84 ended_cb_ = ended_cb; |
| 85 &Pipeline::StartTask, base::Unretained(this), base::Passed(&collection), | 85 error_cb_ = error_cb; |
| 86 ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb)); | 86 seek_cb_ = seek_cb; |
| 87 have_metadata_cb_ = have_metadata_cb; | |
| 88 preroll_completed_cb_ = preroll_completed_cb; | |
| 89 duration_change_cb_ = duration_change_cb; | |
| 90 | |
| 91 task_runner_->PostTask( | |
| 92 FROM_HERE, base::Bind(&Pipeline::StartTask, base::Unretained(this))); | |
| 87 } | 93 } |
| 88 | 94 |
| 89 void Pipeline::Stop(const base::Closure& stop_cb) { | 95 void Pipeline::Stop(const base::Closure& stop_cb) { |
| 90 base::AutoLock auto_lock(lock_); | 96 base::AutoLock auto_lock(lock_); |
| 91 task_runner_->PostTask(FROM_HERE, base::Bind( | 97 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 92 &Pipeline::StopTask, base::Unretained(this), stop_cb)); | 98 &Pipeline::StopTask, base::Unretained(this), stop_cb)); |
| 93 } | 99 } |
| 94 | 100 |
| 95 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { | 101 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { |
| 96 base::AutoLock auto_lock(lock_); | 102 base::AutoLock auto_lock(lock_); |
| 97 if (!running_) { | 103 if (!running_) { |
| 98 NOTREACHED() << "Media pipeline isn't running"; | 104 NOTREACHED() << "Media pipeline isn't running"; |
| 99 return; | 105 return; |
| 100 } | 106 } |
| 101 | 107 |
| 102 task_runner_->PostTask(FROM_HERE, base::Bind( | 108 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 103 &Pipeline::SeekTask, base::Unretained(this), time, seek_cb)); | 109 &Pipeline::SeekTask, base::Unretained(this), time, seek_cb)); |
| 104 } | 110 } |
| 105 | 111 |
| 106 bool Pipeline::IsRunning() const { | 112 bool Pipeline::IsRunning() const { |
| 107 base::AutoLock auto_lock(lock_); | 113 base::AutoLock auto_lock(lock_); |
| 108 return running_; | 114 return running_; |
| 109 } | 115 } |
| 110 | 116 |
| 111 bool Pipeline::HasAudio() const { | |
| 112 base::AutoLock auto_lock(lock_); | |
| 113 return has_audio_; | |
| 114 } | |
| 115 | |
| 116 bool Pipeline::HasVideo() const { | |
| 117 base::AutoLock auto_lock(lock_); | |
| 118 return has_video_; | |
| 119 } | |
| 120 | |
| 121 float Pipeline::GetPlaybackRate() const { | 117 float Pipeline::GetPlaybackRate() const { |
| 122 base::AutoLock auto_lock(lock_); | 118 base::AutoLock auto_lock(lock_); |
| 123 return playback_rate_; | 119 return playback_rate_; |
| 124 } | 120 } |
| 125 | 121 |
| 126 void Pipeline::SetPlaybackRate(float playback_rate) { | 122 void Pipeline::SetPlaybackRate(float playback_rate) { |
| 127 if (playback_rate < 0.0f) | 123 if (playback_rate < 0.0f) |
| 128 return; | 124 return; |
| 129 | 125 |
| 130 base::AutoLock auto_lock(lock_); | 126 base::AutoLock auto_lock(lock_); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 TimeDelta Pipeline::GetMediaDuration() const { | 177 TimeDelta Pipeline::GetMediaDuration() const { |
| 182 base::AutoLock auto_lock(lock_); | 178 base::AutoLock auto_lock(lock_); |
| 183 return clock_->Duration(); | 179 return clock_->Duration(); |
| 184 } | 180 } |
| 185 | 181 |
| 186 int64 Pipeline::GetTotalBytes() const { | 182 int64 Pipeline::GetTotalBytes() const { |
| 187 base::AutoLock auto_lock(lock_); | 183 base::AutoLock auto_lock(lock_); |
| 188 return total_bytes_; | 184 return total_bytes_; |
| 189 } | 185 } |
| 190 | 186 |
| 191 gfx::Size Pipeline::GetInitialNaturalSize() const { | |
| 192 base::AutoLock auto_lock(lock_); | |
| 193 return initial_natural_size_; | |
| 194 } | |
| 195 | |
| 196 bool Pipeline::DidLoadingProgress() const { | 187 bool Pipeline::DidLoadingProgress() const { |
| 197 base::AutoLock auto_lock(lock_); | 188 base::AutoLock auto_lock(lock_); |
| 198 bool ret = did_loading_progress_; | 189 bool ret = did_loading_progress_; |
| 199 did_loading_progress_ = false; | 190 did_loading_progress_ = false; |
| 200 return ret; | 191 return ret; |
| 201 } | 192 } |
| 202 | 193 |
| 203 PipelineStatistics Pipeline::GetStatistics() const { | 194 PipelineStatistics Pipeline::GetStatistics() const { |
| 204 base::AutoLock auto_lock(lock_); | 195 base::AutoLock auto_lock(lock_); |
| 205 return statistics_; | 196 return statistics_; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 &Pipeline::AudioDisabledTask, base::Unretained(this))); | 317 &Pipeline::AudioDisabledTask, base::Unretained(this))); |
| 327 media_log_->AddEvent( | 318 media_log_->AddEvent( |
| 328 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); | 319 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); |
| 329 } | 320 } |
| 330 | 321 |
| 331 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { | 322 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { |
| 332 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); | 323 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); |
| 333 DCHECK(IsRunning()); | 324 DCHECK(IsRunning()); |
| 334 base::AutoLock auto_lock(lock_); | 325 base::AutoLock auto_lock(lock_); |
| 335 | 326 |
| 336 if (!has_audio_) | 327 if (audio_renderer_ == NULL || audio_disabled_) |
|
scherkus (not reviewing)
2014/03/21 22:26:10
audio_renderer_ should never be NULL in this case
sandersd (OOO until July 31)
2014/03/21 23:30:35
Done.
| |
| 337 return; | 328 return; |
| 329 | |
| 338 if (waiting_for_clock_update_ && time < clock_->Elapsed()) | 330 if (waiting_for_clock_update_ && time < clock_->Elapsed()) |
| 339 return; | 331 return; |
| 340 | 332 |
| 341 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see | 333 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see |
| 342 // http://crbug.com/137973 | 334 // http://crbug.com/137973 |
| 343 if (state_ == kSeeking) | 335 if (state_ == kSeeking) |
| 344 return; | 336 return; |
| 345 | 337 |
| 346 clock_->SetTime(time, max_time); | 338 clock_->SetTime(time, max_time); |
| 347 StartClockIfWaitingForTimeUpdate_Locked(); | 339 StartClockIfWaitingForTimeUpdate_Locked(); |
| 348 } | 340 } |
| 349 | 341 |
| 350 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) { | 342 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) { |
| 351 DCHECK(IsRunning()); | 343 DCHECK(IsRunning()); |
| 352 base::AutoLock auto_lock(lock_); | 344 base::AutoLock auto_lock(lock_); |
| 353 | 345 |
| 354 if (has_audio_) | 346 if (audio_renderer_ != NULL && !audio_disabled_) |
|
scherkus (not reviewing)
2014/03/21 22:26:10
nit: hrmm.. can we ditch the direct comparison to
sandersd (OOO until July 31)
2014/03/21 23:30:35
Done.
| |
| 355 return; | 347 return; |
| 356 | 348 |
| 357 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see | 349 // TODO(scherkus): |state_| should only be accessed on pipeline thread, see |
| 358 // http://crbug.com/137973 | 350 // http://crbug.com/137973 |
| 359 if (state_ == kSeeking) | 351 if (state_ == kSeeking) |
| 360 return; | 352 return; |
| 361 | 353 |
| 362 DCHECK(!waiting_for_clock_update_); | 354 DCHECK(!waiting_for_clock_update_); |
| 363 clock_->SetMaxTime(max_time); | 355 clock_->SetMaxTime(max_time); |
| 364 } | 356 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 case kInitVideoRenderer: | 447 case kInitVideoRenderer: |
| 456 return InitializeVideoRenderer(done_cb); | 448 return InitializeVideoRenderer(done_cb); |
| 457 | 449 |
| 458 case kInitPrerolling: | 450 case kInitPrerolling: |
| 459 filter_collection_.reset(); | 451 filter_collection_.reset(); |
| 460 { | 452 { |
| 461 base::AutoLock l(lock_); | 453 base::AutoLock l(lock_); |
| 462 // We do not want to start the clock running. We only want to set the | 454 // We do not want to start the clock running. We only want to set the |
| 463 // base media time so our timestamp calculations will be correct. | 455 // base media time so our timestamp calculations will be correct. |
| 464 clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime()); | 456 clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime()); |
| 457 } | |
| 465 | 458 |
| 466 // TODO(scherkus): |has_audio_| should be true no matter what -- | |
| 467 // otherwise people with muted/disabled sound cards will make our | |
| 468 // default controls look as if every video doesn't contain an audio | |
| 469 // track. | |
| 470 has_audio_ = audio_renderer_ != NULL && !audio_disabled_; | |
| 471 has_video_ = video_renderer_ != NULL; | |
| 472 } | |
| 473 if (!audio_renderer_ && !video_renderer_) { | 459 if (!audio_renderer_ && !video_renderer_) { |
| 474 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); | 460 done_cb.Run(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 475 return; | 461 return; |
| 476 } | 462 } |
| 477 | 463 |
| 478 buffering_state_cb_.Run(kHaveMetadata); | 464 if (!have_metadata_cb_.is_null()) { |
| 479 | 465 PipelineMetadata metadata; |
|
scherkus (not reviewing)
2014/03/21 22:26:10
what about adding an extra ctor that lets you set
sandersd (OOO until July 31)
2014/03/21 23:30:35
That is what I did initially, but I didn't like th
scherkus (not reviewing)
2014/03/21 23:36:36
out of curiosity can you clarify what you meant by
sandersd (OOO until July 31)
2014/03/22 00:40:59
I mean that there is no explicit ordering relation
| |
| 466 metadata.has_audio_ = audio_renderer_ != NULL; | |
| 467 metadata.has_video_ = video_renderer_ != NULL; | |
| 468 metadata.natural_size_ = initial_natural_size_; | |
| 469 have_metadata_cb_.Run(metadata); | |
| 470 } | |
| 480 return DoInitialPreroll(done_cb); | 471 return DoInitialPreroll(done_cb); |
| 481 | 472 |
| 482 case kStarting: | 473 case kStarting: |
| 483 return DoPlay(done_cb); | 474 return DoPlay(done_cb); |
| 484 | 475 |
| 485 case kStarted: | 476 case kStarted: |
| 486 { | 477 { |
| 487 base::AutoLock l(lock_); | 478 base::AutoLock l(lock_); |
| 488 // We use audio stream to update the clock. So if there is such a | 479 // We use audio stream to update the clock. So if there is such a |
| 489 // stream, we pause the clock until we receive a valid timestamp. | 480 // stream, we pause the clock until we receive a valid timestamp. |
| 490 waiting_for_clock_update_ = true; | 481 waiting_for_clock_update_ = true; |
| 491 if (!has_audio_) { | 482 if (audio_renderer_ == NULL || audio_disabled_) { |
| 492 clock_->SetMaxTime(clock_->Duration()); | 483 clock_->SetMaxTime(clock_->Duration()); |
| 493 StartClockIfWaitingForTimeUpdate_Locked(); | 484 StartClockIfWaitingForTimeUpdate_Locked(); |
| 494 } | 485 } |
| 495 } | 486 } |
| 496 | 487 |
| 497 DCHECK(!seek_cb_.is_null()); | 488 DCHECK(!seek_cb_.is_null()); |
| 498 DCHECK_EQ(status_, PIPELINE_OK); | 489 DCHECK_EQ(status_, PIPELINE_OK); |
| 499 | 490 |
| 500 // Fire canplaythrough immediately after playback begins because of | 491 // Fire canplaythrough immediately after playback begins because of |
| 501 // crbug.com/106480. | 492 // crbug.com/106480. |
| 502 // TODO(vrk): set ready state to HaveFutureData when bug above is fixed. | 493 // TODO(vrk): set ready state to HaveFutureData when bug above is fixed. |
| 503 buffering_state_cb_.Run(kPrerollCompleted); | 494 if (!preroll_completed_cb_.is_null()) |
| 495 preroll_completed_cb_.Run(); | |
| 504 return base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 496 return base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
| 505 | 497 |
| 506 case kStopping: | 498 case kStopping: |
| 507 case kStopped: | 499 case kStopped: |
| 508 case kCreated: | 500 case kCreated: |
| 509 case kSeeking: | 501 case kSeeking: |
| 510 NOTREACHED() << "State has no transition: " << state_; | 502 NOTREACHED() << "State has no transition: " << state_; |
| 511 return; | 503 return; |
| 512 } | 504 } |
| 513 } | 505 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 | 716 |
| 725 // Called from any thread. | 717 // Called from any thread. |
| 726 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { | 718 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { |
| 727 base::AutoLock auto_lock(lock_); | 719 base::AutoLock auto_lock(lock_); |
| 728 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; | 720 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 729 statistics_.video_bytes_decoded += stats.video_bytes_decoded; | 721 statistics_.video_bytes_decoded += stats.video_bytes_decoded; |
| 730 statistics_.video_frames_decoded += stats.video_frames_decoded; | 722 statistics_.video_frames_decoded += stats.video_frames_decoded; |
| 731 statistics_.video_frames_dropped += stats.video_frames_dropped; | 723 statistics_.video_frames_dropped += stats.video_frames_dropped; |
| 732 } | 724 } |
| 733 | 725 |
| 734 void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection, | 726 void Pipeline::StartTask() { |
| 735 const base::Closure& ended_cb, | |
| 736 const PipelineStatusCB& error_cb, | |
| 737 const PipelineStatusCB& seek_cb, | |
| 738 const BufferingStateCB& buffering_state_cb, | |
| 739 const base::Closure& duration_change_cb) { | |
| 740 DCHECK(task_runner_->BelongsToCurrentThread()); | 727 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 741 CHECK_EQ(kCreated, state_) | 728 CHECK_EQ(kCreated, state_) |
| 742 << "Media pipeline cannot be started more than once"; | 729 << "Media pipeline cannot be started more than once"; |
| 743 | 730 |
| 744 filter_collection_ = filter_collection.Pass(); | |
| 745 ended_cb_ = ended_cb; | |
| 746 error_cb_ = error_cb; | |
| 747 seek_cb_ = seek_cb; | |
| 748 buffering_state_cb_ = buffering_state_cb; | |
| 749 duration_change_cb_ = duration_change_cb; | |
| 750 | |
| 751 text_renderer_ = filter_collection_->GetTextRenderer(); | 731 text_renderer_ = filter_collection_->GetTextRenderer(); |
| 752 | 732 |
| 753 if (text_renderer_) { | 733 if (text_renderer_) { |
| 754 text_renderer_->Initialize( | 734 text_renderer_->Initialize( |
| 755 base::Bind(&Pipeline::OnTextRendererEnded, base::Unretained(this))); | 735 base::Bind(&Pipeline::OnTextRendererEnded, base::Unretained(this))); |
| 756 } | 736 } |
| 757 | 737 |
| 758 StateTransitionTask(PIPELINE_OK); | 738 StateTransitionTask(PIPELINE_OK); |
| 759 } | 739 } |
| 760 | 740 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 } | 898 } |
| 919 | 899 |
| 920 DCHECK_EQ(status_, PIPELINE_OK); | 900 DCHECK_EQ(status_, PIPELINE_OK); |
| 921 ended_cb_.Run(); | 901 ended_cb_.Run(); |
| 922 } | 902 } |
| 923 | 903 |
| 924 void Pipeline::AudioDisabledTask() { | 904 void Pipeline::AudioDisabledTask() { |
| 925 DCHECK(task_runner_->BelongsToCurrentThread()); | 905 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 926 | 906 |
| 927 base::AutoLock auto_lock(lock_); | 907 base::AutoLock auto_lock(lock_); |
| 928 has_audio_ = false; | |
| 929 audio_disabled_ = true; | 908 audio_disabled_ = true; |
| 930 | 909 |
| 931 // Notify our demuxer that we're no longer rendering audio. | 910 // Notify our demuxer that we're no longer rendering audio. |
| 932 demuxer_->OnAudioRendererDisabled(); | 911 demuxer_->OnAudioRendererDisabled(); |
| 933 | 912 |
| 934 // Start clock since there is no more audio to trigger clock updates. | 913 // Start clock since there is no more audio to trigger clock updates. |
| 935 clock_->SetMaxTime(clock_->Duration()); | 914 clock_->SetMaxTime(clock_->Duration()); |
| 936 StartClockIfWaitingForTimeUpdate_Locked(); | 915 StartClockIfWaitingForTimeUpdate_Locked(); |
| 937 } | 916 } |
| 938 | 917 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 968 base::Bind(&Pipeline::OnAudioTimeUpdate, base::Unretained(this)), | 947 base::Bind(&Pipeline::OnAudioTimeUpdate, base::Unretained(this)), |
| 969 base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)), | 948 base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)), |
| 970 base::Bind(&Pipeline::OnAudioDisabled, base::Unretained(this)), | 949 base::Bind(&Pipeline::OnAudioDisabled, base::Unretained(this)), |
| 971 base::Bind(&Pipeline::SetError, base::Unretained(this))); | 950 base::Bind(&Pipeline::SetError, base::Unretained(this))); |
| 972 } | 951 } |
| 973 | 952 |
| 974 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { | 953 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { |
| 975 DCHECK(task_runner_->BelongsToCurrentThread()); | 954 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 976 | 955 |
| 977 // Get an initial natural size so we have something when we signal | 956 // Get an initial natural size so we have something when we signal |
| 978 // the kHaveMetadata buffering state. | 957 // HaveMetadata. |
| 979 // | 958 // |
| 980 // TODO(acolwell): We have to query demuxer outside of the lock to prevent a | 959 // TODO(acolwell): We have to query demuxer outside of the lock to prevent a |
| 981 // deadlock between ChunkDemuxer and Pipeline. See http://crbug.com/334325 for | 960 // deadlock between ChunkDemuxer and Pipeline. See http://crbug.com/334325 for |
| 982 // ideas on removing locking from ChunkDemuxer. | 961 // ideas on removing locking from ChunkDemuxer. |
| 983 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 962 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 984 gfx::Size initial_natural_size = | 963 initial_natural_size_ = stream->video_decoder_config().natural_size(); |
|
scherkus (not reviewing)
2014/03/21 22:26:10
you can move this up to where we call have_metadat
sandersd (OOO until July 31)
2014/03/21 23:30:35
Done.
| |
| 985 stream->video_decoder_config().natural_size(); | |
| 986 { | |
| 987 base::AutoLock l(lock_); | |
| 988 initial_natural_size_ = initial_natural_size; | |
| 989 } | |
| 990 | 964 |
| 991 video_renderer_ = filter_collection_->GetVideoRenderer(); | 965 video_renderer_ = filter_collection_->GetVideoRenderer(); |
| 992 video_renderer_->Initialize( | 966 video_renderer_->Initialize( |
| 993 stream, | 967 stream, |
| 994 done_cb, | 968 done_cb, |
| 995 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), | 969 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), |
| 996 base::Bind(&Pipeline::OnVideoTimeUpdate, base::Unretained(this)), | 970 base::Bind(&Pipeline::OnVideoTimeUpdate, base::Unretained(this)), |
| 997 base::Bind(&Pipeline::OnVideoRendererEnded, base::Unretained(this)), | 971 base::Bind(&Pipeline::OnVideoRendererEnded, base::Unretained(this)), |
| 998 base::Bind(&Pipeline::SetError, base::Unretained(this)), | 972 base::Bind(&Pipeline::SetError, base::Unretained(this)), |
| 999 base::Bind(&Pipeline::GetMediaTime, base::Unretained(this)), | 973 base::Bind(&Pipeline::GetMediaTime, base::Unretained(this)), |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1017 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 991 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 1018 lock_.AssertAcquired(); | 992 lock_.AssertAcquired(); |
| 1019 if (!waiting_for_clock_update_) | 993 if (!waiting_for_clock_update_) |
| 1020 return; | 994 return; |
| 1021 | 995 |
| 1022 waiting_for_clock_update_ = false; | 996 waiting_for_clock_update_ = false; |
| 1023 clock_->Play(); | 997 clock_->Play(); |
| 1024 } | 998 } |
| 1025 | 999 |
| 1026 } // namespace media | 1000 } // namespace media |
| OLD | NEW |