OSDN Git Service

test: move vaInitialize/vaTerminate to a global test environment
[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 TEST_F(JPEGDecodeTest, Entrypoint)
42 {
43     VAConfigID config = VA_INVALID_ID;
44     ConfigAttribs attributes;
45     struct i965_driver_data *i965(*this);
46
47     ASSERT_PTR(i965);
48
49     if (HAS_JPEG_DECODING(i965)) {
50         config = createConfig(profile, entrypoint, attributes);
51     } else {
52         VAStatus status = i965_CreateConfig(
53             *this, profile, entrypoint, attributes.data(), attributes.size(),
54             &config);
55         EXPECT_STATUS_EQ(VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT, status);
56         EXPECT_INVALID_ID(config);
57     }
58
59     if (config != VA_INVALID_ID)
60         destroyConfig(config);
61 }
62
63 class FourCCTest
64     : public JPEGDecodeTest
65     , public ::testing::WithParamInterface<
66         std::tuple<TestPattern::SharedConst, const char*> >
67 {
68 protected:
69     virtual void SetUp()
70     {
71         JPEGDecodeTest::SetUp();
72
73         std::string sFourcc;
74         std::tie(testPattern, sFourcc) = GetParam();
75
76         ASSERT_PTR(testPattern.get()) << "Invalid test pattern parameter";
77
78         ASSERT_EQ(4u, sFourcc.size())
79             << "Invalid fourcc parameter '" << sFourcc << "'";
80
81         unsigned fourcc = VA_FOURCC(
82             sFourcc[0], sFourcc[1], sFourcc[2], sFourcc[3]);
83
84         pd = testPattern->encoded(fourcc);
85
86         ASSERT_PTR(pd.get())
87             << "Unhandled fourcc parameter '" << sFourcc << "'"
88             << " = 0x" << std::hex << fourcc << std::dec;
89
90         ASSERT_EQ(fourcc, pd->fourcc);
91     }
92
93     void validateComponent(const uint8_t * const expect, const uint8_t * actual,
94         unsigned width, unsigned height, unsigned pitch, unsigned hsample = 1,
95         unsigned vsample = 1)
96     {
97         for (size_t row(0); row < (height / vsample); ++row) {
98             for (size_t col(0); col < (width / hsample); ++col) {
99                 size_t aIdx = (row * pitch) + col;
100                 size_t eIdx = (row * vsample * height) + (col * hsample);
101
102                 std::vector<uint8_t> samples;
103                 for (size_t i(0); i < vsample; ++i) {
104                     for (size_t j(0); j < hsample; ++j) {
105                         size_t sIdx = eIdx + (width * i) + j;
106                         samples.push_back(expect[sIdx]);
107                     }
108                 }
109
110                 const uint8_t eVal =
111                     std::accumulate(samples.begin(), samples.end(), 0x00)
112                     / samples.size();
113
114                 const uint8_t aVal = actual[aIdx];
115
116                 SCOPED_TRACE(
117                     ::testing::Message() << std::endl
118                     << "\tRow    = " << row << std::endl
119                     << "\tColumn = " << col << std::endl
120                     << "\tExpect = 0x"
121                     << std::hex << std::setfill('0') << std::setw(2)
122                     << (uint32_t)eVal << std::endl
123                     << "\tActual = 0x"
124                     << std::hex << std::setfill('0') << std::setw(2)
125                     << (uint32_t)aVal << std::dec);
126
127                 EXPECT_NEAR(eVal, aVal, 0x02);
128             }
129         }
130     }
131
132     void validateImageOutput(const VAImage& image, const uint8_t * const output)
133     {
134         {
135             SCOPED_TRACE("Y Component\n");
136             validateComponent(
137                 testPattern->decoded().data(), output + image.offsets[0],
138                 image.width, image.height, image.pitches[0]);
139         }
140
141         {
142             SCOPED_TRACE("U Component\n");
143             validateComponent(
144                 testPattern->decoded().data() + (image.width * image.height),
145                 output + image.offsets[1], image.width, image.height,
146                 image.pitches[1], pd->pparam.components[0].h_sampling_factor,
147                 pd->pparam.components[0].v_sampling_factor);
148         }
149
150         {
151             SCOPED_TRACE("V Component\n");
152             validateComponent(
153                 testPattern->decoded().data() + (image.width * image.height * 2),
154                 output + image.offsets[2], image.width, image.height,
155                 image.pitches[2], pd->pparam.components[0].h_sampling_factor,
156                 pd->pparam.components[0].v_sampling_factor);
157         }
158     }
159
160     void printComponentDataTo(std::ostream& os, const uint8_t * const data,
161         unsigned w, unsigned h, unsigned pitch, unsigned hsample = 1,
162         unsigned vsample = 1)
163     {
164         const uint8_t *row = data;
165         for (unsigned i(0); i < (h/vsample); ++i) {
166             for (size_t j(0); j < (w/hsample); ++j) {
167                 os  << "0x" << std::hex << std::setfill('0') << std::setw(2)
168                     << (uint32_t)row[j] << ",";
169             }
170             os << std::endl;
171             row += pitch;
172         }
173         os << std::setw(0) << std::setfill(' ') << std::dec << std::endl;
174     }
175
176     void printImageOutputTo(std::ostream& os, const VAImage& image,
177         const uint8_t * const output)
178     {
179         printComponentDataTo(os, output + image.offsets[0], image.width,
180             image.height, image.pitches[0]); // Y
181
182         printComponentDataTo(os, output + image.offsets[1], image.width,
183             image.height, image.pitches[1],
184             pd->pparam.components[0].h_sampling_factor,
185             pd->pparam.components[0].v_sampling_factor); // U
186
187         printComponentDataTo(os, output + image.offsets[2], image.width,
188             image.height, image.pitches[2],
189             pd->pparam.components[0].h_sampling_factor,
190             pd->pparam.components[0].v_sampling_factor); // V
191     }
192
193     TestPattern::SharedConst testPattern;
194     PictureData::SharedConst pd;
195 };
196
197 TEST_P(FourCCTest, Decode)
198 {
199     struct i965_driver_data *i965(*this);
200     ASSERT_PTR(i965);
201     if (not HAS_JPEG_DECODING(i965)) {
202         RecordProperty("skipped", true);
203         std::cout << "[  SKIPPED ] " << getFullTestName()
204             << " is unsupported on this hardware" << std::endl;
205         return;
206     }
207
208     VAConfigAttrib a = { type:VAConfigAttribRTFormat, value:pd->format };
209     ConfigAttribs attribs(1, a);
210
211     ASSERT_NO_FAILURE(
212         Surfaces surfaces = createSurfaces(
213             pd->pparam.picture_width, pd->pparam.picture_height, pd->format));
214     ASSERT_NO_FAILURE(
215         VAConfigID config = createConfig(profile, entrypoint, attribs));
216     ASSERT_NO_FAILURE(
217         VAContextID context = createContext(
218             config, pd->pparam.picture_width, pd->pparam.picture_height, 0,
219             surfaces));
220     ASSERT_NO_FAILURE(
221         VABufferID sliceDataBufId = createBuffer(
222             context, VASliceDataBufferType, pd->sparam.slice_data_size, 1,
223             pd->slice.data()));
224     ASSERT_NO_FAILURE(
225         VABufferID sliceParamBufId = createBuffer(
226             context, VASliceParameterBufferType, sizeof(pd->sparam), 1,
227             &pd->sparam));
228     ASSERT_NO_FAILURE(
229         VABufferID picBufId = createBuffer(
230             context, VAPictureParameterBufferType, sizeof(pd->pparam), 1,
231             &pd->pparam));
232     ASSERT_NO_FAILURE(
233         VABufferID iqMatrixBufId = createBuffer(
234             context, VAIQMatrixBufferType, sizeof(IQMatrix), 1, &pd->iqmatrix));
235     ASSERT_NO_FAILURE(
236         VABufferID huffTableBufId = createBuffer(
237             context, VAHuffmanTableBufferType, sizeof(HuffmanTable), 1,
238             &pd->huffman));
239
240     ASSERT_NO_FAILURE(beginPicture(context, surfaces.front()));
241     ASSERT_NO_FAILURE(renderPicture(context, &picBufId));
242     ASSERT_NO_FAILURE(renderPicture(context, &iqMatrixBufId));
243     ASSERT_NO_FAILURE(renderPicture(context, &huffTableBufId));
244     ASSERT_NO_FAILURE(renderPicture(context, &sliceParamBufId));
245     ASSERT_NO_FAILURE(renderPicture(context, &sliceDataBufId));
246     ASSERT_NO_FAILURE(endPicture(context));
247
248     VAImage image;
249     ASSERT_NO_FAILURE(deriveImage(surfaces.front(), image));
250     ASSERT_NO_FAILURE(
251         uint8_t *output = mapBuffer<uint8_t>(image.buf));
252
253     unsigned rwidth = ALIGN(image.width, 128);
254     unsigned rheight =
255         ALIGN(image.height, 32)
256         + ALIGN(image.height / pd->pparam.components[0].v_sampling_factor, 32)
257         * 2;
258
259     SCOPED_TRACE(
260         ::testing::Message()
261         << std::endl
262         << "image  : " << image.width << "x" << image.height
263         << std::endl
264         << "region : " << rwidth << "x" << rheight
265         << std::endl
266         << "planes : " << image.num_planes
267         << std::endl
268         << "offsets: " << image.offsets[0] << " " << image.offsets[1] << " " << image.offsets[2]
269         << std::endl
270         << "pitches: " << image.pitches[0] << " " << image.pitches[1] << " " << image.pitches[2]
271     );
272
273     EXPECT_EQ(3u, image.num_planes);
274     EXPECT_EQ(pd->pparam.picture_width, image.width);
275     EXPECT_EQ(pd->pparam.picture_height, image.height);
276     EXPECT_EQ(rwidth * rheight, image.data_size);
277     EXPECT_EQ(pd->fourcc, image.format.fourcc);
278
279     std::ostringstream oss;
280     printImageOutputTo(oss, image, output);
281     RecordProperty("Output", oss.str());
282
283     validateImageOutput(image, output);
284
285 //     std::cout << oss.str();
286
287     unmapBuffer(image.buf);
288
289     destroyBuffer(huffTableBufId);
290     destroyBuffer(iqMatrixBufId);
291     destroyBuffer(picBufId);
292     destroyBuffer(sliceParamBufId);
293     destroyBuffer(sliceDataBufId);
294
295     destroyImage(image);
296     destroyContext(context);
297     destroyConfig(config);
298     destroySurfaces(surfaces);
299 }
300
301
302 /** Teach Google Test how to print a TestPattern::SharedConst object */
303 void PrintTo(const TestPattern::SharedConst& t, std::ostream* os)
304 {
305     *os << *t;
306 }
307
308 INSTANTIATE_TEST_CASE_P(
309     JPEG, FourCCTest,
310     ::testing::Combine(
311         ::testing::Values(
312             TestPattern::SharedConst(new TestPatternData<1>),
313             TestPattern::SharedConst(new TestPatternData<2>),
314             TestPattern::SharedConst(new TestPatternData<3>),
315             TestPattern::SharedConst(new TestPatternData<4>)
316         ),
317         ::testing::Values("IMC3", "422H", "422V", "444P", "411P"))
318 );
319
320 } // namespace Decode
321 } // namespace JPEG