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

Commit b97cc6a9 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AAC encoder: add support for SBR mode selection

Change-Id: Ibc07bff7710398929c135f38324dd29857fa0ea6
parent 3c6fac2c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ private:
    status_t setupAACCodec(
            bool encoder,
            int32_t numChannels, int32_t sampleRate, int32_t bitRate,
            int32_t aacProfile, bool isADTS);
            int32_t aacProfile, bool isADTS, int32_t sbrMode);

    status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);

+32 −2
Original line number Diff line number Diff line
@@ -1289,16 +1289,20 @@ status_t ACodec::configureCodec(
            err = INVALID_OPERATION;
        } else {
            int32_t isADTS, aacProfile;
            int32_t sbrMode;
            if (!msg->findInt32("is-adts", &isADTS)) {
                isADTS = 0;
            }
            if (!msg->findInt32("aac-profile", &aacProfile)) {
                aacProfile = OMX_AUDIO_AACObjectNull;
            }
            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
                sbrMode = -1;
            }

            err = setupAACCodec(
                    encoder, numChannels, sampleRate, bitRate, aacProfile,
                    isADTS != 0);
                    isADTS != 0, sbrMode);
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
@@ -1460,7 +1464,7 @@ status_t ACodec::selectAudioPortFormat(

status_t ACodec::setupAACCodec(
        bool encoder, int32_t numChannels, int32_t sampleRate,
        int32_t bitRate, int32_t aacProfile, bool isADTS) {
        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode) {
    if (encoder && isADTS) {
        return -EINVAL;
    }
@@ -1527,6 +1531,32 @@ status_t ACodec::setupAACCodec(
        profile.nAACERtools = OMX_AUDIO_AACERNone;
        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
        switch (sbrMode) {
        case 0:
            // disable sbr
            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
            break;
        case 1:
            // enable single-rate sbr
            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
            break;
        case 2:
            // enable dual-rate sbr
            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
            break;
        case -1:
            // enable both modes -> the codec will decide which mode should be used
            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
            break;
        default:
            // unsupported sbr mode
            return BAD_VALUE;
        }


        err = mOMX->setParameter(
                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+76 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <utils/Log.h>

#include "SoftAACEncoder2.h"
#include <OMX_AudioExt.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/hexdump.h>
@@ -44,6 +45,8 @@ SoftAACEncoder2::SoftAACEncoder2(
      mNumChannels(1),
      mSampleRate(44100),
      mBitRate(0),
      mSBRMode(-1),
      mSBRRatio(0),
      mAACProfile(OMX_AUDIO_AACObjectLC),
      mSentCodecSpecificData(false),
      mInputSize(0),
@@ -156,6 +159,41 @@ OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter(
            aacParams->nSampleRate = mSampleRate;
            aacParams->nFrameLength = 0;

            switch (mSBRMode) {
            case 1: // sbr on
                switch (mSBRRatio) {
                case 0:
                    // set both OMX AAC tool flags
                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
                    break;
                case 1:
                    // set single-rate SBR active
                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
                    aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
                    break;
                case 2:
                    // set dual-rate SBR active
                    aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
                    break;
                default:
                    ALOGE("invalid SBR ratio %d", mSBRRatio);
                    TRESPASS();
                }
                break;
            case 0:  // sbr off
            case -1: // sbr undefined
                aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
                aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
                break;
            default:
                ALOGE("invalid SBR mode %d", mSBRMode);
                TRESPASS();
            }



            return OMX_ErrorNone;
        }

@@ -243,6 +281,23 @@ OMX_ERRORTYPE SoftAACEncoder2::internalSetParameter(
                mAACProfile = aacParams->eAACProfile;
            }

            if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
                    && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
                mSBRMode = 0;
                mSBRRatio = 0;
            } else if ((aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
                    && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
                mSBRMode = 1;
                mSBRRatio = 1;
            } else if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
                    && (aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
                mSBRMode = 1;
                mSBRRatio = 2;
            } else {
                mSBRMode = -1; // codec default sbr mode
                mSBRRatio = 0;
            }

            if (setAudioParams() != OK) {
                return OMX_ErrorUndefined;
            }
@@ -305,11 +360,11 @@ static AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) {
}

status_t SoftAACEncoder2::setAudioParams() {
    // We call this whenever sample rate, number of channels or bitrate change
    // We call this whenever sample rate, number of channels, bitrate or SBR mode change
    // in reponse to setParameter calls.

    ALOGV("setAudioParams: %u Hz, %u channels, %u bps",
         mSampleRate, mNumChannels, mBitRate);
    ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
         mSampleRate, mNumChannels, mBitRate, mSBRMode, mSBRRatio);

    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT,
            getAOTFromProfile(mAACProfile))) {
@@ -335,6 +390,24 @@ status_t SoftAACEncoder2::setAudioParams() {
        return UNKNOWN_ERROR;
    }

    if (mSBRMode != -1 && mAACProfile == OMX_AUDIO_AACObjectELD) {
        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) {
            ALOGE("Failed to set AAC encoder parameters");
            return UNKNOWN_ERROR;
        }
    }

    /* SBR ratio parameter configurations:
       0: Default configuration wherein SBR ratio is configured depending on audio object type by
          the FDK.
       1: Downsampled SBR (default for ELD)
       2: Dualrate SBR (default for HE-AAC)
     */
    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) {
        ALOGE("Failed to set AAC encoder parameters");
        return UNKNOWN_ERROR;
    }

    return OK;
}

+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ private:
    OMX_U32 mNumChannels;
    OMX_U32 mSampleRate;
    OMX_U32 mBitRate;
    OMX_S32 mSBRMode;
    OMX_S32 mSBRRatio;
    OMX_U32 mAACProfile;

    bool mSentCodecSpecificData;