| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 const PipelineStatusCB& error_cb, | 75 const PipelineStatusCB& error_cb, |
| 76 const PipelineStatusCB& seek_cb, | 76 const PipelineStatusCB& seek_cb, |
| 77 const BufferingStateCB& buffering_state_cb, | 77 const BufferingStateCB& buffering_state_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 DCHECK(!buffering_state_cb.is_null()); |
| 82 | 82 |
| 83 running_ = true; | 83 running_ = true; |
| 84 message_loop_->PostTask(FROM_HERE, base::Bind( | 84 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 85 &Pipeline::StartTask, this, base::Passed(&collection), | 85 &Pipeline::StartTask, base::Unretained(this), base::Passed(&collection), |
| 86 ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb)); | 86 ended_cb, error_cb, seek_cb, buffering_state_cb, duration_change_cb)); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void Pipeline::Stop(const base::Closure& stop_cb) { | 89 void Pipeline::Stop(const base::Closure& stop_cb) { |
| 90 base::AutoLock auto_lock(lock_); | 90 base::AutoLock auto_lock(lock_); |
| 91 message_loop_->PostTask(FROM_HERE, base::Bind( | 91 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 92 &Pipeline::StopTask, this, stop_cb)); | 92 &Pipeline::StopTask, base::Unretained(this), stop_cb)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { | 95 void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) { |
| 96 base::AutoLock auto_lock(lock_); | 96 base::AutoLock auto_lock(lock_); |
| 97 if (!running_) { | 97 if (!running_) { |
| 98 NOTREACHED() << "Media pipeline isn't running"; | 98 NOTREACHED() << "Media pipeline isn't running"; |
| 99 return; | 99 return; |
| 100 } | 100 } |
| 101 | 101 |
| 102 message_loop_->PostTask(FROM_HERE, base::Bind( | 102 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 103 &Pipeline::SeekTask, this, time, seek_cb)); | 103 &Pipeline::SeekTask, base::Unretained(this), time, seek_cb)); |
| 104 } | 104 } |
| 105 | 105 |
| 106 bool Pipeline::IsRunning() const { | 106 bool Pipeline::IsRunning() const { |
| 107 base::AutoLock auto_lock(lock_); | 107 base::AutoLock auto_lock(lock_); |
| 108 return running_; | 108 return running_; |
| 109 } | 109 } |
| 110 | 110 |
| 111 bool Pipeline::HasAudio() const { | 111 bool Pipeline::HasAudio() const { |
| 112 base::AutoLock auto_lock(lock_); | 112 base::AutoLock auto_lock(lock_); |
| 113 return has_audio_; | 113 return has_audio_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 124 } | 124 } |
| 125 | 125 |
| 126 void Pipeline::SetPlaybackRate(float playback_rate) { | 126 void Pipeline::SetPlaybackRate(float playback_rate) { |
| 127 if (playback_rate < 0.0f) | 127 if (playback_rate < 0.0f) |
| 128 return; | 128 return; |
| 129 | 129 |
| 130 base::AutoLock auto_lock(lock_); | 130 base::AutoLock auto_lock(lock_); |
| 131 playback_rate_ = playback_rate; | 131 playback_rate_ = playback_rate; |
| 132 if (running_) { | 132 if (running_) { |
| 133 message_loop_->PostTask(FROM_HERE, base::Bind( | 133 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 134 &Pipeline::PlaybackRateChangedTask, this, playback_rate)); | 134 &Pipeline::PlaybackRateChangedTask, base::Unretained(this), |
| 135 playback_rate)); |
| 135 } | 136 } |
| 136 } | 137 } |
| 137 | 138 |
| 138 float Pipeline::GetVolume() const { | 139 float Pipeline::GetVolume() const { |
| 139 base::AutoLock auto_lock(lock_); | 140 base::AutoLock auto_lock(lock_); |
| 140 return volume_; | 141 return volume_; |
| 141 } | 142 } |
| 142 | 143 |
| 143 void Pipeline::SetVolume(float volume) { | 144 void Pipeline::SetVolume(float volume) { |
| 144 if (volume < 0.0f || volume > 1.0f) | 145 if (volume < 0.0f || volume > 1.0f) |
| 145 return; | 146 return; |
| 146 | 147 |
| 147 base::AutoLock auto_lock(lock_); | 148 base::AutoLock auto_lock(lock_); |
| 148 volume_ = volume; | 149 volume_ = volume; |
| 149 if (running_) { | 150 if (running_) { |
| 150 message_loop_->PostTask(FROM_HERE, base::Bind( | 151 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 151 &Pipeline::VolumeChangedTask, this, volume)); | 152 &Pipeline::VolumeChangedTask, base::Unretained(this), volume)); |
| 152 } | 153 } |
| 153 } | 154 } |
| 154 | 155 |
| 155 TimeDelta Pipeline::GetMediaTime() const { | 156 TimeDelta Pipeline::GetMediaTime() const { |
| 156 base::AutoLock auto_lock(lock_); | 157 base::AutoLock auto_lock(lock_); |
| 157 return clock_->Elapsed(); | 158 return clock_->Elapsed(); |
| 158 } | 159 } |
| 159 | 160 |
| 160 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { | 161 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { |
| 161 base::AutoLock auto_lock(lock_); | 162 base::AutoLock auto_lock(lock_); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 void Pipeline::OnDemuxerError(PipelineStatus error) { | 296 void Pipeline::OnDemuxerError(PipelineStatus error) { |
| 296 SetError(error); | 297 SetError(error); |
| 297 } | 298 } |
| 298 | 299 |
| 299 void Pipeline::SetError(PipelineStatus error) { | 300 void Pipeline::SetError(PipelineStatus error) { |
| 300 DCHECK(IsRunning()); | 301 DCHECK(IsRunning()); |
| 301 DCHECK_NE(PIPELINE_OK, error); | 302 DCHECK_NE(PIPELINE_OK, error); |
| 302 VLOG(1) << "Media pipeline error: " << error; | 303 VLOG(1) << "Media pipeline error: " << error; |
| 303 | 304 |
| 304 message_loop_->PostTask(FROM_HERE, base::Bind( | 305 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 305 &Pipeline::ErrorChangedTask, this, error)); | 306 &Pipeline::ErrorChangedTask, base::Unretained(this), error)); |
| 306 | 307 |
| 307 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); | 308 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); |
| 308 } | 309 } |
| 309 | 310 |
| 310 void Pipeline::OnAudioDisabled() { | 311 void Pipeline::OnAudioDisabled() { |
| 311 DCHECK(IsRunning()); | 312 DCHECK(IsRunning()); |
| 312 message_loop_->PostTask(FROM_HERE, base::Bind( | 313 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 313 &Pipeline::AudioDisabledTask, this)); | 314 &Pipeline::AudioDisabledTask, base::Unretained(this))); |
| 314 media_log_->AddEvent( | 315 media_log_->AddEvent( |
| 315 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); | 316 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); |
| 316 } | 317 } |
| 317 | 318 |
| 318 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { | 319 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { |
| 319 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); | 320 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); |
| 320 DCHECK(IsRunning()); | 321 DCHECK(IsRunning()); |
| 321 base::AutoLock auto_lock(lock_); | 322 base::AutoLock auto_lock(lock_); |
| 322 | 323 |
| 323 if (!has_audio_) | 324 if (!has_audio_) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 if (time_offset < epsilon) | 389 if (time_offset < epsilon) |
| 389 return TimeDelta(); | 390 return TimeDelta(); |
| 390 if (time_offset + epsilon > clock_->Duration()) | 391 if (time_offset + epsilon > clock_->Duration()) |
| 391 return clock_->Duration(); | 392 return clock_->Duration(); |
| 392 return time_offset; | 393 return time_offset; |
| 393 } | 394 } |
| 394 | 395 |
| 395 void Pipeline::OnStateTransition(PipelineStatus status) { | 396 void Pipeline::OnStateTransition(PipelineStatus status) { |
| 396 // Force post to process state transitions after current execution frame. | 397 // Force post to process state transitions after current execution frame. |
| 397 message_loop_->PostTask(FROM_HERE, base::Bind( | 398 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 398 &Pipeline::StateTransitionTask, this, status)); | 399 &Pipeline::StateTransitionTask, base::Unretained(this), status)); |
| 399 } | 400 } |
| 400 | 401 |
| 401 void Pipeline::StateTransitionTask(PipelineStatus status) { | 402 void Pipeline::StateTransitionTask(PipelineStatus status) { |
| 402 DCHECK(message_loop_->BelongsToCurrentThread()); | 403 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 403 | 404 |
| 404 // No-op any state transitions if we're stopping. | 405 // No-op any state transitions if we're stopping. |
| 405 if (state_ == kStopping || state_ == kStopped) | 406 if (state_ == kStopping || state_ == kStopped) |
| 406 return; | 407 return; |
| 407 | 408 |
| 408 // Preserve existing abnormal status, otherwise update based on the result of | 409 // Preserve existing abnormal status, otherwise update based on the result of |
| 409 // the previous operation. | 410 // the previous operation. |
| 410 status_ = (status_ != PIPELINE_OK ? status_ : status); | 411 status_ = (status_ != PIPELINE_OK ? status_ : status); |
| 411 | 412 |
| 412 if (status_ != PIPELINE_OK) { | 413 if (status_ != PIPELINE_OK) { |
| 413 ErrorChangedTask(status_); | 414 ErrorChangedTask(status_); |
| 414 return; | 415 return; |
| 415 } | 416 } |
| 416 | 417 |
| 417 // Guard against accidentally clearing |pending_callbacks_| for states that | 418 // Guard against accidentally clearing |pending_callbacks_| for states that |
| 418 // use it as well as states that should not be using it. | 419 // use it as well as states that should not be using it. |
| 419 // | 420 // |
| 420 // TODO(scherkus): Make every state transition use |pending_callbacks_|. | 421 // TODO(scherkus): Make every state transition use |pending_callbacks_|. |
| 421 DCHECK_EQ(pending_callbacks_.get() != NULL, | 422 DCHECK_EQ(pending_callbacks_.get() != NULL, |
| 422 (state_ == kInitPrerolling || state_ == kStarting || | 423 (state_ == kInitPrerolling || state_ == kStarting || |
| 423 state_ == kSeeking)); | 424 state_ == kSeeking)); |
| 424 pending_callbacks_.reset(); | 425 pending_callbacks_.reset(); |
| 425 | 426 |
| 426 PipelineStatusCB done_cb = base::Bind(&Pipeline::OnStateTransition, this); | 427 PipelineStatusCB done_cb = base::Bind( |
| 428 &Pipeline::OnStateTransition, base::Unretained(this)); |
| 427 | 429 |
| 428 // Switch states, performing any entrance actions for the new state as well. | 430 // Switch states, performing any entrance actions for the new state as well. |
| 429 SetState(GetNextState()); | 431 SetState(GetNextState()); |
| 430 switch (state_) { | 432 switch (state_) { |
| 431 case kInitDemuxer: | 433 case kInitDemuxer: |
| 432 return InitializeDemuxer(done_cb); | 434 return InitializeDemuxer(done_cb); |
| 433 | 435 |
| 434 case kInitAudioRenderer: | 436 case kInitAudioRenderer: |
| 435 return InitializeAudioRenderer(done_cb); | 437 return InitializeAudioRenderer(done_cb); |
| 436 | 438 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( | 667 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( |
| 666 size.width(), size.height())); | 668 size.width(), size.height())); |
| 667 | 669 |
| 668 base::AutoLock auto_lock(lock_); | 670 base::AutoLock auto_lock(lock_); |
| 669 natural_size_ = size; | 671 natural_size_ = size; |
| 670 } | 672 } |
| 671 | 673 |
| 672 void Pipeline::OnAudioRendererEnded() { | 674 void Pipeline::OnAudioRendererEnded() { |
| 673 // Force post to process ended messages after current execution frame. | 675 // Force post to process ended messages after current execution frame. |
| 674 message_loop_->PostTask(FROM_HERE, base::Bind( | 676 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 675 &Pipeline::DoAudioRendererEnded, this)); | 677 &Pipeline::DoAudioRendererEnded, base::Unretained(this))); |
| 676 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::AUDIO_ENDED)); | 678 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::AUDIO_ENDED)); |
| 677 } | 679 } |
| 678 | 680 |
| 679 void Pipeline::OnVideoRendererEnded() { | 681 void Pipeline::OnVideoRendererEnded() { |
| 680 // Force post to process ended messages after current execution frame. | 682 // Force post to process ended messages after current execution frame. |
| 681 message_loop_->PostTask(FROM_HERE, base::Bind( | 683 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 682 &Pipeline::DoVideoRendererEnded, this)); | 684 &Pipeline::DoVideoRendererEnded, base::Unretained(this))); |
| 683 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED)); | 685 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED)); |
| 684 } | 686 } |
| 685 | 687 |
| 686 // Called from any thread. | 688 // Called from any thread. |
| 687 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { | 689 void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { |
| 688 base::AutoLock auto_lock(lock_); | 690 base::AutoLock auto_lock(lock_); |
| 689 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; | 691 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 690 statistics_.video_bytes_decoded += stats.video_bytes_decoded; | 692 statistics_.video_bytes_decoded += stats.video_bytes_decoded; |
| 691 statistics_.video_frames_decoded += stats.video_frames_decoded; | 693 statistics_.video_frames_decoded += stats.video_frames_decoded; |
| 692 statistics_.video_frames_dropped += stats.video_frames_dropped; | 694 statistics_.video_frames_dropped += stats.video_frames_dropped; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 718 | 720 |
| 719 if (state_ == kStopped) { | 721 if (state_ == kStopped) { |
| 720 stop_cb.Run(); | 722 stop_cb.Run(); |
| 721 return; | 723 return; |
| 722 } | 724 } |
| 723 | 725 |
| 724 SetState(kStopping); | 726 SetState(kStopping); |
| 725 pending_callbacks_.reset(); | 727 pending_callbacks_.reset(); |
| 726 stop_cb_ = stop_cb; | 728 stop_cb_ = stop_cb; |
| 727 | 729 |
| 728 DoStop(base::Bind(&Pipeline::OnStopCompleted, this)); | 730 DoStop(base::Bind(&Pipeline::OnStopCompleted, base::Unretained(this))); |
| 729 } | 731 } |
| 730 | 732 |
| 731 void Pipeline::ErrorChangedTask(PipelineStatus error) { | 733 void Pipeline::ErrorChangedTask(PipelineStatus error) { |
| 732 DCHECK(message_loop_->BelongsToCurrentThread()); | 734 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 733 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; | 735 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; |
| 734 | 736 |
| 735 if (state_ == kStopping || state_ == kStopped) | 737 if (state_ == kStopping || state_ == kStopped) |
| 736 return; | 738 return; |
| 737 | 739 |
| 738 SetState(kStopping); | 740 SetState(kStopping); |
| 739 pending_callbacks_.reset(); | 741 pending_callbacks_.reset(); |
| 740 status_ = error; | 742 status_ = error; |
| 741 | 743 |
| 742 DoStop(base::Bind(&Pipeline::OnStopCompleted, this)); | 744 DoStop(base::Bind(&Pipeline::OnStopCompleted, base::Unretained(this))); |
| 743 } | 745 } |
| 744 | 746 |
| 745 void Pipeline::PlaybackRateChangedTask(float playback_rate) { | 747 void Pipeline::PlaybackRateChangedTask(float playback_rate) { |
| 746 DCHECK(message_loop_->BelongsToCurrentThread()); | 748 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 747 | 749 |
| 748 // Playback rate changes are only carried out while playing. | 750 // Playback rate changes are only carried out while playing. |
| 749 if (state_ != kStarting && state_ != kStarted) | 751 if (state_ != kStarting && state_ != kStarted) |
| 750 return; | 752 return; |
| 751 | 753 |
| 752 { | 754 { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 audio_ended_ = false; | 799 audio_ended_ = false; |
| 798 video_ended_ = false; | 800 video_ended_ = false; |
| 799 | 801 |
| 800 // Kick off seeking! | 802 // Kick off seeking! |
| 801 { | 803 { |
| 802 base::AutoLock auto_lock(lock_); | 804 base::AutoLock auto_lock(lock_); |
| 803 if (clock_->IsPlaying()) | 805 if (clock_->IsPlaying()) |
| 804 clock_->Pause(); | 806 clock_->Pause(); |
| 805 clock_->SetTime(seek_timestamp, seek_timestamp); | 807 clock_->SetTime(seek_timestamp, seek_timestamp); |
| 806 } | 808 } |
| 807 DoSeek(seek_timestamp, base::Bind(&Pipeline::OnStateTransition, this)); | 809 DoSeek(seek_timestamp, base::Bind( |
| 810 &Pipeline::OnStateTransition, base::Unretained(this))); |
| 808 } | 811 } |
| 809 | 812 |
| 810 void Pipeline::DoAudioRendererEnded() { | 813 void Pipeline::DoAudioRendererEnded() { |
| 811 DCHECK(message_loop_->BelongsToCurrentThread()); | 814 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 812 | 815 |
| 813 if (state_ != kStarted) | 816 if (state_ != kStarted) |
| 814 return; | 817 return; |
| 815 | 818 |
| 816 DCHECK(!audio_ended_); | 819 DCHECK(!audio_ended_); |
| 817 audio_ended_ = true; | 820 audio_ended_ = true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 demuxer_->Initialize(this, done_cb); | 881 demuxer_->Initialize(this, done_cb); |
| 879 } | 882 } |
| 880 | 883 |
| 881 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { | 884 void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |
| 882 DCHECK(message_loop_->BelongsToCurrentThread()); | 885 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 883 | 886 |
| 884 audio_renderer_ = filter_collection_->GetAudioRenderer(); | 887 audio_renderer_ = filter_collection_->GetAudioRenderer(); |
| 885 audio_renderer_->Initialize( | 888 audio_renderer_->Initialize( |
| 886 demuxer_->GetStream(DemuxerStream::AUDIO), | 889 demuxer_->GetStream(DemuxerStream::AUDIO), |
| 887 done_cb, | 890 done_cb, |
| 888 base::Bind(&Pipeline::OnUpdateStatistics, this), | 891 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), |
| 889 base::Bind(&Pipeline::OnAudioUnderflow, this), | 892 base::Bind(&Pipeline::OnAudioUnderflow, base::Unretained(this)), |
| 890 base::Bind(&Pipeline::OnAudioTimeUpdate, this), | 893 base::Bind(&Pipeline::OnAudioTimeUpdate, base::Unretained(this)), |
| 891 base::Bind(&Pipeline::OnAudioRendererEnded, this), | 894 base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)), |
| 892 base::Bind(&Pipeline::OnAudioDisabled, this), | 895 base::Bind(&Pipeline::OnAudioDisabled, base::Unretained(this)), |
| 893 base::Bind(&Pipeline::SetError, this)); | 896 base::Bind(&Pipeline::SetError, base::Unretained(this))); |
| 894 } | 897 } |
| 895 | 898 |
| 896 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { | 899 void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { |
| 897 DCHECK(message_loop_->BelongsToCurrentThread()); | 900 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 898 | 901 |
| 899 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 902 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 900 | 903 |
| 901 { | 904 { |
| 902 // Get an initial natural size so we have something when we signal | 905 // Get an initial natural size so we have something when we signal |
| 903 // the kHaveMetadata buffering state. | 906 // the kHaveMetadata buffering state. |
| 904 base::AutoLock l(lock_); | 907 base::AutoLock l(lock_); |
| 905 natural_size_ = stream->video_decoder_config().natural_size(); | 908 natural_size_ = stream->video_decoder_config().natural_size(); |
| 906 } | 909 } |
| 907 | 910 |
| 908 video_renderer_ = filter_collection_->GetVideoRenderer(); | 911 video_renderer_ = filter_collection_->GetVideoRenderer(); |
| 909 video_renderer_->Initialize( | 912 video_renderer_->Initialize( |
| 910 stream, | 913 stream, |
| 911 done_cb, | 914 done_cb, |
| 912 base::Bind(&Pipeline::OnUpdateStatistics, this), | 915 base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)), |
| 913 base::Bind(&Pipeline::OnVideoTimeUpdate, this), | 916 base::Bind(&Pipeline::OnVideoTimeUpdate, base::Unretained(this)), |
| 914 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this), | 917 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, base::Unretained(this)), |
| 915 base::Bind(&Pipeline::OnVideoRendererEnded, this), | 918 base::Bind(&Pipeline::OnVideoRendererEnded, base::Unretained(this)), |
| 916 base::Bind(&Pipeline::SetError, this), | 919 base::Bind(&Pipeline::SetError, base::Unretained(this)), |
| 917 base::Bind(&Pipeline::GetMediaTime, this), | 920 base::Bind(&Pipeline::GetMediaTime, base::Unretained(this)), |
| 918 base::Bind(&Pipeline::GetMediaDuration, this)); | 921 base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this))); |
| 919 } | 922 } |
| 920 | 923 |
| 921 void Pipeline::OnAudioUnderflow() { | 924 void Pipeline::OnAudioUnderflow() { |
| 922 if (!message_loop_->BelongsToCurrentThread()) { | 925 if (!message_loop_->BelongsToCurrentThread()) { |
| 923 message_loop_->PostTask(FROM_HERE, base::Bind( | 926 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 924 &Pipeline::OnAudioUnderflow, this)); | 927 &Pipeline::OnAudioUnderflow, base::Unretained(this))); |
| 925 return; | 928 return; |
| 926 } | 929 } |
| 927 | 930 |
| 928 if (state_ != kStarted) | 931 if (state_ != kStarted) |
| 929 return; | 932 return; |
| 930 | 933 |
| 931 if (audio_renderer_) | 934 if (audio_renderer_) |
| 932 audio_renderer_->ResumeAfterUnderflow(true); | 935 audio_renderer_->ResumeAfterUnderflow(true); |
| 933 } | 936 } |
| 934 | 937 |
| 935 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 938 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 936 lock_.AssertAcquired(); | 939 lock_.AssertAcquired(); |
| 937 if (!waiting_for_clock_update_) | 940 if (!waiting_for_clock_update_) |
| 938 return; | 941 return; |
| 939 | 942 |
| 940 waiting_for_clock_update_ = false; | 943 waiting_for_clock_update_ = false; |
| 941 clock_->Play(); | 944 clock_->Play(); |
| 942 } | 945 } |
| 943 | 946 |
| 944 } // namespace media | 947 } // namespace media |
| OLD | NEW |