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

Commit 4f468960 authored by Chong Zhang's avatar Chong Zhang
Browse files

hdr10+: parameter passing for OMX

Add hdr10+ parameter passing to OMX. Metadata is sent to
OMX component via setConfig(). Available output metadata is
notified via onEvent(), and then retrieved via getConfig().

Hdr10+ metadata pass through is added to soft VP9 for testing.

bug: 118507186
test: Locally built DecoderTest in cts that sends
setParameters with input frames when decoding VP9.
Verify the metadata is received on expected output.

Change-Id: I9bb87581a3036f9ae3cc881cbfe1a3c99c8f78b3
parent d00c4607
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ enum {

    // HDR related
    kKeyHdrStaticInfo    = 'hdrS', // HDRStaticInfo
    kKeyHdr10PlusInfo    = 'hdrD', // raw data

    // color aspects
    kKeyColorRange       = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
+126 −1
Original line number Diff line number Diff line
@@ -576,6 +576,7 @@ ACodec::ACodec()
      mTunneled(false),
      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
      mDescribeHDR10PlusInfoIndex((OMX_INDEXTYPE)0),
      mStateGeneration(0),
      mVendorExtensionsStatus(kExtensionsUnchecked) {
    memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
@@ -3765,10 +3766,19 @@ status_t ACodec::initDescribeHDRStaticInfoIndex() {
            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
    if (err != OK) {
        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
        return err;
    }

    err = mOMXNode->getExtensionIndex(
                "OMX.google.android.index.describeHDR10PlusInfo", &mDescribeHDR10PlusInfoIndex);
    if (err != OK) {
        mDescribeHDR10PlusInfoIndex = (OMX_INDEXTYPE)0;
        return err;
    }

    return OK;
}

status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
    status_t err = ERROR_UNSUPPORTED;
    if (mDescribeHDRStaticInfoIndex) {
@@ -5397,6 +5407,70 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
    return getVendorParameters(portIndex, notify);
}

DescribeHDR10PlusInfoParams* ACodec::getHDR10PlusInfo(size_t paramSizeUsed) {
    if (mDescribeHDR10PlusInfoIndex == 0) {
        ALOGE("getHDR10PlusInfo: does not support DescribeHDR10PlusInfoParams");
        return nullptr;
    }

    size_t newSize = sizeof(DescribeHDR10PlusInfoParams) - 1 +
            ((paramSizeUsed > 0) ? paramSizeUsed : 512);
    if (mHdr10PlusScratchBuffer == nullptr
            || newSize > mHdr10PlusScratchBuffer->size()) {
        mHdr10PlusScratchBuffer = new ABuffer(newSize);
    }
    DescribeHDR10PlusInfoParams *config =
            (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
    InitOMXParams(config);
    config->nSize = mHdr10PlusScratchBuffer->size();
    config->nPortIndex = 1;
    size_t paramSize = config->nSize - sizeof(DescribeHDR10PlusInfoParams) + 1;
    config->nParamSize = paramSize;
    config->nParamSizeUsed = 0;
    status_t err = mOMXNode->getConfig(
            (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
            config, config->nSize);
    if (err != OK) {
        ALOGE("failed to get DescribeHDR10PlusInfoParams (err %d)", err);
        return nullptr;
    }
    if (config->nParamSize != paramSize) {
        ALOGE("DescribeHDR10PlusInfoParams alters nParamSize: %u vs %zu",
                config->nParamSize, paramSize);
        return nullptr;
    }
    if (paramSizeUsed > 0 && config->nParamSizeUsed != paramSizeUsed) {
        ALOGE("DescribeHDR10PlusInfoParams returns wrong nParamSizeUsed: %u vs %zu",
                config->nParamSizeUsed, paramSizeUsed);
        return nullptr;
    }
    return config;
}

void ACodec::onConfigUpdate(OMX_INDEXTYPE configIndex) {
    if (mDescribeHDR10PlusInfoIndex == 0
            || configIndex != mDescribeHDR10PlusInfoIndex) {
        // mDescribeHDR10PlusInfoIndex is the only update we recognize now
        return;
    }

    DescribeHDR10PlusInfoParams *config = getHDR10PlusInfo();
    if (config == nullptr) {
        return;
    }
    if (config->nParamSizeUsed > config->nParamSize) {
        // try again with the size specified
        config = getHDR10PlusInfo(config->nParamSizeUsed);
        if (config == nullptr) {
            return;
        }
    }

    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
    mOutputFormat->setBuffer("hdr10-plus-info",
            ABuffer::CreateAsCopy(config->nValue, config->nParamSizeUsed));
}

void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
    // aspects are normally communicated in ColorAspects
    int32_t range, standard, transfer;
@@ -6337,6 +6411,15 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
            }
        }

        sp<ABuffer> hdr10PlusInfo;
        if (buffer->format()->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
                && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0
                && hdr10PlusInfo != mCodec->mLastHdr10PlusBuffer) {
            native_window_set_buffers_hdr10_plus_metadata(mCodec->mNativeWindow.get(),
                    hdr10PlusInfo->size(), hdr10PlusInfo->data());
            mCodec->mLastHdr10PlusBuffer = hdr10PlusInfo;
        }

        // save buffers sent to the surface so we can get render time when they return
        int64_t mediaTimeUs = -1;
        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
@@ -7475,12 +7558,45 @@ status_t ACodec::setParameters(const sp<AMessage> &params) {
        }
    }

    sp<ABuffer> hdr10PlusInfo;
    if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
            && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
        (void)setHdr10PlusInfo(hdr10PlusInfo);
    }

    // Ignore errors as failure is expected for codecs that aren't video encoders.
    (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);

    return setVendorParameters(params);
}

