From 77ff763fa44c36d3154ee9267e9eb940dd4c10fc Mon Sep 17 00:00:00 2001 From: "U. Artie Eoff" Date: Wed, 26 Oct 2016 13:24:19 -0700 Subject: test: use YUVImage in JPEG encode tests The YUVImage class allows for more efficient (faster) operations on the YUV input/output of these tests. Signed-off-by: U. Artie Eoff Reviewed-by: Sean V Kelley --- test/i965_jpeg_encode_test.cpp | 135 +++++++++++----------------- test/i965_jpeg_test_data.cpp | 196 +++++++---------------------------------- test/i965_jpeg_test_data.h | 26 +----- 3 files changed, 86 insertions(+), 271 deletions(-) (limited to 'test') diff --git a/test/i965_jpeg_encode_test.cpp b/test/i965_jpeg_encode_test.cpp index 173cd93..d57aa67 100644 --- a/test/i965_jpeg_encode_test.cpp +++ b/test/i965_jpeg_encode_test.cpp @@ -25,6 +25,7 @@ #include "i965_jpeg_test_data.h" #include "i965_streamable.h" #include "i965_test_fixture.h" +#include "test_utils.h" #include #include @@ -108,7 +109,7 @@ protected: << "Unhandled fourcc parameter '" << sFourcc << "'" << " = 0x" << std::hex << fourcc << std::dec; - ASSERT_EQ(fourcc, input->fourcc); + ASSERT_EQ(fourcc, input->image->fourcc); RecordProperty("test_input", toString(*input)); } @@ -184,83 +185,35 @@ protected: 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; + attributes.front().value.value.i = input->image->fourcc; + surfaces = createSurfaces(input->image->width, input->image->height, + input->image->format, 1, attributes); - SCOPED_TRACE(::testing::Message() << std::endl << image); + ASSERT_EQ(1u, surfaces.size()); + ASSERT_ID(surfaces.front()); - 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(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); + input->image->toSurface(surfaces.front()); } void SetUpConfig() { ASSERT_INVALID_ID(config); ConfigAttribs attributes( - 1, {type:VAConfigAttribRTFormat, value:input->format}); + 1, {type:VAConfigAttribRTFormat, value:input->image->format}); config = createConfig(profile, entrypoint, attributes); } void SetUpContext() { ASSERT_INVALID_ID(context); - context = createContext(config, input->width(), - input->height(), 0, surfaces); + context = createContext(config, input->image->width, + input->image->height, 0, surfaces); } void SetUpCodedBuffer() { ASSERT_INVALID_ID(coded); - unsigned size = - std::accumulate(input->sizes.begin(), input->sizes.end(), 8192u); + unsigned size = input->image->sizes.sum() + 8192u; size *= 2; coded = createBuffer(context, VAEncCodedBufferType, size); } @@ -332,12 +285,14 @@ protected: void VerifyOutput() { - TestInput::SharedConst expect = input->toOutputFourcc(); + YUVImage::SharedConst expect = input->toExpectedOutput(); ASSERT_PTR(expect.get()); ::JPEG::Decode::PictureData::SharedConst pd = ::JPEG::Decode::PictureData::make( - input->fourcc_output, output, input->width(), input->height()); + expect->fourcc, output, expect->width, expect->height); + + ASSERT_PTR(pd.get()); ASSERT_NO_FAILURE( Surfaces osurfaces = createSurfaces( @@ -393,35 +348,44 @@ protected: ASSERT_NO_FAILURE(endPicture(ocontext)); ASSERT_NO_FAILURE(syncSurface(osurfaces.front())); - VAImage image; - ASSERT_NO_FAILURE(deriveImage(osurfaces.front(), image)); - ASSERT_EQ(expect->planes, image.num_planes); - ASSERT_GT(image.data_size, 0u); - ASSERT_EQ(expect->width(), image.width); - ASSERT_EQ(expect->height(), image.height); - ASSERT_NO_FAILURE(uint8_t *data = mapBuffer(image.buf)); - - for (size_t i(0); i < image.num_planes; ++i) { - ASSERT_GE(image.pitches[i], expect->widths[i]); - std::valarray source(expect->plane(i), expect->sizes[i]); - std::gslice result_slice(0, {expect->heights[i], expect->widths[i]}, - {image.pitches[i], 1}); - std::valarray result = std::valarray( - data + image.offsets[i], - image.pitches[i] * expect->heights[i])[result_slice]; - std::valarray signs(1, result.size()); - signs[result > source] = -1; - ASSERT_EQ(source.size(), result.size()); - EXPECT_TRUE((source * signs - result * signs).max() <= 2) - << "Byte(s) mismatch in plane " << i; + ASSERT_NO_FAILURE( + YUVImage::Shared result = YUVImage::create(osurfaces.front())); + ASSERT_PTR(result.get()); + ASSERT_EQ(expect->planes, result->planes); + ASSERT_EQ(expect->width, result->width); + ASSERT_EQ(expect->height, result->height); + ASSERT_TRUE((result->widths == expect->widths).min()); + ASSERT_TRUE((result->heights == expect->heights).min()); + ASSERT_TRUE((result->offsets == expect->offsets).min()); + ASSERT_TRUE((result->sizes == expect->sizes).min()); + ASSERT_EQ(expect->bytes.size(), result->bytes.size()); + + std::valarray rbytes(result->bytes.size()); + std::copy(std::begin(result->bytes), std::end(result->bytes), + std::begin(rbytes)); + + std::valarray ebytes(expect->bytes.size()); + std::copy(std::begin(expect->bytes), std::end(expect->bytes), + std::begin(ebytes)); + + EXPECT_TRUE(std::abs(ebytes - rbytes).max() <= 2); + if (HasFailure()) { + std::valarray r = std::abs(ebytes - rbytes); + for (size_t i(0); i < expect->planes; ++i) { + std::valarray plane = r[expect->slices[i]]; + size_t mismatch = std::count_if( + std::begin(plane), std::end(plane), + [](const uint16_t& v){return v > 2;}); + std::cout << "\tplane " << i << ": " + << mismatch << " of " << plane.size() + << " (" << (float(mismatch) / plane.size() * 100) + << "%) mismatch" << std::endl; + } } - unmapBuffer(image.buf); - for (auto id : buffers) destroyBuffer(id); - destroyImage(image); destroyContext(ocontext); destroyConfig(oconfig); destroySurfaces(osurfaces); @@ -448,7 +412,6 @@ TEST_P(JPEGEncodeInputTest, Full) ASSERT_NO_FAILURE(SetUpHuffmanTables()); ASSERT_NO_FAILURE(SetUpSlice()); ASSERT_NO_FAILURE(SetUpHeader()); - ASSERT_NO_FAILURE(CopyInputToSurface()); ASSERT_NO_FAILURE(Encode()); VerifyOutput(); diff --git a/test/i965_jpeg_test_data.cpp b/test/i965_jpeg_test_data.cpp index 956f7cf..fe531c0 100644 --- a/test/i965_jpeg_test_data.cpp +++ b/test/i965_jpeg_test_data.cpp @@ -779,183 +779,53 @@ namespace Encode { { Shared t(new TestInput); - switch(fourcc) { - case VA_FOURCC_I420: - t->planes = 3; - t->widths = {w + (w & 1), (w + 1) >> 1, (w + 1) >> 1}; - t->heights = {h + (h & 1), (h + 1) >> 1, (h + 1) >> 1}; - t->format = VA_RT_FORMAT_YUV420; - t->fourcc_output = VA_FOURCC_IMC3; - break; - case VA_FOURCC_NV12: - t->planes = 2; - t->widths = {w + (w & 1), w + (w & 1), 0}; - t->heights = {h + (h & 1), (h + 1) >> 1, 0}; - t->format = VA_RT_FORMAT_YUV420; - t->fourcc_output = VA_FOURCC_IMC3; - break; - case VA_FOURCC_UYVY: - case VA_FOURCC_YUY2: - t->planes = 1; - t->widths = {(w + (w & 1)) << 1, 0, 0}; - t->heights = {h + (h & 1), 0, 0}; - t->format = VA_RT_FORMAT_YUV422; - t->fourcc_output = VA_FOURCC_422H; - break; - case VA_FOURCC_422H: - t->planes = 3; - t->widths = {w + (w & 1), (w + 1) >> 1, (w + 1) >> 1}; - t->heights = {h + (h & 1), h + (h & 1), h + (h & 1)}; - t->format = VA_RT_FORMAT_YUV422; - t->fourcc_output = VA_FOURCC_422H; - break; - case VA_FOURCC_Y800: - t->planes = 1; - t->widths = {w + (w & 1), 0, 0}; - t->heights = {h + (h & 1), 0, 0}; - t->format = VA_RT_FORMAT_YUV400; - t->fourcc_output = VA_FOURCC_Y800; - t->picture.num_components = 1; - break; - default: - return Shared(); // fourcc is unsupported - } - - t->fourcc = fourcc; - t->picture.picture_width = ALIGN(w, 2); - t->picture.picture_height = ALIGN(h, 2); + t->image = YUVImage::create(fourcc, w, h); - for (size_t i(0); i < t->planes; ++i) - t->sizes[i] = t->widths[i] * t->heights[i]; + if (not bool(t->image.get())) + return Shared(); - for (size_t i(1); i < t->planes; ++i) - t->offsets[i] = t->sizes[i - 1] + t->offsets[i - 1]; + t->picture.picture_width = t->image->width; + t->picture.picture_height = t->image->height; - // Allocate bytes. Values are arbitrary. Caller is responsible for - // assigning byte values as appropriate. - t->bytes.resize( - std::accumulate(std::begin(t->sizes), std::end(t->sizes), 0u)); + if (VA_FOURCC_Y800 == fourcc) + t->picture.num_components = 1; return t; } TestInput::TestInput() - : bytes() + : image() , picture(defaultPictureParameter) , matrix(defaultIQMatrix) , huffman(defaultHuffmanTable) , slice(defaultSliceParameter) - , fourcc(0) - , fourcc_output(0) - , format(0) - , planes(0) - , widths{0,0,0} - , heights{0,0,0} - , offsets{0,0,0} - , sizes{0,0,0} { return; } - const unsigned TestInput::width() const - { - return picture.picture_width; - } - - const unsigned TestInput::height() const + const YUVImage::SharedConst TestInput::toExpectedOutput() const { - return picture.picture_height; - } - - const uint8_t* TestInput::plane(const size_t i) const - { - return bytes.data() + offsets[i]; - } + YUVImage::Shared result; - uint8_t* TestInput::begin(const size_t i) - { - return bytes.data() + offsets[i]; - } - - const uint8_t* TestInput::begin(const size_t i) const - { - return bytes.data() + offsets[i]; - } - - uint8_t* TestInput::end(const size_t i) - { - return begin(i) + sizes[i]; - } - - const uint8_t* TestInput::end(const size_t i) const - { - return begin(i) + sizes[i]; - } - - const TestInput::SharedConst TestInput::toOutputFourcc() const - { - TestInput::Shared result; - - struct IsEvenIndex - { - IsEvenIndex():i(0){} - inline const bool operator()(const uint8_t&) - { - const bool r = (i % 2) != 1; - ++i; - return r; - } - size_t i; - }; - - struct IsOddIndex - { - IsOddIndex():i(0){} - inline const bool operator()(const uint8_t&) - { - const bool r = (i % 2) == 1; - ++i; - return r; - } - size_t i; - }; + switch (image->fourcc) { + case VA_FOURCC_Y800: + return image; + case VA_FOURCC_I420: + case VA_FOURCC_NV12: + result = YUVImage::create(VA_FOURCC_IMC3, image->width, image->height); + break; + case VA_FOURCC_UYVY: + case VA_FOURCC_YUY2: + result = YUVImage::create(VA_FOURCC_422H, image->width, image->height); + break; + default: + break; + } - if (fourcc_output == VA_FOURCC_IMC3) { - if (fourcc == VA_FOURCC_I420) { - return shared_from_this(); - } else if (fourcc == VA_FOURCC_NV12) { - result = create(VA_FOURCC_I420, width(), height()); - // copy Y to plane 0 - std::copy(begin(0), end(0), result->begin(0)); - // copy U to plane 1 - std::copy_if(begin(1), end(1), result->begin(1), IsEvenIndex()); - // copy V to plane 2 - std::copy_if(begin(1), end(1), result->begin(2), IsOddIndex()); - } - } else if (fourcc_output == VA_FOURCC_422H) { - if (fourcc == VA_FOURCC_UYVY) { - result = create(VA_FOURCC_422H, width(), height()); - // copy Y to plane 0 - std::copy_if(begin(0), end(0), result->begin(0), IsOddIndex()); - // copy UV across plane 1 and 2 - std::copy_if(begin(0), end(0), result->begin(1), IsEvenIndex()); - // partition U into plane 1 and V into plane 2 - std::stable_partition( - result->begin(1), result->end(2), IsEvenIndex()); - } else if (fourcc == VA_FOURCC_YUY2) { - result = create(VA_FOURCC_422H, width(), height()); - // copy Y to plane 0 - std::copy_if(begin(0), end(0), result->begin(0), IsEvenIndex()); - // copy UV across plane 1 and 2 - std::copy_if(begin(0), end(0), result->begin(1), IsOddIndex()); - // partition U into plane 1 and V into plane 2 - std::stable_partition( - result->begin(1), result->end(2), IsEvenIndex()); - } - } else if (fourcc_output == VA_FOURCC_Y800) { - if (fourcc == VA_FOURCC_Y800) { - return shared_from_this(); - } + if (bool(result)) { + result->y() = image->y(); + result->u() = image->u(); + result->v() = image->v(); } return result; @@ -964,10 +834,10 @@ namespace Encode { ::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 + << std::string((char*)(&t.image->fourcc), 4) + << " " << t.image->width << "x" << t.image->height + << " " << t.image->widths << " " << t.image->heights + << " " << t.image->sizes << " " << t.image->offsets ; } @@ -989,7 +859,7 @@ namespace Encode { TestInput::Shared input(TestInput::create(fourcc, res[0], res[1])); if (input.get()) { std::generate_n( - std::begin(input->bytes), input->bytes.size(), + std::begin(input->image->bytes), input->image->bytes.size(), RandomValueGenerator(0x00, 0xff)); } return input; diff --git a/test/i965_jpeg_test_data.h b/test/i965_jpeg_test_data.h index 938fb06..0105d47 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_image_utils.h" + #include #include #include @@ -407,40 +409,20 @@ namespace Encode { typedef std::shared_ptr SharedConst; static Shared create(const unsigned, const unsigned, const unsigned); - - const unsigned width() const; - const unsigned height() const; - const uint8_t* plane(const size_t) const; - const SharedConst toOutputFourcc() const; + const YUVImage::SharedConst toExpectedOutput() const; friend ::std::ostream& operator<<(::std::ostream&, const TestInput&); friend ::std::ostream& operator<<(::std::ostream&, const Shared&); friend ::std::ostream& operator<<(::std::ostream&, const SharedConst&); - ByteData bytes; + YUVImage::Shared image; PictureParameter picture; IQMatrix matrix; HuffmanTable huffman; SliceParameter slice; - unsigned fourcc; - unsigned fourcc_output; - unsigned format; - size_t planes; - std::array widths; - std::array heights; - std::array offsets; - std::array sizes; private: TestInput(); - - /** get pointer to beginning of plane @param i **/ - uint8_t* begin(const size_t i); - const uint8_t* begin(const size_t i) const; - - /** get pointer to end of plane @param i **/ - uint8_t* end(const size_t i); - const uint8_t* end(const size_t i) const; }; class TestInputCreator -- cgit v1.2.3