13a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar/*
23a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * Copyright (C) 2016 The Android Open Source Project
33a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar *
43a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
53a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * you may not use this file except in compliance with the License.
63a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * You may obtain a copy of the License at
73a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar *
83a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
93a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar *
103a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * Unless required by applicable law or agreed to in writing, software
113a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
123a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * See the License for the specific language governing permissions and
143a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar * limitations under the License.
153a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar */
163a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
173a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//#define LOG_NDEBUG 0
183a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar#define LOG_TAG "ColorUtils"
193a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
203a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar#include <inttypes.h>
21db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang#include <arpa/inet.h>
22db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang#include <media/stagefright/foundation/ABuffer.h>
233a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar#include <media/stagefright/foundation/ADebug.h>
243a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar#include <media/stagefright/foundation/ALookup.h>
253a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar#include <media/stagefright/foundation/ColorUtils.h>
263a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
273a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarnamespace android {
283a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
293a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar// shortcut names for brevity in the following tables
303a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnartypedef ColorAspects CA;
313a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnartypedef ColorUtils CU;
323a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
33db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang#define HI_UINT16(a) (((a) >> 8) & 0xFF)
34db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang#define LO_UINT16(a) ((a) & 0xFF)
35db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
373a09d8d6f909063990a5681b15a442b2ba8ce54aLajos MolnarALookup<CU::ColorRange, CA::Range> sRanges{
383a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    {
393a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorRangeLimited, CA::RangeLimited },
403a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorRangeFull, CA::RangeFull },
413a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorRangeUnspecified, CA::RangeUnspecified },
423a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
433a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar};
443a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
4558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
463a09d8d6f909063990a5681b15a442b2ba8ce54aLajos MolnarALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandards {
473a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    {
483a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardUnspecified,    { CA::PrimariesUnspecified, CA::MatrixUnspecified } },
493a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT709,          { CA::PrimariesBT709_5, CA::MatrixBT709_5 } },
503a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT601_625,      { CA::PrimariesBT601_6_625, CA::MatrixBT601_6 } },
513a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT601_625_Unadjusted,
523a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar                                            // this is a really close match
533a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar                                            { CA::PrimariesBT601_6_625, CA::MatrixBT709_5 } },
543a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT601_525,      { CA::PrimariesBT601_6_525, CA::MatrixBT601_6 } },
553a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT601_525_Unadjusted,
563a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar                                            { CA::PrimariesBT601_6_525, CA::MatrixSMPTE240M } },
573a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT2020,         { CA::PrimariesBT2020, CA::MatrixBT2020 } },
583a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT2020Constant, { CA::PrimariesBT2020, CA::MatrixBT2020Constant } },
593a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardBT470M,         { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } },
603a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        // NOTE: there is no close match to the matrix used by standard film, chose closest
613a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorStandardFilm,           { CA::PrimariesGenericFilm, CA::MatrixBT2020 } },
623a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
633a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar};
643a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
6558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
663a09d8d6f909063990a5681b15a442b2ba8ce54aLajos MolnarALookup<CU::ColorTransfer, CA::Transfer> sTransfers{
673a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    {
683a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferUnspecified,    CA::TransferUnspecified },
693a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferLinear,         CA::TransferLinear },
703a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferSRGB,           CA::TransferSRGB },
713a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferSMPTE_170M,     CA::TransferSMPTE170M },
723a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferGamma22,        CA::TransferGamma22 },
733a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferGamma28,        CA::TransferGamma28 },
743a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferST2084,         CA::TransferST2084 },
753a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        { CU::kColorTransferHLG,            CA::TransferHLG },
763a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
773a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar};
783a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
793a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isValid(ColorAspects::Primaries p) {
803a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return p <= ColorAspects::PrimariesOther;
813a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
823a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
833a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isDefined(ColorAspects::Primaries p) {
843a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return p <= ColorAspects::PrimariesBT2020;
853a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
863a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
873a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isValid(ColorAspects::MatrixCoeffs c) {
883a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return c <= ColorAspects::MatrixOther;
893a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
903a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
913a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isDefined(ColorAspects::MatrixCoeffs c) {
923a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return c <= ColorAspects::MatrixBT2020Constant;
933a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
943a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
953a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//static
963a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarint32_t ColorUtils::wrapColorAspectsIntoColorStandard(
973a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs) {
983a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    ColorStandard res;
993a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sStandards.map(std::make_pair(primaries, coeffs), &res)) {
1003a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return res;
1013a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if (!isValid(primaries) || !isValid(coeffs)) {
1023a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorStandardUnspecified;
1033a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1043a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1053a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    // check platform media limits
1063a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    uint32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
1073a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (isDefined(primaries) && isDefined(coeffs)) {
1083a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorStandardExtendedStart + primaries + coeffs * numPrimaries;
1093a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else {
1103a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorStandardVendorStart + primaries + coeffs * 0x100;
1113a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1123a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1133a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1143a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//static
1153a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatus_t ColorUtils::unwrapColorAspectsFromColorStandard(
1163a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        int32_t standard,
1173a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs) {
1183a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    std::pair<ColorAspects::Primaries, ColorAspects::MatrixCoeffs> res;
1193a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sStandards.map((ColorStandard)standard, &res)) {
1203a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *primaries = res.first;
1213a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *coeffs = res.second;
1223a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
1233a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1243a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1253a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t start = kColorStandardExtendedStart;
1263a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
1273a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t numCoeffs = ColorAspects::MatrixBT2020Constant + 1;
1283a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (standard >= (int32_t)kColorStandardVendorStart) {
1293a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        start = kColorStandardVendorStart;
1303a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        numPrimaries = ColorAspects::PrimariesOther + 1; // 0x100
1313a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        numCoeffs = ColorAspects::MatrixOther + 1; // 0x100;
1323a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1333a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (standard >= start && standard < start + numPrimaries * numCoeffs) {
1343a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        int32_t product = standard - start;
1353a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *primaries = (ColorAspects::Primaries)(product % numPrimaries);
1363a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *coeffs = (ColorAspects::MatrixCoeffs)(product / numPrimaries);
1373a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
1383a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1393a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *primaries = ColorAspects::PrimariesOther;
1403a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *coeffs = ColorAspects::MatrixOther;
1413a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return BAD_VALUE;
1423a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1433a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1443a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isValid(ColorAspects::Range r) {
1453a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return r <= ColorAspects::RangeOther;
1463a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1473a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1483a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isDefined(ColorAspects::Range r) {
1493a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return r <= ColorAspects::RangeLimited;
1503a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1513a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1523a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//  static
1533a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarint32_t ColorUtils::wrapColorAspectsIntoColorRange(ColorAspects::Range range) {
1543a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    ColorRange res;
1553a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sRanges.map(range, &res)) {
1563a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return res;
1573a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if (!isValid(range)) {
1583a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorRangeUnspecified;
1593a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else {
1603a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        CHECK(!isDefined(range));
1613a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        // all platform values are in sRanges
1623a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorRangeVendorStart + range;
1633a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1643a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1653a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1663a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//static
1673a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatus_t ColorUtils::unwrapColorAspectsFromColorRange(
1683a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        int32_t range, ColorAspects::Range *aspect) {
1693a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sRanges.map((ColorRange)range, aspect)) {
1703a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
1713a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1723a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1733a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t start = kColorRangeVendorStart;
1743a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t numRanges = ColorAspects::RangeOther + 1; // 0x100
1753a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (range >= start && range < start + numRanges) {
1763a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *aspect = (ColorAspects::Range)(range - start);
1773a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
1783a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
1793a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *aspect = ColorAspects::RangeOther;
1803a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return BAD_VALUE;
1813a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1823a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1833a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isValid(ColorAspects::Transfer t) {
1843a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return t <= ColorAspects::TransferOther;
1853a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1863a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1873a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatic bool isDefined(ColorAspects::Transfer t) {
1883a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return t <= ColorAspects::TransferHLG
1893a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar            || (t >= ColorAspects::TransferSMPTE240M && t <= ColorAspects::TransferST428);
1903a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
1913a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
1923a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//  static
1933a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarint32_t ColorUtils::wrapColorAspectsIntoColorTransfer(
1943a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        ColorAspects::Transfer transfer) {
1953a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    ColorTransfer res;
1963a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sTransfers.map(transfer, &res)) {
1973a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return res;
1983a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if (!isValid(transfer)) {
1993a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorTransferUnspecified;
2003a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if (isDefined(transfer)) {
2013a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorTransferExtendedStart + transfer;
2023a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else {
2033a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        // all platform values are in sRanges
2043a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return kColorTransferVendorStart + transfer;
2053a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
2063a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
2073a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
2083a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar//static
2093a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatus_t ColorUtils::unwrapColorAspectsFromColorTransfer(
2103a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        int32_t transfer, ColorAspects::Transfer *aspect) {
2113a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (sTransfers.map((ColorTransfer)transfer, aspect)) {
2123a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
2133a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
2143a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
2153a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t start = kColorTransferExtendedStart;
2163a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t numTransfers = ColorAspects::TransferST428 + 1;
2173a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (transfer >= (int32_t)kColorTransferVendorStart) {
2183a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        start = kColorTransferVendorStart;
2193a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        numTransfers = ColorAspects::TransferOther + 1; // 0x100
2203a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
2213a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (transfer >= start && transfer < start + numTransfers) {
2223a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        *aspect = (ColorAspects::Transfer)(transfer - start);
2233a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
2243a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
2253a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *aspect = ColorAspects::TransferOther;
2263a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return BAD_VALUE;
2273a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
2283a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
2293a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar// static
2303a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatus_t ColorUtils::convertPlatformColorAspectsToCodecAspects(
2313a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects) {
2323a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    status_t res1 = unwrapColorAspectsFromColorRange(range, &aspects.mRange);
2333a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    status_t res2 = unwrapColorAspectsFromColorStandard(
2343a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar            standard, &aspects.mPrimaries, &aspects.mMatrixCoeffs);
2353a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    status_t res3 = unwrapColorAspectsFromColorTransfer(transfer, &aspects.mTransfer);
2363a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    return res1 != OK ? res1 : (res2 != OK ? res2 : res3);
2373a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
2383a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
2393a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar// static
2403a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarstatus_t ColorUtils::convertCodecColorAspectsToPlatformAspects(
2413a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer) {
2423a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *range = wrapColorAspectsIntoColorRange(aspects.mRange);
2433a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *standard = wrapColorAspectsIntoColorStandard(aspects.mPrimaries, aspects.mMatrixCoeffs);
2443a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    *transfer = wrapColorAspectsIntoColorTransfer(aspects.mTransfer);
2453a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (isValid(aspects.mRange) && isValid(aspects.mPrimaries)
2463a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar            && isValid(aspects.mMatrixCoeffs) && isValid(aspects.mTransfer)) {
2473a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return OK;
2483a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else {
2493a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        return BAD_VALUE;
2503a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
2513a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
2523a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
25358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
25458fb7c6e1a9244dd7215a647388c440d8d75851bLajos MolnarALookup<int32_t, ColorAspects::Primaries> sIsoPrimaries {
25558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    {
25658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 1, ColorAspects::PrimariesBT709_5 },
25758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 2, ColorAspects::PrimariesUnspecified },
25858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 4, ColorAspects::PrimariesBT470_6M },
25958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 5, ColorAspects::PrimariesBT601_6_625 },
26058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 6, ColorAspects::PrimariesBT601_6_525 /* main */},
26158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 7, ColorAspects::PrimariesBT601_6_525 },
26258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // -- ITU T.832 201201 ends here
26358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 8, ColorAspects::PrimariesGenericFilm },
26458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 9, ColorAspects::PrimariesBT2020 },
26558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 10, ColorAspects::PrimariesOther /* XYZ */ },
26658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
26758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar};
26858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
26958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
27058fb7c6e1a9244dd7215a647388c440d8d75851bLajos MolnarALookup<int32_t, ColorAspects::Transfer> sIsoTransfers {
27158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    {
27258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 1, ColorAspects::TransferSMPTE170M /* main */},
27358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 2, ColorAspects::TransferUnspecified },
27458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 4, ColorAspects::TransferGamma22 },
27558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 5, ColorAspects::TransferGamma28 },
27658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 6, ColorAspects::TransferSMPTE170M },
27758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 7, ColorAspects::TransferSMPTE240M },
27858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 8, ColorAspects::TransferLinear },
27958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 9, ColorAspects::TransferOther /* log 100:1 */ },
28058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 10, ColorAspects::TransferOther /* log 316:1 */ },
28158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 11, ColorAspects::TransferXvYCC },
28258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 12, ColorAspects::TransferBT1361 },
28358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 13, ColorAspects::TransferSRGB },
28458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // -- ITU T.832 201201 ends here
28558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 14, ColorAspects::TransferSMPTE170M },
28658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 15, ColorAspects::TransferSMPTE170M },
28758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 16, ColorAspects::TransferST2084 },
28858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 17, ColorAspects::TransferST428 },
289de6afd7dcc484bc867de6a0438ae4be9f2c6aaccTakahiro Aizawa        { 18, ColorAspects::TransferHLG },
29058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
29158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar};
29258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
29358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarconst static
29458fb7c6e1a9244dd7215a647388c440d8d75851bLajos MolnarALookup<int32_t, ColorAspects::MatrixCoeffs> sIsoMatrixCoeffs {
29558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    {
29658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 0, ColorAspects::MatrixOther },
29758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 1, ColorAspects::MatrixBT709_5 },
29858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 2, ColorAspects::MatrixUnspecified },
29958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 4, ColorAspects::MatrixBT470_6M },
30058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 6, ColorAspects::MatrixBT601_6 /* main */ },
30158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 5, ColorAspects::MatrixBT601_6 },
30258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 7, ColorAspects::MatrixSMPTE240M },
30358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 8, ColorAspects::MatrixOther /* YCgCo */ },
30458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        // -- ITU T.832 201201 ends here
30558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 9, ColorAspects::MatrixBT2020 },
30658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        { 10, ColorAspects::MatrixBT2020Constant },
30758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
30858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar};
30958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
31058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar// static
31158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarvoid ColorUtils::convertCodecColorAspectsToIsoAspects(
31258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        const ColorAspects &aspects,
31358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange) {
31458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (aspects.mPrimaries == ColorAspects::PrimariesOther ||
31558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            !sIsoPrimaries.map(aspects.mPrimaries, primaries)) {
31658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        CHECK(sIsoPrimaries.map(ColorAspects::PrimariesUnspecified, primaries));
31758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
31858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (aspects.mTransfer == ColorAspects::TransferOther ||
31958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            !sIsoTransfers.map(aspects.mTransfer, transfer)) {
32058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        CHECK(sIsoTransfers.map(ColorAspects::TransferUnspecified, transfer));
32158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
32258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (aspects.mMatrixCoeffs == ColorAspects::MatrixOther ||
32358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            !sIsoMatrixCoeffs.map(aspects.mMatrixCoeffs, coeffs)) {
32458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        CHECK(sIsoMatrixCoeffs.map(ColorAspects::MatrixUnspecified, coeffs));
32558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
32658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    *fullRange = aspects.mRange == ColorAspects::RangeFull;
32758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar}
32858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
32958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar// static
33058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnarvoid ColorUtils::convertIsoColorAspectsToCodecAspects(
33158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
33258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        ColorAspects &aspects) {
33358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (!sIsoPrimaries.map(primaries, &aspects.mPrimaries)) {
33458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
33558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
33658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (!sIsoTransfers.map(transfer, &aspects.mTransfer)) {
33758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        aspects.mTransfer = ColorAspects::TransferUnspecified;
33858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
33958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    if (!sIsoMatrixCoeffs.map(coeffs, &aspects.mMatrixCoeffs)) {
34058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
34158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    }
34258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar    aspects.mRange = fullRange ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
34358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar}
34458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar
3453a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar// static
3463a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnarvoid ColorUtils::setDefaultCodecColorAspectsIfNeeded(
3473a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        ColorAspects &aspects, int32_t width, int32_t height) {
3483a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    ColorAspects::MatrixCoeffs coeffs;
3493a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    ColorAspects::Primaries primaries;
3503a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
3513a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601
3523a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between.
3533a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) {
3543a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        primaries = ColorAspects::PrimariesBT2020;
3553a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        coeffs = ColorAspects::MatrixBT2020;
3563a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if ((width <= 720 && height > 480 && height <= 576)
3573a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar            || (height <= 720 && width > 480 && width <= 576)) {
3583a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        primaries = ColorAspects::PrimariesBT601_6_625;
3593a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        coeffs = ColorAspects::MatrixBT601_6;
3603a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) {
3613a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        primaries = ColorAspects::PrimariesBT601_6_525;
3623a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        coeffs = ColorAspects::MatrixBT601_6;
3633a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    } else {
3643a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        primaries = ColorAspects::PrimariesBT709_5;
3653a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        coeffs = ColorAspects::MatrixBT709_5;
3663a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
3673a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
3683a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (aspects.mRange == ColorAspects::RangeUnspecified) {
3693a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        aspects.mRange = ColorAspects::RangeLimited;
3703a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
3713a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
3723a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
3733a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        aspects.mPrimaries = primaries;
3743a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
3753a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
3763a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        aspects.mMatrixCoeffs = coeffs;
3773a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
3783a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
3793a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar        aspects.mTransfer = ColorAspects::TransferSMPTE170M;
3803a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar    }
3813a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}
3823a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// TODO: move this into a Video HAL
384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos MolnarALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandardFallbacks {
385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    {
386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT470_6M } },
387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT601_6 } },
388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT709,     { CA::PrimariesBT709_5, CA::MatrixSMPTE240M } },
389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT709,     { CA::PrimariesBT709_5, CA::MatrixBT2020 } },
390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_525, { CA::PrimariesBT709_5, CA::MatrixBT2020Constant } },
391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT2020Constant,
393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                       { CA::PrimariesBT470_6M, CA::MatrixBT2020Constant } },
394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_625, { CA::PrimariesBT601_6_625, CA::MatrixBT470_6M } },
396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_625, CA::MatrixBT2020Constant } },
397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT470_6M } },
399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT2020Constant } },
400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT2020Constant,
402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                       { CA::PrimariesGenericFilm, CA::MatrixBT2020Constant } },
403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar};
405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos MolnarALookup<CU::ColorStandard, CA::Primaries> sStandardPrimariesFallbacks {
407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    {
408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardFilm,                 CA::PrimariesGenericFilm },
409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT470M,               CA::PrimariesBT470_6M },
410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT2020,               CA::PrimariesBT2020 },
411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_525_Unadjusted, CA::PrimariesBT601_6_525 },
412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { CU::kColorStandardBT601_625_Unadjusted, CA::PrimariesBT601_6_625 },
413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar};
415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
416b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatic ALookup<android_dataspace, android_dataspace> sLegacyDataSpaceToV0 {
417b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    {
418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_SRGB, HAL_DATASPACE_V0_SRGB },
419b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_BT709, HAL_DATASPACE_V0_BT709 },
420b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_SRGB_LINEAR, HAL_DATASPACE_V0_SRGB_LINEAR },
421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_BT601_525, HAL_DATASPACE_V0_BT601_525 },
422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_BT601_625, HAL_DATASPACE_V0_BT601_625 },
423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        { HAL_DATASPACE_JFIF, HAL_DATASPACE_V0_JFIF },
424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar};
426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarbool ColorUtils::convertDataSpaceToV0(android_dataspace &dataSpace) {
428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)sLegacyDataSpaceToV0.lookup(dataSpace, &dataSpace);
429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return (dataSpace & 0xC000FFFF) == 0;
430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarbool ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects) {
434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // remove changed aspects (change them to Unspecified)
435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    bool changed = false;
436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (aspects.mRange && aspects.mRange != orig.mRange) {
437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = ColorAspects::RangeUnspecified;
438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        changed = true;
439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (aspects.mPrimaries && aspects.mPrimaries != orig.mPrimaries) {
441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (usePlatformAspects) {
443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        changed = true;
446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (aspects.mMatrixCoeffs && aspects.mMatrixCoeffs != orig.mMatrixCoeffs) {
448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
449b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (usePlatformAspects) {
450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        changed = true;
453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (aspects.mTransfer && aspects.mTransfer != orig.mTransfer) {
455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = ColorAspects::TransferUnspecified;
456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        changed = true;
457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return changed;
459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// static
462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarandroid_dataspace ColorUtils::getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand) {
463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // This platform implementation never expands color space (e.g. returns an expanded
464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // dataspace to use where the codec does in-the-background color space conversion)
465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mayExpand = false;
466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (aspects.mRange == ColorAspects::RangeUnspecified
468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            || aspects.mPrimaries == ColorAspects::PrimariesUnspecified
469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            || aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified
470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            || aspects.mTransfer == ColorAspects::TransferUnspecified) {
471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("expected specified color aspects (%u:%u:%u:%u)",
472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                aspects.mRange, aspects.mPrimaries, aspects.mMatrixCoeffs, aspects.mTransfer);
473b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
474b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
475b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // default to video range and transfer
476b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorRange range = kColorRangeLimited;
477b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorTransfer transfer = kColorTransferSMPTE_170M;
478b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)sRanges.map(aspects.mRange, &range);
479b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)sTransfers.map(aspects.mTransfer, &transfer);
480b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
481b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorStandard standard = kColorStandardBT709;
482b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    auto pair = std::make_pair(aspects.mPrimaries, aspects.mMatrixCoeffs);
483b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (!sStandards.map(pair, &standard)) {
484b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (!sStandardFallbacks.map(pair, &standard)) {
485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            (void)sStandardPrimariesFallbacks.map(aspects.mPrimaries, &standard);
486b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
487b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (aspects.mMatrixCoeffs == ColorAspects::MatrixBT2020Constant) {
488b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                range = kColorRangeFull;
489b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
492b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
493b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace = (android_dataspace)(
494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            (range << HAL_DATASPACE_RANGE_SHIFT) | (standard << HAL_DATASPACE_STANDARD_SHIFT) |
495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            (transfer << HAL_DATASPACE_TRANSFER_SHIFT));
496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)sLegacyDataSpaceToV0.rlookup(dataSpace, &dataSpace);
497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (!mayExpand) {
499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // update codec aspects based on dataspace
500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        convertPlatformColorAspectsToCodecAspects(range, standard, transfer, aspects);
501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return dataSpace;
503b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// static
506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ColorUtils::getColorConfigFromFormat(
507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &format, int32_t *range, int32_t *standard, int32_t *transfer) {
508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (!format->findInt32("color-range", range)) {
509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        *range = kColorRangeUnspecified;
510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (!format->findInt32("color-standard", standard)) {
512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        *standard = kColorStandardUnspecified;
513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (!format->findInt32("color-transfer", transfer)) {
515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        *transfer = kColorTransferUnspecified;
516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// static
520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ColorUtils::copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target) {
521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // 0 values are unspecified
522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t value;
523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (source->findInt32("color-range", &value)) {
524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        target->setInt32("color-range", value);
525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (source->findInt32("color-standard", &value)) {
527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        target->setInt32("color-standard", value);
528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (source->findInt32("color-transfer", &value)) {
530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        target->setInt32("color-transfer", value);
531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// static
535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ColorUtils::getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects) {
536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorConfigFromFormat(format, &range, &standard, &transfer);
538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (convertPlatformColorAspectsToCodecAspects(
540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, standard, transfer, aspects) != OK) {
541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("Ignoring illegal color aspects(R:%d(%s), S:%d(%s), T:%d(%s))",
542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                range, asString((ColorRange)range),
543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                standard, asString((ColorStandard)standard),
544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                transfer, asString((ColorTransfer)transfer));
545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // Invalid values were converted to unspecified !params!, but otherwise were not changed
546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // For encoders, we leave these as is. For decoders, we will use default values.
547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("Got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "from format (out:R:%d(%s), S:%d(%s), T:%d(%s))",
550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// static
560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ColorUtils::setColorAspectsIntoFormat(
561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const ColorAspects &aspects, sp<AMessage> &format, bool force) {
562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range = 0, standard = 0, transfer = 0;
563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
564b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // save set values to base output format
565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // (encoder input format will read back actually supported values by the codec)
566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0 || force) {
567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        format->setInt32("color-range", range);
568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0 || force) {
570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        format->setInt32("color-standard", standard);
571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0 || force) {
573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        format->setInt32("color-transfer", transfer);
574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("Setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "into format (out:R:%d(%s), S:%d(%s), T:%d(%s))",
577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
583b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
584b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
585b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
586db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang// static
587db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangvoid ColorUtils::setHDRStaticInfoIntoFormat(
588db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        const HDRStaticInfo &info, sp<AMessage> &format) {
589db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    sp<ABuffer> infoBuffer = new ABuffer(25);
590db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
591db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // Convert the data in infoBuffer to little endian format as defined by CTA-861-3
592db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    uint8_t *data = infoBuffer->data();
593db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // Static_Metadata_Descriptor_ID
594db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[0] = info.mID;
595db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
596db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // display primary 0
597db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[1] = LO_UINT16(info.sType1.mR.x);
598db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[2] = HI_UINT16(info.sType1.mR.x);
599db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[3] = LO_UINT16(info.sType1.mR.y);
600db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[4] = HI_UINT16(info.sType1.mR.y);
601db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
602db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // display primary 1
603db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[5] = LO_UINT16(info.sType1.mG.x);
604db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[6] = HI_UINT16(info.sType1.mG.x);
605db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[7] = LO_UINT16(info.sType1.mG.y);
606db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[8] = HI_UINT16(info.sType1.mG.y);
607db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
608db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // display primary 2
609db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[9] = LO_UINT16(info.sType1.mB.x);
610db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[10] = HI_UINT16(info.sType1.mB.x);
611db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[11] = LO_UINT16(info.sType1.mB.y);
612db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[12] = HI_UINT16(info.sType1.mB.y);
613db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
614db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // white point
615db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[13] = LO_UINT16(info.sType1.mW.x);
616db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[14] = HI_UINT16(info.sType1.mW.x);
617db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[15] = LO_UINT16(info.sType1.mW.y);
618db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[16] = HI_UINT16(info.sType1.mW.y);
619db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
620db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // MaxDisplayLuminance
621db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[17] = LO_UINT16(info.sType1.mMaxDisplayLuminance);
622db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[18] = HI_UINT16(info.sType1.mMaxDisplayLuminance);
623db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
624db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // MinDisplayLuminance
625db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[19] = LO_UINT16(info.sType1.mMinDisplayLuminance);
626db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[20] = HI_UINT16(info.sType1.mMinDisplayLuminance);
627db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
628db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // MaxContentLightLevel
629db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[21] = LO_UINT16(info.sType1.mMaxContentLightLevel);
630db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[22] = HI_UINT16(info.sType1.mMaxContentLightLevel);
631db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
632db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // MaxFrameAverageLightLevel
633db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[23] = LO_UINT16(info.sType1.mMaxFrameAverageLightLevel);
634db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    data[24] = HI_UINT16(info.sType1.mMaxFrameAverageLightLevel);
635db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
636db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    format->setBuffer("hdr-static-info", infoBuffer);
637db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
638db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
639db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang// a simple method copied from Utils.cpp
640db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatic uint16_t U16LE_AT(const uint8_t *ptr) {
641db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return ptr[0] | (ptr[1] << 8);
642db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
643db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
644db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang// static
645db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangbool ColorUtils::getHDRStaticInfoFromFormat(const sp<AMessage> &format, HDRStaticInfo *info) {
646db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    sp<ABuffer> buf;
647db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (!format->findBuffer("hdr-static-info", &buf)) {
648db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return false;
649db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
650db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
651db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    // TODO: Make this more flexible when adding more members to HDRStaticInfo
652db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (buf->size() != 25 /* static Metadata Type 1 size */) {
653db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        ALOGW("Ignore invalid HDRStaticInfo with size: %zu", buf->size());
654db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return false;
655db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
656db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
657db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const uint8_t *data = buf->data();
658db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (*data != HDRStaticInfo::kType1) {
659db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        ALOGW("Unsupported static Metadata Type %u", *data);
660db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return false;
661db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
662db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
663db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->mID = HDRStaticInfo::kType1;
664db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mR.x = U16LE_AT(&data[1]);
665db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mR.y = U16LE_AT(&data[3]);
666db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mG.x = U16LE_AT(&data[5]);
667db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mG.y = U16LE_AT(&data[7]);
668db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mB.x = U16LE_AT(&data[9]);
669db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mB.y = U16LE_AT(&data[11]);
670db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mW.x = U16LE_AT(&data[13]);
671db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mW.y = U16LE_AT(&data[15]);
672db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mMaxDisplayLuminance = U16LE_AT(&data[17]);
673db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mMinDisplayLuminance = U16LE_AT(&data[19]);
674db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mMaxContentLightLevel = U16LE_AT(&data[21]);
675db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    info->sType1.mMaxFrameAverageLightLevel = U16LE_AT(&data[23]);
676db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
677db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("Got HDRStaticInfo from config (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
678db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
679db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
680db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
681db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
682db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
683db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return true;
684db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
685db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
6863a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar}  // namespace android
6873a09d8d6f909063990a5681b15a442b2ba8ce54aLajos Molnar
688