Added basic overlay support to v4l
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sat, 23 Feb 2002 14:05:33 +0000 (14:05 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sat, 23 Feb 2002 14:05:33 +0000 (14:05 +0000)
Original commit message from CVS:
Added basic overlay support to v4l

sys/v4l/Makefile.am
sys/v4l/gstv4lelement.c
sys/v4l/gstv4lelement.h
sys/v4l/v4l_calls.c
sys/v4l/v4l_calls.h

index f5beaa5..a2af6b0 100644 (file)
@@ -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@
index d8991cd..38a2652 100644 (file)
@@ -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;
 
index 9e8e7bd..3ca2ca4 100644 (file)
@@ -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 {
index e01701c..79fe263 100644 (file)
@@ -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);
 
index 2622e7a..f554eaf 100644 (file)
@@ -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