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