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 |