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

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: 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
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_factory.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(media::AudioRendererSink* sink)
26 : sink_(sink), 28 : sink_(sink),
27 state_(kUninitialized), 29 state_(kUninitialized),
28 pending_read_(false), 30 pending_read_(false),
29 received_end_of_stream_(false), 31 received_end_of_stream_(false),
30 rendered_end_of_stream_(false), 32 rendered_end_of_stream_(false),
31 audio_time_buffered_(kNoTimestamp()), 33 audio_time_buffered_(kNoTimestamp()),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 87 }
86 88
87 void AudioRendererImpl::DoPause() { 89 void AudioRendererImpl::DoPause() {
88 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 90 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
89 DCHECK(sink_); 91 DCHECK(sink_);
90 sink_->Pause(false); 92 sink_->Pause(false);
91 } 93 }
92 94
93 void AudioRendererImpl::Flush(const base::Closure& callback) { 95 void AudioRendererImpl::Flush(const base::Closure& callback) {
94 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 96 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
97
98 if (decrypting_demuxer_stream_)
99 decrypting_demuxer_stream_->Reset(base::Closure());
100
95 decoder_->Reset(callback); 101 decoder_->Reset(callback);
96 } 102 }
97 103
98 void AudioRendererImpl::Stop(const base::Closure& callback) { 104 void AudioRendererImpl::Stop(const base::Closure& callback) {
99 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 105 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
100 DCHECK(!callback.is_null()); 106 DCHECK(!callback.is_null());
101 107
102 if (sink_) { 108 if (sink_) {
103 sink_->Stop(); 109 sink_->Stop();
104 sink_ = NULL; 110 sink_ = NULL;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 148
143 // |algorithm_| will request more reads. 149 // |algorithm_| will request more reads.
144 algorithm_->FlushBuffers(); 150 algorithm_->FlushBuffers();
145 earliest_end_time_ = base::Time::Now(); 151 earliest_end_time_ = base::Time::Now();
146 } 152 }
147 153
148 // Pause and flush the stream when we preroll to a new location. 154 // Pause and flush the stream when we preroll to a new location.
149 sink_->Pause(true); 155 sink_->Pause(true);
150 } 156 }
151 157
152 void AudioRendererImpl::Initialize(const scoped_refptr<DemuxerStream>& stream, 158 void AudioRendererImpl::Initialize(
153 const AudioDecoderList& decoders, 159 const scoped_refptr<DemuxerStream>& stream,
154 const PipelineStatusCB& init_cb, 160 const AudioDecoderList& decoders,
155 const StatisticsCB& statistics_cb, 161 const RequestDecryptorNotificationCB& request_decryptor_notification_cb,
156 const base::Closure& underflow_cb, 162 const PipelineStatusCB& init_cb,
157 const TimeCB& time_cb, 163 const StatisticsCB& statistics_cb,
158 const base::Closure& ended_cb, 164 const base::Closure& underflow_cb,
159 const base::Closure& disabled_cb, 165 const TimeCB& time_cb,
160 const PipelineStatusCB& error_cb) { 166 const base::Closure& ended_cb,
167 const base::Closure& disabled_cb,
168 const PipelineStatusCB& error_cb) {
161 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 169 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
162 DCHECK(stream); 170 DCHECK(stream);
163 DCHECK(!decoders.empty()); 171 DCHECK(!decoders.empty());
164 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 172 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
165 DCHECK(!init_cb.is_null()); 173 DCHECK(!init_cb.is_null());
166 DCHECK(!statistics_cb.is_null()); 174 DCHECK(!statistics_cb.is_null());
167 DCHECK(!underflow_cb.is_null()); 175 DCHECK(!underflow_cb.is_null());
168 DCHECK(!time_cb.is_null()); 176 DCHECK(!time_cb.is_null());
169 DCHECK(!ended_cb.is_null()); 177 DCHECK(!ended_cb.is_null());
170 DCHECK(!disabled_cb.is_null()); 178 DCHECK(!disabled_cb.is_null());
171 DCHECK(!error_cb.is_null()); 179 DCHECK(!error_cb.is_null());
172 DCHECK_EQ(kUninitialized, state_); 180 DCHECK_EQ(kUninitialized, state_);
173 DCHECK(sink_); 181 DCHECK(sink_);
174 182
175 init_cb_ = init_cb; 183 init_cb_ = init_cb;
176 statistics_cb_ = statistics_cb; 184 statistics_cb_ = statistics_cb;
177 underflow_cb_ = underflow_cb; 185 underflow_cb_ = underflow_cb;
178 time_cb_ = time_cb; 186 time_cb_ = time_cb;
179 ended_cb_ = ended_cb; 187 ended_cb_ = ended_cb;
180 disabled_cb_ = disabled_cb; 188 disabled_cb_ = disabled_cb;
181 error_cb_ = error_cb; 189 error_cb_ = error_cb;
182 190
183 scoped_ptr<AudioDecoderList> decoder_list(new AudioDecoderList(decoders)); 191 factory_.reset(new AudioDecoderFactory(base::MessageLoopProxy::current(),
184 InitializeNextDecoder(stream, decoder_list.Pass()); 192 decoders,
185 } 193 request_decryptor_notification_cb));
186 194 factory_->InitAudioDecoder(
187 void AudioRendererImpl::InitializeNextDecoder( 195 stream,
188 const scoped_refptr<DemuxerStream>& demuxer_stream, 196 statistics_cb,
189 scoped_ptr<AudioDecoderList> decoders) { 197 base::Bind(&AudioRendererImpl::OnDecoderInitDone, this));
190 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
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 } 198 }
204 199
205 void AudioRendererImpl::OnDecoderInitDone( 200 void AudioRendererImpl::OnDecoderInitDone(
206 const scoped_refptr<DemuxerStream>& demuxer_stream, 201 const scoped_refptr<AudioDecoder>& audio_decoder,
207 scoped_ptr<AudioDecoderList> decoders, 202 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream) {
208 PipelineStatus status) {
209 DCHECK(pipeline_thread_checker_.CalledOnValidThread()); 203 DCHECK(pipeline_thread_checker_.CalledOnValidThread());
210 204
205 decoder_ = audio_decoder;
206 decrypting_demuxer_stream_ = decrypting_demuxer_stream;
207 factory_.reset();
208
211 if (state_ == kStopped) { 209 if (state_ == kStopped) {
212 DCHECK(!sink_); 210 DCHECK(!sink_);
213 return; 211 return;
214 } 212 }
215 213
216 if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) { 214 if (!decoder_) {
217 InitializeNextDecoder(demuxer_stream, decoders.Pass()); 215 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
218 return; 216 return;
219 } 217 }
220 218
221 if (status != PIPELINE_OK) {
222 base::ResetAndReturn(&init_cb_).Run(status);
223 return;
224 }
225
226 int sample_rate = decoder_->samples_per_second(); 219 int sample_rate = decoder_->samples_per_second();
227 int buffer_size = GetHighLatencyOutputBufferSize(sample_rate); 220 int buffer_size = GetHighLatencyOutputBufferSize(sample_rate);
228 AudioParameters::Format format = AudioParameters::AUDIO_PCM_LINEAR; 221 AudioParameters::Format format = AudioParameters::AUDIO_PCM_LINEAR;
229 222
230 // On Windows and Mac we can use the low latency pipeline because they provide 223 // 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 224 // accurate and smooth delay information. On other platforms like Linux there
232 // are jitter issues. 225 // are jitter issues.
233 // TODO(dalecurtis): Fix bugs: http://crbug.com/138098 http://crbug.com/32757 226 // TODO(dalecurtis): Fix bugs: http://crbug.com/138098 http://crbug.com/32757
234 #if defined(OS_WIN) || defined(OS_MAC) 227 #if defined(OS_WIN) || defined(OS_MAC)
235 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 228 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 case kUnderflow: 622 case kUnderflow:
630 case kRebuffering: 623 case kRebuffering:
631 case kStopped: 624 case kStopped:
632 if (status != PIPELINE_OK) 625 if (status != PIPELINE_OK)
633 error_cb_.Run(status); 626 error_cb_.Run(status);
634 return; 627 return;
635 } 628 }
636 } 629 }
637 630
638 } // namespace media 631 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698