Discussion:
[PATCH intel-driver 1/5] test: add a timer class
(too old to reply)
U. Artie Eoff
2016-10-26 20:24:15 UTC
Permalink
The timer is useful to quickly instrument various sections
of code during test development optimization tasks or other
timing needs.

Signed-off-by: U. Artie Eoff <***@intel.com>
---
test/test_utils.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)

diff --git a/test/test_utils.h b/test/test_utils.h
index 007667708adb..333106c239d6 100644
--- a/test/test_utils.h
+++ b/test/test_utils.h
@@ -25,6 +25,7 @@
#ifndef TEST_UTILS_H
#define TEST_UTILS_H

+#include <chrono>
#include <random>

template <typename T>
@@ -46,4 +47,29 @@ private:
std::uniform_int_distribution<T> dis;
};

+class Timer
+{
+public:
+ typedef typename std::chrono::microseconds us;
+ typedef typename std::chrono::milliseconds ms;
+ typedef typename std::chrono::seconds s;
+
+ Timer() { reset(); }
+
+ template <typename T = std::chrono::microseconds>
+ typename T::rep elapsed() const
+ {
+ return std::chrono::duration_cast<T>(
+ std::chrono::steady_clock::now() - start).count();
+ }
+
+ void reset()
+ {
+ start = std::chrono::steady_clock::now();
+ }
+
+private:
+ std::chrono::steady_clock::time_point start;
+};
+
#endif // TEST_UTILS_H
--
2.1.0
U. Artie Eoff
2016-10-26 20:24:19 UTC
Permalink
The YUVImage class allows for more efficient (faster)
operations on the YUV input/output of these tests.

Signed-off-by: U. Artie Eoff <***@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
U. Artie Eoff
2016-10-26 20:24:16 UTC
Permalink
The speed of random number generation can have a
significant impact on test execution time when
initializing large arrays of random values. The C++
random number engines and generators are much slower
than std::rand.

Thus, use C's rand() to generate pseudo-random values
within a given [min,max] range. For testing purposes,
deterministic sequences would be preferable anyway.
That is, if a particular sequence exposes a test failure,
then we can reproduce it later. Also, we seed the
pseudo-random number generator with the current time
so that the sequence is not always the same across
executions. The seed is then recorded in the test
results so that the sequence can be reproduced if
needed.

Signed-off-by: U. Artie Eoff <***@intel.com>
---
test/i965_test_environment.cpp | 7 +++++++
test/object_heap_test.cpp | 4 ----
test/test_utils.h | 19 +++++++++++--------
3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/test/i965_test_environment.cpp b/test/i965_test_environment.cpp
index 0049c1435957..ee8b1cc4465a 100644
--- a/test/i965_test_environment.cpp
+++ b/test/i965_test_environment.cpp
@@ -24,6 +24,8 @@

#include "i965_test_environment.h"

+#include <cstdlib>
+#include <ctime>
#include <fcntl.h> // for O_RDWR
#include <unistd.h> // for close()
#include <va/va_drm.h>
@@ -44,6 +46,11 @@ I965TestEnvironment::I965TestEnvironment()

