mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
camerabin: implement video preview creation
Completes preview creation mechanism to be able to provide a preview image for video clips too.
This commit is contained in:
parent
52e314ef81
commit
fe70981023
4 changed files with 126 additions and 63 deletions
|
@ -59,24 +59,20 @@ create_element (const gchar * factory_name, const gchar * elem_name,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_camerabin_preview_create_pipeline:
|
* gst_camerabin_preview_create_pipeline:
|
||||||
* @camera: camerabin object
|
* @caps: pointer to the caps used in pipeline
|
||||||
*
|
*
|
||||||
* Create a preview converter pipeline.
|
* Create a preview converter pipeline that outputs the format defined in
|
||||||
|
* @caps parameter.
|
||||||
*
|
*
|
||||||
* Returns: TRUE if pipeline was constructed, otherwise FALSE.
|
* Returns: New pipeline, or NULL if error occured.
|
||||||
*/
|
*/
|
||||||
gboolean
|
GstElement *
|
||||||
gst_camerabin_preview_create_pipeline (GstCameraBin * camera)
|
gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstElement *src, *csp, *filter, *vscale, *sink;
|
GstElement *pipe, *src, *csp, *filter, *vscale, *sink;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (!camera->preview_caps) {
|
g_return_val_if_fail (caps != NULL, FALSE);
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Destroy old pipeline, if any */
|
|
||||||
gst_camerabin_preview_destroy_pipeline (camera);
|
|
||||||
|
|
||||||
GST_DEBUG ("creating elements");
|
GST_DEBUG ("creating elements");
|
||||||
|
|
||||||
|
@ -87,17 +83,19 @@ gst_camerabin_preview_create_pipeline (GstCameraBin * camera)
|
||||||
!create_element ("fakesink", "prev_sink", &sink, &error))
|
!create_element ("fakesink", "prev_sink", &sink, &error))
|
||||||
goto no_elements;
|
goto no_elements;
|
||||||
|
|
||||||
camera->preview_pipeline = gst_pipeline_new ("preview-pipeline");
|
/* We have multiple pipelines created by using this function, so we can't
|
||||||
if (camera->preview_pipeline == NULL)
|
* give a name to them. Another way would to ensure the uniqueness of the
|
||||||
|
* name here*/
|
||||||
|
pipe = gst_pipeline_new (NULL);
|
||||||
|
if (pipe == NULL)
|
||||||
goto no_pipeline;
|
goto no_pipeline;
|
||||||
|
|
||||||
GST_DEBUG ("adding elements");
|
GST_DEBUG ("adding elements");
|
||||||
gst_bin_add_many (GST_BIN (camera->preview_pipeline),
|
gst_bin_add_many (GST_BIN (pipe), src, csp, filter, vscale, sink, NULL);
|
||||||
src, csp, filter, vscale, sink, NULL);
|
|
||||||
|
|
||||||
GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, camera->preview_caps);
|
GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
g_object_set (filter, "caps", camera->preview_caps, NULL);
|
g_object_set (filter, "caps", caps, NULL);
|
||||||
g_object_set (sink, "preroll-queue-len", 1, "signal-handoffs", TRUE, NULL);
|
g_object_set (sink, "preroll-queue-len", 1, "signal-handoffs", TRUE, NULL);
|
||||||
g_object_set (vscale, "method", 0, NULL);
|
g_object_set (vscale, "method", 0, NULL);
|
||||||
|
|
||||||
|
@ -118,20 +116,20 @@ gst_camerabin_preview_create_pipeline (GstCameraBin * camera)
|
||||||
if (!gst_element_link_pads (filter, "src", sink, "sink"))
|
if (!gst_element_link_pads (filter, "src", sink, "sink"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return pipe;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
no_elements:
|
no_elements:
|
||||||
{
|
{
|
||||||
g_warning ("Could not make preview pipeline: %s", error->message);
|
g_warning ("Could not make preview pipeline: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
no_pipeline:
|
no_pipeline:
|
||||||
{
|
{
|
||||||
g_warning ("Could not make preview pipeline: %s",
|
g_warning ("Could not make preview pipeline: %s",
|
||||||
"no pipeline (unknown error)");
|
"no pipeline (unknown error)");
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,23 +137,25 @@ no_pipeline:
|
||||||
/**
|
/**
|
||||||
* gst_camerabin_preview_destroy_pipeline:
|
* gst_camerabin_preview_destroy_pipeline:
|
||||||
* @camera: camerabin object
|
* @camera: camerabin object
|
||||||
|
* @pipeline: the pipeline to be destroyed
|
||||||
*
|
*
|
||||||
* Destroy preview converter pipeline.
|
* Destroy preview converter pipeline.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera)
|
gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera,
|
||||||
|
GstElement * pipeline)
|
||||||
{
|
{
|
||||||
if (camera->preview_pipeline) {
|
g_return_if_fail (pipeline != NULL);
|
||||||
gst_element_set_state (camera->preview_pipeline, GST_STATE_NULL);
|
|
||||||
gst_object_unref (camera->preview_pipeline);
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
camera->preview_pipeline = NULL;
|
gst_object_unref (pipeline);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_camerabin_preview_convert:
|
* gst_camerabin_preview_convert:
|
||||||
* @camera: camerabin object
|
* @camera: camerabin object
|
||||||
|
* @pipeline: preview pipeline to use
|
||||||
* @buf: #GstBuffer that contains the frame to be converted
|
* @buf: #GstBuffer that contains the frame to be converted
|
||||||
*
|
*
|
||||||
* Create a preview image of the given frame.
|
* Create a preview image of the given frame.
|
||||||
|
@ -163,7 +163,8 @@ gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera)
|
||||||
* Returns: converted preview image, or NULL if operation failed.
|
* Returns: converted preview image, or NULL if operation failed.
|
||||||
*/
|
*/
|
||||||
GstBuffer *
|
GstBuffer *
|
||||||
gst_camerabin_preview_convert (GstCameraBin * camera, GstBuffer * buf)
|
gst_camerabin_preview_convert (GstCameraBin * camera,
|
||||||
|
GstElement * pipeline, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstMessage *msg;
|
GstMessage *msg;
|
||||||
GstBuffer *result = NULL;
|
GstBuffer *result = NULL;
|
||||||
|
@ -175,13 +176,13 @@ gst_camerabin_preview_convert (GstCameraBin * camera, GstBuffer * buf)
|
||||||
|
|
||||||
g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
|
g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
|
||||||
|
|
||||||
if (camera->preview_pipeline == NULL) {
|
if (pipeline == NULL) {
|
||||||
GST_WARNING ("pipeline is NULL");
|
GST_WARNING ("pipeline is NULL");
|
||||||
goto no_pipeline;
|
goto no_pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = gst_bin_get_by_name (GST_BIN (camera->preview_pipeline), "prev_src");
|
src = gst_bin_get_by_name (GST_BIN (pipeline), "prev_src");
|
||||||
sink = gst_bin_get_by_name (GST_BIN (camera->preview_pipeline), "prev_sink");
|
sink = gst_bin_get_by_name (GST_BIN (pipeline), "prev_sink");
|
||||||
|
|
||||||
if (!src || !sink) {
|
if (!src || !sink) {
|
||||||
GST_WARNING ("pipeline doesn't have src / sink elements");
|
GST_WARNING ("pipeline doesn't have src / sink elements");
|
||||||
|
@ -199,12 +200,12 @@ gst_camerabin_preview_convert (GstCameraBin * camera, GstBuffer * buf)
|
||||||
|
|
||||||
GST_DEBUG ("running conversion pipeline, source is: %" GST_PTR_FORMAT,
|
GST_DEBUG ("running conversion pipeline, source is: %" GST_PTR_FORMAT,
|
||||||
GST_BUFFER_CAPS (buf));
|
GST_BUFFER_CAPS (buf));
|
||||||
gst_element_set_state (camera->preview_pipeline, GST_STATE_PLAYING);
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||||
|
|
||||||
g_signal_emit_by_name (src, "push-buffer", buf, &fret);
|
g_signal_emit_by_name (src, "push-buffer", buf, &fret);
|
||||||
|
|
||||||
/* TODO: do we need to use a bus poll, can we just register a callback to the bus? */
|
/* TODO: do we need to use a bus poll, can we just register a callback to the bus? */
|
||||||
bus = gst_element_get_bus (camera->preview_pipeline);
|
bus = gst_element_get_bus (pipeline);
|
||||||
msg =
|
msg =
|
||||||
gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, 25 * GST_SECOND);
|
gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, 25 * GST_SECOND);
|
||||||
|
|
||||||
|
@ -245,7 +246,7 @@ gst_camerabin_preview_convert (GstCameraBin * camera, GstBuffer * buf)
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (sink, G_CALLBACK (save_result),
|
g_signal_handlers_disconnect_by_func (sink, G_CALLBACK (save_result),
|
||||||
&result);
|
&result);
|
||||||
gst_element_set_state (camera->preview_pipeline, GST_STATE_READY);
|
gst_element_set_state (pipeline, GST_STATE_READY);
|
||||||
|
|
||||||
GST_BUFFER_FLAGS (buf) = bflags;
|
GST_BUFFER_FLAGS (buf) = bflags;
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,14 @@
|
||||||
#include "gstcamerabin.h"
|
#include "gstcamerabin.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
gboolean gst_camerabin_preview_create_pipeline (GstCameraBin * camera);
|
GstElement * gst_camerabin_preview_create_pipeline (GstCameraBin * camera,
|
||||||
|
GstCaps * caps);
|
||||||
|
|
||||||
void gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera);
|
void gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera,
|
||||||
|
GstElement * pipeline);
|
||||||
|
|
||||||
GstBuffer *gst_camerabin_preview_convert (GstCameraBin * camera,
|
GstBuffer *gst_camerabin_preview_convert (GstCameraBin * camera,
|
||||||
GstBuffer * buf);
|
GstElement * pipeline, GstBuffer * buf);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* __CAMERABINPREVIEW_H__ */
|
#endif /* __CAMERABINPREVIEW_H__ */
|
||||||
|
|
|
@ -91,6 +91,22 @@
|
||||||
* </para>
|
* </para>
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
* <refsect2>
|
* <refsect2>
|
||||||
|
* <title>Video and image previews</title>
|
||||||
|
* <para>
|
||||||
|
* GstCameraBin contains "preview-caps" property, which is used to determine
|
||||||
|
* whether the application wants a preview image of the captured picture or
|
||||||
|
* video. When set, a GstMessage named "preview-image" will be sent. This
|
||||||
|
* message will contain a GstBuffer holding the preview image, converted
|
||||||
|
* to a format defined by those preview caps. The ownership of the preview
|
||||||
|
* image is kept in GstCameraBin, so application should ref the preview buffer
|
||||||
|
* object if it needs to use it elsewhere than in message handler.
|
||||||
|
*
|
||||||
|
* Defining preview caps is done by selecting the capturing mode first and
|
||||||
|
* then setting the property. Camerabin remembers caps separately for both
|
||||||
|
* modes, so it is not necessary to set the caps again after changing the mode.
|
||||||
|
* </para>
|
||||||
|
* </refsect2>
|
||||||
|
* <refsect2>
|
||||||
* <note>
|
* <note>
|
||||||
* <para>
|
* <para>
|
||||||
* Since the muxers tested so far have problems with discontinous buffers, QoS
|
* Since the muxers tested so far have problems with discontinous buffers, QoS
|
||||||
|
@ -876,18 +892,12 @@ camerabin_dispose_elements (GstCameraBin * camera)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free caps */
|
/* Free caps */
|
||||||
if (camera->image_capture_caps) {
|
gst_caps_replace (&camera->image_capture_caps, NULL);
|
||||||
gst_caps_replace (&camera->image_capture_caps, NULL);
|
gst_caps_replace (&camera->view_finder_caps, NULL);
|
||||||
}
|
gst_caps_replace (&camera->allowed_caps, NULL);
|
||||||
if (camera->view_finder_caps) {
|
gst_caps_replace (&camera->preview_caps, NULL);
|
||||||
gst_caps_replace (&camera->view_finder_caps, NULL);
|
gst_caps_replace (&camera->video_preview_caps, NULL);
|
||||||
}
|
gst_buffer_replace (&camera->video_preview_buffer, NULL);
|
||||||
if (camera->allowed_caps) {
|
|
||||||
gst_caps_replace (&camera->allowed_caps, NULL);
|
|
||||||
}
|
|
||||||
if (camera->preview_caps) {
|
|
||||||
gst_caps_replace (&camera->preview_caps, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (camera->event_tags) {
|
if (camera->event_tags) {
|
||||||
gst_tag_list_free (camera->event_tags);
|
gst_tag_list_free (camera->event_tags);
|
||||||
|
@ -1678,6 +1688,7 @@ image_pad_blocked (GstPad * pad, gboolean blocked, gpointer user_data)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_camerabin_send_preview (GstCameraBin * camera, GstBuffer * buffer)
|
gst_camerabin_send_preview (GstCameraBin * camera, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
GstElement *pipeline;
|
||||||
GstBuffer *prev = NULL;
|
GstBuffer *prev = NULL;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
GstMessage *msg;
|
GstMessage *msg;
|
||||||
|
@ -1685,7 +1696,9 @@ gst_camerabin_send_preview (GstCameraBin * camera, GstBuffer * buffer)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (camera, "creating preview");
|
GST_DEBUG_OBJECT (camera, "creating preview");
|
||||||
|
|
||||||
prev = gst_camerabin_preview_convert (camera, buffer);
|
pipeline = (camera->mode == MODE_IMAGE) ?
|
||||||
|
camera->preview_pipeline : camera->video_preview_pipeline;
|
||||||
|
prev = gst_camerabin_preview_convert (camera, pipeline, buffer);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (camera, "preview created: %p", prev);
|
GST_DEBUG_OBJECT (camera, "preview created: %p", prev);
|
||||||
|
|
||||||
|
@ -1789,6 +1802,13 @@ gst_camerabin_have_vid_buffer (GstPad * pad, GstBuffer * buffer,
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
GST_LOG ("got video buffer %p with size %d",
|
GST_LOG ("got video buffer %p with size %d",
|
||||||
buffer, GST_BUFFER_SIZE (buffer));
|
buffer, GST_BUFFER_SIZE (buffer));
|
||||||
|
|
||||||
|
if (camera->video_preview_caps &&
|
||||||
|
!camera->video_preview_buffer && !camera->stop_requested) {
|
||||||
|
GST_DEBUG ("storing video preview %p", buffer);
|
||||||
|
camera->video_preview_buffer = gst_buffer_copy (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (camera->stop_requested)) {
|
if (G_UNLIKELY (camera->stop_requested)) {
|
||||||
gst_camerabin_send_video_eos (camera);
|
gst_camerabin_send_video_eos (camera);
|
||||||
ret = FALSE; /* Drop buffer */
|
ret = FALSE; /* Drop buffer */
|
||||||
|
@ -1972,6 +1992,12 @@ gst_camerabin_do_stop (GstCameraBin * camera)
|
||||||
GST_DEBUG_OBJECT (camera, "mark stop");
|
GST_DEBUG_OBJECT (camera, "mark stop");
|
||||||
camera->stop_requested = TRUE;
|
camera->stop_requested = TRUE;
|
||||||
|
|
||||||
|
if (camera->video_preview_caps && camera->video_preview_buffer) {
|
||||||
|
gst_camerabin_send_preview (camera, camera->video_preview_buffer);
|
||||||
|
gst_buffer_unref (camera->video_preview_buffer);
|
||||||
|
camera->video_preview_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Take special care when stopping paused video capture */
|
/* Take special care when stopping paused video capture */
|
||||||
if ((camera->active_bin == camera->vidbin) && camera->paused) {
|
if ((camera->active_bin == camera->vidbin) && camera->paused) {
|
||||||
/* Send eos event to video bin before setting it to playing */
|
/* Send eos event to video bin before setting it to playing */
|
||||||
|
@ -2709,6 +2735,8 @@ gst_camerabin_init (GstCameraBin * camera, GstCameraBinClass * gclass)
|
||||||
camera->pad_src_vid = NULL;
|
camera->pad_src_vid = NULL;
|
||||||
camera->pad_view_vid = NULL;
|
camera->pad_view_vid = NULL;
|
||||||
|
|
||||||
|
camera->video_preview_buffer = NULL;
|
||||||
|
|
||||||
/* source elements */
|
/* source elements */
|
||||||
camera->src_vid_src = NULL;
|
camera->src_vid_src = NULL;
|
||||||
camera->src_filter = NULL;
|
camera->src_filter = NULL;
|
||||||
|
@ -2753,7 +2781,15 @@ gst_camerabin_dispose (GObject * object)
|
||||||
gst_element_set_state (camera->vidbin, GST_STATE_NULL);
|
gst_element_set_state (camera->vidbin, GST_STATE_NULL);
|
||||||
gst_object_unref (camera->vidbin);
|
gst_object_unref (camera->vidbin);
|
||||||
|
|
||||||
gst_camerabin_preview_destroy_pipeline (camera);
|
if (camera->preview_pipeline) {
|
||||||
|
gst_camerabin_preview_destroy_pipeline (camera, camera->preview_pipeline);
|
||||||
|
camera->preview_pipeline = NULL;
|
||||||
|
}
|
||||||
|
if (camera->video_preview_pipeline) {
|
||||||
|
gst_camerabin_preview_destroy_pipeline (camera,
|
||||||
|
camera->video_preview_pipeline);
|
||||||
|
camera->video_preview_pipeline = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
camerabin_destroy_elements (camera);
|
camerabin_destroy_elements (camera);
|
||||||
camerabin_dispose_elements (camera);
|
camerabin_dispose_elements (camera);
|
||||||
|
@ -2878,24 +2914,39 @@ gst_camerabin_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_PREVIEW_CAPS:
|
case ARG_PREVIEW_CAPS:
|
||||||
/* Currently camerabin only provides preview for images, so we don't
|
{
|
||||||
* even handle video mode */
|
GstElement **prev_pipe = NULL;
|
||||||
|
GstCaps **prev_caps = NULL;
|
||||||
|
GstCaps *new_caps = NULL;
|
||||||
|
|
||||||
if (camera->mode == MODE_IMAGE) {
|
if (camera->mode == MODE_IMAGE) {
|
||||||
GstCaps *new_caps = NULL;
|
prev_pipe = &camera->preview_pipeline;
|
||||||
|
prev_caps = &camera->preview_caps;
|
||||||
|
} else if (camera->mode == MODE_VIDEO) {
|
||||||
|
prev_pipe = &camera->video_preview_pipeline;
|
||||||
|
prev_caps = &camera->video_preview_caps;
|
||||||
|
}
|
||||||
|
|
||||||
new_caps = (GstCaps *) gst_value_get_caps (value);
|
new_caps = (GstCaps *) gst_value_get_caps (value);
|
||||||
|
|
||||||
|
if (prev_caps && !gst_caps_is_equal (*prev_caps, new_caps)) {
|
||||||
GST_DEBUG_OBJECT (camera,
|
GST_DEBUG_OBJECT (camera,
|
||||||
"setting preview caps: %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT,
|
"setting preview caps: %" GST_PTR_FORMAT, new_caps);
|
||||||
camera->preview_caps, new_caps);
|
if (*prev_pipe) {
|
||||||
|
gst_camerabin_preview_destroy_pipeline (camera, *prev_pipe);
|
||||||
|
*prev_pipe = NULL;
|
||||||
|
}
|
||||||
|
GST_OBJECT_LOCK (camera);
|
||||||
|
gst_caps_replace (prev_caps, new_caps);
|
||||||
|
GST_OBJECT_UNLOCK (camera);
|
||||||
|
|
||||||
if (!gst_caps_is_equal (camera->preview_caps, new_caps)) {
|
if (new_caps && !gst_caps_is_any (new_caps) &&
|
||||||
GST_OBJECT_LOCK (camera);
|
!gst_caps_is_empty (new_caps)) {
|
||||||
gst_caps_replace (&camera->preview_caps, new_caps);
|
*prev_pipe = gst_camerabin_preview_create_pipeline (camera, new_caps);
|
||||||
GST_OBJECT_UNLOCK (camera);
|
|
||||||
gst_camerabin_preview_create_pipeline (camera);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -2968,7 +3019,10 @@ gst_camerabin_get_property (GObject * object, guint prop_id,
|
||||||
gst_value_set_caps (value, camera->view_finder_caps);
|
gst_value_set_caps (value, camera->view_finder_caps);
|
||||||
break;
|
break;
|
||||||
case ARG_PREVIEW_CAPS:
|
case ARG_PREVIEW_CAPS:
|
||||||
gst_value_set_caps (value, camera->preview_caps);
|
if (camera->mode == MODE_IMAGE)
|
||||||
|
gst_value_set_caps (value, camera->preview_caps);
|
||||||
|
else if (camera->mode == MODE_VIDEO)
|
||||||
|
gst_value_set_caps (value, camera->video_preview_caps);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
|
|
@ -87,6 +87,9 @@ struct _GstCameraBin
|
||||||
/* Caps used to create preview image */
|
/* Caps used to create preview image */
|
||||||
GstCaps *preview_caps;
|
GstCaps *preview_caps;
|
||||||
|
|
||||||
|
/* Caps used to create video preview image */
|
||||||
|
GstCaps *video_preview_caps;
|
||||||
|
|
||||||
/* The digital zoom (from 100% to 1000%) */
|
/* The digital zoom (from 100% to 1000%) */
|
||||||
gint zoom;
|
gint zoom;
|
||||||
|
|
||||||
|
@ -110,6 +113,9 @@ struct _GstCameraBin
|
||||||
GstElement *vidbin; /* bin that holds video capturing elements */
|
GstElement *vidbin; /* bin that holds video capturing elements */
|
||||||
GstElement *active_bin; /* image or video bin that is currently in use */
|
GstElement *active_bin; /* image or video bin that is currently in use */
|
||||||
GstElement *preview_pipeline; /* pipeline for creating preview images */
|
GstElement *preview_pipeline; /* pipeline for creating preview images */
|
||||||
|
GstElement *video_preview_pipeline; /* pipeline for creating video preview image */
|
||||||
|
|
||||||
|
GstBuffer *video_preview_buffer; /* buffer for storing video preview */
|
||||||
|
|
||||||
/* source elements */
|
/* source elements */
|
||||||
GstElement *src_vid_src;
|
GstElement *src_vid_src;
|
||||||
|
|
Loading…
Reference in a new issue