diff options
-rw-r--r-- | libkms++/dumbframebuffer.cpp | 1 | ||||
-rw-r--r-- | libkmstest/testpat.cpp | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/libkms++/dumbframebuffer.cpp b/libkms++/dumbframebuffer.cpp index f422081..9de02da 100644 --- a/libkms++/dumbframebuffer.cpp +++ b/libkms++/dumbframebuffer.cpp @@ -59,6 +59,7 @@ static const map<PixelFormat, FormatInfo> format_info_array = { { PixelFormat::VYUY, { 1, { { 32, 2, 1 } }, } }, /* YUV semi-planar */ { PixelFormat::NV12, { 2, { { 8, 1, 1, }, { 16, 2, 2 } }, } }, + { PixelFormat::NV21, { 2, { { 8, 1, 1, }, { 16, 2, 2 } }, } }, /* RGB16 */ { PixelFormat::RGB565, { 1, { { 16, 1, 1 } }, } }, /* RGB32 */ diff --git a/libkmstest/testpat.cpp b/libkmstest/testpat.cpp index b0b67a4..f9cf907 100644 --- a/libkmstest/testpat.cpp +++ b/libkmstest/testpat.cpp @@ -87,6 +87,48 @@ static void draw_yuv422_macropixel(DumbFramebuffer& buf, unsigned x, unsigned y, } } +static void draw_yuv420_macropixel(DumbFramebuffer& buf, unsigned x, unsigned y, + YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4) +{ + ASSERT((x & 1) == 0); + ASSERT((y & 1) == 0); + + uint8_t *py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x); + uint8_t *py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x); + + uint8_t *puv = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x); + + uint8_t y0 = yuv1.y; + uint8_t y1 = yuv2.y; + uint8_t y2 = yuv3.y; + uint8_t y3 = yuv4.y; + uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4; + uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4; + + switch (buf.format()) { + case PixelFormat::NV12: + py1[0] = y0; + py1[1] = y1; + py2[0] = y2; + py2[1] = y3; + puv[0] = u; + puv[1] = v; + break; + + case PixelFormat::NV21: + py1[0] = y0; + py1[1] = y1; + py2[0] = y2; + py2[1] = y3; + puv[0] = v; + puv[1] = u; + break; + + default: + throw std::invalid_argument("invalid pixelformat"); + } +} + static RGB get_test_pattern_pixel(DumbFramebuffer& fb, unsigned x, unsigned y) { unsigned w = fb.width(); @@ -184,6 +226,21 @@ static void draw_test_pattern_impl(DumbFramebuffer& fb) } } break; + + case PixelFormat::NV12: + case PixelFormat::NV21: + for (y = 0; y < h; y += 2) { + for (x = 0; x < w; x += 2) { + RGB pixel00 = get_test_pattern_pixel(fb, x, y); + RGB pixel10 = get_test_pattern_pixel(fb, x + 1, y); + RGB pixel01 = get_test_pattern_pixel(fb, x, y + 1); + RGB pixel11 = get_test_pattern_pixel(fb, x + 1, y + 1); + draw_yuv420_macropixel(fb, x, y, + pixel00.yuv(), pixel10.yuv(), + pixel01.yuv(), pixel11.yuv()); + } + } + break; default: throw std::invalid_argument("unknown pixelformat"); } |