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 // Note: ported from Chromium commit head: 27c98933749f
5
6 #include "fourcc.h"
7
8 #include <linux/videodev2.h>
9
10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h"
12
13 #include "macros.h"
14
15 namespace media {
16
Fourcc(Fourcc::Value fourcc)17 Fourcc::Fourcc(Fourcc::Value fourcc) : value_(fourcc) {}
18 Fourcc::~Fourcc() = default;
19 Fourcc& Fourcc::operator=(const Fourcc& other) = default;
20
21 // static
FromUint32(uint32_t fourcc)22 base::Optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
23 switch (fourcc) {
24 case AR24:
25 case AB24:
26 case XR24:
27 case XB24:
28 case RGB4:
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 DVLOGF(3) << "Unmapped fourcc: " << FourccToString(fourcc);
44 return base::nullopt;
45 }
46
47 // static
FromVideoPixelFormat(VideoPixelFormat pixel_format,bool single_planar)48 base::Optional<Fourcc> Fourcc::FromVideoPixelFormat(
49 VideoPixelFormat pixel_format,
50 bool single_planar) {
51 if (single_planar) {
52 switch (pixel_format) {
53 case PIXEL_FORMAT_ARGB:
54 return Fourcc(AR24);
55 case PIXEL_FORMAT_ABGR:
56 return Fourcc(AB24);
57 case PIXEL_FORMAT_XRGB:
58 return Fourcc(XR24);
59 case PIXEL_FORMAT_XBGR:
60 return Fourcc(XB24);
61 case PIXEL_FORMAT_BGRA:
62 return Fourcc(RGB4);
63 case PIXEL_FORMAT_I420:
64 return Fourcc(YU12);
65 case PIXEL_FORMAT_YV12:
66 return Fourcc(YV12);
67 case PIXEL_FORMAT_YUY2:
68 return Fourcc(YUYV);
69 case PIXEL_FORMAT_NV12:
70 return Fourcc(NV12);
71 case PIXEL_FORMAT_NV21:
72 return Fourcc(NV21);
73 case PIXEL_FORMAT_I422:
74 case PIXEL_FORMAT_I420A:
75 case PIXEL_FORMAT_I444:
76 case PIXEL_FORMAT_RGB24:
77 case PIXEL_FORMAT_MJPEG:
78 case PIXEL_FORMAT_YUV420P9:
79 case PIXEL_FORMAT_YUV420P10:
80 case PIXEL_FORMAT_YUV422P9:
81 case PIXEL_FORMAT_YUV422P10:
82 case PIXEL_FORMAT_YUV444P9:
83 case PIXEL_FORMAT_YUV444P10:
84 case PIXEL_FORMAT_YUV420P12:
85 case PIXEL_FORMAT_YUV422P12:
86 case PIXEL_FORMAT_YUV444P12:
87 case PIXEL_FORMAT_Y16:
88 case PIXEL_FORMAT_P016LE:
89 case PIXEL_FORMAT_XR30:
90 case PIXEL_FORMAT_XB30:
91 case PIXEL_FORMAT_UNKNOWN:
92 break;
93 }
94 } else {
95 switch (pixel_format) {
96 case PIXEL_FORMAT_I420:
97 return Fourcc(YM12);
98 case PIXEL_FORMAT_YV12:
99 return Fourcc(YM21);
100 case PIXEL_FORMAT_NV12:
101 return Fourcc(NM12);
102 case PIXEL_FORMAT_I422:
103 return Fourcc(YM16);
104 case PIXEL_FORMAT_NV21:
105 return Fourcc(NM21);
106 case PIXEL_FORMAT_I420A:
107 case PIXEL_FORMAT_I444:
108 case PIXEL_FORMAT_YUY2:
109 case PIXEL_FORMAT_ARGB:
110 case PIXEL_FORMAT_XRGB:
111 case PIXEL_FORMAT_RGB24:
112 case PIXEL_FORMAT_MJPEG:
113 case PIXEL_FORMAT_YUV420P9:
114 case PIXEL_FORMAT_YUV420P10:
115 case PIXEL_FORMAT_YUV422P9:
116 case PIXEL_FORMAT_YUV422P10:
117 case PIXEL_FORMAT_YUV444P9:
118 case PIXEL_FORMAT_YUV444P10:
119 case PIXEL_FORMAT_YUV420P12:
120 case PIXEL_FORMAT_YUV422P12:
121 case PIXEL_FORMAT_YUV444P12:
122 case PIXEL_FORMAT_Y16:
123 case PIXEL_FORMAT_ABGR:
124 case PIXEL_FORMAT_XBGR:
125 case PIXEL_FORMAT_P016LE:
126 case PIXEL_FORMAT_XR30:
127 case PIXEL_FORMAT_XB30:
128 case PIXEL_FORMAT_BGRA:
129 case PIXEL_FORMAT_UNKNOWN:
130 break;
131 }
132 }
133 DVLOGF(3) << "Unmapped " << VideoPixelFormatToString(pixel_format) << " for "
134 << (single_planar ? "single-planar" : "multi-planar");
135 return base::nullopt;
136 }
137
ToVideoPixelFormat() const138 VideoPixelFormat Fourcc::ToVideoPixelFormat() const {
139 switch (value_) {
140 case AR24:
141 return PIXEL_FORMAT_ARGB;
142 case AB24:
143 return PIXEL_FORMAT_ABGR;
144 case XR24:
145 return PIXEL_FORMAT_XRGB;
146 case XB24:
147 return PIXEL_FORMAT_XBGR;
148 case RGB4:
149 return PIXEL_FORMAT_BGRA;
150 case YU12:
151 case YM12:
152 return PIXEL_FORMAT_I420;
153 case YV12:
154 case YM21:
155 return PIXEL_FORMAT_YV12;
156 case YUYV:
157 return PIXEL_FORMAT_YUY2;
158 case NV12:
159 case NM12:
160 return PIXEL_FORMAT_NV12;
161 case NV21:
162 case NM21:
163 return PIXEL_FORMAT_NV21;
164 case YM16:
165 return PIXEL_FORMAT_I422;
166 // V4L2_PIX_FMT_MT21C is only used for MT8173 hardware video decoder output
167 // and should be converted by MT8173 image processor for compositor to
168 // render. Since it is an intermediate format for video decoder,
169 // VideoPixelFormat shall not have its mapping. However, we need to create a
170 // VideoFrameLayout for the format to process the intermediate frame. Hence
171 // we map V4L2_PIX_FMT_MT21C to PIXEL_FORMAT_NV12 as their layout are the
172 // same.
173 case MT21:
174 // V4L2_PIX_FMT_MM21 is used for MT8183 hardware video decoder. It is
175 // similar to V4L2_PIX_FMT_MT21C but is not compressed ; thus it can also
176 // be mapped to PIXEL_FORMAT_NV12.
177 case MM21:
178 return PIXEL_FORMAT_NV12;
179 }
180 NOTREACHED() << "Unmapped Fourcc: " << ToString();
181 return PIXEL_FORMAT_UNKNOWN;
182 }
183
184 // static
FromV4L2PixFmt(uint32_t v4l2_pix_fmt)185 base::Optional<Fourcc> Fourcc::FromV4L2PixFmt(uint32_t v4l2_pix_fmt) {
186 // We can do that because we adopt the same internal definition of Fourcc as
187 // V4L2.
188 return FromUint32(v4l2_pix_fmt);
189 }
190
ToV4L2PixFmt() const191 uint32_t Fourcc::ToV4L2PixFmt() const {
192 // Note that we can do that because we adopt the same internal definition of
193 // Fourcc as V4L2.
194 return static_cast<uint32_t>(value_);
195 }
196
ToSinglePlanar() const197 base::Optional<Fourcc> Fourcc::ToSinglePlanar() const {
198 switch (value_) {
199 case AR24:
200 case AB24:
201 case XR24:
202 case XB24:
203 case RGB4:
204 case YU12:
205 case YV12:
206 case YUYV:
207 case NV12:
208 case NV21:
209 return Fourcc(value_);
210 case YM12:
211 return Fourcc(YU12);
212 case YM21:
213 return Fourcc(YV12);
214 case NM12:
215 return Fourcc(NV12);
216 case NM21:
217 return Fourcc(NV21);
218 case YM16:
219 case MT21:
220 case MM21:
221 return base::nullopt;
222 }
223 }
224
operator !=(const Fourcc & lhs,const Fourcc & rhs)225 bool operator!=(const Fourcc& lhs, const Fourcc& rhs) {
226 return !(lhs == rhs);
227 }
228
IsMultiPlanar() const229 bool Fourcc::IsMultiPlanar() const {
230 switch (value_) {
231 case AR24:
232 case AB24:
233 case XR24:
234 case XB24:
235 case RGB4:
236 case YU12:
237 case YV12:
238 case YUYV:
239 case NV12:
240 case NV21:
241 return false;
242 case YM12:
243 case YM21:
244 case NM12:
245 case NM21:
246 case YM16:
247 case MT21:
248 case MM21:
249 return true;
250 }
251 }
252
ToString() const253 std::string Fourcc::ToString() const {
254 return FourccToString(static_cast<uint32_t>(value_));
255 }
256
257 static_assert(Fourcc::AR24 == V4L2_PIX_FMT_ABGR32, "Mismatch Fourcc");
258 #ifdef V4L2_PIX_FMT_RGBA32
259 // V4L2_PIX_FMT_RGBA32 is defined since v5.2
260 static_assert(Fourcc::AB24 == V4L2_PIX_FMT_RGBA32, "Mismatch Fourcc");
261 #endif // V4L2_PIX_FMT_RGBA32
262 static_assert(Fourcc::XR24 == V4L2_PIX_FMT_XBGR32, "Mismatch Fourcc");
263 #ifdef V4L2_PIX_FMT_RGBX32
264 // V4L2_PIX_FMT_RGBX32 is defined since v5.2
265 static_assert(Fourcc::XB24 == V4L2_PIX_FMT_RGBX32, "Mismatch Fourcc");
266 #endif // V4L2_PIX_FMT_RGBX32
267 static_assert(Fourcc::RGB4 == V4L2_PIX_FMT_RGB32, "Mismatch Fourcc");
268 static_assert(Fourcc::YU12 == V4L2_PIX_FMT_YUV420, "Mismatch Fourcc");
269 static_assert(Fourcc::YV12 == V4L2_PIX_FMT_YVU420, "Mismatch Fourcc");
270 static_assert(Fourcc::YM12 == V4L2_PIX_FMT_YUV420M, "Mismatch Fourcc");
271 static_assert(Fourcc::YM21 == V4L2_PIX_FMT_YVU420M, "Mismatch Fourcc");
272 static_assert(Fourcc::YUYV == V4L2_PIX_FMT_YUYV, "Mismatch Fourcc");
273 static_assert(Fourcc::NV12 == V4L2_PIX_FMT_NV12, "Mismatch Fourcc");
274 static_assert(Fourcc::NV21 == V4L2_PIX_FMT_NV21, "Mismatch Fourcc");
275 static_assert(Fourcc::NM12 == V4L2_PIX_FMT_NV12M, "Mismatch Fourcc");
276 static_assert(Fourcc::NM21 == V4L2_PIX_FMT_NV21M, "Mismatch Fourcc");
277 static_assert(Fourcc::YM16 == V4L2_PIX_FMT_YUV422M, "Mismatch Fourcc");
278 static_assert(Fourcc::MT21 == V4L2_PIX_FMT_MT21C, "Mismatch Fourcc");
279 #ifdef V4L2_PIX_FMT_MM21
280 // V4L2_PIX_FMT_MM21 is not yet upstreamed.
281 static_assert(Fourcc::MM21 == V4L2_PIX_FMT_MM21, "Mismatch Fourcc");
282 #endif // V4L2_PIX_FMT_MM21
283 } // namespace media
284