mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
v4l2camerasrc: Implement video capture
Implements video capture on v4l2camerasrc by using the mode property, when mode is set to video, the pad probe pushes a new segment and starts pushing buffers on the pad, when it the property is sent back to preview, the pad probe pushes an EOS and stops pushing buffers. This is controlled by a Recording State variable, that is protected by the GST_OBJECT_LOCK. I don't think locking for every buffer is nice, so we could find an alternative lockless way here.
This commit is contained in:
parent
596422d19c
commit
91b7f2d99e
2 changed files with 66 additions and 11 deletions
|
@ -70,8 +70,8 @@ gst_v4l2_camera_src_set_property (GObject * object,
|
|||
|
||||
switch (prop_id) {
|
||||
case ARG_MODE:
|
||||
self->mode = g_value_get_enum (value);
|
||||
gst_base_camera_src_set_mode (GST_BASE_CAMERA_SRC (self), self->mode);
|
||||
gst_base_camera_src_set_mode (GST_BASE_CAMERA_SRC (self),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case ARG_FILTER_CAPS:
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
@ -168,8 +168,36 @@ gst_v4l2_camera_src_vidsrc_probe (GstPad * pad, GstBuffer * buffer,
|
|||
gpointer data)
|
||||
{
|
||||
GstV4l2CameraSrc *self = GST_V4L2_CAMERA_SRC (data);
|
||||
gboolean ret = FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "pass buffer: %d", self->mode == MODE_VIDEO);
|
||||
return 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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -678,6 +706,7 @@ gst_v4l2_camera_src_set_mode (GstBaseCameraSrc * bcamsrc, GstCameraBinMode mode)
|
|||
{
|
||||
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),
|
||||
|
@ -686,20 +715,34 @@ gst_v4l2_camera_src_set_mode (GstBaseCameraSrc * bcamsrc, GstCameraBinMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
self->mode = mode;
|
||||
|
||||
switch (mode) {
|
||||
case MODE_PREVIEW:
|
||||
return TRUE; // XXX
|
||||
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:
|
||||
return start_image_capture (GST_V4L2_CAMERA_SRC (bcamsrc));
|
||||
ret = start_image_capture (GST_V4L2_CAMERA_SRC (bcamsrc));
|
||||
break;
|
||||
case MODE_VIDEO:
|
||||
return TRUE; // XXX
|
||||
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;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
||||
return FALSE;
|
||||
if (ret)
|
||||
self->mode = mode;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1058,7 +1101,9 @@ static void
|
|||
gst_v4l2_camera_src_init (GstV4l2CameraSrc * self,
|
||||
GstV4l2CameraSrcClass * klass)
|
||||
{
|
||||
/* TODO where are variables reset? */
|
||||
self->mode = MODE_PREVIEW;
|
||||
self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -41,6 +41,13 @@ G_BEGIN_DECLS
|
|||
typedef struct _GstV4l2CameraSrc GstV4l2CameraSrc;
|
||||
typedef struct _GstV4l2CameraSrcClass GstV4l2CameraSrcClass;
|
||||
|
||||
enum GstVideoRecordingStatus {
|
||||
GST_VIDEO_RECORDING_STATUS_DONE,
|
||||
GST_VIDEO_RECORDING_STATUS_STARTING,
|
||||
GST_VIDEO_RECORDING_STATUS_RUNNING,
|
||||
GST_VIDEO_RECORDING_STATUS_FINISHING
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* GstV4l2CameraSrc:
|
||||
|
@ -52,6 +59,9 @@ struct _GstV4l2CameraSrc
|
|||
|
||||
GstCameraBinMode mode;
|
||||
|
||||
/* video recording controls */
|
||||
gint video_rec_status;
|
||||
|
||||
/* source elements */
|
||||
GstElement *src_vid_src;
|
||||
GstElement *src_filter;
|
||||
|
|
Loading…
Reference in a new issue