mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 23:14:46 +00:00
Added basic overlay support to v4l
Original commit message from CVS: Added basic overlay support to v4l
This commit is contained in:
parent
49b26d418b
commit
162086096d
5 changed files with 103 additions and 10 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue