From ba878c95b2fad981fd73dec75203462d35a2ade9 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Tue, 30 Nov 2010 20:13:27 -0300 Subject: [PATCH] camerabin2: adds location property 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 | 2 +- gst/camerabin2/gstcamerabin2.c | 54 +++++++++++++++++++++++++++++++-- gst/camerabin2/gstcamerabin2.h | 5 ++++ gst/camerabin2/gstimagecapturebin.c | 56 +++++++++++++++++++++++++++++++++-- gst/camerabin2/gstimagecapturebin.h | 4 +++ gst/camerabin2/gstvideorecordingbin.c | 55 ++++++++++++++++++++++++++++++++-- gst/camerabin2/gstvideorecordingbin.h | 4 +++ 7 files changed, 173 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 3beb627..85fc6a3 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index 0c0024f..a7bd139 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -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; diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h index a859d80..247e186 100644 --- a/gst/camerabin2/gstcamerabin2.h +++ b/gst/camerabin2/gstcamerabin2.h @@ -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; }; diff --git a/gst/camerabin2/gstimagecapturebin.c b/gst/camerabin2/gstimagecapturebin.c index 242172a..df253d0 100644 --- a/gst/camerabin2/gstimagecapturebin.c +++ b/gst/camerabin2/gstimagecapturebin.c @@ -41,9 +41,12 @@ 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); diff --git a/gst/camerabin2/gstimagecapturebin.h b/gst/camerabin2/gstimagecapturebin.h index b1f5f16..912dec0 100644 --- a/gst/camerabin2/gstimagecapturebin.h +++ b/gst/camerabin2/gstimagecapturebin.h @@ -38,6 +38,10 @@ struct _GstImageCaptureBin GstBin bin; GstPad *ghostpad; + GstElement *sink; + + /* props */ + gchar *location; gboolean elements_created; }; diff --git a/gst/camerabin2/gstvideorecordingbin.c b/gst/camerabin2/gstvideorecordingbin.c index f4c423d..d1753e0 100644 --- a/gst/camerabin2/gstvideorecordingbin.c +++ b/gst/camerabin2/gstvideorecordingbin.c @@ -41,9 +41,12 @@ 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); diff --git a/gst/camerabin2/gstvideorecordingbin.h b/gst/camerabin2/gstvideorecordingbin.h index 88651fa..cf4de89 100644 --- a/gst/camerabin2/gstvideorecordingbin.h +++ b/gst/camerabin2/gstvideorecordingbin.h @@ -38,6 +38,10 @@ struct _GstVideoRecordingBin GstBin bin; GstPad *ghostpad; + GstElement *sink; + + /* props */ + gchar *location; gboolean elements_created; }; -- 2.7.4