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]>; [email protected] >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] ><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(VAEncPackedHeaderParameterBuffer))); > + 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,VAPictureParameterBufferType, 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
