mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
5b3deecab9
commit
ba878c95b2
7 changed files with 173 additions and 7 deletions
|
@ -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])
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -38,6 +38,10 @@ struct _GstImageCaptureBin
|
|||
GstBin bin;
|
||||
|
||||
GstPad *ghostpad;
|
||||
GstElement *sink;
|
||||
|
||||
/* props */
|
||||
gchar *location;
|
||||
|
||||
gboolean elements_created;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -38,6 +38,10 @@ struct _GstVideoRecordingBin
|
|||
GstBin bin;
|
||||
|
||||
GstPad *ghostpad;
|
||||
GstElement *sink;
|
||||
|
||||
/* props */
|
||||
gchar *location;
|
||||
|
||||
gboolean elements_created;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue