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

Side by Side Diff: media/filters/audio_renderer_impl.cc

Issue 403723006: Make media::AudioRenderer inherit from media::TimeSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
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/filters/audio_renderer_impl.h" 5 #include "media/filters/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/time/default_tick_clock.h"
17 #include "media/base/audio_buffer.h" 18 #include "media/base/audio_buffer.h"
18 #include "media/base/audio_buffer_converter.h" 19 #include "media/base/audio_buffer_converter.h"
19 #include "media/base/audio_hardware_config.h" 20 #include "media/base/audio_hardware_config.h"
20 #include "media/base/audio_splicer.h" 21 #include "media/base/audio_splicer.h"
21 #include "media/base/bind_to_current_loop.h" 22 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/demuxer_stream.h" 23 #include "media/base/demuxer_stream.h"
23 #include "media/filters/audio_clock.h" 24 #include "media/filters/audio_clock.h"
24 #include "media/filters/decrypting_demuxer_stream.h" 25 #include "media/filters/decrypting_demuxer_stream.h"
25 26
26 namespace media { 27 namespace media {
(...skipping 18 matching lines...) Expand all
45 media::AudioRendererSink* sink, 46 media::AudioRendererSink* sink,
46 ScopedVector<AudioDecoder> decoders, 47 ScopedVector<AudioDecoder> decoders,
47 const SetDecryptorReadyCB& set_decryptor_ready_cb, 48 const SetDecryptorReadyCB& set_decryptor_ready_cb,
48 AudioHardwareConfig* hardware_config) 49 AudioHardwareConfig* hardware_config)
49 : task_runner_(task_runner), 50 : task_runner_(task_runner),
50 sink_(sink), 51 sink_(sink),
51 audio_buffer_stream_(new AudioBufferStream(task_runner, 52 audio_buffer_stream_(new AudioBufferStream(task_runner,
52 decoders.Pass(), 53 decoders.Pass(),
53 set_decryptor_ready_cb)), 54 set_decryptor_ready_cb)),
54 hardware_config_(hardware_config), 55 hardware_config_(hardware_config),
56 tick_clock_(new base::DefaultTickClock()),
55 state_(kUninitialized), 57 state_(kUninitialized),
56 buffering_state_(BUFFERING_HAVE_NOTHING), 58 buffering_state_(BUFFERING_HAVE_NOTHING),
57 rendering_(false), 59 rendering_(false),
58 sink_playing_(false), 60 sink_playing_(false),
59 pending_read_(false), 61 pending_read_(false),
60 received_end_of_stream_(false), 62 received_end_of_stream_(false),
61 rendered_end_of_stream_(false), 63 rendered_end_of_stream_(false),
62 weak_factory_(this) { 64 weak_factory_(this) {
63 audio_buffer_stream_->set_splice_observer(base::Bind( 65 audio_buffer_stream_->set_splice_observer(base::Bind(
64 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); 66 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
65 audio_buffer_stream_->set_config_change_observer(base::Bind( 67 audio_buffer_stream_->set_config_change_observer(base::Bind(
66 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); 68 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
67 } 69 }
68 70
69 AudioRendererImpl::~AudioRendererImpl() { 71 AudioRendererImpl::~AudioRendererImpl() {
70 // Stop() should have been called and |algorithm_| should have been destroyed. 72 // Stop() should have been called and |algorithm_| should have been destroyed.
71 DCHECK(state_ == kUninitialized || state_ == kStopped); 73 DCHECK(state_ == kUninitialized || state_ == kStopped);
72 DCHECK(!algorithm_.get()); 74 DCHECK(!algorithm_.get());
73 } 75 }
74 76
75 void AudioRendererImpl::StartRendering() { 77 void AudioRendererImpl::StartTicking() {
76 DVLOG(1) << __FUNCTION__; 78 DVLOG(1) << __FUNCTION__;
77 DCHECK(task_runner_->BelongsToCurrentThread()); 79 DCHECK(task_runner_->BelongsToCurrentThread());
78 DCHECK(!rendering_); 80 DCHECK(!rendering_);
79 rendering_ = true; 81 rendering_ = true;
80 82
81 base::AutoLock auto_lock(lock_); 83 base::AutoLock auto_lock(lock_);
82 // Wait for an eventual call to SetPlaybackRate() to start rendering. 84 // Wait for an eventual call to SetPlaybackRate() to start rendering.
83 if (algorithm_->playback_rate() == 0) { 85 if (algorithm_->playback_rate() == 0) {
84 DCHECK(!sink_playing_); 86 DCHECK(!sink_playing_);
85 return; 87 return;
86 } 88 }
87 89
88 StartRendering_Locked(); 90 StartRendering_Locked();
89 } 91 }
90 92
91 void AudioRendererImpl::StartRendering_Locked() { 93 void AudioRendererImpl::StartRendering_Locked() {
92 DVLOG(1) << __FUNCTION__; 94 DVLOG(1) << __FUNCTION__;
93 DCHECK(task_runner_->BelongsToCurrentThread()); 95 DCHECK(task_runner_->BelongsToCurrentThread());
94 DCHECK_EQ(state_, kPlaying); 96 DCHECK_EQ(state_, kPlaying);
95 DCHECK(!sink_playing_); 97 DCHECK(!sink_playing_);
96 DCHECK_NE(algorithm_->playback_rate(), 0); 98 DCHECK_NE(algorithm_->playback_rate(), 0);
97 lock_.AssertAcquired(); 99 lock_.AssertAcquired();
98 100
99 sink_playing_ = true; 101 sink_playing_ = true;
100 102
101 base::AutoUnlock auto_unlock(lock_); 103 base::AutoUnlock auto_unlock(lock_);
102 sink_->Play(); 104 sink_->Play();
103 } 105 }
104 106
105 void AudioRendererImpl::StopRendering() { 107 void AudioRendererImpl::StopTicking() {
106 DVLOG(1) << __FUNCTION__; 108 DVLOG(1) << __FUNCTION__;
107 DCHECK(task_runner_->BelongsToCurrentThread()); 109 DCHECK(task_runner_->BelongsToCurrentThread());
108 DCHECK(rendering_); 110 DCHECK(rendering_);
109 rendering_ = false; 111 rendering_ = false;
110 112
111 base::AutoLock auto_lock(lock_); 113 base::AutoLock auto_lock(lock_);
112 // Rendering should have already been stopped with a zero playback rate. 114 // Rendering should have already been stopped with a zero playback rate.
113 if (algorithm_->playback_rate() == 0) { 115 if (algorithm_->playback_rate() == 0) {
114 DCHECK(!sink_playing_); 116 DCHECK(!sink_playing_);
115 return; 117 return;
116 } 118 }
117 119
118 StopRendering_Locked(); 120 StopRendering_Locked();
119 } 121 }
120 122
121 void AudioRendererImpl::StopRendering_Locked() { 123 void AudioRendererImpl::StopRendering_Locked() {
122 DCHECK(task_runner_->BelongsToCurrentThread()); 124 DCHECK(task_runner_->BelongsToCurrentThread());
123 DCHECK_EQ(state_, kPlaying); 125 DCHECK_EQ(state_, kPlaying);
124 DCHECK(sink_playing_); 126 DCHECK(sink_playing_);
125 lock_.AssertAcquired(); 127 lock_.AssertAcquired();
126 128
127 sink_playing_ = false; 129 sink_playing_ = false;
128 130
129 base::AutoUnlock auto_unlock(lock_); 131 base::AutoUnlock auto_unlock(lock_);
130 sink_->Pause(); 132 sink_->Pause();
131 } 133 }
132 134
133 void AudioRendererImpl::SetMediaTime(base::TimeDelta time) {
134 DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")";
135 DCHECK(task_runner_->BelongsToCurrentThread());
136
137 base::AutoLock auto_lock(lock_);
138 DCHECK(!rendering_);
139 DCHECK_EQ(state_, kFlushed);
140
141 start_timestamp_ = time;
142 }
143
144 void AudioRendererImpl::Flush(const base::Closure& callback) { 135 void AudioRendererImpl::Flush(const base::Closure& callback) {
145 DVLOG(1) << __FUNCTION__; 136 DVLOG(1) << __FUNCTION__;
146 DCHECK(task_runner_->BelongsToCurrentThread()); 137 DCHECK(task_runner_->BelongsToCurrentThread());
147 138
148 base::AutoLock auto_lock(lock_); 139 base::AutoLock auto_lock(lock_);
149 DCHECK_EQ(state_, kPlaying); 140 DCHECK_EQ(state_, kPlaying);
150 DCHECK(flush_cb_.is_null()); 141 DCHECK(flush_cb_.is_null());
151 142
152 flush_cb_ = callback; 143 flush_cb_ = callback;
153 ChangeState_Locked(kFlushing); 144 ChangeState_Locked(kFlushing);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 base::AutoLock auto_lock(lock_); 228 base::AutoLock auto_lock(lock_);
238 DCHECK(!sink_playing_); 229 DCHECK(!sink_playing_);
239 DCHECK_EQ(state_, kFlushed); 230 DCHECK_EQ(state_, kFlushed);
240 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 231 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
241 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 232 DCHECK(!pending_read_) << "Pending read must complete before seeking";
242 233
243 ChangeState_Locked(kPlaying); 234 ChangeState_Locked(kPlaying);
244 AttemptRead_Locked(); 235 AttemptRead_Locked();
245 } 236 }
246 237
238 void AudioRendererImpl::SetMediaTime(base::TimeDelta timestamp) {
239 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InMicroseconds() << ")";
240 DCHECK(task_runner_->BelongsToCurrentThread());
241
242 base::AutoLock auto_lock(lock_);
243 DCHECK(!rendering_);
244 DCHECK_EQ(state_, kFlushed);
245 start_timestamp_ = timestamp;
246 }
247
248 base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
249 DVLOG(1) << __FUNCTION__;
250 DCHECK(task_runner_->BelongsToCurrentThread());
251
252 base::AutoLock auto_lock(lock_);
253 base::TimeDelta timestamp = audio_clock_->CurrentMediaTimestamp(
254 tick_clock_->NowTicks() - last_render_ticks_);
255 if (timestamp == kNoTimestamp())
256 return start_timestamp_;
257 return timestamp;
258 }
259
247 void AudioRendererImpl::Initialize(DemuxerStream* stream, 260 void AudioRendererImpl::Initialize(DemuxerStream* stream,
248 const PipelineStatusCB& init_cb, 261 const PipelineStatusCB& init_cb,
249 const StatisticsCB& statistics_cb, 262 const StatisticsCB& statistics_cb,
250 const TimeCB& time_cb, 263 const TimeCB& time_cb,
251 const BufferingStateCB& buffering_state_cb, 264 const BufferingStateCB& buffering_state_cb,
252 const base::Closure& ended_cb, 265 const base::Closure& ended_cb,
253 const PipelineStatusCB& error_cb) { 266 const PipelineStatusCB& error_cb) {
254 DCHECK(task_runner_->BelongsToCurrentThread()); 267 DCHECK(task_runner_->BelongsToCurrentThread());
255 DCHECK(stream); 268 DCHECK(stream);
256 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 269 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 375
363 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 376 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
364 } 377 }
365 378
366 void AudioRendererImpl::SetVolume(float volume) { 379 void AudioRendererImpl::SetVolume(float volume) {
367 DCHECK(task_runner_->BelongsToCurrentThread()); 380 DCHECK(task_runner_->BelongsToCurrentThread());
368 DCHECK(sink_); 381 DCHECK(sink_);
369 sink_->SetVolume(volume); 382 sink_->SetVolume(volume);
370 } 383 }
371 384
385 void AudioRendererImpl::SetTickClockForTesting(
386 scoped_ptr<base::TickClock> tick_clock) {
387 tick_clock_.swap(tick_clock);
388 }
389
372 void AudioRendererImpl::DecodedAudioReady( 390 void AudioRendererImpl::DecodedAudioReady(
373 AudioBufferStream::Status status, 391 AudioBufferStream::Status status,
374 const scoped_refptr<AudioBuffer>& buffer) { 392 const scoped_refptr<AudioBuffer>& buffer) {
375 DVLOG(2) << __FUNCTION__ << "(" << status << ")"; 393 DVLOG(2) << __FUNCTION__ << "(" << status << ")";
376 DCHECK(task_runner_->BelongsToCurrentThread()); 394 DCHECK(task_runner_->BelongsToCurrentThread());
377 395
378 base::AutoLock auto_lock(lock_); 396 base::AutoLock auto_lock(lock_);
379 DCHECK(state_ != kUninitialized); 397 DCHECK(state_ != kUninitialized);
380 398
381 CHECK(pending_read_); 399 CHECK(pending_read_);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 int audio_delay_milliseconds) { 576 int audio_delay_milliseconds) {
559 const int requested_frames = audio_bus->frames(); 577 const int requested_frames = audio_bus->frames();
560 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( 578 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
561 audio_delay_milliseconds); 579 audio_delay_milliseconds);
562 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() * 580 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() *
563 audio_parameters_.sample_rate()); 581 audio_parameters_.sample_rate());
564 int frames_written = 0; 582 int frames_written = 0;
565 base::Closure time_cb; 583 base::Closure time_cb;
566 { 584 {
567 base::AutoLock auto_lock(lock_); 585 base::AutoLock auto_lock(lock_);
586 last_render_ticks_ = tick_clock_->NowTicks();
568 587
569 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. 588 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
570 if (!algorithm_) { 589 if (!algorithm_) {
571 audio_clock_->WroteSilence(requested_frames, delay_frames); 590 audio_clock_->WroteSilence(requested_frames, delay_frames);
572 return 0; 591 return 0;
573 } 592 }
574 593
575 float playback_rate = algorithm_->playback_rate(); 594 float playback_rate = algorithm_->playback_rate();
576 if (playback_rate == 0) { 595 if (playback_rate == 0) {
577 audio_clock_->WroteSilence(requested_frames, delay_frames); 596 audio_clock_->WroteSilence(requested_frames, delay_frames);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 << buffering_state; 729 << buffering_state;
711 DCHECK_NE(buffering_state_, buffering_state); 730 DCHECK_NE(buffering_state_, buffering_state);
712 lock_.AssertAcquired(); 731 lock_.AssertAcquired();
713 buffering_state_ = buffering_state; 732 buffering_state_ = buffering_state;
714 733
715 task_runner_->PostTask(FROM_HERE, 734 task_runner_->PostTask(FROM_HERE,
716 base::Bind(buffering_state_cb_, buffering_state_)); 735 base::Bind(buffering_state_cb_, buffering_state_));
717 } 736 }
718 737
719 } // namespace media 738 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698