If you can reproduce it again, let's track it in Bugzilla. Sean
On Thu, Oct 13, 2016 at 12:43 AM, Xiang, Haihao <[email protected]> wrote: > >> I’ve not seen any issues in multiple runs either, Haihao. I likewise >> ran them again today. No failures. >> >> What platform are you testing on? > > SKL, and I can't reproduce the issue after rebooting my SKL. Please see > my reply to Altie for more information. > > Thanks > Haihao > > > > >> Sean >> >> On 10/12/16, 12:57 PM, "Libva on behalf of Eoff, Ullysses A" <libva-b >> [email protected] on behalf of [email protected]> >> wrote: >> >> I have not seen these two (7680x4320 YUY2 and UYVY) fail before >> on my SKL... I just ran them >> both 25 times each and did not get any failures: >> >> "./test_i965_drv_video -- >> gtest_filter=Common/JPEGEncodeInputTest.Full/98 --gtest_repeat=25" >> "./test_i965_drv_video -- >> gtest_filter=Common/JPEGEncodeInputTest.Full/97 --gtest_repeat=25" >> >> What is the test failure that you are seeing? >> >> Note that the YUV input data for these tests is random... so in >> this regard, the test is different >> each time it's executed. The random YUV input data can have an >> effect on the actual size >> required for the coded buffer result. So my guess is that the >> tests could fail for one of two reasons: >> >> 1. The user allocated coded buffer is not large enough for the >> driver's encoding result (i.e. overflow occurs). >> 2. For some specific random YUV data inputs, the decoded output >> YUV result does not match. >> >> For the 7680x4320 I420 case, the test always fails due to YUV >> input/output mismatch. IIRC, the >> difference between the failing Y values are within a tolerance of >> 7 or 8. But these tests only allow >> a tolerance of 2. >> >> ---- >> U. Artie >> >> >> > -----Original Message----- >> > From: Xiang, Haihao >> > Sent: Wednesday, October 12, 2016 12:17 PM >> > To: [email protected]; Eoff, Ullysses A <[email protected] >> om>; [email protected] >> > Subject: RE: [Libva] [PATCH intel-driver v2 7/7] test: add some >> jpeg encode tests >> > >> > >> > Hi Artie, >> > >> > When I was investigating the issue with the 7680x4320 I420 >> test, I experienced random failures >> > with Common/JPEGEncodeInputTest.Full/98 and >> Common/JPEGEncodeInputTest.Full/97. I guess >> > it is caused by the test case, did you see this issue in your >> side? To reproduce the issue, you should run the case a few times. >> > >> > Thanks >> > Haihao >> > >> > >-----Original Message----- >> > >From: Libva [mailto:[email protected]] On >> Behalf Of Sean V >> > >Kelley >> > >Sent: Thursday, September 29, 2016 4:15 AM >> > >To: Eoff, Ullysses A <[email protected]>; libva@lists. >> freedesktop.org >> > >Subject: Re: [Libva] [PATCH intel-driver v2 7/7] test: add >> some jpeg encode >> > >tests >> > > >> > > >> > >On Mon, 2016-09-26 at 13:11 -0700, U. Artie Eoff wrote: >> > > >> > > Add JPEG encode tests that encode raw I420 and NV12 >> data >> > > at quality 100 and then decodes them to verify proper >> > > encoding. >> > > >> > > Currently, the 7680x4320 I420 test fails because ~40- >> 60 >> > > Y-values (i.e. plane 0) in each line from the decoded >> > > bitstream are off by more than 2 of the original raw >> > > I420 values. It is not clear why only this resolution >> > > exhibits this problem. >> > > >> > > >> > > >> > >Ah this was the one we talked about. Accepted. >> > > >> > >Sean >> > > >> > > >> > > >> > > v2: don't create any input data in test fixture if >> > > jpeg encoding is not supported. >> > > >> > > Signed-off-by: U. Artie Eoff <[email protected] >> m >> > ><mailto:[email protected]> > >> > > --- >> > > test/Makefile.am | 1 + >> > > test/i965_jpeg_encode_test.cpp | 699 >> > >+++++++++++++++++++++++++++++++++++++++++ >> > > test/i965_jpeg_test_data.h | 198 +++++++++++- >> > > test/i965_test_fixture.h | 1 + >> > > 4 files changed, 895 insertions(+), 4 deletions(-) >> > > create mode 100644 test/i965_jpeg_encode_test.cpp >> > > >> > > diff --git a/test/Makefile.am b/test/Makefile.am >> > > index 2e9edda648a4..99560f8d8a54 100644 >> > > --- a/test/Makefile.am >> > > +++ b/test/Makefile.am >> > > @@ -57,6 +57,7 @@ test_i965_drv_video_SOURCES = >> > > \ >> > > i965_jpeg_test_data.cpp >> > > \ >> > > i965_test_fixture.cpp >> > > \ >> > > i965_jpeg_decode_test.cpp >> > > \ >> > > + i965_jpeg_encode_test.cpp >> > > \ >> > > object_heap_test.cpp >> > > \ >> > > test_main.cpp >> > > \ >> > > $(NULL) >> > > diff --git a/test/i965_jpeg_encode_test.cpp >> > >b/test/i965_jpeg_encode_test.cpp >> > > new file mode 100644 >> > > index 000000000000..08d80c4f75b7 >> > > --- /dev/null >> > > +++ b/test/i965_jpeg_encode_test.cpp >> > > @@ -0,0 +1,699 @@ >> > > +/* >> > > + * Copyright (C) 2016 Intel Corporation. All Rights >> Reserved. >> > > + * >> > > + * Permission is hereby granted, free of charge, to >> any person >> > >obtaining a >> > > + * copy of this software and associated documentation >> files (the >> > > + * "Software"), to deal in the Software without >> restriction, including >> > > + * without limitation the rights to use, copy, >> modify, merge, publish, >> > > + * distribute, sub license, and/or sell copies of the >> Software, and to >> > > + * permit persons to whom the Software is furnished >> to do so, >> > >subject to >> > > + * the following conditions: >> > > + * >> > > + * The above copyright notice and this permission >> notice (including >> > >the >> > > + * next paragraph) shall be included in all copies or >> substantial >> > >portions >> > > + * of the Software. >> > > + * >> > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY >> OF >> > >ANY KIND, EXPRESS >> > > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE >> WARRANTIES >> > >OF >> > > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE >> AND >> > >NON-INFRINGEMENT. >> > > + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS >> SUPPLIERS BE >> > >LIABLE FOR >> > > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN >> AN >> > >ACTION OF CONTRACT, >> > > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN >> > >CONNECTION WITH THE >> > > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE >> SOFTWARE. >> > > + */ >> > > + >> > > +#include "i965_jpeg_test_data.h" >> > > +#include "test_utils.h" >> > > + >> > > +#include <algorithm> >> > > +#include <cstring> >> > > +#include <fstream> >> > > +#include <memory> >> > > +#include <sstream> >> > > +#include <tuple> >> > > + >> > > +namespace JPEG { >> > > +namespace Encode { >> > > + >> > > +class JPEGEncodeTest >> > > + : public I965TestFixture >> > > +{ >> > > +public: >> > > + JPEGEncodeTest() >> > > + : I965TestFixture() >> > > + , config(VA_INVALID_ID) // invalid >> > > + , context(VA_INVALID_ID) // invalid >> > > + { } >> > > + >> > > +protected: >> > > + virtual void TearDown() >> > > + { >> > > + if (context != VA_INVALID_ID) { >> > > + destroyContext(context); >> > > + context = VA_INVALID_ID; >> > > + } >> > > + >> > > + if (config != VA_INVALID_ID) { >> > > + destroyConfig(config); >> > > + config = VA_INVALID_ID; >> > > + } >> > > + >> > > + I965TestFixture::TearDown(); >> > > + } >> > > + >> > > + VAConfigID config; >> > > + VAContextID context; >> > > +}; >> > > + >> > > +TEST_F(JPEGEncodeTest, Entrypoint) >> > > +{ >> > > + ConfigAttribs attributes; >> > > + struct i965_driver_data *i965(*this); >> > > + >> > > + ASSERT_PTR(i965); >> > > + >> > > + if (HAS_JPEG_ENCODING(i965)) { >> > > + config = createConfig(profile, entrypoint, >> attributes); >> > > + } else { >> > > + VAStatus status = i965_CreateConfig( >> > > + *this, profile, entrypoint, >> attributes.data(), attributes.size(), >> > > + &config); >> > > + >> > >EXPECT_STATUS_EQ(VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT, >> > >status); >> > > + EXPECT_INVALID_ID(config); >> > > + } >> > > +} >> > > + >> > > +class TestInputCreator >> > > +{ >> > > +public: >> > > + typedef std::shared_ptr<TestInputCreator> Shared; >> > > + typedef std::shared_ptr<const TestInputCreator> >> SharedConst; >> > > + >> > > + TestInput::Shared create(const unsigned fourcc) >> const >> > > + { >> > > + const std::array<unsigned, 2> res = >> getResolution(); >> > > + >> > > + TestInput::Shared input(new TestInput(fourcc, >> res[0], res[1])); >> > > + ByteData& bytes = input->bytes; >> > > + >> > > + RandomValueGenerator<uint8_t> rg(0x00, 0xff); >> > > + for (size_t i(0); i < input->planes; ++i) >> > > + std::generate_n( >> > > + std::back_inserter(bytes), input- >> >sizes[i], >> > > + [&rg]{ return rg(); }); >> > > + return input; >> > > + } >> > > + >> > > + friend ::std::ostream& operator<<( >> > > + ::std::ostream& os, const TestInputCreator& >> t) >> > > + { >> > > + t.repr(os); >> > > + return os; >> > > + } >> > > + >> > > + friend ::std::ostream& operator<<( >> > > + ::std::ostream& os, const >> TestInputCreator::Shared& t) >> > > + { >> > > + return os << *t; >> > > + } >> > > + >> > > + friend ::std::ostream& operator<<( >> > > + ::std::ostream& os, const >> TestInputCreator::SharedConst& t) >> > > + { >> > > + return os << *t; >> > > + } >> > > + >> > > +protected: >> > > + virtual std::array<unsigned, 2> getResolution() >> const = 0; >> > > + virtual void repr(std::ostream& os) const = 0; >> > > +}; >> > > + >> > > +template <typename T> >> > > +const std::string toString(const T& t) >> > > +{ >> > > + std::ostringstream os; >> > > + os << t; >> > > + return os.str(); >> > > +} >> > > + >> > > +const TestInput::Shared NV12toI420(const >> TestInput::SharedConst& >> > >nv12) >> > > +{ >> > > + TestInput::Shared i420( >> > > + new TestInput(VA_FOURCC_I420, nv12->width(), >> nv12- >> > >>height())); >> > > + >> > > + i420->bytes = nv12->bytes; >> > > + >> > > + size_t i(0); >> > > + auto predicate = [&i](const >> ByteData::value_type&) { >> > > + bool isu = ((i % 2) == 0) or (i == 0); >> > > + ++i; >> > > + return isu; >> > > + }; >> > > + >> > > + std::stable_partition( >> > > + i420->bytes.begin() + i420->offsets[1], >> > > + i420->bytes.end(), predicate); >> > > + >> > > + return i420; >> > > +} >> > > + >> > > +#define ASSERT_NO_FAILURE(statement) \ >> > > + statement; \ >> > > + ASSERT_FALSE(HasFailure()); >> > > + >> > > +class JPEGEncodeInputTest >> > > + : public JPEGEncodeTest >> > > + , public ::testing::WithParamInterface< >> > > + std::tuple<TestInputCreator::SharedConst, >> const char*> > >> > > +{ >> > > +public: >> > > + JPEGEncodeInputTest() >> > > + : JPEGEncodeTest::JPEGEncodeTest() >> > > + , surfaces() // empty >> > > + , coded(VA_INVALID_ID) // invalid >> > > + , renderBuffers() // empty >> > > + , input() // invalid >> > > + , output() // empty >> > > + { } >> > > + >> > > +protected: >> > > + virtual void SetUp() >> > > + { >> > > + JPEGEncodeTest::SetUp(); >> > > + >> > > + struct i965_driver_data *i965(*this); >> > > + ASSERT_PTR(i965); >> > > + if (not HAS_JPEG_ENCODING(i965)) >> > > + return; >> > > + >> > > + TestInputCreator::SharedConst creator; >> > > + std::string sFourcc; >> > > + std::tie(creator, sFourcc) = GetParam(); >> > > + >> > > + ASSERT_PTR(creator.get()) << "Invalid test >> input creator >> > >parameter"; >> > > + >> > > + ASSERT_EQ(4u, sFourcc.size()) >> > > + << "Invalid fourcc parameter '" << >> sFourcc << "'"; >> > > + >> > > + unsigned fourcc = VA_FOURCC( >> > > + sFourcc[0], sFourcc[1], sFourcc[2], >> sFourcc[3]); >> > > + >> > > + input = creator->create(fourcc); >> > > + >> > > + ASSERT_PTR(input.get()) >> > > + << "Unhandled fourcc parameter '" << >> sFourcc << "'" >> > > + << " = 0x" << std::hex << fourcc << >> std::dec; >> > > + >> > > + ASSERT_EQ(fourcc, input->fourcc); >> > > + >> > > + RecordProperty("test_input", >> toString(*input)); >> > > + } >> > > + >> > > + virtual void TearDown() >> > > + { >> > > + for (auto id : renderBuffers) { >> > > + if (id != VA_INVALID_ID) { >> > > + destroyBuffer(id); >> > > + } >> > > + } >> > > + renderBuffers.clear(); >> > > + >> > > + if (coded != VA_INVALID_ID) { >> > > + destroyBuffer(coded); >> > > + coded = VA_INVALID_ID; >> > > + } >> > > + >> > > + if (not surfaces.empty()) { >> > > + destroySurfaces(surfaces); >> > > + surfaces.clear(); >> > > + } >> > > + >> > > + if (std::get<0>(GetParam()).get()) >> > > + std::cout << "Creator: " << >> std::get<0>(GetParam()) << >> > >std::endl; >> > > + if (input.get()) >> > > + std::cout << "Input : " << input << >> std::endl; >> > > + >> > > + JPEGEncodeTest::TearDown(); >> > > + } >> > > + >> > > + void Encode() >> > > + { >> > > + ASSERT_FALSE(surfaces.empty()); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + beginPicture(context, surfaces.front())); >> > > + ASSERT_NO_FAILURE( >> > > + renderPicture(context, >> renderBuffers.data(), >> > >renderBuffers.size())); >> > > + ASSERT_NO_FAILURE( >> > > + endPicture(context)); >> > > + ASSERT_NO_FAILURE( >> > > + syncSurface(surfaces.front())); >> > > + ASSERT_NO_FAILURE( >> > > + VACodedBufferSegment *segment = >> > > + mapBuffer<VACodedBufferSegment>(coded >> )); >> > > + >> > > + EXPECT_FALSE(segment->status & >> > >VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) >> > > + << "segment->size = " << segment->size; >> > > + EXPECT_PTR_NULL(segment->next); >> > > + >> > > + // copy segment buffer to output while >> stripping the packed >> > >header data >> > > + const size_t headerSize(1); >> > > + output.resize(segment->size - headerSize, >> 0x0); >> > > + std::memcpy( >> > > + output.data(), >> > > + reinterpret_cast<uint8_t *>(segment->buf) >> + headerSize, >> > > + segment->size - headerSize); >> > > + >> > > + unmapBuffer(coded); >> > > + >> > > + // EOI JPEG Marker >> > > + ASSERT_GE(output.size(), 2u); >> > > + EXPECT_TRUE( >> > > + unsigned(0xff) == unsigned(*(output.end() >> - 2)) and >> > > + unsigned(0xd9) == >> unsigned(output.back())) >> > > + << "Invalid JPEG EOI Marker"; >> > > + } >> > > + >> > > + void SetUpSurfaces() >> > > + { >> > > + SurfaceAttribs attributes(1); >> > > + attributes.front().flags = >> VA_SURFACE_ATTRIB_SETTABLE; >> > > + attributes.front().type = >> VASurfaceAttribPixelFormat; >> > > + attributes.front().value.type = >> VAGenericValueTypeInteger; >> > > + attributes.front().value.value.i = input- >> >fourcc; >> > > + surfaces = createSurfaces(input->width(), >> input->height(), >> > > + input->format, 1, attributes); >> > > + } >> > > + >> > > + void CopyInputToSurface() >> > > + { >> > > + ASSERT_FALSE(surfaces.empty()); >> > > + >> > > + VAImage image; >> > > + deriveImage(surfaces.front(), image); >> > > + if (HasFailure()) >> > > + return; >> > > + >> > > + SCOPED_TRACE(::testing::Message() << >> std::endl << image); >> > > + >> > > + RecordProperty("input_image", >> toString(image)); >> > > + >> > > + EXPECT_EQ(input->planes, image.num_planes); >> > > + EXPECT_GT(image.data_size, 0u); >> > > + EXPECT_EQ(input->width(), image.width); >> > > + EXPECT_EQ(input->height(), image.height); >> > > + if (HasFailure()) { >> > > + unmapBuffer(image.buf); >> > > + destroyImage(image); >> > > + return; >> > > + } >> > > + >> > > + uint8_t *data = >> mapBuffer<uint8_t>(image.buf); >> > > + if (HasFailure()) { >> > > + destroyImage(image); >> > > + return; >> > > + } >> > > + >> > > + std::memset(data, 0, image.data_size); >> > > + >> > > + for (size_t i(0); i < image.num_planes; ++i) >> { >> > > + size_t w = input->widths[i]; >> > > + size_t h = input->heights[i]; >> > > + >> > > + EXPECT_GE(image.pitches[i], w); >> > > + if (HasFailure()) >> > > + break; >> > > + >> > > + const ByteData::value_type *source = >> input->plane(i); >> > > + uint8_t *dest = data + image.offsets[i]; >> > > + for (size_t r(0); r < h; ++r) { >> > > + std::memcpy(dest, source, w); >> > > + source += w; >> > > + dest += image.pitches[i]; >> > > + } >> > > + } >> > > + >> > > + unmapBuffer(image.buf); >> > > + destroyImage(image); >> > > + } >> > > + >> > > + void SetUpConfig() >> > > + { >> > > + ASSERT_INVALID_ID(config); >> > > + ConfigAttribs attributes( >> > > + 1, {type:VAConfigAttribRTFormat, >> value:input->format}); >> > > + config = createConfig(profile, entrypoint, >> attributes); >> > > + } >> > > + >> > > + void SetUpContext() >> > > + { >> > > + ASSERT_INVALID_ID(context); >> > > + context = createContext(config, input- >> >width(), >> > > + input->height(), 0, surfaces); >> > > + } >> > > + >> > > + void SetUpCodedBuffer() >> > > + { >> > > + ASSERT_INVALID_ID(coded); >> > > + unsigned size = >> > > + std::accumulate(input->sizes.begin(), >> input->sizes.end(), >> > >8192u); >> > > + size *= input->planes; >> > > + coded = createBuffer(context, >> VAEncCodedBufferType, size); >> > > + } >> > > + >> > > + void SetUpPicture() >> > > + { >> > > + input->picture.coded_buf = coded; >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> VAEncPictureParameterBufferType, >> > > + sizeof(PictureParameter), 1, &input- >> >picture)); >> > > + } >> > > + >> > > + void SetUpIQMatrix() >> > > + { >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> VAQMatrixBufferType, sizeof(IQMatrix), >> > > + 1, &input->matrix)); >> > > + } >> > > + >> > > + void SetUpHuffmanTables() >> > > + { >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> VAHuffmanTableBufferType, >> > > + sizeof(HuffmanTable), 1, &input- >> >huffman)); >> > > + } >> > > + >> > > + void SetUpSlice() >> > > + { >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> VAEncSliceParameterBufferType, >> > > + sizeof(SliceParameter), 1, &input- >> >slice)); >> > > + } >> > > + >> > > + void SetUpHeader() >> > > + { >> > > + /* >> > > + * The driver expects a packed JPEG header >> which it prepends to >> > >the >> > > + * coded buffer segment output. The driver >> does not appear to >> > >inspect >> > > + * this header, however. So we'll just >> create a 1-byte packed >> > >header >> > > + * since we really don't care if it contains >> a "valid" JPEG header. >> > > + */ >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> > >VAEncPackedHeaderParameterBufferType, >> > > + sizeof(VAEncPackedHeaderParameterBuff >> er))); >> > > + if (HasFailure()) >> > > + return; >> > > + >> > > + VAEncPackedHeaderParameterBuffer *packed = >> > > + >> > >> >mapBuffer<VAEncPackedHeaderParameterBuffer>(renderBuffers.back()); >> > > + if (HasFailure()) >> > > + return; >> > > + >> > > + std::memset(packed, 0, sizeof(*packed)); >> > > + packed->type = VAEncPackedHeaderRawData; >> > > + packed->bit_length = 8; >> > > + packed->has_emulation_bytes = 0; >> > > + >> > > + unmapBuffer(renderBuffers.back()); >> > > + >> > > + renderBuffers.push_back( >> > > + createBuffer(context, >> VAEncPackedHeaderDataBufferType, >> > >1)); >> > > + } >> > > + >> > > + Surfaces surfaces; >> > > + VABufferID coded; >> > > + Buffers renderBuffers; >> > > + TestInput::Shared input; >> > > + ByteData output; >> > > + >> > > + void VerifyOutput() >> > > + { >> > > + // VerifyOutput only supports VA_FOURCC_IMC3 >> output, >> > >currently >> > > + ASSERT_EQ(unsigned(VA_FOURCC_IMC3), input- >> > >>fourcc_output); >> > > + TestInput::SharedConst expect = input; >> > > + if (input->fourcc == VA_FOURCC_NV12) >> > > + expect = NV12toI420(input); >> > > + >> > > + ::JPEG::Decode::PictureData::SharedConst pd = >> > > + ::JPEG::Decode::PictureData::make( >> > > + input->fourcc_output, output, input- >> >width(), input- >> > >>height()); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + Surfaces osurfaces = createSurfaces( >> > > + pd->pparam.picture_width, pd- >> >pparam.picture_height, >> > > + pd->format));; >> > > + >> > > + ConfigAttribs attribs( >> > > + 1, {type:VAConfigAttribRTFormat, >> value:pd->format}); >> > > + ASSERT_NO_FAILURE( >> > > + VAConfigID oconfig = createConfig( >> > > + ::JPEG::profile, >> ::JPEG::Decode::entrypoint, attribs)); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + VAContextID ocontext = createContext( >> > > + oconfig, pd->pparam.picture_width, >> pd- >> > >>pparam.picture_height, >> > > + 0, osurfaces)); >> > > + >> > > + Buffers buffers; >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + buffers.push_back( >> > > + createBuffer( >> > > + ocontext, VASliceDataBufferType, >> pd- >> > >>sparam.slice_data_size, >> > > + 1, pd->slice.data()))); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + buffers.push_back( >> > > + createBuffer( >> > > + ocontext, >> VASliceParameterBufferType, sizeof(pd- >> > >>sparam), >> > > + 1, &pd->sparam))); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + buffers.push_back( >> > > + createBuffer( >> > > + ocontext,VAPictureParameterBuffer >> Type, sizeof(pd- >> > >>pparam), >> > > + 1, &pd->pparam))); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + buffers.push_back( >> > > + createBuffer( >> > > + ocontext, VAIQMatrixBufferType, >> sizeof(pd->iqmatrix), >> > > + 1, &pd->iqmatrix))); >> > > + >> > > + ASSERT_NO_FAILURE( >> > > + buffers.push_back( >> > > + createBuffer( >> > > + ocontext, >> VAHuffmanTableBufferType, sizeof(pd- >> > >>huffman), >> > > + 1, &pd->huffman))); >> > > + >> > > + ASSERT_NO_FAILURE(beginPicture(ocontext, >> osurfaces.front())); >> > > + ASSERT_NO_FAILURE( >> > > + renderPicture(ocontext, buffers.data(), >> buffers.size())); >> > > + ASSERT_NO_FAILURE(endPicture(ocontext)); >> > > + ASSERT_NO_FAILURE(syncSurface(osurfaces.front >> ())); >> > > + >> > > + VAImage image; >> > > + ASSERT_NO_FAILURE(deriveImage(osurfaces.front >> (), image)); >> > > + ASSERT_NO_FAILURE(uint8_t *data = >> > >mapBuffer<uint8_t>(image.buf)); >> > > + >> > > + auto isClose = [](const uint8_t& a, const >> uint8_t& b) { >> > > + return std::abs(int(a)-int(b)) <= 2; >> > > + }; >> > > + >> > > + for (size_t i(0); i < image.num_planes; ++i) >> { >> > > + size_t w = expect->widths[i]; >> > > + size_t h = expect->heights[i]; >> > > + >> > > + const ByteData::value_type *source = >> expect->plane(i); >> > > + const uint8_t *result = data + >> image.offsets[i]; >> > > + ASSERT_GE(image.pitches[i], w); >> > > + for (size_t r(0); r < h; ++r) { >> > > + EXPECT_TRUE(std::equal(result, result >> + w, source, isClose)) >> > > + << "Byte(s) mismatch in plane " >> << i << " row " << r; >> > > + source += w; >> > > + result += image.pitches[i]; >> > > + } >> > > + } >> > > + >> > > + unmapBuffer(image.buf); >> > > + >> > > + for (auto id : buffers) >> > > + destroyBuffer(id); >> > > + >> > > + destroyImage(image); >> > > + destroyContext(ocontext); >> > > + destroyConfig(oconfig); >> > > + destroySurfaces(osurfaces); >> > > + } >> > > +}; >> > > + >> > > +TEST_P(JPEGEncodeInputTest, Full) >> > > +{ >> > > + struct i965_driver_data *i965(*this); >> > > + ASSERT_PTR(i965); >> > > + if (not HAS_JPEG_ENCODING(i965)) { >> > > + RecordProperty("skipped", true); >> > > + std::cout << "[ SKIPPED ] " << >> getFullTestName() >> > > + << " is unsupported on this hardware" << >> std::endl; >> > > + return; >> > > + } >> > > + >> > > + ASSERT_NO_FAILURE(SetUpSurfaces()); >> > > + ASSERT_NO_FAILURE(SetUpConfig()); >> > > + ASSERT_NO_FAILURE(SetUpContext()); >> > > + ASSERT_NO_FAILURE(SetUpCodedBuffer()); >> > > + ASSERT_NO_FAILURE(SetUpPicture()); >> > > + ASSERT_NO_FAILURE(SetUpIQMatrix()); >> > > + ASSERT_NO_FAILURE(SetUpHuffmanTables()); >> > > + ASSERT_NO_FAILURE(SetUpSlice()); >> > > + ASSERT_NO_FAILURE(SetUpHeader()); >> > > + ASSERT_NO_FAILURE(CopyInputToSurface()); >> > > + ASSERT_NO_FAILURE(Encode()); >> > > + >> > > + VerifyOutput(); >> > > +} >> > > + >> > > +class RandomSizeCreator >> > > + : public TestInputCreator >> > > +{ >> > > +protected: >> > > + std::array<unsigned, 2> getResolution() const >> > > + { >> > > + static RandomValueGenerator<unsigned> rg(1, >> 769); >> > > + return {rg(), rg()}; >> > > + } >> > > + void repr(std::ostream& os) const { os << "Random >> Size"; } >> > > +}; >> > > + >> > > +INSTANTIATE_TEST_CASE_P( >> > > + Random, JPEGEncodeInputTest, >> > > + ::testing::Combine( >> > > + ::testing::ValuesIn( >> > > + std::vector<TestInputCreator::SharedConst >> >( >> > > + 5, TestInputCreator::SharedConst(new >> > >RandomSizeCreator))), >> > > + ::testing::Values("I420", "NV12") >> > > + ) >> > > +); >> > > + >> > > +class FixedSizeCreator >> > > + : public TestInputCreator >> > > +{ >> > > +public: >> > > + FixedSizeCreator(const std::array<unsigned, 2>& >> resolution) >> > > + : res(resolution) >> > > + { } >> > > + >> > > +protected: >> > > + std::array<unsigned, 2> getResolution() const { >> return res; } >> > > + void repr(std::ostream& os) const >> > > + { >> > > + os << "Fixed Size " << res[0] << "x" << >> res[1]; >> > > + } >> > > + >> > > +private: >> > > + const std::array<unsigned, 2> res; >> > > +}; >> > > + >> > > +typedef std::vector<TestInputCreator::SharedConst> >> InputCreators; >> > > + >> > > +InputCreators generateCommonInputs() >> > > +{ >> > > + return { >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({800, 600})), /* >> > >SVGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1024, 600})), /* >> > >WSVGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1024, 768})), /* >> > >XGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1152, 864})), /* >> > >XGA+ */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1280, 720})), /* >> > >WXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1280, 768})), /* >> > >WXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1280, 800})), /* >> > >WXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1280, 1024})), >> > >/* SXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1360, 768})), /* >> > >HD */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1366, 768})), /* >> > >HD */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1440, 900})), /* >> > >WXGA+ */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1600, 900})), /* >> > >HD+ */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1600, 1200})), >> > >/* UXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1680, 1050})), >> > >/* WSXGA+ */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1920, 1080})), >> > >/* FHD */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1920, 1200})), >> > >/* WUXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({2560, 1440})), >> > >/* WQHD */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({2560, 1600})), >> > >/* WQXGA */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({3640, 2160})), >> > >/* UHD (4K) */ >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({7680, 4320})), >> > >/* UHD (8K) */ >> > > + }; >> > > +} >> > > + >> > > +INSTANTIATE_TEST_CASE_P( >> > > + Common, JPEGEncodeInputTest, >> > > + ::testing::Combine( >> > > + ::testing::ValuesIn(generateCommonInputs()), >> > > + ::testing::Values("I420", "NV12") >> > > + ) >> > > +); >> > > + >> > > +INSTANTIATE_TEST_CASE_P( >> > > + Big, JPEGEncodeInputTest, >> > > + ::testing::Combine( >> > > + ::testing::Values( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({8192, 8192})) >> > > + ), >> > > + ::testing::Values("I420", "NV12") >> > > + ) >> > > +); >> > > + >> > > +InputCreators generateEdgeCaseInputs() >> > > +{ >> > > + std::vector<TestInputCreator::SharedConst> >> result; >> > > + for (unsigned i(64); i <= 512; i += 64) { >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i, i}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i+1, i}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i, i+1}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i+1, i+1}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i-1, i}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i, i-1}))); >> > > + result.push_back( >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({i-1, i-1}))); >> > > + } >> > > + >> > > + result.push_back(TestInputCreator::Shared(new >> > >FixedSizeCreator({1, 1}))); >> > > + result.push_back(TestInputCreator::Shared(new >> > >FixedSizeCreator({1, 2}))); >> > > + result.push_back(TestInputCreator::Shared(new >> > >FixedSizeCreator({2, 1}))); >> > > + result.push_back(TestInputCreator::Shared(new >> > >FixedSizeCreator({2, 2}))); >> > > + result.push_back(TestInputCreator::Shared(new >> > >FixedSizeCreator({1, 462}))); >> > > + >> > > + return result; >> > > +} >> > > + >> > > +INSTANTIATE_TEST_CASE_P( >> > > + Edge, JPEGEncodeInputTest, >> > > + ::testing::Combine( >> > > + ::testing::ValuesIn(generateEdgeCaseInputs()) >> , >> > > + ::testing::Values("I420", "NV12") >> > > + ) >> > > +); >> > > + >> > > +InputCreators generateMiscInputs() >> > > +{ >> > > + return { >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({150, 75})), >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({10, 10})), >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({385, 610})), >> > > + TestInputCreator::Shared(new >> FixedSizeCreator({1245, 1281})), >> > > + }; >> > > +} >> > > + >> > > +INSTANTIATE_TEST_CASE_P( >> > > + Misc, JPEGEncodeInputTest, >> > > + ::testing::Combine( >> > > + ::testing::ValuesIn(generateMiscInputs()), >> > > + ::testing::Values("I420", "NV12") >> > > + ) >> > > +); >> > > + >> > > +} // namespace Encode >> > > +} // namespace JPEG >> > > diff --git a/test/i965_jpeg_test_data.h >> b/test/i965_jpeg_test_data.h >> > > index d52f58233cc5..490ec941feb5 100644 >> > > --- a/test/i965_jpeg_test_data.h >> > > +++ b/test/i965_jpeg_test_data.h >> > > @@ -25,6 +25,8 @@ >> > > #ifndef I965_JPEG_TEST_DATA_H >> > > #define I965_JPEG_TEST_DATA_H >> > > >> > > +#include "i965_test_fixture.h" >> > > + >> > > #include <array> >> > > #include <iostream> >> > > #include <map> >> > > @@ -183,6 +185,18 @@ namespace Decode { >> > > const HuffmanTable& huffman = >> defaultHuffmanTable, >> > > const IQMatrix& iqmatrix = >> defaultIQMatrix) >> > > { >> > > + return make(fourcc, slice, W, H, sparam, >> pparam, huffman, >> > >iqmatrix); >> > > + } >> > > + >> > > + static SharedConst make( >> > > + const unsigned fourcc, >> > > + const ByteData& slice, >> > > + const unsigned w, const unsigned h, >> > > + const SliceParameter& sparam = >> defaultSliceParameter, >> > > + const PictureParameter& pparam = >> defaultPictureParameter, >> > > + const HuffmanTable& huffman = >> defaultHuffmanTable, >> > > + const IQMatrix& iqmatrix = >> defaultIQMatrix) >> > > + { >> > > Shared pd( >> > > new PictureData { >> > > slice: slice, >> > > @@ -196,8 +210,8 @@ namespace Decode { >> > > ); >> > > >> > > pd->sparam.slice_data_size = >> slice.size(); >> > > - pd->pparam.picture_width = W; >> > > - pd->pparam.picture_height = H; >> > > + pd->pparam.picture_width = w; >> > > + pd->pparam.picture_height = h; >> > > >> > > switch(fourcc) >> > > { >> > > @@ -232,8 +246,8 @@ namespace Decode { >> > > /* Calculate num_mcus */ >> > > int hfactor = pd- >> >pparam.components[0].h_sampling_factor << >> > >3; >> > > int vfactor = pd- >> >pparam.components[0].v_sampling_factor << >> > >3; >> > > - int wmcu = (W + hfactor - 1) / hfactor; >> > > - int hmcu = (H + vfactor - 1) / vfactor; >> > > + int wmcu = (w + hfactor - 1) / hfactor; >> > > + int hmcu = (h + vfactor - 1) / vfactor; >> > > pd->sparam.num_mcus = wmcu * hmcu; >> > > >> > > return pd; >> > > @@ -321,4 +335,180 @@ namespace Decode { >> > > } // namespace Decode >> > > } // namespace JPEG >> > > >> > > +namespace JPEG { >> > > +namespace Encode { >> > > + typedef >> VAQMatrixBufferJPEG IQMatrix; >> > > + typedef >> VAHuffmanTableBufferJPEGBaseline HuffmanTable; >> > > + typedef >> VAEncPictureParameterBufferJPEG PictureParameter; >> > > + typedef >> VAEncSliceParameterBufferJPEG SliceParameter; >> > > + >> > > + static const VAEntrypoint entrypoint = >> VAEntrypointEncPicture; >> > > + >> > > + static const IQMatrix defaultIQMatrix = { /* >> Quality 50 */ >> > > + load_lum_quantiser_matrix: 1, >> > > + load_chroma_quantiser_matrix: 1, >> > > + lum_quantiser_matrix: { >> > > + 0x10,0x0b,0x0c,0x0e,0x0c,0x0a,0x10,0x0e, >> > > + 0x0d,0x0e,0x12,0x11,0x10,0x13,0x18,0x28, >> > > + 0x1a,0x18,0x16,0x16,0x18,0x31,0x23,0x25, >> > > + 0x1d,0x28,0x3a,0x33,0x3d,0x3c,0x39,0x33, >> > > + 0x38,0x37,0x40,0x48,0x5c,0x4e,0x40,0x44, >> > > + 0x57,0x45,0x37,0x38,0x50,0x6d,0x51,0x57, >> > > + 0x5f,0x62,0x67,0x68,0x67,0x3e,0x4d,0x71, >> > > + 0x79,0x70,0x64,0x78,0x5c,0x65,0x67,0x63, >> > > + }, >> > > + chroma_quantiser_matrix: { >> > > + 0x11,0x12,0x12,0x18,0x15,0x18,0x2f,0x1a, >> > > + 0x1a,0x2f,0x63,0x42,0x38,0x42,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, >> > > + }, >> > > + }; >> > > + >> > > + static const HuffmanTable defaultHuffmanTable = >> > > + ::JPEG::Decode::defaultHuffmanTable; >> > > + >> > > + static const PictureParameter >> defaultPictureParameter = { >> > > + reconstructed_picture: VA_INVALID_ID, >> > > + picture_width: 10, >> > > + picture_height: 10, >> > > + coded_buf: VA_INVALID_ID, >> > > + pic_flags: {value: 0x00100}, >> > > + sample_bit_depth: 8, >> > > + num_scan: 1, >> > > + num_components: 3, >> > > + component_id: {0, 1, 2, 0}, >> > > + quantiser_table_selector: {0, 1, 1, 0}, >> > > + quality: 100, >> > > + }; >> > > + >> > > + static const SliceParameter defaultSliceParameter >> = { >> > > + restart_interval: 0, >> > > + num_components: 3, >> > > + /* component_selector, dc_table_selector, >> ac_table_selector */ >> > > + components: {{1,0,0},{2,1,1},{3,1,1}} >> , >> > > + }; >> > > + >> > > + class TestInput >> > > + { >> > > + public: >> > > + typedef std::shared_ptr<TestInput> Shared; >> > > + typedef std::shared_ptr<TestInput> >> SharedConst; >> > > + >> > > + TestInput(const unsigned fourcc, const >> unsigned w, const >> > >unsigned h) >> > > + : bytes() // caller must fill this in >> after instantiation >> > > + , picture(defaultPictureParameter) >> > > + , matrix(defaultIQMatrix) >> > > + , huffman(defaultHuffmanTable) >> > > + , slice(defaultSliceParameter) >> > > + , fourcc(fourcc) >> > > + , fourcc_output(fourcc) >> > > + , format(0) >> > > + , planes(0) >> > > + , widths{0,0,0} >> > > + , heights{0,0,0} >> > > + , offsets{0,0,0} >> > > + , sizes{0,0,0} >> > > + { >> > > + picture.picture_width = ALIGN(w,2); >> > > + picture.picture_height = ALIGN(h,2); >> > > + >> > > + switch(fourcc) { >> > > + case VA_FOURCC('I', '4', '2', '0'): >> > > + planes = 3; >> > > + widths = { >> > > + w +( w & 1), >> > > + (w + 1) >> 1, >> > > + (w + 1) >> 1 >> > > + }; >> > > + heights = { >> > > + h + (h & 1), >> > > + (h + 1) >> 1, >> > > + (h + 1) >> 1 >> > > + }; >> > > + format = VA_RT_FORMAT_YUV420; >> > > + fourcc_output = VA_FOURCC_IMC3; >> > > + break; >> > > + case VA_FOURCC_NV12: >> > > + planes = 2; >> > > + widths = { >> > > + w + (w & 1), >> > > + w + (w & 1), >> > > + 0 >> > > + }; >> > > + heights = { >> > > + h + (h & 1), >> > > + (h + 1) >> 1, >> > > + 0 >> > > + }; >> > > + format = VA_RT_FORMAT_YUV420; >> > > + fourcc_output = VA_FOURCC_IMC3; >> > > + break; >> > > + default: >> > > + return; >> > > + } >> > > + >> > > + for (size_t i(0); i < planes; ++i) { >> > > + sizes[i] = widths[i] * heights[i]; >> > > + } >> > > + >> > > + for (size_t i(1); i < planes; ++i) { >> > > + offsets[i] = sizes[i - 1]; >> > > + offsets[i] += offsets[i - 1]; >> > > + } >> > > + } >> > > + >> > > + const unsigned width() const >> > > + { >> > > + return picture.picture_width; >> > > + } >> > > + >> > > + const unsigned height() const >> > > + { >> > > + return picture.picture_height; >> > > + } >> > > + >> > > + const uint8_t* plane(const size_t i) const >> > > + { >> > > + return bytes.data() + offsets[i]; >> > > + } >> > > + >> > > + friend ::std::ostream& >> operator<<(::std::ostream& os, const >> > >TestInput& t) >> > > + { >> > > + return os >> > > + << std::string((char*)(&t.fourcc), 4) >> > > + << " " << t.width() << "x" << >> t.height() >> > > + << " " << t.widths << " " << >> t.heights >> > > + << " " << t.sizes << " " << t.offsets >> > > + ; >> > > + } >> > > + >> > > + friend ::std::ostream& >> operator<<(::std::ostream& os, const >> > >Shared& t) >> > > + { >> > > + return os << *t; >> > > + } >> > > + >> > > + ByteData bytes; >> > > + PictureParameter picture; >> > > + IQMatrix matrix; >> > > + HuffmanTable huffman; >> > > + SliceParameter slice; >> > > + unsigned fourcc; >> > > + unsigned fourcc_output; >> > > + unsigned format; >> > > + size_t planes; >> > > + std::array<size_t, 3> widths; >> > > + std::array<size_t, 3> heights; >> > > + std::array<size_t, 3> offsets; >> > > + std::array<size_t, 3> sizes; >> > > + }; >> > > + >> > > + >> > > +} // namespace Encode >> > > +} // namespace JPEG >> > > + >> > > #endif >> > > diff --git a/test/i965_test_fixture.h >> b/test/i965_test_fixture.h >> > > index 54d85d223789..c805b359e19f 100644 >> > > --- a/test/i965_test_fixture.h >> > > +++ b/test/i965_test_fixture.h >> > > @@ -35,6 +35,7 @@ >> > > typedef std::vector<VASurfaceID> Surfaces; >> > > typedef std::vector<VASurfaceAttrib> SurfaceAttribs; >> > > typedef std::vector<VAConfigAttrib> ConfigAttribs; >> > > +typedef std::vector<VABufferID> Buffers; >> > > >> > > /** >> > > * This test fixture handles initialization and >> termination of the i965 >> > >driver >> > > >> >> _______________________________________________ >> Libva mailing list >> [email protected] >> https://lists.freedesktop.org/mailman/listinfo/libva >> >> -- Sean V. Kelley <[email protected]> Open Source Technology Center / SSG Intel Corp. _______________________________________________ Libva mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libva
