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