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

Commit 9ed79de1 authored by Andy Hung's avatar Andy Hung
Browse files

FlacDecoder: Enable float support

Test: MediaCodecTest#testFlacIdentity
Bug: 122117025
Change-Id: I9a80a61fbcfc615305b39befbbd9840748098a6a
parent decf9a51
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -83,8 +83,21 @@ public:
                DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
                .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 32768))
                .build());

        addParameter(
                DefineParam(mPcmEncodingInfo, C2_PARAMKEY_PCM_ENCODING)
                .withDefault(new C2StreamPcmEncodingInfo::output(0u, C2Config::PCM_16))
                .withFields({C2F(mPcmEncodingInfo, value).oneOf({
                     C2Config::PCM_16,
                     // C2Config::PCM_8,
                     C2Config::PCM_FLOAT})
                })
                .withSetter((Setter<decltype(*mPcmEncodingInfo)>::StrictValueWithNoDeps))
                .build());
    }

    int32_t getPcmEncodingInfo() const { return mPcmEncodingInfo->value; }

private:
    std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
    std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
@@ -94,6 +107,7 @@ private:
    std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
    std::shared_ptr<C2BitrateTuning::input> mBitrate;
    std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
    std::shared_ptr<C2StreamPcmEncodingInfo::output> mPcmEncodingInfo;
};

C2SoftFlacDec::C2SoftFlacDec(
@@ -263,11 +277,11 @@ void C2SoftFlacDec::process(
        return;
    }

    size_t outSize;
    if (mHasStreamInfo)
        outSize = mStreamInfo.max_blocksize * mStreamInfo.channels * sizeof(short);
    else
        outSize = kMaxBlockSize * FLACDecoder::kMaxChannels * sizeof(short);
    const bool outputFloat = mIntf->getPcmEncodingInfo() == C2Config::PCM_FLOAT;
    const size_t sampleSize = outputFloat ? sizeof(float) : sizeof(short);
    size_t outSize = mHasStreamInfo ?
            mStreamInfo.max_blocksize * mStreamInfo.channels * sampleSize
          : kMaxBlockSize * FLACDecoder::kMaxChannels * sampleSize;

    std::shared_ptr<C2LinearBlock> block;
    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
@@ -284,9 +298,8 @@ void C2SoftFlacDec::process(
        return;
    }

    short *output = reinterpret_cast<short *>(wView.data());
    status_t decoderErr = mFLACDecoder->decodeOneFrame(
                            input, inSize, output, &outSize);
                            input, inSize, wView.data(), &outSize, outputFloat);
    if (decoderErr != OK) {
        ALOGE("process: FLACDecoder decodeOneFrame returns error %d", decoderErr);
        mSignalledError = true;
+8 −5
Original line number Diff line number Diff line
@@ -2183,7 +2183,8 @@ status_t ACodec::configureCodec(
            err = setupG711Codec(encoder, sampleRate, numChannels);
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
        // numChannels needs to be set to properly communicate PCM values.
        int32_t numChannels = 2, sampleRate = 44100, compressionLevel = -1;
        if (encoder &&
                (!msg->findInt32("channel-count", &numChannels)
                        || !msg->findInt32("sample-rate", &sampleRate))) {
@@ -2209,7 +2210,7 @@ status_t ACodec::configureCodec(
                }
            }
            err = setupFlacCodec(
                    encoder, numChannels, sampleRate, compressionLevel);
                    encoder, numChannels, sampleRate, compressionLevel, pcmEncoding);
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
        int32_t numChannels, sampleRate;
@@ -3033,8 +3034,8 @@ status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numCha
}