void I965TestEnvironment::SetUp()
{
+ std::time_t seed(std::time(0));
+ std::srand(seed);
+ ::testing::Test::RecordProperty("rand_seed", seed);
+ std::cout << "Seeded std::rand() with " << seed << "." << std::endl;
+
ASSERT_EQ(-1, m_handle);
ASSERT_PTR_NULL(m_vaDisplay);

diff --git a/test/object_heap_test.cpp b/test/object_heap_test.cpp
index 70257f63f409..89fd8d78bdbb 100644
--- a/test/object_heap_test.cpp
+++ b/test/object_heap_test.cpp
@@ -181,10 +181,6 @@ TEST(ObjectHeapTest, DataIntegrity)

ASSERT_EQ(0, object_heap_init(&heap, sizeof(test_object), 0));

- std::time_t seed = std::time(0);
- std::srand(seed);
- RecordProperty("seed", seed);
-
std::vector<int> values;

auto generator = [&]{
diff --git a/test/test_utils.h b/test/test_utils.h
index 333106c239d6..8083591f587b 100644
--- a/test/test_utils.h
+++ b/test/test_utils.h
@@ -26,25 +26,28 @@
#define TEST_UTILS_H

#include <chrono>
-#include <random>
+#include <cstdlib>

template <typename T>
class RandomValueGenerator
{
public:
RandomValueGenerator(const T& min, const T& max)
- : dis(min, max)
- { }
+ : minVal(min)
+ , maxVal(max)
+ {
+ return;
+ }

- const T operator()()
+ const T operator()() const
{
- static std::random_device rd;
- static std::default_random_engine gen(rd());
- return dis(gen);
+ return static_cast<T>(
+ std::rand() % (maxVal + 1 - minVal) + minVal);
}

private:
- std::uniform_int_distribution<T> dis;
+ T minVal;
+ T maxVal;
};

class Timer
--
2.1.0
U. Artie Eoff
2016-10-26 20:24:18 UTC
Permalink
Add stream operators for std::valarray.

Signed-off-by: U. Artie Eoff <***@intel.com>
---
test/i965_streamable.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)

diff --git a/test/i965_streamable.h b/test/i965_streamable.h
index 4969c1413173..0f7e1291c4c4 100644
--- a/test/i965_streamable.h
+++ b/test/i965_streamable.h
@@ -29,6 +29,7 @@
#include <iostream>
#include <iomanip>
#include <sstream>
+#include <valarray>
#include <va/va.h>

namespace std {
@@ -55,6 +56,30 @@ namespace std {
}
return os << std::dec << "}";
}
+
+ template <typename T> inline std::ostream&
+ operator<<(std::ostream& os, const std::valarray<T>& a)
+ {
+ os << "{";
+ for (const auto& s : a) {
+ if (&s != &a[0])
+ os << ",";
+ os << s;
+ }
+ return os << "}";
+ }
+
+ template <> inline std::ostream&
+ operator<<(std::ostream& os, const std::valarray<uint8_t>& a)
+ {
+ os << "{" << std::hex;
+ for (const auto& s : a) {
+ if (&s != &a[0])
+ os << ",";
+ os << "0x" << std::setfill('0') << std::setw(2) << unsigned(s);
+ }
+ return os << std::dec << "}";
+ }
}// namespace std

template <typename T>
--
2.1.0
U. Artie Eoff
2016-10-26 20:24:17 UTC
Permalink
Add a class that employs std::valarray and std::slice
to manage YUV input/output data. Using valarray's and
slice's are generally more efficient than std::vector
in most test use cases where YUV data is needed.

Current test cases that are using different (yet
similar) code to manage it's own YUV input/output
data can eventually converge onto use of this common
class instead.

Signed-off-by: U. Artie Eoff <***@intel.com>
---
test/Makefile.am | 2 +
test/i965_test_image_utils.cpp | 747 +++++++++++++++++++++++++++++++++++++++++
test/i965_test_image_utils.h | 66 ++++
3 files changed, 815 insertions(+)
create mode 100644 test/i965_test_image_utils.cpp
create mode 100644 test/i965_test_image_utils.h

