camerabin: add "preview-source-filter" property

Adds 'preview-source-filter' for adding an element to proccess
the preview images before posting them to the bus.
This commit is contained in:
Hoseok Chang 2010-06-21 16:17:24 +03:00 committed by Thiago Santos
parent 5c92dc23cc
commit f0f8df1a30
5 changed files with 98 additions and 7 deletions

View file

@ -68,7 +68,8 @@ create_element (const gchar * factory_name, const gchar * elem_name,
* Returns: New pipeline, or NULL if error occured. * Returns: New pipeline, or NULL if error occured.
*/ */
GstElement * GstElement *
gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps) gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps,
GstElement * src_filter)
{ {
GstElement *pipe, *src, *csp, *filter, *vscale, *sink; GstElement *pipe, *src, *csp, *filter, *vscale, *sink;
GError *error = NULL; GError *error = NULL;
@ -93,6 +94,9 @@ gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps)
GST_DEBUG ("adding elements"); GST_DEBUG ("adding elements");
gst_bin_add_many (GST_BIN (pipe), src, csp, filter, vscale, sink, NULL); gst_bin_add_many (GST_BIN (pipe), src, csp, filter, vscale, sink, NULL);
if (src_filter) {
gst_bin_add (GST_BIN (pipe), src_filter);
}
GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, caps); GST_DEBUG ("preview format is: %" GST_PTR_FORMAT, caps);
@ -105,9 +109,20 @@ gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstCaps * caps)
if (!gst_element_link_pads (src, "src", vscale, "sink")) if (!gst_element_link_pads (src, "src", vscale, "sink"))
return FALSE; return FALSE;
GST_DEBUG ("linking vscale->csp"); if (src_filter) {
if (!gst_element_link_pads (vscale, "src", csp, "sink")) GST_DEBUG ("linking vscale->filter");
return FALSE; if (!gst_element_link_pads (vscale, "src", src_filter, "sink")) {
return FALSE;
}
GST_DEBUG ("linking filter->csp");
if (!gst_element_link_pads (src_filter, "src", csp, "sink")) {
return FALSE;
}
} else {
GST_DEBUG ("linking vscale->csp");
if (!gst_element_link_pads (vscale, "src", csp, "sink"))
return FALSE;
}
GST_DEBUG ("linking csp->capsfilter"); GST_DEBUG ("linking csp->capsfilter");
if (!gst_element_link_pads (csp, "src", filter, "sink")) if (!gst_element_link_pads (csp, "src", filter, "sink"))

View file

@ -27,7 +27,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
GstElement * gst_camerabin_preview_create_pipeline (GstCameraBin * camera, GstElement * gst_camerabin_preview_create_pipeline (GstCameraBin * camera,
GstCaps * caps); GstCaps * caps, GstElement * src_filter);
void gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera, void gst_camerabin_preview_destroy_pipeline (GstCameraBin * camera,
GstElement * pipeline); GstElement * pipeline);

View file

