1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "Fourcc"
7
8 #include <v4l2_codec2/common/Fourcc.h>
9
10 #include <linux/videodev2.h>
11
12 #include <utils/Log.h>
13
14 namespace android {
15
Fourcc(Fourcc::Value fourcc)16 Fourcc::Fourcc(Fourcc::Value fourcc) : mValue(fourcc) {}
17 Fourcc::~Fourcc() = default;
18 Fourcc& Fourcc::operator=(const Fourcc& other) = default;
19
20 // static
fromUint32(uint32_t fourcc)21 std::optional<Fourcc> Fourcc::fromUint32(uint32_t fourcc) {
22 switch (fourcc) {
23 case AR24:
24 case AB24:
25 case XR24:
26 case XB24:
27 case RGB4:
28 case YU12:
29 case YV12:
30 case YM12:
31 case YM21:
32 case YUYV:
33 case NV12:
34 case NV21:
35 case NM12:
36 case NM21:
37 case YM16:
38 case MT21:
39 case MM21:
40 return Fourcc(static_cast<Value>(fourcc));
41 }
42 ALOGV("Unmapped fourcc: %s", fourccToString(fourcc).c_str());
43 return std::nullopt;
44 }
45
46 // static
fromVideoPixelFormat(VideoPixelFormat pixelFormat,bool singlePlanar)47 std::optional<Fourcc> Fourcc::fromVideoPixelFormat(VideoPixelFormat pixelFormat,
48 bool singlePlanar) {
49 if (singlePlanar) {
50 switch (pixelFormat) {
51 case VideoPixelFormat::ARGB:
52 return Fourcc(AR24);
53 case VideoPixelFormat::ABGR:
54 return Fourcc(AB24);
55 case VideoPixelFormat::XRGB:
56 return Fourcc(XR24);
57 case VideoPixelFormat::XBGR:
58 return Fourcc(XB24);
59 case VideoPixelFormat::BGRA:
60 return Fourcc(RGB4);
61 case VideoPixelFormat::I420:
62 return Fourcc(YU12);
63 case VideoPixelFormat::YV12:
64 return Fourcc(YV12);
65 case VideoPixelFormat::YUY2:
66 return Fourcc(YUYV);
67 case VideoPixelFormat::NV12:
68 return Fourcc(NV12);
69 case VideoPixelFormat::NV21:
70 return Fourcc(NV21);
71 case VideoPixelFormat::I422:
72 case VideoPixelFormat::I420A:
73 case VideoPixelFormat::I444:
74 case VideoPixelFormat::RGB24:
75 case VideoPixelFormat::MJPEG:
76 case VideoPixelFormat::YUV420P9:
77 case VideoPixelFormat::YUV420P10:
78 case VideoPixelFormat::YUV422P9:
79 case VideoPixelFormat::YUV422P10:
80 case VideoPixelFormat::YUV444P9:
81 case VideoPixelFormat::YUV444P10:
82 case VideoPixelFormat::YUV420P12:
83 case VideoPixelFormat::YUV422P12:
84 case VideoPixelFormat::YUV444P12:
85 case VideoPixelFormat::Y16:
86 case VideoPixelFormat::P016LE:
87 case VideoPixelFormat::XR30:
88 case VideoPixelFormat::XB30:
89 case VideoPixelFormat::UNKNOWN:
90 break;
91 }
92 } else {
93 switch (pixelFormat) {
94 case VideoPixelFormat::I420:
95 return Fourcc(YM12);
96 case VideoPixelFormat::YV12:
97 return Fourcc(YM21);
98 case VideoPixelFormat::NV12:
99 return Fourcc(NM12);
100 case VideoPixelFormat::I422:
101 return Fourcc(YM16);
102 case VideoPixelFormat::NV21:
103 return Fourcc(NM21);
104 case VideoPixelFormat::I420A:
105 case VideoPixelFormat::I444:
106 case VideoPixelFormat::YUY2:
107 case VideoPixelFormat::ARGB:
108 case VideoPixelFormat::XRGB:
109 case VideoPixelFormat::RGB24:
110 case VideoPixelFormat::MJPEG:
111 case VideoPixelFormat::YUV420P9:
112 case VideoPixelFormat::YUV420P10:
113 case VideoPixelFormat::YUV422P9:
114 case VideoPixelFormat::YUV422P10:
115 case VideoPixelFormat::YUV444P9:
116 case VideoPixelFormat::YUV444P10:
117 case VideoPixelFormat::YUV420P12:
118 case VideoPixelFormat::YUV422P12:
119 case VideoPixelFormat::YUV444P12:
120 case VideoPixelFormat::Y16:
121 case VideoPixelFormat::ABGR:
122 case VideoPixelFormat::XBGR:
123 case VideoPixelFormat::P016LE:
124 case VideoPixelFormat::XR30:
125 case VideoPixelFormat::XB30:
126 case VideoPixelFormat::BGRA:
127 case VideoPixelFormat::UNKNOWN:
128 break;
129 }
130 }
131 ALOGE("Unmapped %s for %s", videoPixelFormatToString(pixelFormat).c_str(),
132 singlePlanar ? "single-planar" : "multi-planar");
133 return std::nullopt;
134 }
135
toVideoPixelFormat() const136 VideoPixelFormat Fourcc::toVideoPixelFormat() const {
137 switch (mValue) {
138 case AR24:
139 return VideoPixelFormat::ARGB;
140 case AB24:
141 return VideoPixelFormat::ABGR;
142 case XR24:
143 return VideoPixelFormat::XRGB;
144 case XB24:
145 return VideoPixelFormat::XBGR;
146 case RGB4:
147 return VideoPixelFormat::BGRA;
148 case YU12:
149 case YM12:
150 return VideoPixelFormat::I420;
151 case YV12:
152 case YM21:
153 return VideoPixelFormat::YV12;
154 case YUYV:
155 return VideoPixelFormat::YUY2;
156 case NV12:
157 case NM12:
158 return VideoPixelFormat::NV12;
159 case NV21:
160 case NM21:
161 return VideoPixelFormat::NV21;
162 case YM16:
163 return VideoPixelFormat::I422;
164 // V4L2_PIX_FMT_MT21C is only used for MT8173 hardware video decoder output
165 // and should be converted by MT8173 image processor for compositor to
166 // render. Since it is an intermediate format for video decoder,
167 // VideoPixelFormat shall not have its mapping. However, we need to create a
168 // VideoFrameLayout for the format to process the intermediate frame. Hence
169 // we map V4L2_PIX_FMT_MT21C to PIXEL_FORMAT_NV12 as their layout are the
170 // same.
171 case MT21:
172 // V4L2_PIX_FMT_MM21 is used for MT8183 hardware video decoder. It is
173 // similar to V4L2_PIX_FMT_MT21C but is not compressed ; thus it can also
174 // be mapped to PIXEL_FORMAT_NV12.
175 case MM21:
176 return VideoPixelFormat::NV12;
177 }
178
179 ALOGE("Unmapped Fourcc: %s", toString().c_str());
180 return VideoPixelFormat::UNKNOWN;
181 }
182
183 // static
fromV4L2PixFmt(uint32_t v4l2PixFmt)184 std::optional<Fourcc> Fourcc::fromV4L2PixFmt(uint32_t v4l2PixFmt) {
185 // We can do that because we adopt the same internal definition of Fourcc as
186 // V4L2.
187 return fromUint32(v4l2PixFmt);
188 }
189
toV4L2PixFmt() const190 uint32_t Fourcc::toV4L2PixFmt() const {
191 // Note that we can do that because we adopt the same internal definition of
192 // Fourcc as V4L2.
193 return static_cast<uint32_t>(mValue);
194 }
195
toSinglePlanar() const196 std::optional<Fourcc> Fourcc::toSinglePlanar() const {
197 switch (mValue) {
198 case AR24:
199 case AB24:
200 case XR24:
201 case XB24:
202 case RGB4:
203 case YU12:
204 case YV12:
205 case YUYV:
206 case NV12:
207 case NV21:
208 return Fourcc(mValue);
209 case YM12:
210 return Fourcc(YU12);
211 case YM21:
212 return Fourcc(YV12);
213 case NM12:
214 return Fourcc(NV12);
215 case NM21:
216 return Fourcc(NV21);
217 case YM16:
218 case MT21:
219 case MM21:
220 return std::nullopt;
221 }
222 }
223
operator !=(const Fourcc & lhs,const Fourcc & rhs)224 bool operator!=(const Fourcc& lhs, const Fourcc& rhs) {
225 return !(lhs == rhs);
226 }
227
isMultiPlanar() const228 bool Fourcc::isMultiPlanar() const {
229 switch (mValue) {
230 case AR24:
231 case AB24:
232 case XR24:
233 case XB24:
234 case RGB4:
235 case YU12:
236 case YV12:
237 case YUYV:
238 case NV12:
239 case NV21:
240 return false;
241 case YM12:
242 case YM21:
243 case NM12:
244 case NM21:
245 case YM16:
246 case MT21:
247 case MM21:
248 return true;
249 }
250 }
251
toString() const252 std::string Fourcc::toString() const {
253 return fourccToString(static_cast<uint32_t>(mValue));
254 }
255
256 static_assert(Fourcc::AR24 == V4L2_PIX_FMT_ABGR32, "Mismatch Fourcc");
257 #ifdef V4L2_PIX_FMT_RGBA32
258 // V4L2_PIX_FMT_RGBA32 is defined since v5.2
259 static_assert(Fourcc::AB24 == V4L2_PIX_FMT_RGBA32, "Mismatch Fourcc");
260 #endif // V4L2_PIX_FMT_RGBA32
261 static_assert(Fourcc::XR24 == V4L2_PIX_FMT_XBGR32, "Mismatch Fourcc");
262 #ifdef V4L2_PIX_FMT_RGBX32
263 // V4L2_PIX_FMT_RGBX32 is defined since v5.2
264 static_assert(Fourcc::XB24 == V4L2_PIX_FMT_RGBX32, "Mismatch Fourcc");
265 #endif // V4L2_PIX_FMT_RGBX32
266 static_assert(Fourcc::RGB4 == V4L2_PIX_FMT_RGB32, "Mismatch Fourcc");
267 static_assert(Fourcc::YU12 == V4L2_PIX_FMT_YUV420, "Mismatch Fourcc");
268 static_assert(Fourcc::YV12 == V4L2_PIX_FMT_YVU420, "Mismatch Fourcc");
269 static_assert(Fourcc::YM12 == V4L2_PIX_FMT_YUV420M, "Mismatch Fourcc");
270 static_assert(Fourcc::YM21 == V4L2_PIX_FMT_YVU420M, "Mismatch Fourcc");
271 static_assert(Fourcc::YUYV == V4L2_PIX_FMT_YUYV, "Mismatch Fourcc");
272 static_assert(Fourcc::NV12 == V4L2_PIX_FMT_NV12, "Mismatch Fourcc");
273 static_assert(Fourcc::NV21 == V4L2_PIX_FMT_NV21, "Mismatch Fourcc");
274 static_assert(Fourcc::NM12 == V4L2_PIX_FMT_NV12M, "Mismatch Fourcc");
275 static_assert(Fourcc::NM21 == V4L2_PIX_FMT_NV21M, "Mismatch Fourcc");
276 static_assert(Fourcc::YM16 == V4L2_PIX_FMT_YUV422M, "Mismatch Fourcc");
277 static_assert(Fourcc::MT21 == V4L2_PIX_FMT_MT21C, "Mismatch Fourcc");
278 #ifdef V4L2_PIX_FMT_MM21
279 // V4L2_PIX_FMT_MM21 is not yet upstreamed.
280 static_assert(Fourcc::MM21 == V4L2_PIX_FMT_MM21, "Mismatch Fourcc");
281 #endif // V4L2_PIX_FMT_MM21
282
283 } // namespace android
284