status_t ACodec::setupFlacCodec(
        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {

        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel,
        AudioEncoding encoding) {
    if (encoder) {
        OMX_AUDIO_PARAM_FLACTYPE def;
        InitOMXParams(&def);
@@ -3057,7 +3058,8 @@ status_t ACodec::setupFlacCodec(
    return setupRawAudioFormat(
            encoder ? kPortIndexInput : kPortIndexOutput,
            sampleRate,
            numChannels);
            numChannels,
            encoding);
}

status_t ACodec::setupRawAudioFormat(
@@ -3115,6 +3117,7 @@ status_t ACodec::setupRawAudioFormat(
    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;

    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
        ALOGE("%s: incorrect numChannels: %d", __func__, numChannels);
        return OMX_ErrorNone;
    }

+28 −10
Original line number Diff line number Diff line
@@ -89,12 +89,12 @@ void SoftFlacDecoder::initPorts() {
    def.eDir = OMX_DirOutput;
    def.nBufferCountMin = kNumOutputBuffers;
    def.nBufferCountActual = def.nBufferCountMin;
    def.nBufferSize = 4096 * FLACDecoder::kMaxChannels;
    def.nBufferSize = kNumSamplesPerFrame * FLACDecoder::kMaxChannels * sizeof(float);
    def.bEnabled = OMX_TRUE;
    def.bPopulated = OMX_FALSE;
    def.eDomain = OMX_PortDomainAudio;
    def.bBuffersContiguous = OMX_FALSE;
    def.nBufferAlignment = 2;
    def.nBufferAlignment = sizeof(float);

    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    def.format.audio.pNativeRender = NULL;
@@ -173,7 +173,7 @@ OMX_ERRORTYPE SoftFlacDecoder::internalGetParameter(
                flacParams->nChannels = mStreamInfo.channels;
                flacParams->nSampleRate = mStreamInfo.sample_rate;
            } else {
                flacParams->nChannels = 1;
                flacParams->nChannels = 2;
                flacParams->nSampleRate = 44100;
            }

@@ -195,10 +195,10 @@ OMX_ERRORTYPE SoftFlacDecoder::internalGetParameter(
                return OMX_ErrorBadPortIndex;
            }

            pcmParams->eNumData = OMX_NumericalDataSigned;
            pcmParams->eNumData = mNumericalData;
            pcmParams->eEndian = OMX_EndianBig;
            pcmParams->bInterleaved = OMX_TRUE;
            pcmParams->nBitPerSample = 16;
            pcmParams->nBitPerSample = mBitsPerSample;
            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
@@ -211,7 +211,7 @@ OMX_ERRORTYPE SoftFlacDecoder::internalGetParameter(
                pcmParams->nChannels = mStreamInfo.channels;
                pcmParams->nSamplingRate = mStreamInfo.sample_rate;
            } else {
                pcmParams->nChannels = 1;
                pcmParams->nChannels = 2;
                pcmParams->nSamplingRate = 44100;
            }

@@ -281,6 +281,19 @@ OMX_ERRORTYPE SoftFlacDecoder::internalSetParameter(
                return OMX_ErrorBadPortIndex;
            }

            if (pcmParams->eNumData == OMX_NumericalDataFloat && pcmParams->nBitPerSample == 32) {
                mNumericalData = OMX_NumericalDataFloat;
                mBitsPerSample = 32;
            } else if (pcmParams->eNumData == OMX_NumericalDataSigned
                     && pcmParams->nBitPerSample == 16) {
                mNumericalData = OMX_NumericalDataSigned;
                mBitsPerSample = 16;
            } else {
                ALOGE("Invalid eNumData %d, nBitsPerSample %d",
                        pcmParams->eNumData, pcmParams->nBitPerSample);
                return OMX_ErrorUndefined;
            }

            return OMX_ErrorNone;
        }

@@ -301,11 +314,13 @@ void SoftFlacDecoder::onQueueFilled(OMX_U32 /* portIndex */) {
    List<BufferInfo *> &inQueue = getPortQueue(0);
    List<BufferInfo *> &outQueue = getPortQueue(1);

    const bool outputFloat = mNumericalData == OMX_NumericalDataFloat;

    ALOGV("onQueueFilled %d/%d:", inQueue.empty(), outQueue.empty());
    while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mFinishedDecoder) {
        BufferInfo *outInfo = *outQueue.begin();
        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
        int16_t *outBuffer = reinterpret_cast<int16_t *>(outHeader->pBuffer + outHeader->nOffset);
        void *outBuffer = reinterpret_cast<void *>(outHeader->pBuffer + outHeader->nOffset);
        size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
        int64_t timeStamp = 0;

@@ -374,7 +389,7 @@ void SoftFlacDecoder::onQueueFilled(OMX_U32 /* portIndex */) {
            }

            status_t decoderErr = mFLACDecoder->decodeOneFrame(
                    inBuffer, inBufferLength, outBuffer, &outBufferSize);
                    inBuffer, inBufferLength, outBuffer, &outBufferSize, outputFloat);
            if (decoderErr != OK) {
                ALOGE("onQueueFilled: FLACDecoder decodeOneFrame returns error %d", decoderErr);
                mSignalledError = true;
@@ -393,7 +408,9 @@ void SoftFlacDecoder::onQueueFilled(OMX_U32 /* portIndex */) {
                continue;
            }
        } else if (mSawInputEOS) {
            status_t decoderErr = mFLACDecoder->decodeOneFrame(NULL, 0, outBuffer, &outBufferSize);
            status_t decoderErr = mFLACDecoder->decodeOneFrame(
                    nullptr /* inBuffer */, 0 /* inBufferLen */,
                    outBuffer, &outBufferSize, outputFloat);
            mFinishedDecoder = true;
            if (decoderErr != OK) {
                ALOGE("onQueueFilled: FLACDecoder finish returns error %d", decoderErr);
@@ -456,7 +473,8 @@ void SoftFlacDecoder::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
            mOutputPortSettingsChange = AWAITING_ENABLED;
            PortInfo *info = editPortInfo(1 /* portIndex */);
            if (!info->mDef.bEnabled) {
                info->mDef.nBufferSize = mStreamInfo.max_blocksize * mStreamInfo.channels * 2;
                info->mDef.nBufferSize =
                        mStreamInfo.max_blocksize * mStreamInfo.channels * sizeof(float);
            }
            break;
        }
+4 −0
Original line number Diff line number Diff line
@@ -45,10 +45,14 @@ protected:
    virtual void onReset() override;

private:
    static constexpr unsigned int kNumSamplesPerFrame = 2048; // adjusted based on stream.

    enum {
        kNumInputBuffers   = 4,
        kNumOutputBuffers  = 4,
    };
    OMX_NUMERICALDATATYPE mNumericalData = OMX_NumericalDataSigned;
    OMX_U32 mBitsPerSample = 16;

    FLACDecoder *mFLACDecoder;
    FLAC__StreamMetadata_StreamInfo mStreamInfo;
+8 −2
Original line number Diff line number Diff line
@@ -27,11 +27,17 @@ cc_library {
    },

    static: {
        whole_static_libs: ["libFLAC"],
        whole_static_libs: [
            "libFLAC",
            "libaudioutils",
        ],
    },

    shared: {
        static_libs: ["libFLAC"],
        static_libs: [
            "libFLAC",
            "libaudioutils",
        ],
    },

    shared_libs: [
Loading