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

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

Issue 11778079: Encrypted Media: Enforcing the CDM to decode audio into S16 integers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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/decrypting_audio_decoder.h" 5 #include "media/filters/decrypting_audio_decoder.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop_proxy.h" 13 #include "base/message_loop_proxy.h"
14 #include "media/base/audio_decoder_config.h" 14 #include "media/base/audio_decoder_config.h"
15 #include "media/base/bind_to_loop.h" 15 #include "media/base/bind_to_loop.h"
16 #include "media/base/buffers.h" 16 #include "media/base/buffers.h"
17 #include "media/base/data_buffer.h" 17 #include "media/base/data_buffer.h"
18 #include "media/base/decoder_buffer.h" 18 #include "media/base/decoder_buffer.h"
19 #include "media/base/decryptor.h" 19 #include "media/base/decryptor.h"
20 #include "media/base/demuxer_stream.h" 20 #include "media/base/demuxer_stream.h"
21 #include "media/base/pipeline.h" 21 #include "media/base/pipeline.h"
22 22
23 namespace media { 23 namespace media {
24 24
25 #define BIND_TO_LOOP(function) \ 25 #define BIND_TO_LOOP(function) \
26 media::BindToLoop(message_loop_, base::Bind(function, this)) 26 media::BindToLoop(message_loop_, base::Bind(function, this))
27 27
28 const int DecryptingAudioDecoder::kSupportedBitsPerChannel = 16;
29
28 static inline bool IsOutOfSync(const base::TimeDelta& timestamp_1, 30 static inline bool IsOutOfSync(const base::TimeDelta& timestamp_1,
29 const base::TimeDelta& timestamp_2) { 31 const base::TimeDelta& timestamp_2) {
30 // Out of sync of 100ms would be pretty noticeable and we should keep any 32 // Out of sync of 100ms would be pretty noticeable and we should keep any
31 // drift below that. 33 // drift below that.
32 const int64 kOutOfSyncThresholdInMicroseconds = 100000; 34 const int64 kOutOfSyncThresholdInMicroseconds = 100000;
33 return std::abs(timestamp_1.InMicroseconds() - timestamp_2.InMicroseconds()) > 35 return std::abs(timestamp_1.InMicroseconds() - timestamp_2.InMicroseconds()) >
34 kOutOfSyncThresholdInMicroseconds; 36 kOutOfSyncThresholdInMicroseconds;
35 } 37 }
36 38
37 DecryptingAudioDecoder::DecryptingAudioDecoder( 39 DecryptingAudioDecoder::DecryptingAudioDecoder(
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) { 165 void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) {
164 DVLOG(2) << "SetDecryptor()"; 166 DVLOG(2) << "SetDecryptor()";
165 DCHECK(message_loop_->BelongsToCurrentThread()); 167 DCHECK(message_loop_->BelongsToCurrentThread());
166 DCHECK_EQ(state_, kDecryptorRequested) << state_; 168 DCHECK_EQ(state_, kDecryptorRequested) << state_;
167 DCHECK(!init_cb_.is_null()); 169 DCHECK(!init_cb_.is_null());
168 DCHECK(!set_decryptor_ready_cb_.is_null()); 170 DCHECK(!set_decryptor_ready_cb_.is_null());
169 171
170 set_decryptor_ready_cb_.Reset(); 172 set_decryptor_ready_cb_.Reset();
171 decryptor_ = decryptor; 173 decryptor_ = decryptor;
172 174
175 const AudioDecoderConfig& input_config =
176 demuxer_stream_->audio_decoder_config();
173 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig()); 177 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig());
174 scoped_config->CopyFrom(demuxer_stream_->audio_decoder_config()); 178 scoped_config->Initialize(input_config.codec(),
179 kSampleFormatS16,
180 input_config.channel_layout(),
181 input_config.samples_per_second(),
182 input_config.extra_data(),
183 input_config.extra_data_size(),
184 input_config.is_encrypted(),
185 false);
175 186
176 state_ = kPendingDecoderInit; 187 state_ = kPendingDecoderInit;
177 decryptor_->InitializeAudioDecoder( 188 decryptor_->InitializeAudioDecoder(
178 scoped_config.Pass(), 189 scoped_config.Pass(),
179 BIND_TO_LOOP(&DecryptingAudioDecoder::FinishInitialization)); 190 BIND_TO_LOOP(&DecryptingAudioDecoder::FinishInitialization));
180 } 191 }
181 192
182 void DecryptingAudioDecoder::FinishInitialization(bool success) { 193 void DecryptingAudioDecoder::FinishInitialization(bool success) {
183 DVLOG(2) << "FinishInitialization()"; 194 DVLOG(2) << "FinishInitialization()";
184 DCHECK(message_loop_->BelongsToCurrentThread()); 195 DCHECK(message_loop_->BelongsToCurrentThread());
185 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 196 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
186 DCHECK(!init_cb_.is_null()); 197 DCHECK(!init_cb_.is_null());
187 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 198 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
188 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. 199 DCHECK(read_cb_.is_null()); // No Read() before initialization finished.
189 200
190 if (!success) { 201 if (!success) {
191 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 202 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
192 state_ = kDecodeFinished; 203 state_ = kDecodeFinished;
193 return; 204 return;
194 } 205 }
195 206
196 // Success! 207 // Success!
197 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); 208 SetDecoderConfig();
198 bits_per_channel_ = config.bits_per_channel();
199 channel_layout_ = config.channel_layout();
200 samples_per_second_ = config.samples_per_second();
201 const int kBitsPerByte = 8;
202 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) *
203 bits_per_channel_ / kBitsPerByte;
204 209
205 decryptor_->RegisterNewKeyCB( 210 decryptor_->RegisterNewKeyCB(
206 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded)); 211 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded));
207 212
208 state_ = kIdle; 213 state_ = kIdle;
209 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 214 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
210 } 215 }
211 216
212 void DecryptingAudioDecoder::FinishConfigChange(bool success) { 217 void DecryptingAudioDecoder::FinishConfigChange(bool success) {
213 DVLOG(2) << "FinishConfigChange()"; 218 DVLOG(2) << "FinishConfigChange()";
214 DCHECK(message_loop_->BelongsToCurrentThread()); 219 DCHECK(message_loop_->BelongsToCurrentThread());
215 DCHECK_EQ(state_, kPendingConfigChange) << state_; 220 DCHECK_EQ(state_, kPendingConfigChange) << state_;
216 DCHECK(!read_cb_.is_null()); 221 DCHECK(!read_cb_.is_null());
217 222
218 if (!success) { 223 if (!success) {
219 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 224 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
220 state_ = kDecodeFinished; 225 state_ = kDecodeFinished;
221 if (!reset_cb_.is_null()) 226 if (!reset_cb_.is_null())
222 base::ResetAndReturn(&reset_cb_).Run(); 227 base::ResetAndReturn(&reset_cb_).Run();
223 return; 228 return;
224 } 229 }
225 230
226 // Config change succeeded. 231 // Config change succeeded.
232 SetDecoderConfig();
DaleCurtis 2013/01/10 01:24:35 Is this a bug fix?
xhwang 2013/01/10 18:17:23 Hmm, yes, filed bug and split this change to https
233
227 if (!reset_cb_.is_null()) { 234 if (!reset_cb_.is_null()) {
228 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 235 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
229 DoReset(); 236 DoReset();
230 return; 237 return;
231 } 238 }
232 239
233 state_ = kPendingDemuxerRead; 240 state_ = kPendingDemuxerRead;
234 ReadFromDemuxerStream(); 241 ReadFromDemuxerStream();
235 } 242 }
236 243
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 285 }
279 286
280 DVLOG(3) << "DoDecryptAndDecodeBuffer()"; 287 DVLOG(3) << "DoDecryptAndDecodeBuffer()";
281 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 288 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
282 DCHECK(!read_cb_.is_null()); 289 DCHECK(!read_cb_.is_null());
283 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; 290 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
284 291
285 if (status == DemuxerStream::kConfigChanged) { 292 if (status == DemuxerStream::kConfigChanged) {
286 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged"; 293 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged";
287 294
288 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig()); 295 const AudioDecoderConfig& input_config =
289 scoped_config->CopyFrom(demuxer_stream_->audio_decoder_config()); 296 demuxer_stream_->audio_decoder_config();
297 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig());
298 scoped_config->Initialize(input_config.codec(),
299 kSampleFormatS16,
300 input_config.channel_layout(),
301 input_config.samples_per_second(),
302 input_config.extra_data(),
303 input_config.extra_data_size(),
304 input_config.is_encrypted(),
305 false);
290 306
291 state_ = kPendingConfigChange; 307 state_ = kPendingConfigChange;
292 decryptor_->DeinitializeDecoder(Decryptor::kAudio); 308 decryptor_->DeinitializeDecoder(Decryptor::kAudio);
293 decryptor_->InitializeAudioDecoder( 309 decryptor_->InitializeAudioDecoder(
294 scoped_config.Pass(), BindToCurrentLoop(base::Bind( 310 scoped_config.Pass(), BindToCurrentLoop(base::Bind(
295 &DecryptingAudioDecoder::FinishConfigChange, this))); 311 &DecryptingAudioDecoder::FinishConfigChange, this)));
296 return; 312 return;
297 } 313 }
298 314
299 if (!reset_cb_.is_null()) { 315 if (!reset_cb_.is_null()) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 456
441 void DecryptingAudioDecoder::DoReset() { 457 void DecryptingAudioDecoder::DoReset() {
442 DCHECK(init_cb_.is_null()); 458 DCHECK(init_cb_.is_null());
443 DCHECK(read_cb_.is_null()); 459 DCHECK(read_cb_.is_null());
444 output_timestamp_base_ = kNoTimestamp(); 460 output_timestamp_base_ = kNoTimestamp();
445 total_samples_decoded_ = 0; 461 total_samples_decoded_ = 0;
446 state_ = kIdle; 462 state_ = kIdle;
447 base::ResetAndReturn(&reset_cb_).Run(); 463 base::ResetAndReturn(&reset_cb_).Run();
448 } 464 }
449 465
466 void DecryptingAudioDecoder::SetDecoderConfig() {
467 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config();
468 bits_per_channel_ = kSupportedBitsPerChannel;
469 channel_layout_ = config.channel_layout();
470 samples_per_second_ = config.samples_per_second();
471 const int kBitsPerByte = 8;
472 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) *
473 bits_per_channel_ / kBitsPerByte;
474 output_timestamp_base_ = kNoTimestamp();
475 total_samples_decoded_ = 0;
476 }
477
450 void DecryptingAudioDecoder::EnqueueFrames( 478 void DecryptingAudioDecoder::EnqueueFrames(
451 const Decryptor::AudioBuffers& frames) { 479 const Decryptor::AudioBuffers& frames) {
452 queued_audio_frames_ = frames; 480 queued_audio_frames_ = frames;
453 481
454 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin(); 482 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin();
455 iter != queued_audio_frames_.end(); 483 iter != queued_audio_frames_.end();
456 ++iter) { 484 ++iter) {
457 scoped_refptr<Buffer>& frame = *iter; 485 scoped_refptr<Buffer>& frame = *iter;
458 486
459 DCHECK(!frame->IsEndOfStream()) << "EOS frame returned."; 487 DCHECK(!frame->IsEndOfStream()) << "EOS frame returned.";
(...skipping 24 matching lines...) Expand all
484 512
485 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration( 513 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration(
486 int number_of_samples) const { 514 int number_of_samples) const {
487 DCHECK(samples_per_second_); 515 DCHECK(samples_per_second_);
488 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond * 516 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond *
489 number_of_samples / 517 number_of_samples /
490 samples_per_second_); 518 samples_per_second_);
491 } 519 }
492 520
493 } // namespace media 521 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698