status_t ACodec::setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo) {
    if (mDescribeHDR10PlusInfoIndex == 0) {
        ALOGE("setHdr10PlusInfo: does not support DescribeHDR10PlusInfoParams");
        return ERROR_UNSUPPORTED;
    }
    size_t newSize = sizeof(DescribeHDR10PlusInfoParams) + hdr10PlusInfo->size() - 1;
    if (mHdr10PlusScratchBuffer == nullptr ||
            newSize > mHdr10PlusScratchBuffer->size()) {
        mHdr10PlusScratchBuffer = new ABuffer(newSize);
    }
    DescribeHDR10PlusInfoParams *config =
            (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
    InitOMXParams(config);
    config->nPortIndex = 0;
    config->nSize = newSize;
    config->nParamSize = hdr10PlusInfo->size();
    config->nParamSizeUsed = hdr10PlusInfo->size();
    memcpy(config->nValue, hdr10PlusInfo->data(), hdr10PlusInfo->size());
    status_t err = mOMXNode->setConfig(
            (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
            config, config->nSize);
    if (err != OK) {
        ALOGE("failed to set DescribeHDR10PlusInfoParams (err %d)", err);
    }
    return OK;
}

// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
// the minimum number of characters to keep in |key| (even if it has trailing tags).
// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
@@ -7902,6 +8018,15 @@ bool ACodec::ExecutingState::onOMXEvent(
            return true;
        }

        case OMX_EventConfigUpdate:
        {
            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);

            mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);

            return true;
        }

        case OMX_EventBufferFlag:
        {
            return true;
+7 −0
Original line number Diff line number Diff line
@@ -2197,6 +2197,13 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                }
                            }

                            sp<ABuffer> hdr10PlusInfo;
                            if (mOutputFormat->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
                                    && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
                                native_window_set_buffers_hdr10_plus_metadata(mSurface.get(),
                                        hdr10PlusInfo->size(), hdr10PlusInfo->data());
                            }

                            if (mime.startsWithIgnoreCase("video/")) {
                                mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
                            }
+18 −1
Original line number Diff line number Diff line
@@ -119,7 +119,8 @@ static bool isHdr(const sp<AMessage> &format) {
    }

    // if user/container supplied HDR static info without transfer set, assume true
    if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
    if ((format->contains("hdr-static-info") || format->contains("hdr10-plus-info"))
            && !format->contains("color-transfer")) {
        return true;
    }
    // otherwise, verify that an HDR transfer function is set
@@ -876,6 +877,16 @@ status_t convertMetaDataToMessage(
            ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
        }

        if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size)
                && size > 0) {
            sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
            if (buffer.get() == NULL || buffer->base() == NULL) {
                return NO_MEMORY;
            }
            memcpy(buffer->data(), data, size);
            msg->setBuffer("hdr10-plus-info", buffer);
        }

        convertMetaDataToMessageColorAspects(meta, msg);
    } else if (!strncasecmp("audio/", mime, 6)) {
        int32_t numChannels, sampleRate;
@@ -1624,6 +1635,12 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
            }
        }

        sp<ABuffer> hdr10PlusInfo;
        if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
            meta->setData(kKeyHdr10PlusInfo, 0,
                    hdr10PlusInfo->data(), hdr10PlusInfo->size());
        }

        convertMessageToMetaDataColorAspects(msg, meta);

        AString tsSchema;
+3 −3
Original line number Diff line number Diff line
@@ -1058,8 +1058,8 @@ OMX_ERRORTYPE SoftAVC::getConfig(
    }
}

OMX_ERRORTYPE SoftAVC::setConfig(
        OMX_INDEXTYPE index, const OMX_PTR _params) {
OMX_ERRORTYPE SoftAVC::internalSetConfig(
        OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig) {
    switch ((int)index) {
        case OMX_IndexConfigVideoIntraVOPRefresh:
        {
@@ -1125,7 +1125,7 @@ OMX_ERRORTYPE SoftAVC::setConfig(
        }

        default:
            return SimpleSoftOMXComponent::setConfig(index, _params);
            return SimpleSoftOMXComponent::internalSetConfig(index, _params, frameConfig);
    }
}

Loading