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

Commit 6f23cfc9 authored by Wonsik Kim's avatar Wonsik Kim
Browse files

CCodec: convert audio decoder output PCM format

Bug: 197719179
Test: cts/media/device-small
Change-Id: I861d29633358cf0c812b45f119f6ba00da1512c6
parent 05ad278a
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -1311,8 +1311,8 @@ void CCodec::configure(const sp<AMessage> &msg) {
            }
        }

        // set channel-mask
        if (config->mDomain & Config::IS_AUDIO) {
            // set channel-mask
            int32_t mask;
            if (msg->findInt32(KEY_CHANNEL_MASK, &mask)) {
                if (config->mDomain & Config::IS_ENCODER) {
@@ -1321,6 +1321,15 @@ void CCodec::configure(const sp<AMessage> &msg) {
                    config->mOutputFormat->setInt32(KEY_CHANNEL_MASK, mask);
                }
            }

            // set PCM encoding
            int32_t pcmEncoding = kAudioEncodingPcm16bit;
            msg->findInt32(KEY_PCM_ENCODING, &pcmEncoding);
            if (encoder) {
                config->mInputFormat->setInt32("android._config-pcm-encoding", pcmEncoding);
            } else {
                config->mOutputFormat->setInt32("android._config-pcm-encoding", pcmEncoding);
            }
        }

        std::unique_ptr<C2Param> colorTransferRequestParam;
+58 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <C2PlatformSupport.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
@@ -197,6 +198,56 @@ void OutputBuffers::setSkipCutBuffer(int32_t skip, int32_t cut) {
    mSkipCutBuffer = new SkipCutBuffer(skip, cut, mChannelCount);
}

bool OutputBuffers::convert(
        const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst) {
    if (!src || src->data().type() != C2BufferData::LINEAR) {
        return false;
    }
    int32_t configEncoding = kAudioEncodingPcm16bit;
    int32_t codecEncoding = kAudioEncodingPcm16bit;
    if (mFormat->findInt32("android._codec-pcm-encoding", &codecEncoding)
            && mFormat->findInt32("android._config-pcm-encoding", &configEncoding)) {
        if (mSrcEncoding != codecEncoding || mDstEncoding != configEncoding) {
            if (codecEncoding != configEncoding) {
                mDataConverter = AudioConverter::Create(
                        (AudioEncoding)codecEncoding, (AudioEncoding)configEncoding);
                ALOGD_IF(mDataConverter, "[%s] Converter created from %d to %d",
                         mName, codecEncoding, configEncoding);
                mFormatWithConverter = mFormat->dup();
                mFormatWithConverter->setInt32(KEY_PCM_ENCODING, configEncoding);
            } else {
                mDataConverter = nullptr;
                mFormatWithConverter = nullptr;
            }
            mSrcEncoding = codecEncoding;
            mDstEncoding = configEncoding;
        }
        if (int encoding; !mFormat->findInt32(KEY_PCM_ENCODING, &encoding)
                || encoding != mDstEncoding) {
        }
    }
    if (!mDataConverter) {
        return false;
    }
    sp<MediaCodecBuffer> srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
    if (!srcBuffer) {
        return false;
    }
    if (!dst) {
        *dst = new Codec2Buffer(
                mFormat,
                new ABuffer(mDataConverter->targetSize(srcBuffer->size())));
    }
    sp<MediaCodecBuffer> dstBuffer = *dst;
    status_t err = mDataConverter->convert(srcBuffer, dstBuffer);
    if (err != OK) {
        ALOGD("[%s] buffer conversion failed: %d", mName, err);
        return false;
    }
    dstBuffer->setFormat(mFormatWithConverter);
    return true;
}

void OutputBuffers::clearStash() {
    mPending.clear();
    mReorderStash.clear();
@@ -1074,7 +1125,7 @@ status_t OutputBuffersArray::registerBuffer(
        return err;
    }
    c2Buffer->setFormat(mFormat);
    if (!c2Buffer->copy(buffer)) {
    if (!convert(buffer, &c2Buffer) && !c2Buffer->copy(buffer)) {
        ALOGD("[%s] copy buffer failed", mName);
        return WOULD_BLOCK;
    }
@@ -1190,10 +1241,13 @@ status_t FlexOutputBuffers::registerBuffer(
        const std::shared_ptr<C2Buffer> &buffer,
        size_t *index,
        sp<MediaCodecBuffer> *clientBuffer) {
    sp<Codec2Buffer> newBuffer = wrap(buffer);
    sp<Codec2Buffer> newBuffer;
    if (!convert(buffer, &newBuffer)) {
        newBuffer = wrap(buffer);
        if (newBuffer == nullptr) {
            return NO_MEMORY;
        }
    }
    newBuffer->setFormat(mFormat);
    *index = mImpl.assignSlot(newBuffer);
    handleImageData(newBuffer);
+16 −0
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@

#define CCODEC_BUFFERS_H_

#include <optional>
#include <string>

#include <C2Config.h>
#include <DataConverter.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/MediaCodecBuffer.h>

@@ -382,6 +384,14 @@ protected:
     */
    void submit(const sp<MediaCodecBuffer> &buffer);

    /**
     * Apply DataConverter from |src| to |*dst| if needed. If |dst| is nullptr,
     * a new buffer is allocated.
     *
     * Returns true if conversion was needed and executed; false otherwise.
     */
    bool convert(const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst);

private:
    // SkipCutBuffer
    int32_t mDelay;
@@ -391,6 +401,12 @@ private:

    void setSkipCutBuffer(int32_t skip, int32_t cut);

    // DataConverter
    sp<DataConverter> mDataConverter;
    sp<AMessage> mFormatWithConverter;
    std::optional<int32_t> mSrcEncoding;
    std::optional<int32_t> mDstEncoding;

    // Output stash

    // Struct for an entry in the output stash (mPending and mReorderStash)
+22 −17
Original line number Diff line number Diff line
@@ -657,16 +657,15 @@ void CCodecConfig::initializeStandardParams() {
    add(ConfigMapper(KEY_SAMPLE_RATE,   C2_PARAMKEY_CODED_SAMPLE_RATE,  "value")
        .limitTo(D::AUDIO & D::CODED));

    add(ConfigMapper(KEY_PCM_ENCODING,  C2_PARAMKEY_PCM_ENCODING,       "value")
        .limitTo(D::AUDIO)
        .withMappers([](C2Value v) -> C2Value {
    auto pcmEncodingMapper = [](C2Value v) -> C2Value {
        int32_t value;
        C2Config::pcm_encoding_t to;
        if (v.get(&value) && C2Mapper::map(value, &to)) {
            return to;
        }
        return C2Value();
        }, [](C2Value v) -> C2Value {
    };
    auto pcmEncodingReverse = [](C2Value v) -> C2Value {
        C2Config::pcm_encoding_t value;
        int32_t to;
        using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
@@ -674,7 +673,13 @@ void CCodecConfig::initializeStandardParams() {
            return to;
        }
        return C2Value();
        }));
    };
    add(ConfigMapper(KEY_PCM_ENCODING,              C2_PARAMKEY_PCM_ENCODING, "value")
        .limitTo(D::AUDIO)
        .withMappers(pcmEncodingMapper, pcmEncodingReverse));
    add(ConfigMapper("android._codec-pcm-encoding", C2_PARAMKEY_PCM_ENCODING, "value")
        .limitTo(D::AUDIO & D::READ)
        .withMappers(pcmEncodingMapper, pcmEncodingReverse));

    add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
        .limitTo(D::AUDIO & D::CODED)
+2 −1
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ cc_library_shared {

    srcs: [
        "CodecBase.cpp",
        "DataConverter.cpp",
        "FrameRenderTracker.cpp",
        "MediaCodecListWriter.cpp",
        "SkipCutBuffer.cpp",
@@ -125,6 +126,7 @@ cc_library_shared {
    ],

    shared_libs: [
        "libaudioutils",
        "libgui",
        "libhidlallocatorutils",
        "liblog",
@@ -266,7 +268,6 @@ cc_library {
        "CallbackMediaSource.cpp",
        "CameraSource.cpp",
        "CameraSourceTimeLapse.cpp",
        "DataConverter.cpp",
        "FrameDecoder.cpp",
        "HevcUtils.cpp",
        "InterfaceUtils.cpp",