1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef COLOR_UTILS_H_ 18 19 #define COLOR_UTILS_H_ 20 21 #include <stdint.h> 22 23 #define STRINGIFY_ENUMS 24 25 #include <media/stagefright/foundation/AMessage.h> 26 27 #include <media/hardware/VideoAPI.h> 28 #include <system/graphics.h> 29 30 struct AMediaFormat; 31 32 namespace android { 33 34 struct ColorUtils { 35 /* 36 * Media-platform color constants. MediaCodec uses (an extended version of) platform-defined 37 * constants that are derived from HAL_DATASPACE, since these are directly exposed to the user. 38 * We extend the values to maintain the richer set of information defined inside media 39 * containers and bitstreams that are not supported by the platform. We also expect vendors 40 * to extend some of these values with vendor-specific values. These are separated into a 41 * vendor-extension section so they won't collide with future platform values. 42 */ 43 44 /** 45 * graphic.h constants changed in Android 8.0 after ColorStandard values were already public 46 * in Android 7.0. We will not deal with the break in graphic.h here, but list the public 47 * Android SDK MediaFormat values here. 48 */ 49 enum ColorStandard : uint32_t { 50 kColorStandardUnspecified = 0, 51 kColorStandardBT709 = 1, 52 kColorStandardBT601_625 = 2, 53 kColorStandardBT601_625_Unadjusted = 3, // not in SDK 54 kColorStandardBT601_525 = 4, 55 kColorStandardBT601_525_Unadjusted = 5, // not in SDK 56 kColorStandardBT2020 = 6, 57 kColorStandardBT2020Constant = 7, // not in SDK 58 kColorStandardBT470M = 8, // not in SDK 59 kColorStandardFilm = 9, // not in SDK 60 kColorStandardDisplay_P3 = 10, // not in SDK, new in Android 8.0 61 kColorStandardDCI_P3 = kColorStandardDisplay_P3, // legacy (incorrect) name for Display P3 62 63 /* This marks a section of color-standard values that are not supported by graphics HAL, 64 but track defined color primaries-matrix coefficient combinations in media. 65 These are stable for a given release. */ 66 kColorStandardExtendedStart = 64, 67 68 /* This marks a section of color-standard values that are not supported by graphics HAL 69 nor using media defined color primaries or matrix coefficients. These may differ per 70 device. */ 71 kColorStandardVendorStart = 0x10000, 72 }; 73 74 enum ColorTransfer : uint32_t { 75 kColorTransferUnspecified = 0, 76 kColorTransferLinear = 1, 77 kColorTransferSRGB = 2, 78 kColorTransferSMPTE_170M = 3, // not in SDK 79 kColorTransferGamma22 = 4, // not in SDK 80 kColorTransferGamma28 = 5, // not in SDK 81 kColorTransferST2084 = 6, 82 kColorTransferHLG = 7, 83 kColorTransferGamma26 = 8, // not in SDK, new in Android 8.0 84 85 /* This marks a section of color-transfer values that are not supported by graphics HAL, 86 but track media-defined color-transfer. These are stable for a given release. */ 87 kColorTransferExtendedStart = 32, 88 89 /* This marks a section of color-transfer values that are not supported by graphics HAL 90 nor defined by media. These may differ per device. */ 91 kColorTransferVendorStart = 0x10000, 92 }; 93 94 enum ColorRange : uint32_t { 95 kColorRangeUnspecified = 0, 96 kColorRangeFull = 1, 97 kColorRangeLimited = 2, 98 99 /* This marks a section of color-transfer values that are not supported by graphics HAL, 100 but track media-defined color-transfer. These are stable for a given release. */ 101 kColorRangeExtendedStart = 8, 102 103 /* This marks a section of color-transfer values that are not supported by graphics HAL 104 nor defined by media. These may differ per device. */ 105 kColorRangeVendorStart = 0x10000, 106 }; 107 108 /* 109 * Static utilities for codec support 110 */ 111 112 // using int32_t for media range/standard/transfers to denote extended ranges 113 // wrap methods change invalid aspects to the Unspecified value 114 static int32_t wrapColorAspectsIntoColorStandard( 115 ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs); 116 static int32_t wrapColorAspectsIntoColorRange(ColorAspects::Range range); 117 static int32_t wrapColorAspectsIntoColorTransfer(ColorAspects::Transfer transfer); 118 119 // unwrap methods change invalid aspects to the Other value 120 static status_t unwrapColorAspectsFromColorRange( 121 int32_t range, ColorAspects::Range *aspect); 122 static status_t unwrapColorAspectsFromColorTransfer( 123 int32_t transfer, ColorAspects::Transfer *aspect); 124 static status_t unwrapColorAspectsFromColorStandard( 125 int32_t standard, 126 ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs); 127 128 static status_t convertPlatformColorAspectsToCodecAspects( 129 int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects); 130 static status_t convertCodecColorAspectsToPlatformAspects( 131 const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer); 132 133 // converts Other values to Unspecified 134 static void convertCodecColorAspectsToIsoAspects( 135 const ColorAspects &aspects, 136 int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange); 137 // converts unsupported values to Other 138 static void convertIsoColorAspectsToCodecAspects( 139 int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange, 140 ColorAspects &aspects); 141 static void convertIsoColorAspectsToPlatformAspects( 142 int32_t primaries, int32_t isotransfer, int32_t coeffs, bool fullRange, 143 int32_t *range, int32_t *standard, int32_t *transfer); 144 145 // unpack a uint32_t to a full ColorAspects struct 146 static ColorAspects unpackToColorAspects(uint32_t packed); 147 148 // pack a full ColorAspects struct into a uint32_t 149 static uint32_t packToU32(const ColorAspects &aspects); 150 151 // updates Unspecified color aspects to their defaults based on the video size 152 static void setDefaultCodecColorAspectsIfNeeded( 153 ColorAspects &aspects, int32_t width, int32_t height); 154 155 // it returns the closest dataSpace for given color |aspects|. if |mayExpand| is true, it allows 156 // returning a larger dataSpace that contains the color space given by |aspects|, and is better 157 // suited to blending. This requires implicit color space conversion on part of the device. 158 static android_dataspace getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand); 159 160 // it returns the platform color configs from given |dataspace|. 161 static void getColorConfigFromDataSpace( 162 const android_dataspace &dataspace, int *range, int *standard, int *transfer); 163 164 // converts |dataSpace| to a V0 enum, and returns true if dataSpace is an aspect-only value 165 static bool convertDataSpaceToV0(android_dataspace &dataSpace); 166 167 // compares |aspect| to |orig|. Returns |true| if any aspects have changed, except if they 168 // changed to Unspecified value. It also sets the changed values to Unspecified in |aspect|. 169 static bool checkIfAspectsChangedAndUnspecifyThem( 170 ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects = false); 171 172 // finds color config in format, defaulting them to 0. 173 static void getColorConfigFromFormat( 174 const sp<AMessage> &format, int *range, int *standard, int *transfer); 175 176 // copies existing color config from |source| to |target|. 177 static void copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target); 178 179 // finds color config in format as ColorAspects, defaulting them to 0. 180 static void getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects); 181 182 // writes |aspects| into format. iff |force| is false, Unspecified values are not 183 // written. 184 static void setColorAspectsIntoFormat( 185 const ColorAspects &aspects, sp<AMessage> &format, bool force = false); 186 187 // finds HDR metadata in format as HDRStaticInfo, defaulting them to 0. 188 // Return |true| if could find HDR metadata in format. Otherwise, return |false|. 189 static bool getHDRStaticInfoFromFormat(const sp<AMessage> &format, HDRStaticInfo *info); 190 191 // writes |info| into format. 192 static void setHDRStaticInfoIntoFormat(const HDRStaticInfo &info, sp<AMessage> &format); 193 // writes |info| into format. 194 static void setHDRStaticInfoIntoAMediaFormat(const HDRStaticInfo &info, AMediaFormat *format); 195 // (internal) used by the setHDRStaticInfoInfo* routines 196 static void fillHdrStaticInfoBuffer( const HDRStaticInfo &info, uint8_t *data); 197 198 // determine whether HDR static info is valid 199 static bool isHDRStaticInfoValid(HDRStaticInfo *info); 200 }; 201 202 inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") { 203 using namespace android; 204 switch (i) { 205 case ColorUtils::kColorStandardUnspecified: return "Unspecified"; 206 case ColorUtils::kColorStandardBT709: return "BT709"; 207 case ColorUtils::kColorStandardBT601_625: return "BT601_625"; 208 case ColorUtils::kColorStandardBT601_625_Unadjusted: return "BT601_625_Unadjusted"; 209 case ColorUtils::kColorStandardBT601_525: return "BT601_525"; 210 case ColorUtils::kColorStandardBT601_525_Unadjusted: return "BT601_525_Unadjusted"; 211 case ColorUtils::kColorStandardBT2020: return "BT2020"; 212 case ColorUtils::kColorStandardBT2020Constant: return "BT2020Constant"; 213 case ColorUtils::kColorStandardBT470M: return "BT470M"; 214 case ColorUtils::kColorStandardFilm: return "Film"; 215 case ColorUtils::kColorStandardDisplay_P3: return "Display_P3"; 216 default: return def; 217 } 218 } 219 220 inline static const char *asString(android::ColorUtils::ColorTransfer i, const char *def = "??") { 221 using namespace android; 222 switch (i) { 223 case ColorUtils::kColorTransferUnspecified: return "Unspecified"; 224 case ColorUtils::kColorTransferLinear: return "Linear"; 225 case ColorUtils::kColorTransferSRGB: return "SRGB"; 226 case ColorUtils::kColorTransferSMPTE_170M: return "SMPTE_170M"; 227 case ColorUtils::kColorTransferGamma22: return "Gamma22"; 228 case ColorUtils::kColorTransferGamma28: return "Gamma28"; 229 case ColorUtils::kColorTransferST2084: return "ST2084"; 230 case ColorUtils::kColorTransferHLG: return "HLG"; 231 case ColorUtils::kColorTransferGamma26: return "Gamma26"; 232 default: return def; 233 } 234 } 235 236 inline static const char *asString(android::ColorUtils::ColorRange i, const char *def = "??") { 237 using namespace android; 238 switch (i) { 239 case ColorUtils::kColorRangeUnspecified: return "Unspecified"; 240 case ColorUtils::kColorRangeFull: return "Full"; 241 case ColorUtils::kColorRangeLimited: return "Limited"; 242 default: return def; 243 } 244 } 245 246 } // namespace android 247 248 #endif // COLOR_UTILS_H_ 249 250