summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2011-01-27 14:39:19 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2011-02-03 19:09:20 -0300
commit869a61343c415cee12fef7dd43d4c1a0114acf4c (patch)
treee1173509bf537cda76c95e4384abfbb78dff9b61
parentb2a45f6f21f44ca0d0c127c6a7f1fe25a206dea0 (diff)
camerabin2: Add preview-filter property
Adds a property to select a custom element for preview pipeline buffers processing
-rw-r--r--gst/camerabin2/camerabingeneral.c19
-rw-r--r--gst/camerabin2/camerabingeneral.h3
-rw-r--r--gst/camerabin2/gstcamerabin2.c31
-rw-r--r--gst/camerabin2/gstcamerabin2.h1
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.c238
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.h2
6 files changed, 184 insertions, 110 deletions
diff --git a/gst/camerabin2/camerabingeneral.c b/gst/camerabin2/camerabingeneral.c
index d6c1c8674..26edc12d0 100644
--- a/gst/camerabin2/camerabingeneral.c
+++ b/gst/camerabin2/camerabingeneral.c
@@ -317,20 +317,22 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
return GST_FLOW_OK;
}
/**
* gst_camerabin_create_preview_pipeline:
* @element: Owner of this pipeline
+ * @filter: Custom filter to process preview data (an extra ref is taken)
*
* Creates a new previewing pipeline that can receive buffers
* to be posted as camerabin preview messages for @element
*
* Returns: The newly created #GstCameraBinPreviewPipelineData
*/
GstCameraBinPreviewPipelineData *
-gst_camerabin_create_preview_pipeline (GstElement * element)
+gst_camerabin_create_preview_pipeline (GstElement * element,
+ GstElement * filter)
{
GstCameraBinPreviewPipelineData *data;
GstElement *csp;
GstElement *csp2;
GstElement *vscale;
gboolean added = FALSE;
@@ -351,24 +353,33 @@ gst_camerabin_create_preview_pipeline (GstElement * element)
!csp2 || !vscale) {
goto error;
}
gst_bin_add_many (GST_BIN (data->pipeline), data->appsrc, data->capsfilter,
data->appsink, csp, csp2, vscale, NULL);
+ if (filter)
+ gst_bin_add (GST_BIN (data->pipeline), gst_object_ref (filter));
added = TRUE;
- if (!gst_element_link_many (data->appsrc, csp, vscale, csp2, data->capsfilter,
- data->appsink, NULL))
- goto error;
+ if (filter) {
+ if (!gst_element_link_many (data->appsrc, filter, csp, vscale, csp2,
+ data->capsfilter, data->appsink, NULL))
+ goto error;
+ } else {
+ if (!gst_element_link_many (data->appsrc, csp, vscale, csp2,
+ data->capsfilter, data->appsink, NULL))
+ goto error;
+ }
callbacks.new_preroll = gst_camerabin_preview_pipeline_new_preroll;
callbacks.new_buffer = gst_camerabin_preview_pipeline_new_buffer;
gst_app_sink_set_callbacks ((GstAppSink *) data->appsink, &callbacks, data,
NULL);
data->element = element;
+ data->filter = filter;
return data;
error:
GST_WARNING ("Failed to create camerabin's preview pipeline");
if (!added) {
if (csp)
diff --git a/gst/camerabin2/camerabingeneral.h b/gst/camerabin2/camerabingeneral.h
index 4e0812a99..f39cbd77e 100644
--- a/gst/camerabin2/camerabingeneral.h
+++ b/gst/camerabin2/camerabingeneral.h
@@ -25,19 +25,20 @@
typedef struct
{
GstElement *pipeline;
GstElement *appsrc;
+ GstElement *filter;
GstElement *capsfilter;
GstElement *appsink;
GstElement *element;
} GstCameraBinPreviewPipelineData;
-GstCameraBinPreviewPipelineData *gst_camerabin_create_preview_pipeline (GstElement * element);
+GstCameraBinPreviewPipelineData *gst_camerabin_create_preview_pipeline (GstElement * element, GstElement * filter);
void gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData * preview);
gboolean gst_camerabin_preview_pipeline_post (GstCameraBinPreviewPipelineData * preview, GstBuffer * buffer);
void gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview, GstCaps * caps);
gboolean gst_camerabin_try_add_element (GstBin * bin, const gchar * srcpad, GstElement * new_elem, const gchar * dstpad);
gboolean gst_camerabin_add_element (GstBin * bin, GstElement * new_elem);
diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c
index 85a56967a..d7139a4ab 100644
--- a/gst/camerabin2/gstcamerabin2.c
+++ b/gst/camerabin2/gstcamerabin2.c
@@ -72,13 +72,14 @@ enum
PROP_VIDEO_CAPTURE_CAPS,
PROP_POST_PREVIEWS,
PROP_PREVIEW_CAPS,
PROP_VIDEO_ENCODING_PROFILE,
PROP_IMAGE_FILTER,
PROP_VIDEO_FILTER,
- PROP_VIEWFINDER_FILTER
+ PROP_VIEWFINDER_FILTER,
+ PROP_PREVIEW_FILTER
};
enum
{
/* action signals */
START_CAPTURE_SIGNAL,
@@ -300,12 +301,16 @@ gst_camera_bin_dispose (GObject * object)
if (camerabin->video_profile)
gst_encoding_profile_unref (camerabin->video_profile);
if (camerabin->preview_caps)
gst_caps_replace (&camerabin->preview_caps, NULL);
+ if (camerabin->preview_filter) {
+ gst_object_unref (camerabin->preview_filter);
+ camerabin->preview_filter = NULL;
+ }
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_camera_bin_finalize (GObject * object)
@@ -429,12 +434,18 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
g_object_class_install_property (object_class, PROP_VIEWFINDER_FILTER,
g_param_spec_object ("viewfinder-filter", "Viewfinder filter",
"The element that will process frames going to the viewfinder."
" (Should be set on NULL state)",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_PREVIEW_FILTER,
+ g_param_spec_object ("preview-filter", "Preview filter",
+ "The element that will process preview buffers."
+ " (Should be set on NULL state)",
+ GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/**
* GstCameraBin::capture-start:
* @camera: the camera bin element
*
* Starts image capture or video recording depending on the Mode.
@@ -675,13 +686,14 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
g_assert (camera->src != NULL);
g_object_set (camera->src, "mode", camera->mode, NULL);
if (camera->src
&& g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src),
"preview-caps")) {
g_object_set (camera->src, "post-previews", camera->post_previews,
- "preview-caps", camera->preview_caps, NULL);
+ "preview-caps", camera->preview_caps, "preview-filter",
+ camera->preview_filter, NULL);
}
if (new_src) {
gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->src));
camera->src_capture_notify_id = g_signal_connect (G_OBJECT (camera->src),
"notify::ready-for-capture",
G_CALLBACK (gst_camera_bin_src_notify_readyforcapture), camera);
@@ -869,12 +881,23 @@ gst_camera_bin_set_property (GObject * object, guint prop_id,
case PROP_VIEWFINDER_FILTER:
if (camera->user_viewfinder_filter)
g_object_unref (camera->user_viewfinder_filter);
camera->user_viewfinder_filter = g_value_dup_object (value);
break;
+ case PROP_PREVIEW_FILTER:
+ if (camera->preview_filter)
+ g_object_unref (camera->preview_filter);
+
+ camera->preview_filter = g_value_dup_object (value);
+ if (camera->src
+ && g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src),
+ "preview-filter"))
+ g_object_set (camera->src, "preview-filter", camera->preview_filter,
+ NULL);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
@@ -969,12 +992,16 @@ gst_camera_bin_get_property (GObject * object, guint prop_id,
g_value_set_object (value, camera->image_filter);
break;
case PROP_VIEWFINDER_FILTER:
if (camera->viewfinder_filter)
g_value_set_object (value, camera->viewfinder_filter);
break;
+ case PROP_PREVIEW_FILTER:
+ if (camera->preview_filter)
+ g_value_set_object (value, camera->preview_filter);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h
index f24417f1e..64828b49e 100644
--- a/gst/camerabin2/gstcamerabin2.h
+++ b/gst/camerabin2/gstcamerabin2.h
@@ -68,12 +68,13 @@ struct _GstCameraBin
/* properties */
gint mode;
gchar *video_location;
gchar *image_location;
gboolean post_previews;
GstCaps *preview_caps;
+ GstElement *preview_filter;
GstEncodingProfile *video_profile;
gboolean elements_created;
};
struct _GstCameraBinClass
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c
index 864373bdc..c35fe8d77 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.c
+++ b/gst/camerabin2/gstwrappercamerabinsrc.c
@@ -36,13 +36,14 @@
enum
{
PROP_0,
PROP_VIDEO_SRC,
PROP_POST_PREVIEWS,
- PROP_PREVIEW_CAPS
+ PROP_PREVIEW_CAPS,
+ PROP_PREVIEW_FILTER
};
#define DEFAULT_POST_PREVIEWS TRUE
/* Using "bilinear" as default zoom method */
#define CAMERABIN_DEFAULT_ZOOM_METHOD 1
@@ -71,12 +72,17 @@ gst_wrapper_camera_bin_src_dispose (GObject * object)
self->preview_pipeline = NULL;
}
if (self->preview_caps)
gst_caps_replace (&self->preview_caps, NULL);
+ if (self->preview_filter) {
+ gst_object_unref (self->preview_filter);
+ self->preview_filter = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_wrapper_camera_bin_src_finalize (GstWrapperCameraBinSrc * self)
{
@@ -110,12 +116,18 @@ gst_wrapper_camera_bin_src_set_property (GObject * object,
gst_caps_replace (&self->preview_caps,
(GstCaps *) gst_value_get_caps (value));
if (self->preview_pipeline)
gst_camerabin_preview_set_caps (self->preview_pipeline,
(GstCaps *) gst_value_get_caps (value));
break;
+ case PROP_PREVIEW_FILTER:
+ if (self->preview_filter)
+ gst_object_unref (self->preview_filter);
+ self->preview_filter = g_value_dup_object (value);
+ self->preview_filter_changed = TRUE;
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
break;
}
}
@@ -136,12 +148,16 @@ gst_wrapper_camera_bin_src_get_property (GObject * object,
g_value_set_boolean (value, self->post_previews);
break;
case PROP_PREVIEW_CAPS:
if (self->preview_caps)
gst_value_set_caps (value, self->preview_caps);
break;
+ case PROP_PREVIEW_FILTER:
+ if (self->preview_filter)
+ g_value_set_object (value, self->preview_filter);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
break;
}
}
@@ -291,133 +307,144 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
GstElement *tee;
gboolean ret = FALSE;
GstElement *videoscale;
GstPad *vf_pad;
GstPad *tee_capture_pad;
- if (self->elements_created)
- return TRUE;
+ if (!self->elements_created) {
- GST_DEBUG_OBJECT (self, "constructing pipeline");
+ GST_DEBUG_OBJECT (self, "constructing pipeline");
- /* Add application set or default video src element */
- if (!(self->src_vid_src = gst_camerabin_setup_default_element (cbin,
- self->app_vid_src, "autovideosrc", DEFAULT_VIDEOSRC,
- "camerasrc-real-src"))) {
- self->src_vid_src = NULL;
- goto done;
- } else {
- if (!gst_camerabin_add_element (cbin, self->src_vid_src)) {
+ /* Add application set or default video src element */
+ if (!(self->src_vid_src = gst_camerabin_setup_default_element (cbin,
+ self->app_vid_src, "autovideosrc", DEFAULT_VIDEOSRC,
+ "camerasrc-real-src"))) {
+ self->src_vid_src = NULL;
goto done;
+ } else {
+ if (!gst_camerabin_add_element (cbin, self->src_vid_src)) {
+ goto done;
+ }
}
- }
- /* we lost the reference */
- self->app_vid_src = NULL;
+ /* we lost the reference */
+ self->app_vid_src = NULL;
- /* add a buffer probe to the src elemento to drop EOS from READY->NULL */
- {
- GstPad *pad;
- pad = gst_element_get_static_pad (self->src_vid_src, "src");
+ /* add a buffer probe to the src elemento to drop EOS from READY->NULL */
+ {
+ GstPad *pad;
+ pad = gst_element_get_static_pad (self->src_vid_src, "src");
- self->src_event_probe_id = gst_pad_add_event_probe (pad,
- (GCallback) gst_camerabin_drop_eos_probe, NULL);
- gst_object_unref (pad);
- }
+ self->src_event_probe_id = gst_pad_add_event_probe (pad,
+ (GCallback) gst_camerabin_drop_eos_probe, NULL);
+ gst_object_unref (pad);
+ }
- if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
- "src-colorspace"))
- goto done;
+ if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
+ "src-colorspace"))
+ goto done;
- if (!(self->src_filter =
- gst_camerabin_create_and_add_element (cbin, "capsfilter",
- "src-capsfilter")))
- goto done;
+ if (!(self->src_filter =
+ gst_camerabin_create_and_add_element (cbin, "capsfilter",
+ "src-capsfilter")))
+ goto done;
- if (!(self->src_zoom_crop =
- gst_camerabin_create_and_add_element (cbin, "videocrop",
- "zoom-crop")))
- goto done;
- if (!(self->src_zoom_scale =
- gst_camerabin_create_and_add_element (cbin, "videoscale",
- "zoom-scale")))
- goto done;
- if (!(self->src_zoom_filter =
- gst_camerabin_create_and_add_element (cbin, "capsfilter",
- "zoom-capsfilter")))
- goto done;
+ if (!(self->src_zoom_crop =
+ gst_camerabin_create_and_add_element (cbin, "videocrop",
+ "zoom-crop")))
+ goto done;
+ if (!(self->src_zoom_scale =
+ gst_camerabin_create_and_add_element (cbin, "videoscale",
+ "zoom-scale")))
+ goto done;
+ if (!(self->src_zoom_filter =
+ gst_camerabin_create_and_add_element (cbin, "capsfilter",
+ "zoom-capsfilter")))
+ goto done;
- if (!(tee =
- gst_camerabin_create_and_add_element (cbin, "tee", "camerasrc-tee")))
- goto done;
+ if (!(tee =
+ gst_camerabin_create_and_add_element (cbin, "tee",
+ "camerasrc-tee")))
+ goto done;
- /* viewfinder pad */
- vf_pad = gst_element_get_request_pad (tee, "src%d");
- g_object_set (tee, "alloc-pad", vf_pad, NULL);
- gst_object_unref (vf_pad);
+ /* viewfinder pad */
+ vf_pad = gst_element_get_request_pad (tee, "src%d");
+ g_object_set (tee, "alloc-pad", vf_pad, NULL);
+ gst_object_unref (vf_pad);
- /* the viewfinder should always work, so we add some converters to it */
- if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
- "viewfinder-colorspace"))
- goto done;
- if (!(videoscale =
- gst_camerabin_create_and_add_element (cbin, "videoscale",
- "viewfinder-scale")))
- goto done;
+ /* the viewfinder should always work, so we add some converters to it */
+ if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace",
+ "viewfinder-colorspace"))
+ goto done;
+ if (!(videoscale =
+ gst_camerabin_create_and_add_element (cbin, "videoscale",
+ "viewfinder-scale")))
+ goto done;
- /* image/video pad from tee */
- tee_capture_pad = gst_element_get_request_pad (tee, "src%d");
+ /* image/video pad from tee */
+ tee_capture_pad = gst_element_get_request_pad (tee, "src%d");
- self->output_selector =
- gst_element_factory_make ("output-selector", "outsel");
- g_object_set (self->output_selector, "pad-negotiation-mode", 0, NULL);
- gst_bin_add (GST_BIN (self), self->output_selector);
- {
- GstPad *pad = gst_element_get_static_pad (self->output_selector, "sink");
+ self->output_selector =
+ gst_element_factory_make ("output-selector", "outsel");
+ g_object_set (self->output_selector, "pad-negotiation-mode", 0, NULL);
+ gst_bin_add (GST_BIN (self), self->output_selector);
+ {
+ GstPad *pad = gst_element_get_static_pad (self->output_selector, "sink");
- /* check return TODO */
- gst_pad_link (tee_capture_pad, pad);
- gst_object_unref (pad);
+ /* check return TODO */
+ gst_pad_link (tee_capture_pad, pad);
+ gst_object_unref (pad);
+ }
+ gst_object_unref (tee_capture_pad);
+
+ /* Create the 2 output pads for video and image */
+ self->outsel_vidpad =
+ gst_element_get_request_pad (self->output_selector, "src%d");
+ self->outsel_imgpad =
+ gst_element_get_request_pad (self->output_selector, "src%d");
+
+ g_assert (self->outsel_vidpad != NULL);
+ g_assert (self->outsel_imgpad != NULL);
+
+ gst_pad_add_buffer_probe (self->outsel_imgpad,
+ G_CALLBACK (gst_wrapper_camera_bin_src_imgsrc_probe), self);
+ gst_pad_add_buffer_probe (self->outsel_vidpad,
+ G_CALLBACK (gst_wrapper_camera_bin_src_vidsrc_probe), self);
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc),
+ self->outsel_imgpad);
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc),
+ self->outsel_vidpad);
+
+ if (bcamsrc->mode == MODE_IMAGE) {
+ g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
+ NULL);
+ } else {
+ g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
+ NULL);
+ }
+
+ /* hook-up the vf ghostpad */
+ vf_pad = gst_element_get_static_pad (videoscale, "src");
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
+ gst_object_unref (vf_pad);
+
+ gst_pad_set_active (self->vfsrc, TRUE);
+ gst_pad_set_active (self->imgsrc, TRUE); /* XXX ??? */
+ gst_pad_set_active (self->vidsrc, TRUE); /* XXX ??? */
}
- gst_object_unref (tee_capture_pad);
-
- /* Create the 2 output pads for video and image */
- self->outsel_vidpad =
- gst_element_get_request_pad (self->output_selector, "src%d");
- self->outsel_imgpad =
- gst_element_get_request_pad (self->output_selector, "src%d");
-
- g_assert (self->outsel_vidpad != NULL);
- g_assert (self->outsel_imgpad != NULL);
-
- gst_pad_add_buffer_probe (self->outsel_imgpad,
- G_CALLBACK (gst_wrapper_camera_bin_src_imgsrc_probe), self);
- gst_pad_add_buffer_probe (self->outsel_vidpad,
- G_CALLBACK (gst_wrapper_camera_bin_src_vidsrc_probe), self);
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc), self->outsel_imgpad);
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), self->outsel_vidpad);
-
- if (bcamsrc->mode == MODE_IMAGE) {
- g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
- NULL);
- } else {
- g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
- NULL);
+ /* recreate the preview pipeline */
+ if (self->preview_pipeline && self->preview_filter_changed) {
+ gst_camerabin_destroy_preview_pipeline (self->preview_pipeline);
}
- /* hook-up the vf ghostpad */
- vf_pad = gst_element_get_static_pad (videoscale, "src");
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
- gst_object_unref (vf_pad);
-
- gst_pad_set_active (self->vfsrc, TRUE);
- gst_pad_set_active (self->imgsrc, TRUE); /* XXX ??? */
- gst_pad_set_active (self->vidsrc, TRUE); /* XXX ??? */
+ if (self->preview_pipeline == NULL)
+ self->preview_pipeline =
+ gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self),
+ self->preview_filter);
- /* create the preview pipeline */
- self->preview_pipeline =
- gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self));
+ g_assert (self->preview_pipeline != NULL);
+ self->preview_filter_changed = FALSE;
if (self->preview_caps)
gst_camerabin_preview_set_caps (self->preview_pipeline, self->preview_caps);
ret = TRUE;
self->elements_created = TRUE;
done:
@@ -1022,12 +1049,17 @@ gst_wrapper_camera_bin_src_class_init (GstWrapperCameraBinSrcClass * klass)
g_object_class_install_property (gobject_class, PROP_PREVIEW_CAPS,
g_param_spec_boxed ("preview-caps", "Preview caps",
"The caps of the preview image to be posted",
GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_PREVIEW_FILTER,
+ g_param_spec_object ("preview-filter", "Preview filter",
+ "A custom preview filter to process preview image data",
+ GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gstelement_class->change_state = gst_wrapper_camera_bin_src_change_state;
gstbasecamerasrc_class->construct_pipeline =
gst_wrapper_camera_bin_src_construct_pipeline;
gstbasecamerasrc_class->set_zoom = gst_wrapper_camera_bin_src_set_zoom;
gstbasecamerasrc_class->set_mode = gst_wrapper_camera_bin_src_set_mode;
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.h b/gst/camerabin2/gstwrappercamerabinsrc.h
index c74be279c..b2f4c7ae6 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.h
+++ b/gst/camerabin2/gstwrappercamerabinsrc.h
@@ -110,12 +110,14 @@ struct _GstWrapperCameraBinSrc
gboolean video_renegotiate;
/* Preview convert pipeline */
GstCameraBinPreviewPipelineData *preview_pipeline;
gboolean post_previews;
GstCaps *preview_caps;
+ GstElement *preview_filter;
+ gboolean preview_filter_changed;
};
/**
* GstWrapperCameraBinSrcClass:
*