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.
This commit is contained in:
Thiago Santos 2010-11-30 20:13:27 -03:00
parent 5b3deecab9
commit ba878c95b2
7 changed files with 173 additions and 7 deletions

View 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])

View 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;
}
@ -366,6 +393,19 @@ gst_camera_bin_change_state (GstElement * element, GstStateChange trans)
return ret;
}
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;

View 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;
};

View file

@ -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",
@ -61,6 +64,41 @@ GST_BOILERPLATE (GstImageCaptureBin, gst_image_capture_bin, GstBin,
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)
{
@ -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);

View file

@ -38,6 +38,10 @@ struct _GstImageCaptureBin
GstBin bin;
GstPad *ghostpad;
GstElement *sink;
/* props */
gchar *location;
gboolean elements_created;
};

View file

@ -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",
@ -62,6 +65,41 @@ static GstStateChangeReturn
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)
{
@ -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);

View file

@ -38,6 +38,10 @@ struct _GstVideoRecordingBin
GstBin bin;
GstPad *ghostpad;
GstElement *sink;
/* props */
gchar *location;
gboolean elements_created;
};