OLD | NEW |
---|---|
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/opus_audio_decoder.h" | 5 #include "media/filters/opus_audio_decoder.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
249 | 249 |
250 for (int i = 0; i < extra_data->channels; ++i) | 250 for (int i = 0; i < extra_data->channels; ++i) |
251 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i); | 251 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i); |
252 return true; | 252 return true; |
253 } | 253 } |
254 | 254 |
255 OpusAudioDecoder::OpusAudioDecoder( | 255 OpusAudioDecoder::OpusAudioDecoder( |
256 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | 256 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) |
257 : task_runner_(task_runner), | 257 : task_runner_(task_runner), |
258 weak_factory_(this), | 258 weak_factory_(this), |
259 demuxer_stream_(NULL), | |
260 opus_decoder_(NULL), | 259 opus_decoder_(NULL), |
261 channel_layout_(CHANNEL_LAYOUT_NONE), | 260 channel_layout_(CHANNEL_LAYOUT_NONE), |
262 samples_per_second_(0), | 261 samples_per_second_(0), |
263 sample_format_(kSampleFormatF32), | 262 sample_format_(kSampleFormatF32), |
264 bits_per_channel_(SampleFormatToBytesPerChannel(sample_format_) * 8), | 263 bits_per_channel_(SampleFormatToBytesPerChannel(sample_format_) * 8), |
265 last_input_timestamp_(kNoTimestamp()), | 264 last_input_timestamp_(kNoTimestamp()), |
266 frames_to_discard_(0), | 265 frames_to_discard_(0), |
267 frame_delay_at_start_(0), | 266 frame_delay_at_start_(0), |
268 start_input_timestamp_(kNoTimestamp()) { | 267 start_input_timestamp_(kNoTimestamp()) { |
269 } | 268 } |
270 | 269 |
271 void OpusAudioDecoder::Initialize( | 270 void OpusAudioDecoder::Initialize(const AudioDecoderConfig& config, |
272 DemuxerStream* stream, | 271 const PipelineStatusCB& status_cb) { |
273 const PipelineStatusCB& status_cb, | |
274 const StatisticsCB& statistics_cb) { | |
275 DCHECK(task_runner_->BelongsToCurrentThread()); | 272 DCHECK(task_runner_->BelongsToCurrentThread()); |
276 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); | 273 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); |
277 | 274 |
278 if (demuxer_stream_) { | |
279 // TODO(scherkus): initialization currently happens more than once in | |
280 // PipelineIntegrationTest.BasicPlayback. | |
281 DLOG(ERROR) << "Initialize has already been called."; | |
282 CHECK(false); | |
283 } | |
284 | |
285 weak_this_ = weak_factory_.GetWeakPtr(); | 275 weak_this_ = weak_factory_.GetWeakPtr(); |
286 demuxer_stream_ = stream; | 276 config_ = config; |
287 | 277 |
288 if (!ConfigureDecoder()) { | 278 if (!ConfigureDecoder()) { |
289 initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 279 initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
290 return; | 280 return; |
291 } | 281 } |
292 | 282 |
293 statistics_cb_ = statistics_cb; | |
294 initialize_cb.Run(PIPELINE_OK); | 283 initialize_cb.Run(PIPELINE_OK); |
295 } | 284 } |
296 | 285 |
297 void OpusAudioDecoder::Read(const ReadCB& read_cb) { | 286 void OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
287 const DecodeCB& decode_cb) { | |
298 DCHECK(task_runner_->BelongsToCurrentThread()); | 288 DCHECK(task_runner_->BelongsToCurrentThread()); |
299 DCHECK(!read_cb.is_null()); | 289 DCHECK(!decode_cb.is_null()); |
300 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; | |
301 DCHECK(stop_cb_.is_null()); | |
302 read_cb_ = BindToCurrentLoop(read_cb); | |
303 | 290 |
304 ReadFromDemuxerStream(); | 291 DecodeBuffer(buffer, BindToCurrentLoop(decode_cb)); |
305 } | 292 } |
306 | 293 |
307 int OpusAudioDecoder::bits_per_channel() { | 294 int OpusAudioDecoder::bits_per_channel() { |
308 DCHECK(task_runner_->BelongsToCurrentThread()); | 295 DCHECK(task_runner_->BelongsToCurrentThread()); |
309 return bits_per_channel_; | 296 return bits_per_channel_; |
310 } | 297 } |
311 | 298 |
312 ChannelLayout OpusAudioDecoder::channel_layout() { | 299 ChannelLayout OpusAudioDecoder::channel_layout() { |
313 DCHECK(task_runner_->BelongsToCurrentThread()); | 300 DCHECK(task_runner_->BelongsToCurrentThread()); |
314 return channel_layout_; | 301 return channel_layout_; |
315 } | 302 } |
316 | 303 |
317 int OpusAudioDecoder::samples_per_second() { | 304 int OpusAudioDecoder::samples_per_second() { |
318 DCHECK(task_runner_->BelongsToCurrentThread()); | 305 DCHECK(task_runner_->BelongsToCurrentThread()); |
319 return samples_per_second_; | 306 return samples_per_second_; |
320 } | 307 } |
321 | 308 |
322 void OpusAudioDecoder::Reset(const base::Closure& closure) { | 309 void OpusAudioDecoder::Reset(const base::Closure& closure) { |
323 DCHECK(task_runner_->BelongsToCurrentThread()); | 310 DCHECK(task_runner_->BelongsToCurrentThread()); |
324 reset_cb_ = BindToCurrentLoop(closure); | |
325 | 311 |
326 // A demuxer read is pending, we'll wait until it finishes. | 312 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE); |
327 if (!read_cb_.is_null()) | 313 ResetTimestampState(); |
328 return; | 314 task_runner_->PostTask(FROM_HERE, closure); |
329 | |
330 DoReset(); | |
331 } | 315 } |
332 | 316 |
333 void OpusAudioDecoder::Stop(const base::Closure& closure) { | 317 void OpusAudioDecoder::Stop(const base::Closure& closure) { |
334 DCHECK(task_runner_->BelongsToCurrentThread()); | 318 DCHECK(task_runner_->BelongsToCurrentThread()); |
335 stop_cb_ = BindToCurrentLoop(closure); | |
336 | 319 |
337 // A demuxer read is pending, we'll wait until it finishes. | 320 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE); |
338 if (!read_cb_.is_null()) | 321 ResetTimestampState(); |
339 return; | 322 CloseDecoder(); |
340 | 323 task_runner_->PostTask(FROM_HERE, closure); |
xhwang
2014/03/05 00:40:46
Nice!
| |
341 if (!reset_cb_.is_null()) { | |
342 DoReset(); | |
343 return; | |
344 } | |
345 | |
346 DoStop(); | |
347 } | 324 } |
348 | 325 |
349 OpusAudioDecoder::~OpusAudioDecoder() {} | 326 OpusAudioDecoder::~OpusAudioDecoder() {} |
350 | 327 |
351 void OpusAudioDecoder::DoReset() { | 328 void OpusAudioDecoder::DecodeBuffer( |
352 DCHECK(!reset_cb_.is_null()); | 329 const scoped_refptr<DecoderBuffer>& input, |
330 const DecodeCB& decode_cb) { | |
331 DCHECK(task_runner_->BelongsToCurrentThread()); | |
332 DCHECK(!decode_cb.is_null()); | |
353 | 333 |
354 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE); | |
355 ResetTimestampState(); | |
356 base::ResetAndReturn(&reset_cb_).Run(); | |
357 | |
358 if (!stop_cb_.is_null()) | |
359 DoStop(); | |
360 } | |
361 | |
362 void OpusAudioDecoder::DoStop() { | |
363 DCHECK(!stop_cb_.is_null()); | |
364 | |
365 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE); | |
366 ResetTimestampState(); | |
367 CloseDecoder(); | |
368 base::ResetAndReturn(&stop_cb_).Run(); | |
369 } | |
370 | |
371 void OpusAudioDecoder::ReadFromDemuxerStream() { | |
372 DCHECK(!read_cb_.is_null()); | |
373 demuxer_stream_->Read(base::Bind(&OpusAudioDecoder::BufferReady, weak_this_)); | |
374 } | |
375 | |
376 void OpusAudioDecoder::BufferReady( | |
377 DemuxerStream::Status status, | |
378 const scoped_refptr<DecoderBuffer>& input) { | |
379 DCHECK(task_runner_->BelongsToCurrentThread()); | |
380 DCHECK(!read_cb_.is_null()); | |
381 DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status; | |
382 | |
383 // Drop the buffer, fire |read_cb_| and complete the pending Reset(). | |
384 // If there happens to also be a pending Stop(), that will be handled at | |
385 // the end of DoReset(). | |
386 if (!reset_cb_.is_null()) { | |
387 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
388 DoReset(); | |
389 return; | |
390 } | |
391 | |
392 // Drop the buffer, fire |read_cb_| and complete the pending Stop(). | |
393 if (!stop_cb_.is_null()) { | |
394 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
395 DoStop(); | |
396 return; | |
397 } | |
398 | |
399 if (status == DemuxerStream::kAborted) { | |
400 DCHECK(!input.get()); | |
401 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
402 return; | |
403 } | |
404 | |
405 if (status == DemuxerStream::kConfigChanged) { | |
406 DCHECK(!input.get()); | |
407 DVLOG(1) << "Config changed."; | |
408 | |
409 if (!ConfigureDecoder()) { | |
410 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | |
411 return; | |
412 } | |
413 | |
414 ResetTimestampState(); | |
415 ReadFromDemuxerStream(); | |
416 return; | |
417 } | |
418 | |
419 DCHECK_EQ(status, DemuxerStream::kOk); | |
420 DCHECK(input.get()); | 334 DCHECK(input.get()); |
421 | 335 |
422 // Libopus does not buffer output. Decoding is complete when an end of stream | 336 // Libopus does not buffer output. Decoding is complete when an end of stream |
423 // input buffer is received. | 337 // input buffer is received. |
424 if (input->end_of_stream()) { | 338 if (input->end_of_stream()) { |
425 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); | 339 decode_cb.Run(kOk, AudioBuffer::CreateEOSBuffer()); |
426 return; | 340 return; |
427 } | 341 } |
428 | 342 |
429 // Make sure we are notified if http://crbug.com/49709 returns. Issue also | 343 // Make sure we are notified if http://crbug.com/49709 returns. Issue also |
430 // occurs with some damaged files. | 344 // occurs with some damaged files. |
431 if (input->timestamp() == kNoTimestamp() && | 345 if (input->timestamp() == kNoTimestamp() && |
432 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { | 346 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { |
433 DLOG(ERROR) << "Received a buffer without timestamps!"; | 347 DLOG(ERROR) << "Received a buffer without timestamps!"; |
434 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 348 decode_cb.Run(kDecodeError, NULL); |
435 return; | 349 return; |
436 } | 350 } |
437 | 351 |
438 if (last_input_timestamp_ != kNoTimestamp() && | 352 if (last_input_timestamp_ != kNoTimestamp() && |
439 input->timestamp() != kNoTimestamp() && | 353 input->timestamp() != kNoTimestamp() && |
440 input->timestamp() < last_input_timestamp_) { | 354 input->timestamp() < last_input_timestamp_) { |
441 base::TimeDelta diff = input->timestamp() - last_input_timestamp_; | 355 base::TimeDelta diff = input->timestamp() - last_input_timestamp_; |
442 DLOG(ERROR) << "Input timestamps are not monotonically increasing! " | 356 DLOG(ERROR) << "Input timestamps are not monotonically increasing! " |
443 << " ts " << input->timestamp().InMicroseconds() << " us" | 357 << " ts " << input->timestamp().InMicroseconds() << " us" |
444 << " diff " << diff.InMicroseconds() << " us"; | 358 << " diff " << diff.InMicroseconds() << " us"; |
445 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 359 decode_cb.Run(kDecodeError, NULL); |
446 return; | 360 return; |
447 } | 361 } |
448 | 362 |
449 // Apply the necessary codec delay. | 363 // Apply the necessary codec delay. |
450 if (start_input_timestamp_ == kNoTimestamp()) | 364 if (start_input_timestamp_ == kNoTimestamp()) |
451 start_input_timestamp_ = input->timestamp(); | 365 start_input_timestamp_ = input->timestamp(); |
452 if (last_input_timestamp_ == kNoTimestamp() && | 366 if (last_input_timestamp_ == kNoTimestamp() && |
453 input->timestamp() == start_input_timestamp_) { | 367 input->timestamp() == start_input_timestamp_) { |
454 frames_to_discard_ = frame_delay_at_start_; | 368 frames_to_discard_ = frame_delay_at_start_; |
455 } | 369 } |
456 | 370 |
457 last_input_timestamp_ = input->timestamp(); | 371 last_input_timestamp_ = input->timestamp(); |
458 | 372 |
459 scoped_refptr<AudioBuffer> output_buffer; | 373 scoped_refptr<AudioBuffer> output_buffer; |
460 | 374 |
461 if (!Decode(input, &output_buffer)) { | 375 if (!Decode(input, &output_buffer)) { |
462 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 376 decode_cb.Run(kDecodeError, NULL); |
463 return; | 377 return; |
464 } | 378 } |
465 | 379 |
466 if (output_buffer.get()) { | 380 if (output_buffer.get()) { |
467 // Execute callback to return the decoded audio. | 381 // Execute callback to return the decoded audio. |
468 base::ResetAndReturn(&read_cb_).Run(kOk, output_buffer); | 382 decode_cb.Run(kOk, output_buffer); |
469 } else { | 383 } else { |
470 // We exhausted the input data, but it wasn't enough for a frame. Ask for | 384 // We exhausted the input data, but it wasn't enough for a frame. |
471 // more data in order to fulfill this read. | 385 decode_cb.Run(kNotEnoughData, NULL); |
472 ReadFromDemuxerStream(); | |
473 } | 386 } |
474 } | 387 } |
475 | 388 |
476 bool OpusAudioDecoder::ConfigureDecoder() { | 389 bool OpusAudioDecoder::ConfigureDecoder() { |
477 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); | 390 if (config_.codec() != kCodecOpus) { |
478 | |
479 if (config.codec() != kCodecOpus) { | |
480 DVLOG(1) << "Codec must be kCodecOpus."; | 391 DVLOG(1) << "Codec must be kCodecOpus."; |
481 return false; | 392 return false; |
482 } | 393 } |
483 | 394 |
484 const int channel_count = | 395 const int channel_count = |
485 ChannelLayoutToChannelCount(config.channel_layout()); | 396 ChannelLayoutToChannelCount(config_.channel_layout()); |
486 if (!config.IsValidConfig() || channel_count > kMaxVorbisChannels) { | 397 if (!config_.IsValidConfig() || channel_count > kMaxVorbisChannels) { |
487 DLOG(ERROR) << "Invalid or unsupported audio stream -" | 398 DLOG(ERROR) << "Invalid or unsupported audio stream -" |
488 << " codec: " << config.codec() | 399 << " codec: " << config_.codec() |
489 << " channel count: " << channel_count | 400 << " channel count: " << channel_count |
490 << " channel layout: " << config.channel_layout() | 401 << " channel layout: " << config_.channel_layout() |
491 << " bits per channel: " << config.bits_per_channel() | 402 << " bits per channel: " << config_.bits_per_channel() |
492 << " samples per second: " << config.samples_per_second(); | 403 << " samples per second: " << config_.samples_per_second(); |
493 return false; | 404 return false; |
494 } | 405 } |
495 | 406 |
496 if (config.is_encrypted()) { | 407 if (config_.is_encrypted()) { |
497 DLOG(ERROR) << "Encrypted audio stream not supported."; | 408 DLOG(ERROR) << "Encrypted audio stream not supported."; |
498 return false; | 409 return false; |
499 } | 410 } |
500 | 411 |
412 // TODO(rileya) Remove this check once we properly support midstream audio | |
413 // config changes. | |
501 if (opus_decoder_ && | 414 if (opus_decoder_ && |
502 (channel_layout_ != config.channel_layout() || | 415 (channel_layout_ != config_.channel_layout() || |
503 samples_per_second_ != config.samples_per_second())) { | 416 samples_per_second_ != config_.samples_per_second())) { |
504 DLOG(ERROR) << "Unsupported config change -" | 417 DLOG(ERROR) << "Unsupported config change -" |
505 << ", channel_layout: " << channel_layout_ | 418 << ", channel_layout: " << channel_layout_ |
506 << " -> " << config.channel_layout() | 419 << " -> " << config_.channel_layout() |
507 << ", sample_rate: " << samples_per_second_ | 420 << ", sample_rate: " << samples_per_second_ |
508 << " -> " << config.samples_per_second(); | 421 << " -> " << config_.samples_per_second(); |
509 return false; | 422 return false; |
510 } | 423 } |
511 | 424 |
512 // Clean up existing decoder if necessary. | 425 // Clean up existing decoder if necessary. |
513 CloseDecoder(); | 426 CloseDecoder(); |
514 | 427 |
515 // Parse the Opus Extra Data. | 428 // Parse the Opus Extra Data. |
516 OpusExtraData opus_extra_data; | 429 OpusExtraData opus_extra_data; |
517 if (!ParseOpusExtraData(config.extra_data(), config.extra_data_size(), | 430 if (!ParseOpusExtraData(config_.extra_data(), config_.extra_data_size(), |
518 config, | 431 config_, |
519 &opus_extra_data)) | 432 &opus_extra_data)) |
520 return false; | 433 return false; |
521 | 434 |
522 // Convert from seconds to samples. | 435 // Convert from seconds to samples. |
523 timestamp_offset_ = config.codec_delay(); | 436 timestamp_offset_ = config_.codec_delay(); |
524 frame_delay_at_start_ = TimeDeltaToAudioFrames(config.codec_delay(), | 437 frame_delay_at_start_ = TimeDeltaToAudioFrames(config_.codec_delay(), |
525 config.samples_per_second()); | 438 config_.samples_per_second()); |
526 if (timestamp_offset_ <= base::TimeDelta() || frame_delay_at_start_ < 0) { | 439 if (timestamp_offset_ <= base::TimeDelta() || frame_delay_at_start_ < 0) { |
527 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: " | 440 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: " |
528 << config.codec_delay().InMicroseconds(); | 441 << config_.codec_delay().InMicroseconds(); |
529 return false; | 442 return false; |
530 } | 443 } |
531 | 444 |
532 if (frame_delay_at_start_ != opus_extra_data.skip_samples) { | 445 if (frame_delay_at_start_ != opus_extra_data.skip_samples) { |
533 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " | 446 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " |
534 << "value in Opus Extra Data."; | 447 << "value in Opus Extra Data."; |
535 return false; | 448 return false; |
536 } | 449 } |
537 | 450 |
538 uint8 channel_mapping[kMaxVorbisChannels] = {0}; | 451 uint8 channel_mapping[kMaxVorbisChannels] = {0}; |
539 memcpy(&channel_mapping, | 452 memcpy(&channel_mapping, |
540 kDefaultOpusChannelLayout, | 453 kDefaultOpusChannelLayout, |
541 kMaxChannelsWithDefaultLayout); | 454 kMaxChannelsWithDefaultLayout); |
542 | 455 |
543 if (channel_count > kMaxChannelsWithDefaultLayout) { | 456 if (channel_count > kMaxChannelsWithDefaultLayout) { |
544 RemapOpusChannelLayout(opus_extra_data.stream_map, | 457 RemapOpusChannelLayout(opus_extra_data.stream_map, |
545 channel_count, | 458 channel_count, |
546 channel_mapping); | 459 channel_mapping); |
547 } | 460 } |
548 | 461 |
549 // Init Opus. | 462 // Init Opus. |
550 int status = OPUS_INVALID_STATE; | 463 int status = OPUS_INVALID_STATE; |
551 opus_decoder_ = opus_multistream_decoder_create(config.samples_per_second(), | 464 opus_decoder_ = opus_multistream_decoder_create(config_.samples_per_second(), |
552 channel_count, | 465 channel_count, |
553 opus_extra_data.num_streams, | 466 opus_extra_data.num_streams, |
554 opus_extra_data.num_coupled, | 467 opus_extra_data.num_coupled, |
555 channel_mapping, | 468 channel_mapping, |
556 &status); | 469 &status); |
557 if (!opus_decoder_ || status != OPUS_OK) { | 470 if (!opus_decoder_ || status != OPUS_OK) { |
558 DLOG(ERROR) << "opus_multistream_decoder_create failed status=" | 471 DLOG(ERROR) << "opus_multistream_decoder_create failed status=" |
559 << opus_strerror(status); | 472 << opus_strerror(status); |
560 return false; | 473 return false; |
561 } | 474 } |
562 | 475 |
563 status = opus_multistream_decoder_ctl( | 476 status = opus_multistream_decoder_ctl( |
564 opus_decoder_, OPUS_SET_GAIN(opus_extra_data.gain_db)); | 477 opus_decoder_, OPUS_SET_GAIN(opus_extra_data.gain_db)); |
565 if (status != OPUS_OK) { | 478 if (status != OPUS_OK) { |
566 DLOG(ERROR) << "Failed to set OPUS header gain; status=" | 479 DLOG(ERROR) << "Failed to set OPUS header gain; status=" |
567 << opus_strerror(status); | 480 << opus_strerror(status); |
568 return false; | 481 return false; |
569 } | 482 } |
570 | 483 |
571 channel_layout_ = config.channel_layout(); | 484 channel_layout_ = config_.channel_layout(); |
572 samples_per_second_ = config.samples_per_second(); | 485 samples_per_second_ = config_.samples_per_second(); |
573 output_timestamp_helper_.reset( | 486 output_timestamp_helper_.reset( |
574 new AudioTimestampHelper(config.samples_per_second())); | 487 new AudioTimestampHelper(config_.samples_per_second())); |
575 start_input_timestamp_ = kNoTimestamp(); | 488 start_input_timestamp_ = kNoTimestamp(); |
576 return true; | 489 return true; |
577 } | 490 } |
578 | 491 |
579 void OpusAudioDecoder::CloseDecoder() { | 492 void OpusAudioDecoder::CloseDecoder() { |
580 if (opus_decoder_) { | 493 if (opus_decoder_) { |
581 opus_multistream_decoder_destroy(opus_decoder_); | 494 opus_multistream_decoder_destroy(opus_decoder_); |
582 opus_decoder_ = NULL; | 495 opus_decoder_ = NULL; |
583 } | 496 } |
584 } | 497 } |
585 | 498 |
586 void OpusAudioDecoder::ResetTimestampState() { | 499 void OpusAudioDecoder::ResetTimestampState() { |
587 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 500 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); |
588 last_input_timestamp_ = kNoTimestamp(); | 501 last_input_timestamp_ = kNoTimestamp(); |
589 frames_to_discard_ = TimeDeltaToAudioFrames( | 502 frames_to_discard_ = |
590 demuxer_stream_->audio_decoder_config().seek_preroll(), | 503 TimeDeltaToAudioFrames(config_.seek_preroll(), samples_per_second_); |
591 samples_per_second_); | |
592 } | 504 } |
593 | 505 |
594 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, | 506 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, |
595 scoped_refptr<AudioBuffer>* output_buffer) { | 507 scoped_refptr<AudioBuffer>* output_buffer) { |
596 // Allocate a buffer for the output samples. | 508 // Allocate a buffer for the output samples. |
597 *output_buffer = AudioBuffer::CreateBuffer( | 509 *output_buffer = AudioBuffer::CreateBuffer( |
598 sample_format_, | 510 sample_format_, |
599 ChannelLayoutToChannelCount(channel_layout_), | 511 ChannelLayoutToChannelCount(channel_layout_), |
600 kMaxOpusOutputPacketSizeSamples); | 512 kMaxOpusOutputPacketSizeSamples); |
601 const int buffer_size = | 513 const int buffer_size = |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
650 return false; | 562 return false; |
651 } | 563 } |
652 output_buffer->get()->TrimEnd(discard_padding); | 564 output_buffer->get()->TrimEnd(discard_padding); |
653 frames_to_output -= discard_padding; | 565 frames_to_output -= discard_padding; |
654 } | 566 } |
655 } else { | 567 } else { |
656 frames_to_discard_ -= frames_to_output; | 568 frames_to_discard_ -= frames_to_output; |
657 frames_to_output = 0; | 569 frames_to_output = 0; |
658 } | 570 } |
659 | 571 |
660 // Decoding finished successfully, update statistics. | |
661 PipelineStatistics statistics; | |
662 statistics.audio_bytes_decoded = input->data_size(); | |
663 statistics_cb_.Run(statistics); | |
664 | |
665 // Assign timestamp and duration to the buffer. | 572 // Assign timestamp and duration to the buffer. |
666 output_buffer->get()->set_timestamp( | 573 output_buffer->get()->set_timestamp( |
667 output_timestamp_helper_->GetTimestamp() - timestamp_offset_); | 574 output_timestamp_helper_->GetTimestamp() - timestamp_offset_); |
668 output_buffer->get()->set_duration( | 575 output_buffer->get()->set_duration( |
669 output_timestamp_helper_->GetFrameDuration(frames_to_output)); | 576 output_timestamp_helper_->GetFrameDuration(frames_to_output)); |
670 output_timestamp_helper_->AddFrames(frames_decoded); | 577 output_timestamp_helper_->AddFrames(frames_decoded); |
671 | 578 |
672 // Discard the buffer to indicate we need more data. | 579 // Discard the buffer to indicate we need more data. |
673 if (!frames_to_output) | 580 if (!frames_to_output) |
674 *output_buffer = NULL; | 581 *output_buffer = NULL; |
675 | 582 |
676 return true; | 583 return true; |
677 } | 584 } |
678 | 585 |
679 } // namespace media | 586 } // namespace media |
OLD | NEW |