From: Ronald S. Bultje Date: Sat, 23 Feb 2002 14:05:33 +0000 (+0000) Subject: Added basic overlay support to v4l X-Git-Tag: 1.19.3~511^2~16118 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=162086096d150bbda472e89eda8df38f5de2b3c3;p=platform%2Fupstream%2Fgstreamer.git Added basic overlay support to v4l Original commit message from CVS: Added basic overlay support to v4l --- diff --git a/sys/v4l/Makefile.am b/sys/v4l/Makefile.am index f5beaa5..a2af6b0 100644 --- a/sys/v4l/Makefile.am +++ b/sys/v4l/Makefile.am @@ -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@ diff --git a/sys/v4l/gstv4lelement.c b/sys/v4l/gstv4lelement.c index d8991cd..38a2652 100644 --- a/sys/v4l/gstv4lelement.c +++ b/sys/v4l/gstv4lelement.c @@ -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;ix; + 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; diff --git a/sys/v4l/gstv4lelement.h b/sys/v4l/gstv4lelement.h index 9e8e7bd..3ca2ca4 100644 --- a/sys/v4l/gstv4lelement.h +++ b/sys/v4l/gstv4lelement.h @@ -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 { diff --git a/sys/v4l/v4l_calls.c b/sys/v4l/v4l_calls.c index e01701c..79fe263 100644 --- a/sys/v4l/v4l_calls.c +++ b/sys/v4l/v4l_calls.c @@ -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); diff --git a/sys/v4l/v4l_calls.h b/sys/v4l/v4l_calls.h index 2622e7a..f554eaf 100644 --- a/sys/v4l/v4l_calls.h +++ b/sys/v4l/v4l_calls.h @@ -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