videotestsrc: add pattern with out-of-gamut colors

Adds a pattern with out-of-gamut colors in a checkerboard
pattern with in-gamut neighbors.  Useful for checking YCbCr->RGB
color matrixing.  Correct matrixing and clamping will cause the
checkerboard pattern to be invisible.
This commit is contained in:
David Schleef 2009-10-06 19:35:50 -07:00
parent 730eead9a9
commit 205ada8454
4 changed files with 109 additions and 3 deletions

View file

@ -129,6 +129,7 @@ gst_video_test_src_pattern_get_type (void)
{GST_VIDEO_TEST_SRC_BLINK, "Blink", "blink"},
{GST_VIDEO_TEST_SRC_SMPTE75, "SMPTE 75% color bars", "smpte75"},
{GST_VIDEO_TEST_SRC_ZONE_PLATE, "Zone plate", "zone-plate"},
{GST_VIDEO_TEST_SRC_GAMUT, "Gamut checkers", "gamut"},
{0, NULL, NULL}
};
@ -354,6 +355,9 @@ gst_video_test_src_set_pattern (GstVideoTestSrc * videotestsrc,
case GST_VIDEO_TEST_SRC_ZONE_PLATE:
videotestsrc->make_image = gst_video_test_src_zoneplate;
break;
case GST_VIDEO_TEST_SRC_GAMUT:
videotestsrc->make_image = gst_video_test_src_gamut;
break;
default:
g_assert_not_reached ();
}

View file

@ -54,8 +54,18 @@ G_BEGIN_DECLS
* @GST_VIDEO_TEST_SRC_BLINK: Alternate between black and white
* @GST_VIDEO_TEST_SRC_SMPTE75: SMPTE test pattern (75% color bars)
* @GST_VIDEO_TEST_SRC_ZONE_PLATE: Zone plate
* @GST_VIDEO_TEST_SRC_GAMUT: Gamut checking pattern
*
* The test pattern to produce.
*
* The Gamut pattern creates a checkerboard pattern of colors at the
* edge of the YCbCr gamut and nearby colors that are out of gamut.
* The pattern is divided into 4 regions: black, white, red, and blue.
* After conversion to RGB, the out-of-gamut colors should be converted
* to the same value as their in-gamut neighbors. If the checkerboard
* pattern is still visible after conversion, this indicates a faulty
* conversion. Image manipulation, such as adjusting contrast or
* brightness, can also cause the pattern to be visible.
*/
typedef enum {
GST_VIDEO_TEST_SRC_SMPTE,
@ -72,13 +82,14 @@ typedef enum {
GST_VIDEO_TEST_SRC_CIRCULAR,
GST_VIDEO_TEST_SRC_BLINK,
GST_VIDEO_TEST_SRC_SMPTE75,
GST_VIDEO_TEST_SRC_ZONE_PLATE
GST_VIDEO_TEST_SRC_ZONE_PLATE,
GST_VIDEO_TEST_SRC_GAMUT
} GstVideoTestSrcPattern;
/**
* GstVideoTestSrcColorSpec:
* @GST_VIDEO_TEST_SRC_BT601: ITU-R Rec. BT.601
* @GST_VIDEO_TEST_SRC_BT709: ITU-R Rec. BT.601
* @GST_VIDEO_TEST_SRC_BT601: ITU-R Rec. BT.601/BT.470 (SD)
* @GST_VIDEO_TEST_SRC_BT709: ITU-R Rec. BT.709 (HD)
*
* The color specification to use.
*/

View file

@ -1431,6 +1431,95 @@ gst_video_test_src_circular (GstVideoTestSrc * v, unsigned char *dest,
}
}
void
gst_video_test_src_gamut (GstVideoTestSrc * v, guchar * dest, int w, int h)
{
int x, y;
paintinfo pi = { NULL, };
paintinfo *p = π
struct fourcc_list_struct *fourcc;
struct vts_color_struct_yuv yuv_primary;
struct vts_color_struct_yuv yuv_secondary;
struct vts_color_struct_rgb rgb_primary = { 0 };
struct vts_color_struct_rgb rgb_secondary = { 0 };
struct vts_color_struct_gray gray_primary = { 0 };
struct vts_color_struct_gray gray_secondary = { 0 };
p->rgb_colors = vts_colors_rgb;
if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
p->yuv_colors = vts_colors_bt601_ycbcr_100;
} else {
p->yuv_colors = vts_colors_bt709_ycbcr_100;
}
p->gray_colors = vts_colors_gray_100;
p->width = w;
p->height = h;
fourcc = v->fourcc;
if (fourcc == NULL)
return;
fourcc->paint_setup (p, dest);
p->paint_hline = fourcc->paint_hline;
for (y = 0; y < h; y++) {
int region = (y * 4) / h;
switch (region) {
case 0: /* black */
yuv_primary = p->yuv_colors[COLOR_BLACK];
yuv_secondary = p->yuv_colors[COLOR_BLACK];
yuv_secondary.Y = 0;
rgb_primary = p->rgb_colors[COLOR_BLACK];
rgb_secondary = p->rgb_colors[COLOR_BLACK];
gray_primary = p->gray_colors[COLOR_BLACK];
gray_secondary = p->gray_colors[COLOR_BLACK];
break;
case 1:
yuv_primary = p->yuv_colors[COLOR_WHITE];
yuv_secondary = p->yuv_colors[COLOR_WHITE];
yuv_secondary.Y = 255;
rgb_primary = p->rgb_colors[COLOR_WHITE];
rgb_secondary = p->rgb_colors[COLOR_WHITE];
gray_primary = p->gray_colors[COLOR_WHITE];
gray_secondary = p->gray_colors[COLOR_WHITE];
break;
case 2:
yuv_primary = p->yuv_colors[COLOR_RED];
yuv_secondary = p->yuv_colors[COLOR_RED];
yuv_secondary.V = 255;
rgb_primary = p->rgb_colors[COLOR_RED];
rgb_secondary = p->rgb_colors[COLOR_RED];
gray_primary = p->gray_colors[COLOR_RED];
gray_secondary = p->gray_colors[COLOR_RED];
break;
case 3:
yuv_primary = p->yuv_colors[COLOR_BLUE];
yuv_secondary = p->yuv_colors[COLOR_BLUE];
yuv_secondary.U = 255;
rgb_primary = p->rgb_colors[COLOR_BLUE];
rgb_secondary = p->rgb_colors[COLOR_BLUE];
gray_primary = p->gray_colors[COLOR_BLUE];
gray_secondary = p->gray_colors[COLOR_BLUE];
break;
}
for (x = 0; x < w; x += 8) {
int len = MIN (8, w - x);
if ((x ^ y) & (1 << 4)) {
p->rgb_color = &rgb_primary;
p->yuv_color = &yuv_primary;
p->gray_color = &gray_primary;
} else {
p->rgb_color = &rgb_secondary;
p->yuv_color = &yuv_secondary;
p->gray_color = &gray_secondary;
}
p->paint_hline (p, x, y, len);
}
}
}
static void
paint_setup_I420 (paintinfo * p, unsigned char *dest)
{

View file

@ -114,6 +114,8 @@ void gst_video_test_src_circular (GstVideoTestSrc * v,
unsigned char *dest, int w, int h);
void gst_video_test_src_zoneplate (GstVideoTestSrc * v,
unsigned char *dest, int w, int h);
void gst_video_test_src_gamut (GstVideoTestSrc * v,
unsigned char *dest, int w, int h);
extern struct fourcc_list_struct fourcc_list[];
extern int n_fourccs;