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

Commit 058458ed authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "codec2: query supported pixel formats from Codec2InfoBuilder" am:...

Merge "codec2: query supported pixel formats from Codec2InfoBuilder" am: e36588e4 am: 7bc90c91 am: e550298b

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

Change-Id: Id3dade7ade846d77edf02577b0453c2753c13b06
parents 51638619 e550298b
Loading
Loading
Loading
Loading
+112 −12
Original line number Original line Diff line number Diff line
@@ -54,6 +54,9 @@ namespace android {


using Traits = C2Component::Traits;
using Traits = C2Component::Traits;


// HAL pixel format -> framework color format
typedef std::map<uint32_t, int32_t> PixelFormatMap;

namespace /* unnamed */ {
namespace /* unnamed */ {


bool hasPrefix(const std::string& s, const char* prefix) {
bool hasPrefix(const std::string& s, const char* prefix) {
@@ -67,6 +70,26 @@ bool hasSuffix(const std::string& s, const char* suffix) {
            s.compare(s.size() - suffixLen, suffixLen, suffix) == 0;
            s.compare(s.size() - suffixLen, suffixLen, suffix) == 0;
}
}


std::optional<int32_t> findFrameworkColorFormat(
        const C2FlexiblePixelFormatDescriptorStruct &desc) {
    switch (desc.bitDepth) {
        case 8u:
            if (desc.layout == C2Color::PLANAR_PACKED
                    || desc.layout == C2Color::SEMIPLANAR_PACKED) {
                return COLOR_FormatYUV420Flexible;
            }
            break;
        case 10u:
            if (desc.layout == C2Color::SEMIPLANAR_PACKED) {
                return COLOR_FormatYUVP010;
            }
            break;
        default:
            break;
    }
    return std::nullopt;
}

// returns true if component advertised supported profile level(s)
// returns true if component advertised supported profile level(s)
bool addSupportedProfileLevels(
bool addSupportedProfileLevels(
        std::shared_ptr<Codec2Client::Interface> intf,
        std::shared_ptr<Codec2Client::Interface> intf,
@@ -211,27 +234,69 @@ bool addSupportedProfileLevels(
void addSupportedColorFormats(
void addSupportedColorFormats(
        std::shared_ptr<Codec2Client::Interface> intf,
        std::shared_ptr<Codec2Client::Interface> intf,
        MediaCodecInfo::CapabilitiesWriter *caps,
        MediaCodecInfo::CapabilitiesWriter *caps,
        const Traits& trait, const std::string &mediaType) {
        const Traits& trait, const std::string &mediaType,
    (void)intf;
        const PixelFormatMap &pixelFormatMap) {

    // TODO: get this from intf() as well, but how do we map them to
    // TODO: get this from intf() as well, but how do we map them to
    // MediaCodec color formats?
    // MediaCodec color formats?
    bool encoder = trait.kind == C2Component::KIND_ENCODER;
    bool encoder = trait.kind == C2Component::KIND_ENCODER;
    if (mediaType.find("video") != std::string::npos
    if (mediaType.find("video") != std::string::npos
            || mediaType.find("image") != std::string::npos) {
            || mediaType.find("image") != std::string::npos) {

        std::vector<C2FieldSupportedValuesQuery> query;
        if (encoder) {
            C2StreamPixelFormatInfo::input pixelFormat;
            query.push_back(C2FieldSupportedValuesQuery::Possible(
                    C2ParamField::Make(pixelFormat, pixelFormat.value)));
        } else {
            C2StreamPixelFormatInfo::output pixelFormat;
            query.push_back(C2FieldSupportedValuesQuery::Possible(
                    C2ParamField::Make(pixelFormat, pixelFormat.value)));
        }
        std::list<int32_t> supportedColorFormats;
        if (intf->querySupportedValues(query, C2_DONT_BLOCK) == C2_OK) {
            if (query[0].status == C2_OK) {
                const C2FieldSupportedValues &fsv = query[0].values;
                if (fsv.type == C2FieldSupportedValues::VALUES) {
                    for (C2Value::Primitive value : fsv.values) {
                        auto it = pixelFormatMap.find(value.u32);
                        if (it != pixelFormatMap.end()) {
                            auto it2 = std::find(
                                    supportedColorFormats.begin(),
                                    supportedColorFormats.end(),
                                    it->second);
                            if (it2 == supportedColorFormats.end()) {
                                supportedColorFormats.push_back(it->second);
                            }
                        }
                    }
                }
            }
        }
        auto addDefaultColorFormat = [caps, &supportedColorFormats](int32_t colorFormat) {
            caps->addColorFormat(colorFormat);
            auto it = std::find(
                    supportedColorFormats.begin(), supportedColorFormats.end(), colorFormat);
            if (it != supportedColorFormats.end()) {
                supportedColorFormats.erase(it);
            }
        };

        // vendor video codecs prefer opaque format
        // vendor video codecs prefer opaque format
        if (trait.name.find("android") == std::string::npos) {
        if (trait.name.find("android") == std::string::npos) {
            caps->addColorFormat(COLOR_FormatSurface);
            addDefaultColorFormat(COLOR_FormatSurface);
        }
        }
        caps->addColorFormat(COLOR_FormatYUV420Flexible);
        addDefaultColorFormat(COLOR_FormatYUV420Flexible);
        caps->addColorFormat(COLOR_FormatYUV420Planar);
        addDefaultColorFormat(COLOR_FormatYUV420Planar);
        caps->addColorFormat(COLOR_FormatYUV420SemiPlanar);
        addDefaultColorFormat(COLOR_FormatYUV420SemiPlanar);
        caps->addColorFormat(COLOR_FormatYUV420PackedPlanar);
        addDefaultColorFormat(COLOR_FormatYUV420PackedPlanar);
        caps->addColorFormat(COLOR_FormatYUV420PackedSemiPlanar);
        addDefaultColorFormat(COLOR_FormatYUV420PackedSemiPlanar);
        // framework video encoders must support surface format, though it is unclear
        // framework video encoders must support surface format, though it is unclear
        // that they will be able to map it if it is opaque
        // that they will be able to map it if it is opaque
        if (encoder && trait.name.find("android") != std::string::npos) {
        if (encoder && trait.name.find("android") != std::string::npos) {
            caps->addColorFormat(COLOR_FormatSurface);
            addDefaultColorFormat(COLOR_FormatSurface);
        }
        for (int32_t colorFormat : supportedColorFormats) {
            caps->addColorFormat(colorFormat);
        }
        }
    }
    }
}
}
@@ -423,6 +488,7 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
        }
        }
    }
    }


    std::map<std::string, PixelFormatMap> nameToPixelFormatMap;
    for (const Traits& trait : traits) {
    for (const Traits& trait : traits) {
        C2Component::rank_t rank = trait.rank;
        C2Component::rank_t rank = trait.rank;


@@ -436,8 +502,9 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
        nameAndAliases.insert(nameAndAliases.begin(), trait.name);
        nameAndAliases.insert(nameAndAliases.begin(), trait.name);
        for (const std::string &nameOrAlias : nameAndAliases) {
        for (const std::string &nameOrAlias : nameAndAliases) {
            bool isAlias = trait.name != nameOrAlias;
            bool isAlias = trait.name != nameOrAlias;
            std::shared_ptr<Codec2Client> client;
            std::shared_ptr<Codec2Client::Interface> intf =
            std::shared_ptr<Codec2Client::Interface> intf =
                Codec2Client::CreateInterfaceByName(nameOrAlias.c_str());
                Codec2Client::CreateInterfaceByName(nameOrAlias.c_str(), &client);
            if (!intf) {
            if (!intf) {
                ALOGD("could not create interface for %s'%s'",
                ALOGD("could not create interface for %s'%s'",
                        isAlias ? "alias " : "",
                        isAlias ? "alias " : "",
@@ -631,7 +698,40 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
                        caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
                        caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
                    }
                    }
                }
                }
                addSupportedColorFormats(intf, caps.get(), trait, mediaType);

                auto it = nameToPixelFormatMap.find(client->getServiceName());
                if (it == nameToPixelFormatMap.end()) {
                    it = nameToPixelFormatMap.try_emplace(client->getServiceName()).first;
                    PixelFormatMap &pixelFormatMap = it->second;
                    pixelFormatMap[HAL_PIXEL_FORMAT_YCBCR_420_888] = COLOR_FormatYUV420Flexible;
                    pixelFormatMap[HAL_PIXEL_FORMAT_YCBCR_P010]    = COLOR_FormatYUVP010;
                    pixelFormatMap[HAL_PIXEL_FORMAT_RGBA_1010102]  = COLOR_Format32bitABGR2101010;
                    pixelFormatMap[HAL_PIXEL_FORMAT_RGBA_FP16]     = COLOR_Format64bitABGRFloat;

                    std::shared_ptr<C2StoreFlexiblePixelFormatDescriptorsInfo> pixelFormatInfo;
                    std::vector<std::unique_ptr<C2Param>> heapParams;
                    if (client->query(
                                {},
                                {C2StoreFlexiblePixelFormatDescriptorsInfo::PARAM_TYPE},
                                C2_MAY_BLOCK,
                                &heapParams) == C2_OK
                            && heapParams.size() == 1u) {
                        pixelFormatInfo.reset(C2StoreFlexiblePixelFormatDescriptorsInfo::From(
                                heapParams[0].release()));
                    }
                    if (pixelFormatInfo && *pixelFormatInfo) {
                        for (size_t i = 0; i < pixelFormatInfo->flexCount(); ++i) {
                            C2FlexiblePixelFormatDescriptorStruct &desc =
                                pixelFormatInfo->m.values[i];
                            std::optional<int32_t> colorFormat = findFrameworkColorFormat(desc);
                            if (colorFormat) {
                                pixelFormatMap[desc.pixelFormat] = *colorFormat;
                            }
                        }
                    }
                }
                addSupportedColorFormats(
                        intf, caps.get(), trait, mediaType, it->second);
            }
            }
        }
        }
    }
    }
+35 −30
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@
#define LOG_TAG "Codec2Mapper"
#define LOG_TAG "Codec2Mapper"
#include <utils/Log.h>
#include <utils/Log.h>


#include <map>
#include <optional>

#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SurfaceUtils.h>
#include <media/stagefright/SurfaceUtils.h>
#include <media/stagefright/foundation/ALookup.h>
#include <media/stagefright/foundation/ALookup.h>
@@ -408,6 +411,30 @@ ALookup<C2Config::profile_t, int32_t> sAv1Hdr10PlusProfiles = {
    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
};
};


