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

Commit ea068487 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5587110 from 7d44121e to qt-release

Change-Id: Ibc5ce7276504a2a0d41f4752ce77f118d28fdc5f
parents 05015a3f 7d44121e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
            DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
                .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
                .withFields({
                    C2F(mSize, width).inRange(320, 1920, 2),
                    C2F(mSize, height).inRange(128, 1088, 2),
                    C2F(mSize, width).inRange(2, 1920, 2),
                    C2F(mSize, height).inRange(2, 1088, 2),
                })
                .withSetter(SizeSetter)
                .build());
+88 −9
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#define LOG_TAG "C2SoftVpxDec"
#include <log/log.h>

#include <algorithm>

#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/MediaDefs.h>

@@ -303,13 +305,43 @@ private:
#endif
};

C2SoftVpxDec::ConverterThread::ConverterThread(
        const std::shared_ptr<Mutexed<ConversionQueue>> &queue)
    : Thread(false), mQueue(queue) {}

bool C2SoftVpxDec::ConverterThread::threadLoop() {
    Mutexed<ConversionQueue>::Locked queue(*mQueue);
    if (queue->entries.empty()) {
        queue.waitForCondition(queue->cond);
        if (queue->entries.empty()) {
            return true;
        }
    }
    std::function<void()> convert = queue->entries.front();
    queue->entries.pop_front();
    if (!queue->entries.empty()) {
        queue->cond.signal();
    }
    queue.unlock();

    convert();

    queue.lock();
    if (--queue->numPending == 0u) {
        queue->cond.broadcast();
    }
    return true;
}

