gst_camera_bin_start_capture (GstCameraBin * camerabin)
{
GST_DEBUG_OBJECT (camerabin, "Received start-capture");
- g_mutex_lock (camerabin->capture_mutex);
- if (!camerabin->capturing) {
- GST_INFO_OBJECT (camerabin, "Starting capture, mode: %d", camerabin->mode);
- g_object_set (camerabin->src, "mode", camerabin->mode, NULL);
- camerabin->capturing = TRUE;
- } else {
- GST_WARNING_OBJECT (camerabin, "Capture already ongoing");
- }
- g_mutex_unlock (camerabin->capture_mutex);
+ g_signal_emit_by_name (camerabin->src, "start-capture", NULL);
}
static void
gst_camera_bin_stop_capture (GstCameraBin * camerabin)
{
- /* TODO do we need a lock here? it is just an if */
- if (camerabin->capturing) {
- /* Capturing is cleaned on the notify function because it works
- * both for images and videos */
- g_object_set (camerabin->src, "mode", MODE_PREVIEW, NULL);
- }
+ g_signal_emit_by_name (camerabin->src, "stop-capture", NULL);
}
static void
gst_camera_bin_change_mode (GstCameraBin * camerabin, gint mode)
{
+ if (mode == camerabin->mode)
+ return;
+
/* stop any ongoing capture */
gst_camera_bin_stop_capture (camerabin);
-
camerabin->mode = mode;
+ g_object_set (camerabin->src, "mode", mode, NULL);
}
static void
{
GstCameraBin *camerabin = GST_CAMERA_BIN_CAST (object);
- if (camerabin->src_mode_notify_id)
- g_signal_handler_disconnect (camerabin->src, camerabin->src_mode_notify_id);
if (camerabin->src)
gst_object_unref (camerabin->src);
- g_mutex_free (camerabin->capture_mutex);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_camera_bin_init (GstCameraBin * camerabin)
{
- camerabin->capturing = FALSE;
- camerabin->capture_mutex = g_mutex_new ();
camerabin->mode = MODE_IMAGE;
}
-static void
-gst_camera_bin_src_notify_mode (GObject * src, GParamSpec * pspec,
- gpointer data)
-{
- GstCameraBin *camera = GST_CAMERA_BIN_CAST (data);
- gint mode;
-
- g_object_get (src, "mode", &mode, NULL);
-
- if (mode == MODE_PREVIEW) {
- g_mutex_lock (camera->capture_mutex);
- g_assert (camera->capturing);
- camera->capturing = FALSE;
- g_mutex_unlock (camera->capture_mutex);
- }
-}
-
/**
* gst_camera_bin_create_elements:
* @param camera: the #GstCameraBin
vf = gst_element_factory_make ("viewfinderbin", "vf-bin");
camera->src = gst_object_ref (src);
- camera->src_mode_notify_id = g_signal_connect (src, "notify::mode",
- (GCallback) gst_camera_bin_src_notify_mode, camera);
vid_queue = gst_element_factory_make ("queue", "video-queue");
img_queue = gst_element_factory_make ("queue", "image-queue");
#include "camerabingeneral.h"
#include "gstcamerabin-enum.h"
+enum
+{
+ /* action signals */
+ START_CAPTURE_SIGNAL,
+ STOP_CAPTURE_SIGNAL,
+ /* emit signals */
+ IMG_DONE_SIGNAL,
+ LAST_SIGNAL
+};
#define CAMERABIN_DEFAULT_VF_CAPS "video/x-raw-yuv,format=(fourcc)I420"
GST_DEBUG_CATEGORY (v4l2_camera_src_debug);
#define GST_CAT_DEFAULT v4l2_camera_src_debug
+static guint v4l2camerasrc_signals[LAST_SIGNAL];
+
GST_BOILERPLATE (GstV4l2CameraSrc, gst_v4l2_camera_src, GstBaseCameraSrc,
GST_TYPE_BASE_CAMERA_SRC);
static void
gst_v4l2_camera_src_dispose (GObject * object)
{
+ GstV4l2CameraSrc *src = GST_V4L2_CAMERA_SRC (object);
+
+ g_mutex_free (src->capturing_mutex);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
gpointer data)
{
GstV4l2CameraSrc *self = GST_V4L2_CAMERA_SRC (data);
- gboolean ret;
- GST_DEBUG_OBJECT (self, "pass buffer: %d", self->mode == MODE_IMAGE);
+ gboolean ret = FALSE;
- ret = self->mode == MODE_IMAGE;
- if (ret) {
- self->mode = MODE_PREVIEW;
- g_object_notify (G_OBJECT (self), "mode");
+ GST_DEBUG_OBJECT (self, "pass buffer: %d", self->mode == MODE_IMAGE);
+ g_mutex_lock (self->capturing_mutex);
+ if (self->image_capture_count > 0) {
+ ret = TRUE;
+ self->image_capture_count--;
+ if (self->image_capture_count == 0)
+ self->capturing = FALSE;
}
+ g_mutex_unlock (self->capturing_mutex);
return ret;
}
GstV4l2CameraSrc *self = GST_V4L2_CAMERA_SRC (data);
gboolean ret = FALSE;
- GST_DEBUG_OBJECT (self, "pass buffer: %d", self->mode == MODE_VIDEO);
-
/* TODO do we want to lock for every buffer? */
/*
* Note that we can use gst_pad_push_event here because we are a buffer
* probe.
*/
- if (self->mode == MODE_VIDEO) {
- GST_OBJECT_LOCK (self);
- if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
- /* send the newseg */
- gst_pad_push_event (pad, gst_event_new_new_segment (FALSE, 1.0,
- GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer), -1, 0));
- self->video_rec_status = GST_VIDEO_RECORDING_STATUS_RUNNING;
- ret = TRUE;
- } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_FINISHING) {
- /* send eos */
- gst_pad_push_event (pad, gst_event_new_eos ());
- self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
- self->mode = MODE_PREVIEW;
- g_object_notify (G_OBJECT (self), "mode");
- } else {
- ret = TRUE;
- }
- GST_OBJECT_UNLOCK (self);
+ g_mutex_lock (self->capturing_mutex);
+ if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
+ /* NOP */
+ } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
+ /* send the newseg */
+ gst_pad_push_event (pad, gst_event_new_new_segment (FALSE, 1.0,
+ GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer), -1, 0));
+ self->video_rec_status = GST_VIDEO_RECORDING_STATUS_RUNNING;
+ ret = TRUE;
+ } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_FINISHING) {
+ /* send eos */
+ gst_pad_push_event (pad, gst_event_new_eos ());
+ self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
+ self->capturing = FALSE;
+ } else {
+ ret = TRUE;
}
-
+ g_mutex_unlock (self->capturing_mutex);
return ret;
}
{
GstV4l2CameraSrc *self = GST_V4L2_CAMERA_SRC (bcamsrc);
GstPhotography *photography = gst_base_camera_src_get_photography (bcamsrc);
- gint ret = TRUE;
if (photography) {
if (g_object_class_find_property (G_OBJECT_GET_CLASS (photography),
}
}
- switch (mode) {
- case MODE_PREVIEW:
- if (self->mode == MODE_VIDEO) {
- GST_OBJECT_LOCK (self);
- if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING)
- self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
- else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_RUNNING)
- self->video_rec_status = GST_VIDEO_RECORDING_STATUS_FINISHING;
- GST_OBJECT_UNLOCK (self);
- }
- break;
- case MODE_IMAGE:
- ret = start_image_capture (GST_V4L2_CAMERA_SRC (bcamsrc));
- break;
- case MODE_VIDEO:
- GST_OBJECT_LOCK (self);
- if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE)
- self->video_rec_status = GST_VIDEO_RECORDING_STATUS_STARTING;
- GST_OBJECT_UNLOCK (self);
- break;
- default:
- g_assert_not_reached ();
- ret = FALSE;
- }
-
- if (ret)
- self->mode = mode;
- return ret;
+ self->mode = mode;
+ return TRUE;
}
static gboolean
}
static void
+gst_v4l2_camera_src_start_capture (GstV4l2CameraSrc * src)
+{
+ g_mutex_lock (src->capturing_mutex);
+ if (src->capturing) {
+ GST_WARNING_OBJECT (src, "Capturing already ongoing");
+ g_mutex_unlock (src->capturing_mutex);
+ return;
+ }
+
+ src->capturing = TRUE;
+ if (src->mode == MODE_IMAGE) {
+ src->image_capture_count = 1;
+ start_image_capture (src);
+ } else if (src->mode == MODE_VIDEO) {
+ if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
+ src->video_rec_status = GST_VIDEO_RECORDING_STATUS_STARTING;
+ }
+ } else {
+ g_assert_not_reached ();
+ src->capturing = FALSE;
+ }
+ g_mutex_unlock (src->capturing_mutex);
+}
+
+static void
+gst_v4l2_camera_src_stop_capture (GstV4l2CameraSrc * src)
+{
+ g_mutex_lock (src->capturing_mutex);
+ if (!src->capturing) {
+ GST_DEBUG_OBJECT (src, "No ongoing capture");
+ g_mutex_unlock (src->capturing_mutex);
+ return;
+ }
+ if (src->mode == MODE_VIDEO) {
+ if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_STARTING) {
+ GST_DEBUG_OBJECT (src, "Aborting not started recording");
+ src->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
+
+ } else if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_RUNNING) {
+ GST_DEBUG_OBJECT (src, "Marking video recording as finishing");
+ src->video_rec_status = GST_VIDEO_RECORDING_STATUS_FINISHING;
+ }
+ } else {
+ src->image_capture_count = 0;
+ src->capturing = FALSE;
+ }
+ g_mutex_unlock (src->capturing_mutex);
+}
+
+static void
gst_v4l2_camera_src_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gobject_class->set_property = gst_v4l2_camera_src_set_property;
gobject_class->get_property = gst_v4l2_camera_src_get_property;
- // g_object_class_install_property ....
+ /* g_object_class_install_property .... */
g_object_class_install_property (gobject_class, ARG_MODE,
g_param_spec_enum ("mode", "Mode",
- "The capture mode (still image capture, video recording or "
- "viewfinder)",
- GST_TYPE_CAMERABIN_MODE, MODE_PREVIEW,
+ "The capture mode (still image capture or video recording)",
+ GST_TYPE_CAMERABIN_MODE, MODE_IMAGE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /* Signals */
+ v4l2camerasrc_signals[START_CAPTURE_SIGNAL] =
+ g_signal_new ("start-capture",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GstV4l2CameraSrcClass, start_capture),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ v4l2camerasrc_signals[STOP_CAPTURE_SIGNAL] =
+ g_signal_new ("stop-capture",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GstV4l2CameraSrcClass, stop_capture),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ klass->start_capture = gst_v4l2_camera_src_start_capture;
+ klass->stop_capture = gst_v4l2_camera_src_stop_capture;
+
gstbasecamerasrc_class->construct_pipeline =
gst_v4l2_camera_src_construct_pipeline;
gstbasecamerasrc_class->setup_pipeline = gst_v4l2_camera_src_setup_pipeline;
GstV4l2CameraSrcClass * klass)
{
/* TODO where are variables reset? */
- self->mode = MODE_PREVIEW;
+ self->mode = MODE_IMAGE;
+ self->image_capture_count = 0;
self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
+ self->capturing_mutex = g_mutex_new ();
+ self->capturing = FALSE;
}
gboolean