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

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

Issue 11492003: Encrypted Media: Support Audio Decrypt-Only. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years 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/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_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/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/command_line.h" 14 #include "base/command_line.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/message_loop_proxy.h" 16 #include "base/message_loop_proxy.h"
17 #include "media/audio/audio_util.h" 17 #include "media/audio/audio_util.h"
18 #include "media/base/audio_splicer.h" 18 #include "media/base/audio_splicer.h"
19 #include "media/base/bind_to_loop.h" 19 #include "media/base/bind_to_loop.h"
20 #include "media/base/demuxer_stream.h" 20 #include "media/base/demuxer_stream.h"
21 #include "media/base/media_switches.h" 21 #include "media/base/media_switches.h"
22 #include "media/filters/audio_decoder_selector.h"
23 #include "media/filters/decrypting_demuxer_stream.h"
22 24
23 namespace media { 25 namespace media {
24 26
25 AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink) 27 AudioRendererImpl::AudioRendererImpl(
28 media::AudioRendererSink* sink,
29 const SetDecryptorReadyCB& set_decryptor_ready_cb)
26 : sink_(sink), 30 : sink_(sink),
31 set_decryptor_ready_cb_(set_decryptor_ready_cb),
27 state_(kUninitialized), 32 state_(kUninitialized),
28 pending_read_(false), 33 pending_read_(false),
29 received_end_of_stream_(false), 34 received_end_of_stream_(false),
30 rendered_end_of_stream_(false), 35 rendered_end_of_stream_(false),
31 audio_time_buffered_(kNoTimestamp()), 36 audio_time_buffered_(kNoTimestamp()),
32 current_time_(kNoTimestamp()), 37 current_time_(kNoTimestamp()),
33 underflow_disabled_(false), 38 underflow_disabled_(false),
34 preroll_aborted_(false), 39 preroll_aborted_(false),
35 actual_frames_per_buffer_(0) { 40 actual_frames_per_buffer_(0) {
36 // We're created on the render thread, but this thread checker is for another. 41 // We're created on the render thread, but this thread checker is for another.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 90 }
86 91
87 void AudioRendererImpl::DoPause() { 92 void AudioRendererImpl::DoPause() {
88 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 93 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
89 DCHECK(sink_); 94 DCHECK(sink_);
90 sink_->Pause(false); 95 sink_->Pause(false);
91 } 96 }
92 97
93 void AudioRendererImpl::Flush(const base::Closure& callback) { 98 void AudioRendererImpl::Flush(const base::Closure& callback) {
94 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 99 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
100
101 if (decrypting_demuxer_stream_) {
102 decrypting_demuxer_stream_->Reset(base::Bind(
103 &AudioRendererImpl::ResetDecoder, this, callback));
104 return;
105 }
106
107 decoder_->Reset(callback);
108 }
109
110 void AudioRendererImpl::ResetDecoder(const base::Closure& callback) {
111 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
95 decoder_->Reset(callback); 112 decoder_->Reset(callback);
96 } 113 }
97 114
98 void AudioRendererImpl::Stop(const base::Closure& callback) { 115 void AudioRendererImpl::Stop(const base::Closure& callback) {
99 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 116 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
100 DCHECK(!callback.is_null()); 117 DCHECK(!callback.is_null());
101 118
102 if (sink_) { 119 if (sink_) {
103 sink_->Stop(); 120 sink_->Stop();
104 sink_ = NULL; 121 sink_ = NULL;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 DCHECK(sink_); 190 DCHECK(sink_);
174 191
175 init_cb_ = init_cb; 192 init_cb_ = init_cb;
176 statistics_cb_ = statistics_cb; 193 statistics_cb_ = statistics_cb;
177 underflow_cb_ = underflow_cb; 194 underflow_cb_ = underflow_cb;
178 time_cb_ = time_cb; 195 time_cb_ = time_cb;
179 ended_cb_ = ended_cb; 196 ended_cb_ = ended_cb;
180 disabled_cb_ = disabled_cb; 197 disabled_cb_ = disabled_cb;
181 error_cb_ = error_cb; 198 error_cb_ = error_cb;
182 199
183 scoped_ptr<AudioDecoderList> decoder_list(new AudioDecoderList(decoders)); 200 scoped_ptr<AudioDecoderSelector> decoder_selector(
184 InitializeNextDecoder(stream, decoder_list.Pass()); 201 new AudioDecoderSelector(base::MessageLoopProxy::current(),
202 decoders,
203 set_decryptor_ready_cb_));
204
205 // To avoid calling |decoder_selector| methods and passing ownership of
206 // |decoder_selector| in the same line.
207 AudioDecoderSelector* decoder_selector_ptr = decoder_selector.get();
208
209 decoder_selector_ptr->SelectAudioDecoder(
210 stream,
211 statistics_cb,
212 base::Bind(&AudioRendererImpl::OnDecoderSelected, this,
213 base::Passed(&decoder_selector)));
185 } 214 }
186 215
187 void AudioRendererImpl::InitializeNextDecoder( 216 void AudioRendererImpl::OnDecoderSelected(
188 const scoped_refptr<DemuxerStream>& demuxer_stream, 217 scoped_ptr<AudioDecoderSelector> decoder_selector,
189 scoped_ptr<AudioDecoderList> decoders) { 218 const scoped_refptr<AudioDecoder>& selected_decoder,
190 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 219 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream) {
191 DCHECK(!decoders->empty());
192
193 scoped_refptr<AudioDecoder> decoder = decoders->front();
194 decoders->pop_front();
195
196 DCHECK(decoder);
197 decoder_ = decoder;
198 decoder->Initialize(
199 demuxer_stream, BindToLoop(base::MessageLoopProxy::current(), base::Bind(
200 &AudioRendererImpl::OnDecoderInitDone, this, demuxer_stream,
201 base::Passed(&decoders))),
202 statistics_cb_);
203 }
204
205 void AudioRendererImpl::OnDecoderInitDone(
206 const scoped_refptr<DemuxerStream>& demuxer_stream,
207 scoped_ptr<AudioDecoderList> decoders,
208 PipelineStatus status) {
209 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 220 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
210 221
211 if (state_ == kStopped) { 222 if (state_ == kStopped) {
212 DCHECK(!sink_); 223 DCHECK(!sink_);
213 return; 224 return;
214 } 225 }
215 226
216 if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) { 227 if (!selected_decoder) {
217 InitializeNextDecoder(demuxer_stream, decoders.Pass()); 228 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
218 return; 229 return;
219 } 230 }
220 231
221 if (status != PIPELINE_OK) { 232 decoder_ = selected_decoder;
222 base::ResetAndReturn(&init_cb_).Run(status); 233 decrypting_demuxer_stream_ = decrypting_demuxer_stream;
223 return;
224 }
225 234
226 int sample_rate = decoder_->samples_per_second(); 235 int sample_rate = decoder_->samples_per_second();
227 int buffer_size = GetHighLatencyOutputBufferSize(sample_rate); 236 int buffer_size = GetHighLatencyOutputBufferSize(sample_rate);
228 AudioParameters::Format format = AudioParameters::AUDIO_PCM_LINEAR; 237 AudioParameters::Format format = AudioParameters::AUDIO_PCM_LINEAR;
229 238
230 // On Windows and Mac we can use the low latency pipeline because they provide 239 // On Windows and Mac we can use the low latency pipeline because they provide
231 // accurate and smooth delay information. On other platforms like Linux there 240 // accurate and smooth delay information. On other platforms like Linux there
232 // are jitter issues. 241 // are jitter issues.
233 // TODO(dalecurtis): Fix bugs: http://crbug.com/138098 http://crbug.com/32757 242 // TODO(dalecurtis): Fix bugs: http://crbug.com/138098 http://crbug.com/32757
234 #if defined(OS_WIN) || defined(OS_MAC) 243 #if defined(OS_WIN) || defined(OS_MAC)
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 case kUnderflow: 638 case kUnderflow:
630 case kRebuffering: 639 case kRebuffering:
631 case kStopped: 640 case kStopped:
632 if (status != PIPELINE_OK) 641 if (status != PIPELINE_OK)
633 error_cb_.Run(status); 642 error_cb_.Run(status);
634 return; 643 return;
635 } 644 }
636 } 645 }
637 646
638 } // namespace media 647 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698