Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: media/base/pipeline.cc

Issue 376013003: Rename media::Clock to media::TimeDeltaInterpolator and update API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: SetBounds Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/synchronization/condition_variable.h" 19 #include "base/synchronization/condition_variable.h"
20 #include "media/base/audio_decoder.h" 20 #include "media/base/audio_decoder.h"
21 #include "media/base/audio_renderer.h" 21 #include "media/base/audio_renderer.h"
22 #include "media/base/clock.h"
23 #include "media/base/filter_collection.h" 22 #include "media/base/filter_collection.h"
24 #include "media/base/media_log.h" 23 #include "media/base/media_log.h"
25 #include "media/base/text_renderer.h" 24 #include "media/base/text_renderer.h"
26 #include "media/base/text_track_config.h" 25 #include "media/base/text_track_config.h"
26 #include "media/base/time_delta_interpolator.h"
27 #include "media/base/video_decoder.h" 27 #include "media/base/video_decoder.h"
28 #include "media/base/video_decoder_config.h" 28 #include "media/base/video_decoder_config.h"
29 #include "media/base/video_renderer.h" 29 #include "media/base/video_renderer.h"
30 30
31 using base::TimeDelta; 31 using base::TimeDelta;
32 32
33 namespace media { 33 namespace media {
34 34
35 Pipeline::Pipeline( 35 Pipeline::Pipeline(
36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
37 MediaLog* media_log) 37 MediaLog* media_log)
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 volume_(1.0f), 42 volume_(1.0f),
43 playback_rate_(0.0f), 43 playback_rate_(0.0f),
44 clock_(new Clock(&default_tick_clock_)), 44 interpolator_(new TimeDeltaInterpolator(&default_tick_clock_)),
45 clock_state_(CLOCK_PAUSED), 45 interpolation_state_(INTERPOLATION_STOPPED),
46 status_(PIPELINE_OK), 46 status_(PIPELINE_OK),
47 state_(kCreated), 47 state_(kCreated),
48 audio_ended_(false), 48 audio_ended_(false),
49 video_ended_(false), 49 video_ended_(false),
50 text_ended_(false), 50 text_ended_(false),
51 audio_buffering_state_(BUFFERING_HAVE_NOTHING), 51 audio_buffering_state_(BUFFERING_HAVE_NOTHING),
52 video_buffering_state_(BUFFERING_HAVE_NOTHING), 52 video_buffering_state_(BUFFERING_HAVE_NOTHING),
53 demuxer_(NULL), 53 demuxer_(NULL),
54 underflow_disabled_for_testing_(false) { 54 underflow_disabled_for_testing_(false) {
55 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); 55 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
56 media_log_->AddEvent( 56 media_log_->AddEvent(
57 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); 57 media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED));
58 clock_->SetTime(base::TimeDelta(), base::TimeDelta()); 58 interpolator_->SetBounds(base::TimeDelta(), base::TimeDelta());
59 } 59 }
60 60
61 Pipeline::~Pipeline() { 61 Pipeline::~Pipeline() {
62 DCHECK(thread_checker_.CalledOnValidThread()) 62 DCHECK(thread_checker_.CalledOnValidThread())
63 << "Pipeline must be destroyed on same thread that created it"; 63 << "Pipeline must be destroyed on same thread that created it";
64 DCHECK(!running_) << "Stop() must complete before destroying object"; 64 DCHECK(!running_) << "Stop() must complete before destroying object";
65 DCHECK(stop_cb_.is_null()); 65 DCHECK(stop_cb_.is_null());
66 DCHECK(seek_cb_.is_null()); 66 DCHECK(seek_cb_.is_null());
67 67
68 media_log_->AddEvent( 68 media_log_->AddEvent(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 base::AutoLock auto_lock(lock_); 150 base::AutoLock auto_lock(lock_);
151 volume_ = volume; 151 volume_ = volume;
152 if (running_) { 152 if (running_) {
153 task_runner_->PostTask(FROM_HERE, base::Bind( 153 task_runner_->PostTask(FROM_HERE, base::Bind(
154 &Pipeline::VolumeChangedTask, base::Unretained(this), volume)); 154 &Pipeline::VolumeChangedTask, base::Unretained(this), volume));
155 } 155 }
156 } 156 }
157 157
158 TimeDelta Pipeline::GetMediaTime() const { 158 TimeDelta Pipeline::GetMediaTime() const {
159 base::AutoLock auto_lock(lock_); 159 base::AutoLock auto_lock(lock_);
160 return std::min(clock_->Elapsed(), duration_); 160 return std::min(interpolator_->GetInterpolatedTime(), duration_);
161 } 161 }
162 162
163 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() const { 163 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() const {
164 base::AutoLock auto_lock(lock_); 164 base::AutoLock auto_lock(lock_);
165 return buffered_time_ranges_; 165 return buffered_time_ranges_;
166 } 166 }
167 167
168 TimeDelta Pipeline::GetMediaDuration() const { 168 TimeDelta Pipeline::GetMediaDuration() const {
169 base::AutoLock auto_lock(lock_); 169 base::AutoLock auto_lock(lock_);
170 return duration_; 170 return duration_;
171 } 171 }
172 172
173 bool Pipeline::DidLoadingProgress() { 173 bool Pipeline::DidLoadingProgress() {
174 base::AutoLock auto_lock(lock_); 174 base::AutoLock auto_lock(lock_);
175 bool ret = did_loading_progress_; 175 bool ret = did_loading_progress_;
176 did_loading_progress_ = false; 176 did_loading_progress_ = false;
177 return ret; 177 return ret;
178 } 178 }
179 179
180 PipelineStatistics Pipeline::GetStatistics() const { 180 PipelineStatistics Pipeline::GetStatistics() const {
181 base::AutoLock auto_lock(lock_); 181 base::AutoLock auto_lock(lock_);
182 return statistics_; 182 return statistics_;
183 } 183 }
184 184
185 void Pipeline::SetClockForTesting(Clock* clock) { 185 void Pipeline::SetTimeDeltaInterpolatorForTesting(
186 clock_.reset(clock); 186 TimeDeltaInterpolator* interpolator) {
187 interpolator_.reset(interpolator);
187 } 188 }
188 189
189 void Pipeline::SetErrorForTesting(PipelineStatus status) { 190 void Pipeline::SetErrorForTesting(PipelineStatus status) {
190 SetError(status); 191 SetError(status);
191 } 192 }
192 193
193 void Pipeline::SetState(State next_state) { 194 void Pipeline::SetState(State next_state) {
194 DVLOG(1) << GetStateString(state_) << " -> " << GetStateString(next_state); 195 DVLOG(1) << GetStateString(state_) << " -> " << GetStateString(next_state);
195 196
196 state_ = next_state; 197 state_ = next_state;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 &Pipeline::ErrorChangedTask, base::Unretained(this), error)); 281 &Pipeline::ErrorChangedTask, base::Unretained(this), error));
281 282
282 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); 283 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error));
283 } 284 }
284 285
285 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { 286 void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
286 DCHECK(task_runner_->BelongsToCurrentThread()); 287 DCHECK(task_runner_->BelongsToCurrentThread());
287 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds()); 288 DCHECK_LE(time.InMicroseconds(), max_time.InMicroseconds());
288 base::AutoLock auto_lock(lock_); 289 base::AutoLock auto_lock(lock_);
289 290
290 if (clock_state_ == CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE && 291 if (interpolation_state_ == INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE &&
291 time < clock_->Elapsed()) { 292 time < interpolator_->GetInterpolatedTime()) {
292 return; 293 return;
293 } 294 }
294 295
295 if (state_ == kSeeking) 296 if (state_ == kSeeking)
296 return; 297 return;
297 298
298 clock_->SetTime(time, max_time); 299 interpolator_->SetBounds(time, max_time);
299 StartClockIfWaitingForTimeUpdate_Locked(); 300 StartClockIfWaitingForTimeUpdate_Locked();
300 } 301 }
301 302
302 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) { 303 void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) {
303 DCHECK(task_runner_->BelongsToCurrentThread()); 304 DCHECK(task_runner_->BelongsToCurrentThread());
304 305
305 if (audio_renderer_) 306 if (audio_renderer_)
306 return; 307 return;
307 308
308 if (state_ == kSeeking) 309 if (state_ == kSeeking)
309 return; 310 return;
310 311
311 base::AutoLock auto_lock(lock_); 312 base::AutoLock auto_lock(lock_);
312 DCHECK_NE(clock_state_, CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE); 313 DCHECK_NE(interpolation_state_, INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE);
313 clock_->SetMaxTime(max_time); 314 interpolator_->SetUpperBound(max_time);
314 } 315 }
315 316
316 void Pipeline::SetDuration(TimeDelta duration) { 317 void Pipeline::SetDuration(TimeDelta duration) {
317 DCHECK(IsRunning()); 318 DCHECK(IsRunning());
318 media_log_->AddEvent( 319 media_log_->AddEvent(
319 media_log_->CreateTimeEvent( 320 media_log_->CreateTimeEvent(
320 MediaLogEvent::DURATION_SET, "duration", duration)); 321 MediaLogEvent::DURATION_SET, "duration", duration));
321 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); 322 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration);
322 323
323 base::AutoLock auto_lock(lock_); 324 base::AutoLock auto_lock(lock_);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 stream->video_decoder_config().natural_size(); 391 stream->video_decoder_config().natural_size();
391 } 392 }
392 metadata_cb_.Run(metadata); 393 metadata_cb_.Run(metadata);
393 } 394 }
394 } 395 }
395 396
396 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 397 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
397 398
398 { 399 {
399 base::AutoLock auto_lock(lock_); 400 base::AutoLock auto_lock(lock_);
400 clock_->SetTime(start_timestamp_, start_timestamp_); 401 interpolator_->SetBounds(start_timestamp_, start_timestamp_);
401 } 402 }
402 403
403 if (audio_renderer_) 404 if (audio_renderer_)
404 audio_renderer_->StartPlayingFrom(start_timestamp_); 405 audio_renderer_->StartPlayingFrom(start_timestamp_);
405 if (video_renderer_) 406 if (video_renderer_)
406 video_renderer_->StartPlayingFrom(start_timestamp_); 407 video_renderer_->StartPlayingFrom(start_timestamp_);
407 if (text_renderer_) 408 if (text_renderer_)
408 text_renderer_->StartPlaying(); 409 text_renderer_->StartPlaying();
409 410
410 PlaybackRateChangedTask(GetPlaybackRate()); 411 PlaybackRateChangedTask(GetPlaybackRate());
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 636
636 void Pipeline::PlaybackRateChangedTask(float playback_rate) { 637 void Pipeline::PlaybackRateChangedTask(float playback_rate) {
637 DCHECK(task_runner_->BelongsToCurrentThread()); 638 DCHECK(task_runner_->BelongsToCurrentThread());
638 639
639 // Playback rate changes are only carried out while playing. 640 // Playback rate changes are only carried out while playing.
640 if (state_ != kPlaying) 641 if (state_ != kPlaying)
641 return; 642 return;
642 643
643 { 644 {
644 base::AutoLock auto_lock(lock_); 645 base::AutoLock auto_lock(lock_);
645 clock_->SetPlaybackRate(playback_rate); 646 interpolator_->SetPlaybackRate(playback_rate);
646 } 647 }
647 648
648 if (audio_renderer_) 649 if (audio_renderer_)
649 audio_renderer_->SetPlaybackRate(playback_rate_); 650 audio_renderer_->SetPlaybackRate(playback_rate_);
650 if (video_renderer_) 651 if (video_renderer_)
651 video_renderer_->SetPlaybackRate(playback_rate_); 652 video_renderer_->SetPlaybackRate(playback_rate_);
652 } 653 }
653 654
654 void Pipeline::VolumeChangedTask(float volume) { 655 void Pipeline::VolumeChangedTask(float volume) {
655 DCHECK(task_runner_->BelongsToCurrentThread()); 656 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 697
697 if (state_ != kPlaying) 698 if (state_ != kPlaying)
698 return; 699 return;
699 700
700 DCHECK(!audio_ended_); 701 DCHECK(!audio_ended_);
701 audio_ended_ = true; 702 audio_ended_ = true;
702 703
703 // Start clock since there is no more audio to trigger clock updates. 704 // Start clock since there is no more audio to trigger clock updates.
704 { 705 {
705 base::AutoLock auto_lock(lock_); 706 base::AutoLock auto_lock(lock_);
706 clock_->SetMaxTime(duration_); 707 interpolator_->SetUpperBound(duration_);
707 StartClockIfWaitingForTimeUpdate_Locked(); 708 StartClockIfWaitingForTimeUpdate_Locked();
708 } 709 }
709 710
710 RunEndedCallbackIfNeeded(); 711 RunEndedCallbackIfNeeded();
711 } 712 }
712 713
713 void Pipeline::DoVideoRendererEnded() { 714 void Pipeline::DoVideoRendererEnded() {
714 DCHECK(task_runner_->BelongsToCurrentThread()); 715 DCHECK(task_runner_->BelongsToCurrentThread());
715 716
716 if (state_ != kPlaying) 717 if (state_ != kPlaying)
(...skipping 25 matching lines...) Expand all
742 743
743 if (video_renderer_ && !video_ended_) 744 if (video_renderer_ && !video_ended_)
744 return; 745 return;
745 746
746 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_) 747 if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_)
747 return; 748 return;
748 749
749 { 750 {
750 base::AutoLock auto_lock(lock_); 751 base::AutoLock auto_lock(lock_);
751 PauseClockAndStopRendering_Locked(); 752 PauseClockAndStopRendering_Locked();
752 clock_->SetTime(duration_, duration_); 753 interpolator_->SetBounds(duration_, duration_);
753 } 754 }
754 755
755 DCHECK_EQ(status_, PIPELINE_OK); 756 DCHECK_EQ(status_, PIPELINE_OK);
756 ended_cb_.Run(); 757 ended_cb_.Run();
757 } 758 }
758 759
759 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream, 760 void Pipeline::AddTextStreamTask(DemuxerStream* text_stream,
760 const TextTrackConfig& config) { 761 const TextTrackConfig& config) {
761 DCHECK(task_runner_->BelongsToCurrentThread()); 762 DCHECK(task_runner_->BelongsToCurrentThread());
762 // TODO(matthewjheaney): fix up text_ended_ when text stream 763 // TODO(matthewjheaney): fix up text_ended_ when text stream
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 << " " << new_buffering_state << ") " 816 << " " << new_buffering_state << ") "
816 << (buffering_state == &audio_buffering_state_ ? "audio" : "video"); 817 << (buffering_state == &audio_buffering_state_ ? "audio" : "video");
817 DCHECK(task_runner_->BelongsToCurrentThread()); 818 DCHECK(task_runner_->BelongsToCurrentThread());
818 bool was_waiting_for_enough_data = WaitingForEnoughData(); 819 bool was_waiting_for_enough_data = WaitingForEnoughData();
819 820
820 *buffering_state = new_buffering_state; 821 *buffering_state = new_buffering_state;
821 822
822 // Disable underflow by ignoring updates that renderers have ran out of data 823 // Disable underflow by ignoring updates that renderers have ran out of data
823 // after we have started the clock. 824 // after we have started the clock.
824 if (state_ == kPlaying && underflow_disabled_for_testing_ && 825 if (state_ == kPlaying && underflow_disabled_for_testing_ &&
825 clock_state_ != CLOCK_PAUSED) { 826 interpolation_state_ != INTERPOLATION_STOPPED) {
826 return; 827 return;
827 } 828 }
828 829
829 // Renderer underflowed. 830 // Renderer underflowed.
830 if (!was_waiting_for_enough_data && WaitingForEnoughData()) { 831 if (!was_waiting_for_enough_data && WaitingForEnoughData()) {
831 PausePlayback(); 832 PausePlayback();
832 833
833 // TODO(scherkus): Fire BUFFERING_HAVE_NOTHING callback to alert clients of 834 // TODO(scherkus): Fire BUFFERING_HAVE_NOTHING callback to alert clients of
834 // underflow state http://crbug.com/144683 835 // underflow state http://crbug.com/144683
835 return; 836 return;
(...skipping 24 matching lines...) Expand all
860 DCHECK(WaitingForEnoughData()); 861 DCHECK(WaitingForEnoughData());
861 DCHECK(task_runner_->BelongsToCurrentThread()); 862 DCHECK(task_runner_->BelongsToCurrentThread());
862 863
863 base::AutoLock auto_lock(lock_); 864 base::AutoLock auto_lock(lock_);
864 PauseClockAndStopRendering_Locked(); 865 PauseClockAndStopRendering_Locked();
865 } 866 }
866 867
867 void Pipeline::StartPlayback() { 868 void Pipeline::StartPlayback() {
868 DVLOG(1) << __FUNCTION__; 869 DVLOG(1) << __FUNCTION__;
869 DCHECK_EQ(state_, kPlaying); 870 DCHECK_EQ(state_, kPlaying);
870 DCHECK_EQ(clock_state_, CLOCK_PAUSED); 871 DCHECK_EQ(interpolation_state_, INTERPOLATION_STOPPED);
871 DCHECK(!WaitingForEnoughData()); 872 DCHECK(!WaitingForEnoughData());
872 DCHECK(task_runner_->BelongsToCurrentThread()); 873 DCHECK(task_runner_->BelongsToCurrentThread());
873 874
874 if (audio_renderer_) { 875 if (audio_renderer_) {
875 // We use audio stream to update the clock. So if there is such a 876 // We use audio stream to update the clock. So if there is such a
876 // stream, we pause the clock until we receive a valid timestamp. 877 // stream, we pause the clock until we receive a valid timestamp.
877 base::AutoLock auto_lock(lock_); 878 base::AutoLock auto_lock(lock_);
878 clock_state_ = CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE; 879 interpolation_state_ = INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE;
879 audio_renderer_->StartRendering(); 880 audio_renderer_->StartRendering();
880 } else { 881 } else {
881 base::AutoLock auto_lock(lock_); 882 base::AutoLock auto_lock(lock_);
882 clock_state_ = CLOCK_PLAYING; 883 interpolation_state_ = INTERPOLATION_STARTED;
883 clock_->SetMaxTime(duration_); 884 interpolator_->SetUpperBound(duration_);
884 clock_->Play(); 885 interpolator_->StartInterpolating();
885 } 886 }
886 } 887 }
887 888
888 void Pipeline::PauseClockAndStopRendering_Locked() { 889 void Pipeline::PauseClockAndStopRendering_Locked() {
889 lock_.AssertAcquired(); 890 lock_.AssertAcquired();
890 switch (clock_state_) { 891 switch (interpolation_state_) {
891 case CLOCK_PAUSED: 892 case INTERPOLATION_STOPPED:
892 return; 893 return;
893 894
894 case CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE: 895 case INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE:
895 audio_renderer_->StopRendering(); 896 audio_renderer_->StopRendering();
896 break; 897 break;
897 898
898 case CLOCK_PLAYING: 899 case INTERPOLATION_STARTED:
899 if (audio_renderer_) 900 if (audio_renderer_)
900 audio_renderer_->StopRendering(); 901 audio_renderer_->StopRendering();
901 clock_->Pause(); 902 interpolator_->StopInterpolating();
902 break; 903 break;
903 } 904 }
904 905
905 clock_state_ = CLOCK_PAUSED; 906 interpolation_state_ = INTERPOLATION_STOPPED;
906 } 907 }
907 908
908 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 909 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
909 lock_.AssertAcquired(); 910 lock_.AssertAcquired();
910 if (clock_state_ != CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE) 911 if (interpolation_state_ != INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE)
911 return; 912 return;
912 913
913 clock_state_ = CLOCK_PLAYING; 914 interpolation_state_ = INTERPOLATION_STARTED;
914 clock_->Play(); 915 interpolator_->StartInterpolating();
915 } 916 }
916 917
917 } // namespace media 918 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698