OSDN Git Service

Fix packed headers attribute test in vaCreateConfig()
[android-x86/hardware-intel-common-vaapi.git] / test / i965_jpeg_decode_test.cpp
1 /*
2  * Copyright (C) 2016 Intel Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "i965_test_fixture.h"
26 #include "i965_jpeg_test_data.h"
27
28 #include <iomanip>
29 #include <iostream>
30 #include <numeric>
31 #include <sstream>
32 #include <string>
33 #include <tuple>
34 #include <vector>
35
36 namespace JPEG {
37 namespace Decode {
38
39 class JPEGDecodeTest : public I965TestFixture { };
40
41 class FourCCTest
42     : public JPEGDecodeTest
43     , public ::testing::WithParamInterface<
44         std::tuple<TestPattern::SharedConst, const char*> >
45 {
46 protected:
47     virtual void SetUp()
48     {
49         JPEGDecodeTest::SetUp();
50
51         std::string sFourcc;
52         std::tie(testPattern, sFourcc) = GetParam();
53
54         ASSERT_PTR(testPattern.get()) << "Invalid test pattern parameter";
55
56         ASSERT_EQ(4u, sFourcc.size())
57             << "Invalid fourcc parameter '" << sFourcc << "'";
58
59         unsigned fourcc = VA_FOURCC(
60             sFourcc[0], sFourcc[1], sFourcc[2], sFourcc[3]);
61
62         pd = testPattern->encoded(fourcc);
63
64         ASSERT_PTR(pd.get())
65             << "Unhandled fourcc parameter '" << sFourcc << "'"
66             << " = 0x" << std::hex << fourcc << std::dec;
67
68         ASSERT_EQ(fourcc, pd->fourcc);
69     }
70
71     void validateComponent(const uint8_t * const expect, const uint8_t * actual,
72         unsigned width, unsigned height, unsigned pitch, unsigned hsample = 1,
73         unsigned vsample = 1)
74     {
75         for (size_t row(0); row < (height / vsample); ++row) {
76             for (size_t col(0); col < (width / hsample); ++col) {
77                 size_t aIdx = (row * pitch) + col;
78                 size_t eIdx = (row * vsample * height) + (col * hsample);
79
80                 std::vector<uint8_t> samples;
81                 for (size_t i(0); i < vsample; ++i) {
82                     for (size_t j(0); j < hsample; ++j) {
83                         size_t sIdx = eIdx + (width * i) + j;
84                         samples.push_back(expect[sIdx]);
85                     }
86                 }
87
88                 const uint8_t eVal =
89                     std::accumulate(samples.begin(), samples.end(), 0x00)
90                     / samples.size();
91
92                 const uint8_t aVal = actual[aIdx];
93
94                 SCOPED_TRACE(
95                     ::testing::Message() << std::endl
96                     << "\tRow    = " << row << std::endl
97                     << "\tColumn = " << col << std::endl
98                     << "\tExpect = 0x"
99                     << std::hex << std::setfill('0') << std::setw(2)
100                     << (uint32_t)eVal << std::endl
101                     << "\tActual = 0x"
102                     << std::hex << std::setfill('0') << std::setw(2)
103                     << (uint32_t)aVal << std::dec);
104
105                 EXPECT_NEAR(eVal, aVal, 0x02);
106             }
107         }
108     }
109
110     void validateImageOutput(const VAImage& image, const uint8_t * const output)
111     {
112         {
113             SCOPED_TRACE("Y Component\n");
114             validateComponent(
115                 testPattern->decoded().data(), output + image.offsets[0],
116                 image.width, image.height, image.pitches[0]);
117         }
118
119         {
120             SCOPED_TRACE("U Component\n");
121             validateComponent(
122                 testPattern->decoded().data() + (image.width * image.height),
123                 output + image.offsets[1], image.width, image.height,
124                 image.pitches[1], pd->pparam.components[0].h_sampling_factor,
125                 pd->pparam.components[0].v_sampling_factor);
126         }
127
128         {
129             SCOPED_TRACE("V Component\n");
130             validateComponent(
131                 testPattern->decoded().data() + (image.width * image.height * 2),
132                 output + image.offsets[2], image.width, image.height,
133                 image.pitches[2], pd->pparam.components[0].h_sampling_factor,
134                 pd->pparam.components[0].v_sampling_factor);
135         }
136     }
137
138     void printComponentDataTo(std::ostream& os, const uint8_t * const data,
139         unsigned w, unsigned h, unsigned pitch, unsigned hsample = 1,
140         unsigned vsample = 1)
141     {
142         const uint8_t *row = data;
143         for (unsigned i(0); i < (h/vsample); ++i) {
144             for (size_t j(0); j < (w/hsample); ++j) {
145                 os  << "0x" << std::hex << std::setfill('0') << std::setw(2)
146                     << (uint32_t)row[j] << ",";
147             }
148             os << std::endl;
149             row += pitch;
150         }
151         os << std::setw(0) << std::setfill(' ') << std::dec << std::endl;
152     }
153
154     void printImageOutputTo(std::ostream& os, const VAImage& image,
155         const uint8_t * const output)
156     {
157         printComponentDataTo(os, output + image.offsets[0], image.width,
158             image.height, image.pitches[0]); // Y
159
160         printComponentDataTo(os, output + image.offsets[1], image.width,
161             image.height, image.pitches[1],
162             pd->pparam.components[0].h_sampling_factor,
163             pd->pparam.components[0].v_sampling_factor); // U
164
165         printComponentDataTo(os, output + image.offsets[2], image.width,
166             image.height, image.pitches[2],
167             pd->pparam.components[0].h_sampling_factor,
168             pd->pparam.components[0].v_sampling_factor); // V
169     }
170
171     TestPattern::SharedConst testPattern;
172     PictureData::SharedConst pd;
173 };
174
175 TEST_P(FourCCTest, Decode)
176 {
177     struct i965_driver_data *i965(*this);
178     ASSERT_PTR(i965);
179     if (not HAS_JPEG_DECODING(i965)) {
180         RecordProperty("skipped", true);
181         std::cout << "[  SKIPPED ] " << getFullTestName()
182             << " is unsupported on this hardware" << std::endl;
183         return;
184     }
185
186     VAConfigAttrib a = { type:VAConfigAttribRTFormat, value:pd->format };
187     ConfigAttribs attribs(1, a);
188
189     ASSERT_NO_FAILURE(
190         Surfaces surfaces = createSurfaces(
191             pd->pparam.picture_width, pd->pparam.picture_height, pd->format));
192     ASSERT_NO_FAILURE(
193         VAConfigID config = createConfig(profile, entrypoint, attribs));
194     ASSERT_NO_FAILURE(
195         VAContextID context = createContext(
196             config, pd->pparam.picture_width, pd->pparam.picture_height, 0,
197             surfaces));
198     ASSERT_NO_FAILURE(
199         VABufferID sliceDataBufId = createBuffer(
200             context, VASliceDataBufferType, pd->sparam.slice_data_size, 1,
201             pd->slice.data()));
202     ASSERT_NO_FAILURE(
203         VABufferID sliceParamBufId = createBuffer(
204             context, VASliceParameterBufferType, sizeof(pd->sparam), 1,
205             &pd->sparam));
206     ASSERT_NO_FAILURE(
207         VABufferID picBufId = createBuffer(
208             context, VAPictureParameterBufferType, sizeof(pd->pparam), 1,
209             &pd->pparam));
210     ASSERT_NO_FAILURE(
211         VABufferID iqMatrixBufId = createBuffer(
212             context, VAIQMatrixBufferType, sizeof(IQMatrix), 1, &pd->iqmatrix));
213     ASSERT_NO_FAILURE(
214         VABufferID huffTableBufId = createBuffer(
215             context, VAHuffmanTableBufferType, sizeof(HuffmanTable), 1,
216             &pd->huffman));
217
218     ASSERT_NO_FAILURE(beginPicture(context, surfaces.front()));
219     ASSERT_NO_FAILURE(renderPicture(context, &picBufId));
220     ASSERT_NO_FAILURE(renderPicture(context, &iqMatrixBufId));
221     ASSERT_NO_FAILURE(renderPicture(context, &huffTableBufId));
222     ASSERT_NO_FAILURE(renderPicture(context, &sliceParamBufId));
223     ASSERT_NO_FAILURE(renderPicture(context, &sliceDataBufId));
224     ASSERT_NO_FAILURE(endPicture(context));
225
226     VAImage image{.image_id = VA_INVALID_ID};
227     ASSERT_NO_FAILURE(deriveImage(surfaces.front(), image));
228     ASSERT_NO_FAILURE(
229         uint8_t *output = mapBuffer<uint8_t>(image.buf));
230
231     unsigned rwidth = ALIGN(image.width, 128);
232     unsigned rheight =
233         ALIGN(image.height, 32)
234         + ALIGN(image.height / pd->pparam.components[0].v_sampling_factor, 32)
235         * 2;
236
237     SCOPED_TRACE(
238         ::testing::Message()
239         << std::endl
240         << "image  : " << image.width << "x" << image.height
241         << std::endl
242         << "region : " << rwidth << "x" << rheight
243         << std::endl
244         << "planes : " << image.num_planes
245         << std::endl
246         << "offsets: " << image.offsets[0] << " " << image.offsets[1] << " " << image.offsets[2]
247         << std::endl
248         << "pitches: " << image.pitches[0] << " " << image.pitches[1] << " " << image.pitches[2]
249     );
250
251     EXPECT_EQ(3u, image.num_planes);
252     EXPECT_EQ(pd->pparam.picture_width, image.width);
253     EXPECT_EQ(pd->pparam.picture_height, image.height);
254     EXPECT_EQ(rwidth * rheight, image.data_size);
255     EXPECT_EQ(pd->fourcc, image.format.fourcc);
256
257     std::ostringstream oss;
258     printImageOutputTo(oss, image, output);
259     RecordProperty("Output", oss.str());
260
261     validateImageOutput(image, output);
262
263 //     std::cout << oss.str();
264
265     unmapBuffer(image.buf);
266
267     destroyBuffer(huffTableBufId);
268     destroyBuffer(iqMatrixBufId);
269     destroyBuffer(picBufId);
270     destroyBuffer(sliceParamBufId);
271     destroyBuffer(sliceDataBufId);
272
273     destroyImage(image);
274     destroyContext(context);
275     destroyConfig(config);
276     destroySurfaces(surfaces);
277 }
278
279
280 /** Teach Google Test how to print a TestPattern::SharedConst object */
281 void PrintTo(const TestPattern::SharedConst& t, std::ostream* os)
282 {
283     *os << *t;
284 }
285
286 INSTANTIATE_TEST_CASE_P(
287     JPEG, FourCCTest,
288     ::testing::Combine(
289         ::testing::Values(
290             TestPattern::SharedConst(new TestPatternData<1>),
291             TestPattern::SharedConst(new TestPatternData<2>),
292             TestPattern::SharedConst(new TestPatternData<3>),
293             TestPattern::SharedConst(new TestPatternData<4>)
294         ),
295         ::testing::Values("IMC3", "422H", "422V", "444P", "411P"))
296 );
297
298 } // namespace Decode
299 } // namespace JPEG