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