• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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