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

Commit d7c3a752 authored by Mingming Yin's avatar Mingming Yin Committed by Steve Kondik
Browse files

Audio: Enable QCOM's HW AAC encoder conditionally

- Check related system prop to enable QCOM's HW
  AAC encoder
- Use QCOM's HW AAC encoder only for supported
  channels/sample rate/bitrate.
- Use Google's SW AAC encoder if the required AAC
  audio parameter is not supported by QCOM's HW
  AAC encoder

Change-Id: Ifc2409107e48390a6268dc5d5694df8fb47f60aa
parent 6bc7ed20
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -931,9 +931,22 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {

    OMXClient client;
    CHECK_EQ(client.connect(), (status_t)OK);
#ifdef ENABLE_QC_AV_ENHANCEMENTS
    sp<MediaSource> audioEncoder;
    if (QCUtils::UseQCHWAACEncoder(mAudioEncoder,mAudioChannels,mAudioBitRate,mSampleRate)) {
        //use hw aac encoder
        ALOGV("use QCOM HW AAC encoder");
        audioEncoder = OMXCodec::Create(client.interface(), encMeta,
            true /* createEncoder */, audioSource,"OMX.qcom.audio.encoder.aac",OMXCodec::kHardwareCodecsOnly );
    } else {
        audioEncoder = OMXCodec::Create(client.interface(), encMeta,
            true /* createEncoder */, audioSource);
    }
#else
    sp<MediaSource> audioEncoder =
        OMXCodec::Create(client.interface(), encMeta,
                         true /* createEncoder */, audioSource);
#endif
    // If encoder could not be created (as in LPCM), then
    // use the AudioSource directly as the MediaSource.
    if (audioEncoder == NULL) {
+3 −0
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ MediaCodecList::MediaCodecList()

        addMediaCodec(true /* encoder */, "AACEncoder", "audio/mp4a-latm");

        addMediaCodec(
                true /* encoder */, "OMX.qcom.audio.encoder.aac", "audio/mp4a-latm");

        addMediaCodec(
                false /* encoder */, "OMX.google.raw.decoder", "audio/raw");
    }
+56 −0
Original line number Diff line number Diff line
@@ -244,6 +244,58 @@ void QCUtils::setBFrames(
    return;
}

/*
QCOM HW AAC encoder allowed bitrates
------------------------------------------------------------------------------------------------------------------
Bitrate limit |AAC-LC(Mono)           | AAC-LC(Stereo)        |AAC+(Mono)            | AAC+(Stereo)            | eAAC+                      |
Minimum     |Min(24000,0.5 * f_s)   |Min(24000,f_s)           | 24000                      |24000                        |  24000                       |
Maximum    |Min(192000,6 * f_s)    |Min(192000,12 * f_s)  | Min(192000,6 * f_s)  | Min(192000,12 * f_s)  |  Min(192000,12 * f_s) |
------------------------------------------------------------------------------------------------------------------
*/
bool QCUtils::UseQCHWAACEncoder(audio_encoder Encoder,int32_t Channel,int32_t BitRate,int32_t SampleRate)
{
    bool ret = false;
    int minBiteRate = -1;
    int maxBiteRate = -1;
    char propValue[PROPERTY_VALUE_MAX] = {0};

    property_get("qcom.hw.aac.encoder",propValue,NULL);
    if (!strncmp(propValue,"true",sizeof("true"))) {
        //check for QCOM's HW AAC encoder only when qcom.aac.encoder =  true;
        ALOGV("qcom.aac.encoder enabled, check AAC encoder(%d) allowed bitrates",Encoder);
        switch (Encoder) {
        case AUDIO_ENCODER_AAC:// for AAC-LC format
            if (Channel == 1) {//mono
                minBiteRate = MIN_BITERATE_AAC<(SampleRate/2)?MIN_BITERATE_AAC:(SampleRate/2);
                maxBiteRate = MAX_BITERATE_AAC<(SampleRate*6)?MAX_BITERATE_AAC:(SampleRate*6);
            } else if (Channel == 2) {//stereo
                minBiteRate = MIN_BITERATE_AAC<SampleRate?MIN_BITERATE_AAC:SampleRate;
                maxBiteRate = MAX_BITERATE_AAC<(SampleRate*12)?MAX_BITERATE_AAC:(SampleRate*12);
            }
            break;
        case AUDIO_ENCODER_HE_AAC:// for AAC+ format
            if (Channel == 1) {//mono
                minBiteRate = MIN_BITERATE_AAC;
                maxBiteRate = MAX_BITERATE_AAC<(SampleRate*6)?MAX_BITERATE_AAC:(SampleRate*6);
            } else if (Channel == 2) {//stereo
                minBiteRate = MIN_BITERATE_AAC;
                maxBiteRate = MAX_BITERATE_AAC<(SampleRate*12)?MAX_BITERATE_AAC:(SampleRate*12);
            }
            break;
        default:
            ALOGV("encoder:%d not supported by QCOM HW AAC encoder",Encoder);

        }

        //return true only when 1. minBiteRate and maxBiteRate are updated(not -1) 2. minBiteRate <= SampleRate <= maxBiteRate
        if (SampleRate >= minBiteRate && SampleRate <= maxBiteRate) {
            ret = true;
        }
    }

    return ret;
}

sp<MediaExtractor> QCUtils::MediaExtractor_CreateIfNeeded(sp<MediaExtractor> defaultExt,
                                                            const sp<DataSource> &source,
                                                            const char *mime) {
@@ -381,6 +433,10 @@ void QCUtils::setBFrames(
        int32_t iFramesInterval, int32_t frameRate) {
}

bool QCUtils::UseQCHWAACEncoder(audio_encoder Encoder,int32_t Channel,
    int32_t BitRate,int32_t SampleRate) {
    return false;
}

sp<MediaExtractor> QCUtils::MediaExtractor_CreateIfNeeded(sp<MediaExtractor> defaultExt,
                                                            const sp<DataSource> &source,
+4 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#include <camera/CameraParameters.h>
#include <OMX_Video.h>

#define MIN_BITERATE_AAC 24000
#define MAX_BITERATE_AAC 192000

namespace android {

@@ -105,6 +107,8 @@ struct QCUtils {
    static void setBFrames(OMX_VIDEO_PARAM_AVCTYPE &h264type, bool &numBFrames,
            int32_t iFramesInterval, int32_t frameRate);

    static bool UseQCHWAACEncoder(audio_encoder Encoder,int32_t Channel,int32_t BitRate, int32_t SampleRate);

    static sp<MediaExtractor> MediaExtractor_CreateIfNeeded(sp<MediaExtractor> defaultExt,
              const sp<DataSource> &source, const char *mime);