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