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

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

Issue 1805013003: Enable implicit signalling for HE AAC v1 & v2 in ADTS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: WIP Created 4 years, 9 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/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() ||
293 channels != ChannelLayoutToChannelCount(config_.channel_layout()) || 304 channel_layout != config_.channel_layout() ||
305 channels != ChannelLayoutToChannelCount(config_.channel_layout()) || // IIUC, this should go. We previously allowed channel layout changes as long as the number of channels held fixed. Why?
DaleCurtis 2016/03/18 00:16:23 Needed as discussed via e-mail.
chcunningham 2016/03/25 01:41:16 Acknowledged.
294 av_frame_->format != av_sample_format_) { 306 av_frame_->format != av_sample_format_) {
295 DLOG(ERROR) << "Unsupported midstream configuration change!"
296 << " Sample Rate: " << av_frame_->sample_rate << " vs "
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 307
308 // Only allow midstream configuration changes for AAC. Sample format is
309 // not expected to change between AAC profiles.
303 if (config_.codec() == kCodecAAC && 310 if (config_.codec() == kCodecAAC &&
304 av_frame_->sample_rate == 2 * config_.samples_per_second()) { 311 av_frame_->format == av_sample_format_) {
305 MEDIA_LOG(DEBUG, media_log_) 312 MEDIA_LOG(DEBUG, media_log_)
306 << "Implicit HE-AAC signalling is being" 313 << " Detected AAC midstream configuration change"
307 << " used. Please use mp4a.40.5 instead of" 314 << " PTS:" << buffer->timestamp().InMicroseconds()
308 << " mp4a.40.2 in the mimetype."; 315 << " Sample Rate: " << av_frame_->sample_rate << " vs "
316 << config_.samples_per_second()
317 << ", ChannelLayout: " << channel_layout << " vs "
318 << config_.channel_layout()
319 << ", Channels: " << channels << " vs "
320 << ChannelLayoutToChannelCount(config_.channel_layout());
321 config_.Initialize(config_.codec(),
322 config_.sample_format(),
323 channel_layout,
324 av_frame_->sample_rate,
325 config_.extra_data(),
326 config_.encryption_scheme(),
327 config_.seek_preroll(),
328 config_.codec_delay());
329 config_changed = true;
330 ResetTimestampState();
331 } else {
332 MEDIA_LOG(ERROR, media_log_)
333 << "Unsupported midstream configuration change!"
334 << " Sample Rate: " << av_frame_->sample_rate << " vs "
335 << config_.samples_per_second()
336 << ", Channels: " << channels << " vs "
337 << ChannelLayoutToChannelCount(config_.channel_layout())
338 << ", Sample Format: " << av_frame_->format << " vs "
339 << av_sample_format_;
340 // This is an unrecoverable error, so bail out.
341 av_frame_unref(av_frame_.get());
342 return false;
309 } 343 }
310 // This is an unrecoverable error, so bail out.
311 av_frame_unref(av_frame_.get());
312 return false;
313 } 344 }
314 345
315 // Get the AudioBuffer that the data was decoded into. Adjust the number 346 // Get the AudioBuffer that the data was decoded into. Adjust the number
316 // of frames, in case fewer than requested were actually decoded. 347 // of frames, in case fewer than requested were actually decoded.
317 output = reinterpret_cast<AudioBuffer*>( 348 output = reinterpret_cast<AudioBuffer*>(
318 av_buffer_get_opaque(av_frame_->buf[0])); 349 av_buffer_get_opaque(av_frame_->buf[0]));
319 350
320 DCHECK_EQ(ChannelLayoutToChannelCount(config_.channel_layout()), 351 DCHECK_EQ(ChannelLayoutToChannelCount(config_.channel_layout()),
321 output->channel_count()); 352 output->channel_count());
322 const int unread_frames = output->frame_count() - av_frame_->nb_samples; 353 const int unread_frames = output->frame_count() - av_frame_->nb_samples;
323 DCHECK_GE(unread_frames, 0); 354 DCHECK_GE(unread_frames, 0);
324 if (unread_frames > 0) 355 if (unread_frames > 0)
325 output->TrimEnd(unread_frames); 356 output->TrimEnd(unread_frames);
326 av_frame_unref(av_frame_.get()); 357 av_frame_unref(av_frame_.get());
327 } 358 }
328 359
329 // WARNING: |av_frame_| no longer has valid data at this point. 360 // WARNING: |av_frame_| no longer has valid data at this point.
330 const int decoded_frames = frame_decoded ? output->frame_count() : 0; 361 const int decoded_frames = frame_decoded ? output->frame_count() : 0;
331 if (IsEndOfStream(result, decoded_frames, buffer)) { 362 if (IsEndOfStream(result, decoded_frames, buffer)) {
332 DCHECK_EQ(packet.size, 0); 363 DCHECK_EQ(packet.size, 0);
333 } else if (discard_helper_->ProcessBuffers(buffer, output)) { 364 } else if (discard_helper_->ProcessBuffers(buffer, output)) {
365 if (config_changed &&
366 output->sample_rate() != config_.samples_per_second()) {
367 // At the boundary of the config change, FFmpeg's AAC decoder gives the
368 // previous sample rate when calling our GetAudioBuffer. Set the correct
369 // sample rate before sending the buffer along.
370 // TODO(chcunningham): Fix FFmpeg and upstream it.
371 output->AdjustSampleRate(config_.samples_per_second());
372 }
334 *has_produced_frame = true; 373 *has_produced_frame = true;
335 output_cb_.Run(output); 374 output_cb_.Run(output);
336 } 375 }
337 } while (packet.size > 0); 376 } while (packet.size > 0);
338 377
339 return true; 378 return true;
340 } 379 }
341 380
342 void FFmpegAudioDecoder::ReleaseFFmpegResources() { 381 void FFmpegAudioDecoder::ReleaseFFmpegResources() {
343 codec_context_.reset(); 382 codec_context_.reset();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return true; 426 return true;
388 } 427 }
389 428
390 void FFmpegAudioDecoder::ResetTimestampState() { 429 void FFmpegAudioDecoder::ResetTimestampState() {
391 discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second(), 430 discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second(),
392 config_.codec_delay())); 431 config_.codec_delay()));
393 discard_helper_->Reset(config_.codec_delay()); 432 discard_helper_->Reset(config_.codec_delay());
394 } 433 }
395 434
396 } // namespace media 435 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698