Cast: Skip receiver log messages with time delta that can't be encoded.
[chromium-blink-merge.git] / media / filters / decrypting_audio_decoder.cc
bloba96c9dba0c5f92c89184a231d512ce93be5657e3
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"
7 #include <cstdlib>
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/single_thread_task_runner.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_current_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"
24 namespace media {
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
31 // drift below that.
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::SingleThreadTaskRunner>& task_runner,
39 const SetDecryptorReadyCB& set_decryptor_ready_cb)
40 : task_runner_(task_runner),
41 weak_factory_(this),
42 state_(kUninitialized),
43 demuxer_stream_(NULL),
44 set_decryptor_ready_cb_(set_decryptor_ready_cb),
45 decryptor_(NULL),
46 key_added_while_decode_pending_(false),
47 bits_per_channel_(0),
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(task_runner_->BelongsToCurrentThread());
58 DCHECK_EQ(state_, kUninitialized) << state_;
59 DCHECK(stream);
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);
68 return;
71 // DecryptingAudioDecoder only accepts potentially encrypted stream.
72 if (!config.is_encrypted()) {
73 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
74 return;
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) {
87 DVLOG(3) << "Read()";
88 DCHECK(task_runner_->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());
98 return;
101 if (!queued_audio_frames_.empty()) {
102 base::ResetAndReturn(&read_cb_).Run(kOk, queued_audio_frames_.front());
103 queued_audio_frames_.pop_front();
104 return;
107 state_ = kPendingDemuxerRead;
108 ReadFromDemuxerStream();
111 void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
112 DVLOG(2) << "Reset() - state: " << state_;
113 DCHECK(task_runner_->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());
123 reset_cb_ = BindToCurrentLoop(closure);
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
130 // DeliverFrame().
131 if (state_ == kPendingConfigChange ||
132 state_ == kPendingDemuxerRead ||
133 state_ == kPendingDecode) {
134 DCHECK(!read_cb_.is_null());
135 return;
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());
145 DoReset();
148 void DecryptingAudioDecoder::Stop(const base::Closure& closure) {
149 DVLOG(2) << "Stop() - state: " << state_;
150 DCHECK(task_runner_->BelongsToCurrentThread());
152 // Invalidate all weak pointers so that pending callbacks won't be fired into
153 // this object.
154 weak_factory_.InvalidateWeakPtrs();
156 if (decryptor_) {
157 decryptor_->DeinitializeDecoder(Decryptor::kAudio);
158 decryptor_ = NULL;
160 if (!set_decryptor_ready_cb_.is_null())
161 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB());
162 pending_buffer_to_decode_ = NULL;
163 if (!init_cb_.is_null())
164 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
165 if (!read_cb_.is_null())
166 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
167 if (!reset_cb_.is_null())
168 base::ResetAndReturn(&reset_cb_).Run();
170 state_ = kStopped;
171 task_runner_->PostTask(FROM_HERE, closure);
174 int DecryptingAudioDecoder::bits_per_channel() {
175 DCHECK(task_runner_->BelongsToCurrentThread());
176 return bits_per_channel_;
179 ChannelLayout DecryptingAudioDecoder::channel_layout() {
180 DCHECK(task_runner_->BelongsToCurrentThread());
181 return channel_layout_;
184 int DecryptingAudioDecoder::samples_per_second() {
185 DCHECK(task_runner_->BelongsToCurrentThread());
186 return samples_per_second_;
189 DecryptingAudioDecoder::~DecryptingAudioDecoder() {
190 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_;
193 void DecryptingAudioDecoder::SetDecryptor(Decryptor* decryptor) {
194 DVLOG(2) << "SetDecryptor()";
195 DCHECK(task_runner_->BelongsToCurrentThread());
196 DCHECK_EQ(state_, kDecryptorRequested) << state_;
197 DCHECK(!init_cb_.is_null());
198 DCHECK(!set_decryptor_ready_cb_.is_null());
200 set_decryptor_ready_cb_.Reset();
202 if (!decryptor) {
203 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
204 // TODO(xhwang): Add kError state. See http://crbug.com/251503
205 state_ = kStopped;
206 return;
209 decryptor_ = decryptor;
211 const AudioDecoderConfig& input_config =
212 demuxer_stream_->audio_decoder_config();
213 AudioDecoderConfig config;
214 config.Initialize(input_config.codec(),
215 kSampleFormatS16,
216 input_config.channel_layout(),
217 input_config.samples_per_second(),
218 input_config.extra_data(),
219 input_config.extra_data_size(),
220 input_config.is_encrypted(),
221 false,
222 base::TimeDelta(),
223 base::TimeDelta());
225 state_ = kPendingDecoderInit;
226 decryptor_->InitializeAudioDecoder(
227 config,
228 BindToCurrentLoop(base::Bind(
229 &DecryptingAudioDecoder::FinishInitialization, weak_this_)));
232 void DecryptingAudioDecoder::FinishInitialization(bool success) {
233 DVLOG(2) << "FinishInitialization()";
234 DCHECK(task_runner_->BelongsToCurrentThread());
235 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
236 DCHECK(!init_cb_.is_null());
237 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
238 DCHECK(read_cb_.is_null()); // No Read() before initialization finished.
240 if (!success) {
241 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
242 state_ = kStopped;
243 return;
246 // Success!
247 UpdateDecoderConfig();
249 decryptor_->RegisterNewKeyCB(
250 Decryptor::kAudio,
251 BindToCurrentLoop(
252 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_)));
254 state_ = kIdle;
255 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
258 void DecryptingAudioDecoder::FinishConfigChange(bool success) {
259 DVLOG(2) << "FinishConfigChange()";
260 DCHECK(task_runner_->BelongsToCurrentThread());
261 DCHECK_EQ(state_, kPendingConfigChange) << state_;
262 DCHECK(!read_cb_.is_null());
264 if (!success) {
265 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
266 state_ = kDecodeFinished;
267 if (!reset_cb_.is_null())
268 base::ResetAndReturn(&reset_cb_).Run();
269 return;
272 // Config change succeeded.
273 UpdateDecoderConfig();
275 if (!reset_cb_.is_null()) {
276 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
277 DoReset();
278 return;
281 state_ = kPendingDemuxerRead;
282 ReadFromDemuxerStream();
285 void DecryptingAudioDecoder::ReadFromDemuxerStream() {
286 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
287 DCHECK(!read_cb_.is_null());
289 demuxer_stream_->Read(
290 base::Bind(&DecryptingAudioDecoder::DecryptAndDecodeBuffer, weak_this_));
293 void DecryptingAudioDecoder::DecryptAndDecodeBuffer(
294 DemuxerStream::Status status,
295 const scoped_refptr<DecoderBuffer>& buffer) {
296 DVLOG(3) << "DecryptAndDecodeBuffer()";
297 DCHECK(task_runner_->BelongsToCurrentThread());
298 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
299 DCHECK(!read_cb_.is_null());
300 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
302 if (status == DemuxerStream::kConfigChanged) {
303 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged";
305 const AudioDecoderConfig& input_config =
306 demuxer_stream_->audio_decoder_config();
307 AudioDecoderConfig config;
308 config.Initialize(input_config.codec(),
309 kSampleFormatS16,
310 input_config.channel_layout(),
311 input_config.samples_per_second(),
312 input_config.extra_data(),
313 input_config.extra_data_size(),
314 input_config.is_encrypted(),
315 false,
316 base::TimeDelta(),
317 base::TimeDelta());
319 state_ = kPendingConfigChange;
320 decryptor_->DeinitializeDecoder(Decryptor::kAudio);
321 decryptor_->InitializeAudioDecoder(
322 config, BindToCurrentLoop(base::Bind(
323 &DecryptingAudioDecoder::FinishConfigChange, weak_this_)));
324 return;
327 if (!reset_cb_.is_null()) {
328 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
329 DoReset();
330 return;
333 if (status == DemuxerStream::kAborted) {
334 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
335 state_ = kIdle;
336 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
337 return;
340 DCHECK_EQ(status, DemuxerStream::kOk);
342 // Initialize the |next_output_timestamp_| to be the timestamp of the first
343 // non-EOS buffer.
344 if (timestamp_helper_->base_timestamp() == kNoTimestamp() &&
345 !buffer->end_of_stream()) {
346 timestamp_helper_->SetBaseTimestamp(buffer->timestamp());
349 pending_buffer_to_decode_ = buffer;
350 state_ = kPendingDecode;
351 DecodePendingBuffer();
354 void DecryptingAudioDecoder::DecodePendingBuffer() {
355 DCHECK(task_runner_->BelongsToCurrentThread());
356 DCHECK_EQ(state_, kPendingDecode) << state_;
358 int buffer_size = 0;
359 if (!pending_buffer_to_decode_->end_of_stream()) {
360 buffer_size = pending_buffer_to_decode_->data_size();
363 decryptor_->DecryptAndDecodeAudio(
364 pending_buffer_to_decode_,
365 BindToCurrentLoop(base::Bind(
366 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size)));
369 void DecryptingAudioDecoder::DeliverFrame(
370 int buffer_size,
371 Decryptor::Status status,
372 const Decryptor::AudioBuffers& frames) {
373 DVLOG(3) << "DeliverFrame() - status: " << status;
374 DCHECK(task_runner_->BelongsToCurrentThread());
375 DCHECK_EQ(state_, kPendingDecode) << state_;
376 DCHECK(!read_cb_.is_null());
377 DCHECK(pending_buffer_to_decode_.get());
378 DCHECK(queued_audio_frames_.empty());
380 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
381 key_added_while_decode_pending_ = false;
383 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode =
384 pending_buffer_to_decode_;
385 pending_buffer_to_decode_ = NULL;
387 if (!reset_cb_.is_null()) {
388 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
389 DoReset();
390 return;
393 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty());
395 if (status == Decryptor::kError) {
396 DVLOG(2) << "DeliverFrame() - kError";
397 state_ = kDecodeFinished;
398 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
399 return;
402 if (status == Decryptor::kNoKey) {
403 DVLOG(2) << "DeliverFrame() - kNoKey";
404 // Set |pending_buffer_to_decode_| back as we need to try decoding the
405 // pending buffer again when new key is added to the decryptor.
406 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
408 if (need_to_try_again_if_nokey_is_returned) {
409 // The |state_| is still kPendingDecode.
410 DecodePendingBuffer();
411 return;
414 state_ = kWaitingForKey;
415 return;
418 // The buffer has been accepted by the decoder, let's report statistics.
419 if (buffer_size) {
420 PipelineStatistics statistics;
421 statistics.audio_bytes_decoded = buffer_size;
422 statistics_cb_.Run(statistics);
425 if (status == Decryptor::kNeedMoreData) {
426 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
427 if (scoped_pending_buffer_to_decode->end_of_stream()) {
428 state_ = kDecodeFinished;
429 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer());
430 return;
433 state_ = kPendingDemuxerRead;
434 ReadFromDemuxerStream();
435 return;
438 DCHECK_EQ(status, Decryptor::kSuccess);
439 DCHECK(!frames.empty());
440 EnqueueFrames(frames);
442 state_ = kIdle;
443 base::ResetAndReturn(&read_cb_).Run(kOk, queued_audio_frames_.front());
444 queued_audio_frames_.pop_front();
447 void DecryptingAudioDecoder::OnKeyAdded() {
448 DCHECK(task_runner_->BelongsToCurrentThread());
450 if (state_ == kPendingDecode) {
451 key_added_while_decode_pending_ = true;
452 return;
455 if (state_ == kWaitingForKey) {
456 state_ = kPendingDecode;
457 DecodePendingBuffer();
461 void DecryptingAudioDecoder::DoReset() {
462 DCHECK(init_cb_.is_null());
463 DCHECK(read_cb_.is_null());
464 timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
465 state_ = kIdle;
466 base::ResetAndReturn(&reset_cb_).Run();
469 void DecryptingAudioDecoder::UpdateDecoderConfig() {
470 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config();
471 bits_per_channel_ = kSupportedBitsPerChannel;
472 channel_layout_ = config.channel_layout();
473 samples_per_second_ = config.samples_per_second();
474 timestamp_helper_.reset(new AudioTimestampHelper(samples_per_second_));
477 void DecryptingAudioDecoder::EnqueueFrames(
478 const Decryptor::AudioBuffers& frames) {
479 queued_audio_frames_ = frames;
481 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin();
482 iter != queued_audio_frames_.end();
483 ++iter) {
484 scoped_refptr<AudioBuffer>& frame = *iter;
486 DCHECK(!frame->end_of_stream()) << "EOS frame returned.";
487 DCHECK_GT(frame->frame_count(), 0) << "Empty frame returned.";
489 base::TimeDelta current_time = timestamp_helper_->GetTimestamp();
490 if (IsOutOfSync(current_time, frame->timestamp())) {
491 DVLOG(1) << "Timestamp returned by the decoder ("
492 << frame->timestamp().InMilliseconds() << " ms)"
493 << " does not match the input timestamp and number of samples"
494 << " decoded (" << current_time.InMilliseconds() << " ms).";
497 frame->set_timestamp(current_time);
498 frame->set_duration(
499 timestamp_helper_->GetFrameDuration(frame->frame_count()));
500 timestamp_helper_->AddFrames(frame->frame_count());
504 } // namespace media