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

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

Powered by Google App Engine
This is Rietveld 408576698