@ -66,7 +66,8 @@ enum
ARG_IMAGE_CAPTURE_HEIGHT, ARG_IMAGE_CAPTURE_HEIGHT,
ARG_VIDEO_CAPTURE_WIDTH, ARG_VIDEO_CAPTURE_WIDTH,
ARG_VIDEO_CAPTURE_HEIGHT, ARG_VIDEO_CAPTURE_HEIGHT,
ARG_VIDEO_CAPTURE_FRAMERATE ARG_VIDEO_CAPTURE_FRAMERATE,
ARG_PREVIEW_SOURCE_FILTER
}; };
/** /**

View file

@ -890,6 +890,16 @@ camerabin_dispose_elements (GstCameraBin * camera)
camera->app_viewfinder_filter = NULL; camera->app_viewfinder_filter = NULL;
} }
if (camera->app_preview_source_filter) {
gst_object_unref (camera->app_preview_source_filter);
camera->app_preview_source_filter = NULL;
}
if (camera->app_video_preview_source_filter) {
gst_object_unref (camera->app_video_preview_source_filter);
camera->app_video_preview_source_filter = NULL;
}
/* Free caps */ /* Free caps */
gst_caps_replace (&camera->image_capture_caps, NULL); gst_caps_replace (&camera->image_capture_caps, NULL);
gst_caps_replace (&camera->view_finder_caps, NULL); gst_caps_replace (&camera->view_finder_caps, NULL);
@ -2856,6 +2866,22 @@ gst_camerabin_class_init (GstCameraBinClass * klass)
"Caps defining the preview image format", "Caps defining the preview image format",
GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstCameraBin:preview-source-filter:
* Set up preview filter element, all frames coming from appsrc
* element will be processed by this element.
* Applications can use this to overlay text/images for preview frame,
* for example.
* This property can only be set while #GstCameraBin is in NULL state.
* The ownership of the element will be taken by #GstCameraBin.
*/
g_object_class_install_property (gobject_class, ARG_PREVIEW_SOURCE_FILTER,
g_param_spec_object ("preview-source-filter",
"preview source filter element",
"Optional preview source filter GStreamer element",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/** /**
* GstCameraBin:viewfinder-filter: * GstCameraBin:viewfinder-filter:
* Set up viewfinder filter element, all frames going to viewfinder sink * Set up viewfinder filter element, all frames going to viewfinder sink
@ -3155,6 +3181,10 @@ gst_camerabin_init (GstCameraBin * camera, GstCameraBinClass * gclass)
camera->app_vf_sink = NULL; camera->app_vf_sink = NULL;
camera->app_viewfinder_filter = NULL; camera->app_viewfinder_filter = NULL;
/* preview elements */
camera->app_preview_source_filter = NULL;
camera->app_video_preview_source_filter = NULL;
/* source elements */ /* source elements */
camera->src_vid_src = NULL; camera->src_vid_src = NULL;
camera->src_filter = NULL; camera->src_filter = NULL;
@ -3337,14 +3367,17 @@ gst_camerabin_set_property (GObject * object, guint prop_id,
case ARG_PREVIEW_CAPS: case ARG_PREVIEW_CAPS:
{ {
GstElement **prev_pipe = NULL; GstElement **prev_pipe = NULL;
GstElement **preview_source_filter = NULL;
GstCaps **prev_caps = NULL; GstCaps **prev_caps = NULL;
GstCaps *new_caps = NULL; GstCaps *new_caps = NULL;
if (camera->mode == MODE_IMAGE) { if (camera->mode == MODE_IMAGE) {
prev_pipe = &camera->preview_pipeline; prev_pipe = &camera->preview_pipeline;
preview_source_filter = &camera->app_preview_source_filter;
prev_caps = &camera->preview_caps; prev_caps = &camera->preview_caps;
} else if (camera->mode == MODE_VIDEO) { } else if (camera->mode == MODE_VIDEO) {
prev_pipe = &camera->video_preview_pipeline; prev_pipe = &camera->video_preview_pipeline;
preview_source_filter = &camera->app_video_preview_source_filter;
prev_caps = &camera->video_preview_caps; prev_caps = &camera->video_preview_caps;
} }
@ -3363,11 +3396,45 @@ gst_camerabin_set_property (GObject * object, guint prop_id,
if (new_caps && !gst_caps_is_any (new_caps) && if (new_caps && !gst_caps_is_any (new_caps) &&
!gst_caps_is_empty (new_caps)) { !gst_caps_is_empty (new_caps)) {
*prev_pipe = gst_camerabin_preview_create_pipeline (camera, new_caps); *prev_pipe =
gst_camerabin_preview_create_pipeline (camera, new_caps,
*preview_source_filter);
} }
} }
break; break;
} }
case ARG_PREVIEW_SOURCE_FILTER:
if (GST_STATE (camera) != GST_STATE_NULL) {
GST_ELEMENT_ERROR (camera, CORE, FAILED,
("camerabin must be in NULL state when setting the preview source filter element"),
(NULL));
} else {
GstElement **preview_pipe = NULL;
GstElement **preview_source_filter = NULL;
GstCaps *preview_caps = NULL;
if (camera->mode == MODE_IMAGE) {
preview_pipe = &camera->preview_pipeline;
preview_source_filter = &camera->app_preview_source_filter;
preview_caps = camera->preview_caps;
} else if (camera->mode == MODE_VIDEO) {
preview_pipe = &camera->video_preview_pipeline;
preview_source_filter = &camera->app_video_preview_source_filter;
preview_caps = camera->video_preview_caps;
}
if (*preview_source_filter)
gst_object_unref (*preview_source_filter);
*preview_source_filter = g_value_dup_object (value);
if (*preview_pipe) {
gst_camerabin_preview_destroy_pipeline (camera, *preview_pipe);
*preview_pipe =
gst_camerabin_preview_create_pipeline (camera, preview_caps,
*preview_source_filter);
}
}
break;
case ARG_VIEWFINDER_FILTER: case ARG_VIEWFINDER_FILTER:
if (GST_STATE (camera) != GST_STATE_NULL) { if (GST_STATE (camera) != GST_STATE_NULL) {
GST_ELEMENT_ERROR (camera, CORE, FAILED, GST_ELEMENT_ERROR (camera, CORE, FAILED,
@ -3526,6 +3593,12 @@ gst_camerabin_get_property (GObject * object, guint prop_id,
else if (camera->mode == MODE_VIDEO) else if (camera->mode == MODE_VIDEO)
gst_value_set_caps (value, camera->video_preview_caps); gst_value_set_caps (value, camera->video_preview_caps);
break; break;
case ARG_PREVIEW_SOURCE_FILTER:
if (camera->mode == MODE_IMAGE)
g_value_set_object (value, camera->app_preview_source_filter);
else if (camera->mode == MODE_VIDEO)
g_value_set_object (value, camera->app_video_preview_source_filter);
break;
case ARG_VIEWFINDER_FILTER: case ARG_VIEWFINDER_FILTER:
g_value_set_object (value, camera->app_viewfinder_filter); g_value_set_object (value, camera->app_viewfinder_filter);
break; break;

View file

@ -162,6 +162,8 @@ struct _GstCameraBin
GstElement *app_vf_sink; GstElement *app_vf_sink;
GstElement *app_video_filter; GstElement *app_video_filter;
GstElement *app_viewfinder_filter; GstElement *app_viewfinder_filter;
GstElement *app_preview_source_filter;
GstElement *app_video_preview_source_filter;
/* Night mode handling */ /* Night mode handling */
gboolean night_mode; gboolean night_mode;