tests/check/libs/video.c: Add unit test that makes sure that the strides, offsets and sizes returned for the various ...

Original commit message from CVS:
* tests/check/libs/video.c: (paintinfo), (paintinfo_struct),
(fourcc_list_struct), (fourcc_list), (fourcc_get_size),
(paint_setup_I420), (paint_setup_YV12), (paint_setup_AYUV),
(paint_setup_YUY2), (paint_setup_UYVY), (paint_setup_YVYU),
(paint_setup_IYU2), (paint_setup_Y41B), (paint_setup_Y42B),
(paint_setup_Y800), (paint_setup_YVU9), (paint_setup_YUV9),
(gst_video_format_is_packed), (video_format_is_packed):
Add unit test that makes sure that the strides, offsets and
sizes returned for the various YUV formats by the new video API
match the old reference implementation in videotestsrc.
This commit is contained in:
Tim-Philipp Müller 2008-03-02 18:24:37 +00:00
parent 843366350e
commit f82c6ab4f4
2 changed files with 412 additions and 20 deletions

View file

@ -1,3 +1,16 @@
2008-03-02 Tim-Philipp Müller <tim at centricular dot net>
* tests/check/libs/video.c: (paintinfo), (paintinfo_struct),
(fourcc_list_struct), (fourcc_list), (fourcc_get_size),
(paint_setup_I420), (paint_setup_YV12), (paint_setup_AYUV),
(paint_setup_YUY2), (paint_setup_UYVY), (paint_setup_YVYU),
(paint_setup_IYU2), (paint_setup_Y41B), (paint_setup_Y42B),
(paint_setup_Y800), (paint_setup_YVU9), (paint_setup_YUV9),
(gst_video_format_is_packed), (video_format_is_packed):
Add unit test that makes sure that the strides, offsets and
sizes returned for the various YUV formats by the new video API
match the old reference implementation in videotestsrc.
2008-03-02 Tim-Philipp Müller <tim at centricular dot net>
* gst-libs/gst/video/video.c: (gst_video_calculate_display_ratio),

View file

