Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: media/filters/opus_audio_decoder.cc

Issue 141243003: Add AudioBufferStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decoderstream_rebased
Patch Set: add TODOs Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698