1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef API_VIDEO_COLOR_SPACE_H_
12 #define API_VIDEO_COLOR_SPACE_H_
13 
14 #include <stdint.h>
15 
16 #include "absl/types/optional.h"
17 #include "api/video/hdr_metadata.h"
18 #include "rtc_base/system/rtc_export.h"
19 
20 namespace webrtc {
21 
22 // This class represents color information as specified in T-REC H.273,
23 // available from https://www.itu.int/rec/T-REC-H.273.
24 //
25 // WebRTC's supported codecs:
26 // - VP9 supports color profiles, see VP9 Bitstream & Decoding Process
27 // Specification Version 0.6 Section 7.2.2 "Color config semantics" available
28 // from https://www.webmproject.org.
29 // - VP8 only supports BT.601, see
30 // https://tools.ietf.org/html/rfc6386#section-9.2
31 // - H264 uses the exact same representation as T-REC H.273. See T-REC-H.264
32 // E.2.1, "VUI parameters semantics", available from
33 // https://www.itu.int/rec/T-REC-H.264.
34 
35 class RTC_EXPORT ColorSpace {
36  public:
37   enum class PrimaryID : uint8_t {
38     // The indices are equal to the values specified in T-REC H.273 Table 2.
39     kBT709 = 1,
40     kUnspecified = 2,
41     kBT470M = 4,
42     kBT470BG = 5,
43     kSMPTE170M = 6,  // Identical to BT601
44     kSMPTE240M = 7,
45     kFILM = 8,
46     kBT2020 = 9,
47     kSMPTEST428 = 10,
48     kSMPTEST431 = 11,
49     kSMPTEST432 = 12,
50     kJEDECP22 = 22,  // Identical to EBU3213-E
51     // When adding/removing entries here, please make sure to do the
52     // corresponding change to kPrimaryIds.
53   };
54 
55   enum class TransferID : uint8_t {
56     // The indices are equal to the values specified in T-REC H.273 Table 3.
57     kBT709 = 1,
58     kUnspecified = 2,
59     kGAMMA22 = 4,
60     kGAMMA28 = 5,
61     kSMPTE170M = 6,
62     kSMPTE240M = 7,
63     kLINEAR = 8,
64     kLOG = 9,
65     kLOG_SQRT = 10,
66     kIEC61966_2_4 = 11,
67     kBT1361_ECG = 12,
68     kIEC61966_2_1 = 13,
69     kBT2020_10 = 14,
70     kBT2020_12 = 15,
71     kSMPTEST2084 = 16,
72     kSMPTEST428 = 17,
73     kARIB_STD_B67 = 18,
74     // When adding/removing entries here, please make sure to do the
75     // corresponding change to kTransferIds.
76   };
77 
78   enum class MatrixID : uint8_t {
79     // The indices are equal to the values specified in T-REC H.273 Table 4.
80     kRGB = 0,
81     kBT709 = 1,
82     kUnspecified = 2,
83     kFCC = 4,
84     kBT470BG = 5,
85     kSMPTE170M = 6,
86     kSMPTE240M = 7,
87     kYCOCG = 8,
88     kBT2020_NCL = 9,
89     kBT2020_CL = 10,
90     kSMPTE2085 = 11,
91     kCDNCLS = 12,
92     kCDCLS = 13,
93     kBT2100_ICTCP = 14,
94     // When adding/removing entries here, please make sure to do the
95     // corresponding change to kMatrixIds.
96   };
97 
98   enum class RangeID {
99     // The indices are equal to the values specified at
100     // https://www.webmproject.org/docs/container/#colour for the element Range.
101     kInvalid = 0,
102     // Limited Rec. 709 color range with RGB values ranging from 16 to 235.
103     kLimited = 1,
104     // Full RGB color range with RGB valees from 0 to 255.
105     kFull = 2,
106     // Range is defined by MatrixCoefficients/TransferCharacteristics.
107     kDerived = 3,
108     // When adding/removing entries here, please make sure to do the
109     // corresponding change to kRangeIds.
110   };
111 
112   enum class ChromaSiting {
113     // Chroma siting specifies how chroma is subsampled relative to the luma
114     // samples in a YUV video frame.
115     // The indices are equal to the values specified at
116     // https://www.webmproject.org/docs/container/#colour for the element
117     // ChromaSitingVert and ChromaSitingHorz.
118     kUnspecified = 0,
119     kCollocated = 1,
120     kHalf = 2,
121     // When adding/removing entries here, please make sure to do the
122     // corresponding change to kChromaSitings.
123   };
124 
125   ColorSpace();
126   ColorSpace(const ColorSpace& other);
127   ColorSpace(ColorSpace&& other);
128   ColorSpace& operator=(const ColorSpace& other);
129   ColorSpace(PrimaryID primaries,
130              TransferID transfer,
131              MatrixID matrix,
132              RangeID range);
133   ColorSpace(PrimaryID primaries,
134              TransferID transfer,
135              MatrixID matrix,
136              RangeID range,
137              ChromaSiting chroma_siting_horizontal,
138              ChromaSiting chroma_siting_vertical,
139              const HdrMetadata* hdr_metadata);
140   friend bool operator==(const ColorSpace& lhs, const ColorSpace& rhs) {
141     return lhs.primaries_ == rhs.primaries_ && lhs.transfer_ == rhs.transfer_ &&
142            lhs.matrix_ == rhs.matrix_ && lhs.range_ == rhs.range_ &&
143            lhs.chroma_siting_horizontal_ == rhs.chroma_siting_horizontal_ &&
144            lhs.chroma_siting_vertical_ == rhs.chroma_siting_vertical_ &&
145            lhs.hdr_metadata_ == rhs.hdr_metadata_;
146   }
147   friend bool operator!=(const ColorSpace& lhs, const ColorSpace& rhs) {
148     return !(lhs == rhs);
149   }
150 
151   PrimaryID primaries() const;
152   TransferID transfer() const;
153   MatrixID matrix() const;
154   RangeID range() const;
155   ChromaSiting chroma_siting_horizontal() const;
156   ChromaSiting chroma_siting_vertical() const;
157   const HdrMetadata* hdr_metadata() const;
158 
159   bool set_primaries_from_uint8(uint8_t enum_value);
160   bool set_transfer_from_uint8(uint8_t enum_value);
161   bool set_matrix_from_uint8(uint8_t enum_value);
162   bool set_range_from_uint8(uint8_t enum_value);
163   bool set_chroma_siting_horizontal_from_uint8(uint8_t enum_value);
164   bool set_chroma_siting_vertical_from_uint8(uint8_t enum_value);
165   void set_hdr_metadata(const HdrMetadata* hdr_metadata);
166 
167  private:
168   PrimaryID primaries_ = PrimaryID::kUnspecified;
169   TransferID transfer_ = TransferID::kUnspecified;
170   MatrixID matrix_ = MatrixID::kUnspecified;
171   RangeID range_ = RangeID::kInvalid;
172   ChromaSiting chroma_siting_horizontal_ = ChromaSiting::kUnspecified;
173   ChromaSiting chroma_siting_vertical_ = ChromaSiting::kUnspecified;
174   absl::optional<HdrMetadata> hdr_metadata_;
175 };
176 
177 }  // namespace webrtc
178 #endif  // API_VIDEO_COLOR_SPACE_H_
179