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.c17
-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.c48
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.h2
6 files changed, 88 insertions, 14 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
@@ -320,6 +320,7 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
/**
* 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
@@ -327,7 +328,8 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
* 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;
@@ -354,11 +356,19 @@ gst_camerabin_create_preview_pipeline (GstElement * element)
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))
+ 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;
@@ -366,6 +376,7 @@ gst_camerabin_create_preview_pipeline (GstElement * element)
NULL);
data->element = element;
+ data->filter = filter;
return data;
error:
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
@@ -28,13 +28,14 @@ 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);
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
@@ -75,7 +75,8 @@ enum
PROP_VIDEO_ENCODING_PROFILE,
PROP_IMAGE_FILTER,
PROP_VIDEO_FILTER,
- PROP_VIEWFINDER_FILTER
+ PROP_VIEWFINDER_FILTER,
+ PROP_PREVIEW_FILTER
};
enum
@@ -303,6 +304,10 @@ gst_camera_bin_dispose (GObject * object)
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);
}
@@ -432,6 +437,12 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
" (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:
@@ -678,7 +689,8 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
&& 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));
@@ -872,6 +884,17 @@ gst_camera_bin_set_property (GObject * object, guint prop_id,
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;
@@ -972,6 +995,10 @@ gst_camera_bin_get_property (GObject * object, guint prop_id,
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
@@ -71,6 +71,7 @@ struct _GstCameraBin
gchar *image_location;
gboolean post_previews;
GstCaps *preview_caps;
+ GstElement *preview_filter;
GstEncodingProfile *video_profile;
gboolean elements_created;
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
@@ -39,7 +39,8 @@ enum
PROP_0,
PROP_VIDEO_SRC,
PROP_POST_PREVIEWS,
- PROP_PREVIEW_CAPS
+ PROP_PREVIEW_CAPS,
+ PROP_PREVIEW_FILTER
};
#define DEFAULT_POST_PREVIEWS TRUE
@@ -74,6 +75,11 @@ gst_wrapper_camera_bin_src_dispose (GObject * object)
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);
}
@@ -113,6 +119,12 @@ gst_wrapper_camera_bin_src_set_property (GObject * object,
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;
@@ -139,6 +151,10 @@ gst_wrapper_camera_bin_src_get_property (GObject * object,
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;
@@ -294,8 +310,7 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
GstPad *vf_pad;
GstPad *tee_capture_pad;
- if (self->elements_created)
- return TRUE;
+ if (!self->elements_created) {
GST_DEBUG_OBJECT (self, "constructing pipeline");
@@ -346,7 +361,8 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
goto done;
if (!(tee =
- gst_camerabin_create_and_add_element (cbin, "tee", "camerasrc-tee")))
+ gst_camerabin_create_and_add_element (cbin, "tee",
+ "camerasrc-tee")))
goto done;
/* viewfinder pad */
@@ -392,8 +408,10 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
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);
+ 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,
@@ -411,10 +429,19 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
gst_pad_set_active (self->vfsrc, TRUE);
gst_pad_set_active (self->imgsrc, TRUE); /* XXX ??? */
gst_pad_set_active (self->vidsrc, TRUE); /* XXX ??? */
+ }
+ /* recreate the preview pipeline */
+ if (self->preview_pipeline && self->preview_filter_changed) {
+ gst_camerabin_destroy_preview_pipeline (self->preview_pipeline);
+ }
- /* create the preview pipeline */
+ if (self->preview_pipeline == NULL)
self->preview_pipeline =
- gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self));
+ gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self),
+ self->preview_filter);
+
+ 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);
@@ -1025,6 +1052,11 @@ gst_wrapper_camera_bin_src_class_init (GstWrapperCameraBinSrcClass * klass)
"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 =
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
@@ -113,6 +113,8 @@ struct _GstWrapperCameraBinSrc
GstCameraBinPreviewPipelineData *preview_pipeline;
gboolean post_previews;
GstCaps *preview_caps;
+ GstElement *preview_filter;
+ gboolean preview_filter_changed;
};