mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
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:
parent
7035f1be3e
commit
863a0f81f8
4 changed files with 336 additions and 294 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue