camerabin2: adds location property
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>
Tue, 30 Nov 2010 23:13:27 +0000 (20:13 -0300)
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>
Wed, 8 Dec 2010 18:38:28 +0000 (15:38 -0300)
Adds a location property to enable applications to select
the captured files names. Locations are handled just like
multifilesink ones

Also disables -Wformat-nonliteral to allow to use non-literals
on g_strdup_printf on camerabin and generate a sequence of
locations for captures.

configure.ac
gst/camerabin2/gstcamerabin2.c
gst/camerabin2/gstcamerabin2.h
gst/camerabin2/gstimagecapturebin.c
gst/camerabin2/gstimagecapturebin.h
gst/camerabin2/gstvideorecordingbin.c
gst/camerabin2/gstvideorecordingbin.h

index 3beb627..85fc6a3 100644 (file)
@@ -266,7 +266,7 @@ dnl -Waggregate-return - libexif returns aggregates
 dnl -Wundef - Windows headers check _MSC_VER unconditionally
 AG_GST_SET_ERROR_CFLAGS($GST_GIT, [
     -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls
-    -Wwrite-strings -Wformat-nonliteral -Wformat-security -Wold-style-definition
+    -Wwrite-strings -Wformat-security -Wold-style-definition
     -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar
     -Wnested-externs])
 
index 0c0024f..a7bd139 100644 (file)
@@ -60,7 +60,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_camera_bin_debug);
 enum
 {
   PROP_0,
-  PROP_MODE
+  PROP_MODE,
+  PROP_LOCATION
 };
 
 enum
@@ -74,6 +75,8 @@ enum
 static guint camerabin_signals[LAST_SIGNAL];
 
 #define DEFAULT_MODE MODE_IMAGE
+#define DEFAULT_VID_LOCATION "vid_%d"
+#define DEFAULT_IMG_LOCATION "img_%d"
 
 /********************************
  * Standard GObject boilerplate *
@@ -162,8 +165,13 @@ gst_camera_bin_src_notify_readyforcapture (GObject * obj, GParamSpec * pspec,
   if (camera->mode == MODE_VIDEO) {
     g_object_get (camera->src, "ready-for-capture", &ready, NULL);
     if (!ready) {
+      gchar *location;
+
       /* a video recording is about to start, we reset the videobin */
       gst_element_set_state (camera->vidbin, GST_STATE_NULL);
+      location = g_strdup_printf (camera->vid_location, camera->vid_index++);
+      g_object_set (camera->vidbin, "location", location, NULL);
+      g_free (location);
       gst_element_set_state (camera->vidbin, GST_STATE_PLAYING);
     }
   }
