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

Added basic overlay support to v4l

Original commit message from CVS:
Added basic overlay support to v4l
parent 49b26d41
......@@ -3,7 +3,7 @@ plugindir = $(libdir)/gst
plugin_LTLIBRARIES = libv4lelement.la libv4lsrc.la \
libv4lmjpegsrc.la libv4lmjpegsink.la
libv4lelement_la_SOURCES = gstv4lelement.c v4l_calls.c
libv4lelement_la_SOURCES = gstv4lelement.c v4l_calls.c v4l-overlay_calls.c
libv4lelement_la_CFLAGS = $(GST_CFLAGS)
libv4lelement_la_LIBADD = $(GST_LIBS)
libv4lelement_la_LDFLAGS = @GST_PLUGIN_LDFLAGS@
......
......@@ -57,7 +57,11 @@ enum {
ARG_DEVICE_IS_MJPEG_CAPTURE,
ARG_DEVICE_IS_MJPEG_PLAYBACK,
ARG_DEVICE_IS_MPEG_CAPTURE,
ARG_DEVICE_IS_MPEG_PLAYBACK
ARG_DEVICE_IS_MPEG_PLAYBACK,
ARG_DISPLAY,
ARG_VIDEOWINDOW,
ARG_CLIPPING,
ARG_DO_OVERLAY,
};
......@@ -190,6 +194,19 @@ gst_v4lelement_class_init (GstV4lElementClass *klass)
g_param_spec_boolean("can_playback_mpeg","can_playback_mpeg","can_playback_mpeg",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DISPLAY,
g_param_spec_string("display","display","display",
NULL, G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DO_OVERLAY,
g_param_spec_boolean("do_overlay","do_overlay","do_overlay",
0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VIDEOWINDOW,
g_param_spec_pointer("videowindow","videowindow","videowindow",
G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CLIPPING,
g_param_spec_pointer("videowindowclip","videowindowclip","videowindowclip",
G_PARAM_WRITABLE));
gobject_class->set_property = gst_v4lelement_set_property;
gobject_class->get_property = gst_v4lelement_get_property;
......@@ -204,6 +221,7 @@ gst_v4lelement_init (GstV4lElement *v4lelement)
v4lelement->video_fd = -1;
v4lelement->buffer = NULL;
v4lelement->videodev = NULL;
v4lelement->display = NULL;
v4lelement->norm = -1;
v4lelement->channel = -1; /* the first channel */
......@@ -324,12 +342,44 @@ gst_v4lelement_set_property (GObject *object,
}
break;
case ARG_DEVICE:
if (GST_V4L_IS_OPEN(v4lelement))
break; /* only set when *not* open */
if (v4lelement->videodev)
g_free(v4lelement->videodev);
v4lelement->videodev = g_strdup(g_value_get_string(value));
break;
case ARG_DO_OVERLAY:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_enable_overlay(v4lelement, g_value_get_boolean(value));
break;
case ARG_DISPLAY:
if (v4lelement->display) g_free(v4lelement->display);
v4lelement->display = g_strdup(g_value_get_string(value));
break;
case ARG_VIDEOWINDOW:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_set_window(v4lelement,
((GstV4lRect*)g_value_get_pointer(value))->x,
((GstV4lRect*)g_value_get_pointer(value))->y,
((GstV4lRect*)g_value_get_pointer(value))->w,
((GstV4lRect*)g_value_get_pointer(value))->h);
break;
case ARG_CLIPPING:
if (GST_V4L_IS_OPEN(v4lelement))
{
gint i;
struct video_clip *clips;
GList *list = (GList*)g_value_get_pointer(value);
clips = g_malloc(sizeof(struct video_clip) * g_list_length(list));
for (i=0;i<g_list_length(list);i++)
{
clips[i].x = ((GstV4lRect*)g_list_nth_data(list, i))->x;
clips[i].y = ((GstV4lRect*)g_list_nth_data(list, i))->y;
clips[i].width = ((GstV4lRect*)g_list_nth_data(list, i))->w;
clips[i].height = ((GstV4lRect*)g_list_nth_data(list, i))->h;
}
gst_v4l_set_clips(v4lelement, clips, g_list_length(list));
g_free(clips);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -494,6 +544,9 @@ gst_v4lelement_change_state (GstElement *element)
{
int n, temp;
if (v4lelement->display)
gst_v4l_set_overlay(v4lelement, v4lelement->display);
if (!gst_v4l_open(v4lelement))
return GST_STATE_FAILURE;
......
......@@ -43,6 +43,10 @@ extern "C" {
typedef struct _GstV4lElement GstV4lElement;
typedef struct _GstV4lElementClass GstV4lElementClass;
typedef struct _GstV4lRect {
gint x, y, w, h;
} GstV4lRect;
struct _GstV4lElement {
GstElement element;
......@@ -61,6 +65,9 @@ struct _GstV4lElement {
/* some more info about the current input's capabilities */
struct video_channel vchan;
/* and last but not least, the current video window */
struct video_window vwin;
/* caching values */
gint channel;
gint norm;
......@@ -72,6 +79,7 @@ struct _GstV4lElement {
gint hue;
gint contrast;
gint saturation;
gchar *display;
};
struct _GstV4lElementClass {
......
......@@ -100,6 +100,20 @@ gst_v4l_open (GstV4lElement *v4lelement)
return FALSE;
}
/* and get the video window */
if (GST_V4L_IS_OVERLAY(v4lelement))
{
if (ioctl(v4lelement->video_fd, VIDIOCGWIN, &(v4lelement->vwin)) < 0)
{
close(v4lelement->video_fd);
v4lelement->video_fd = -1;
gst_element_error(GST_ELEMENT(v4lelement),
"Failed to get video window properties of \'%s\': %s",
v4lelement->videodev, sys_errlist[errno]);
return FALSE;
}
}
gst_info("Opened device \'%s\' (\'%s\') successfully\n",
v4lelement->vcap.name, v4lelement->videodev);
......
......@@ -35,6 +35,9 @@ extern "C" {
#define GST_V4L_IS_ACTIVE(v4lelement) \
(v4lelement->buffer != NULL)
#define GST_V4L_IS_OVERLAY(v4lelement) \
(v4lelement->vcap.type & VID_TYPE_OVERLAY)
/* checks whether the current v4lelement has already been open()'ed or not */
#define GST_V4L_CHECK_OPEN(v4lelement) \
if (v4lelement->video_fd <= 0) \
......@@ -53,6 +56,15 @@ extern "C" {
return FALSE; \
}
/* checks whether the current v4lelement does video overlay */
#define GST_V4L_CHECK_OVERLAY(v4lelement) \
if (!(v4lelement->vcap.type & VID_TYPE_OVERLAY)) \
{ \
gst_element_error(GST_ELEMENT(v4lelement), \
"Device doesn';t do overlay"); \
return FALSE; \
}
/* checks whether we're in capture mode or not */
#define GST_V4L_CHECK_ACTIVE(v4lelement) \
if (v4lelement->buffer == NULL) \
......@@ -98,8 +110,8 @@ gboolean gst_v4l_close (GstV4lElement *v4lelement);
/* norm control (norm = VIDEO_MODE_{PAL|NTSC|SECAM|AUTO}) */
gint gst_v4l_get_num_chans (GstV4lElement *v4lelement);
gboolean gst_v4l_get_chan_norm (GstV4lElement *v4lelement, gint *channel, gint *norm);
gboolean gst_v4l_set_chan_norm (GstV4lElement *v4lelement, gint channel, gint norm);
gboolean gst_v4l_get_chan_norm (GstV4lElement *v4lelement, gint *channel, gint *norm);
gboolean gst_v4l_set_chan_norm (GstV4lElement *v4lelement, gint channel, gint norm);
GList *gst_v4l_get_chan_names (GstV4lElement *v4lelement);
/* frequency control */
......@@ -108,13 +120,19 @@ gboolean gst_v4l_get_frequency (GstV4lElement *v4lelement, gulong *frequency);
gboolean gst_v4l_set_frequency (GstV4lElement *v4lelement, gulong frequency);
/* picture control */
gboolean gst_v4l_get_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint *value);
gboolean gst_v4l_set_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint value);
gboolean gst_v4l_get_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint *value);
gboolean gst_v4l_set_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint value);
/* audio control */
gboolean gst_v4l_has_audio (GstV4lElement *v4lelement);
gboolean gst_v4l_get_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint *value);
gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint value);
gboolean gst_v4l_get_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint *value);
gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint value);
/* overlay */
gboolean gst_v4l_set_overlay (GstV4lElement *v4lelement, gchar *display);
gboolean gst_v4l_set_window (GstV4lElement *v4lelement, gint x, gint y, gint w, gint h);
gboolean gst_v4l_set_clips (GstV4lElement *v4lelement, struct video_clip *clips, gint num_clips);
gboolean gst_v4l_enable_overlay (GstV4lElement *v4lelement, gboolean enable);
#ifdef __cplusplus
......
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