diff options
author | David Schleef <ds@schleef.org> | 2010-06-03 18:14:05 -0700 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-06-03 23:57:46 -0700 |
commit | 90a2cd5cc5761ed9a8491e157bd959e3f06949f5 (patch) | |
tree | f847b3b83b8e5908754f2d620bba319164c55148 /gst/bayer | |
parent | 2db6d968d82297414a401773e4e8ccf58391137a (diff) |
bayer2rgb: handle other bayer formats
Diffstat (limited to 'gst/bayer')
-rw-r--r-- | gst/bayer/gstbayer2rgb.c | 99 |
1 files changed, 62 insertions, 37 deletions
diff --git a/gst/bayer/gstbayer2rgb.c b/gst/bayer/gstbayer2rgb.c index ac88202c5..3a1adacef 100644 --- a/gst/bayer/gstbayer2rgb.c +++ b/gst/bayer/gstbayer2rgb.c @@ -85,6 +85,15 @@ #define GST_CAT_DEFAULT gst_bayer2rgb_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); +enum +{ + GST_BAYER_2_RGB_FORMAT_BGGR = 0, + GST_BAYER_2_RGB_FORMAT_GBRG, + GST_BAYER_2_RGB_FORMAT_GRBG, + GST_BAYER_2_RGB_FORMAT_RGGB +}; + + #define GST_TYPE_BAYER2RGB (gst_bayer2rgb_get_type()) #define GST_BAYER2RGB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BAYER2RGB,GstBayer2RGB)) #define GST_IS_BAYER2RGB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BAYER2RGB)) @@ -108,6 +117,7 @@ struct _GstBayer2RGB int r_off; /* offset for red */ int g_off; /* offset for green */ int b_off; /* offset for blue */ + int format; }; struct _GstBayer2RGBClass @@ -252,29 +262,43 @@ static gboolean gst_bayer2rgb_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { - GstBayer2RGB *filter = GST_BAYER2RGB (base); + GstBayer2RGB *bayer2rgb = GST_BAYER2RGB (base); GstStructure *structure; int val, bpp; + const char *format; GST_DEBUG ("in caps %" GST_PTR_FORMAT " out caps %" GST_PTR_FORMAT, incaps, outcaps); structure = gst_caps_get_structure (incaps, 0); - gst_structure_get_int (structure, "width", &filter->width); - gst_structure_get_int (structure, "height", &filter->height); - filter->stride = GST_ROUND_UP_4 (filter->width); + gst_structure_get_int (structure, "width", &bayer2rgb->width); + gst_structure_get_int (structure, "height", &bayer2rgb->height); + bayer2rgb->stride = GST_ROUND_UP_4 (bayer2rgb->width); + + format = gst_structure_get_string (structure, "format"); + if (g_str_equal (format, "bggr")) { + bayer2rgb->format = GST_BAYER_2_RGB_FORMAT_BGGR; + } else if (g_str_equal (format, "gbrg")) { + bayer2rgb->format = GST_BAYER_2_RGB_FORMAT_GBRG; + } else if (g_str_equal (format, "grbg")) { + bayer2rgb->format = GST_BAYER_2_RGB_FORMAT_GRBG; + } else if (g_str_equal (format, "rggb")) { + bayer2rgb->format = GST_BAYER_2_RGB_FORMAT_RGGB; + } else { + return FALSE; + } /* To cater for different RGB formats, we need to set params for later */ structure = gst_caps_get_structure (outcaps, 0); gst_structure_get_int (structure, "bpp", &bpp); - filter->pixsize = bpp / 8; + bayer2rgb->pixsize = bpp / 8; gst_structure_get_int (structure, "red_mask", &val); - filter->r_off = get_pix_offset (val, bpp); + bayer2rgb->r_off = get_pix_offset (val, bpp); gst_structure_get_int (structure, "green_mask", &val); - filter->g_off = get_pix_offset (val, bpp); + bayer2rgb->g_off = get_pix_offset (val, bpp); gst_structure_get_int (structure, "blue_mask", &val); - filter->b_off = get_pix_offset (val, bpp); + bayer2rgb->b_off = get_pix_offset (val, bpp); return TRUE; } @@ -364,6 +388,25 @@ gst_bayer2rgb_get_unit_size (GstBaseTransform * base, GstCaps * caps, #define BLUE 2 /* Pure blue element */ #define GREENR 3 /* Green element which is on a red line */ +static int +get_pixel_type (GstBayer2RGB * filter, int x, int y) +{ + int type; + + if (((x ^ filter->format) & 1)) { + if ((y ^ (filter->format >> 1)) & 1) + type = RED; + else + type = GREENB; + } else { + if ((y ^ (filter->format >> 1)) & 1) + type = GREENR; + else + type = BLUE; + } + return type; +} + /* 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 +506,15 @@ vborder (uint8_t * input, uint8_t * output, int right_left, static void do_row0_col0 (uint8_t * input, uint8_t * output, GstBayer2RGB * filter) { - int type; - /* 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, get_pixel_type (filter, 1, 0), filter); + hborder (input, output, 1, get_pixel_type (filter, 1, filter->height - 1), + 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, get_pixel_type (filter, 0, 1), filter); + vborder (input, output, 1, get_pixel_type (filter, filter->width - 1, 1), + filter); } static void @@ -520,24 +555,17 @@ corner (uint8_t * input, uint8_t * output, int x, int y, static void do_corners (uint8_t * input, uint8_t * output, GstBayer2RGB * filter) { - int typ; - /* Top left */ - corner (input, output, 0, 0, 1, 1, BLUE, filter); + corner (input, output, 0, 0, 1, 1, get_pixel_type (filter, 0, 0), filter); /* Bottom left */ corner (input, output, 0, filter->height - 1, 1, -1, - (filter->height & 1) ? BLUE : GREENR, filter); + get_pixel_type (filter, 0, filter->height - 1), filter); /* Top right */ corner (input, output, filter->width - 1, 0, -1, 0, - (filter->width & 1) ? BLUE : GREENB, filter); + get_pixel_type (filter, filter->width - 1, 0), filter); /* Bottom right */ - if (filter->width & 1) /* if odd # cols, B or GB */ - typ = BLUE; - else - typ = GREENB; /* if even # cols, B or GR */ - typ |= (filter->height & 1); /* if odd # rows, GB or GR */ corner (input, output, filter->width - 1, filter->height - 1, -1, -1, - typ, filter); + get_pixel_type (filter, filter->width - 1, filter->height - 1), filter); } static void @@ -563,10 +591,7 @@ do_body (uint8_t * input, uint8_t * output, GstBayer2RGB * filter) * 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 = get_pixel_type (filter, 1, h); /* Calculate the starting position for the row */ op = h * filter->width * filter->pixsize; /* output (converted) pos */ ip = h * filter->stride; /* input (bayer data) pos */ |