From c063f053890fe54ba53a956d2d19f4d80dc1812b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 2 Sep 2006 12:59:48 +0000 Subject: [PATCH] gst/videotestsrc/videotestsrc.*: Add support for AYUV and the various RGBA formats. Initialise fields of paintinfo st... Original commit message from CVS: * gst/videotestsrc/videotestsrc.c: (paintinfo_find_by_structure), (paint_get_structure), (gst_video_test_src_get_size), (gst_video_test_src_smpte), (gst_video_test_src_snow), (gst_video_test_src_unicolor), (paint_setup_AYUV), (paint_hline_AYUV), (paint_setup_ARGB8888), (paint_setup_ABGR8888), (paint_setup_RGBA8888), (paint_setup_BGRA8888), (paint_hline_str4): * gst/videotestsrc/videotestsrc.h: Add support for AYUV and the various RGBA formats. Initialise fields of paintinfo structs allocated on the stack. * tests/check/elements/videotestsrc.c: (right_shift_colour), (fix_expected_colour), (check_rgb_buf), (got_buf_cb), (GST_START_TEST), (videotestsrc_suite): Add unit tests for videotestsrc's RGB output. --- ChangeLog | 17 ++ gst/videotestsrc/videotestsrc.c | 108 +++++++++- gst/videotestsrc/videotestsrc.h | 2 + tests/check/elements/videotestsrc.c | 305 +++++++++++++++++++++++++++- 4 files changed, 422 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 142432a4b3..0dc5911128 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-09-02 Tim-Philipp Müller + + * gst/videotestsrc/videotestsrc.c: (paintinfo_find_by_structure), + (paint_get_structure), (gst_video_test_src_get_size), + (gst_video_test_src_smpte), (gst_video_test_src_snow), + (gst_video_test_src_unicolor), (paint_setup_AYUV), + (paint_hline_AYUV), (paint_setup_ARGB8888), (paint_setup_ABGR8888), + (paint_setup_RGBA8888), (paint_setup_BGRA8888), (paint_hline_str4): + * gst/videotestsrc/videotestsrc.h: + Add support for AYUV and the various RGBA formats. Initialise + fields of paintinfo structs allocated on the stack. + + * tests/check/elements/videotestsrc.c: (right_shift_colour), + (fix_expected_colour), (check_rgb_buf), (got_buf_cb), + (GST_START_TEST), (videotestsrc_suite): + Add unit tests for videotestsrc's RGB output. + 2006-09-01 Tim-Philipp Müller * gst/videotestsrc/gstvideotestsrc.c: diff --git a/gst/videotestsrc/videotestsrc.c b/gst/videotestsrc/videotestsrc.c index 7529749816..7cdb57d763 100644 --- a/gst/videotestsrc/videotestsrc.c +++ b/gst/videotestsrc/videotestsrc.c @@ -257,6 +257,7 @@ 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); @@ -266,6 +267,10 @@ 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); +static void paint_setup_ARGB8888 (paintinfo * p, unsigned char *dest); +static void paint_setup_ABGR8888 (paintinfo * p, unsigned char *dest); +static void paint_setup_RGBA8888 (paintinfo * p, unsigned char *dest); +static void paint_setup_BGRA8888 (paintinfo * p, unsigned char *dest); static void paint_setup_xRGB8888 (paintinfo * p, unsigned char *dest); static void paint_setup_xBGR8888 (paintinfo * p, unsigned char *dest); static void paint_setup_RGBx8888 (paintinfo * p, unsigned char *dest); @@ -281,6 +286,7 @@ static void paint_hline_IYU2 (paintinfo * p, int x, int y, int w); static void paint_hline_Y41B (paintinfo * p, int x, int y, int w); static void paint_hline_Y42B (paintinfo * p, int x, int y, int w); static void paint_hline_Y800 (paintinfo * p, int x, int y, int w); +static void paint_hline_AYUV (paintinfo * p, int x, int y, int w); #if 0 static void paint_hline_IMC1 (paintinfo * p, int x, int y, int w); @@ -298,6 +304,7 @@ struct fourcc_list_struct fourcc_list[] = { {"Y422", "Y422", 16, paint_setup_UYVY, paint_hline_YUY2}, {"UYNV", "UYNV", 16, paint_setup_UYVY, paint_hline_YUY2}, /* FIXME: UYNV? */ {"YVYU", "YVYU", 16, paint_setup_YVYU, paint_hline_YUY2}, + {"AYUV", "AYUV", 32, paint_setup_AYUV, paint_hline_AYUV}, /* interlaced */ /*{ "IUYV", "IUY2", 16, paint_setup_YVYU, paint_hline_YUY2 }, */ @@ -356,6 +363,14 @@ struct fourcc_list_struct fourcc_list[] = { 0xff000000, 0x00ff0000, 0x0000ff00}, {"RGB ", "BGRx8888", 32, paint_setup_BGRx8888, paint_hline_str4, 1, 24, 0x0000ff00, 0x00ff0000, 0xff000000}, + {"RGB ", "ARGB8888", 32, paint_setup_ARGB8888, paint_hline_str4, 1, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, + {"RGB ", "ABGR8888", 32, paint_setup_ABGR8888, paint_hline_str4, 1, 32, + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}, + {"RGB ", "RGBA8888", 32, paint_setup_RGBA8888, paint_hline_str4, 1, 32, + 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff}, + {"RGB ", "BGRA8888", 32, paint_setup_BGRA8888, paint_hline_str4, 1, 32, + 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff}, {"RGB ", "RGB888", 24, paint_setup_RGB888, paint_hline_str3, 1, 24, 0x00ff0000, 0x0000ff00, 0x000000ff}, {"RGB ", "BGR888", 24, paint_setup_BGR888, paint_hline_str3, 1, 24, @@ -396,6 +411,7 @@ paintinfo_find_by_structure (const GstStructure * structure) int red_mask; int green_mask; int blue_mask; + int alpha_mask; int depth; int bpp; @@ -405,14 +421,26 @@ paintinfo_find_by_structure (const GstStructure * structure) ret &= gst_structure_get_int (structure, "depth", &depth); ret &= gst_structure_get_int (structure, "bpp", &bpp); + if (depth == 32) { + ret &= gst_structure_get_int (structure, "alpha_mask", &alpha_mask); + ret &= (alpha_mask != 0); + } else { + alpha_mask = 0; + } + + if (!ret) { + GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure); + return NULL; + } + for (i = 0; i < n_fourccs; i++) { if (strcmp (fourcc_list[i].fourcc, "RGB ") == 0 && fourcc_list[i].red_mask == red_mask && fourcc_list[i].green_mask == green_mask && fourcc_list[i].blue_mask == blue_mask && + (alpha_mask == 0 || fourcc_list[i].alpha_mask == alpha_mask) && fourcc_list[i].depth == depth && fourcc_list[i].bitspp == bpp) { return fourcc_list + i; - } } return NULL; @@ -463,6 +491,7 @@ paintrect_find_name (const char *name) GstStructure * paint_get_structure (struct fourcc_list_struct * format) { + GstStructure *structure = NULL; unsigned int fourcc; g_return_val_if_fail (format, NULL); @@ -479,17 +508,22 @@ paint_get_structure (struct fourcc_list_struct * format) } else { endianness = G_BIG_ENDIAN; } - return gst_structure_new ("video/x-raw-rgb", + structure = gst_structure_new ("video/x-raw-rgb", "bpp", G_TYPE_INT, format->bitspp, "endianness", G_TYPE_INT, endianness, "depth", G_TYPE_INT, format->depth, "red_mask", G_TYPE_INT, format->red_mask, "green_mask", G_TYPE_INT, format->green_mask, "blue_mask", G_TYPE_INT, format->blue_mask, NULL); + if (format->depth == 32 && format->alpha_mask > 0) { + gst_structure_set (structure, "alpha_mask", G_TYPE_INT, + format->alpha_mask, NULL); + } } else { - return gst_structure_new ("video/x-raw-yuv", + structure = gst_structure_new ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, fourcc, NULL); } + return structure; } /* returns the size in bytes for one video frame of the given dimensions @@ -497,7 +531,7 @@ paint_get_structure (struct fourcc_list_struct * format) int gst_video_test_src_get_size (GstVideoTestSrc * v, int w, int h) { - paintinfo pi = { 0 }; + paintinfo pi = { NULL, }; paintinfo *p = π struct fourcc_list_struct *fourcc; @@ -519,7 +553,7 @@ gst_video_test_src_smpte (GstVideoTestSrc * v, unsigned char *dest, int w, int i; int y1, y2; int j; - paintinfo pi; + paintinfo pi = { NULL, }; paintinfo *p = π struct fourcc_list_struct *fourcc; @@ -627,7 +661,7 @@ gst_video_test_src_snow (GstVideoTestSrc * v, unsigned char *dest, int w, int h) { int i; int j; - paintinfo pi; + paintinfo pi = { NULL, }; paintinfo *p = π struct fourcc_list_struct *fourcc; struct vts_color_struct color; @@ -661,7 +695,7 @@ gst_video_test_src_unicolor (GstVideoTestSrc * v, unsigned char *dest, int w, int h, struct vts_color_struct *color) { int i; - paintinfo pi; + paintinfo pi = { NULL, }; paintinfo *p = π struct fourcc_list_struct *fourcc; @@ -750,6 +784,17 @@ paint_setup_YV12 (paintinfo * p, unsigned char *dest) 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) { @@ -780,6 +825,20 @@ paint_setup_YVYU (paintinfo * p, unsigned char *dest) p->endptr = dest + p->ystride * p->height; } +static void +paint_hline_AYUV (paintinfo * p, int x, int y, int w) +{ + /* TODO: put into colour struct or take value from property maybe */ + const uint8_t alpha_color = 128; + int offset; + + offset = (y * p->ystride) + (x * 4); + oil_splat_u8 (p->yp + offset, 4, &p->color->Y, w); + oil_splat_u8 (p->up + offset, 4, &p->color->U, w); + oil_splat_u8 (p->vp + offset, 4, &p->color->V, w); + oil_splat_u8 (p->ap + offset, 4, &alpha_color, w); +} + static void paint_hline_YUY2 (paintinfo * p, int x, int y, int w) { @@ -979,6 +1038,34 @@ paint_hline_YUV9 (paintinfo * p, int x, int y, int w) #endif } +static void +paint_setup_ARGB8888 (paintinfo * p, unsigned char *dest) +{ + paint_setup_xRGB8888 (p, dest); + p->ap = dest; +} + +static void +paint_setup_ABGR8888 (paintinfo * p, unsigned char *dest) +{ + paint_setup_xBGR8888 (p, dest); + p->ap = dest; +} + +static void +paint_setup_RGBA8888 (paintinfo * p, unsigned char *dest) +{ + paint_setup_RGBx8888 (p, dest); + p->ap = dest + 3; +} + +static void +paint_setup_BGRA8888 (paintinfo * p, unsigned char *dest) +{ + paint_setup_BGRx8888 (p, dest); + p->ap = dest + 3; +} + static void paint_setup_xRGB8888 (paintinfo * p, unsigned char *dest) { @@ -1047,6 +1134,13 @@ paint_hline_str4 (paintinfo * p, int x, int y, int w) oil_splat_u8 (p->yp + offset + x * 4, 4, &p->color->R, w); oil_splat_u8 (p->up + offset + x * 4, 4, &p->color->G, w); oil_splat_u8 (p->vp + offset + x * 4, 4, &p->color->B, w); + + if (p->ap != NULL) { + /* TODO: put into colour struct or take value from property maybe */ + const uint8_t alpha_color = 128; + + oil_splat_u8 (p->ap + offset + (x * 4), 4, &alpha_color, w); + } } static void diff --git a/gst/videotestsrc/videotestsrc.h b/gst/videotestsrc/videotestsrc.h index f10e16f07b..b49ea27ddb 100644 --- a/gst/videotestsrc/videotestsrc.h +++ b/gst/videotestsrc/videotestsrc.h @@ -34,6 +34,7 @@ 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; @@ -56,6 +57,7 @@ struct fourcc_list_struct unsigned int red_mask; unsigned int green_mask; unsigned int blue_mask; + unsigned int alpha_mask; }; struct fourcc_list_struct * diff --git a/tests/check/elements/videotestsrc.c b/tests/check/elements/videotestsrc.c index a38ce88c4b..1378a10fc6 100644 --- a/tests/check/elements/videotestsrc.c +++ b/tests/check/elements/videotestsrc.c @@ -3,6 +3,7 @@ * unit test for videotestsrc * * Copyright (C) <2005> Thomas Vander Stichele + * Copyright (C) <2006> Tim-Philipp Müller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,6 +21,14 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_VALGRIND +# include +#endif + #include #include @@ -115,17 +124,307 @@ GST_START_TEST (test_all_patterns) GST_END_TEST; -/* FIXME: - * add tests for every colorspace */ +static guint32 +right_shift_colour (guint32 mask, guint32 pixel) +{ + if (mask == 0) + return 0; -Suite * + pixel = pixel & mask; + while ((mask & 0x01) == 0) { + mask = mask >> 1; + pixel = pixel >> 1; + } + + return pixel; +} + +static guint8 +fix_expected_colour (guint32 col_mask, guint8 col_expected) +{ + guint32 mask; + gint last = g_bit_nth_msf (col_mask, -1); + gint first = g_bit_nth_lsf (col_mask, -1); + + mask = 1 << (last - first + 1); + mask -= 1; + + g_assert (col_expected == 0x00 || col_expected == 0xff); + + /* this only works because we only check for all-bits-set or no-bits-set */ + return col_expected & mask; +} + +static gboolean +check_rgb_buf (const guint8 * pixels, guint32 r_mask, guint32 g_mask, + guint32 b_mask, guint32 a_mask, guint8 r_expected, guint8 g_expected, + guint8 b_expected, guint endianness, guint bpp, guint depth) +{ + guint32 pixel, red, green, blue, alpha; + + switch (bpp) { + case 32:{ + if (endianness == G_LITTLE_ENDIAN) + pixel = GST_READ_UINT32_LE (pixels); + else + pixel = GST_READ_UINT32_BE (pixels); + break; + } + case 24:{ + if (endianness == G_BIG_ENDIAN) { + pixel = (GST_READ_UINT8 (pixels) << 16) | + (GST_READ_UINT8 (pixels + 1) << 8) | + (GST_READ_UINT8 (pixels + 2) << 0); + } else { + pixel = (GST_READ_UINT8 (pixels + 2) << 16) | + (GST_READ_UINT8 (pixels + 1) << 8) | + (GST_READ_UINT8 (pixels + 0) << 0); + } + break; + } + case 16:{ + if (endianness == G_LITTLE_ENDIAN) + pixel = GST_READ_UINT16_LE (pixels); + else + pixel = GST_READ_UINT16_BE (pixels); + break; + } + } + + red = right_shift_colour (r_mask, pixel); + green = right_shift_colour (g_mask, pixel); + blue = right_shift_colour (b_mask, pixel); + alpha = right_shift_colour (a_mask, pixel); + + /* can't enable this by default, valgrind will complain about accessing + * uninitialised memory for the depth=24,bpp=32 formats ... */ + /* GST_LOG ("pixels: 0x%02x 0x%02x 0x%02x 0x%02x => pixel = 0x%08x", + pixels[0], (guint) pixels[1], pixels[2], pixels[3], pixel); */ + + /* fix up the mask (for rgb15/16) */ + if (bpp == 16) { + r_expected = fix_expected_colour (r_mask, r_expected); + g_expected = fix_expected_colour (g_mask, g_expected); + b_expected = fix_expected_colour (b_mask, b_expected); + } + + fail_unless (red == r_expected, "RED: expected 0x%02x, found 0x%02x", + r_expected, red); + fail_unless (green == g_expected, "GREEN: expected 0x%02x, found 0x%02x", + g_expected, green); + fail_unless (blue == b_expected, "BLUE: expected 0x%02x, found 0x%02x", + b_expected, blue); + + fail_unless (a_mask == 0 || alpha != 0); /* better than nothing */ +} + +static void +got_buf_cb (GstElement * sink, GstBuffer * new_buf, GstPad * pad, + GstBuffer ** p_old_buf) +{ + gst_buffer_replace (p_old_buf, new_buf); +} + +/* tests the positioning of pixels within the various RGB pixel layouts */ +GST_START_TEST (test_rgb_formats) +{ + const struct + { + const gchar *pattern_name; + gint pattern_enum; + guint8 r_expected; + guint8 g_expected; + guint8 b_expected; + } test_patterns[] = { + { + "white", 3, 0xff, 0xff, 0xff}, { + "red", 4, 0xff, 0x00, 0x00}, { + "green", 5, 0x00, 0xff, 0x00}, { + "blue", 6, 0x00, 0x00, 0xff}, { + "black", 2, 0x00, 0x00, 0x00} + }; + const struct + { + const gchar *nick; + guint bpp, depth; + guint32 red_mask, green_mask, blue_mask, alpha_mask; + } rgb_formats[] = { + { + "RGBA", 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff}, { + "ARGB", 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, { + "BGRA", 32, 32, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff}, { + "ABGR", 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}, { + "RGBx", 32, 24, 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000}, { + "xRGB", 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, { + "BGRx", 32, 24, 0x0000ff00, 0x00ff0000, 0xff000000, 0x00000000}, { + "xBGR", 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000}, { + "RGB ", 24, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, { + "BGR ", 24, 24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000}, { + "RGB565", 16, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000}, { + "xRGB1555", 16, 15, 0x00007c00, 0x000003e0, 0x0000001f, 0x0000000} + }; + GstElement *pipeline, *src, *filter, *sink; + const GstCaps *template_caps; + GstBuffer *buf = NULL; + GstPad *srcpad; + gint p, i, e; + + /* test check function */ + fail_unless (right_shift_colour (0x00ff0000, 0x11223344) == 0x22); + + pipeline = gst_pipeline_new ("pipeline"); + src = gst_check_setup_element ("videotestsrc"); + filter = gst_check_setup_element ("capsfilter"); + sink = gst_check_setup_element ("fakesink"); + + gst_bin_add_many (GST_BIN (pipeline), src, filter, sink, NULL); + + fail_unless (gst_element_link (src, filter)); + fail_unless (gst_element_link (filter, sink)); + + srcpad = gst_element_get_pad (src, "src"); + template_caps = gst_pad_get_pad_template_caps (srcpad); + gst_object_unref (srcpad); + + g_object_set (sink, "signal-handoffs", TRUE, NULL); + g_signal_connect (sink, "preroll-handoff", G_CALLBACK (got_buf_cb), &buf); + + GST_LOG ("videotestsrc src template caps: %" GST_PTR_FORMAT, template_caps); + + for (i = 0; i < G_N_ELEMENTS (rgb_formats); ++i) { + for (e = 0; e < 2; ++e) { + guint endianness; + GstCaps *caps; + + if (e == 0) { + endianness = G_BYTE_ORDER; + } else { + endianness = + (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN; + } + + caps = gst_caps_new_simple ("video/x-raw-rgb", + "bpp", G_TYPE_INT, rgb_formats[i].bpp, + "depth", G_TYPE_INT, rgb_formats[i].depth, + "red_mask", G_TYPE_INT, rgb_formats[i].red_mask, + "green_mask", G_TYPE_INT, rgb_formats[i].green_mask, + "blue_mask", G_TYPE_INT, rgb_formats[i].blue_mask, + "width", G_TYPE_INT, 16, "height", G_TYPE_INT, 16, + "endianness", G_TYPE_INT, endianness, + "framerate", GST_TYPE_FRACTION, 1, 1, NULL); + + fail_unless (rgb_formats[i].alpha_mask == 0 || rgb_formats[i].bpp == 32); + + if (rgb_formats[i].alpha_mask != 0) { + gst_structure_set (gst_caps_get_structure (caps, 0), + "alpha_mask", G_TYPE_INT, rgb_formats[i].alpha_mask, NULL); + } + + if (gst_caps_is_subset (caps, template_caps)) { + + /* caps are supported, let's run some tests then ... */ + for (p = 0; p < G_N_ELEMENTS (test_patterns); ++p) { + GstStateChangeReturn state_ret; + + g_object_set (src, "pattern", test_patterns[p].pattern_enum, NULL); + + GST_INFO ("%5s %u/%u %08x %08x %08x %08x %u, pattern=%s", + rgb_formats[i].nick, rgb_formats[i].bpp, rgb_formats[i].depth, + rgb_formats[i].red_mask, rgb_formats[i].green_mask, + rgb_formats[i].blue_mask, rgb_formats[i].alpha_mask, endianness, + test_patterns[p].pattern_name); + + /* now get videotestsrc to produce a buffer with the given caps */ + g_object_set (filter, "caps", caps, NULL); + + state_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + fail_unless (state_ret != GST_STATE_CHANGE_FAILURE, + "pipeline _set_state() to PAUSED failed"); + state_ret = gst_element_get_state (pipeline, NULL, NULL, -1); + fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS, + "pipeline failed going to PAUSED state"); + + state_ret = gst_element_set_state (pipeline, GST_STATE_NULL); + fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS); + + fail_unless (buf != NULL); + + /* check buffer caps */ + { + GstStructure *s; + gint v; + + fail_unless (GST_BUFFER_CAPS (buf) != NULL); + + s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); + fail_unless (gst_structure_get_int (s, "bpp", &v)); + fail_unless_equals_int (v, rgb_formats[i].bpp); + fail_unless (gst_structure_get_int (s, "depth", &v)); + fail_unless_equals_int (v, rgb_formats[i].depth); + fail_unless (gst_structure_get_int (s, "red_mask", &v)); + fail_unless_equals_int (v, rgb_formats[i].red_mask); + fail_unless (gst_structure_get_int (s, "green_mask", &v)); + fail_unless_equals_int (v, rgb_formats[i].green_mask); + fail_unless (gst_structure_get_int (s, "blue_mask", &v)); + fail_unless_equals_int (v, rgb_formats[i].blue_mask); + /* there mustn't be an alpha_mask if there's no alpha component */ + if (rgb_formats[i].depth == 32) { + fail_unless (gst_structure_get_int (s, "alpha_mask", &v)); + fail_unless_equals_int (v, rgb_formats[i].alpha_mask); + } else { + fail_unless (gst_structure_get_value (s, "alpha_mask") == NULL); + } + } + + + /* now check the first pixel */ + fail_unless (check_rgb_buf (GST_BUFFER_DATA (buf), + rgb_formats[i].red_mask, rgb_formats[i].green_mask, + rgb_formats[i].blue_mask, rgb_formats[i].alpha_mask, + test_patterns[p].r_expected, test_patterns[p].g_expected, + test_patterns[p].b_expected, endianness, rgb_formats[i].bpp, + rgb_formats[i].depth)); + + gst_buffer_unref (buf); + buf = NULL; + } + + } else { + GST_INFO ("videotestsrc doesn't support format %" GST_PTR_FORMAT, caps); + } + + gst_caps_unref (caps); + } + } + + gst_object_unref (pipeline); +} + +GST_END_TEST; + + +/* FIXME: add tests for YUV formats */ + +static Suite * videotestsrc_suite (void) { Suite *s = suite_create ("videotestsrc"); TCase *tc_chain = tcase_create ("general"); suite_add_tcase (s, tc_chain); + +#ifdef HAVE_VALGRIND + if (RUNNING_ON_VALGRIND) { + /* otherwise valgrind errors out when liboil probes CPU extensions + * during which it causes SIGILLs etc. to be fired */ + g_setenv ("OIL_CPU_FLAGS", "0", 0); + /* test_rgb_formats takes a bit longer, so increase timeout */ + tcase_set_timeout (tc_chain, 5 * 60); + } +#endif + tcase_add_test (tc_chain, test_all_patterns); + tcase_add_test (tc_chain, test_rgb_formats); return s; }