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 "base/optional.h"
6 #include "media/gpu/chromeos/fourcc.h"
7 
8 #include "media/gpu/buildflags.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 #if BUILDFLAG(USE_V4L2_CODEC)
12 #include <linux/videodev2.h>
13 #endif  // BUILDFLAG(USE_V4L2_CODEC)
14 #if BUILDFLAG(USE_VAAPI)
15 #include <va/va.h>
16 #endif  // BUILDFLAG(USE_VAAPI)
17 
18 namespace media {
19 
20 #if BUILDFLAG(USE_V4L2_CODEC)
21 // Checks that converting a V4L2 pixel format to Fourcc and back to V4L2
22 // yields the same format as the original one.
CheckFromV4L2PixFmtAndBack(uint32_t fmt)23 static void CheckFromV4L2PixFmtAndBack(uint32_t fmt) {
24   base::Optional<Fourcc> fourcc = Fourcc::FromV4L2PixFmt(fmt);
25   EXPECT_NE(fourcc, base::nullopt);
26   EXPECT_EQ(fourcc->ToV4L2PixFmt(), fmt);
27 }
28 
TEST(FourccTest,V4L2PixFmtToV4L2PixFmt)29 TEST(FourccTest, V4L2PixFmtToV4L2PixFmt) {
30   // Temporary defined in v4l2/v4l2_device.h
31   static constexpr uint32_t V4L2_MM21 = ComposeFourcc('M', 'M', '2', '1');
32 
33   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_ABGR32);
34 #ifdef V4L2_PIX_FMT_RGBA32
35   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_RGBA32);
36 #endif
37   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_XBGR32);
38 #ifdef V4L2_PIX_FMT_RGBX32
39   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_RGBX32);
40 #endif
41   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_RGB32);
42   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YUV420);
43   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YVU420);
44   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YUV420M);
45   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YVU420M);
46   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YUYV);
47   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_NV12);
48   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_NV21);
49   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_NV12M);
50   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_YUV422M);
51   CheckFromV4L2PixFmtAndBack(V4L2_PIX_FMT_MT21C);
52   CheckFromV4L2PixFmtAndBack(V4L2_MM21);
53 }
54 
TEST(FourccTest,V4L2PixFmtToVideoPixelFormat)55 TEST(FourccTest, V4L2PixFmtToVideoPixelFormat) {
56   EXPECT_EQ(PIXEL_FORMAT_NV12,
57             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_NV12)->ToVideoPixelFormat());
58   EXPECT_EQ(PIXEL_FORMAT_NV12,
59             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_NV12M)->ToVideoPixelFormat());
60 
61   EXPECT_EQ(PIXEL_FORMAT_NV12,
62             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_MT21C)->ToVideoPixelFormat());
63   EXPECT_EQ(PIXEL_FORMAT_NV12,
64             Fourcc::FromV4L2PixFmt(ComposeFourcc('M', 'M', '2', '1'))
65                 ->ToVideoPixelFormat());
66 
67   EXPECT_EQ(PIXEL_FORMAT_I420,
68             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_YUV420)->ToVideoPixelFormat());
69   EXPECT_EQ(PIXEL_FORMAT_I420,
70             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_YUV420M)->ToVideoPixelFormat());
71 
72   EXPECT_EQ(PIXEL_FORMAT_YV12,
73             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_YVU420)->ToVideoPixelFormat());
74   EXPECT_EQ(PIXEL_FORMAT_YV12,
75             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_YVU420M)->ToVideoPixelFormat());
76 
77   EXPECT_EQ(PIXEL_FORMAT_I422,
78             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_YUV422M)->ToVideoPixelFormat());
79 
80   // Noted that previously in V4L2Device::V4L2PixFmtToVideoPixelFormat(),
81   // V4L2_PIX_FMT_RGB32 maps to PIXEL_FORMAT_ARGB. However, the mapping was
82   // wrong. It should be mapped to PIXEL_FORMAT_BGRA.
83   EXPECT_EQ(PIXEL_FORMAT_BGRA,
84             Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_RGB32)->ToVideoPixelFormat());
85 
86   // Randomly pick an unmapped v4l2 fourcc.
87   EXPECT_EQ(base::nullopt, Fourcc::FromV4L2PixFmt(V4L2_PIX_FMT_Z16));
88 }
89 
TEST(FourccTest,VideoPixelFormatToV4L2PixFmt)90 TEST(FourccTest, VideoPixelFormatToV4L2PixFmt) {
91   EXPECT_EQ(
92       V4L2_PIX_FMT_NV12,
93       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_NV12, true)->ToV4L2PixFmt());
94   EXPECT_EQ(
95       V4L2_PIX_FMT_NV12M,
96       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_NV12, false)->ToV4L2PixFmt());
97 
98   EXPECT_EQ(
99       V4L2_PIX_FMT_YUV420,
100       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_I420, true)->ToV4L2PixFmt());
101   EXPECT_EQ(
102       V4L2_PIX_FMT_YUV420M,
103       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_I420, false)->ToV4L2PixFmt());
104 
105   EXPECT_EQ(
106       V4L2_PIX_FMT_YVU420,
107       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_YV12, true)->ToV4L2PixFmt());
108   EXPECT_EQ(
109       V4L2_PIX_FMT_YVU420M,
110       Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_YV12, false)->ToV4L2PixFmt());
111 }
112 #endif  // BUILDFLAG(USE_V4L2_CODEC)
113 
114 #if BUILDFLAG(USE_VAAPI)
115 // Checks that converting a VaFourCC to Fourcc and back to VaFourCC
116 // yields the same format as the original one.
CheckFromVAFourCCAndBack(uint32_t va_fourcc)117 static void CheckFromVAFourCCAndBack(uint32_t va_fourcc) {
118   base::Optional<Fourcc> fourcc = Fourcc::FromVAFourCC(va_fourcc);
119   EXPECT_NE(fourcc, base::nullopt);
120   base::Optional<uint32_t> to_va_fourcc = fourcc->ToVAFourCC();
121   EXPECT_NE(to_va_fourcc, base::nullopt);
122   EXPECT_EQ(*to_va_fourcc, va_fourcc);
123 }
124 
TEST(FourccTest,FromVaFourCCAndBack)125 TEST(FourccTest, FromVaFourCCAndBack) {
126   CheckFromVAFourCCAndBack(VA_FOURCC_I420);
127   CheckFromVAFourCCAndBack(VA_FOURCC_NV12);
128   CheckFromVAFourCCAndBack(VA_FOURCC_NV21);
129   CheckFromVAFourCCAndBack(VA_FOURCC_YV12);
130   CheckFromVAFourCCAndBack(VA_FOURCC_YUY2);
131   CheckFromVAFourCCAndBack(VA_FOURCC_RGBA);
132   CheckFromVAFourCCAndBack(VA_FOURCC_RGBX);
133   CheckFromVAFourCCAndBack(VA_FOURCC_BGRA);
134   CheckFromVAFourCCAndBack(VA_FOURCC_BGRX);
135   CheckFromVAFourCCAndBack(VA_FOURCC_ARGB);
136   CheckFromVAFourCCAndBack(VA_FOURCC_P010);
137 }
138 
TEST(FourccTest,VAFourCCToVideoPixelFormat)139 TEST(FourccTest, VAFourCCToVideoPixelFormat) {
140   EXPECT_EQ(PIXEL_FORMAT_I420,
141             Fourcc::FromVAFourCC(VA_FOURCC_I420)->ToVideoPixelFormat());
142   EXPECT_EQ(PIXEL_FORMAT_NV12,
143             Fourcc::FromVAFourCC(VA_FOURCC_NV12)->ToVideoPixelFormat());
144   EXPECT_EQ(PIXEL_FORMAT_NV21,
145             Fourcc::FromVAFourCC(VA_FOURCC_NV21)->ToVideoPixelFormat());
146   EXPECT_EQ(PIXEL_FORMAT_YV12,
147             Fourcc::FromVAFourCC(VA_FOURCC_YV12)->ToVideoPixelFormat());
148   EXPECT_EQ(PIXEL_FORMAT_YUY2,
149             Fourcc::FromVAFourCC(VA_FOURCC_YUY2)->ToVideoPixelFormat());
150   EXPECT_EQ(PIXEL_FORMAT_ABGR,
151             Fourcc::FromVAFourCC(VA_FOURCC_RGBA)->ToVideoPixelFormat());
152   EXPECT_EQ(PIXEL_FORMAT_XBGR,
153             Fourcc::FromVAFourCC(VA_FOURCC_RGBX)->ToVideoPixelFormat());
154   EXPECT_EQ(PIXEL_FORMAT_ARGB,
155             Fourcc::FromVAFourCC(VA_FOURCC_BGRA)->ToVideoPixelFormat());
156   EXPECT_EQ(PIXEL_FORMAT_XRGB,
157             Fourcc::FromVAFourCC(VA_FOURCC_BGRX)->ToVideoPixelFormat());
158   EXPECT_EQ(PIXEL_FORMAT_P016LE,
159             Fourcc::FromVAFourCC(VA_FOURCC_P010)->ToVideoPixelFormat());
160 }
161 
TEST(FourccTest,VideoPixelFormatToVAFourCC)162 TEST(FourccTest, VideoPixelFormatToVAFourCC) {
163   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_I420),
164             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_I420)->ToVAFourCC());
165   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_NV12),
166             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_NV12)->ToVAFourCC());
167   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_NV21),
168             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_NV21)->ToVAFourCC());
169   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_YV12),
170             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_YV12)->ToVAFourCC());
171   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_YUY2),
172             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_YUY2)->ToVAFourCC());
173   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_RGBA),
174             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_ABGR)->ToVAFourCC());
175   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_RGBX),
176             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_XBGR)->ToVAFourCC());
177   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_BGRA),
178             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_ARGB)->ToVAFourCC());
179   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_BGRX),
180             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_XRGB)->ToVAFourCC());
181   EXPECT_EQ(static_cast<uint32_t>(VA_FOURCC_P010),
182             *Fourcc::FromVideoPixelFormat(PIXEL_FORMAT_P016LE)->ToVAFourCC());
183 }
184 #endif  // BUILDFLAG(USE_VAAPI)
185 
TEST(FourccTest,FourccToSinglePlanar)186 TEST(FourccTest, FourccToSinglePlanar) {
187   EXPECT_EQ(Fourcc(Fourcc::AR24).ToSinglePlanar(), Fourcc(Fourcc::AR24));
188   EXPECT_EQ(Fourcc(Fourcc::AB24).ToSinglePlanar(), Fourcc(Fourcc::AB24));
189   EXPECT_EQ(Fourcc(Fourcc::XR24).ToSinglePlanar(), Fourcc(Fourcc::XR24));
190   EXPECT_EQ(Fourcc(Fourcc::XB24).ToSinglePlanar(), Fourcc(Fourcc::XB24));
191   EXPECT_EQ(Fourcc(Fourcc::RGB4).ToSinglePlanar(), Fourcc(Fourcc::RGB4));
192   EXPECT_EQ(Fourcc(Fourcc::YU12).ToSinglePlanar(), Fourcc(Fourcc::YU12));
193   EXPECT_EQ(Fourcc(Fourcc::YV12).ToSinglePlanar(), Fourcc(Fourcc::YV12));
194   EXPECT_EQ(Fourcc(Fourcc::YUYV).ToSinglePlanar(), Fourcc(Fourcc::YUYV));
195   EXPECT_EQ(Fourcc(Fourcc::NV12).ToSinglePlanar(), Fourcc(Fourcc::NV12));
196   EXPECT_EQ(Fourcc(Fourcc::NV21).ToSinglePlanar(), Fourcc(Fourcc::NV21));
197   EXPECT_EQ(Fourcc(Fourcc::P010).ToSinglePlanar(), Fourcc(Fourcc::P010));
198   EXPECT_EQ(Fourcc(Fourcc::YM12).ToSinglePlanar(),
199             Fourcc(Fourcc::YU12).ToSinglePlanar());
200   EXPECT_EQ(Fourcc(Fourcc::YM21).ToSinglePlanar(),
201             Fourcc(Fourcc::YV12).ToSinglePlanar());
202   EXPECT_EQ(Fourcc(Fourcc::NM12).ToSinglePlanar(),
203             Fourcc(Fourcc::NV12).ToSinglePlanar());
204   EXPECT_EQ(Fourcc(Fourcc::NM21).ToSinglePlanar(),
205             Fourcc(Fourcc::NV21).ToSinglePlanar());
206 }
207 }  // namespace media
208