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 | 19 | ||||
-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 | 238 | ||||
-rw-r--r-- | gst/camerabin2/gstwrappercamerabinsrc.h | 2 |
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; }; |