Commit 6dd1750d authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Updated all plugins to new capsnego format and added some small usability...

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
parent 3333429a
......@@ -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;
}
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)
);
/* we will try_set_caps() with the actual size (wxh) when we know it */
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 {
......
This diff is collapsed.
......@@ -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,22 +196,21 @@ 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)
v4lelement->vchan.channel = channel;
v4lelement->vchan.norm = norm;
if (ioctl(v4lelement->video_fd, VIDIOCSCHAN, &(v4lelement->vchan)) < 0)
{
gst_error("V4lElement - Error getting the channel/norm settings: %s",
gst_element_error(GST_ELEMENT(v4lelement),
"Error setting the channel/norm settings: %s",
sys_errlist[errno]);
return FALSE;
}
#endif
vchan.channel = channel;
vchan.norm = norm;
if (ioctl(v4lelement->video_fd, VIDIOCSCHAN, &vchan) < 0)
if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &(v4lelement->vchan)) < 0)
{
gst_element_error(GST_ELEMENT(v4lelement),
"Error setting the channel/norm settings: %s",
"Error getting the channel/norm settings: %s",
sys_errlist[errno]);
return FALSE;
}
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment