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

Commit 2d2a2967 authored by Chong Zhang's avatar Chong Zhang
Browse files

hdr: enable VP9 profile2 in SoftVPX

- enable highbitdepth in libvpx use 16bit for 10-bit YUV

- hook up metadata retrieval in SoftVPX

- send metadata to native window

- pack 10-bit YUV into RGBA_1010102 format in soft renderer

bug: 64227585

Change-Id: Id900a1a8ee5cc2e5c19eef0f46419ad9b8eb587b
parent cf11d8f7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -551,6 +551,8 @@ ACodec::ACodec()
      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
      mStateGeneration(0),
      mVendorExtensionsStatus(kExtensionsUnchecked) {
    memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));

    mUninitializedState = new UninitializedState(this);
    mLoadedState = new LoadedState(this);
    mLoadedToIdleState = new LoadedToIdleState(this);
@@ -6103,6 +6105,14 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
            mCodec->mLastNativeWindowDataSpace = dataSpace;
            ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
        }
        if (buffer->format()->contains("hdr-static-info")) {
            HDRStaticInfo info;
            if (ColorUtils::getHDRStaticInfoFromFormat(buffer->format(), &info)
                && memcmp(&mCodec->mLastHDRStaticInfo, &info, sizeof(info))) {
                setNativeWindowHdrMetadata(mCodec->mNativeWindow.get(), &info);
                mCodec->mLastHDRStaticInfo = info;
            }
        }

        // save buffers sent to the surface so we can get render time when they return
        int64_t mediaTimeUs = -1;
+6 −0
Original line number Diff line number Diff line
@@ -1832,6 +1832,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                        mSurface.get(), (android_dataspace)dataSpace);
                                ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
                            }
                            if (mOutputFormat->contains("hdr-static-info")) {
                                HDRStaticInfo info;
                                if (ColorUtils::getHDRStaticInfoFromFormat(mOutputFormat, &info)) {
                                    setNativeWindowHdrMetadata(mSurface.get(), &info);
                                }
                            }

                            if (mime.startsWithIgnoreCase("video/")) {
                                mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
+35 −1
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@
#define LOG_TAG "SurfaceUtils"
#include <utils/Log.h>

#include <media/hardware/VideoAPI.h>
#include <media/stagefright/SurfaceUtils.h>

#include <gui/Surface.h>

namespace android {
@@ -128,6 +128,40 @@ status_t setNativeWindowSizeFormatAndUsage(
    return NO_ERROR;
}

void setNativeWindowHdrMetadata(ANativeWindow *nativeWindow, HDRStaticInfo *info) {
    struct android_smpte2086_metadata smpte2086_meta = {
            .displayPrimaryRed = {
                    info->sType1.mR.x * 0.00002f,
                    info->sType1.mR.y * 0.00002f
            },
            .displayPrimaryGreen = {
                    info->sType1.mG.x * 0.00002f,
                    info->sType1.mG.y * 0.00002f
            },
            .displayPrimaryBlue = {
                    info->sType1.mB.x * 0.00002f,
                    info->sType1.mB.y * 0.00002f
            },
            .whitePoint = {
                    info->sType1.mW.x * 0.00002f,
                    info->sType1.mW.y * 0.00002f
            },
            .maxLuminance = (float) info->sType1.mMaxDisplayLuminance,
            .minLuminance = info->sType1.mMinDisplayLuminance * 0.0001f
    };

    int err = native_window_set_buffers_smpte2086_metadata(nativeWindow, &smpte2086_meta);
    ALOGW_IF(err != 0, "failed to set smpte2086 metadata on surface (%d)", err);

    struct android_cta861_3_metadata cta861_meta = {
            .maxContentLightLevel = (float) info->sType1.mMaxContentLightLevel,
            .maxFrameAverageLightLevel = (float) info->sType1.mMaxFrameAverageLightLevel
    };

    err = native_window_set_buffers_cta861_3_metadata(nativeWindow, &cta861_meta);
    ALOGW_IF(err != 0, "failed to set cta861_3 metadata on surface (%d)", err);
}

status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */) {
    status_t err = NO_ERROR;
    ANativeWindowBuffer* anb = NULL;
+2 −1
Original line number Diff line number Diff line
@@ -353,7 +353,8 @@ bool SoftMPEG4::handlePortSettingsChange() {
    bool portWillReset = false;
    const bool fakeStride = true;
    SoftVideoDecoderOMXComponent::handlePortSettingsChange(
            &portWillReset, buf_width, buf_height, cropSettingsMode, fakeStride);
            &portWillReset, buf_width, buf_height,
            OMX_COLOR_FormatYUV420Planar, cropSettingsMode, fakeStride);
    if (portWillReset) {
        if (mMode == MODE_H263) {
            PVCleanUpVideoDecoder(mHandle);
+16 −4
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ namespace android {
// Only need to declare the highest supported profile and level here.
static const CodecProfileLevel kVP9ProfileLevels[] = {
    { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level5 },
    { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Level5 },
    { OMX_VIDEO_VP9Profile2HDR, OMX_VIDEO_VP9Level5 },
};

SoftVPX::SoftVPX(
@@ -78,6 +80,10 @@ static int GetCPUCoreCount() {
    return cpuCoreCount;
}

bool SoftVPX::supportDescribeHdrStaticInfo() {
    return true;
}

status_t SoftVPX::initDecoder() {
    mCtx = new vpx_codec_ctx_t;
    vpx_codec_err_t vpx_err;
@@ -146,15 +152,21 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por
        uint32_t height = mImg->d_h;
        outInfo = *outQueue.begin();
        outHeader = outInfo->mHeader;
        CHECK_EQ(mImg->fmt, VPX_IMG_FMT_I420);
        handlePortSettingsChange(portWillReset, width, height);
        CHECK(mImg->fmt == VPX_IMG_FMT_I420 || mImg->fmt == VPX_IMG_FMT_I42016);
        OMX_COLOR_FORMATTYPE outputColorFormat = OMX_COLOR_FormatYUV420Planar;
        int32_t bpp = 1;
        if (mImg->fmt == VPX_IMG_FMT_I42016) {
            outputColorFormat = OMX_COLOR_FormatYUV420Planar16;
            bpp = 2;
        }
        handlePortSettingsChange(portWillReset, width, height, outputColorFormat);
        if (*portWillReset) {
            return true;
        }

        outHeader->nOffset = 0;
        outHeader->nFlags = 0;
        outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
        outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * bpp * 3) / 2;
        outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv;
        if (outputBufferSafe(outHeader)) {
            uint8_t *dst = outHeader->pBuffer;
Loading