Home | History | Annotate | Download | only in foundation
      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 namespace android {
     31 
     32 struct ColorUtils {
     33     /*
     34      * Media-platform color constants. MediaCodec uses (an extended version of) platform-defined
     35      * constants that are derived from HAL_DATASPACE, since these are directly exposed to the user.
     36      * We extend the values to maintain the richer set of information defined inside media
     37      * containers and bitstreams that are not supported by the platform. We also expect vendors
     38      * to extend some of these values with vendor-specific values. These are separated into a
     39      * vendor-extension section so they won't collide with future platform values.
     40      */
     41 
     42 #define GET_HAL_ENUM(class, name) HAL_DATASPACE_##class##name
     43 #define GET_HAL_BITFIELD(class, name) (GET_HAL_ENUM(class, _##name) >> GET_HAL_ENUM(class, _SHIFT))
     44 
     45     enum ColorStandard : uint32_t {
     46         kColorStandardUnspecified =          GET_HAL_BITFIELD(STANDARD, UNSPECIFIED),
     47         kColorStandardBT709 =                GET_HAL_BITFIELD(STANDARD, BT709),
     48         kColorStandardBT601_625 =            GET_HAL_BITFIELD(STANDARD, BT601_625),
     49         kColorStandardBT601_625_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_625_UNADJUSTED),
     50         kColorStandardBT601_525 =            GET_HAL_BITFIELD(STANDARD, BT601_525),
     51         kColorStandardBT601_525_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_525_UNADJUSTED),
     52         kColorStandardBT2020 =               GET_HAL_BITFIELD(STANDARD, BT2020),
     53         kColorStandardBT2020Constant =       GET_HAL_BITFIELD(STANDARD, BT2020_CONSTANT_LUMINANCE),
     54         kColorStandardBT470M =               GET_HAL_BITFIELD(STANDARD, BT470M),
     55         kColorStandardFilm =                 GET_HAL_BITFIELD(STANDARD, FILM),
     56         kColorStandardMax =                  GET_HAL_BITFIELD(STANDARD, MASK),
     57 
     58         /* This marks a section of color-standard values that are not supported by graphics HAL,
     59            but track defined color primaries-matrix coefficient combinations in media.
     60            These are stable for a given release. */
     61         kColorStandardExtendedStart = kColorStandardMax + 1,
     62 
     63         /* This marks a section of color-standard values that are not supported by graphics HAL
     64            nor using media defined color primaries or matrix coefficients. These may differ per
     65            device. */
     66         kColorStandardVendorStart = 0x10000,
     67     };
     68 
     69     enum ColorTransfer : uint32_t  {
     70         kColorTransferUnspecified = GET_HAL_BITFIELD(TRANSFER, UNSPECIFIED),
     71         kColorTransferLinear =      GET_HAL_BITFIELD(TRANSFER, LINEAR),
     72         kColorTransferSRGB =        GET_HAL_BITFIELD(TRANSFER, SRGB),
     73         kColorTransferSMPTE_170M =  GET_HAL_BITFIELD(TRANSFER, SMPTE_170M),
     74         kColorTransferGamma22 =     GET_HAL_BITFIELD(TRANSFER, GAMMA2_2),
     75         kColorTransferGamma28 =     GET_HAL_BITFIELD(TRANSFER, GAMMA2_8),
     76         kColorTransferST2084 =      GET_HAL_BITFIELD(TRANSFER, ST2084),
     77         kColorTransferHLG =         GET_HAL_BITFIELD(TRANSFER, HLG),
     78         kColorTransferMax =         GET_HAL_BITFIELD(TRANSFER, MASK),
     79 
     80         /* This marks a section of color-transfer values that are not supported by graphics HAL,
     81            but track media-defined color-transfer. These are stable for a given release. */
     82         kColorTransferExtendedStart = kColorTransferMax + 1,
     83 
     84         /* This marks a section of color-transfer values that are not supported by graphics HAL
     85            nor defined by media. These may differ per device. */
     86         kColorTransferVendorStart = 0x10000,
     87     };
     88 
     89     enum ColorRange : uint32_t  {
     90         kColorRangeUnspecified = GET_HAL_BITFIELD(RANGE, UNSPECIFIED),
     91         kColorRangeFull =        GET_HAL_BITFIELD(RANGE, FULL),
     92         kColorRangeLimited =     GET_HAL_BITFIELD(RANGE, LIMITED),
     93         kColorRangeMax =         GET_HAL_BITFIELD(RANGE, MASK),
     94 
     95         /* This marks a section of color-transfer values that are not supported by graphics HAL,
     96            but track media-defined color-transfer. These are stable for a given release. */
     97         kColorRangeExtendedStart = kColorRangeMax + 1,
     98 
     99         /* This marks a section of color-transfer values that are not supported by graphics HAL
    100            nor defined by media. These may differ per device. */
    101         kColorRangeVendorStart = 0x10000,
    102     };
    103 
    104 #undef GET_HAL_BITFIELD
    105 #undef GET_HAL_ENUM
    106 
    107     /*
    108      * Static utilities for codec support
    109      */
    110 
    111     // using int32_t for media range/standard/transfers to denote extended ranges
    112     // wrap methods change invalid aspects to the Unspecified value
    113     static int32_t wrapColorAspectsIntoColorStandard(
    114             ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs);
    115     static int32_t wrapColorAspectsIntoColorRange(ColorAspects::Range range);
    116     static int32_t wrapColorAspectsIntoColorTransfer(ColorAspects::Transfer transfer);
    117 
    118     // unwrap methods change invalid aspects to the Other value
    119     static status_t unwrapColorAspectsFromColorRange(
    120             int32_t range, ColorAspects::Range *aspect);
    121     static status_t unwrapColorAspectsFromColorTransfer(
    122             int32_t transfer, ColorAspects::Transfer *aspect);
    123     static status_t unwrapColorAspectsFromColorStandard(
    124             int32_t standard,
    125             ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs);
    126 
    127     static status_t convertPlatformColorAspectsToCodecAspects(
    128             int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects);
    129     static status_t convertCodecColorAspectsToPlatformAspects(
    130             const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer);
    131 
    132     // converts Other values to Unspecified
    133     static void convertCodecColorAspectsToIsoAspects(
    134             const ColorAspects &aspects,
    135             int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange);
    136     // converts unsupported values to Other
    137     static void convertIsoColorAspectsToCodecAspects(
    138             int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
    139             ColorAspects &aspects);
    140 
    141     // unpack a uint32_t to a full ColorAspects struct
    142     static ColorAspects unpackToColorAspects(uint32_t packed);
    143 
    144     // pack a full ColorAspects struct into a uint32_t
    145     static uint32_t packToU32(const ColorAspects &aspects);
    146 
    147     // updates Unspecified color aspects to their defaults based on the video size
    148     static void setDefaultCodecColorAspectsIfNeeded(
    149             ColorAspects &aspects, int32_t width, int32_t height);
    150 
    151     // it returns the closest dataSpace for given color |aspects|. if |mayExpand| is true, it allows
    152     // returning a larger dataSpace that contains the color space given by |aspects|, and is better
    153     // suited to blending. This requires implicit color space conversion on part of the device.
    154     static android_dataspace getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand);
    155 
    156     // converts |dataSpace| to a V0 enum, and returns true if dataSpace is an aspect-only value
    157     static bool convertDataSpaceToV0(android_dataspace &dataSpace);
    158 
    159     // compares |aspect| to |orig|. Returns |true| if any aspects have changed, except if they
    160     // changed to Unspecified value. It also sets the changed values to Unspecified in |aspect|.
    161     static bool checkIfAspectsChangedAndUnspecifyThem(
    162             ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects = false);
    163 
    164     // finds color config in format, defaulting them to 0.
    165     static void getColorConfigFromFormat(
    166             const sp<AMessage> &format, int *range, int *standard, int *transfer);
    167 
    168     // copies existing color config from |source| to |target|.
    169     static void copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target);
    170 
    171     // finds color config in format as ColorAspects, defaulting them to 0.
    172     static void getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects);
    173 
    174     // writes |aspects| into format. iff |force| is false, Unspecified values are not
    175     // written.
    176     static void setColorAspectsIntoFormat(
    177             const ColorAspects &aspects, sp<AMessage> &format, bool force = false);
    178 
    179     // finds HDR metadata in format as HDRStaticInfo, defaulting them to 0.
    180     // Return |true| if could find HDR metadata in format. Otherwise, return |false|.
    181     static bool getHDRStaticInfoFromFormat(const sp<AMessage> &format, HDRStaticInfo *info);
    182 
    183     // writes |info| into format.
    184     static void setHDRStaticInfoIntoFormat(const HDRStaticInfo &info, sp<AMessage> &format);
    185 };
    186 
    187 inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") {
    188     using namespace android;
    189     switch (i) {
    190         case ColorUtils::kColorStandardUnspecified:          return "Unspecified";
    191         case ColorUtils::kColorStandardBT709:                return "BT709";
    192         case ColorUtils::kColorStandardBT601_625:            return "BT601_625";
    193         case ColorUtils::kColorStandardBT601_625_Unadjusted: return "BT601_625_Unadjusted";
    194         case ColorUtils::kColorStandardBT601_525:            return "BT601_525";
    195         case ColorUtils::kColorStandardBT601_525_Unadjusted: return "BT601_525_Unadjusted";
    196         case ColorUtils::kColorStandardBT2020:               return "BT2020";
    197         case ColorUtils::kColorStandardBT2020Constant:       return "BT2020Constant";
    198         case ColorUtils::kColorStandardBT470M:               return "BT470M";
    199         case ColorUtils::kColorStandardFilm:                 return "Film";
    200         default:                                            return def;
    201     }
    202 }
    203 
    204 inline static const char *asString(android::ColorUtils::ColorTransfer i, const char *def = "??") {
    205     using namespace android;
    206     switch (i) {
    207         case ColorUtils::kColorTransferUnspecified: return "Unspecified";
    208         case ColorUtils::kColorTransferLinear:      return "Linear";
    209         case ColorUtils::kColorTransferSRGB:        return "SRGB";
    210         case ColorUtils::kColorTransferSMPTE_170M:  return "SMPTE_170M";
    211         case ColorUtils::kColorTransferGamma22:     return "Gamma22";
    212         case ColorUtils::kColorTransferGamma28:     return "Gamma28";
    213         case ColorUtils::kColorTransferST2084:      return "ST2084";
    214         case ColorUtils::kColorTransferHLG:         return "HLG";
    215         default:                                   return def;
    216     }
    217 }
    218 
    219 inline static const char *asString(android::ColorUtils::ColorRange i, const char *def = "??") {
    220     using namespace android;
    221     switch (i) {
    222         case ColorUtils::kColorRangeUnspecified: return "Unspecified";
    223         case ColorUtils::kColorRangeFull:        return "Full";
    224         case ColorUtils::kColorRangeLimited:     return "Limited";
    225         default:                                return def;
    226     }
    227 }
    228 
    229 }  // namespace android
    230 
    231 #endif  // COLOR_UTILS_H_
    232 
    233