[Libva] [PATCH intel-driver 5/5] test: use YUVImage in JPEG encode tests

U. Artie Eoff ullysses.a.eoff at intel.com
Wed Oct 26 20:24:19 UTC 2016


The YUVImage class allows for more efficient (faster)
operations on the YUV input/output of these tests.

Signed-off-by: U. Artie Eoff <ullysses.a.eoff at intel.com>
---
 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(-)

diff --git a/test/i965_jpeg_encode_test.cpp b/test/i965_jpeg_encode_test.cpp
index 173cd93ec926..d57aa6726be2 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 <numeric>
 #include <cstring>
@@ -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<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);
+        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<uint8_t>(image.buf));
-
-        for (size_t i(0); i < image.num_planes; ++i) {
-            ASSERT_GE(image.pitches[i], expect->widths[i]);
-            std::valarray<uint8_t> source(expect->plane(i), expect->sizes[i]);
-            std::gslice result_slice(0, {expect->heights[i], expect->widths[i]},
-                {image.pitches[i], 1});
-            std::valarray<uint8_t> result = std::valarray<uint8_t>(
-                data + image.offsets[i],
-                image.pitches[i] * expect->heights[i])[result_slice];
-            std::valarray<uint8_t> 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<int16_t> rbytes(result->bytes.size());
+        std::copy(std::begin(result->bytes), std::end(result->bytes),
+            std::begin(rbytes));
+
+        std::valarray<int16_t> 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<int16_t> r = std::abs(ebytes - rbytes);
+            for (size_t i(0); i < expect->planes; ++i) {
+                std::valarray<int16_t> 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 956f7cfc0a1f..fe531c0a2d14 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<uint8_t>(0x00, 0xff));
         }
         return input;
diff --git a/test/i965_jpeg_test_data.h b/test/i965_jpeg_test_data.h
index 938fb06b258c..0105d4768140 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 <array>
 #include <iostream>
 #include <map>
@@ -407,40 +409,20 @@ namespace Encode {
         typedef std::shared_ptr<const TestInput> 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<size_t, 3> widths;
-        std::array<size_t, 3> heights;
-        std::array<size_t, 3> offsets;
-        std::array<size_t, 3> 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
-- 
2.1.0



More information about the Libva mailing list