| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 const PipelineStatusCB& error_cb, | 108 const PipelineStatusCB& error_cb, |
| 109 const PipelineStatusCB& seek_cb, | 109 const PipelineStatusCB& seek_cb, |
| 110 const BufferingStateCB& buffering_state_cb, | 110 const BufferingStateCB& buffering_state_cb, |
| 111 const base::Closure& duration_change_cb) { | 111 const base::Closure& duration_change_cb) { |
| 112 base::AutoLock auto_lock(lock_); | 112 base::AutoLock auto_lock(lock_); |
| 113 CHECK(!running_) << "Media pipeline is already running"; | 113 CHECK(!running_) << "Media pipeline is already running"; |
| 114 DCHECK(!buffering_state_cb.is_null()); | 114 DCHECK(!buffering_state_cb.is_null()); |
| 115 | 115 |
| 116 running_ = true; | 116 running_ = true; |
| 117 message_loop_->PostTask(FROM_HERE, base::Bind( | 117 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 118 &Pipeline::StartTask, this, base::Passed(&collection), | 118 &Pipeline::StartTask, base::Unretained(this), base::Passed(&collection), |
| 119 ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb)); | 119 ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb)); |
| 120 } | 120 } |
| 121 | 121 |
| 122 void Pipeline::Stop(const base::Closure& stop_cb) { | 122 void Pipeline::Stop(const base::Closure& stop_cb) { |
| 123 base::AutoLock auto_lock(lock_); | 123 base::AutoLock auto_lock(lock_); |
| 124 message_loop_->PostTask(FROM_HERE, base::Bind( | 124 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 125 &Pipeline::StopTask, this, stop_cb)); | 125 &Pipeline::StopTask, base::Unretained(this), stop_cb)); |
| 126 } | 126 } |
| 127 | 127 |
| 128 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { | 128 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { |
| 129 base::AutoLock auto_lock(lock_); | 129 base::AutoLock auto_lock(lock_); |
| 130 if (!running_) { | 130 if (!running_) { |
| 131 NOTREACHED() << "Media pipeline isn't running"; | 131 NOTREACHED() << "Media pipeline isn't running"; |
| 132 return; | 132 return; |
| 133 } | 133 } |
| 134 | 134 |
| 135 message_loop_->PostTask(FROM_HERE, base::Bind( | 135 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 136 &Pipeline::SeekTask, this, time, seek_cb)); | 136 &Pipeline::SeekTask, base::Unretained(this), time, seek_cb)); |
| 137 } | 137 } |
| 138 | 138 |
| 139 bool Pipeline::IsRunning() const { | 139 bool Pipeline::IsRunning() const { |
| 140 base::AutoLock auto_lock(lock_); | 140 base::AutoLock auto_lock(lock_); |
| 141 return running_; | 141 return running_; |
| 142 } | 142 } |
| 143 | 143 |
| 144 bool Pipeline::HasAudio() const { | 144 bool Pipeline::HasAudio() const { |
| 145 base::AutoLock auto_lock(lock_); | 145 base::AutoLock auto_lock(lock_); |
| 146 return has_audio_; | 146 return has_audio_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 157 } | 157 } |
| 158 | 158 |
| 159 void Pipeline::SetPlaybackRate(float playback_rate) { | 159 void Pipeline::SetPlaybackRate(float playback_rate) { |
| 160 if (playback_rate < 0.0f) | 160 if (playback_rate < 0.0f) |
| 161 return; | 161 return; |
| 162 | 162 |
| 163 base::AutoLock auto_lock(lock_); | 163 base::AutoLock auto_lock(lock_); |
| 164 playback_rate_ = playback_rate; | 164 playback_rate_ = playback_rate; |
| 165 if (running_) { | 165 if (running_) { |
| 166 message_loop_->PostTask(FROM_HERE, base::Bind( | 166 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 167 &Pipeline::PlaybackRateChangedTask, this, playback_rate)); | 167 &Pipeline::PlaybackRateChangedTask, base::Unretained(this), |
| 168 playback_rate)); |
| 168 } | 169 } |
| 169 } | 170 } |
| 170 | 171 |
| 171 float Pipeline::GetVolume() const { | 172 float Pipeline::GetVolume() const { |
| 172 base::AutoLock auto_lock(lock_); | 173 base::AutoLock auto_lock(lock_); |
| 173 return volume_; | 174 return volume_; |
| 174 } | 175 } |
| 175 | 176 |
| 176 void Pipeline::SetVolume(float volume) { | 177 void Pipeline::SetVolume(float volume) { |
| 177 if (volume < 0.0f || volume > 1.0f) | 178 if (volume < 0.0f || volume > 1.0f) |
| 178 return; | 179 return; |
| 179 | 180 |
| 180 base::AutoLock auto_lock(lock_); | 181 base::AutoLock auto_lock(lock_); |
| 181 volume_ = volume; | 182 volume_ = volume; |
| 182 if (running_) { | 183 if (running_) { |
| 183 message_loop_->PostTask(FROM_HERE, base::Bind( | 184 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 184 &Pipeline::VolumeChangedTask, this, volume)); | 185 &Pipeline::VolumeChangedTask, base::Unretained(this), volume)); |
| 185 } | 186 } |
| 186 } | 187 } |
| 187 | 188 |
| 188 TimeDelta Pipeline::GetMediaTime() const { | 189 TimeDelta Pipeline::GetMediaTime() const { |
| 189 base::AutoLock auto_lock(lock_); | 190 base::AutoLock auto_lock(lock_); |
| 190 return clock_->Elapsed(); | 191 return clock_->Elapsed(); |
| 191 } | 192 } |
| 192 | 193 |
| 193 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { | 194 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { |
| 194 base::AutoLock auto_lock(lock_); | 195 base::AutoLock auto_lock(lock_); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 void Pipeline::OnDemuxerError(PipelineStatus error) { | 329 void Pipeline::OnDemuxerError(PipelineStatus error) { |
| 329 SetError(error); | 330 SetError(error); |
| 330 } | 331 } |
| 331 | 332 |
| 332 void Pipeline::SetError(PipelineStatus error) { | 333 void Pipeline::SetError(PipelineStatus error) { |
| 333 DCHECK(IsRunning()); | 334 DCHECK(IsRunning()); |
| 334 DCHECK_NE(PIPELINE_OK, error); | 335 DCHECK_NE(PIPELINE_OK, error); |
| 335 VLOG(1) << "Media pipeline error: " << error; | 336 VLOG(1) << "Media pipeline error: " << error; |
| 336 | 337 |
| 337 message_loop_->PostTask(FROM_HERE, base::Bind( | 338 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 338 &Pipeline::ErrorChangedTask, this, error)); | 339 &Pipeline::ErrorChangedTask, base::Unretained(this), error)); |
| 339 | 340 |
| 340 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); | 341 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); |
| 341 } | 342 } |
| 342 | 343 |
| 343 void Pipeline::OnAudioDisabled() { | 344 void Pipeline::OnAudioDisabled() { |
| 344 DCHECK(IsRunning()); | 345 DCHECK(IsRunning()); |
| 345 message_loop_->PostTask(FROM_HERE, base::Bind( | 346 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 346 &Pipeline::AudioDisabledTask, this)); | 347 &Pipeline::AudioDisabledTask, base::Unretained(this))); |
| 347 media_log_->AddEvent( | 348 media_log_->AddEvent( |
| 348 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); | 349 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); |
| 349 } | 350 } |
| 350 | 351 |
| 351 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { | 352 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { |
| 352 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); | 353 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); |
| 353 DCHECK(IsRunning()); | 354 DCHECK(IsRunning()); |
| 354 base::AutoLock auto_lock(lock_); | 355 base::AutoLock auto_lock(lock_); |
| 355 | 356 |
| 356 if (!has_audio_) | 357 if (!has_audio_) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 if (time_offset < epsilon) | 422 if (time_offset < epsilon) |
| 422 return TimeDelta(); | 423 return TimeDelta(); |
| 423 if (time_offset + epsilon > clock_->Duration()) | 424 if (time_offset + epsilon > clock_->Duration()) |
| 424 return clock_->Duration(); | 425 return clock_->Duration(); |
| 425 return time_offset; | 426 return time_offset; |
| 426 } | 427 } |
| 427 | 428 |
| 428 void Pipeline::OnStateTransition(PipelineStatus status) { | 429 void Pipeline::OnStateTransition(PipelineStatus status) { |
| 429 // Force post to process state transitions after current execution frame. | 430 // Force post to process state transitions after current execution frame. |
| 430 message_loop_->PostTask(FROM_HERE, base::Bind( | 431 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 431 &Pipeline::StateTransitionTask, this, status)); | 432 &Pipeline::StateTransitionTask, base::Unretained(this), status)); |
| 432 } | 433 } |
| 433 | 434 |
| 434 void Pipeline::StateTransitionTask(PipelineStatus status) { | 435 void Pipeline::StateTransitionTask(PipelineStatus status) { |
| 435 DCHECK(message_loop_->BelongsToCurrentThread()); | 436 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 436 | 437 |
| 437 // No-op any state transitions if we're stopping. | 438 // No-op any state transitions if we're stopping. |
| 438 if (state_ == kStopping || state_ == kStopped) | 439 if (state_ == kStopping || state_ == kStopped) |
| 439 return; | 440 return; |
| 440 | 441 |
| 441 // Preserve existing abnormal status, otherwise update based on the result of | 442 // Preserve existing abnormal status, otherwise update based on the result of |
| 442 // the previous operation. | 443 // the previous operation. |
| 443 status_ = (status_ != PIPELINE_OK ? status_ : status); | 444 status_ = (status_ != PIPELINE_OK ? status_ : status); |
| 444 | 445 |
| 445 if (status_ != PIPELINE_OK) { | 446 if (status_ != PIPELINE_OK) { |
| 446 ErrorChangedTask(status_); | 447 ErrorChangedTask(status_); |
| 447 return; | 448 return; |
| 448 } | 449 } |
| 449 | 450 |
| 450 // Guard against accidentally clearing |pending_callbacks_| for states that | 451 // Guard against accidentally clearing |pending_callbacks_| for states that |
| 451 // use it as well as states that should not be using it. | 452 // use it as well as states that should not be using it. |
| 452 // | 453 // |
| 453 // TODO(scherkus): Make every state transition use |pending_callbacks_|. | 454 // TODO(scherkus): Make every state transition use |pending_callbacks_|. |
| 454 DCHECK_EQ(pending_callbacks_.get() != NULL, | 455 DCHECK_EQ(pending_callbacks_.get() != NULL, |
| 455 (state_ == kInitPrerolling || state_ == kStarting || | 456 (state_ == kInitPrerolling || state_ == kStarting || |
| 456 state_ == kSeeking)); | 457 state_ == kSeeking)); |
| 457 pending_callbacks_.reset(); | 458 pending_callbacks_.reset(); |
| 458 | 459 |
| 459 PipelineStatusCB done_cb = base::Bind(&Pipeline::OnStateTransition, this); | 460 PipelineStatusCB done_cb = base::Bind( |
| 461 &Pipeline::OnStateTransition, base::Unretained(this)); |
| 460 | 462 |
| 461 // Switch states, performing any entrance actions for the new state as well. | 463 // Switch states, performing any entrance actions for the new state as well. |
| 462 SetState(GetNextState()); | 464 SetState(GetNextState()); |
| 463 switch (state_) { | 465 switch (state_) { |
| 464 case kInitDemuxer: | 466 case kInitDemuxer: |
| 465 return InitializeDemuxer(done_cb); | 467 return InitializeDemuxer(done_cb); |
| 466 | 468 |
| 467 case kInitAudioRenderer: | 469 case kInitAudioRenderer: |
| 468 return InitializeAudioRenderer(done_cb); | 470 return InitializeAudioRenderer(done_cb); |
| 469 | 471 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( | 700 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( |
| 699 size.width(), size.height())); | 701 size.width(), size.height())); |
| 700 | 702 |
| 701 base::AutoLock auto_lock(lock_); | 703 base::AutoLock auto_lock(lock_); |
| 702 natural_size_ = size; | 704 natural_size_ = size; |
| 703 } | 705 } |
| 704 | 706 |
| 705 void Pipeline::OnAudioRendererEnded() { | 707 void Pipeline::OnAudioRendererEnded() { |
| 706 // Force post to process ended messages after current execution frame. | 708 // Force post to process ended messages after current execution frame. |
| 707 message_loop_->PostTask(FROM_HERE, base::Bind( | 709 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 708 &Pipeline::DoAudioRendererEnded, this)); | 710 &Pipeline::DoAudioRendererEnded, base::Unretained(this))); |
| 709 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::AUDIO_ENDED)); | 711 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::AUDIO_ENDED)); |
| 710 } | 712 } |
| 711 | 713 |
| 712 void Pipeline::OnVideoRendererEnded() { | 714 void Pipeline::OnVideoRendererEnded() { |
| 713 // Force post to process ended messages after current execution frame. | 715 // Force post to process ended messages after current execution frame. |
| 714 message_loop_->PostTask(FROM_HERE, base::Bind( | 716 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 715 &Pipeline::DoVideoRendererEnded, this)); | 717 &Pipeline::DoVideoRendererEnded, base::Unretained(this))); |
| 716 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED)); | 718 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED)); |
| 717 } | 719 } |
| 718 | 720 |
| 719 // Called from any thread. | 721 // Called from any thread. |
| 720 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { | 722 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { |
| 721 base::AutoLock auto_lock(lock_); | 723 base::AutoLock auto_lock(lock_); |
| 722 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; | 724 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 723 statistics_.video_bytes_decoded += stats.video_bytes_decoded; | 725 statistics_.video_bytes_decoded += stats.video_bytes_decoded; |
| 724 statistics_.video_frames_decoded += stats.video_frames_decoded; | 726 statistics_.video_frames_decoded += stats.video_frames_decoded; |
| 725 statistics_.video_frames_dropped += stats.video_frames_dropped; | 727 statistics_.video_frames_dropped += stats.video_frames_dropped; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 751 | 753 |
| 752 if (state_ == kStopped) { | 754 if (state_ == kStopped) { |
| 753 stop_cb.Run(); | 755 stop_cb.Run(); |
| 754 return; | 756 return; |
| 755 } | 757 } |
| 756 | 758 |
| 757 SetState(kStopping); | 759 SetState(kStopping); |
| 758 pending_callbacks_.reset(); | 760 pending_callbacks_.reset(); |
| 759 stop_cb_ = stop_cb; | 761 stop_cb_ = stop_cb; |
| 760 | 762 |
| 761 DoStop(base::Bind(&Pipeline::OnStopCompleted, this)); | 763 DoStop(base::Bind(&Pipeline::OnStopCompleted, base::Unretained(this))); |
| 762 } | 764 } |
| 763 | 765 |
| 764 void Pipeline::ErrorChangedTask(PipelineStatus error) { | 766 void Pipeline::ErrorChangedTask(PipelineStatus error) { |
| 765 DCHECK(message_loop_->BelongsToCurrentThread()); | 767 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 766 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; | 768 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; |
| 767 | 769 |
| 768 if (state_ == kStopping || state_ == kStopped) | 770 if (state_ == kStopping || state_ == kStopped) |
| 769 return; | 771 return; |
| 770 | 772 |
| 771 SetState(kStopping); | 773 SetState(kStopping); |
| 772 pending_callbacks_.reset(); | 774 pending_callbacks_.reset(); |
| 773 status_ = error; | 775 status_ = error; |
| 774 | 776 |
| 775 DoStop(base::Bind(&Pipeline::OnStopCompleted, this)); | 777 DoStop(base::Bind(&Pipeline::OnStopCompleted, base::Unretained(this))); |
| 776 } | 778 } |
| 777 | 779 |
| 778 void Pipeline::PlaybackRateChangedTask(float playback_rate) { | 780 void Pipeline::PlaybackRateChangedTask(float playback_rate) { |
| 779 DCHECK(message_loop_->BelongsToCurrentThread()); | 781 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 780 | 782 |
| 781 // Playback rate changes are only carried out while playing. | 783 // Playback rate changes are only carried out while playing. |
| 782 if (state_ != kStarting && state_ != kStarted) | 784 if (state_ != kStarting && state_ != kStarted) |
| 783 return; | 785 return; |
| 784 | 786 |
| 785 { | 787 { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 audio_ended_ = false; | 832 audio_ended_ = false; |
| 831 video_ended_ = false; | 833 video_ended_ = false; |
| 832 | 834 |
| 833 // Kick off seeking! | 835 // Kick off seeking! |
| 834 { | 836 { |
| 835 base::AutoLock auto_lock(lock_); | 837 base::AutoLock auto_lock(lock_); |
| 836 if (clock_->IsPlaying()) | 838 if (clock_->IsPlaying()) |
| 837 clock_->Pause(); | 839 clock_->Pause(); |
| 838 clock_->SetTime(seek_timestamp, seek_timestamp); | 840 clock_->SetTime(seek_timestamp, seek_timestamp); |
| 839 } | 841 } |
| 840 DoSeek(seek_timestamp, base::Bind(&Pipeline::OnStateTransition, this)); | 842 DoSeek(seek_timestamp, base::Bind( |
| 843 &Pipeline::OnStateTransition, base::Unretained(this))); |
| 841 } | 844 } |
| 842 | 845 |
| 843 void Pipeline::DoAudioRendererEnded() { | 846 void Pipeline::DoAudioRendererEnded() { |
| 844 DCHECK(message_loop_->BelongsToCurrentThread()); | 847 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 845 | 848 |
| 846 if (state_ != kStarted) | 849 if (state_ != kStarted) |
| 847 return; | 850 return; |
| 848 | 851 |
| 849 DCHECK(!audio_ended_); | 852 DCHECK(!audio_ended_); |
| 850 audio_ended_ = true; | 853 audio_ended_ = true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 demuxer_->Initialize(this, done_cb); | 914 demuxer_->Initialize(this, done_cb); |
| 912 } | 915 } |
| 913 | 916 |
| 914 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { | 917 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |
| 915 DCHECK(message_loop_->BelongsToCurrentThread()); | 918 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 916 | 919 |
| 917 audio_renderer_ = filter_collection_->GetAudioRenderer(); | 920 audio_renderer_ = filter_collection_->GetAudioRenderer(); |
| 918 audio_renderer_->Initialize( | 921 audio_renderer_->Initialize( |
| 919 demuxer_->GetStream(DemuxerStream::AUDIO), | 922 demuxer_->GetStream(DemuxerStream::AUDIO), |
| 920 done_cb, | 923 done_cb, |
| 921 base::Bind(&Pipeline::OnUpdateStatistics, this), | 924 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), |
| 922 base::Bind(&Pipeline::OnAudioUnderflow, this), | 925 base::Bind(&Pipeline::OnAudioUnderflow, base::Unretained(this)), |
| 923 base::Bind(&Pipeline::OnAudioTimeUpdate, this), | 926 base::Bind(&Pipeline::OnAudioTimeUpdate, base::Unretained(this)), |
| 924 base::Bind(&Pipeline::OnAudioRendererEnded, this), | 927 base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)), |
| 925 base::Bind(&Pipeline::OnAudioDisabled, this), | 928 base::Bind(&Pipeline::OnAudioDisabled, base::Unretained(this)), |
| 926 base::Bind(&Pipeline::SetError, this)); | 929 base::Bind(&Pipeline::SetError, base::Unretained(this))); |
| 927 } | 930 } |
| 928 | 931 |
| 929 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { | 932 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { |
| 930 DCHECK(message_loop_->BelongsToCurrentThread()); | 933 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 931 | 934 |
| 932 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 935 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 933 | 936 |
| 934 { | 937 { |
| 935 // Get an initial natural size so we have something when we signal | 938 // Get an initial natural size so we have something when we signal |
| 936 // the kHaveMetadata buffering state. | 939 // the kHaveMetadata buffering state. |
| 937 base::AutoLock l(lock_); | 940 base::AutoLock l(lock_); |
| 938 natural_size_ = stream->video_decoder_config().natural_size(); | 941 natural_size_ = stream->video_decoder_config().natural_size(); |
| 939 } | 942 } |
| 940 | 943 |
| 941 video_renderer_ = filter_collection_->GetVideoRenderer(); | 944 video_renderer_ = filter_collection_->GetVideoRenderer(); |
| 942 video_renderer_->Initialize( | 945 video_renderer_->Initialize( |
| 943 stream, | 946 stream, |
| 944 done_cb, | 947 done_cb, |
| 945 base::Bind(&Pipeline::OnUpdateStatistics, this), | 948 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), |
| 946 base::Bind(&Pipeline::OnVideoTimeUpdate, this), | 949 base::Bind(&Pipeline::OnVideoTimeUpdate, base::Unretained(this)), |
| 947 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this), | 950 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, base::Unretained(this)), |
| 948 base::Bind(&Pipeline::OnVideoRendererEnded, this), | 951 base::Bind(&Pipeline::OnVideoRendererEnded, base::Unretained(this)), |
| 949 base::Bind(&Pipeline::SetError, this), | 952 base::Bind(&Pipeline::SetError, base::Unretained(this)), |
| 950 base::Bind(&Pipeline::GetMediaTime, this), | 953 base::Bind(&Pipeline::GetMediaTime, base::Unretained(this)), |
| 951 base::Bind(&Pipeline::GetMediaDuration, this)); | 954 base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this))); |
| 952 } | 955 } |
| 953 | 956 |
| 954 void Pipeline::OnAudioUnderflow() { | 957 void Pipeline::OnAudioUnderflow() { |
| 955 if (!message_loop_->BelongsToCurrentThread()) { | 958 if (!message_loop_->BelongsToCurrentThread()) { |
| 956 message_loop_->PostTask(FROM_HERE, base::Bind( | 959 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 957 &Pipeline::OnAudioUnderflow, this)); | 960 &Pipeline::OnAudioUnderflow, base::Unretained(this))); |
| 958 return; | 961 return; |
| 959 } | 962 } |
| 960 | 963 |
| 961 if (state_ != kStarted) | 964 if (state_ != kStarted) |
| 962 return; | 965 return; |
| 963 | 966 |
| 964 if (audio_renderer_) | 967 if (audio_renderer_) |
| 965 audio_renderer_->ResumeAfterUnderflow(true); | 968 audio_renderer_->ResumeAfterUnderflow(true); |
| 966 } | 969 } |
| 967 | 970 |
| 968 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 971 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 969 lock_.AssertAcquired(); | 972 lock_.AssertAcquired(); |
| 970 if (!waiting_for_clock_update_) | 973 if (!waiting_for_clock_update_) |
| 971 return; | 974 return; |
| 972 | 975 |
| 973 waiting_for_clock_update_ = false; | 976 waiting_for_clock_update_ = false; |
| 974 clock_->Play(); | 977 clock_->Play(); |
| 975 } | 978 } |
| 976 | 979 |
| 977 } // namespace media | 980 } // namespace media |
| OLD | NEW |