@ -1,8 +1,8 @@
/* GStreamer
*
* unit test for video
/* GStreamer unit test for video
*
* Copyright (C) <2003> David A. Schleef <ds@schleef.org>
* Copyright (C) <2006> Jan Schmidt <thaytan@mad.scientist.com>
* Copyright (C) <2008> Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -31,6 +31,399 @@
#include <gst/video/video.h>
#include <string.h>
/* These are from the current/old videotestsrc; we check our new public API
* in libgstvideo against the old one to make sure the sizes and offsets
* end up the same */
typedef struct paintinfo_struct paintinfo;
struct paintinfo_struct
{
unsigned char *dest; /* pointer to first byte of video data */
unsigned char *yp, *up, *vp; /* pointers to first byte of each component
* for both packed/planar YUV and RGB */
unsigned char *ap; /* pointer to first byte of alpha component */
unsigned char *endptr; /* pointer to byte beyond last video data */
int ystride;
int ustride;
int vstride;
int width;
int height;
};
struct fourcc_list_struct
{
char *fourcc;
char *name;
int bitspp;
void (*paint_setup) (paintinfo * p, unsigned char *dest);
};
static void paint_setup_I420 (paintinfo * p, unsigned char *dest);
static void paint_setup_YV12 (paintinfo * p, unsigned char *dest);
static void paint_setup_YUY2 (paintinfo * p, unsigned char *dest);
static void paint_setup_UYVY (paintinfo * p, unsigned char *dest);
static void paint_setup_YVYU (paintinfo * p, unsigned char *dest);
static void paint_setup_IYU2 (paintinfo * p, unsigned char *dest);
static void paint_setup_Y41B (paintinfo * p, unsigned char *dest);
static void paint_setup_Y42B (paintinfo * p, unsigned char *dest);
static void paint_setup_Y800 (paintinfo * p, unsigned char *dest);
static void paint_setup_AYUV (paintinfo * p, unsigned char *dest);
#if 0
static void paint_setup_IMC1 (paintinfo * p, unsigned char *dest);
static void paint_setup_IMC2 (paintinfo * p, unsigned char *dest);
static void paint_setup_IMC3 (paintinfo * p, unsigned char *dest);
static void paint_setup_IMC4 (paintinfo * p, unsigned char *dest);
#endif
static void paint_setup_YUV9 (paintinfo * p, unsigned char *dest);
static void paint_setup_YVU9 (paintinfo * p, unsigned char *dest);
int fourcc_get_size (struct fourcc_list_struct *fourcc, int w, int h);
struct fourcc_list_struct fourcc_list[] = {
/* packed */
{"YUY2", "YUY2", 16, paint_setup_YUY2},
{"UYVY", "UYVY", 16, paint_setup_UYVY},
{"Y422", "Y422", 16, paint_setup_UYVY},
{"UYNV", "UYNV", 16, paint_setup_UYVY}, /* FIXME: UYNV? */
{"YVYU", "YVYU", 16, paint_setup_YVYU},
{"AYUV", "AYUV", 32, paint_setup_AYUV},
/* interlaced */
/*{ "IUYV", "IUY2", 16, paint_setup_YVYU }, */
/* inverted */
/*{ "cyuv", "cyuv", 16, paint_setup_YVYU }, */
/*{ "Y41P", "Y41P", 12, paint_setup_YVYU }, */
/* interlaced */
/*{ "IY41", "IY41", 12, paint_setup_YVYU }, */
/*{ "Y211", "Y211", 8, paint_setup_YVYU }, */
/*{ "Y41T", "Y41T", 12, paint_setup_YVYU }, */
/*{ "Y42P", "Y42P", 16, paint_setup_YVYU }, */
/*{ "CLJR", "CLJR", 8, paint_setup_YVYU }, */
/*{ "IYU1", "IYU1", 12, paint_setup_YVYU }, */
{"IYU2", "IYU2", 24, paint_setup_IYU2},
/* planar */
/* YVU9 */
{"YVU9", "YVU9", 9, paint_setup_YVU9},
/* YUV9 */
{"YUV9", "YUV9", 9, paint_setup_YUV9},
/* IF09 */
/* YV12 */
{"YV12", "YV12", 12, paint_setup_YV12},
/* I420 */
{"I420", "I420", 12, paint_setup_I420},
/* NV12 */
/* NV21 */
#if 0
/* IMC1 */
{"IMC1", "IMC1", 16, paint_setup_IMC1},
/* IMC2 */
{"IMC2", "IMC2", 12, paint_setup_IMC2},
/* IMC3 */
{"IMC3", "IMC3", 16, paint_setup_IMC3},
/* IMC4 */
{"IMC4", "IMC4", 12, paint_setup_IMC4},
#endif
/* CLPL */
/* Y41B */
{"Y41B", "Y41B", 12, paint_setup_Y41B},
/* Y42B */
{"Y42B", "Y42B", 16, paint_setup_Y42B},
/* Y800 grayscale */
{"Y800", "Y800", 8, paint_setup_Y800}
};
/* returns the size in bytes for one video frame of the given dimensions
* given the fourcc */
int
fourcc_get_size (struct fourcc_list_struct *fourcc, int w, int h)
{
paintinfo pi = { NULL, };
paintinfo *p = &pi;
p->width = w;
p->height = h;
fourcc->paint_setup (p, NULL);
return (unsigned long) p->endptr;
}
static void
paint_setup_I420 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->up = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
p->ustride = GST_ROUND_UP_8 (p->width) / 2;
p->vp = p->up + p->ustride * GST_ROUND_UP_2 (p->height) / 2;
p->vstride = GST_ROUND_UP_8 (p->ystride) / 2;
p->endptr = p->vp + p->vstride * GST_ROUND_UP_2 (p->height) / 2;
}
static void
paint_setup_YV12 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->vp = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
p->vstride = GST_ROUND_UP_8 (p->ystride) / 2;
p->up = p->vp + p->vstride * GST_ROUND_UP_2 (p->height) / 2;
p->ustride = GST_ROUND_UP_8 (p->ystride) / 2;
p->endptr = p->up + p->ustride * GST_ROUND_UP_2 (p->height) / 2;
}
static void
paint_setup_AYUV (paintinfo * p, unsigned char *dest)
{
p->ap = dest;
p->yp = dest + 1;
p->up = dest + 2;
p->vp = dest + 3;
p->ystride = p->width * 4;
p->endptr = dest + p->ystride * p->height;
}
static void
paint_setup_YUY2 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->up = dest + 1;
p->vp = dest + 3;
p->ystride = GST_ROUND_UP_2 (p->width) * 2;
p->endptr = dest + p->ystride * p->height;
}
static void
paint_setup_UYVY (paintinfo * p, unsigned char *dest)
{
p->yp = dest + 1;
p->up = dest;
p->vp = dest + 2;
p->ystride = GST_ROUND_UP_2 (p->width) * 2;
p->endptr = dest + p->ystride * p->height;
}
static void
paint_setup_YVYU (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->up = dest + 3;
p->vp = dest + 1;
p->ystride = GST_ROUND_UP_2 (p->width) * 2;
p->endptr = dest + p->ystride * p->height;
}
static void
paint_setup_IYU2 (paintinfo * p, unsigned char *dest)
{
/* untested */
p->yp = dest + 1;
p->up = dest + 0;
p->vp = dest + 2;
p->ystride = GST_ROUND_UP_4 (p->width * 3);
p->endptr = dest + p->ystride * p->height;
}
static void
paint_setup_Y41B (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->up = p->yp + p->ystride * p->height;
p->ustride = GST_ROUND_UP_8 (p->width) / 4;
p->vp = p->up + p->ustride * p->height;
p->vstride = GST_ROUND_UP_8 (p->width) / 4;
p->endptr = p->vp + p->vstride * p->height;
}
static void
paint_setup_Y42B (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->up = p->yp + p->ystride * p->height;
p->ustride = GST_ROUND_UP_8 (p->width) / 2;
p->vp = p->up + p->ustride * p->height;
p->vstride = GST_ROUND_UP_8 (p->width) / 2;
p->endptr = p->vp + p->vstride * p->height;
}
static void
paint_setup_Y800 (paintinfo * p, unsigned char *dest)
{
/* untested */
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->endptr = dest + p->ystride * p->height;
}
#if 0
static void
paint_setup_IMC1 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->up = dest + p->width * p->height;
p->vp = dest + p->width * p->height + p->width * p->height / 2;
}
static void
paint_setup_IMC2 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->vp = dest + p->width * p->height;
p->up = dest + p->width * p->height + p->width / 2;
}
static void
paint_setup_IMC3 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->up = dest + p->width * p->height + p->width * p->height / 2;
p->vp = dest + p->width * p->height;
}
static void
paint_setup_IMC4 (paintinfo * p, unsigned char *dest)
{
p->yp = dest;
p->vp = dest + p->width * p->height + p->width / 2;
p->up = dest + p->width * p->height;
}
#endif
static void
paint_setup_YVU9 (paintinfo * p, unsigned char *dest)
{
int h = GST_ROUND_UP_4 (p->height);
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->vp = p->yp + p->ystride * GST_ROUND_UP_4 (p->height);
p->vstride = GST_ROUND_UP_4 (p->ystride / 4);
p->up = p->vp + p->vstride * GST_ROUND_UP_4 (h / 4);
p->ustride = GST_ROUND_UP_4 (p->ystride / 4);
p->endptr = p->up + p->ustride * GST_ROUND_UP_4 (h / 4);
}
static void
paint_setup_YUV9 (paintinfo * p, unsigned char *dest)
{
/* untested */
int h = GST_ROUND_UP_4 (p->height);
p->yp = dest;
p->ystride = GST_ROUND_UP_4 (p->width);
p->up = p->yp + p->ystride * h;
p->ustride = GST_ROUND_UP_4 (p->ystride / 4);
p->vp = p->up + p->ustride * GST_ROUND_UP_4 (h / 4);
p->vstride = GST_ROUND_UP_4 (p->ystride / 4);
p->endptr = p->vp + p->vstride * GST_ROUND_UP_4 (h / 4);
}
#define gst_video_format_is_packed video_format_is_packed
static gboolean
video_format_is_packed (GstVideoFormat fmt)
{
switch (fmt) {
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
case GST_VIDEO_FORMAT_Y41B:
case GST_VIDEO_FORMAT_Y42B:
return FALSE;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
return TRUE;
default:
g_return_val_if_reached (FALSE);
}
return FALSE;
}
GST_START_TEST (test_video_formats)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (fourcc_list); ++i) {
GstVideoFormat fmt;
const gchar *s;
guint32 fourcc;
guint w, h;
s = fourcc_list[i].fourcc;
fourcc = GST_MAKE_FOURCC (s[0], s[1], s[2], s[3]);
fmt = gst_video_format_from_fourcc (fourcc);
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
continue;
GST_INFO ("Fourcc %s, packed=%d", fourcc_list[i].fourcc,
gst_video_format_is_packed (fmt));
fail_unless (gst_video_format_is_yuv (fmt));
/* use any non-NULL pointer so we can compare against NULL */
{
paintinfo paintinfo = { 0, };
fourcc_list[i].paint_setup (&paintinfo, (unsigned char *) s);
if (paintinfo.ap != NULL) {
fail_unless (gst_video_format_has_alpha (fmt));
} else {
fail_if (gst_video_format_has_alpha (fmt));
}
}
for (w = 1; w <= 65; ++w) {
for (h = 1; h <= 65; ++h) {
paintinfo paintinfo = { 0, };
GST_LOG ("%s, %dx%d", fourcc_list[i].fourcc, w, h);
paintinfo.width = w;
paintinfo.height = h;
fourcc_list[i].paint_setup (&paintinfo, NULL);
fail_unless_equals_int (gst_video_format_get_row_stride (fmt, 0, w),
paintinfo.ystride);
if (!gst_video_format_is_packed (fmt)) {
/* planar */
fail_unless_equals_int (gst_video_format_get_row_stride (fmt, 1, w),
paintinfo.ustride);
fail_unless_equals_int (gst_video_format_get_row_stride (fmt, 2, w),
paintinfo.vstride);
/* check component_width * height against offsets/size somehow? */
}
fail_unless_equals_int (gst_video_format_get_component_offset (fmt, 0,
w, h), (unsigned long) paintinfo.yp);
fail_unless_equals_int (gst_video_format_get_component_offset (fmt, 1,
w, h), (unsigned long) paintinfo.up);
fail_unless_equals_int (gst_video_format_get_component_offset (fmt, 2,
w, h), (unsigned long) paintinfo.vp);
fail_unless_equals_int (gst_video_format_get_size (fmt, w, h),
(unsigned long) paintinfo.endptr);
}
}
}
}
GST_END_TEST;
GST_START_TEST (test_dar_calc)
{
guint display_ratio_n, display_ratio_d;
@ -55,31 +448,17 @@ GST_START_TEST (test_dar_calc)
GST_END_TEST;
Suite *
static Suite *
video_suite (void)
{
Suite *s = suite_create ("video support library");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_video_formats);
tcase_add_test (tc_chain, test_dar_calc);
return s;
}
int
main (int argc, char **argv)
{
int nf;
Suite *s = video_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}
GST_CHECK_MAIN (video);