GNOME Bugzilla – Bug 571976
[PATCH] enable selection of start pixel colour
Last modified: 2009-02-16 14:22:30 UTC
Different image sources provide images with different pixels at the origin. The attached patch adds a parameter to the bayer plugin, that allows to support them all. Other information: Index: gst/bayer/gstbayer2rgb.c =================================================================== RCS file: /cvs/gstreamer/gst-plugins-bad/gst/bayer/gstbayer2rgb.c,v retrieving revision 1.6 diff -u -r1.6 gstbayer2rgb.c --- gst/bayer/gstbayer2rgb.c 12 Jun 2008 14:49:15 -0000 1.6 +++ gst/bayer/gstbayer2rgb.c 19 Nov 2008 11:04:17 -0000 @@ -96,6 +96,18 @@ typedef void (*GstBayer2RGBProcessFunc) (GstBayer2RGB *, guint8 *, guint); +/* + * We define values for the colors, just to make the code more readable. + */ +typedef enum +{ + RED, /* Pure red element */ + GREENB, /* Green element which is on a blue line */ + BLUE, /* Pure blue element */ + GREENR, /* Green element which is on a red line */ + GST_BAYER_START_PIXEL_COLOUR_DEFAULT = GREENB, +} GstBayerStartPixelColour; + struct _GstBayer2RGB { GstBaseTransform basetransform; @@ -108,6 +120,8 @@ int r_off; /* offset for red */ int g_off; /* offset for green */ int b_off; /* offset for blue */ + + GstBayerStartPixelColour start_colour; }; struct _GstBayer2RGBClass @@ -138,7 +152,8 @@ enum { - PROP_0 + PROP_0, + PROP_BAYER_START_PIXEL_COLOUR, }; #define DEBUG_INIT(bla) \ @@ -178,6 +193,26 @@ gst_caps_from_string (SINK_CAPS))); } +#define GST_BAYER_START_PIXEL_COLOUR (gst_bayer_start_pixel_colour_get_type ()) +static GType +gst_bayer_start_pixel_colour_get_type (void) +{ + static GType start_pixel_colour_type; + static const GEnumValue colour_types[] = { + {RED, "Red", "red"}, + {BLUE, "Blue", "blue"}, + {GREENR, "Green-Red", "green_red"}, + {GREENB, "Green-Blue", "green_blue"}, + {0, NULL, NULL} + }; + + if (!start_pixel_colour_type) + start_pixel_colour_type = + g_enum_register_static ("GstBayerStartPixelColour", colour_types); + + return start_pixel_colour_type; +} + static void gst_bayer2rgb_class_init (GstBayer2RGBClass * klass) { @@ -195,6 +230,11 @@ GST_DEBUG_FUNCPTR (gst_bayer2rgb_set_caps); GST_BASE_TRANSFORM_CLASS (klass)->transform = GST_DEBUG_FUNCPTR (gst_bayer2rgb_transform); + + g_object_class_install_property (gobject_class, PROP_BAYER_START_PIXEL_COLOUR, + g_param_spec_enum ("start_pixel", "B/R/GB/GR first", "Colour of the start pixel", + GST_BAYER_START_PIXEL_COLOUR, GST_BAYER_START_PIXEL_COLOUR_DEFAULT, + G_PARAM_READWRITE)); } static void @@ -209,8 +249,12 @@ gst_bayer2rgb_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { + GstBayer2RGB *filter = GST_BAYER2RGB (object); switch (prop_id) { + case PROP_BAYER_START_PIXEL_COLOUR: + filter->start_colour = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -221,8 +265,12 @@ gst_bayer2rgb_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { + GstBayer2RGB *filter = GST_BAYER2RGB (object); switch (prop_id) { + case PROP_BAYER_START_PIXEL_COLOUR: + g_value_set_enum (value, filter->start_colour); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -289,6 +337,7 @@ filter->r_off = 0; filter->g_off = 0; filter->b_off = 0; + filter->start_colour = GST_BAYER_START_PIXEL_COLOUR_DEFAULT; } static GstCaps * @@ -356,14 +405,6 @@ return FALSE; } -/* - * We define values for the colors, just to make the code more readable. - */ -#define RED 0 /* Pure red element */ -#define GREENB 1 /* Green element which is on a blue line */ -#define BLUE 2 /* Pure blue element */ -#define GREENR 3 /* Green element which is on a red line */ - /* Routine to generate the top and bottom edges (not including corners) */ static void hborder (uint8_t * input, uint8_t * output, int bot_top, @@ -463,23 +504,40 @@ static void do_row0_col0 (uint8_t * input, uint8_t * output, GstBayer2RGB * filter) { - int type; + GstBayerStartPixelColour type_top, type_bottom, type_left, type_right; + + type_top = filter->start_colour; + + switch (filter->start_colour) { + case RED: + type_bottom = filter->height & 1 ? type_top : GREENB; + type_left = BLUE; + type_right = filter->width & 1 ? type_left : GREENB; + break; + case BLUE: + type_bottom = filter->height & 1 ? type_top : GREENR;; + type_left = RED; + type_right = filter->width & 1 ? type_left : GREENR; + break; + case GREENR: + type_bottom = filter->height & 1 ? type_top : BLUE;; + type_left = GREENB; + type_right = filter->width & 1 ? type_left : BLUE; + break; + case GREENB: + type_bottom = filter->height & 1 ? type_top : RED; + type_left = GREENR; + type_right = filter->width & 1 ? type_left : RED; + break; + } /* Horizontal edges */ - hborder (input, output, 0, GREENB, filter); - if (filter->height & 1) - type = GREENB; /* odd # rows, "bottom" edge same as top */ - else - type = RED; /* even #, bottom side different */ - hborder (input, output, 1, type, filter); + hborder (input, output, 0, type_top, filter); + hborder (input, output, 1, type_bottom, filter); /* Vertical edges */ - vborder (input, output, 0, GREENR, filter); - if (filter->width & 1) - type = GREENR; /* odd # cols, "right" edge same as left */ - else - type = RED; /* even #, right side different */ - vborder (input, output, 1, type, filter); + vborder (input, output, 0, type_left, filter); + vborder (input, output, 1, type_right, filter); } static void @@ -542,9 +600,9 @@ static void do_body (uint8_t * input, uint8_t * output, GstBayer2RGB * filter) { - int ip, op; /* input and output pointers */ - int w, h; /* loop indices */ - int type; /* calculated colour of current element */ + int ip, op; /* input and output pointers */ + int w, h; /* loop indices */ + GstBayerStartPixelColour type; /* calculated colour of current element */ int a1, a2; int v1, v2, h1, h2; @@ -562,10 +620,24 @@ * the pixel at position (1,1). Assuming BG format, this should * be RED for odd-numbered rows and GREENB for even rows. */ - if (h & 1) - type = RED; - else - type = GREENB; + + type = filter->start_colour; + + switch (filter->start_colour) { + case RED: + type = h & 1 ? GREENB : RED; + break; + case BLUE: + type = h & 1 ? GREENR : BLUE; + break; + case GREENR: + type = h & 1 ? BLUE : GREENR; + break; + case GREENB: + type = h & 1 ? RED : GREENB; + break; + } + /* Calculate the starting position for the row */ op = h * filter->width * filter->pixsize; /* output (converted) pos */ ip = h * filter->stride; /* input (bayer data) pos */
Please take a look at bug #566614. We want to make this configurable via a caps field *** This bug has been marked as a duplicate of 566614 ***