mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
Updated all plugins to new capsnego format and added some small usability enhancements to v4lelement
Original commit message from CVS: Updated all plugins to new capsnego format and added some small usability enhancements to v4lelement
This commit is contained in:
parent
3333429a0d
commit
6dd1750d19
9 changed files with 464 additions and 323 deletions
|
@ -39,7 +39,9 @@ enum {
|
|||
enum {
|
||||
ARG_0,
|
||||
ARG_CHANNEL,
|
||||
ARG_CHANNEL_NAME,
|
||||
ARG_NORM,
|
||||
ARG_NORM_NAME,
|
||||
ARG_HAS_TUNER,
|
||||
ARG_FREQUENCY,
|
||||
ARG_HAS_AUDIO,
|
||||
|
@ -119,9 +121,15 @@ gst_v4lelement_class_init (GstV4lElementClass *klass)
|
|||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNEL,
|
||||
g_param_spec_int("channel","channel","channel",
|
||||
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNEL_NAME,
|
||||
g_param_spec_string("channel_name","channel_name","channel_name",
|
||||
NULL, G_PARAM_READABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NORM,
|
||||
g_param_spec_int("norm","norm","norm",
|
||||
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NORM_NAME,
|
||||
g_param_spec_string("norm_name","norm_name","norm_name",
|
||||
NULL, G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_TUNER,
|
||||
g_param_spec_boolean("has_tuner","has_tuner","has_tuner",
|
||||
|
@ -159,10 +167,9 @@ gst_v4lelement_class_init (GstV4lElementClass *klass)
|
|||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
|
||||
g_param_spec_string("device","device","device",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_NAME,
|
||||
g_param_spec_string("device_name","device_name","device_name",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
NULL, G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_CAPTURE,
|
||||
g_param_spec_boolean("can_capture","can_capture","can_capture",
|
||||
|
@ -326,7 +333,7 @@ gst_v4lelement_set_property (GObject *object,
|
|||
v4lelement->videodev = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
default:
|
||||
//G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -353,11 +360,26 @@ gst_v4lelement_get_property (GObject *object,
|
|||
gst_v4l_get_chan_norm(v4lelement, &temp_i, NULL);
|
||||
g_value_set_int(value, temp_i);
|
||||
break;
|
||||
case ARG_CHANNEL_NAME:
|
||||
if (GST_V4L_IS_OPEN(v4lelement))
|
||||
g_value_set_string(value, g_strdup(v4lelement->vchan.name));
|
||||
else
|
||||
g_value_set_string(value, g_strdup("Unknown"));
|
||||
break;
|
||||
case ARG_NORM:
|
||||
if (GST_V4L_IS_OPEN(v4lelement))
|
||||
gst_v4l_get_chan_norm(v4lelement, NULL, &temp_i);
|
||||
g_value_set_int(value, temp_i);
|
||||
break;
|
||||
case ARG_NORM_NAME:
|
||||
if (GST_V4L_IS_OPEN(v4lelement))
|
||||
{
|
||||
gst_v4l_get_chan_norm(v4lelement, NULL, &temp_i);
|
||||
g_value_set_string(value, g_strdup(norm_name[temp_i]));
|
||||
}
|
||||
else
|
||||
g_value_set_string(value, g_strdup("Unknwon"));
|
||||
break;
|
||||
case ARG_HAS_TUNER:
|
||||
g_value_set_boolean(value, FALSE);
|
||||
if (GST_V4L_IS_OPEN(v4lelement))
|
||||
|
@ -454,7 +476,7 @@ gst_v4lelement_get_property (GObject *object,
|
|||
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MPEG_DECODER);
|
||||
break;
|
||||
default:
|
||||
//G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,9 @@ struct _GstV4lElement {
|
|||
/* the video-device's capabilities */
|
||||
struct video_capability vcap;
|
||||
|
||||
/* some more info about the current input's capabilities */
|
||||
struct video_channel vchan;
|
||||
|
||||
/* caching values */
|
||||
gint channel;
|
||||
gint norm;
|
||||
|
|
|
@ -46,24 +46,14 @@ enum {
|
|||
ARG_FRAME_TIME,
|
||||
};
|
||||
|
||||
GST_PADTEMPLATE_FACTORY (sink_template,
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"v4lmjpegsink_caps",
|
||||
"video/jpeg",
|
||||
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
|
||||
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
/* init functions */
|
||||
static void gst_v4lmjpegsink_class_init (GstV4lMjpegSinkClass *klass);
|
||||
static void gst_v4lmjpegsink_init (GstV4lMjpegSink *v4lmjpegsink);
|
||||
|
||||
/* the chain of buffers */
|
||||
static GstPadConnectReturn gst_v4lmjpegsink_sinkconnect (GstPad *pad,
|
||||
GstCaps *vscapslist);
|
||||
static void gst_v4lmjpegsink_chain (GstPad *pad,
|
||||
GstBuffer *buf);
|
||||
|
||||
|
@ -79,6 +69,10 @@ static void gst_v4lmjpegsink_get_property (GObject
|
|||
static void gst_v4lmjpegsink_close (GstV4lMjpegSink *v4lmjpegsink);
|
||||
static GstElementStateReturn gst_v4lmjpegsink_change_state (GstElement *element);
|
||||
|
||||
|
||||
static GstCaps *capslist = NULL;
|
||||
static GstPadTemplate *sink_template;
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static guint gst_v4lmjpegsink_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -155,37 +149,13 @@ gst_v4lmjpegsink_class_init (GstV4lMjpegSinkClass *klass)
|
|||
gstelement_class->change_state = gst_v4lmjpegsink_change_state;
|
||||
}
|
||||
|
||||
static GstPadConnectReturn
|
||||
gst_v4lmjpegsink_sinkconnect (GstPad *pad,
|
||||
GstCaps *caps)
|
||||
{
|
||||
GstV4lMjpegSink *v4lmjpegsink;
|
||||
|
||||
v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad));
|
||||
|
||||
if (!GST_CAPS_IS_FIXED (caps))
|
||||
return GST_PAD_CONNECT_DELAYED;
|
||||
|
||||
v4lmjpegsink->width = gst_caps_get_int (caps, "width");
|
||||
v4lmjpegsink->height = gst_caps_get_int (caps, "height");
|
||||
|
||||
gst_v4lmjpegsink_set_playback(v4lmjpegsink,
|
||||
v4lmjpegsink->width, v4lmjpegsink->height,
|
||||
v4lmjpegsink->x_offset, v4lmjpegsink->y_offset,
|
||||
GST_V4LELEMENT(v4lmjpegsink)->norm, 0); /* TODO: interlacing */
|
||||
|
||||
g_signal_emit (G_OBJECT (v4lmjpegsink), gst_v4lmjpegsink_signals[SIGNAL_HAVE_SIZE], 0,
|
||||
v4lmjpegsink->width, v4lmjpegsink->height);
|
||||
|
||||
return GST_PAD_CONNECT_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_v4lmjpegsink_init (GstV4lMjpegSink *v4lmjpegsink)
|
||||
{
|
||||
v4lmjpegsink->sinkpad = gst_pad_new_from_template(GST_PADTEMPLATE_GET (sink_template), "sink");
|
||||
v4lmjpegsink->sinkpad = gst_pad_new_from_template (sink_template, "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (v4lmjpegsink), v4lmjpegsink->sinkpad);
|
||||
|
||||
gst_pad_set_chain_function (v4lmjpegsink->sinkpad, gst_v4lmjpegsink_chain);
|
||||
gst_pad_set_connect_function (v4lmjpegsink->sinkpad, gst_v4lmjpegsink_sinkconnect);
|
||||
|
||||
|
@ -205,6 +175,39 @@ gst_v4lmjpegsink_init (GstV4lMjpegSink *v4lmjpegsink)
|
|||
}
|
||||
|
||||
|
||||
static GstPadConnectReturn
|
||||
gst_v4lmjpegsink_sinkconnect (GstPad *pad,
|
||||
GstCaps *vscapslist)
|
||||
{
|
||||
GstV4lMjpegSink *v4lmjpegsink;
|
||||
GstCaps *caps;
|
||||
|
||||
v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad));
|
||||
|
||||
for (caps = capslist; caps != NULL; caps = vscapslist = vscapslist->next)
|
||||
{
|
||||
v4lmjpegsink->width = gst_caps_get_int (caps, "width");
|
||||
v4lmjpegsink->height = gst_caps_get_int (caps, "height");
|
||||
|
||||
if (!gst_v4lmjpegsink_set_playback(v4lmjpegsink,
|
||||
v4lmjpegsink->width, v4lmjpegsink->height,
|
||||
v4lmjpegsink->x_offset, v4lmjpegsink->y_offset,
|
||||
GST_V4LELEMENT(v4lmjpegsink)->norm, 0)) /* TODO: interlacing */
|
||||
continue;
|
||||
|
||||
g_signal_emit (G_OBJECT (v4lmjpegsink), gst_v4lmjpegsink_signals[SIGNAL_HAVE_SIZE], 0,
|
||||
v4lmjpegsink->width, v4lmjpegsink->height);
|
||||
|
||||
return GST_PAD_CONNECT_OK;
|
||||
}
|
||||
|
||||
/* if we got here - it's not good */
|
||||
gst_element_error(GST_ELEMENT(v4lmjpegsink),
|
||||
"Failed to find acceptable caps");
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_v4lmjpegsink_chain (GstPad *pad,
|
||||
GstBuffer *buf)
|
||||
|
@ -281,7 +284,7 @@ gst_v4lmjpegsink_set_property (GObject *object,
|
|||
v4lmjpegsink->y_offset = g_value_get_int(value);
|
||||
break;
|
||||
default:
|
||||
/*parent_class->set_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +315,7 @@ gst_v4lmjpegsink_get_property (GObject *object,
|
|||
g_value_set_int (value, v4lmjpegsink->bufsize);
|
||||
break;
|
||||
default:
|
||||
/*parent_class->get_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -379,14 +382,29 @@ plugin_init (GModule *module,
|
|||
GstPlugin *plugin)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
GstCaps *caps;
|
||||
|
||||
/* create an elementfactory for the v4lmjpegsink element */
|
||||
factory = gst_elementfactory_new("v4lmjpegsink",GST_TYPE_V4LMJPEGSINK,
|
||||
&gst_v4lmjpegsink_details);
|
||||
g_return_val_if_fail(factory != NULL, FALSE);
|
||||
|
||||
gst_elementfactory_add_padtemplate (factory,
|
||||
GST_PADTEMPLATE_GET (sink_template));
|
||||
caps = gst_caps_new ("v4lmjpegsink_caps",
|
||||
"video/jpeg",
|
||||
gst_props_new (
|
||||
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
|
||||
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
|
||||
NULL )
|
||||
);
|
||||
capslist = gst_caps_append(capslist, caps);
|
||||
|
||||
sink_template = gst_padtemplate_new (
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
capslist, NULL);
|
||||
|
||||
gst_elementfactory_add_padtemplate (factory, sink_template);
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
|
||||
|
|
|
@ -57,12 +57,8 @@ static void gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *
|
|||
static void gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc);
|
||||
|
||||
/* pad/buffer functions */
|
||||
/*
|
||||
static GstPadNegotiateReturn gst_v4lmjpegsrc_negotiate (GstPad *pad,
|
||||
GstCaps **caps,
|
||||
gpointer *user_data);
|
||||
*/
|
||||
static GstCaps* gst_v4lmjpegsrc_create_caps (GstV4lMjpegSrc *v4lmjpegsrc);
|
||||
static GstPadConnectReturn gst_v4lmjpegsrc_srcconnect (GstPad *pad,
|
||||
GstCaps *caps);
|
||||
static GstBuffer* gst_v4lmjpegsrc_get (GstPad *pad);
|
||||
|
||||
/* get/set params */
|
||||
|
@ -87,6 +83,9 @@ static GstBuffer* gst_v4lmjpegsrc_buffer_copy (GstBuffer *srcbu
|
|||
static void gst_v4lmjpegsrc_buffer_free (GstBuffer *buf);
|
||||
|
||||
|
||||
static GstCaps *capslist = NULL;
|
||||
static GstPadTemplate *src_template;
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
//static guint gst_v4lmjpegsrc_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -174,11 +173,11 @@ gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass)
|
|||
static void
|
||||
gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc)
|
||||
{
|
||||
v4lmjpegsrc->srcpad = gst_pad_new("src", GST_PAD_SRC);
|
||||
v4lmjpegsrc->srcpad = gst_pad_new_from_template (src_template, "src");
|
||||
gst_element_add_pad(GST_ELEMENT(v4lmjpegsrc), v4lmjpegsrc->srcpad);
|
||||
|
||||
gst_pad_set_get_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_get);
|
||||
//gst_pad_set_negotiate_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_negotiate);
|
||||
gst_pad_set_connect_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_srcconnect);
|
||||
|
||||
v4lmjpegsrc->bufferpool = gst_buffer_pool_new();
|
||||
gst_buffer_pool_set_buffer_new_function(v4lmjpegsrc->bufferpool, gst_v4lmjpegsrc_buffer_new);
|
||||
|
@ -202,46 +201,21 @@ gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc)
|
|||
v4lmjpegsrc->numbufs = 64;
|
||||
v4lmjpegsrc->bufsize = 256;
|
||||
|
||||
v4lmjpegsrc->init = TRUE;
|
||||
v4lmjpegsrc->capslist = capslist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static GstPadNegotiateReturn
|
||||
gst_v4lmjpegsrc_negotiate (GstPad *pad,
|
||||
GstCaps **caps,
|
||||
gpointer *user_data)
|
||||
static GstPadConnectReturn
|
||||
gst_v4lmjpegsrc_srcconnect (GstPad *pad,
|
||||
GstCaps *caps)
|
||||
{
|
||||
GstV4lMjpegSrc *v4lmjpegsrc;
|
||||
|
||||
v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if (!*caps) {
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
else {
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
/* we will try_set_caps() with the actual size (wxh) when we know it */
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static GstCaps*
|
||||
gst_v4lmjpegsrc_create_caps (GstV4lMjpegSrc *v4lmjpegsrc)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
caps = GST_CAPS_NEW (
|
||||
"v4lmjpegsrc_caps",
|
||||
"video/jpeg",
|
||||
"width", GST_PROPS_INT(v4lmjpegsrc->end_width),
|
||||
"height", GST_PROPS_INT(v4lmjpegsrc->end_height)
|
||||
);
|
||||
|
||||
return caps;
|
||||
return GST_PAD_CONNECT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -256,17 +230,6 @@ gst_v4lmjpegsrc_get (GstPad *pad)
|
|||
|
||||
v4lmjpegsrc = GST_V4LMJPEGSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if (v4lmjpegsrc->init) {
|
||||
gst_pad_try_set_caps (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_create_caps (v4lmjpegsrc));
|
||||
v4lmjpegsrc->init = FALSE;
|
||||
}
|
||||
else {
|
||||
if (!gst_pad_get_caps (v4lmjpegsrc->srcpad) &&
|
||||
!gst_pad_renegotiate (v4lmjpegsrc->srcpad)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
buf = gst_buffer_new_from_pool(v4lmjpegsrc->bufferpool, 0, 0);
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -326,7 +289,7 @@ gst_v4lmjpegsrc_set_property (GObject *object,
|
|||
v4lmjpegsrc->bufsize = g_value_get_int(value);
|
||||
break;
|
||||
default:
|
||||
/*parent_class->set_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -357,7 +320,7 @@ gst_v4lmjpegsrc_get_property (GObject *object,
|
|||
g_value_set_int(value, v4lmjpegsrc->breq.size);
|
||||
break;
|
||||
default:
|
||||
/*parent_class->get_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -368,6 +331,7 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
|
|||
{
|
||||
GstV4lMjpegSrc *v4lmjpegsrc;
|
||||
GstElementStateReturn parent_value;
|
||||
GstCaps *caps;
|
||||
|
||||
g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), GST_STATE_FAILURE);
|
||||
|
||||
|
@ -396,7 +360,19 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
|
|||
v4lmjpegsrc->quality))
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
v4lmjpegsrc->init = TRUE;
|
||||
/* we now have an actual width/height - *set it* */
|
||||
caps = gst_caps_new("v4lmjpegsrc_caps",
|
||||
"video/jpeg",
|
||||
gst_props_new(
|
||||
"width", GST_PROPS_INT(v4lmjpegsrc->end_width),
|
||||
"height", GST_PROPS_INT(v4lmjpegsrc->end_height),
|
||||
NULL ) );
|
||||
if (!gst_pad_try_set_caps(v4lmjpegsrc->srcpad, caps))
|
||||
{
|
||||
gst_element_error(GST_ELEMENT(v4lmjpegsrc),
|
||||
"Failed to set new caps");
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
if (!gst_v4lmjpegsrc_capture_init(v4lmjpegsrc))
|
||||
return GST_STATE_FAILURE;
|
||||
break;
|
||||
|
@ -509,11 +485,30 @@ static gboolean
|
|||
plugin_init (GModule *module, GstPlugin *plugin)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
GstCaps *caps;
|
||||
|
||||
/* create an elementfactory for the v4lmjpegsrcparse element */
|
||||
factory = gst_elementfactory_new("v4lmjpegsrc",GST_TYPE_V4LMJPEGSRC,
|
||||
&gst_v4lmjpegsrc_details);
|
||||
g_return_val_if_fail(factory != NULL, FALSE);
|
||||
|
||||
caps = gst_caps_new ("v4lmjpegsrc_caps",
|
||||
"video/jpeg",
|
||||
gst_props_new (
|
||||
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
|
||||
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
|
||||
NULL )
|
||||
);
|
||||
capslist = gst_caps_append(capslist, caps);
|
||||
|
||||
src_template = gst_padtemplate_new (
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
capslist, NULL);
|
||||
|
||||
gst_elementfactory_add_padtemplate (factory, src_template);
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -55,6 +55,9 @@ struct _GstV4lMjpegSrc {
|
|||
struct mjpeg_sync bsync;
|
||||
struct mjpeg_requestbuffers breq;
|
||||
|
||||
/* list of available caps */
|
||||
GstCaps *capslist;
|
||||
|
||||
/* caching values */
|
||||
gint x_offset;
|
||||
gint y_offset;
|
||||
|
@ -69,8 +72,6 @@ struct _GstV4lMjpegSrc {
|
|||
gint quality;
|
||||
gint numbufs;
|
||||
gint bufsize; /* in KB */
|
||||
|
||||
gboolean init;
|
||||
};
|
||||
|
||||
struct _GstV4lMjpegSrcClass {
|
||||
|
|
|
@ -54,11 +54,8 @@ static void gst_v4lsrc_class_init (GstV4lSrcClass *klass);
|
|||
static void gst_v4lsrc_init (GstV4lSrc *v4lsrc);
|
||||
|
||||
/* pad/buffer functions */
|
||||
/*static GstPadNegotiateReturn gst_v4lsrc_negotiate (GstPad *pad,
|
||||
GstCaps **caps,
|
||||
gpointer *user_data);
|
||||
*/
|
||||
static GstCaps* gst_v4lsrc_create_caps (GstV4lSrc *v4lsrc);
|
||||
static GstPadConnectReturn gst_v4lsrc_srcconnect (GstPad *pad,
|
||||
GstCaps *caps);
|
||||
static GstBuffer* gst_v4lsrc_get (GstPad *pad);
|
||||
|
||||
/* get/set params */
|
||||
|
@ -83,6 +80,9 @@ static GstBuffer* gst_v4lsrc_buffer_copy (GstBuffer *srcbuf);
|
|||
static void gst_v4lsrc_buffer_free (GstBuffer *buf);
|
||||
|
||||
|
||||
static GstCaps *capslist = NULL;
|
||||
static GstPadTemplate *src_template;
|
||||
|
||||
static GstElementClass *parent_class = NULL;\
|
||||
//static guint gst_v4lsrc_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -151,11 +151,11 @@ gst_v4lsrc_class_init (GstV4lSrcClass *klass)
|
|||
static void
|
||||
gst_v4lsrc_init (GstV4lSrc *v4lsrc)
|
||||
{
|
||||
v4lsrc->srcpad = gst_pad_new("src", GST_PAD_SRC);
|
||||
v4lsrc->srcpad = gst_pad_new_from_template (src_template, "src");
|
||||
gst_element_add_pad(GST_ELEMENT(v4lsrc), v4lsrc->srcpad);
|
||||
|
||||
gst_pad_set_get_function (v4lsrc->srcpad, gst_v4lsrc_get);
|
||||
//gst_pad_set_negotiate_function (v4lsrc->srcpad, gst_v4lsrc_negotiate);
|
||||
gst_pad_set_connect_function (v4lsrc->srcpad, gst_v4lsrc_srcconnect);
|
||||
|
||||
v4lsrc->bufferpool = gst_buffer_pool_new();
|
||||
gst_buffer_pool_set_buffer_new_function(v4lsrc->bufferpool, gst_v4lsrc_buffer_new);
|
||||
|
@ -163,192 +163,155 @@ gst_v4lsrc_init (GstV4lSrc *v4lsrc)
|
|||
gst_buffer_pool_set_buffer_free_function(v4lsrc->bufferpool, gst_v4lsrc_buffer_free);
|
||||
gst_buffer_pool_set_user_data(v4lsrc->bufferpool, v4lsrc);
|
||||
|
||||
v4lsrc->palette = VIDEO_PALETTE_YUV420P;
|
||||
v4lsrc->palette = 0; /* means 'any' - user can specify a specific palette */
|
||||
v4lsrc->width = 160;
|
||||
v4lsrc->height = 120;
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5;
|
||||
|
||||
v4lsrc->init = TRUE;
|
||||
v4lsrc->capslist = capslist;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static GstPadNegotiateReturn
|
||||
gst_v4lsrc_negotiate (GstPad *pad,
|
||||
GstCaps **caps,
|
||||
gpointer *user_data)
|
||||
static GstPadConnectReturn
|
||||
gst_v4lsrc_srcconnect (GstPad *pad,
|
||||
GstCaps *vscapslist)
|
||||
{
|
||||
GstV4lSrc *v4lsrc;
|
||||
GstCaps *caps, *newcaps;
|
||||
gint palette = v4lsrc->palette;
|
||||
|
||||
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if (!*caps) {
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
else {
|
||||
gint width, height;
|
||||
gulong format;
|
||||
|
||||
width = gst_caps_get_int (*caps, "width");
|
||||
height = gst_caps_get_int (*caps, "height");
|
||||
format = gst_caps_get_fourcc_int (*caps, "format");
|
||||
|
||||
switch (format) {
|
||||
case GST_MAKE_FOURCC ('R','G','B',' '):
|
||||
/* TODO: caps = gst_caps_normalize(capslist); */
|
||||
for (caps = vscapslist ; caps != NULL ; caps = vscapslist = vscapslist->next)
|
||||
{
|
||||
if (v4lsrc->palette > 0)
|
||||
{
|
||||
switch (v4lsrc->palette)
|
||||
{
|
||||
gint depth;
|
||||
|
||||
depth = gst_caps_get_int (*caps, "depth");
|
||||
|
||||
switch (depth) {
|
||||
case 15:
|
||||
v4lsrc->palette = VIDEO_PALETTE_RGB555;
|
||||
v4lsrc->buffer_size = width * height * 2;
|
||||
break;
|
||||
case 16:
|
||||
v4lsrc->palette = VIDEO_PALETTE_RGB565;
|
||||
v4lsrc->buffer_size = width * height * 2;
|
||||
break;
|
||||
case 24:
|
||||
v4lsrc->palette = VIDEO_PALETTE_RGB24;
|
||||
v4lsrc->buffer_size = width * height * 3;
|
||||
break;
|
||||
case 32:
|
||||
v4lsrc->palette = VIDEO_PALETTE_RGB32;
|
||||
v4lsrc->buffer_size = width * height * 4;
|
||||
break;
|
||||
default:
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GST_MAKE_FOURCC ('I','4','2','0'):
|
||||
v4lsrc->palette = VIDEO_PALETTE_YUV420P;
|
||||
v4lsrc->buffer_size = width * height * 1.5;
|
||||
break;
|
||||
|
||||
case GST_MAKE_FOURCC ('U','Y','V','Y'):
|
||||
v4lsrc->palette = VIDEO_PALETTE_UYVY; //YUV422?;
|
||||
v4lsrc->buffer_size = width * height * 2;
|
||||
break;
|
||||
|
||||
case GST_MAKE_FOURCC ('Y','U','Y','2'):
|
||||
v4lsrc->palette = VIDEO_PALETTE_YUYV; //YUV422?;
|
||||
v4lsrc->buffer_size = width * height * 2;
|
||||
break;
|
||||
|
||||
/* TODO: add YUV4:2:2 planar and YUV4:2:0 packed, maybe also YUV4:1:1? */
|
||||
|
||||
default:
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
|
||||
}
|
||||
|
||||
/* if we get here, it's okay */
|
||||
v4lsrc->width = width;
|
||||
v4lsrc->height = height;
|
||||
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static GstCaps*
|
||||
gst_v4lsrc_create_caps (GstV4lSrc *v4lsrc)
|
||||
{
|
||||
GstCaps *caps = NULL;
|
||||
gulong fourcc = 0;
|
||||
|
||||
switch (v4lsrc->palette) {
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
{
|
||||
int depth=0, bpp=0;
|
||||
|
||||
fourcc = GST_STR_FOURCC ("RGB ");
|
||||
|
||||
switch (v4lsrc->palette) {
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
depth = 15;
|
||||
bpp = 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
depth = 16;
|
||||
bpp = 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
depth = 24;
|
||||
bpp = 3;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
depth = 32;
|
||||
bpp = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
caps = GST_CAPS_NEW (
|
||||
"v4lsrc_caps",
|
||||
"video/raw",
|
||||
"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)
|
||||
);
|
||||
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * bpp;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_PALETTE_YUV422:
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
{
|
||||
switch (v4lsrc->palette) {
|
||||
case VIDEO_PALETTE_YUV422:
|
||||
fourcc = (G_BYTE_ORDER == G_BIG_ENDIAN) ?
|
||||
GST_STR_FOURCC("UYVY") : GST_STR_FOURCC("YUY2");
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUYV:
|
||||
fourcc = GST_STR_FOURCC("YUY2");
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_UYVY:
|
||||
fourcc = GST_STR_FOURCC("UYVY");
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
fourcc = GST_STR_FOURCC("I420");
|
||||
v4lsrc->buffer_size = v4lsrc->width * v4lsrc->height * 1.5;
|
||||
break;
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('I','4','2','0') &&
|
||||
gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('I','Y','U','V'))
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_YUV422:
|
||||
case VIDEO_PALETTE_YUYV:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('Y','U','Y','2'))
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_UYVY:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('U','Y','V','Y'))
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_YUV411:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('Y','4','1','P'))
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('R','G','B',' ') ||
|
||||
gst_caps_get_int(caps, "depth") != 15)
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('R','G','B',' ') ||
|
||||
gst_caps_get_int(caps, "depth") != 16)
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('R','G','B',' ') ||
|
||||
gst_caps_get_int(caps, "depth") != 24)
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
if (gst_caps_get_fourcc_int (caps, "format") != GST_MAKE_FOURCC('R','G','B',' ') ||
|
||||
gst_caps_get_int(caps, "depth") != 32)
|
||||
goto try_next;
|
||||
goto try_caps;
|
||||
default:
|
||||
goto try_next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gst_caps_get_fourcc_int(caps, "format"))
|
||||
{
|
||||
case GST_MAKE_FOURCC('I','4','2','0'):
|
||||
case GST_MAKE_FOURCC('I','Y','U','V'):
|
||||
palette = VIDEO_PALETTE_YUV420P;
|
||||
goto try_caps;
|
||||
case GST_MAKE_FOURCC('Y','U','Y','2'):
|
||||
palette = VIDEO_PALETTE_YUV422;
|
||||
goto try_caps;
|
||||
case GST_MAKE_FOURCC('U','Y','V','Y'):
|
||||
palette = VIDEO_PALETTE_UYVY;
|
||||
goto try_caps;
|
||||
case GST_MAKE_FOURCC('Y','4','1','P'):
|
||||
palette = VIDEO_PALETTE_YUV411;
|
||||
goto try_caps;
|
||||
case GST_MAKE_FOURCC('R','G','B',' '):
|
||||
switch (gst_caps_get_int(caps, "depth"))
|
||||
{
|
||||
case 15:
|
||||
palette = VIDEO_PALETTE_RGB555;
|
||||
goto try_caps;
|
||||
case 16:
|
||||
palette = VIDEO_PALETTE_RGB565;
|
||||
goto try_caps;
|
||||
case 24:
|
||||
palette = VIDEO_PALETTE_RGB24;
|
||||
goto try_caps;
|
||||
case 32:
|
||||
palette = VIDEO_PALETTE_RGB32;
|
||||
goto try_caps;
|
||||
default:
|
||||
goto try_next;
|
||||
}
|
||||
default:
|
||||
goto try_next;
|
||||
}
|
||||
|
||||
caps = GST_CAPS_NEW (
|
||||
"v4lsrc_caps",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (fourcc),
|
||||
"width", GST_PROPS_INT (v4lsrc->width),
|
||||
"height", GST_PROPS_INT (v4lsrc->height)
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
/* if this caps wasn't useful, try the next one */
|
||||
try_next:
|
||||
continue;
|
||||
|
||||
/* if this caps was useful, try it out */
|
||||
try_caps:
|
||||
/* TODO: try the current 'palette' out on the video device */
|
||||
|
||||
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, palette))
|
||||
continue;
|
||||
|
||||
/* try to connect the pad/caps with the actual width/height */
|
||||
if (palette >= VIDEO_PALETTE_RGB565 && palette <= VIDEO_PALETTE_RGB555)
|
||||
newcaps = gst_caps_new("v4lsrc_caps",
|
||||
"video/raw",
|
||||
gst_props_new(
|
||||
"format", GST_PROPS_FOURCC(gst_caps_get_fourcc_int(caps, "format")),
|
||||
"width", GST_PROPS_INT(v4lsrc->width),
|
||||
"width", GST_PROPS_INT(v4lsrc->height),
|
||||
"bpp", GST_PROPS_INT(gst_caps_get_int(caps, "bpp")),
|
||||
"depth", GST_PROPS_INT(gst_caps_get_int(caps, "depth")),
|
||||
NULL ) );
|
||||
else
|
||||
newcaps = gst_caps_new("v4lsrc_caps",
|
||||
"video/raw",
|
||||
gst_props_new(
|
||||
"format", GST_PROPS_FOURCC(gst_caps_get_fourcc_int(caps, "format")),
|
||||
"width", GST_PROPS_INT(v4lsrc->width),
|
||||
"height", GST_PROPS_INT(v4lsrc->height),
|
||||
NULL ) );
|
||||
|
||||
if (!gst_pad_try_set_caps(v4lsrc->srcpad, newcaps))
|
||||
continue;
|
||||
else
|
||||
return GST_PAD_CONNECT_DONE;
|
||||
}
|
||||
|
||||
return caps;
|
||||
/* still nothing - no good caps */
|
||||
gst_element_error(GST_ELEMENT(v4lsrc),
|
||||
"Failed to find acceptable caps");
|
||||
return GST_PAD_CONNECT_REFUSED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -363,17 +326,6 @@ gst_v4lsrc_get (GstPad *pad)
|
|||
|
||||
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
|
||||
|
||||
if (v4lsrc->init) {
|
||||
gst_pad_try_set_caps (v4lsrc->srcpad, gst_v4lsrc_create_caps (v4lsrc));
|
||||
v4lsrc->init = FALSE;
|
||||
}
|
||||
else {
|
||||
if (!gst_pad_get_caps (v4lsrc->srcpad) &&
|
||||
!gst_pad_renegotiate (v4lsrc->srcpad)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
buf = gst_buffer_new_from_pool(v4lsrc->bufferpool, 0, 0);
|
||||
if (!buf)
|
||||
{
|
||||
|
@ -419,7 +371,7 @@ gst_v4lsrc_set_property (GObject *object,
|
|||
break;
|
||||
|
||||
default:
|
||||
/*parent_class->set_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -462,7 +414,7 @@ gst_v4lsrc_get_property (GObject *object,
|
|||
break;
|
||||
|
||||
default:
|
||||
/*parent_class->get_property(object, prop_id, value, pspec);*/
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -473,6 +425,7 @@ gst_v4lsrc_change_state (GstElement *element)
|
|||
{
|
||||
GstV4lSrc *v4lsrc;
|
||||
GstElementStateReturn parent_value;
|
||||
GstCaps *caps;
|
||||
|
||||
g_return_val_if_fail(GST_IS_V4LSRC(element), GST_STATE_FAILURE);
|
||||
|
||||
|
@ -481,9 +434,120 @@ gst_v4lsrc_change_state (GstElement *element)
|
|||
switch (GST_STATE_TRANSITION(element)) {
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
/* set capture parameters and mmap the buffers */
|
||||
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette))
|
||||
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height,
|
||||
v4lsrc->palette>0 ? v4lsrc->palette : v4lsrc->mmap.format))
|
||||
return GST_STATE_FAILURE;
|
||||
v4lsrc->init = TRUE;
|
||||
/* retry setting the video-palette */
|
||||
if (v4lsrc->palette > 0)
|
||||
{
|
||||
switch (v4lsrc->palette)
|
||||
{
|
||||
case VIDEO_PALETTE_YUYV:
|
||||
case VIDEO_PALETTE_UYVY:
|
||||
case VIDEO_PALETTE_YUV422:
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
case VIDEO_PALETTE_YUV411:
|
||||
{
|
||||
gulong format;
|
||||
switch (v4lsrc->palette)
|
||||
{
|
||||
case VIDEO_PALETTE_YUYV:
|
||||
format = GST_MAKE_FOURCC('Y','U','Y','2');
|
||||
break;
|
||||
case VIDEO_PALETTE_UYVY:
|
||||
format = GST_MAKE_FOURCC('U','Y','V','Y');
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV422:
|
||||
format = GST_MAKE_FOURCC('Y','U','Y','2');
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
format = GST_MAKE_FOURCC('I','4','2','0');
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV411:
|
||||
format = GST_MAKE_FOURCC('Y','4','1','P');
|
||||
break;
|
||||
}
|
||||
caps = gst_caps_new("v4lsrc_caps",
|
||||
"video/raw",
|
||||
gst_props_new(
|
||||
"format", GST_PROPS_FOURCC(format),
|
||||
"width", GST_PROPS_INT(v4lsrc->width),
|
||||
"height", GST_PROPS_INT(v4lsrc->height),
|
||||
NULL ) );
|
||||
break;
|
||||
}
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
{
|
||||
gint depth, bpp;
|
||||
switch (v4lsrc->palette)
|
||||
{
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
bpp = 2;
|
||||
depth = 15;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
bpp = 2;
|
||||
depth = 16;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
bpp = 3;
|
||||
depth = 24;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
bpp = 4;
|
||||
depth = 32;
|
||||
break;
|
||||
}
|
||||
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(v4lsrc->width),
|
||||
"height", GST_PROPS_INT(v4lsrc->height),
|
||||
"bpp", GST_PROPS_INT(bpp),
|
||||
"depth", GST_PROPS_INT(depth),
|
||||
NULL ) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
gst_element_error(GST_ELEMENT(v4lsrc),
|
||||
"Failed to find a fourcc code for palette %d (\'%s\')",
|
||||
v4lsrc->palette, palette_name[v4lsrc->palette]);
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GstCaps *oldcaps = gst_pad_get_caps(v4lsrc->srcpad);
|
||||
|
||||
if (gst_caps_get_fourcc_int(oldcaps, "format") == GST_MAKE_FOURCC('R','G','B',' '))
|
||||
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(v4lsrc->width),
|
||||
"height", GST_PROPS_INT(v4lsrc->height),
|
||||
"bpp", GST_PROPS_INT(gst_caps_get_int(oldcaps, "bpp")),
|
||||
"depth", GST_PROPS_INT(gst_caps_get_int(oldcaps, "depth")),
|
||||
NULL) );
|
||||
else
|
||||
caps = gst_caps_new("v4lsrc_caps",
|
||||
"video/raw",
|
||||
gst_props_new(
|
||||
"format", GST_PROPS_FOURCC(gst_caps_get_fourcc_int(oldcaps, "format")),
|
||||
"width", GST_PROPS_INT(v4lsrc->width),
|
||||
"height", GST_PROPS_INT(v4lsrc->height),
|
||||
NULL) );
|
||||
}
|
||||
if (!gst_pad_try_set_caps(v4lsrc->srcpad, caps))
|
||||
{
|
||||
gst_element_error(GST_ELEMENT(v4lsrc),
|
||||
"Failed to set new caps");
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
if (!gst_v4lsrc_capture_init(v4lsrc))
|
||||
return GST_STATE_FAILURE;
|
||||
break;
|
||||
|
@ -573,7 +637,7 @@ gst_v4lsrc_buffer_free (GstBuffer *buf)
|
|||
}
|
||||
|
||||
gst_element_error(GST_ELEMENT(v4lsrc),
|
||||
"Couldn't find the buffer");
|
||||
"Couldn\'t find the buffer");
|
||||
}
|
||||
|
||||
|
||||
|
@ -582,11 +646,60 @@ 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] = { 2, 2, 3, 4 };
|
||||
gint rgb_depth[4] = { 15, 16, 24, 32 };
|
||||
|
||||
/* create an elementfactory for the v4lsrc */
|
||||
factory = gst_elementfactory_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_padtemplate_new (
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
capslist, NULL);
|
||||
|
||||
gst_elementfactory_add_padtemplate (factory, src_template);
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -49,9 +49,6 @@ struct _GstV4lSrc {
|
|||
/* bufferpool for the buffers we're gonna use */
|
||||
GstBufferPool *bufferpool;
|
||||
|
||||
/* whether we need to reset the GstPad */
|
||||
gboolean init;
|
||||
|
||||
/* capture/buffer info */
|
||||
struct video_mmap mmap;
|
||||
struct video_mbuf mbuf;
|
||||
|
@ -71,6 +68,9 @@ struct _GstV4lSrc {
|
|||
pthread_mutex_t mutex_queued_frames;
|
||||
pthread_cond_t cond_queued_frames;
|
||||
|
||||
/* list of available caps */
|
||||
GstCaps *capslist;
|
||||
|
||||
/* caching values */
|
||||
gint width;
|
||||
gint height;
|
||||
|
|
|
@ -161,26 +161,16 @@ gst_v4l_get_chan_norm (GstV4lElement *v4lelement,
|
|||
gint *channel,
|
||||
gint *norm)
|
||||
{
|
||||
struct video_channel vchan;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "V4L: gst_v4l_get_chan_norm()\n");
|
||||
#endif
|
||||
|
||||
GST_V4L_CHECK_OPEN(v4lelement);
|
||||
|
||||
if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
|
||||
{
|
||||
gst_element_error(GST_ELEMENT(v4lelement),
|
||||
"Error getting the channel/norm settings: %s",
|
||||
sys_errlist[errno]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (channel)
|
||||
*channel = vchan.channel;
|
||||
*channel = v4lelement->vchan.channel;
|
||||
if (norm)
|
||||
*norm = vchan.norm;
|
||||
*norm = v4lelement->vchan.norm;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -198,8 +188,6 @@ gst_v4l_set_chan_norm (GstV4lElement *v4lelement,
|
|||
gint channel,
|
||||
gint norm)
|
||||
{
|
||||
struct video_channel vchan;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "V4L: gst_v4l_set_chan_norm(), channel = %d, norm = %d (%s)\n",
|
||||
channel, norm, norm_name[norm]);
|
||||
|
@ -208,19 +196,10 @@ gst_v4l_set_chan_norm (GstV4lElement *v4lelement,
|
|||
GST_V4L_CHECK_OPEN(v4lelement);
|
||||
GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
|
||||
|
||||
#if 0
|
||||
if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
|
||||
{
|
||||
gst_error("V4lElement - Error getting the channel/norm settings: %s",
|
||||
sys_errlist[errno]);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
v4lelement->vchan.channel = channel;
|
||||
v4lelement->vchan.norm = norm;
|
||||
|
||||
vchan.channel = channel;
|
||||
vchan.norm = norm;
|
||||
|
||||
if (ioctl(v4lelement->video_fd, VIDIOCSCHAN, &vchan) < 0)
|
||||
if (ioctl(v4lelement->video_fd, VIDIOCSCHAN, &(v4lelement->vchan)) < 0)
|
||||
{
|
||||
gst_element_error(GST_ELEMENT(v4lelement),
|
||||
"Error setting the channel/norm settings: %s",
|
||||
|
@ -228,6 +207,14 @@ gst_v4l_set_chan_norm (GstV4lElement *v4lelement,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &(v4lelement->vchan)) < 0)
|
||||
{
|
||||
gst_element_error(GST_ELEMENT(v4lelement),
|
||||
"Error getting the channel/norm settings: %s",
|
||||
sys_errlist[errno]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -246,7 +233,8 @@ gst_v4l_has_tuner (GstV4lElement *v4lelement)
|
|||
|
||||
GST_V4L_CHECK_OPEN(v4lelement);
|
||||
|
||||
return (v4lelement->vcap.type & VID_TYPE_TUNER);
|
||||
return (v4lelement->vcap.type & VID_TYPE_TUNER &&
|
||||
v4lelement->vchan.flags & VIDEO_VC_TUNER);
|
||||
}
|
||||
|
||||
|
||||
|
@ -442,7 +430,8 @@ gst_v4l_has_audio (GstV4lElement *v4lelement)
|
|||
|
||||
GST_V4L_CHECK_OPEN(v4lelement);
|
||||
|
||||
return (v4lelement->vcap.audios > 0);
|
||||
return (v4lelement->vcap.audios > 0 &&
|
||||
v4lelement->vchan.flags & VIDEO_VC_AUDIO);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ gst_v4lsrc_set_capture (GstV4lSrc *v4lsrc,
|
|||
width, height, palette);
|
||||
#endif
|
||||
|
||||
GST_V4L_CHECK_OPEN(GST_V4LELEMENT(v4lsrc));
|
||||
/*GST_V4L_CHECK_OPEN(GST_V4LELEMENT(v4lsrc));*/
|
||||
GST_V4L_CHECK_NOT_ACTIVE(GST_V4LELEMENT(v4lsrc));
|
||||
|
||||
v4lsrc->mmap.width = width;
|
||||
|
|
Loading…
Reference in a new issue