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
3 // found in the LICENSE file.
5 #include "media/filters/decrypting_audio_decoder.h"
10 #include "base/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "media/base/audio_buffer.h"
15 #include "media/base/audio_decoder_config.h"
16 #include "media/base/audio_timestamp_helper.h"
17 #include "media/base/bind_to_loop.h"
18 #include "media/base/buffers.h"
19 #include "media/base/decoder_buffer.h"
20 #include "media/base/decryptor.h"
21 #include "media/base/demuxer_stream.h"
22 #include "media/base/pipeline.h"
26 const int DecryptingAudioDecoder::kSupportedBitsPerChannel
= 16;
28 static inline bool IsOutOfSync(const base::TimeDelta
& timestamp_1
,
29 const base::TimeDelta
& timestamp_2
) {
30 // Out of sync of 100ms would be pretty noticeable and we should keep any
32 const int64 kOutOfSyncThresholdInMilliseconds
= 100;
33 return std::abs(timestamp_1
.InMilliseconds() - timestamp_2
.InMilliseconds()) >
34 kOutOfSyncThresholdInMilliseconds
;
37 DecryptingAudioDecoder::DecryptingAudioDecoder(
38 const scoped_refptr
<base::MessageLoopProxy
>& message_loop
,
39 const SetDecryptorReadyCB
& set_decryptor_ready_cb
)
40 : message_loop_(message_loop
),
42 state_(kUninitialized
),
43 demuxer_stream_(NULL
),
44 set_decryptor_ready_cb_(set_decryptor_ready_cb
),
46 key_added_while_decode_pending_(false),
48 channel_layout_(CHANNEL_LAYOUT_NONE
),
49 samples_per_second_(0) {
52 void DecryptingAudioDecoder::Initialize(
53 DemuxerStream
* stream
,
54 const PipelineStatusCB
& status_cb
,
55 const StatisticsCB
& statistics_cb
) {
56 DVLOG(2) << "Initialize()";
57 DCHECK(message_loop_
->BelongsToCurrentThread());
58 DCHECK_EQ(state_
, kUninitialized
) << state_
;
61 weak_this_
= weak_factory_
.GetWeakPtr();
62 init_cb_
= BindToCurrentLoop(status_cb
);
64 const AudioDecoderConfig
& config
= stream
->audio_decoder_config();
65 if (!config
.IsValidConfig()) {
66 DLOG(ERROR
) << "Invalid audio stream config.";
67 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_ERROR_DECODE
);
71 // DecryptingAudioDecoder only accepts potentially encrypted stream.
72 if (!config
.is_encrypted()) {
73 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
77 DCHECK(!demuxer_stream_
);
78 demuxer_stream_
= stream
;
79 statistics_cb_
= statistics_cb
;
81 state_
= kDecryptorRequested
;
82 set_decryptor_ready_cb_
.Run(BindToCurrentLoop(
83 base::Bind(&DecryptingAudioDecoder::SetDecryptor
, weak_this_
)));
86 void DecryptingAudioDecoder::Read(const ReadCB
& read_cb
) {
88 DCHECK(message_loop_
->BelongsToCurrentThread());
89 DCHECK(state_
== kIdle
|| state_
== kDecodeFinished
) << state_
;
90 DCHECK(!read_cb
.is_null());
91 CHECK(read_cb_
.is_null()) << "Overlapping decodes are not supported.";
93 read_cb_
= BindToCurrentLoop(read_cb
);
95 // Return empty (end-of-stream) frames if decoding has finished.
96 if (state_
== kDecodeFinished
) {
97 base::ResetAndReturn(&read_cb_
).Run(kOk
, AudioBuffer::CreateEOSBuffer());
101 if (!queued_audio_frames_
.empty()) {
102 base::ResetAndReturn(&read_cb_
).Run(kOk
, queued_audio_frames_
.front());
103 queued_audio_frames_
.pop_front();
107 state_
= kPendingDemuxerRead
;
108 ReadFromDemuxerStream();
111 void DecryptingAudioDecoder::Reset(const base::Closure
& closure
) {
112 DVLOG(2) << "Reset() - state: " << state_
;
113 DCHECK(message_loop_
->BelongsToCurrentThread());
114 DCHECK(state_
== kIdle
||
115 state_
== kPendingConfigChange
||
116 state_
== kPendingDemuxerRead
||
117 state_
== kPendingDecode
||
118 state_
== kWaitingForKey
||
119 state_
== kDecodeFinished
) << state_
;
120 DCHECK(init_cb_
.is_null()); // No Reset() during pending initialization.
121 DCHECK(reset_cb_
.is_null());
125 decryptor_
->ResetDecoder(Decryptor::kAudio
);
127 // Reset() cannot complete if the read callback is still pending.
128 // Defer the resetting process in this case. The |reset_cb_| will be fired
129 // after the read callback is fired - see DecryptAndDecodeBuffer() and
131 if (state_
== kPendingConfigChange
||
132 state_
== kPendingDemuxerRead
||
133 state_
== kPendingDecode
) {
134 DCHECK(!read_cb_
.is_null());
138 if (state_
== kWaitingForKey
) {
139 DCHECK(!read_cb_
.is_null());
140 pending_buffer_to_decode_
= NULL
;
141 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
144 DCHECK(read_cb_
.is_null());
148 int DecryptingAudioDecoder::bits_per_channel() {
149 DCHECK(message_loop_
->BelongsToCurrentThread());
150 return bits_per_channel_
;
153 ChannelLayout
DecryptingAudioDecoder::channel_layout() {
154 DCHECK(message_loop_
->BelongsToCurrentThread());
155 return channel_layout_
;
158 int DecryptingAudioDecoder::samples_per_second() {
159 DCHECK(message_loop_
->BelongsToCurrentThread());
160 return samples_per_second_
;
163 DecryptingAudioDecoder::~DecryptingAudioDecoder() {
166 void DecryptingAudioDecoder::SetDecryptor(Decryptor
* decryptor
) {
167 DVLOG(2) << "SetDecryptor()";
168 DCHECK(message_loop_
->BelongsToCurrentThread());
169 DCHECK_EQ(state_
, kDecryptorRequested
) << state_
;
170 DCHECK(!init_cb_
.is_null());
171 DCHECK(!set_decryptor_ready_cb_
.is_null());
173 set_decryptor_ready_cb_
.Reset();
176 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
177 // TODO(xhwang): Add kError state. See http://crbug.com/251503
178 state_
= kDecodeFinished
;
182 decryptor_
= decryptor
;
184 const AudioDecoderConfig
& input_config
=
185 demuxer_stream_
->audio_decoder_config();
186 AudioDecoderConfig config
;
187 config
.Initialize(input_config
.codec(),
189 input_config
.channel_layout(),
190 input_config
.samples_per_second(),
191 input_config
.extra_data(),
192 input_config
.extra_data_size(),
193 input_config
.is_encrypted(),
198 state_
= kPendingDecoderInit
;
199 decryptor_
->InitializeAudioDecoder(
201 BindToCurrentLoop(base::Bind(
202 &DecryptingAudioDecoder::FinishInitialization
, weak_this_
)));
205 void DecryptingAudioDecoder::FinishInitialization(bool success
) {
206 DVLOG(2) << "FinishInitialization()";
207 DCHECK(message_loop_
->BelongsToCurrentThread());
208 DCHECK_EQ(state_
, kPendingDecoderInit
) << state_
;
209 DCHECK(!init_cb_
.is_null());
210 DCHECK(reset_cb_
.is_null()); // No Reset() before initialization finished.
211 DCHECK(read_cb_
.is_null()); // No Read() before initialization finished.
214 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
215 state_
= kDecodeFinished
;
220 UpdateDecoderConfig();
222 decryptor_
->RegisterNewKeyCB(
223 Decryptor::kAudio
, BindToCurrentLoop(base::Bind(
224 &DecryptingAudioDecoder::OnKeyAdded
, weak_this_
)));
227 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_OK
);
230 void DecryptingAudioDecoder::FinishConfigChange(bool success
) {
231 DVLOG(2) << "FinishConfigChange()";
232 DCHECK(message_loop_
->BelongsToCurrentThread());
233 DCHECK_EQ(state_
, kPendingConfigChange
) << state_
;
234 DCHECK(!read_cb_
.is_null());
237 base::ResetAndReturn(&read_cb_
).Run(kDecodeError
, NULL
);
238 state_
= kDecodeFinished
;
239 if (!reset_cb_
.is_null())
240 base::ResetAndReturn(&reset_cb_
).Run();
244 // Config change succeeded.
245 UpdateDecoderConfig();
247 if (!reset_cb_
.is_null()) {
248 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
253 state_
= kPendingDemuxerRead
;
254 ReadFromDemuxerStream();
257 void DecryptingAudioDecoder::ReadFromDemuxerStream() {
258 DCHECK_EQ(state_
, kPendingDemuxerRead
) << state_
;
259 DCHECK(!read_cb_
.is_null());
261 demuxer_stream_
->Read(
262 base::Bind(&DecryptingAudioDecoder::DecryptAndDecodeBuffer
, weak_this_
));
265 void DecryptingAudioDecoder::DecryptAndDecodeBuffer(
266 DemuxerStream::Status status
,
267 const scoped_refptr
<DecoderBuffer
>& buffer
) {
268 DVLOG(3) << "DecryptAndDecodeBuffer()";
269 DCHECK(message_loop_
->BelongsToCurrentThread());
270 DCHECK_EQ(state_
, kPendingDemuxerRead
) << state_
;
271 DCHECK(!read_cb_
.is_null());
272 DCHECK_EQ(buffer
.get() != NULL
, status
== DemuxerStream::kOk
) << status
;
274 if (status
== DemuxerStream::kConfigChanged
) {
275 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged";
277 const AudioDecoderConfig
& input_config
=
278 demuxer_stream_
->audio_decoder_config();
279 AudioDecoderConfig config
;
280 config
.Initialize(input_config
.codec(),
282 input_config
.channel_layout(),
283 input_config
.samples_per_second(),
284 input_config
.extra_data(),
285 input_config
.extra_data_size(),
286 input_config
.is_encrypted(),
291 state_
= kPendingConfigChange
;
292 decryptor_
->DeinitializeDecoder(Decryptor::kAudio
);
293 decryptor_
->InitializeAudioDecoder(
294 config
, BindToCurrentLoop(base::Bind(
295 &DecryptingAudioDecoder::FinishConfigChange
, weak_this_
)));
299 if (!reset_cb_
.is_null()) {
300 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
305 if (status
== DemuxerStream::kAborted
) {
306 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
308 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
312 DCHECK_EQ(status
, DemuxerStream::kOk
);
314 // Initialize the |next_output_timestamp_| to be the timestamp of the first
316 if (timestamp_helper_
->base_timestamp() == kNoTimestamp() &&
317 !buffer
->end_of_stream()) {
318 timestamp_helper_
->SetBaseTimestamp(buffer
->timestamp());
321 pending_buffer_to_decode_
= buffer
;
322 state_
= kPendingDecode
;
323 DecodePendingBuffer();
326 void DecryptingAudioDecoder::DecodePendingBuffer() {
327 DCHECK(message_loop_
->BelongsToCurrentThread());
328 DCHECK_EQ(state_
, kPendingDecode
) << state_
;
331 if (!pending_buffer_to_decode_
->end_of_stream()) {
332 buffer_size
= pending_buffer_to_decode_
->data_size();
335 decryptor_
->DecryptAndDecodeAudio(
336 pending_buffer_to_decode_
,
337 BindToCurrentLoop(base::Bind(
338 &DecryptingAudioDecoder::DeliverFrame
, weak_this_
, buffer_size
)));
341 void DecryptingAudioDecoder::DeliverFrame(
343 Decryptor::Status status
,
344 const Decryptor::AudioBuffers
& frames
) {
345 DVLOG(3) << "DeliverFrame() - status: " << status
;
346 DCHECK(message_loop_
->BelongsToCurrentThread());
347 DCHECK_EQ(state_
, kPendingDecode
) << state_
;
348 DCHECK(!read_cb_
.is_null());
349 DCHECK(pending_buffer_to_decode_
.get());
350 DCHECK(queued_audio_frames_
.empty());
352 bool need_to_try_again_if_nokey_is_returned
= key_added_while_decode_pending_
;
353 key_added_while_decode_pending_
= false;
355 scoped_refptr
<DecoderBuffer
> scoped_pending_buffer_to_decode
=
356 pending_buffer_to_decode_
;
357 pending_buffer_to_decode_
= NULL
;
359 if (!reset_cb_
.is_null()) {
360 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
365 DCHECK_EQ(status
== Decryptor::kSuccess
, !frames
.empty());
367 if (status
== Decryptor::kError
) {
368 DVLOG(2) << "DeliverFrame() - kError";
369 state_
= kDecodeFinished
;
370 base::ResetAndReturn(&read_cb_
).Run(kDecodeError
, NULL
);
374 if (status
== Decryptor::kNoKey
) {
375 DVLOG(2) << "DeliverFrame() - kNoKey";
376 // Set |pending_buffer_to_decode_| back as we need to try decoding the
377 // pending buffer again when new key is added to the decryptor.
378 pending_buffer_to_decode_
= scoped_pending_buffer_to_decode
;
380 if (need_to_try_again_if_nokey_is_returned
) {
381 // The |state_| is still kPendingDecode.
382 DecodePendingBuffer();
386 state_
= kWaitingForKey
;
390 // The buffer has been accepted by the decoder, let's report statistics.
392 PipelineStatistics statistics
;
393 statistics
.audio_bytes_decoded
= buffer_size
;
394 statistics_cb_
.Run(statistics
);
397 if (status
== Decryptor::kNeedMoreData
) {
398 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
399 if (scoped_pending_buffer_to_decode
->end_of_stream()) {
400 state_
= kDecodeFinished
;
401 base::ResetAndReturn(&read_cb_
).Run(kOk
, AudioBuffer::CreateEOSBuffer());
405 state_
= kPendingDemuxerRead
;
406 ReadFromDemuxerStream();
410 DCHECK_EQ(status
, Decryptor::kSuccess
);
411 DCHECK(!frames
.empty());
412 EnqueueFrames(frames
);
415 base::ResetAndReturn(&read_cb_
).Run(kOk
, queued_audio_frames_
.front());
416 queued_audio_frames_
.pop_front();
419 void DecryptingAudioDecoder::OnKeyAdded() {
420 DCHECK(message_loop_
->BelongsToCurrentThread());
422 if (state_
== kPendingDecode
) {
423 key_added_while_decode_pending_
= true;
427 if (state_
== kWaitingForKey
) {
428 state_
= kPendingDecode
;
429 DecodePendingBuffer();
433 void DecryptingAudioDecoder::DoReset() {
434 DCHECK(init_cb_
.is_null());
435 DCHECK(read_cb_
.is_null());
436 timestamp_helper_
->SetBaseTimestamp(kNoTimestamp());
438 base::ResetAndReturn(&reset_cb_
).Run();
441 void DecryptingAudioDecoder::UpdateDecoderConfig() {
442 const AudioDecoderConfig
& config
= demuxer_stream_
->audio_decoder_config();
443 bits_per_channel_
= kSupportedBitsPerChannel
;
444 channel_layout_
= config
.channel_layout();
445 samples_per_second_
= config
.samples_per_second();
446 timestamp_helper_
.reset(new AudioTimestampHelper(samples_per_second_
));
449 void DecryptingAudioDecoder::EnqueueFrames(
450 const Decryptor::AudioBuffers
& frames
) {
451 queued_audio_frames_
= frames
;
453 for (Decryptor::AudioBuffers::iterator iter
= queued_audio_frames_
.begin();
454 iter
!= queued_audio_frames_
.end();
456 scoped_refptr
<AudioBuffer
>& frame
= *iter
;
458 DCHECK(!frame
->end_of_stream()) << "EOS frame returned.";
459 DCHECK_GT(frame
->frame_count(), 0) << "Empty frame returned.";
461 base::TimeDelta current_time
= timestamp_helper_
->GetTimestamp();
462 if (IsOutOfSync(current_time
, frame
->timestamp())) {
463 DVLOG(1) << "Timestamp returned by the decoder ("
464 << frame
->timestamp().InMilliseconds() << " ms)"
465 << " does not match the input timestamp and number of samples"
466 << " decoded (" << current_time
.InMilliseconds() << " ms).";
469 frame
->set_timestamp(current_time
);
471 timestamp_helper_
->GetFrameDuration(frame
->frame_count()));
472 timestamp_helper_
->AddFrames(frame
->frame_count());