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

Commit 9acb919b authored by Wonsik Kim's avatar Wonsik Kim Committed by Automerger Merge Worker
Browse files

Merge changes Ia8f9e872,Ie7801651 am: 35c51248 am: d6365327

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1956459

Change-Id: Ia9b14864315dc6374b4c28aab19d7a8d74982e0a
parents f092f490 d6365327
Loading
Loading
Loading
Loading
+46 −4
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct C2Config {
    enum drc_compression_mode_t : int32_t;  ///< DRC compression mode
    enum drc_effect_type_t : int32_t;       ///< DRC effect type
    enum drc_album_mode_t : int32_t;        ///< DRC album mode
    enum hdr_dynamic_metadata_type_t : uint32_t;  ///< HDR dynamic metadata type
    enum intra_refresh_mode_t : uint32_t;   ///< intra refresh modes
    enum level_t : uint32_t;                ///< coding level
    enum ordinal_key_t : uint32_t;          ///< work ordering keys
@@ -189,10 +190,13 @@ enum C2ParamIndexKind : C2Param::type_index_t {

    kParamIndexPictureTypeMask,
    kParamIndexPictureType,
    // deprecated
    kParamIndexHdr10PlusMetadata,

    kParamIndexPictureQuantization,

    kParamIndexHdrDynamicMetadata,

    /* ------------------------------------ video components ------------------------------------ */

    kParamIndexFrameRate = C2_PARAM_INDEX_VIDEO_PARAM_START,
@@ -1605,16 +1609,54 @@ struct C2HdrStaticMetadataStruct {
    C2FIELD(maxFall, "max-fall")
};
typedef C2StreamParam<C2Info, C2HdrStaticMetadataStruct, kParamIndexHdrStaticMetadata>
        C2StreamHdrStaticInfo;
        C2StreamHdrStaticMetadataInfo;
typedef C2StreamParam<C2Info, C2HdrStaticMetadataStruct, kParamIndexHdrStaticMetadata>
        C2StreamHdrStaticInfo;  // deprecated
constexpr char C2_PARAMKEY_HDR_STATIC_INFO[] = "raw.hdr-static-info";

/**
 * HDR10+ Metadata Info.
 *
 * Deprecated. Use C2StreamHdrDynamicMetadataInfo with
 * HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40
 */
typedef C2StreamParam<C2Info, C2BlobValue, kParamIndexHdr10PlusMetadata>
        C2StreamHdr10PlusInfo;
constexpr char C2_PARAMKEY_INPUT_HDR10_PLUS_INFO[] = "input.hdr10-plus-info";
constexpr char C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO[] = "output.hdr10-plus-info";
        C2StreamHdr10PlusInfo;  // deprecated
constexpr char C2_PARAMKEY_INPUT_HDR10_PLUS_INFO[] = "input.hdr10-plus-info";  // deprecated
constexpr char C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO[] = "output.hdr10-plus-info";  // deprecated

/**
 * HDR dynamic metadata types
 */
C2ENUM(C2Config::hdr_dynamic_metadata_type_t, uint32_t,
    HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_10,  ///< SMPTE ST 2094-10
    HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40,  ///< SMPTE ST 2094-40
)

struct C2HdrDynamicMetadataStruct {
    inline C2HdrDynamicMetadataStruct() { memset(this, 0, sizeof(*this)); }

    inline C2HdrDynamicMetadataStruct(
            size_t flexCount, C2Config::hdr_dynamic_metadata_type_t type)
        : type_(type) {
        memset(data, 0, flexCount);
    }

    C2Config::hdr_dynamic_metadata_type_t type_;
    uint8_t data[];

    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(HdrDynamicMetadata, data)
    C2FIELD(type_, "type")
    C2FIELD(data, "data")
};

/**
 * Dynamic HDR Metadata Info.
 */
typedef C2StreamParam<C2Info, C2HdrDynamicMetadataStruct, kParamIndexHdrDynamicMetadata>
        C2StreamHdrDynamicMetadataInfo;
constexpr char C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO[] = "input.hdr-dynamic-info";
constexpr char C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO[] = "output.hdr-dynamic-info";

/* ------------------------------------ block-based coding ----------------------------------- */

+2 −0
Original line number Diff line number Diff line
@@ -42,12 +42,14 @@ cc_library_shared {
        "android.hardware.drm@1.0",
        "android.hardware.media.c2@1.0",
        "android.hardware.media.omx@1.0",
        "android.hardware.graphics.mapper@4.0",
        "libbase",
        "libbinder",
        "libcodec2",
        "libcodec2_client",
        "libcodec2_vndk",
        "libcutils",
        "libgralloctypes",
        "libgui",
        "libhidlallocatorutils",
        "libhidlbase",
+13 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@

#include "utils/Codec2Mapper.h"
#include "C2OMXNode.h"
#include "Codec2Buffer.h"

namespace android {

@@ -466,6 +467,18 @@ status_t C2OMXNode::emptyBuffer(
                new Buffer2D(block->share(
                        C2Rect(block->width(), block->height()), ::C2Fence())));
        work->input.buffers.push_back(c2Buffer);
        std::shared_ptr<C2StreamHdrStaticInfo::input> staticInfo;
        std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> dynamicInfo;
        GetHdrMetadataFromGralloc4Handle(
                block->handle(),
                &staticInfo,
                &dynamicInfo);
        if (staticInfo && *staticInfo) {
            c2Buffer->setInfo(staticInfo);
        }
        if (dynamicInfo && *dynamicInfo) {
            c2Buffer->setInfo(dynamicInfo);
        }
    }
    work->worklets.clear();
    work->worklets.emplace_back(new C2Worklet);
+36 −4
Original line number Diff line number Diff line
@@ -840,6 +840,35 @@ status_t CCodecBufferChannel::renderOutputBuffer(
        hdr10PlusInfo.reset();
    }

    // HDR dynamic info
    std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> hdrDynamicInfo =
        std::static_pointer_cast<const C2StreamHdrDynamicMetadataInfo::output>(
                c2Buffer->getInfo(C2StreamHdrDynamicMetadataInfo::output::PARAM_TYPE));
    // TODO: make this sticky & enable unset
    if (hdrDynamicInfo && hdrDynamicInfo->flexCount() == 0) {
        hdrDynamicInfo.reset();
    }

    if (hdr10PlusInfo) {
        // C2StreamHdr10PlusInfo is deprecated; components should use
        // C2StreamHdrDynamicMetadataInfo
        // TODO: #metric
        if (hdrDynamicInfo) {
            // It is unexpected that C2StreamHdr10PlusInfo and
            // C2StreamHdrDynamicMetadataInfo is both present.
            // C2StreamHdrDynamicMetadataInfo takes priority.
            // TODO: #metric
        } else {
            std::shared_ptr<C2StreamHdrDynamicMetadataInfo::output> info =
                    C2StreamHdrDynamicMetadataInfo::output::AllocShared(
                            hdr10PlusInfo->flexCount(),
                            0u,
                            C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
            memcpy(info->m.data, hdr10PlusInfo->m.value, hdr10PlusInfo->flexCount());
            hdrDynamicInfo = info;
        }
    }

    std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
    if (blocks.size() != 1u) {
        ALOGD("[%s] expected 1 graphic block, but got %zu", mName, blocks.size());
@@ -859,7 +888,7 @@ status_t CCodecBufferChannel::renderOutputBuffer(
            videoScalingMode,
            transform,
            Fence::NO_FENCE, 0);
    if (hdrStaticInfo || hdr10PlusInfo) {
    if (hdrStaticInfo || hdrDynamicInfo) {
        HdrMetadata hdr;
        if (hdrStaticInfo) {
            // If mastering max and min luminance fields are 0, do not use them.
@@ -896,13 +925,16 @@ status_t CCodecBufferChannel::renderOutputBuffer(
                hdr.cta8613 = cta861_meta;
            }
        }
        if (hdr10PlusInfo) {
        if (hdrDynamicInfo
                && hdrDynamicInfo->m.type_ == C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40) {
            hdr.validTypes |= HdrMetadata::HDR10PLUS;
            hdr.hdr10plus.assign(
                    hdr10PlusInfo->m.value,
                    hdr10PlusInfo->m.value + hdr10PlusInfo->flexCount());
                    hdrDynamicInfo->m.data,
                    hdrDynamicInfo->m.data + hdrDynamicInfo->flexCount());
        }
        qbi.setHdrMetadata(hdr);

        SetHdrMetadataToGralloc4Handle(hdrStaticInfo, hdrDynamicInfo, block.handle());
    }
    // we don't have dirty regions
    qbi.setSurfaceDamage(Region::INVALID_REGION);
+219 −0
Original line number Diff line number Diff line
@@ -18,9 +18,14 @@
#define LOG_TAG "Codec2Buffer"
#include <utils/Log.h>

#include <aidl/android/hardware/graphics/common/Cta861_3.h>
#include <aidl/android/hardware/graphics/common/Smpte2086.h>
#include <android-base/properties.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <android/hardware/drm/1.0/types.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
#include <gralloctypes/Gralloc4.h>
#include <hidlmemory/FrameworkUtils.h>
#include <media/hardware/HardwareAPI.h>
#include <media/stagefright/CodecBase.h>
@@ -941,4 +946,218 @@ native_handle_t *EncryptedLinearBlockBuffer::handle() const {
    return const_cast<native_handle_t *>(mBlock->handle());
}

using ::aidl::android::hardware::graphics::common::Cta861_3;
using ::aidl::android::hardware::graphics::common::Smpte2086;

using ::android::gralloc4::MetadataType_Cta861_3;
using ::android::gralloc4::MetadataType_Smpte2086;
using ::android::gralloc4::MetadataType_Smpte2094_40;

using ::android::hardware::Return;
using ::android::hardware::hidl_vec;

using Error4 = ::android::hardware::graphics::mapper::V4_0::Error;
using IMapper4 = ::android::hardware::graphics::mapper::V4_0::IMapper;

namespace {

sp<IMapper4> GetMapper4() {
    static sp<IMapper4> sMapper = IMapper4::getService();
    return sMapper;
}

class NativeHandleDeleter {
public:
    explicit NativeHandleDeleter(native_handle_t *handle) : mHandle(handle) {}
    ~NativeHandleDeleter() {
        if (mHandle) {
            native_handle_delete(mHandle);
        }
    }
private:
    native_handle_t *mHandle;
};

}  // namspace

c2_status_t GetHdrMetadataFromGralloc4Handle(
        const C2Handle *const handle,
        std::shared_ptr<C2StreamHdrStaticMetadataInfo::input> *staticInfo,
        std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> *dynamicInfo) {
    c2_status_t err = C2_OK;
    native_handle_t *nativeHandle = UnwrapNativeCodec2GrallocHandle(handle);
    if (nativeHandle == nullptr) {
        // Nothing to do
        return err;
    }
    // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
    //         does not clone the fds. Thus we need to delete the handle
    //         without closing it when going out of scope.
    //         NativeHandle cannot solve this problem, as it would close and
    //         delete the handle, while we need delete only.
    NativeHandleDeleter nhd(nativeHandle);
    sp<IMapper4> mapper = GetMapper4();
    if (!mapper) {
        // Gralloc4 not supported; nothing to do
        return err;
    }
    Error4 mapperErr = Error4::NONE;
    if (staticInfo) {
        staticInfo->reset(new C2StreamHdrStaticMetadataInfo::input(0u));
        memset(&(*staticInfo)->mastering, 0, sizeof((*staticInfo)->mastering));
        (*staticInfo)->maxCll = 0;
        (*staticInfo)->maxFall = 0;
        IMapper4::get_cb cb = [&mapperErr, staticInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
            mapperErr = err;
            if (err != Error4::NONE) {
                return;
            }

            std::optional<Smpte2086> smpte2086;
            gralloc4::decodeSmpte2086(vec, &smpte2086);
            if (smpte2086) {
                (*staticInfo)->mastering.red.x    = smpte2086->primaryRed.x;
                (*staticInfo)->mastering.red.y    = smpte2086->primaryRed.y;
                (*staticInfo)->mastering.green.x  = smpte2086->primaryGreen.x;
                (*staticInfo)->mastering.green.y  = smpte2086->primaryGreen.y;
                (*staticInfo)->mastering.blue.x   = smpte2086->primaryBlue.x;
                (*staticInfo)->mastering.blue.y   = smpte2086->primaryBlue.y;
                (*staticInfo)->mastering.white.x  = smpte2086->whitePoint.x;
                (*staticInfo)->mastering.white.y  = smpte2086->whitePoint.y;

                (*staticInfo)->mastering.maxLuminance = smpte2086->maxLuminance;
                (*staticInfo)->mastering.minLuminance = smpte2086->minLuminance;
            } else {
                mapperErr = Error4::BAD_VALUE;
            }
        };
        Return<void> ret = mapper->get(nativeHandle, MetadataType_Smpte2086, cb);
        if (!ret.isOk()) {
            err = C2_REFUSED;
        } else if (mapperErr != Error4::NONE) {
            err = C2_CORRUPTED;
        }
        cb = [&mapperErr, staticInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
            mapperErr = err;
            if (err != Error4::NONE) {
                return;
            }

            std::optional<Cta861_3> cta861_3;
            gralloc4::decodeCta861_3(vec, &cta861_3);
            if (cta861_3) {
                (*staticInfo)->maxCll   = cta861_3->maxContentLightLevel;
                (*staticInfo)->maxFall  = cta861_3->maxFrameAverageLightLevel;
            } else {
                mapperErr = Error4::BAD_VALUE;
            }
        };
        ret = mapper->get(nativeHandle, MetadataType_Cta861_3, cb);
        if (!ret.isOk()) {
            err = C2_REFUSED;
        } else if (mapperErr != Error4::NONE) {
            err = C2_CORRUPTED;
        }
    }
    if (dynamicInfo) {
        dynamicInfo->reset();
        IMapper4::get_cb cb = [&mapperErr, dynamicInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
            mapperErr = err;
            if (err != Error4::NONE) {
                return;
            }
            if (!dynamicInfo) {
                return;
            }
            *dynamicInfo = C2StreamHdrDynamicMetadataInfo::input::AllocShared(
                    vec.size(), 0u, C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
            memcpy((*dynamicInfo)->m.data, vec.data(), vec.size());
        };
        Return<void> ret = mapper->get(nativeHandle, MetadataType_Smpte2094_40, cb);
        if (!ret.isOk() || mapperErr != Error4::NONE) {
            dynamicInfo->reset();
        }
    }

    return err;
}

c2_status_t SetHdrMetadataToGralloc4Handle(
        const std::shared_ptr<const C2StreamHdrStaticMetadataInfo::output> &staticInfo,
        const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
        const C2Handle *const handle) {
    c2_status_t err = C2_OK;
    native_handle_t *nativeHandle = UnwrapNativeCodec2GrallocHandle(handle);
    if (nativeHandle == nullptr) {
        // Nothing to do
        return err;
    }
    // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
    //         does not clone the fds. Thus we need to delete the handle
    //         without closing it when going out of scope.
    NativeHandleDeleter nhd(nativeHandle);
    sp<IMapper4> mapper = GetMapper4();
    if (!mapper) {
        // Gralloc4 not supported; nothing to do
        return err;
    }
    if (staticInfo && *staticInfo) {
        std::optional<Smpte2086> smpte2086 = Smpte2086{
            {staticInfo->mastering.red.x, staticInfo->mastering.red.y},
            {staticInfo->mastering.green.x, staticInfo->mastering.green.y},
            {staticInfo->mastering.blue.x, staticInfo->mastering.blue.y},
            {staticInfo->mastering.white.x, staticInfo->mastering.white.y},
            staticInfo->mastering.maxLuminance,
            staticInfo->mastering.minLuminance,
        };
        hidl_vec<uint8_t> vec;
        if (gralloc4::encodeSmpte2086(smpte2086, &vec) == OK) {
            Return<Error4> ret = mapper->set(nativeHandle, MetadataType_Smpte2086, vec);
            if (!ret.isOk()) {
                err = C2_REFUSED;
            } else if (ret != Error4::NONE) {
                err = C2_CORRUPTED;
            }
        }
        std::optional<Cta861_3> cta861_3 = Cta861_3{
            staticInfo->maxCll,
            staticInfo->maxFall,
        };
        if (gralloc4::encodeCta861_3(cta861_3, &vec) == OK) {
            Return<Error4> ret = mapper->set(nativeHandle, MetadataType_Cta861_3, vec);
            if (!ret.isOk()) {
                err = C2_REFUSED;
            } else if (ret != Error4::NONE) {
                err = C2_CORRUPTED;
            }
        }
    }
    if (dynamicInfo && *dynamicInfo) {
        hidl_vec<uint8_t> vec;
        vec.resize(dynamicInfo->flexCount());
        memcpy(vec.data(), dynamicInfo->m.data, dynamicInfo->flexCount());
        std::optional<IMapper4::MetadataType> metadataType;
        switch (dynamicInfo->m.type_) {
        case C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_10:
            // TODO
            break;
        case C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40:
            metadataType = MetadataType_Smpte2094_40;
            break;
        }
        if (metadataType) {
            Return<Error4> ret = mapper->set(nativeHandle, *metadataType, vec);
            if (!ret.isOk()) {
                err = C2_REFUSED;
            } else if (ret != Error4::NONE) {
                err = C2_CORRUPTED;
            }
        } else {
            err = C2_BAD_VALUE;
        }
    }

    return err;
}

}  // namespace android
Loading