// HAL_PIXEL_FORMAT_* -> COLOR_Format*
ALookup<uint32_t, int32_t> sPixelFormats = {
    { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, COLOR_FormatSurface },

    // YCBCR_420_888 maps to YUV420Flexible and vice versa
    { HAL_PIXEL_FORMAT_YCBCR_420_888,          COLOR_FormatYUV420Flexible },

    // Fallback matches for YCBCR_420_888
    { HAL_PIXEL_FORMAT_YCBCR_420_888,          COLOR_FormatYUV420Planar },
    { HAL_PIXEL_FORMAT_YCBCR_420_888,          COLOR_FormatYUV420SemiPlanar },
    { HAL_PIXEL_FORMAT_YCBCR_420_888,          COLOR_FormatYUV420PackedPlanar },
    { HAL_PIXEL_FORMAT_YCBCR_420_888,          COLOR_FormatYUV420PackedSemiPlanar },

    // Fallback matches for YUV420Flexible
    { HAL_PIXEL_FORMAT_YCRCB_420_SP,           COLOR_FormatYUV420Flexible },
    { HAL_PIXEL_FORMAT_YV12,                   COLOR_FormatYUV420Flexible },

    { HAL_PIXEL_FORMAT_YCBCR_422_SP,           COLOR_FormatYUV422PackedSemiPlanar },
    { HAL_PIXEL_FORMAT_YCBCR_422_I,            COLOR_FormatYUV422PackedPlanar },
    { HAL_PIXEL_FORMAT_YCBCR_P010,             COLOR_FormatYUVP010 },
    { HAL_PIXEL_FORMAT_RGBA_1010102,           COLOR_Format32bitABGR2101010 },
    { HAL_PIXEL_FORMAT_RGBA_FP16,              COLOR_Format64bitABGRFloat },
};

