ColorUtils.h revision b77d03b62cb743d0faf74b54aa466b4d220b5e61
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
30namespace android {
31
32struct 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    // updates Unspecified color aspects to their defaults based on the video size
133    static void setDefaultCodecColorAspectsIfNeeded(
134            ColorAspects &aspects, int32_t width, int32_t height);
135
136    // it returns the closest dataSpace for given color |aspects|. if |mayExpand| is true, it allows
137    // returning a larger dataSpace that contains the color space given by |aspects|, and is better
138    // suited to blending. This requires implicit color space conversion on part of the device.
139    static android_dataspace getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand);
140
141    // converts |dataSpace| to a V0 enum, and returns true if dataSpace is an aspect-only value
142    static bool convertDataSpaceToV0(android_dataspace &dataSpace);
143
144    // compares |aspect| to |orig|. Returns |true| if any aspects have changed, except if they
145    // changed to Unspecified value. It also sets the changed values to Unspecified in |aspect|.
146    static bool checkIfAspectsChangedAndUnspecifyThem(
147            ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects = false);
148
149    // finds color config in format, defaulting them to 0.
150    static void getColorConfigFromFormat(
151            const sp<AMessage> &format, int *range, int *standard, int *transfer);
152
153    // copies existing color config from |source| to |target|.
154    static void copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target);
155
156    // finds color config in format as ColorAspects, defaulting them to 0.
157    static void getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects);
158
159    // writes |aspects| into format. iff |force| is false, Unspecified values are not
160    // written.
161    static void setColorAspectsIntoFormat(
162            const ColorAspects &aspects, sp<AMessage> &format, bool force = false);
163};
164
165inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") {
166    using namespace android;
167    switch (i) {
168        case ColorUtils::kColorStandardUnspecified:          return "Unspecified";
169        case ColorUtils::kColorStandardBT709:                return "BT709";
170        case ColorUtils::kColorStandardBT601_625:            return "BT601_625";
171        case ColorUtils::kColorStandardBT601_625_Unadjusted: return "BT601_625_Unadjusted";
172        case ColorUtils::kColorStandardBT601_525:            return "BT601_525";
173        case ColorUtils::kColorStandardBT601_525_Unadjusted: return "BT601_525_Unadjusted";
174        case ColorUtils::kColorStandardBT2020:               return "BT2020";
175        case ColorUtils::kColorStandardBT2020Constant:       return "BT2020Constant";
176        case ColorUtils::kColorStandardBT470M:               return "BT470M";
177        case ColorUtils::kColorStandardFilm:                 return "Film";
178        default:                                            return def;
179    }
180}
181
182inline static const char *asString(android::ColorUtils::ColorTransfer i, const char *def = "??") {
183    using namespace android;
184    switch (i) {
185        case ColorUtils::kColorTransferUnspecified: return "Unspecified";
186        case ColorUtils::kColorTransferLinear:      return "Linear";
187        case ColorUtils::kColorTransferSRGB:        return "SRGB";
188        case ColorUtils::kColorTransferSMPTE_170M:  return "SMPTE_170M";
189        case ColorUtils::kColorTransferGamma22:     return "Gamma22";
190        case ColorUtils::kColorTransferGamma28:     return "Gamma28";
191        case ColorUtils::kColorTransferST2084:      return "ST2084";
192        case ColorUtils::kColorTransferHLG:         return "HLG";
193        default:                                   return def;
194    }
195}
196
197inline static const char *asString(android::ColorUtils::ColorRange i, const char *def = "??") {
198    using namespace android;
199    switch (i) {
200        case ColorUtils::kColorRangeUnspecified: return "Unspecified";
201        case ColorUtils::kColorRangeFull:        return "Full";
202        case ColorUtils::kColorRangeLimited:     return "Limited";
203        default:                                return def;
204    }
205}
206
207}  // namespace android
208
209#endif  // COLOR_UTILS_H_
210
211