diff options
author | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-01-27 14:39:19 -0300 |
---|---|---|
committer | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-02-03 19:09:20 -0300 |
commit | 869a61343c415cee12fef7dd43d4c1a0114acf4c (patch) | |
tree | e1173509bf537cda76c95e4384abfbb78dff9b61 | |
parent | b2a45f6f21f44ca0d0c127c6a7f1fe25a206dea0 (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.c | 17 | ||||
-rw-r--r-- | gst/camerabin2/camerabingeneral.h | 3 | ||||
-rw-r--r-- | gst/camerabin2/gstcamerabin2.c | 31 | ||||
-rw-r--r-- | gst/camerabin2/gstcamerabin2.h | 1 | ||||
-rw-r--r-- | gst/camerabin2/gstwrappercamerabinsrc.c | 48 | ||||
-rw-r--r-- | gst/camerabin2/gstwrappercamerabinsrc.h | 2 |
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; }; |