/**
/**
 * A helper that passes through vendor extension profile and level values.
 * A helper that passes through vendor extension profile and level values.
 */
 */
@@ -981,41 +1008,19 @@ bool C2Mapper::map(ColorAspects::Transfer from, C2Color::transfer_t *to) {
// static
// static
bool C2Mapper::mapPixelFormatFrameworkToCodec(
bool C2Mapper::mapPixelFormatFrameworkToCodec(
        int32_t frameworkValue, uint32_t *c2Value) {
        int32_t frameworkValue, uint32_t *c2Value) {
    switch (frameworkValue) {
    if (!sPixelFormats.map(frameworkValue, c2Value)) {
        case COLOR_FormatSurface:
        // passthrough if not mapped
            *c2Value = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
            return true;
        case COLOR_FormatYUV420Flexible:
        case COLOR_FormatYUV420Planar:
        case COLOR_FormatYUV420SemiPlanar:
        case COLOR_FormatYUV420PackedPlanar:
        case COLOR_FormatYUV420PackedSemiPlanar:
            *c2Value = HAL_PIXEL_FORMAT_YCBCR_420_888;
            return true;
        default:
            // Passthrough
        *c2Value = uint32_t(frameworkValue);
        *c2Value = uint32_t(frameworkValue);
            return true;
    }
    }
    return true;
}
}


// static
// static
bool C2Mapper::mapPixelFormatCodecToFramework(
bool C2Mapper::mapPixelFormatCodecToFramework(
        uint32_t c2Value, int32_t *frameworkValue) {
        uint32_t c2Value, int32_t *frameworkValue) {
    switch (c2Value) {
    if (!sPixelFormats.map(c2Value, frameworkValue)) {
        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
        // passthrough if not mapped
            *frameworkValue = COLOR_FormatSurface;
            return true;
        case HAL_PIXEL_FORMAT_YCBCR_422_SP:
        case HAL_PIXEL_FORMAT_YCRCB_420_SP:
        case HAL_PIXEL_FORMAT_YCBCR_422_I:
        case HAL_PIXEL_FORMAT_YCBCR_420_888:
        case HAL_PIXEL_FORMAT_YV12:
            *frameworkValue = COLOR_FormatYUV420Flexible;
            return true;
        default:
            // Passthrough
        *frameworkValue = int32_t(c2Value);
        *frameworkValue = int32_t(c2Value);
            return true;
    }
    }
    return true;
}
}
+5 −0
Original line number Original line Diff line number Diff line
@@ -592,9 +592,11 @@ constexpr int32_t COLOR_Format24BitARGB6666 = 42;
constexpr int32_t COLOR_Format24bitBGR888             = 12;
constexpr int32_t COLOR_Format24bitBGR888             = 12;
constexpr int32_t COLOR_Format24bitRGB888             = 11;
constexpr int32_t COLOR_Format24bitRGB888             = 11;
constexpr int32_t COLOR_Format25bitARGB1888           = 14;
constexpr int32_t COLOR_Format25bitARGB1888           = 14;
constexpr int32_t COLOR_Format32bitABGR2101010        = 0x7F00AAA2;
constexpr int32_t COLOR_Format32bitABGR8888           = 0x7F00A000;
constexpr int32_t COLOR_Format32bitABGR8888           = 0x7F00A000;
constexpr int32_t COLOR_Format32bitARGB8888           = 16;
constexpr int32_t COLOR_Format32bitARGB8888           = 16;
constexpr int32_t COLOR_Format32bitBGRA8888           = 15;
constexpr int32_t COLOR_Format32bitBGRA8888           = 15;
constexpr int32_t COLOR_Format64bitABGRFloat          = 0x7F000F16;
constexpr int32_t COLOR_Format8bitRGB332              = 2;
constexpr int32_t COLOR_Format8bitRGB332              = 2;
constexpr int32_t COLOR_FormatCbYCrY                  = 27;
constexpr int32_t COLOR_FormatCbYCrY                  = 27;
constexpr int32_t COLOR_FormatCrYCbY                  = 28;
constexpr int32_t COLOR_FormatCrYCbY                  = 28;
@@ -648,9 +650,11 @@ inline static const char *asString_ColorFormat(int32_t i, const char *def = "??"
        case COLOR_Format24bitBGR888:               return "24bitBGR888";
        case COLOR_Format24bitBGR888:               return "24bitBGR888";
        case COLOR_Format24bitRGB888:               return "24bitRGB888";
        case COLOR_Format24bitRGB888:               return "24bitRGB888";
        case COLOR_Format25bitARGB1888:             return "25bitARGB1888";
        case COLOR_Format25bitARGB1888:             return "25bitARGB1888";
        case COLOR_Format32bitABGR2101010:          return "32bitABGR2101010";
        case COLOR_Format32bitABGR8888:             return "32bitABGR8888";
        case COLOR_Format32bitABGR8888:             return "32bitABGR8888";
        case COLOR_Format32bitARGB8888:             return "32bitARGB8888";
        case COLOR_Format32bitARGB8888:             return "32bitARGB8888";
        case COLOR_Format32bitBGRA8888:             return "32bitBGRA8888";
        case COLOR_Format32bitBGRA8888:             return "32bitBGRA8888";
        case COLOR_Format64bitABGRFloat:            return "64bitABGRFloat";
        case COLOR_Format8bitRGB332:                return "8bitRGB332";
        case COLOR_Format8bitRGB332:                return "8bitRGB332";
        case COLOR_FormatCbYCrY:                    return "CbYCrY";
        case COLOR_FormatCbYCrY:                    return "CbYCrY";
        case COLOR_FormatCrYCbY:                    return "CrYCbY";
        case COLOR_FormatCrYCbY:                    return "CrYCbY";
@@ -683,6 +687,7 @@ inline static const char *asString_ColorFormat(int32_t i, const char *def = "??"
        case COLOR_FormatYUV422SemiPlanar:          return "YUV422SemiPlanar";
        case COLOR_FormatYUV422SemiPlanar:          return "YUV422SemiPlanar";
        case COLOR_FormatYUV444Flexible:            return "YUV444Flexible";
        case COLOR_FormatYUV444Flexible:            return "YUV444Flexible";
        case COLOR_FormatYUV444Interleaved:         return "YUV444Interleaved";
        case COLOR_FormatYUV444Interleaved:         return "YUV444Interleaved";
        case COLOR_FormatYUVP010:                   return "YUVP010";
        case COLOR_QCOM_FormatYUV420SemiPlanar:     return "QCOM_YUV420SemiPlanar";
        case COLOR_QCOM_FormatYUV420SemiPlanar:     return "QCOM_YUV420SemiPlanar";
        case COLOR_TI_FormatYUV420PackedSemiPlanar: return "TI_YUV420PackedSemiPlanar";
        case COLOR_TI_FormatYUV420PackedSemiPlanar: return "TI_YUV420PackedSemiPlanar";
        default:                                    return def;
        default:                                    return def;