[Libva] [PATCH intel-driver v2 7/7] test: add some jpeg encode tests
Zhao Yakui
yakui.zhao at intel.com
Tue Sep 27 01:46:22 UTC 2016
On 09/27/2016 04:11 AM, 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.
>
> v2: don't create any input data in test fixture if
> jpeg encoding is not supported.
This looks good to me.
Add: Reviewed-by: Zhao Yakui <yakui.zhao at intel.com>
Thanks
>
> Signed-off-by: U. Artie Eoff<ullysses.a.eoff at intel.com>
> ---
> 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
More information about the Libva
mailing list