Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b16bf6b authored by John Grossman's avatar John Grossman
Browse files

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: default avatarJohn Grossman <johngro@google.com>
Change-Id: I78fb89b4356004d7834629ccc82ca99c4cc7954a
parent 96fecb7f
Loading
Loading
Loading
Loading
+44 −3
Original line number Diff line number Diff line
@@ -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<MetaData> 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.
            if (formatActuallyChanged)
                stopAndCleanupRenderer();

            res = OK;
        }