2 * Copyright (C) 2016 Intel Corporation. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 #include "i965_test_fixture.h"
26 #include "i965_jpeg_test_data.h"
39 class JPEGDecodeTest : public I965TestFixture { };
42 : public JPEGDecodeTest
43 , public ::testing::WithParamInterface<
44 std::tuple<TestPattern::SharedConst, const char*> >
49 JPEGDecodeTest::SetUp();
52 std::tie(testPattern, sFourcc) = GetParam();
54 ASSERT_PTR(testPattern.get()) << "Invalid test pattern parameter";
56 ASSERT_EQ(4u, sFourcc.size())
57 << "Invalid fourcc parameter '" << sFourcc << "'";
59 unsigned fourcc = VA_FOURCC(
60 sFourcc[0], sFourcc[1], sFourcc[2], sFourcc[3]);
62 pd = testPattern->encoded(fourcc);
65 << "Unhandled fourcc parameter '" << sFourcc << "'"
66 << " = 0x" << std::hex << fourcc << std::dec;
68 ASSERT_EQ(fourcc, pd->fourcc);
71 void validateComponent(const uint8_t * const expect, const uint8_t * actual,
72 unsigned width, unsigned height, unsigned pitch, unsigned hsample = 1,
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);
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]);
89 std::accumulate(samples.begin(), samples.end(), 0x00)
92 const uint8_t aVal = actual[aIdx];
95 ::testing::Message() << std::endl
96 << "\tRow = " << row << std::endl
97 << "\tColumn = " << col << std::endl
99 << std::hex << std::setfill('0') << std::setw(2)
100 << (uint32_t)eVal << std::endl
102 << std::hex << std::setfill('0') << std::setw(2)
103 << (uint32_t)aVal << std::dec);
105 EXPECT_NEAR(eVal, aVal, 0x02);
110 void validateImageOutput(const VAImage& image, const uint8_t * const output)
113 SCOPED_TRACE("Y Component\n");
115 testPattern->decoded().data(), output + image.offsets[0],
116 image.width, image.height, image.pitches[0]);
120 SCOPED_TRACE("U Component\n");
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);
129 SCOPED_TRACE("V Component\n");
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);
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)
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] << ",";
151 os << std::setw(0) << std::setfill(' ') << std::dec << std::endl;
154 void printImageOutputTo(std::ostream& os, const VAImage& image,
155 const uint8_t * const output)
157 printComponentDataTo(os, output + image.offsets[0], image.width,
158 image.height, image.pitches[0]); // Y
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
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
171 TestPattern::SharedConst testPattern;
172 PictureData::SharedConst pd;
175 TEST_P(FourCCTest, Decode)
177 struct i965_driver_data *i965(*this);
179 if (not HAS_JPEG_DECODING(i965)) {
180 RecordProperty("skipped", true);
181 std::cout << "[ SKIPPED ] " << getFullTestName()
182 << " is unsupported on this hardware" << std::endl;
186 VAConfigAttrib a = { type:VAConfigAttribRTFormat, value:pd->format };
187 ConfigAttribs attribs(1, a);
190 Surfaces surfaces = createSurfaces(
191 pd->pparam.picture_width, pd->pparam.picture_height, pd->format));
193 VAConfigID config = createConfig(profile, entrypoint, attribs));
195 VAContextID context = createContext(
196 config, pd->pparam.picture_width, pd->pparam.picture_height, 0,
199 VABufferID sliceDataBufId = createBuffer(
200 context, VASliceDataBufferType, pd->sparam.slice_data_size, 1,
203 VABufferID sliceParamBufId = createBuffer(
204 context, VASliceParameterBufferType, sizeof(pd->sparam), 1,
207 VABufferID picBufId = createBuffer(
208 context, VAPictureParameterBufferType, sizeof(pd->pparam), 1,
211 VABufferID iqMatrixBufId = createBuffer(
212 context, VAIQMatrixBufferType, sizeof(IQMatrix), 1, &pd->iqmatrix));
214 VABufferID huffTableBufId = createBuffer(
215 context, VAHuffmanTableBufferType, sizeof(HuffmanTable), 1,
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));
227 ASSERT_NO_FAILURE(deriveImage(surfaces.front(), image));
229 uint8_t *output = mapBuffer<uint8_t>(image.buf));
231 unsigned rwidth = ALIGN(image.width, 128);
233 ALIGN(image.height, 32)
234 + ALIGN(image.height / pd->pparam.components[0].v_sampling_factor, 32)
240 << "image : " << image.width << "x" << image.height
242 << "region : " << rwidth << "x" << rheight
244 << "planes : " << image.num_planes
246 << "offsets: " << image.offsets[0] << " " << image.offsets[1] << " " << image.offsets[2]
248 << "pitches: " << image.pitches[0] << " " << image.pitches[1] << " " << image.pitches[2]
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);
257 std::ostringstream oss;
258 printImageOutputTo(oss, image, output);
259 RecordProperty("Output", oss.str());
261 validateImageOutput(image, output);
263 // std::cout << oss.str();
265 unmapBuffer(image.buf);
267 destroyBuffer(huffTableBufId);
268 destroyBuffer(iqMatrixBufId);
269 destroyBuffer(picBufId);
270 destroyBuffer(sliceParamBufId);
271 destroyBuffer(sliceDataBufId);
274 destroyContext(context);
275 destroyConfig(config);
276 destroySurfaces(surfaces);
280 /** Teach Google Test how to print a TestPattern::SharedConst object */
281 void PrintTo(const TestPattern::SharedConst& t, std::ostream* os)
286 INSTANTIATE_TEST_CASE_P(
290 TestPattern::SharedConst(new TestPatternData<1>),
291 TestPattern::SharedConst(new TestPatternData<2>),
292 TestPattern::SharedConst(new TestPatternData<3>),
293 TestPattern::SharedConst(new TestPatternData<4>)
295 ::testing::Values("IMC3", "422H", "422V", "444P", "411P"))
298 } // namespace Decode