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