diff --git a/test/Makefile.am b/test/Makefile.am
index 7a5437e71450..fe9843b0ee6a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -50,6 +50,7 @@ noinst_HEADERS = \
i965_jpeg_test_data.h \
i965_test_environment.h \
i965_test_fixture.h \
+ i965_test_image_utils.h \
test.h \
test_utils.h \
$(NULL)
@@ -70,6 +71,7 @@ test_i965_drv_video_SOURCES = \
i965_surface_test.cpp \
i965_test_environment.cpp \
i965_test_fixture.cpp \
+ i965_test_image_utils.cpp \
object_heap_test.cpp \
test_main.cpp \
$(NULL)
diff --git a/test/i965_test_image_utils.cpp b/test/i965_test_image_utils.cpp
new file mode 100644
index 000000000000..bdfcbf3c6e21
--- /dev/null
+++ b/test/i965_test_image_utils.cpp
@@ -0,0 +1,747 @@
+/*
+ * 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_test_environment.h"
+#include "i965_test_image_utils.h"
+
+#include <cstring> // std::memset
+
+YUVImage::YUVImage()
+ : bytes()
+ , width(0)
+ , height(0)
+ , fourcc(0)
+ , format(0)
+ , planes(0)
+ , widths{0,0,0}
+ , heights{0,0,0}
+ , offsets{0,0,0}
+ , sizes{0,0,0}
+ , slices()
+{
+ return;
+}
+
+YUVImage::Shared YUVImage::create(
+ const unsigned fourcc, size_t w, size_t h)
+{
+ Shared t(new YUVImage);
+
+ t->fourcc = fourcc;
+ t->width = w = w + (w & 1);
+ t->height = h = h + (h & 1);
+
+ switch(fourcc) {
+ case VA_FOURCC_444P:
+ t->planes = 3;
+ t->widths = {w, w, w};
+ t->heights = {h, h, h};
+ t->format = VA_RT_FORMAT_YUV444;
+ break;
+ case VA_FOURCC_IMC3:
+ case VA_FOURCC_I420:
+ t->planes = 3;
+ t->widths = {w, w >> 1, w >> 1};
+ t->heights = {h, h >> 1, h >> 1};
+ t->format = VA_RT_FORMAT_YUV420;
+ break;
+ case VA_FOURCC_NV12:
+ t->planes = 2;
+ t->widths = {w, w, 0};
+ t->heights = {h, h >> 1, 0};
+ t->format = VA_RT_FORMAT_YUV420;
+ break;
+ case VA_FOURCC_UYVY:
+ case VA_FOURCC_YUY2:
+ t->planes = 1;
+ t->widths = {w << 1, 0, 0};
+ t->heights = {h, 0, 0};
+ t->format = VA_RT_FORMAT_YUV422;
+ break;
+ case VA_FOURCC_422H:
+ t->planes = 3;
+ t->widths = {w, w >> 1, w >> 1};
+ t->heights = {h, h, h};
+ t->format = VA_RT_FORMAT_YUV422;
+ break;
+ case VA_FOURCC_422V:
+ t->planes = 3;
+ t->widths = {w, w, w};
+ t->heights = {h, h >> 1,h >> 1};
+ t->format = VA_RT_FORMAT_YUV422;
+ break;
+ case VA_FOURCC_Y800:
+ t->planes = 1;
+ t->widths = {w, 0, 0};
+ t->heights = {h, 0, 0};
+ t->format = VA_RT_FORMAT_YUV400;
+ break;
+ default:
+ return Shared(); // fourcc is unsupported
+ }
+
+ t->sizes = t->widths * t->heights;
+ t->bytes = std::valarray<uint8_t>(t->sizes.sum());
+
+ for (size_t i(1); i < t->planes; ++i)
+ t->offsets[i] = t->sizes[i - 1] + t->offsets[i - 1];
+
+ // Initialize slices
+ switch(fourcc) {
+ case VA_FOURCC_444P:
+ case VA_FOURCC_IMC3:
+ case VA_FOURCC_I420:
+ case VA_FOURCC_422H:
+ case VA_FOURCC_422V:
+ t->slices[1] = std::slice{t->offsets[1], t->sizes[1], 1};
+ t->slices[2] = std::slice{t->offsets[2], t->sizes[2], 1};
+ /* fall-through */
+ case VA_FOURCC_Y800:
+ t->slices[0] = std::slice{t->offsets[0], t->sizes[0], 1};
+ break;
+ case VA_FOURCC_NV12:
+ t->slices[0] = std::slice{t->offsets[0], t->sizes[0], 1};
+ t->slices[1] = std::slice{t->offsets[1], t->sizes[1]/2, 2};
+ t->slices[2] = std::slice{t->offsets[1] + 1, t->sizes[1]/2, 2};
+ break;
+ case VA_FOURCC_UYVY:
+ t->slices[0] = std::slice{t->offsets[0] + 1, t->sizes[0]/2, 2};
+ t->slices[1] = std::slice{t->offsets[0], t->sizes[0]/4, 4};
+ t->slices[2] = std::slice{t->offsets[0] + 2, t->sizes[0]/4, 4};
+ break;
+ case VA_FOURCC_YUY2:
+ t->slices[0] = std::slice{t->offsets[0], t->sizes[0]/2, 2};
+ t->slices[1] = std::slice{t->offsets[0] + 1, t->sizes[0]/4, 4};
+ t->slices[2] = std::slice{t->offsets[0] + 3, t->sizes[0]/4, 4};
+ break;
+ default:
+ return Shared(); // fourcc is unsupported
+ }
+
+ return t;
+}
+
+YUVImage::Shared YUVImage::create(const VAImage& image)
+{
+ I965TestEnvironment& env = *I965TestEnvironment::instance();
+
+ Shared result = create(image.format.fourcc, image.width, image.height);
+ EXPECT_PTR(result.get());
+
+ if (::testing::Test::HasFailure())
+ return Shared();
+
+ EXPECT_EQ(result->fourcc, image.format.fourcc);
+ EXPECT_EQ(result->planes, image.num_planes);
+ EXPECT_EQ(result->width, image.width);
+ EXPECT_EQ(result->height, image.height);
+ EXPECT_GE(image.data_size, result->bytes.size());
+
+ if (::testing::Test::HasFailure())
+ return Shared();
+
+ uint8_t* data = NULL;
+ EXPECT_STATUS(i965_MapBuffer(env, image.buf, (void**)&data));
+
+ if (::testing::Test::HasFailure())
+ return Shared();
+
+ auto it(std::begin(result->bytes));
+ for (size_t i(0); i < image.num_planes; ++i) {
+ const size_t pitch(image.pitches[i]);
+ const size_t width(result->widths[i]);
+ const size_t height(result->heights[i]);
+ const uint8_t *source = data + image.offsets[i];
+
+ EXPECT_GE(pitch, width);
+ if (::testing::Test::HasFailure())
+ break;
+
+ for (size_t j(0); j < height; ++j) {
+ std::copy(source, source + width, it);
+ source += pitch;
+ it += width;
+ }
+ }
+
+ EXPECT_STATUS(i965_UnmapBuffer(env, image.buf));
+
+ if (::testing::Test::HasFailure())
+ return Shared();
+
+ return result;
+}
+
+YUVImage::Shared YUVImage::create(const VASurfaceID surface)
+{
+ I965TestEnvironment& env = *I965TestEnvironment::instance();
+ VAImage image;
+
+ EXPECT_STATUS(i965_DeriveImage(env, surface, &image));
+
+ if (::testing::Test::HasFailure())
+ return Shared();
+
+ Shared result = YUVImage::create(image);
+
+ EXPECT_STATUS(i965_DestroyImage(env, image.image_id));
+
+ return result;
+}
+
+void YUVImage::toSurface(VASurfaceID surface) const
+{
+ I965TestEnvironment& env = *I965TestEnvironment::instance();
+ VAImage image;
+
+ ASSERT_STATUS(i965_DeriveImage(env, surface, &image));
+
+ EXPECT_ID(image.image_id);
+ EXPECT_EQ(fourcc, image.format.fourcc);
+ EXPECT_EQ(planes, image.num_planes);
+ EXPECT_EQ(width, image.width);
+ EXPECT_EQ(height, image.height);
+ EXPECT_GE(image.data_size, bytes.size());
+
+ if (::testing::Test::HasFailure()) {
+ EXPECT_STATUS(i965_DestroyImage(env, image.image_id));
+ return;
+ }
+
+ uint8_t* data = NULL;
+ EXPECT_STATUS(i965_MapBuffer(env, image.buf, (void**)&data));
+ EXPECT_PTR(data);
+
+ if (::testing::Test::HasFailure()) {
+ EXPECT_STATUS(i965_DestroyImage(env, image.image_id));
+ return;
+ }
+
+ std::memset(data, 0, image.data_size);
+
+ auto it(std::begin(bytes));
+ for (size_t i(0); i < image.num_planes; ++i) {
+ const size_t pitch(image.pitches[i]);
+ const size_t w(widths[i]);
+ const size_t h(heights[i]);
+ uint8_t *dest = data + image.offsets[i];
+
+ EXPECT_GE(pitch, w);
+ if (::testing::Test::HasFailure())
+ break;
+
+ for (size_t j(0); j < h; ++j) {
+ std::copy(it, it + w, dest);
+ dest += pitch;
+ it += w;
+ }
+ }
+
+ EXPECT_STATUS(i965_UnmapBuffer(env, image.buf));
+ EXPECT_STATUS(i965_DestroyImage(env, image.image_id));
+}
+
+TEST(YUVImageTest, 444P)
+{
+ std::valarray<uint8_t> data = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x6b,0x12,0x99
+ };
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_444P, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(3u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,2,2} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,2,2} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,4,4} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,4,8} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x00,0x73,0x54,0xcc} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0xca,0x6b,0x12,0x99} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, IMC3)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_IMC3, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(3u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,1,1} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,4,5} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x00} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x73} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, I420)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_I420, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(3u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,1,1} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,4,5} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x00} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x73} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, NV12)
+{
+ std::valarray<uint8_t> data = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x6b,0x12,0x99};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_NV12, 2, 4);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(4u, image->height);
+ EXPECT_EQ(2u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,2,0} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,2,0} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{8,4,0} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,8,0} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0xca,0x12} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x6b,0x99} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, UYVY)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_UYVY, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(1u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{4,0,0} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,0,0} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{8,0,0} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,0,0} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0xaf,0xff,0x73,0xcc} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0x00} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x23,0x54} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, YUY2)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_YUY2, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(1u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{4,0,0} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,0,0} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{8,0,0} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,0,0} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0x23,0x00,0x54} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0xaf,0x73} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0xff,0xcc} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, 422H)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_422H, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(3u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,2,2} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,2,2} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,4,6} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x00,0x73} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x54,0xcc} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, 422V)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_422V, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(3u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,2,2} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,1,1} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,2,2} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,4,6} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+ std::valarray<uint8_t> u = image->u();
+ std::valarray<uint8_t> v = image->v();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x00,0x73} == u).min() );
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x54,0xcc} == v).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+ image->u() = u;
+ image->v() = v;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, Y800)
+{
+ std::valarray<uint8_t> data = {0x11,0xaf,0x23,0xff};
+
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC_Y800, 2, 2);
+ ASSERT_PTR(image.get());
+
+ EXPECT_EQ(data.size(), image->bytes.size());
+ EXPECT_EQ(2u, image->width);
+ EXPECT_EQ(2u, image->height);
+ EXPECT_EQ(1u, image->planes);
+ EXPECT_TRUE( (std::valarray<size_t>{2,0,0} == image->widths).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{2,0,0} == image->heights).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{4,0,0} == image->sizes).min() );
+ EXPECT_TRUE( (std::valarray<size_t>{0,0,0} == image->offsets).min() );
+
+ image->bytes = data;
+
+ std::valarray<uint8_t> y = image->y();
+
+ EXPECT_TRUE( (std::valarray<uint8_t>{0x11,0xaf,0x23,0xff} == y).min() );
+
+ image->bytes = uint8_t(0);
+
+ EXPECT_FALSE( (image->bytes == data).min() );
+
+ image->y() = y;
+
+ EXPECT_TRUE( (image->bytes == data).min() );
+}
+
+TEST(YUVImageTest, Invalid)
+{
+ YUVImage::Shared image = YUVImage::create(VA_FOURCC('B','E','E','F'), 2, 2);
+ EXPECT_PTR_NULL(image.get());
+}
+
+TEST(YUVImageTest, I420toNV12)
+{
+ std::valarray<uint8_t> data1 = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x6b,0x12,0x99};
+ std::valarray<uint8_t> data2 = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x12,0x6b,0x99};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_I420, 2, 4);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_NV12, 2, 4);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, NV12toI420)
+{
+ std::valarray<uint8_t> data1 = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x6b,0x12,0x99};
+ std::valarray<uint8_t> data2 = {
+ 0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc,0xca,0x12,0x6b,0x99};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_NV12, 2, 4);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_I420, 2, 4);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, UYVYtoYUY2)
+{
+ std::valarray<uint8_t> data1 = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+ std::valarray<uint8_t> data2 = {0xaf,0x11,0xff,0x23,0x73,0x00,0xcc,0x54};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_UYVY, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_YUY2, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, YUY2toUYVY)
+{
+ std::valarray<uint8_t> data1 = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+ std::valarray<uint8_t> data2 = {0xaf,0x11,0xff,0x23,0x73,0x00,0xcc,0x54};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_YUY2, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_UYVY, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, UYVYto422H)
+{
+ std::valarray<uint8_t> data1 = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+ std::valarray<uint8_t> data2 = {0xaf,0xff,0x73,0xcc,0x11,0x00,0x23,0x54};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_UYVY, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_422H, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, 422HtoUYVY)
+{
+ std::valarray<uint8_t> data1 = {0xaf,0xff,0x73,0xcc,0x11,0x00,0x23,0x54};
+ std::valarray<uint8_t> data2 = {0x11,0xaf,0x23,0xff,0x00,0x73,0x54,0xcc};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_422H, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_UYVY, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, YUY2to422H)
+{
+ std::valarray<uint8_t> data1 = {0xaf,0xff,0x73,0xcc,0x11,0x00,0x23,0x54};
+ std::valarray<uint8_t> data2 = {0xaf,0x73,0x11,0x23,0xff,0x00,0xcc,0x54};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_YUY2, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_422H, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
+
+TEST(YUVImageTest, 422HtoYUY2)
+{
+ std::valarray<uint8_t> data1 = {0xaf,0x73,0x11,0x23,0xff,0x00,0xcc,0x54};
+ std::valarray<uint8_t> data2 = {0xaf,0xff,0x73,0xcc,0x11,0x00,0x23,0x54};
+
+ YUVImage::Shared image1 = YUVImage::create(VA_FOURCC_422H, 2, 2);
+ YUVImage::Shared image2 = YUVImage::create(VA_FOURCC_YUY2, 2, 2);
+ ASSERT_PTR(image1.get());
+ ASSERT_PTR(image2.get());
+
+ image1->bytes = data1;
+ image2->y() = image1->y();
+ image2->u() = image1->u();
+ image2->v() = image1->v();
+
+ EXPECT_TRUE( (image2->bytes == data2).min() );
+}
diff --git a/test/i965_test_image_utils.h b/test/i965_test_image_utils.h
new file mode 100644
index 000000000000..60c84ae96ec2
--- /dev/null
+++ b/test/i965_test_image_utils.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef I965_TEST_IMAGE_UTILS_H
+#define I965_TEST_IMAGE_UTILS_H
+
+#include <array>
+#include <memory>
+#include <valarray>
+#include <va/va.h>
+
+class YUVImage
+ : public std::enable_shared_from_this<YUVImage>
+{
+public:
+ typedef std::shared_ptr<YUVImage> Shared;
+ typedef std::shared_ptr<const YUVImage> SharedConst;
+
+ static Shared create(const unsigned, size_t, size_t);
+ static Shared create(const VAImage&);
+ static Shared create(const VASurfaceID);
+
+ std::slice_array<uint8_t> y() { return bytes[slices[0]]; }
+ std::slice_array<uint8_t> u() { return bytes[slices[1]]; }
+ std::slice_array<uint8_t> v() { return bytes[slices[2]]; }
+
+ void toSurface(VASurfaceID) const;
+
+ std::valarray<uint8_t> bytes;
+ size_t width;
+ size_t height;
+ unsigned fourcc;
+ unsigned format;
+ size_t planes;
+ std::valarray<size_t> widths;
+ std::valarray<size_t> heights;
+ std::valarray<size_t> offsets;
+ std::valarray<size_t> sizes;
+ std::array<std::slice, 3> slices;
+
+private:
+ YUVImage();
+};
+
+#endif
--
2.1.0
Sean V Kelley
2016-10-28 20:27:19 UTC
Permalink
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own class.  This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion operations on YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed on the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.

lgtm (also tested0, applied.

Thanks,

Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
Xiang, Haihao
2016-11-10 03:56:48 UTC
Permalink
Hi Artie,

Did you run gtest on SKL?  I saw a failure with this optimization on
SKL. After reverting back to commit 63b98a5, the issue disappears. 

[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)

Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own class.  This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion operations on YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed on the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Eoff, Ullysses A
2016-11-10 16:45:03 UTC
Permalink
Yes I ran this on my SKL and don't see this issue.
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test Speed Optimization
Hi Artie,
Did you run gtest on SKL?  I saw a failure with this optimization on
SKL. After reverting back to commit 63b98a5, the issue disappears.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own class.  This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion operations on YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed on the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Eoff, Ullysses A
2016-11-11 18:23:02 UTC
Permalink
Hi Haihao,

Please file a bug if this persists.

Thanks,
U. Artie
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test Speed Optimization
Hi Artie,
Did you run gtest on SKL?  I saw a failure with this optimization on
SKL. After reverting back to commit 63b98a5, the issue disappears.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own class.  This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion operations on YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed on the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Xiang, Haihao
2016-11-21 03:18:09 UTC
Permalink
I ran gtest again and got 2 failed cases now:

[==========] 580 tests from 16 test cases ran. (111876 ms total)
[  PASSED  ] 578 tests.
[  FAILED  ] 2 tests, listed below:
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x525ce4 pointing to "UYVY")
[  FAILED  ] Common/JPEGEncodeInputTest.Full/98, where GetParam() =
(Fixed Size 7680x4320, 0x525d10 pointing to "YUY2")

however Common/JPEGEncodeInputTest.Full/97 and
Common/JPEGEncodeInputTest.Full/98 pass when run the tests separately.

[ RUN      ] Common/JPEGEncodeInputTest.Full/97
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/97 (6458 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6458 ms total)

[ RUN      ] Common/JPEGEncodeInputTest.Full/98
Creator: Fixed Size 7680x4320
Input  : YUY2 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/98 (6235 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6235 ms total)

so I guess some buffers/parameters are not cleared before running a new
test in a full testing run. I will file a bug to track this issue.

Thanks
Haihao
Post by Eoff, Ullysses A
Hi Haihao,
Please file a bug if this persists.
Thanks,
U. Artie
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test Speed Optimization
Hi Artie,
Did you run gtest on SKL?  I saw a failure with this optimization on
SKL. After reverting back to commit 63b98a5, the issue disappears.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own
class.  This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion operations
on
YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed
on
the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Sean V Kelley
2016-11-21 22:28:01 UTC
Permalink
Hello Haihao,

If you like, please file a bug and provide details about your system
configuration and the errors you are seeing. I'm not able to
duplicate your errors.

Sean
Post by Xiang, Haihao
[==========] 580 tests from 16 test cases ran. (111876 ms total)
[ PASSED ] 578 tests.
[ FAILED ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x525ce4 pointing to "UYVY")
[ FAILED ] Common/JPEGEncodeInputTest.Full/98, where GetParam() =
(Fixed Size 7680x4320, 0x525d10 pointing to "YUY2")
however Common/JPEGEncodeInputTest.Full/97 and
Common/JPEGEncodeInputTest.Full/98 pass when run the tests separately.
[ RUN ] Common/JPEGEncodeInputTest.Full/97
Creator: Fixed Size 7680x4320
Input : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[ OK ] Common/JPEGEncodeInputTest.Full/97 (6458 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6458 ms total)
[ RUN ] Common/JPEGEncodeInputTest.Full/98
Creator: Fixed Size 7680x4320
Input : YUY2 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[ OK ] Common/JPEGEncodeInputTest.Full/98 (6235 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6235 ms total)
so I guess some buffers/parameters are not cleared before running a new
test in a full testing run. I will file a bug to track this issue.
Thanks
Haihao
Post by Eoff, Ullysses A
Hi Haihao,
Please file a bug if this persists.
Thanks,
U. Artie
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test Speed Optimization
Hi Artie,
Did you run gtest on SKL? I saw a failure with this optimization
on
SKL. After reverting back to commit 63b98a5, the issue disappears.
[ RUN ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
Actual: false
Expected: true
plane 0: 29641916 of 33177600 (89.3432%) mismatch
plane 1: 184960 of 16588800 (1.11497%) mismatch
plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0}
{0,0,0}
[ FAILED ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data fields and
routines
from the ::JPEG::Encode::TestInput class into it's own
class. This
new class,
YUVImage, was then refactored to use std::valarray/std::slice to
manage the
underlying YUV byte data. The JPEG encode tests are updated
accordingly. This
change allows for faster comparison and conversion operations
on
YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed
on
the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can be used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
test: add a timer class
test: use C random library for random numbers
test: add YUVImage class
test: streamable valarray
test: use YUVImage in JPEG encode tests
test/Makefile.am | 2 +
test/i965_jpeg_encode_test.cpp | 135 +++-----
test/i965_jpeg_test_data.cpp | 196 ++---------
test/i965_jpeg_test_data.h | 26 +-
test/i965_streamable.h | 25 ++
test/i965_test_environment.cpp | 7 +
test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
test/i965_test_image_utils.h | 66 ++++
test/object_heap_test.cpp | 4 -
test/test_utils.h | 45 ++-
10 files changed, 970 insertions(+), 283 deletions(-)
create mode 100644 test/i965_test_image_utils.cpp
create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
--
Sean V. Kelley <***@intel.com>
Open Source Technology Center / SSG
Intel Corp.
Xiang, Haihao
2016-11-22 04:36:48 UTC
Permalink
Hi Sean,

The configuration is very simple and I ran the test within a text
console. Maybe it is a random issue so it is hard to reproduce in your
side. I will try to debug it. 

Thanks
Haihao
Post by Sean V Kelley
Hello Haihao,
If you like, please file a bug and provide details about your system
configuration and the errors you are seeing.  I'm not able to
duplicate your errors.
Sean
Post by Xiang, Haihao
[==========] 580 tests from 16 test cases ran. (111876 ms total)
[  PASSED  ] 578 tests.
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x525ce4 pointing to "UYVY")
[  FAILED  ] Common/JPEGEncodeInputTest.Full/98, where GetParam() =
(Fixed Size 7680x4320, 0x525d10 pointing to "YUY2")
however Common/JPEGEncodeInputTest.Full/97 and
Common/JPEGEncodeInputTest.Full/98 pass when run the tests
separately.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/97 (6458 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6458 ms total)
[ RUN      ] Common/JPEGEncodeInputTest.Full/98
Creator: Fixed Size 7680x4320
Input  : YUY2 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/98 (6235 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6235 ms total)
so I guess some buffers/parameters are not cleared before running a new
test in a full testing run. I will file a bug to track this issue.
Thanks
Haihao
Post by Eoff, Ullysses A
Hi Haihao,
Please file a bug if this persists.
Thanks,
U. Artie
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Ullysses A
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test
Speed Optimization
Hi Artie,
Did you run gtest on SKL?  I saw a failure with this
optimization
on
SKL. After reverting back to commit 63b98a5, the issue
disappears.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data
fields
and
routines
from the ::JPEG::Encode::TestInput class into it's own class.  This
new class,
YUVImage, was then refactored to use
std::valarray/std::slice
to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion
operations
on
YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed
on
the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can
be
used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Xiang, Haihao
2017-01-06 05:08:15 UTC
Permalink
Recently I re-ran the gtest on SKL and didn't reproduce the error even with HEAD
77ff763fa44c36d3154ee9267e9eb940dd4c10fc. I will keep one eye on it and let you
know if I see something.

Thanks
Haihao
 
Post by Xiang, Haihao
Hi Sean,
The configuration is very simple and I ran the test within a text
console. Maybe it is a random issue so it is hard to reproduce in your
side. I will try to debug it. 
Thanks
Haihao
Post by Sean V Kelley
Hello Haihao,
If you like, please file a bug and provide details about your system
configuration and the errors you are seeing.  I'm not able to
duplicate your errors.
Sean
Post by Xiang, Haihao
[==========] 580 tests from 16 test cases ran. (111876 ms total)
[  PASSED  ] 578 tests.
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x525ce4 pointing to "UYVY")
[  FAILED  ] Common/JPEGEncodeInputTest.Full/98, where GetParam() =
(Fixed Size 7680x4320, 0x525d10 pointing to "YUY2")
however Common/JPEGEncodeInputTest.Full/97 and
Common/JPEGEncodeInputTest.Full/98 pass when run the tests
separately.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/97 (6458 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6458 ms total)
[ RUN      ] Common/JPEGEncodeInputTest.Full/98
Creator: Fixed Size 7680x4320
Input  : YUY2 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[       OK ] Common/JPEGEncodeInputTest.Full/98 (6235 ms)
[----------] 1 test from Common/JPEGEncodeInputTest (6235 ms total)
so I guess some buffers/parameters are not cleared before running a new
test in a full testing run. I will file a bug to track this issue.
Thanks
Haihao
Post by Eoff, Ullysses A
Hi Haihao,
Please file a bug if this persists.
Thanks,
U. Artie
-----Original Message-----
From: Xiang, Haihao
Sent: Wednesday, November 09, 2016 7:57 PM
Subject: Re: [Libva] [PATCH intel-driver 0/5] JPEG Encode Test
Speed Optimization
Hi Artie,
Did you run gtest on SKL?  I saw a failure with this
optimization
on
SKL. After reverting back to commit 63b98a5, the issue
disappears.
[ RUN      ] Common/JPEGEncodeInputTest.Full/97
i965_jpeg_encode_test.cpp:371: Failure
Value of: std::abs(ebytes - rbytes).max() <= 2
  Actual: false
