xref: /aosp_15_r20/external/v4l2_codec2/common/include/v4l2_codec2/common/Fourcc.h (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 // Note: ported from Chromium commit head: 27c98933749f
5 
6 #ifndef ANDROID_V4L2_CODEC2_COMMON_FOURCC_H
7 #define ANDROID_V4L2_CODEC2_COMMON_FOURCC_H
8 
9 #include <stdint.h>
10 #include <optional>
11 #include <string>
12 
13 #include <v4l2_codec2/common/VideoPixelFormat.h>
14 
15 namespace android {
16 
17 // Composes a Fourcc value.
composeFourcc(char a,char b,char c,char d)18 constexpr uint32_t composeFourcc(char a, char b, char c, char d) {
19     return static_cast<uint32_t>(a) | (static_cast<uint32_t>(b) << 8) |
20            (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24);
21 }
22 
23 // Fourcc enum holder and converters.
24 // Usage:
25 // Fourcc f1(Fourcc::AR24);
26 // EXPECT_EQ("AR24", f1.ToString());
27 // Fourcc f2 = Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_ARGB);
28 // EXPECT_EQ(f2, f1);
29 class Fourcc {
30 public:
31     enum Value : uint32_t {
32         // RGB formats.
33         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-rgb.html
34         // Maps to PIXEL_FORMAT_ARGB, V4L2_PIX_FMT_ABGR32, VA_FOURCC_BGRA.
35         // 32bpp BGRA (byte-order), 1 plane.
36         AR24 = composeFourcc('A', 'R', '2', '4'),
37 
38         // Maps to PIXEL_FORMAT_ABGR, V4L2_PIX_FMT_RGBA32, VA_FOURCC_RGBA.
39         // 32bpp RGBA (byte-order), 1 plane
40         AB24 = composeFourcc('A', 'B', '2', '4'),
41 
42         // Maps to PIXEL_FORMAT_XRGB, V4L2_PIX_FMT_XBGR32, VA_FOURCC_BGRX.
43         // 32bpp BGRX (byte-order), 1 plane.
44         XR24 = composeFourcc('X', 'R', '2', '4'),
45 
46         // Maps to PIXEL_FORMAT_XBGR, V4L2_PIX_FMT_RGBX32, VA_FOURCC_RGBX.
47         // 32bpp RGBX (byte-order), 1 plane.
48         XB24 = composeFourcc('X', 'B', '2', '4'),
49 
50         // Maps to PIXEL_FORMAT_BGRA, V4L2_PIX_FMT_RGB32, VA_FOURCC_ARGB.
51         // 32bpp ARGB (byte-order), 1 plane.
52         // Note that V4L2_PIX_FMT_RGB32("RGB4") is deprecated and replaced by
53         // V4L2_PIX_FMT_ARGB32("BA24"), however, some board relies on the fourcc mapping so we keep
54         // it as-is.
55         RGB4 = composeFourcc('R', 'G', 'B', '4'),
56 
57         BGR4 = composeFourcc('B', 'G', 'R', '4'),
58 
59         // YUV420 single-planar formats.
60         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-yuv420.html
61         // Maps to PIXEL_FORMAT_I420, V4L2_PIX_FMT_YUV420, VA_FOURCC_I420.
62         // 12bpp YUV planar 1x1 Y, 2x2 UV samples.
63         YU12 = composeFourcc('Y', 'U', '1', '2'),
64         // Maps to PIXEL_FORMAT_YV12, V4L2_PIX_FMT_YVU420, VA_FOURCC_YV12.
65         // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
66         YV12 = composeFourcc('Y', 'V', '1', '2'),
67 
68         // YUV420 multi-planar format.
69         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-yuv420m.htm
70         // Maps to PIXEL_FORMAT_I420, V4L2_PIX_FMT_YUV420M.
71         YM12 = composeFourcc('Y', 'M', '1', '2'),
72         // Maps to PIXEL_FORMAT_YV12, V4L2_PIX_FMT_YVU420M.
73         YM21 = composeFourcc('Y', 'M', '2', '1'),
74 
75         // YUYV format.
76         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-yuyv.html
77         // Maps to PIXEL_FORMAT_YUY2, V4L2_PIX_FMT_YUYV, VA_FOURCC_YUY2.
78         // 16bpp YUV planar (YUV 4:2:2), YUYV (byte-order), 1 plane.
79         YUYV = composeFourcc('Y', 'U', 'Y', 'V'),
80 
81         // NV12 single-planar format.
82         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-nv12.html
83         // Maps to PIXEL_FORMAT_NV12, V4L2_PIX_FMT_NV12, VA_FOURCC_NV12.
84         // 12bpp with Y plane followed by a 2x2 interleaved UV plane.
85         NV12 = composeFourcc('N', 'V', '1', '2'),
86         // Maps to PIXEL_FORMAT_NV21, V4L2_PIX_FMT_NV21, VA_FOURCC_NV21.
87         // 12bpp with Y plane followed by a 2x2 interleaved VU plane.
88         NV21 = composeFourcc('N', 'V', '2', '1'),
89 
90         // NV12 multi-planar format.
91         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-nv12m.html
92         // Maps to PIXEL_FORMAT_NV12, V4L2_PIX_FMT_NV12M,
93         NM12 = composeFourcc('N', 'M', '1', '2'),
94         // Maps to PIXEL_FORMAT_NV21, V4L2_PIX_FMT_NV21M.
95         NM21 = composeFourcc('N', 'M', '2', '1'),
96 
97         // YUV422 multi-planar format.
98         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-yuv422m.html
99         // Maps to PIXEL_FORMAT_I422, V4L2_PIX_FMT_YUV422M
100         // 16bpp YUV planar 1x1 Y, 2x1 UV samples.
101         YM16 = composeFourcc('Y', 'M', '1', '6'),
102 
103         // V4L2 proprietary format.
104         // https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-reserved.html
105         // Maps to V4L2_PIX_FMT_MT21C.
106         // It is used for MT8173 hardware video decoder output and should be converted by MT8173 image
107         // processor for compositor to render.
108         MT21 = composeFourcc('M', 'T', '2', '1'),
109         // Maps to V4L2_PIX_FMT_MM21.
110         // It is used for MT8183 hardware video decoder.
111         MM21 = composeFourcc('M', 'M', '2', '1'),
112     };
113 
114     explicit Fourcc(Fourcc::Value fourcc);
115     Fourcc& operator=(const Fourcc& fourcc);
116     ~Fourcc();
117 
118     bool operator==(const Fourcc& rhs) const { return mValue == rhs.mValue; }
119 
120     // Factory methods:
121 
122     // Builds a Fourcc from a given fourcc code. This will return a valid Fourcc if the argument is
123     // part of the |Value| enum, or nullopt otherwise.
124     static std::optional<Fourcc> fromUint32(uint32_t fourcc);
125 
126     // Converts a VideoPixelFormat to Fourcc. Returns nullopt for invalid input. Note that a
127     // VideoPixelFormat may have two Fourcc counterparts. Caller has to specify if it is for
128     // single-planar or multi-planar format.
129     static std::optional<Fourcc> fromVideoPixelFormat(VideoPixelFormat pixelFormat,
130                                                       bool singlePlanar = true);
131     // Converts a V4L2PixFmt to Fourcc. Returns nullopt for invalid input.
132     static std::optional<Fourcc> fromV4L2PixFmt(uint32_t v4l2PixFmt);
133 
134     // Value getters:
135     // Returns the VideoPixelFormat counterpart of the value. Returns PIXEL_FORMAT_UNKNOWN if no
136     // mapping is found.
137     VideoPixelFormat toVideoPixelFormat() const;
138     // Returns the V4L2PixFmt counterpart of the value. Returns 0 if no mapping is found.
139     uint32_t toV4L2PixFmt() const;
140 
141     // Returns the single-planar Fourcc of the value. If value is a single-planar, returns the same
142     // Fourcc. Returns nullopt if no mapping is found.
143     std::optional<Fourcc> toSinglePlanar() const;
144 
145     // Returns whether |value_| is multi planar format.
146     bool isMultiPlanar() const;
147 
148     // Outputs human readable fourcc string, e.g. "NV12".
149     std::string toString() const;
150 
151 private:
152     Value mValue;
153 };
154 
155 bool operator!=(const Fourcc& lhs, const Fourcc& rhs);
156 
157 }  // namespace android
158 
159 #endif  // ANDROID_V4L2_CODEC2_COMMON_FOURCC_H
160