From 2b16bf6bdbae150a3aa0da51361e3ea9e63fd3c2 Mon Sep 17 00:00:00 2001 From: John Grossman Date: Wed, 21 Mar 2012 17:57:43 -0700 Subject: LibAAH_RTP: Fix handling of PCM format changes. When an audio decoder signals a format change, we were destroying our renderer so that a new one could be created with the new format, but we were not updating our internal format state variables with the new format information. This fixes issues with AAC audio with SBR extensions; in particular content coming from Pandora. Pandora audio is currently being delivered as AAC-LC decoding to 22.05 KHz, but with an SBR layer which gives 44.1 KHz. Whether or not you are going to get 22.05 or 44.1 depends on if your decoder supports SBR ("High Efficiency" profile). Stagefright does not parse the extension sample rate present in the ESDS; instead it reports the sample rate of the base stream (22050 in this case). Its only when the decoder decides it can handle SBR that you get a chance to discover that the content is actually 44.1, information it delivers via a format change status code during read. Signed-off-by: John Grossman Change-Id: I78fb89b4356004d7834629ccc82ca99c4cc7954a --- media/libaah_rtp/aah_decoder_pump.cpp | 47 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/media/libaah_rtp/aah_decoder_pump.cpp b/media/libaah_rtp/aah_decoder_pump.cpp index 68bac4fd6300..3569b2e80d86 100644 --- a/media/libaah_rtp/aah_decoder_pump.cpp +++ b/media/libaah_rtp/aah_decoder_pump.cpp @@ -308,14 +308,55 @@ void* AAH_DecoderPump::workThread() { decode_timer.stop(); if (res == INFO_FORMAT_CHANGED) { - // Format has changed. Destroy our current renderer so that a new - // one can be created during queueToRenderer with the proper format. + sp params = decoder_->getFormat(); + bool formatActuallyChanged = false; + + if (params != NULL) { + int32_t channels; + int32_t sample_rate; + + if (params->findInt32(kKeySampleRate, &sample_rate)) { + if (format_sample_rate_ != sample_rate) { + LOGD("Format change: sample rate %d Hz -> %d Hz", + format_sample_rate_, sample_rate); + formatActuallyChanged = true; + format_sample_rate_ = sample_rate; + } + } else { + LOGW("Decoder signalled a format change, but provided no" + " sample rate. Keeping current setting of %d Hz", + format_sample_rate_); + } + + if (params->findInt32(kKeyChannelCount, &channels)) { + if (format_channels_ != channels) { + LOGD("Format change: channels %d -> %d", + format_channels_, channels); + formatActuallyChanged = true; + format_channels_ = channels; + } + } else { + LOGW("Decoder signalled a format change, but provided no" + " channel count. Keeping current setting of %d" + " channels", format_channels_); + } + } else { + LOGW("Decoder signalled a format change, but provided no format" + " information. Keeping current settings of %d Hz %d" + " Channels", format_sample_rate_, format_channels_); + } + + // If the format has actually changed, destroy our current renderer + // so that a new one can be created during queueToRenderer with the + // proper format. // // TODO : In order to transition seamlessly, we should change this // to put the old renderer in a queue to play out completely before // we destroy it. We can still create a new renderer, the timed // nature of the renderer should ensure a seamless splice. - stopAndCleanupRenderer(); + if (formatActuallyChanged) + stopAndCleanupRenderer(); + res = OK; } -- cgit v1.2.3-59-g8ed1b