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

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

Issue 1838203003: [TO M50] Enable implicit signalling for HE AAC v1 & v2 in ADTS. (Closed) Base URL: https://chromium.googlesource.com/a/chromium/src.git@2661
Patch Set: Created 4 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
« no previous file with comments | « media/base/audio_buffer.cc ('k') | media/renderers/audio_renderer_impl.h » ('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/ffmpeg_audio_decoder.h" 5 #include "media/filters/ffmpeg_audio_decoder.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); 72 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
73 if (frame->nb_samples <= 0) 73 if (frame->nb_samples <= 0)
74 return AVERROR(EINVAL); 74 return AVERROR(EINVAL);
75 75
76 if (s->channels != channels) { 76 if (s->channels != channels) {
77 DLOG(ERROR) << "AVCodecContext and AVFrame disagree on channel count."; 77 DLOG(ERROR) << "AVCodecContext and AVFrame disagree on channel count.";
78 return AVERROR(EINVAL); 78 return AVERROR(EINVAL);
79 } 79 }
80 80
81 if (s->sample_rate != frame->sample_rate) {
82 DLOG(ERROR) << "AVCodecContext and AVFrame disagree on sample rate."
83 << s->sample_rate << " vs " << frame->sample_rate;
84 return AVERROR(EINVAL);
85 }
86
81 // Determine how big the buffer should be and allocate it. FFmpeg may adjust 87 // Determine how big the buffer should be and allocate it. FFmpeg may adjust
82 // how big each channel data is in order to meet the alignment policy, so 88 // how big each channel data is in order to meet the alignment policy, so
83 // we need to take this into consideration. 89 // we need to take this into consideration.
84 int buffer_size_in_bytes = 90 int buffer_size_in_bytes =
85 av_samples_get_buffer_size(&frame->linesize[0], 91 av_samples_get_buffer_size(&frame->linesize[0],
86 channels, 92 channels,
87 frame->nb_samples, 93 frame->nb_samples,
88 format, 94 format,
89 AudioBuffer::kChannelAlignment); 95 AudioBuffer::kChannelAlignment);
90 // Check for errors from av_samples_get_buffer_size(). 96 // Check for errors from av_samples_get_buffer_size().
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 286
281 break; 287 break;
282 } 288 }
283 289
284 // Update packet size and data pointer in case we need to call the decoder 290 // Update packet size and data pointer in case we need to call the decoder
285 // with the remaining bytes from this packet. 291 // with the remaining bytes from this packet.
286 packet.size -= result; 292 packet.size -= result;
287 packet.data += result; 293 packet.data += result;
288 294
289 scoped_refptr<AudioBuffer> output; 295 scoped_refptr<AudioBuffer> output;
290 const int channels = DetermineChannels(av_frame_.get()); 296
297 bool config_changed = false;
291 if (frame_decoded) { 298 if (frame_decoded) {
299 const int channels = DetermineChannels(av_frame_.get());
300 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout(
301 codec_context_->channel_layout, codec_context_->channels);
302
292 if (av_frame_->sample_rate != config_.samples_per_second() || 303 if (av_frame_->sample_rate != config_.samples_per_second() ||
304 channel_layout != config_.channel_layout() ||
293 channels != ChannelLayoutToChannelCount(config_.channel_layout()) || 305 channels != ChannelLayoutToChannelCount(config_.channel_layout()) ||
294 av_frame_->format != av_sample_format_) { 306 av_frame_->format != av_sample_format_) {
295 DLOG(ERROR) << "Unsupported midstream configuration change!" 307 // Only allow midstream configuration changes for AAC. Sample format is
296 << " Sample Rate: " << av_frame_->sample_rate << " vs " 308 // not expected to change between AAC profiles.
297 << config_.samples_per_second()
298 << ", Channels: " << channels << " vs "
299 << ChannelLayoutToChannelCount(config_.channel_layout())
300 << ", Sample Format: " << av_frame_->format << " vs "
301 << av_sample_format_;
302
303 if (config_.codec() == kCodecAAC && 309 if (config_.codec() == kCodecAAC &&
304 av_frame_->sample_rate == 2 * config_.samples_per_second()) { 310 av_frame_->format == av_sample_format_) {
305 MEDIA_LOG(DEBUG, media_log_) 311 MEDIA_LOG(DEBUG, media_log_)
306 << "Implicit HE-AAC signalling is being" 312 << " Detected AAC midstream configuration change"
307 << " used. Please use mp4a.40.5 instead of" 313 << " PTS:" << buffer->timestamp().InMicroseconds()
308 << " mp4a.40.2 in the mimetype."; 314 << " Sample Rate: " << av_frame_->sample_rate << " vs "
315 << config_.samples_per_second()
316 << ", ChannelLayout: " << channel_layout << " vs "
317 << config_.channel_layout() << ", Channels: " << channels
318 << " vs "
319 << ChannelLayoutToChannelCount(config_.channel_layout());
320 config_.Initialize(config_.codec(), config_.sample_format(),
321 channel_layout, av_frame_->sample_rate,
322 config_.extra_data(), config_.is_encrypted(),
323 config_.seek_preroll(), config_.codec_delay());
324 config_changed = true;
325 ResetTimestampState();
326 } else {
327 MEDIA_LOG(ERROR, media_log_)
328 << "Unsupported midstream configuration change!"
329 << " Sample Rate: " << av_frame_->sample_rate << " vs "
330 << config_.samples_per_second() << ", Channels: " << channels
331 << " vs " << ChannelLayoutToChannelCount(config_.channel_layout())
332 << ", Sample Format: " << av_frame_->format << " vs "
333 << av_sample_format_;
334 // This is an unrecoverable error, so bail out.
335 av_frame_unref(av_frame_.get());
336 return false;
309 } 337 }
310 // This is an unrecoverable error, so bail out.
311 av_frame_unref(av_frame_.get());
312 return false;
313 } 338 }
314 339
315 // Get the AudioBuffer that the data was decoded into. Adjust the number 340 // Get the AudioBuffer that the data was decoded into. Adjust the number
316 // of frames, in case fewer than requested were actually decoded. 341 // of frames, in case fewer than requested were actually decoded.
317 output = reinterpret_cast<AudioBuffer*>( 342 output = reinterpret_cast<AudioBuffer*>(
318 av_buffer_get_opaque(av_frame_->buf[0])); 343 av_buffer_get_opaque(av_frame_->buf[0]));
319 344
320 DCHECK_EQ(ChannelLayoutToChannelCount(config_.channel_layout()), 345 DCHECK_EQ(ChannelLayoutToChannelCount(config_.channel_layout()),
321 output->channel_count()); 346 output->channel_count());
322 const int unread_frames = output->frame_count() - av_frame_->nb_samples; 347 const int unread_frames = output->frame_count() - av_frame_->nb_samples;
323 DCHECK_GE(unread_frames, 0); 348 DCHECK_GE(unread_frames, 0);
324 if (unread_frames > 0) 349 if (unread_frames > 0)
325 output->TrimEnd(unread_frames); 350 output->TrimEnd(unread_frames);
326 av_frame_unref(av_frame_.get()); 351 av_frame_unref(av_frame_.get());
327 } 352 }
328 353
329 // WARNING: |av_frame_| no longer has valid data at this point. 354 // WARNING: |av_frame_| no longer has valid data at this point.
330 const int decoded_frames = frame_decoded ? output->frame_count() : 0; 355 const int decoded_frames = frame_decoded ? output->frame_count() : 0;
331 if (IsEndOfStream(result, decoded_frames, buffer)) { 356 if (IsEndOfStream(result, decoded_frames, buffer)) {
332 DCHECK_EQ(packet.size, 0); 357 DCHECK_EQ(packet.size, 0);
333 } else if (discard_helper_->ProcessBuffers(buffer, output)) { 358 } else if (discard_helper_->ProcessBuffers(buffer, output)) {
359 if (config_changed &&
360 output->sample_rate() != config_.samples_per_second()) {
361 // At the boundary of the config change, FFmpeg's AAC decoder gives the
362 // previous sample rate when calling our GetAudioBuffer. Set the correct
363 // sample rate before sending the buffer along.
364 // TODO(chcunningham): Fix FFmpeg and upstream it.
365 output->AdjustSampleRate(config_.samples_per_second());
366 }
334 *has_produced_frame = true; 367 *has_produced_frame = true;
335 output_cb_.Run(output); 368 output_cb_.Run(output);
336 } 369 }
337 } while (packet.size > 0); 370 } while (packet.size > 0);
338 371
339 return true; 372 return true;
340 } 373 }
341 374
342 void FFmpegAudioDecoder::ReleaseFFmpegResources() { 375 void FFmpegAudioDecoder::ReleaseFFmpegResources() {
343 codec_context_.reset(); 376 codec_context_.reset();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return true; 420 return true;
388 } 421 }
389 422
390 void FFmpegAudioDecoder::ResetTimestampState() { 423 void FFmpegAudioDecoder::ResetTimestampState() {
391 discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second(), 424 discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second(),
392 config_.codec_delay())); 425 config_.codec_delay()));
393 discard_helper_->Reset(config_.codec_delay()); 426 discard_helper_->Reset(config_.codec_delay());
394 } 427 }
395 428
396 } // namespace media 429 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_buffer.cc ('k') | media/renderers/audio_renderer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698