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
This commit is contained in:
Ronald S. Bultje 2003-05-10 14:36:34 +00:00
parent 7035f1be3e
commit 863a0f81f8
4 changed files with 336 additions and 294 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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);

View file

@ -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 {