From: Ronald S. Bultje Date: Sat, 10 May 2003 14:36:34 +0000 (+0000) Subject: This implements filtered-caps negotiation for all the v4l*src elements, and removes... X-Git-Tag: 1.19.3~511^2~15422 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=863a0f81f822f147ea1df3cd6903953d1e2da02a;p=platform%2Fupstream%2Fgstreamer.git This implements filtered-caps negotiation for all the v4l*src elements, and removes the accompanying properties since... Original commit message from CVS: This implements filtered-caps negotiation for all the v4l*src elements, and removes the accompanying properties since they're no longer needed --- diff --git a/sys/v4l/gstv4lmjpegsrc.c b/sys/v4l/gstv4lmjpegsrc.c index bcac29969f..92ef56fa32 100644 --- a/sys/v4l/gstv4lmjpegsrc.c +++ b/sys/v4l/gstv4lmjpegsrc.c @@ -47,17 +47,16 @@ enum { /* arguments */ enum { ARG_0, +#if 0 ARG_X_OFFSET, ARG_Y_OFFSET, ARG_F_WIDTH, ARG_F_HEIGHT, - ARG_H_DECIMATION, - ARG_V_DECIMATION, - ARG_WIDTH, - ARG_HEIGHT, + /* normally, we would want to use subframe capture, however, + * for the time being it's easier if we disable it first */ +#endif ARG_QUALITY, ARG_NUMBUFS, - ARG_BUFSIZE, ARG_USE_FIXED_FPS }; @@ -75,6 +74,8 @@ static gboolean gst_v4lmjpegsrc_srcconvert (GstPad *pad, static GstPadLinkReturn gst_v4lmjpegsrc_srcconnect (GstPad *pad, GstCaps *caps); static GstBuffer* gst_v4lmjpegsrc_get (GstPad *pad); +static GstCaps* gst_v4lmjpegsrc_getcaps (GstPad *pad, + GstCaps *caps); /* get/set params */ static void gst_v4lmjpegsrc_set_property (GObject *object, @@ -145,6 +146,7 @@ gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass) parent_class = g_type_class_ref(GST_TYPE_V4LELEMENT); +#if 0 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_X_OFFSET, g_param_spec_int("x_offset","x_offset","x_offset", G_MININT,G_MAXINT,0,G_PARAM_WRITABLE)); @@ -157,20 +159,7 @@ gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass) g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_F_HEIGHT, g_param_spec_int("frame_height","frame_height","frame_height", G_MININT,G_MAXINT,0,G_PARAM_WRITABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_H_DECIMATION, - g_param_spec_int("h_decimation","h_decimation","h_decimation", - G_MININT,G_MAXINT,0,G_PARAM_WRITABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_V_DECIMATION, - g_param_spec_int("v_decimation","v_decimation","v_decimation", - G_MININT,G_MAXINT,0,G_PARAM_WRITABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDTH, - g_param_spec_int("width","width","width", - G_MININT,G_MAXINT,0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT, - g_param_spec_int("height","height","height", - G_MININT,G_MAXINT,0,G_PARAM_READABLE)); +#endif g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_QUALITY, g_param_spec_int("quality","quality","quality", @@ -179,9 +168,6 @@ gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass) g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUMBUFS, g_param_spec_int("num_buffers","num_buffers","num_buffers", G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFSIZE, - g_param_spec_int("buffer_size","buffer_size","buffer_size", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_USE_FIXED_FPS, g_param_spec_boolean("use_fixed_fps", "Use Fixed FPS", @@ -227,6 +213,7 @@ gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc) gst_element_add_pad(GST_ELEMENT(v4lmjpegsrc), v4lmjpegsrc->srcpad); gst_pad_set_get_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_get); + gst_pad_set_getcaps_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_getcaps); gst_pad_set_link_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_srcconnect); gst_pad_set_convert_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_srcconvert); @@ -238,21 +225,16 @@ gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc) (GstBufferPoolBufferFreeFunction)gst_v4lmjpegsrc_buffer_free, v4lmjpegsrc); +#if 0 v4lmjpegsrc->frame_width = 0; v4lmjpegsrc->frame_height = 0; v4lmjpegsrc->x_offset = -1; v4lmjpegsrc->y_offset = -1; - - v4lmjpegsrc->horizontal_decimation = 4; - v4lmjpegsrc->vertical_decimation = 4; - - v4lmjpegsrc->end_width = 0; - v4lmjpegsrc->end_height = 0; +#endif v4lmjpegsrc->quality = 50; v4lmjpegsrc->numbufs = 64; - v4lmjpegsrc->bufsize = 256; /* no clock */ v4lmjpegsrc->clock = NULL; @@ -343,14 +325,44 @@ gst_v4lmjpegsrc_srcconvert (GstPad *pad, } +static inline gulong +calc_bufsize (int hor_dec, + int ver_dec) +{ + guint8 div = hor_dec * ver_dec; + guint32 num = (1024 * 512) / (div); + guint32 result = 2; + + num--; + while (num) { + num >>= 1; + result <<= 1; + } + + if (result > (512 * 1024)) + return (512 * 1024); + if (result < 8192) + return 8192; + return result; +} + +#define gst_caps_get_int_range(caps, name, min, max) \ + gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \ + name), \ + min, max) + + static GstPadLinkReturn gst_v4lmjpegsrc_srcconnect (GstPad *pad, GstCaps *caps) { GstPadLinkReturn ret_val; - GstV4lMjpegSrc *v4lmjpegsrc; - - v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad)); + GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad)); + gint hor_dec, ver_dec; + gint w, h; + gint max_w = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxwidth, + max_h = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxheight; + gulong bufsize; /* in case the buffers are active (which means that we already * did capsnego before and didn't clean up), clean up anyways */ @@ -370,11 +382,64 @@ gst_v4lmjpegsrc_srcconnect (GstPad *pad, * our own mime type back and it'll work. Other properties are to be set * by the src, not by the opposite caps */ + if (gst_caps_has_property(caps, "width")) { + if (gst_caps_has_fixed_property(caps, "width")) { + gst_caps_get_int(caps, "width", &w); + } else { + int max; + gst_caps_get_int_range(caps, "width", &w, &max); + } + } + if (gst_caps_has_property(caps, "height")) { + if (gst_caps_has_fixed_property(caps, "height")) { + gst_caps_get_int(caps, "height", &h); + } else { + int max; + gst_caps_get_int_range(caps, "height", &h, &max); + } + } + + /* figure out decimation */ + if (w >= max_w) { + hor_dec = 1; + } else if (w*2 >= max_w) { + hor_dec = 2; + } else { + hor_dec = 4; + } + if (h >= max_h) { + ver_dec = 1; + } else if (h*2 >= max_h) { + ver_dec = 2; + } else { + ver_dec = 4; + } + + /* calculate bufsize */ + bufsize = calc_bufsize(hor_dec, ver_dec); + /* set buffer info */ - if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize)) + if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, + v4lmjpegsrc->numbufs, bufsize)) { return GST_PAD_LINK_REFUSED; + } /* set capture parameters and mmap the buffers */ + if (hor_dec == ver_dec) { + if (!gst_v4lmjpegsrc_set_capture(v4lmjpegsrc, + hor_dec, + v4lmjpegsrc->quality)) { + return GST_PAD_LINK_REFUSED; + } + } else { + if (!gst_v4lmjpegsrc_set_capture_m(v4lmjpegsrc, + 0, 0, max_w, max_h, + hor_dec, ver_dec, + v4lmjpegsrc->quality)) { + return GST_PAD_LINK_REFUSED; + } + } +#if 0 if (!v4lmjpegsrc->frame_width && !v4lmjpegsrc->frame_height && v4lmjpegsrc->x_offset < 0 && v4lmjpegsrc->y_offset < 0 && v4lmjpegsrc->horizontal_decimation == v4lmjpegsrc->vertical_decimation) @@ -392,6 +457,8 @@ gst_v4lmjpegsrc_srcconnect (GstPad *pad, v4lmjpegsrc->quality)) return GST_PAD_LINK_REFUSED; } +#endif + /* we now have an actual width/height - *set it* */ caps = gst_caps_new("v4lmjpegsrc_caps", "video/jpeg", @@ -520,6 +587,30 @@ gst_v4lmjpegsrc_get (GstPad *pad) } +static GstCaps* +gst_v4lmjpegsrc_getcaps (GstPad *pad, + GstCaps *_caps) +{ + GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad)); + struct video_capability *vcap = &GST_V4LELEMENT(v4lmjpegsrc)->vcap; + GstCaps *caps; + + if (!GST_V4L_IS_OPEN(GST_V4LELEMENT(v4lmjpegsrc))) { + return NULL; + } + + caps = GST_CAPS_NEW("v4lmjpegsrc_jpeg_caps", + "video/jpeg", + "width", GST_PROPS_INT_RANGE(vcap->maxwidth/4, + vcap->maxwidth), + "height", GST_PROPS_INT_RANGE(vcap->maxheight/4, + vcap->maxheight), + NULL); + + return caps; +} + + static void gst_v4lmjpegsrc_set_property (GObject *object, guint prop_id, @@ -532,6 +623,7 @@ gst_v4lmjpegsrc_set_property (GObject *object, v4lmjpegsrc = GST_V4LMJPEGSRC(object); switch (prop_id) { +#if 0 case ARG_X_OFFSET: v4lmjpegsrc->x_offset = g_value_get_int(value); break; @@ -544,21 +636,13 @@ gst_v4lmjpegsrc_set_property (GObject *object, case ARG_F_HEIGHT: v4lmjpegsrc->frame_height = g_value_get_int(value); break; - case ARG_H_DECIMATION: - v4lmjpegsrc->horizontal_decimation = g_value_get_int(value); - break; - case ARG_V_DECIMATION: - v4lmjpegsrc->vertical_decimation = g_value_get_int(value); - break; +#endif case ARG_QUALITY: v4lmjpegsrc->quality = g_value_get_int(value); break; case ARG_NUMBUFS: v4lmjpegsrc->numbufs = g_value_get_int(value); break; - case ARG_BUFSIZE: - v4lmjpegsrc->bufsize = g_value_get_int(value); - break; case ARG_USE_FIXED_FPS: if (!GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsrc))) { v4lmjpegsrc->use_fixed_fps = g_value_get_boolean(value); @@ -583,12 +667,7 @@ gst_v4lmjpegsrc_get_property (GObject *object, v4lmjpegsrc = GST_V4LMJPEGSRC(object); switch (prop_id) { - case ARG_WIDTH: - g_value_set_int(value, v4lmjpegsrc->end_width); - break; - case ARG_HEIGHT: - g_value_set_int(value, v4lmjpegsrc->end_height); - break; +#if 0 case ARG_X_OFFSET: g_value_set_int(value, v4lmjpegsrc->x_offset); break; @@ -601,21 +680,13 @@ gst_v4lmjpegsrc_get_property (GObject *object, case ARG_F_HEIGHT: g_value_set_int(value, v4lmjpegsrc->frame_height); break; - case ARG_H_DECIMATION: - g_value_set_int(value, v4lmjpegsrc->horizontal_decimation); - break; - case ARG_V_DECIMATION: - g_value_set_int(value, v4lmjpegsrc->vertical_decimation); - break; +#endif case ARG_QUALITY: g_value_set_int(value, v4lmjpegsrc->quality); break; case ARG_NUMBUFS: g_value_set_int(value, v4lmjpegsrc->breq.count); break; - case ARG_BUFSIZE: - g_value_set_int(value, v4lmjpegsrc->breq.size); - break; case ARG_USE_FIXED_FPS: g_value_set_boolean(value, v4lmjpegsrc->use_fixed_fps); break; diff --git a/sys/v4l/gstv4lmjpegsrc.h b/sys/v4l/gstv4lmjpegsrc.h index fea2a5672d..ccac3c56a8 100644 --- a/sys/v4l/gstv4lmjpegsrc.h +++ b/sys/v4l/gstv4lmjpegsrc.h @@ -74,20 +74,19 @@ struct _GstV4lMjpegSrc { /* how are we going to push buffers? */ gboolean use_fixed_fps; + /* end size */ + gint end_width, end_height; + /* caching values */ +#if 0 gint x_offset; gint y_offset; gint frame_width; gint frame_height; - gint horizontal_decimation; - gint vertical_decimation; - - gint end_width; - gint end_height; +#endif gint quality; gint numbufs; - gint bufsize; /* in KB */ }; struct _GstV4lMjpegSrcClass { diff --git a/sys/v4l/gstv4lsrc.c b/sys/v4l/gstv4lsrc.c index c42b482bc6..898e87f36f 100644 --- a/sys/v4l/gstv4lsrc.c +++ b/sys/v4l/gstv4lsrc.c @@ -48,10 +48,6 @@ enum { /* arguments */ enum { ARG_0, - ARG_WIDTH, - ARG_HEIGHT, - ARG_PALETTE, - ARG_PALETTE_NAME, ARG_NUMBUFS, ARG_BUFSIZE, ARG_USE_FIXED_FPS @@ -70,6 +66,8 @@ static gboolean gst_v4lsrc_srcconvert (GstPad *pad, gint64 *dest_value); static GstPadLinkReturn gst_v4lsrc_srcconnect (GstPad *pad, GstCaps *caps); +static GstCaps* gst_v4lsrc_getcaps (GstPad *pad, + GstCaps *caps); static GstBuffer* gst_v4lsrc_get (GstPad *pad); /* get/set params */ @@ -98,11 +96,9 @@ static void gst_v4lsrc_buffer_free (GstBufferPool *pool, static void gst_v4lsrc_set_clock (GstElement *element, GstClock *clock); +static GstPadTemplate *src_template = NULL; -static GstCaps *capslist = NULL; -static GstPadTemplate *src_template; - -static GstElementClass *parent_class = NULL;\ +static GstElementClass *parent_class = NULL; static guint gst_v4lsrc_signals[LAST_SIGNAL] = { 0 }; @@ -141,19 +137,6 @@ gst_v4lsrc_class_init (GstV4lSrcClass *klass) parent_class = g_type_class_ref(GST_TYPE_V4LELEMENT); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDTH, - g_param_spec_int("width", "Width", "Video width", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT, - g_param_spec_int("height", "Height", "Video height", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PALETTE, - g_param_spec_int("palette", "Palette", "Video palette", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PALETTE_NAME, - g_param_spec_string("palette_name", "Palette name", - "Name of the current video palette", - NULL, G_PARAM_READABLE)); g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUMBUFS, g_param_spec_int("num_buffers","Num Buffers","Number of buffers", G_MININT,G_MAXINT,0,G_PARAM_READABLE)); @@ -199,6 +182,7 @@ gst_v4lsrc_init (GstV4lSrc *v4lsrc) gst_element_add_pad(GST_ELEMENT(v4lsrc), v4lsrc->srcpad); gst_pad_set_get_function (v4lsrc->srcpad, gst_v4lsrc_get); + gst_pad_set_getcaps_function (v4lsrc->srcpad, gst_v4lsrc_getcaps); gst_pad_set_link_function (v4lsrc->srcpad, gst_v4lsrc_srcconnect); gst_pad_set_convert_function (v4lsrc->srcpad, gst_v4lsrc_srcconvert); @@ -210,9 +194,6 @@ gst_v4lsrc_init (GstV4lSrc *v4lsrc) (GstBufferPoolBufferFreeFunction)gst_v4lsrc_buffer_free, v4lsrc); - v4lsrc->palette = 0; /* means 'any' - user can specify a specific palette */ - v4lsrc->width = 160; - v4lsrc->height = 120; v4lsrc->buffer_size = 0; /* no clock */ @@ -303,6 +284,108 @@ gst_v4lsrc_srcconvert (GstPad *pad, return TRUE; } +static GstCaps * +gst_v4lsrc_palette_to_caps (int palette, + GstPropsEntry *width, + GstPropsEntry *height) +{ + guint32 fourcc; + GstCaps *caps; + + switch (palette) { + case VIDEO_PALETTE_YUV422: + case VIDEO_PALETTE_YUYV: + fourcc = GST_MAKE_FOURCC('Y','U','Y','2'); + break; + case VIDEO_PALETTE_YUV420P: + fourcc = GST_MAKE_FOURCC('I','4','2','0'); + break; + case VIDEO_PALETTE_UYVY: + fourcc = GST_MAKE_FOURCC('U','Y','V','Y'); + break; + case VIDEO_PALETTE_YUV411: + fourcc = GST_MAKE_FOURCC('Y','4','1','P'); + break; + case VIDEO_PALETTE_RGB555: + case VIDEO_PALETTE_RGB565: + case VIDEO_PALETTE_RGB24: + case VIDEO_PALETTE_RGB32: + fourcc = GST_MAKE_FOURCC('R','G','B',' '); + break; + default: + return NULL; + } + + if (fourcc == GST_MAKE_FOURCC('R','G','B',' ')) { + gint depth = 0; + guint32 r_mask = 0, g_mask = 0, b_mask = 0; + + switch (palette) { + case VIDEO_PALETTE_RGB555: + depth = 15; + r_mask = 0x7c00; g_mask = 0x03e0; b_mask = 0x001f; + break; + case VIDEO_PALETTE_RGB565: + depth = 16; + r_mask = 0xf800; g_mask = 0x07f0; b_mask = 0x001f; + break; + case VIDEO_PALETTE_RGB24: + depth = 24; + r_mask = 0xff0000; g_mask = 0x00ff00; b_mask = 0x0000ff; + break; + case VIDEO_PALETTE_RGB32: + depth = 32; + r_mask = 0x00ff0000; g_mask = 0x0000ff00; b_mask = 0x000000ff; + break; + default: + g_assert_not_reached(); + break; + } + + caps = GST_CAPS_NEW("v4lsrc_rgb_caps", + "video/raw", + "format", GST_PROPS_FOURCC(fourcc), + "bpp", GST_PROPS_INT((depth+1) & ~1), + "depth", GST_PROPS_INT(depth), + "endianness", GST_PROPS_INT(G_BYTE_ORDER), + "red_mask", GST_PROPS_INT(r_mask), + "green_mask", GST_PROPS_INT(g_mask), + "blue_mask", GST_PROPS_INT(b_mask), + NULL); + } else { + caps = GST_CAPS_NEW("v4lsrc_yuv_caps", + "video/raw", + "format", GST_PROPS_FOURCC(fourcc), + NULL); + } + + gst_props_add_entry(caps->properties, width); + gst_props_add_entry(caps->properties, height); + + return caps; +} + +#define gst_v4lsrc_palette_to_caps_fixed(palette, width, height) \ + gst_v4lsrc_palette_to_caps(palette, \ + gst_props_entry_new("width", \ + GST_PROPS_INT(width)), \ + gst_props_entry_new("height", \ + GST_PROPS_INT(height)) \ + ) +#define gst_v4lsrc_palette_to_caps_range(palette, min_w, max_w, min_h, max_h) \ + gst_v4lsrc_palette_to_caps(palette, \ + gst_props_entry_new("width", \ + GST_PROPS_INT_RANGE(min_w, \ + max_w)), \ + gst_props_entry_new("height", \ + GST_PROPS_INT_RANGE(min_h, \ + max_h)) \ + ) + +#define gst_caps_get_int_range(caps, name, min, max) \ + gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \ + name), \ + min, max) static GstPadLinkReturn gst_v4lsrc_srcconnect (GstPad *pad, @@ -327,123 +410,76 @@ gst_v4lsrc_srcconnect (GstPad *pad, return GST_PAD_LINK_DELAYED; } - palette = v4lsrc->palette; - /* TODO: caps = gst_caps_normalize(capslist); */ for (caps = vscapslist ; caps != NULL ; caps = vscapslist = vscapslist->next) { guint32 fourcc; - gint depth; + gint depth, w, h; gst_caps_get_fourcc_int (caps, "format", &fourcc); - - if (v4lsrc->palette > 0) - { - switch (v4lsrc->palette) - { - case VIDEO_PALETTE_YUV420P: - if (fourcc != GST_MAKE_FOURCC('I','4','2','0') && - fourcc != GST_MAKE_FOURCC('I','Y','U','V')) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5; - goto try_caps; - case VIDEO_PALETTE_YUV422: - case VIDEO_PALETTE_YUYV: - if (fourcc != GST_MAKE_FOURCC('Y','U','Y','2')) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case VIDEO_PALETTE_UYVY: - if (fourcc != GST_MAKE_FOURCC('U','Y','V','Y')) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case VIDEO_PALETTE_YUV411: - if (fourcc != GST_MAKE_FOURCC('Y','4','1','P')) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5; - goto try_caps; - case VIDEO_PALETTE_RGB555: - depth = gst_caps_get_int (caps, "depth", &depth); - if (fourcc != GST_MAKE_FOURCC('R','G','B',' ') || - depth != 15) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case VIDEO_PALETTE_RGB565: - depth = gst_caps_get_int (caps, "depth", &depth); - if (fourcc != GST_MAKE_FOURCC('R','G','B',' ') || - depth != 16) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case VIDEO_PALETTE_RGB24: - depth = gst_caps_get_int (caps, "depth", &depth); - if (fourcc != GST_MAKE_FOURCC('R','G','B',' ') || - depth != 24) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 3; - goto try_caps; - case VIDEO_PALETTE_RGB32: - depth = gst_caps_get_int (caps, "depth", &depth); - if (fourcc != GST_MAKE_FOURCC('R','G','B',' ') || - depth != 32) - goto try_next; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 4; - goto try_caps; - default: - goto try_next; + if (gst_caps_has_property(caps, "width")) { + if (gst_caps_has_fixed_property(caps, "width")) { + gst_caps_get_int(caps, "width", &w); + } else { + int max; + gst_caps_get_int_range(caps, "width", &w, &max); } } - else - { - switch (fourcc) - { - case GST_MAKE_FOURCC('I','4','2','0'): - case GST_MAKE_FOURCC('I','Y','U','V'): - palette = VIDEO_PALETTE_YUV420P; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5; - goto try_caps; - case GST_MAKE_FOURCC('Y','U','Y','2'): - palette = VIDEO_PALETTE_YUV422; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case GST_MAKE_FOURCC('U','Y','V','Y'): - palette = VIDEO_PALETTE_UYVY; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case GST_MAKE_FOURCC('Y','4','1','P'): - palette = VIDEO_PALETTE_YUV411; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5; - goto try_caps; - case GST_MAKE_FOURCC('R','G','B',' '): - depth = gst_caps_get_int (caps, "depth", &depth); - switch (depth) - { - case 15: - palette = VIDEO_PALETTE_RGB555; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case 16: - palette = VIDEO_PALETTE_RGB565; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2; - goto try_caps; - case 24: - palette = VIDEO_PALETTE_RGB24; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 3; - goto try_caps; - case 32: - palette = VIDEO_PALETTE_RGB32; - v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 4; - goto try_caps; - default: - goto try_next; - } - default: - goto try_next; + if (gst_caps_has_property(caps, "height")) { + if (gst_caps_has_fixed_property(caps, "height")) { + gst_caps_get_int(caps, "height", &h); + } else { + int max; + gst_caps_get_int_range(caps, "height", &h, &max); } } + switch (fourcc) + { + case GST_MAKE_FOURCC('I','4','2','0'): + case GST_MAKE_FOURCC('I','Y','U','V'): + palette = VIDEO_PALETTE_YUV420P; + v4lsrc->buffer_size = ((w+1)&~1) * ((h+1)&~1) * 1.5; + goto try_caps; + case GST_MAKE_FOURCC('Y','U','Y','2'): + palette = VIDEO_PALETTE_YUV422; + v4lsrc->buffer_size = ((w+1)&~1) * h * 2; + goto try_caps; + case GST_MAKE_FOURCC('U','Y','V','Y'): + palette = VIDEO_PALETTE_UYVY; + v4lsrc->buffer_size = ((w+1)&~1) * h * 2; + goto try_caps; + case GST_MAKE_FOURCC('Y','4','1','P'): + palette = VIDEO_PALETTE_YUV411; + v4lsrc->buffer_size = ((w+3)&~3) * h * 1.5; + goto try_caps; + case GST_MAKE_FOURCC('R','G','B',' '): + depth = gst_caps_get_int (caps, "depth", &depth); + switch (depth) + { + case 15: + palette = VIDEO_PALETTE_RGB555; + v4lsrc->buffer_size = w * h * 2; + goto try_caps; + case 16: + palette = VIDEO_PALETTE_RGB565; + v4lsrc->buffer_size = w * h * 2; + goto try_caps; + case 24: + palette = VIDEO_PALETTE_RGB24; + v4lsrc->buffer_size = w * h * 3; + goto try_caps; + case 32: + palette = VIDEO_PALETTE_RGB32; + v4lsrc->buffer_size = w * h * 4; + goto try_caps; + default: + goto try_next; + } + default: + goto try_next; + } + /* if this caps wasn't useful, try the next one */ try_next: continue; @@ -455,32 +491,7 @@ gst_v4lsrc_srcconnect (GstPad *pad, continue; /* try to connect the pad/caps with the actual width/height */ - if (palette >= VIDEO_PALETTE_RGB565 && palette <= VIDEO_PALETTE_RGB555) { - gint depth; - gint bpp; - - gst_caps_get_int(caps, "bpp", &bpp), - gst_caps_get_int(caps, "depth", &depth), - - newcaps = gst_caps_new("v4lsrc_caps", - "video/raw", - gst_props_new( - "format", GST_PROPS_FOURCC(fourcc), - "width", GST_PROPS_INT(v4lsrc->width), - "height", GST_PROPS_INT(v4lsrc->height), - "bpp", GST_PROPS_INT(bpp), - "depth", GST_PROPS_INT(depth), - NULL ) ); - } - else { - newcaps = gst_caps_new("v4lsrc_caps", - "video/raw", - gst_props_new( - "format", GST_PROPS_FOURCC(fourcc), - "width", GST_PROPS_INT(v4lsrc->width), - "height", GST_PROPS_INT(v4lsrc->height), - NULL ) ); - } + newcaps = gst_v4lsrc_palette_to_caps_fixed(palette, w, h); gst_caps_debug (newcaps, "new caps to set on v4lsrc's src pad"); @@ -489,7 +500,7 @@ gst_v4lsrc_srcconnect (GstPad *pad, else if (ret_val == GST_PAD_LINK_DELAYED) return GST_PAD_LINK_DELAYED; - if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, palette)) + if (!gst_v4lsrc_set_capture(v4lsrc, w, h, palette)) return GST_PAD_LINK_REFUSED; if (!gst_v4lsrc_capture_init(v4lsrc)) @@ -503,6 +514,40 @@ gst_v4lsrc_srcconnect (GstPad *pad, } +static GstCaps * +gst_v4lsrc_getcaps (GstPad *pad, + GstCaps *caps) +{ + GstCaps *list = NULL; + GstV4lSrc *v4lsrc = GST_V4LSRC(gst_pad_get_parent(pad)); + int palette[] = { + VIDEO_PALETTE_YUV422, + VIDEO_PALETTE_YUV420P, + VIDEO_PALETTE_UYVY, + VIDEO_PALETTE_YUV411P, + VIDEO_PALETTE_RGB555, + VIDEO_PALETTE_RGB565, + VIDEO_PALETTE_RGB24, + VIDEO_PALETTE_RGB32, + }, i; + struct video_capability *vcap = &GST_V4LELEMENT(v4lsrc)->vcap; + + if (!GST_V4L_IS_OPEN(GST_V4LELEMENT(v4lsrc))) { + return NULL; + } + + for (i = 0; i < 8; i++) { + GstCaps *one; + one = gst_v4lsrc_palette_to_caps_range(palette[i], + vcap->minwidth, vcap->maxwidth, + vcap->minheight, vcap->maxheight); + list = gst_caps_append(list, one); + } + + return list; +} + + static GstBuffer* gst_v4lsrc_get (GstPad *pad) { @@ -611,18 +656,6 @@ gst_v4lsrc_set_property (GObject *object, v4lsrc = GST_V4LSRC(object); switch (prop_id) { - case ARG_WIDTH: - v4lsrc->width = g_value_get_int(value); - break; - - case ARG_HEIGHT: - v4lsrc->height = g_value_get_int(value); - break; - - case ARG_PALETTE: - v4lsrc->palette = g_value_get_int(value); - break; - case ARG_USE_FIXED_FPS: if (!GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lsrc))) { v4lsrc->use_fixed_fps = g_value_get_boolean(value); @@ -648,22 +681,6 @@ gst_v4lsrc_get_property (GObject *object, v4lsrc = GST_V4LSRC(object); switch (prop_id) { - case ARG_WIDTH: - g_value_set_int(value, v4lsrc->mmap.width); - break; - - case ARG_HEIGHT: - g_value_set_int(value, v4lsrc->mmap.height); - break; - - case ARG_PALETTE: - g_value_set_int(value, v4lsrc->mmap.format); - break; - - case ARG_PALETTE_NAME: - g_value_set_string(value, g_strdup(palette_name[v4lsrc->mmap.format])); - break; - case ARG_NUMBUFS: g_value_set_int(value, v4lsrc->mbuf.frames); break; @@ -804,57 +821,17 @@ plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; - GstCaps *caps; - gint i; - gulong format[5] = { GST_MAKE_FOURCC('Y','U','Y','2'), /* VIDEO_PALETTE_YUV422/_YUYV */ - GST_MAKE_FOURCC('I','4','2','0'), /* VIDEO_PALETTE_YUV420P */ - GST_MAKE_FOURCC('I','Y','U','V'), /* VIDEO_PALETTE_YUV420P */ - GST_MAKE_FOURCC('U','Y','V','Y'), /* VIDEO_PALETTE_UYVY */ - GST_MAKE_FOURCC('Y','4','1','P') /* VIDEO_PALETTE_YUV411 */ - }; - gint rgb_bpp[4] = { 16, 16, 24, 32 }; - gint rgb_depth[4] = { 15, 16, 24, 32 }; /* create an elementfactory for the v4lsrc */ factory = gst_element_factory_new("v4lsrc",GST_TYPE_V4LSRC, &gst_v4lsrc_details); g_return_val_if_fail(factory != NULL, FALSE); - /* make a list of all available caps - first the YUV formats */ - for (i=0;i<5;i++) - { - caps = gst_caps_new ("v4lsrc_caps", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC(format[i]), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT), - NULL ) - ); - capslist = gst_caps_append(capslist, caps); - } - - /* now all the RGB formats */ - for (i=0;i<4;i++) - { - caps = gst_caps_new ("v4lsrc_caps", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT), - "bpp", GST_PROPS_INT(rgb_bpp[i]), - "depth", GST_PROPS_INT(rgb_depth[i]), - NULL ) - ); - capslist = gst_caps_append(capslist, caps); - } - src_template = gst_pad_template_new ( "src", GST_PAD_SRC, GST_PAD_ALWAYS, - capslist, NULL); + NULL); gst_element_factory_add_pad_template (factory, src_template); diff --git a/sys/v4l/gstv4lsrc.h b/sys/v4l/gstv4lsrc.h index 6a7d299c8c..9c2070ac60 100644 --- a/sys/v4l/gstv4lsrc.h +++ b/sys/v4l/gstv4lsrc.h @@ -85,11 +85,6 @@ struct _GstV4lSrc { /* how are we going to push buffers? */ gboolean use_fixed_fps; - - /* caching values */ - gint width; - gint height; - gint palette; }; struct _GstV4lSrcClass {