C2SoftVpxDec::C2SoftVpxDec(
        const char *name,
        c2_node_id_t id,
        const std::shared_ptr<IntfImpl> &intfImpl)
    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
      mIntf(intfImpl),
      mCodecCtx(nullptr) {
      mCodecCtx(nullptr),
      mCoreCount(1),
      mQueue(new Mutexed<ConversionQueue>) {
}

C2SoftVpxDec::~C2SoftVpxDec() {
@@ -399,7 +431,7 @@ status_t C2SoftVpxDec::initDecoder() {

    vpx_codec_dec_cfg_t cfg;
    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
    cfg.threads = GetCPUCoreCount();
    cfg.threads = mCoreCount = GetCPUCoreCount();

    vpx_codec_flags_t flags;
    memset(&flags, 0, sizeof(vpx_codec_flags_t));
@@ -413,6 +445,18 @@ status_t C2SoftVpxDec::initDecoder() {
        return UNKNOWN_ERROR;
    }

    if (mMode == MODE_VP9) {
        using namespace std::string_literals;
        for (int i = 0; i < mCoreCount; ++i) {
            sp<ConverterThread> thread(new ConverterThread(mQueue));
            mConverterThreads.push_back(thread);
            if (thread->run(("vp9conv #"s + std::to_string(i)).c_str(),
                            ANDROID_PRIORITY_AUDIO) != OK) {
                return UNKNOWN_ERROR;
            }
        }
    }

    return OK;
}

@@ -422,6 +466,21 @@ status_t C2SoftVpxDec::destroyDecoder() {
        delete mCodecCtx;
        mCodecCtx = nullptr;
    }
    bool running = true;
    for (const sp<ConverterThread> &thread : mConverterThreads) {
        thread->requestExit();
    }
    while (running) {
        mQueue->lock()->cond.broadcast();
        running = false;
        for (const sp<ConverterThread> &thread : mConverterThreads) {
            if (thread->isRunning()) {
                running = true;
                break;
            }
        }
    }
    mConverterThreads.clear();

    return OK;
}
@@ -759,10 +818,30 @@ bool C2SoftVpxDec::outputBuffer(
        const uint16_t *srcV = (const uint16_t *)img->planes[VPX_PLANE_V];

        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2,
                                    dstYStride / sizeof(uint32_t),
                                    mWidth, mHeight);
            Mutexed<ConversionQueue>::Locked queue(*mQueue);
            size_t i = 0;
            constexpr size_t kHeight = 64;
            for (; i < mHeight; i += kHeight) {
                queue->entries.push_back(
                        [dst, srcY, srcU, srcV,
                         srcYStride, srcUStride, srcVStride, dstYStride,
                         width = mWidth, height = std::min(mHeight - i, kHeight)] {
                            convertYUV420Planar16ToY410(
                                    (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
                                    width, height);
                        });
                srcY += srcYStride / 2 * kHeight;
                srcU += srcUStride / 2 * (kHeight / 2);
                srcV += srcVStride / 2 * (kHeight / 2);
                dst += dstYStride * kHeight;
            }
            CHECK_EQ(0u, queue->numPending);
            queue->numPending = queue->entries.size();
            while (queue->numPending > 0) {
                queue->cond.signal();
                queue.waitForCondition(queue->cond);
            }
        } else {
            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
                                                srcUStride / 2, srcVStride / 2,
+22 −0
Original line number Diff line number Diff line
@@ -50,6 +50,19 @@ struct C2SoftVpxDec : public SimpleC2Component {
        MODE_VP9,
    } mMode;

    struct ConversionQueue;

    class ConverterThread : public Thread {
    public:
        explicit ConverterThread(
                const std::shared_ptr<Mutexed<ConversionQueue>> &queue);
        ~ConverterThread() override = default;
        bool threadLoop() override;

    private:
        std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
    };

    std::shared_ptr<IntfImpl> mIntf;
    vpx_codec_ctx_t *mCodecCtx;
    bool mFrameParallelMode;  // Frame parallel is only supported by VP9 decoder.
@@ -59,6 +72,15 @@ struct C2SoftVpxDec : public SimpleC2Component {
    bool mSignalledOutputEos;
    bool mSignalledError;

    int mCoreCount;
    struct ConversionQueue {
        std::list<std::function<void()>> entries;
        Condition cond;
        size_t numPending{0u};
    };
    std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
    std::vector<sp<ConverterThread>> mConverterThreads;

    status_t initDecoder();
    status_t destroyDecoder();
    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
+6 −0
Original line number Diff line number Diff line
@@ -1993,6 +1993,12 @@ void MatroskaExtractor::addTracks() {
                    }
                } else if (!strcmp("V_AV1", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
                    if (codecPrivateSize > 0) {
                        // 'csd-0' for AV1 is the Blob of Codec Private data as
                        // specified in https://aomediacodec.github.io/av1-isobmff/.
                        AMediaFormat_setBuffer(
                                meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
                    }
                } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) {
                        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
                                MEDIA_MIMETYPE_VIDEO_MPEG2);
+64 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/foundation/OpusHeader.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
#include <media/AudioSystem.h>
#include <media/MediaPlayerInterface.h>
@@ -573,6 +574,68 @@ static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &fo
    }
}

static void parseAV1ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    // Parse CSD structure to extract profile level information
    // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox
    const uint8_t *data = csd->data();
    size_t remaining = csd->size();
    if (remaining < 4 || data[0] != 0x81) {  // configurationVersion == 1
        return;
    }
    uint8_t profileData = (data[1] & 0xE0) >> 5;
    uint8_t levelData = data[1] & 0x1F;
    uint8_t highBitDepth = (data[2] & 0x40) >> 6;

    const static ALookup<std::pair<uint8_t, uint8_t>, int32_t> profiles {
        { { 0, 0 }, AV1ProfileMain8 },
        { { 1, 0 }, AV1ProfileMain10 },
    };

    int32_t profile;
    if (profiles.map(std::make_pair(highBitDepth, profileData), &profile)) {
        // bump to HDR profile
        if (isHdr(format) && profile == AV1ProfileMain10) {
            if (format->contains("hdr10-plus-info")) {
                profile = AV1ProfileMain10HDR10Plus;
            } else {
                profile = AV1ProfileMain10HDR10;
            }
        }
        format->setInt32("profile", profile);
    }
    const static ALookup<uint8_t, int32_t> levels {
        { 0, AV1Level2   },
        { 1, AV1Level21  },
        { 2, AV1Level22  },
        { 3, AV1Level23  },
        { 4, AV1Level3   },
        { 5, AV1Level31  },
        { 6, AV1Level32  },
        { 7, AV1Level33  },
        { 8, AV1Level4   },
        { 9, AV1Level41  },
        { 10, AV1Level42  },
        { 11, AV1Level43  },
        { 12, AV1Level5   },
        { 13, AV1Level51  },
        { 14, AV1Level52  },
        { 15, AV1Level53  },
        { 16, AV1Level6   },
        { 17, AV1Level61  },
        { 18, AV1Level62  },
        { 19, AV1Level63  },
        { 20, AV1Level7   },
        { 21, AV1Level71  },
        { 22, AV1Level72  },
        { 23, AV1Level73  },
    };

    int32_t level;
    if (levels.map(levelData, &level)) {
        format->setInt32("level", level);
    }
}


static std::vector<std::pair<const char *, uint32_t>> stringMappings {
    {
@@ -1234,6 +1297,7 @@ status_t convertMetaDataToMessage(
        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);
        parseAV1ProfileLevelFromCsd(buffer, msg);
    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const char *)data, size);
        if (esds.InitCheck() != (status_t)OK) {
Loading