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
@@ -322,2 +322,3 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
* @element: Owner of this pipeline
+ * @filter: Custom filter to process preview data (an extra ref is taken)
*
@@ -329,3 +330,4 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
GstCameraBinPreviewPipelineData *
-gst_camerabin_create_preview_pipeline (GstElement * element)
+gst_camerabin_create_preview_pipeline (GstElement * element,
+ GstElement * filter)
{
@@ -356,7 +358,15 @@ gst_camerabin_create_preview_pipeline (GstElement * element)
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;
+ }
@@ -368,2 +378,3 @@ gst_camerabin_create_preview_pipeline (GstElement * element)
data->element = element;
+ data->filter = filter;
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
@@ -30,2 +30,3 @@ typedef struct
GstElement *appsrc;
+ GstElement *filter;
GstElement *capsfilter;
@@ -36,3 +37,3 @@ typedef struct
-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);
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
@@ -77,3 +77,4 @@ enum
PROP_VIDEO_FILTER,
- PROP_VIEWFINDER_FILTER
+ PROP_VIEWFINDER_FILTER,
+ PROP_PREVIEW_FILTER
};
@@ -305,2 +306,6 @@ gst_camera_bin_dispose (GObject * object)
gst_caps_replace (&camerabin->preview_caps, NULL);
+ if (camerabin->preview_filter) {
+ gst_object_unref (camerabin->preview_filter);
+ camerabin->preview_filter = NULL;
+ }
@@ -434,2 +439,8 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
+ 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));
+
@@ -680,3 +691,4 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
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);
}
@@ -874,2 +886,13 @@ gst_camera_bin_set_property (GObject * object, guint prop_id,
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:
@@ -974,2 +997,6 @@ gst_camera_bin_get_property (GObject * object, guint prop_id,
break;
+ case PROP_PREVIEW_FILTER:
+ if (camera->preview_filter)
+ g_value_set_object (value, camera->preview_filter);
+ break;
default:
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
@@ -73,2 +73,3 @@ struct _GstCameraBin
GstCaps *preview_caps;
+ GstElement *preview_filter;
GstEncodingProfile *video_profile;
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
@@ -41,3 +41,4 @@ enum
PROP_POST_PREVIEWS,
- PROP_PREVIEW_CAPS
+ PROP_PREVIEW_CAPS,
+ PROP_PREVIEW_FILTER
};
@@ -76,2 +77,7 @@ gst_wrapper_camera_bin_src_dispose (GObject * object)
+ if (self->preview_filter) {
+ gst_object_unref (self->preview_filter);
+ self->preview_filter = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -115,2 +121,8 @@ gst_wrapper_camera_bin_src_set_property (GObject * object,
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:
@@ -141,2 +153,6 @@ gst_wrapper_camera_bin_src_get_property (GObject * object,
break;
+ case PROP_PREVIEW_FILTER:
+ if (self->preview_filter)
+ g_value_set_object (value, self->preview_filter);
+ break;
default:
@@ -296,123 +312,134 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
- 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)
@@ -1027,2 +1054,7 @@ gst_wrapper_camera_bin_src_class_init (GstWrapperCameraBinSrcClass * klass)
+ 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;
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
@@ -115,2 +115,4 @@ struct _GstWrapperCameraBinSrc
GstCaps *preview_caps;
+ GstElement *preview_filter;
+ gboolean preview_filter_changed;
};