Expected: true
        plane 0: 29641916 of 33177600 (89.3432%) mismatch
        plane 1: 184960 of 16588800 (1.11497%) mismatch
        plane 2: 0 of 16588800 (0%) mismatch
Creator: Fixed Size 7680x4320
Input  : UYVY 7680x4320 {15360,0,0} {4320,0,0} {66355200,0,0} {0,0,0}
[  FAILED  ] Common/JPEGEncodeInputTest.Full/97, where GetParam() =
(Fixed Size 7680x4320, 0x522e64 pointing to "UYVY") (7295 ms)
Thanks
Haihao
Post by Sean V Kelley
This patch series splits out the general YUV input data
fields
and
routines
from the ::JPEG::Encode::TestInput class into it's own
class.  This
new class,
YUVImage, was then refactored to use
std::valarray/std::slice
to
manage the
underlying YUV byte data.  The JPEG encode tests are updated
accordingly.  This
change allows for faster comparison and conversion
operations
on
YUV
byte data
input/output results and helps reduce some of the copying overhead.
Also changed the random value generator to improve it's speed.
With these changes, I observe ~2x improvement in runtime speed
on
the
JPEG
Encode test cases.
Finally, included is a Timer class for convenience that can
be
used
for future
test development.
Nice refactoring that will make it easier for adding the other
encoders.
lgtm (also tested0, applied.
Thanks,
Sean
  test: add a timer class
  test: use C random library for random numbers
  test: add YUVImage class
  test: streamable valarray
  test: use YUVImage in JPEG encode tests
 test/Makefile.am               |   2 +
 test/i965_jpeg_encode_test.cpp | 135 +++-----
 test/i965_jpeg_test_data.cpp   | 196 ++---------
 test/i965_jpeg_test_data.h     |  26 +-
 test/i965_streamable.h         |  25 ++
 test/i965_test_environment.cpp |   7 +
 test/i965_test_image_utils.cpp | 747
+++++++++++++++++++++++++++++++++++++++++
 test/i965_test_image_utils.h   |  66 ++++
 test/object_heap_test.cpp      |   4 -
 test/test_utils.h              |  45 ++-
 10 files changed, 970 insertions(+), 283 deletions(-)
 create mode 100644 test/i965_test_image_utils.cpp
 create mode 100644 test/i965_test_image_utils.h
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
_______________________________________________
Libva mailing list
https://lists.freedesktop.org/mailman/listinfo/libva
Loading...