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

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

Issue 239423005: Wire up codec_delay() to MP3StreamParser and FFmpegAudioDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ResetTimestampState() on config change. Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/opus_audio_decoder.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/sys_byteorder.h" 10 #include "base/sys_byteorder.h"
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i); 246 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i);
247 return true; 247 return true;
248 } 248 }
249 249
250 OpusAudioDecoder::OpusAudioDecoder( 250 OpusAudioDecoder::OpusAudioDecoder(
251 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 251 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
252 : task_runner_(task_runner), 252 : task_runner_(task_runner),
253 opus_decoder_(NULL), 253 opus_decoder_(NULL),
254 last_input_timestamp_(kNoTimestamp()), 254 last_input_timestamp_(kNoTimestamp()),
255 frames_to_discard_(0), 255 frames_to_discard_(0),
256 frame_delay_at_start_(0),
257 start_input_timestamp_(kNoTimestamp()) {} 256 start_input_timestamp_(kNoTimestamp()) {}
258 257
259 void OpusAudioDecoder::Initialize(const AudioDecoderConfig& config, 258 void OpusAudioDecoder::Initialize(const AudioDecoderConfig& config,
260 const PipelineStatusCB& status_cb) { 259 const PipelineStatusCB& status_cb) {
261 DCHECK(task_runner_->BelongsToCurrentThread()); 260 DCHECK(task_runner_->BelongsToCurrentThread());
262 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); 261 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
263 262
264 config_ = config; 263 config_ = config;
265 264
266 if (!ConfigureDecoder()) { 265 if (!ConfigureDecoder()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 << " diff " << diff.InMicroseconds() << " us"; 329 << " diff " << diff.InMicroseconds() << " us";
331 decode_cb.Run(kDecodeError, NULL); 330 decode_cb.Run(kDecodeError, NULL);
332 return; 331 return;
333 } 332 }
334 333
335 // Apply the necessary codec delay. 334 // Apply the necessary codec delay.
336 if (start_input_timestamp_ == kNoTimestamp()) 335 if (start_input_timestamp_ == kNoTimestamp())
337 start_input_timestamp_ = input->timestamp(); 336 start_input_timestamp_ = input->timestamp();
338 if (last_input_timestamp_ == kNoTimestamp() && 337 if (last_input_timestamp_ == kNoTimestamp() &&
339 input->timestamp() == start_input_timestamp_) { 338 input->timestamp() == start_input_timestamp_) {
340 frames_to_discard_ = frame_delay_at_start_; 339 frames_to_discard_ = config_.codec_delay();
341 } 340 }
342 341
343 last_input_timestamp_ = input->timestamp(); 342 last_input_timestamp_ = input->timestamp();
344 343
345 scoped_refptr<AudioBuffer> output_buffer; 344 scoped_refptr<AudioBuffer> output_buffer;
346 345
347 if (!Decode(input, &output_buffer)) { 346 if (!Decode(input, &output_buffer)) {
348 decode_cb.Run(kDecodeError, NULL); 347 decode_cb.Run(kDecodeError, NULL);
349 return; 348 return;
350 } 349 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 // Clean up existing decoder if necessary. 383 // Clean up existing decoder if necessary.
385 CloseDecoder(); 384 CloseDecoder();
386 385
387 // Parse the Opus Extra Data. 386 // Parse the Opus Extra Data.
388 OpusExtraData opus_extra_data; 387 OpusExtraData opus_extra_data;
389 if (!ParseOpusExtraData(config_.extra_data(), config_.extra_data_size(), 388 if (!ParseOpusExtraData(config_.extra_data(), config_.extra_data_size(),
390 config_, 389 config_,
391 &opus_extra_data)) 390 &opus_extra_data))
392 return false; 391 return false;
393 392
394 // Convert from seconds to samples. 393 if (config_.codec_delay() <= 0) {
395 timestamp_offset_ = config_.codec_delay();
396 frame_delay_at_start_ = TimeDeltaToAudioFrames(config_.codec_delay(),
397 config_.samples_per_second());
398 if (timestamp_offset_ <= base::TimeDelta() || frame_delay_at_start_ < 0) {
399 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: " 394 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: "
400 << config_.codec_delay().InMicroseconds(); 395 << config_.codec_delay();
401 return false; 396 return false;
402 } 397 }
403 398
404 if (frame_delay_at_start_ != opus_extra_data.skip_samples) { 399 if (config_.codec_delay() != opus_extra_data.skip_samples) {
405 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " 400 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the "
406 << "value in Opus Extra Data."; 401 << "value in Opus Extra Data.";
407 return false; 402 return false;
408 } 403 }
409 404
410 uint8 channel_mapping[kMaxVorbisChannels] = {0}; 405 uint8 channel_mapping[kMaxVorbisChannels] = {0};
411 memcpy(&channel_mapping, 406 memcpy(&channel_mapping,
412 kDefaultOpusChannelLayout, 407 kDefaultOpusChannelLayout,
413 kMaxChannelsWithDefaultLayout); 408 kMaxChannelsWithDefaultLayout);
414 409
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 << " timestamp: " << input->timestamp().InMicroseconds() 484 << " timestamp: " << input->timestamp().InMicroseconds()
490 << " us, duration: " << input->duration().InMicroseconds() 485 << " us, duration: " << input->duration().InMicroseconds()
491 << " us, packet size: " << input->data_size() << " bytes with" 486 << " us, packet size: " << input->data_size() << " bytes with"
492 << " status: " << opus_strerror(frames_decoded); 487 << " status: " << opus_strerror(frames_decoded);
493 return false; 488 return false;
494 } 489 }
495 490
496 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && 491 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() &&
497 !input->end_of_stream()) { 492 !input->end_of_stream()) {
498 DCHECK(input->timestamp() != kNoTimestamp()); 493 DCHECK(input->timestamp() != kNoTimestamp());
494 // Adjust the timestamp helper so the base timestamp is corrected for frames
495 // dropped due to codec delay.
499 output_timestamp_helper_->SetBaseTimestamp(input->timestamp()); 496 output_timestamp_helper_->SetBaseTimestamp(input->timestamp());
497 output_timestamp_helper_->SetBaseTimestamp(
498 input->timestamp() -
499 output_timestamp_helper_->GetFrameDuration(config_.codec_delay()));
500 } 500 }
501 501
502 // Trim off any extraneous allocation. 502 // Trim off any extraneous allocation.
503 DCHECK_LE(frames_decoded, output_buffer->get()->frame_count()); 503 DCHECK_LE(frames_decoded, output_buffer->get()->frame_count());
504 const int trim_frames = output_buffer->get()->frame_count() - frames_decoded; 504 const int trim_frames = output_buffer->get()->frame_count() - frames_decoded;
505 if (trim_frames > 0) 505 if (trim_frames > 0)
506 output_buffer->get()->TrimEnd(trim_frames); 506 output_buffer->get()->TrimEnd(trim_frames);
507 507
508 // Handle frame discard and trimming. 508 // Handle frame discard and trimming.
509 int frames_to_output = frames_decoded; 509 int frames_to_output = frames_decoded;
(...skipping 12 matching lines...) Expand all
522 } 522 }
523 output_buffer->get()->TrimEnd(discard_padding); 523 output_buffer->get()->TrimEnd(discard_padding);
524 frames_to_output -= discard_padding; 524 frames_to_output -= discard_padding;
525 } 525 }
526 } else { 526 } else {
527 frames_to_discard_ -= frames_to_output; 527 frames_to_discard_ -= frames_to_output;
528 frames_to_output = 0; 528 frames_to_output = 0;
529 } 529 }
530 530
531 // Assign timestamp and duration to the buffer. 531 // Assign timestamp and duration to the buffer.
532 output_buffer->get()->set_timestamp( 532 output_buffer->get()->set_timestamp(output_timestamp_helper_->GetTimestamp());
533 output_timestamp_helper_->GetTimestamp() - timestamp_offset_);
534 output_buffer->get()->set_duration( 533 output_buffer->get()->set_duration(
535 output_timestamp_helper_->GetFrameDuration(frames_to_output)); 534 output_timestamp_helper_->GetFrameDuration(frames_to_output));
536 output_timestamp_helper_->AddFrames(frames_decoded); 535 output_timestamp_helper_->AddFrames(frames_decoded);
537 536
538 // Discard the buffer to indicate we need more data. 537 // Discard the buffer to indicate we need more data.
539 if (!frames_to_output) 538 if (!frames_to_output)
540 *output_buffer = NULL; 539 *output_buffer = NULL;
541 540
542 return true; 541 return true;
543 } 542 }
544 543
545 } // namespace media 544 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/opus_audio_decoder.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698