@@ -174,6 +182,9 @@ gst_camera_bin_dispose (GObject * object)
 {
   GstCameraBin *camerabin = GST_CAMERA_BIN_CAST (object);
 
+  g_free (camerabin->img_location);
+  g_free (camerabin->vid_location);
+
   if (camerabin->src_capture_notify_id)
     g_signal_handler_disconnect (camerabin->src,
         camerabin->src_capture_notify_id);
@@ -183,6 +194,9 @@ gst_camera_bin_dispose (GObject * object)
   if (camerabin->vidbin)
     gst_object_unref (camerabin->vidbin);
 
+  if (camerabin->imgbin)
+    gst_object_unref (camerabin->imgbin);
+
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -233,6 +247,13 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
           GST_TYPE_CAMERABIN_MODE, DEFAULT_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (object_class, PROP_LOCATION,
+      g_param_spec_string ("location", "Location",
+          "Location to save the captured files. A %d might be used on the"
+          "filename as a placeholder for a numeric index of the capture."
+          "Default for images is img_%d and vid_%d for videos",
+          DEFAULT_IMG_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstCameraBin::capture-start:
    * @camera: the camera bin element
@@ -261,7 +282,9 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
 static void
 gst_camera_bin_init (GstCameraBin * camerabin)
 {
-  camerabin->mode = MODE_IMAGE;
+  camerabin->mode = DEFAULT_MODE;
+  camerabin->vid_location = g_strdup (DEFAULT_VID_LOCATION);
+  camerabin->img_location = g_strdup (DEFAULT_IMG_LOCATION);
 }
 
 /**
@@ -300,6 +323,7 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
 
   camera->src = gst_object_ref (src);
   camera->vidbin = gst_object_ref (vid);
+  camera->imgbin = gst_object_ref (img);
 
   vid_queue = gst_element_factory_make ("queue", "video-queue");
   img_queue = gst_element_factory_make ("queue", "image-queue");
@@ -334,6 +358,9 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
       "notify::ready-for-capture",
       G_CALLBACK (gst_camera_bin_src_notify_readyforcapture), camera);
 
+  g_object_set (vid, "location", camera->vid_location, NULL);
+  g_object_set (img, "location", camera->img_location, NULL);
+
   camera->elements_created = TRUE;
   return TRUE;
 }
@@ -367,6 +394,19 @@ gst_camera_bin_change_state (GstElement * element, GstStateChange trans)
 }
 
 static void
+gst_camera_bin_set_location (GstCameraBin * camera, const gchar * location)
+{
+  if (camera->mode == MODE_IMAGE) {
+    g_object_set (camera->imgbin, "location", location, NULL);
+    g_free (camera->img_location);
+    camera->img_location = g_strdup (location);
+  } else {
+    g_free (camera->vid_location);
+    camera->vid_location = g_strdup (location);
+  }
+}
+
+static void
 gst_camera_bin_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
@@ -376,6 +416,9 @@ gst_camera_bin_set_property (GObject * object, guint prop_id,
     case PROP_MODE:
       gst_camera_bin_change_mode (camera, g_value_get_enum (value));
       break;
+    case PROP_LOCATION:
+      gst_camera_bin_set_location (camera, g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -392,6 +435,13 @@ gst_camera_bin_get_property (GObject * object, guint prop_id,
     case PROP_MODE:
       g_value_set_enum (value, camera->mode);
       break;
+    case PROP_LOCATION:
+      if (camera->mode == MODE_VIDEO) {
+        g_value_set_string (value, camera->vid_location);
+      } else {
+        g_value_set_string (value, camera->img_location);
+      }
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index a859d80..247e186 100644 (file)
@@ -41,9 +41,14 @@ struct _GstCameraBin
   gulong src_capture_notify_id;
 
   GstElement *vidbin;
+  GstElement *imgbin;
+
+  gint vid_index;
 
   /* properties */
   gint mode;
+  gchar *vid_location;
+  gchar *img_location;
 
   gboolean elements_created;
 };
index 242172a..df253d0 100644 (file)
 
 enum
 {
-  PROP_0
+  PROP_0,
+  PROP_LOCATION
 };
 
+#define DEFAULT_LOCATION "img_%d"
+
 /* pad templates */
 
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -62,6 +65,41 @@ static GstStateChangeReturn
 gst_image_capture_bin_change_state (GstElement * element, GstStateChange trans);
 
 static void
+gst_image_capture_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstImageCaptureBin *imgbin = GST_IMAGE_CAPTURE_BIN_CAST (object);
+
+  switch (prop_id) {
+    case PROP_LOCATION:
+      imgbin->location = g_value_dup_string (value);
+      if (imgbin->sink) {
+        g_object_set (imgbin, "location", imgbin->location, NULL);
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_image_capture_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstImageCaptureBin *imgbin = GST_IMAGE_CAPTURE_BIN_CAST (object);
+
+  switch (prop_id) {
+    case PROP_LOCATION:
+      g_value_set_string (value, imgbin->location);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
 gst_image_capture_bin_base_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
@@ -77,12 +115,23 @@ gst_image_capture_bin_base_init (gpointer g_class)
 static void
 gst_image_capture_bin_class_init (GstImageCaptureBinClass * klass)
 {
+  GObjectClass *gobject_class;
   GstElementClass *element_class;
 
+  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
 
+  gobject_class->set_property = gst_image_capture_bin_set_property;
+  gobject_class->get_property = gst_image_capture_bin_get_property;
+
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_image_capture_bin_change_state);
+
+  g_object_class_install_property (gobject_class, PROP_LOCATION,
+      g_param_spec_string ("location", "Location",
+          "Location to save the captured files. A %%d can be used as a "
+          "placeholder for a capture count",
+          DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -94,6 +143,8 @@ gst_image_capture_bin_init (GstImageCaptureBin * image_capturebin,
       gst_static_pad_template_get (&sink_template));
   gst_element_add_pad (GST_ELEMENT_CAST (image_capturebin),
       image_capturebin->ghostpad);
+
+  image_capturebin->location = g_strdup (DEFAULT_LOCATION);
 }
 
 static gboolean
@@ -125,7 +176,8 @@ gst_image_capture_bin_create_elements (GstImageCaptureBin * icbin)
   if (!sink)
     goto error;
 
-  g_object_set (sink, "location", "cap_%03d.jpg", "async", FALSE, NULL);
+  icbin->sink = gst_object_ref (sink);
+  g_object_set (sink, "location", icbin->location, "async", FALSE, NULL);
 
   /* add and link */
   gst_bin_add_many (GST_BIN_CAST (icbin), csp, enc, mux, sink, NULL);
index b1f5f16..912dec0 100644 (file)
@@ -38,6 +38,10 @@ struct _GstImageCaptureBin
   GstBin bin;
 
   GstPad *ghostpad;
+  GstElement *sink;
+
+  /* props */
+  gchar *location;
 
   gboolean elements_created;
 };
index f4c423d..d1753e0 100644 (file)
 
 enum
 {
-  PROP_0
+  PROP_0,
+  PROP_LOCATION
 };
 
+#define DEFAULT_LOCATION "vidcap"
+
 /* pad templates */
 
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -63,6 +66,41 @@ gst_video_recording_bin_change_state (GstElement * element,
     GstStateChange trans);
 
 static void
+gst_video_recording_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstVideoRecordingBin *vidbin = GST_VIDEO_RECORDING_BIN_CAST (object);
+
+  switch (prop_id) {
+    case PROP_LOCATION:
+      vidbin->location = g_value_dup_string (value);
+      if (vidbin->sink) {
+        g_object_set (vidbin, "location", vidbin->location, NULL);
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_video_recording_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstVideoRecordingBin *vidbin = GST_VIDEO_RECORDING_BIN_CAST (object);
+
+  switch (prop_id) {
+    case PROP_LOCATION:
+      g_value_set_string (value, vidbin->location);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
 gst_video_recording_bin_base_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
@@ -78,12 +116,22 @@ gst_video_recording_bin_base_init (gpointer g_class)
 static void
 gst_video_recording_bin_class_init (GstVideoRecordingBinClass * klass)
 {
+  GObjectClass *gobject_class;
   GstElementClass *element_class;
 
+  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
 
+  gobject_class->set_property = gst_video_recording_bin_set_property;
+  gobject_class->get_property = gst_video_recording_bin_get_property;
+
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_video_recording_bin_change_state);
+
+  g_object_class_install_property (gobject_class, PROP_LOCATION,
+      g_param_spec_string ("location", "Location",
+          "Location to save the captured files.",
+          DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -95,6 +143,8 @@ gst_video_recording_bin_init (GstVideoRecordingBin * video_recordingbin,
       gst_static_pad_template_get (&sink_template));
   gst_element_add_pad (GST_ELEMENT_CAST (video_recordingbin),
       video_recordingbin->ghostpad);
+
+  video_recordingbin->location = g_strdup (DEFAULT_LOCATION);
 }
 
 static gboolean
@@ -126,7 +176,8 @@ gst_video_recording_bin_create_elements (GstVideoRecordingBin * vrbin)
   if (!sink)
     goto error;
 
-  g_object_set (sink, "location", "cap.ogg", "async", FALSE, NULL);
+  vrbin->sink = gst_object_ref (sink);
+  g_object_set (sink, "location", vrbin->location, "async", FALSE, NULL);
 
   /* add and link */
   gst_bin_add_many (GST_BIN_CAST (vrbin), csp, enc, mux, sink, NULL);
index 88651fa..cf4de89 100644 (file)
@@ -38,6 +38,10 @@ struct _GstVideoRecordingBin
   GstBin bin;
 
   GstPad *ghostpad;
+  GstElement *sink;
+
+  /* props */
+  gchar *location;
 
   gboolean elements_created;
 };