| 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 |