xref: /aosp_15_r20/external/v4l2_codec2/common/Fourcc.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
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