diff --git a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c index 892a013826..a26533fc83 100644 --- a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c +++ b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c @@ -61,7 +61,10 @@ enum PROP_0, PROP_MODE, PROP_ZOOM, - PROP_READY_FOR_CAPTURE + PROP_READY_FOR_CAPTURE, + PROP_POST_PREVIEW, + PROP_PREVIEW_CAPS, + PROP_PREVIEW_FILTER }; enum @@ -73,6 +76,8 @@ enum LAST_SIGNAL }; +#define DEFAULT_POST_PREVIEW TRUE + static guint basecamerasrc_signals[LAST_SIGNAL]; GST_DEBUG_CATEGORY (base_camera_src_debug); @@ -276,6 +281,19 @@ gst_base_camera_src_dispose (GObject * object) g_mutex_free (src->capturing_mutex); + if (src->preview_pipeline) { + gst_camerabin_destroy_preview_pipeline (src->preview_pipeline); + src->preview_pipeline = NULL; + } + + if (src->preview_caps) + gst_caps_replace (&src->preview_caps, NULL); + + if (src->preview_filter) { + gst_object_unref (src->preview_filter); + src->preview_filter = NULL; + } + G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -303,6 +321,26 @@ gst_base_camera_src_set_property (GObject * object, gst_base_camera_src_setup_zoom (self); break; } + case PROP_POST_PREVIEW: + self->post_preview = g_value_get_boolean (value); + break; + case PROP_PREVIEW_CAPS: + gst_caps_replace (&self->preview_caps, + (GstCaps *) gst_value_get_caps (value)); + if (self->preview_pipeline) { + GST_DEBUG_OBJECT (self, + "Setting preview pipeline caps %" GST_PTR_FORMAT, + self->preview_caps); + 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; @@ -325,6 +363,17 @@ gst_base_camera_src_get_property (GObject * object, case PROP_ZOOM: g_value_set_int (value, g_atomic_int_get (&self->zoom)); break; + case PROP_POST_PREVIEW: + g_value_set_boolean (value, self->post_preview); + break; + case PROP_PREVIEW_CAPS: + 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; @@ -370,10 +419,32 @@ gst_base_camera_src_change_state (GstElement * element, case GST_STATE_CHANGE_NULL_TO_READY: if (!construct_pipeline (self)) return GST_STATE_CHANGE_FAILURE; + + /* recreate the preview pipeline */ + if (self->preview_pipeline && self->preview_filter_changed) { + gst_camerabin_destroy_preview_pipeline (self->preview_pipeline); + } + + if (self->preview_pipeline == NULL) + self->preview_pipeline = + 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_DEBUG_OBJECT (self, + "Setting preview pipeline caps %" GST_PTR_FORMAT, + self->preview_caps); + gst_camerabin_preview_set_caps (self->preview_pipeline, + self->preview_caps); + } break; case GST_STATE_CHANGE_READY_TO_PAUSED: if (!setup_pipeline (self)) return GST_STATE_CHANGE_FAILURE; + gst_element_set_state (self->preview_pipeline->pipeline, + GST_STATE_PLAYING); break; default: break; @@ -381,6 +452,14 @@ gst_base_camera_src_change_state (GstElement * element, ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL); + break; + default: + break; + } + return ret; } @@ -426,6 +505,27 @@ gst_base_camera_src_class_init (GstBaseCameraSrcClass * klass) GST_TYPE_CAMERABIN_MODE, MODE_IMAGE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstBaseCameraSrc:post-previews: + * + * When %TRUE, preview images should be posted to the bus when + * captures are made + */ + g_object_class_install_property (gobject_class, PROP_POST_PREVIEW, + g_param_spec_boolean ("post-previews", "Post Previews", + "If capture preview images should be posted to the bus", + DEFAULT_POST_PREVIEW, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_PREVIEW_CAPS, + g_param_spec_boxed ("preview-caps", "Preview caps", + "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)); + /** * GstBaseCameraSrc:ready-for-capture: * @@ -479,4 +579,16 @@ gst_base_camera_src_init (GstBaseCameraSrc * self, self->capturing = FALSE; self->capturing_mutex = g_mutex_new (); + + self->post_preview = DEFAULT_POST_PREVIEW; +} + +void +gst_base_camera_src_post_preview (GstBaseCameraSrc * self, GstBuffer * buf) +{ + if (self->post_preview) { + gst_camerabin_preview_pipeline_post (self->preview_pipeline, buf); + } else { + GST_DEBUG_OBJECT (self, "Previews not enabled, not posting"); + } } diff --git a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h index 70535bccff..4ff5e8842d 100644 --- a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h +++ b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h @@ -27,6 +27,7 @@ #include #include #include "gstcamerabin-enum.h" +#include "gstcamerabinpreview.h" G_BEGIN_DECLS #define GST_TYPE_BASE_CAMERA_SRC \ @@ -66,6 +67,13 @@ struct _GstBaseCameraSrc gboolean capturing; GMutex *capturing_mutex; + /* Preview convert pipeline */ + GstCaps *preview_caps; + gboolean post_preview; + GstElement *preview_filter; + GstCameraBinPreviewPipelineData *preview_pipeline; + gboolean preview_filter_changed; + /* Resolution of the buffers configured to camerabin */ gint width; gint height; @@ -126,6 +134,7 @@ GstCaps * gst_base_camera_src_get_allowed_input_caps (GstBaseCameraSrc * self); void gst_base_camera_src_finish_capture (GstBaseCameraSrc *self); +void gst_base_camera_src_post_preview (GstBaseCameraSrc *self, GstBuffer * buf); // XXX add methods to get/set img capture and vid capture caps.. #endif /* __GST_BASE_CAMERA_SRC_H__ */ diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c index 811479493c..d258d04f4a 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.c +++ b/gst/camerabin2/gstwrappercamerabinsrc.c @@ -37,14 +37,9 @@ enum { PROP_0, - PROP_VIDEO_SRC, - PROP_POST_PREVIEWS, - PROP_PREVIEW_CAPS, - PROP_PREVIEW_FILTER + PROP_VIDEO_SRC }; -#define DEFAULT_POST_PREVIEWS TRUE - /* Using "bilinear" as default zoom method */ #define CAMERABIN_DEFAULT_ZOOM_METHOD 1 @@ -67,19 +62,6 @@ gst_wrapper_camera_bin_src_dispose (GObject * object) self->app_vid_src = NULL; } - if (self->preview_pipeline) { - gst_camerabin_destroy_preview_pipeline (self->preview_pipeline); - self->preview_pipeline = NULL; - } - - 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); } @@ -109,26 +91,6 @@ gst_wrapper_camera_bin_src_set_property (GObject * object, gst_object_ref (self->app_vid_src); } break; - case PROP_POST_PREVIEWS: - self->post_previews = g_value_get_boolean (value); - break; - case PROP_PREVIEW_CAPS: - gst_caps_replace (&self->preview_caps, - (GstCaps *) gst_value_get_caps (value)); - if (self->preview_pipeline) { - GST_DEBUG_OBJECT (self, - "Setting preview pipeline caps %" GST_PTR_FORMAT, - self->preview_caps); - 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; @@ -148,17 +110,6 @@ gst_wrapper_camera_bin_src_get_property (GObject * object, else g_value_set_object (value, self->app_vid_src); break; - case PROP_POST_PREVIEWS: - g_value_set_boolean (value, self->post_previews); - break; - case PROP_PREVIEW_CAPS: - 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; @@ -243,10 +194,8 @@ gst_wrapper_camera_bin_src_imgsrc_probe (GstPad * pad, GstBuffer * buffer, /* post preview */ /* TODO This can likely be optimized if the viewfinder caps is the same as * the preview caps, avoiding another scaling of the same buffer. */ - if (self->post_previews) { - GST_DEBUG_OBJECT (self, "Posting preview for image"); - gst_camerabin_preview_pipeline_post (self->preview_pipeline, buffer); - } + GST_DEBUG_OBJECT (self, "Posting preview for image"); + gst_base_camera_src_post_preview (camerasrc, buffer); if (self->image_capture_count == 0) { gst_base_camera_src_finish_capture (camerasrc); @@ -294,10 +243,8 @@ gst_wrapper_camera_bin_src_vidsrc_probe (GstPad * pad, GstBuffer * buffer, self->video_rec_status = GST_VIDEO_RECORDING_STATUS_RUNNING; /* post preview */ - if (self->post_previews) { - GST_DEBUG_OBJECT (self, "Posting preview for video"); - gst_camerabin_preview_pipeline_post (self->preview_pipeline, buffer); - } + GST_DEBUG_OBJECT (self, "Posting preview for video"); + gst_base_camera_src_post_preview (camerasrc, buffer); ret = TRUE; } else if (self->video_rec_status == GST_VIDEO_RECORDING_STATUS_FINISHING) { @@ -503,24 +450,6 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc) 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); - } - - if (self->preview_pipeline == NULL) - self->preview_pipeline = - 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_DEBUG_OBJECT (self, "Setting preview pipeline caps %" GST_PTR_FORMAT, - self->preview_caps); - gst_camerabin_preview_set_caps (self->preview_pipeline, self->preview_caps); - } - ret = TRUE; self->elements_created = TRUE; done: @@ -1071,11 +1000,8 @@ gst_wrapper_camera_bin_src_change_state (GstElement * element, self->drop_newseg = FALSE; break; case GST_STATE_CHANGE_READY_TO_NULL: - gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL); break; case GST_STATE_CHANGE_NULL_TO_READY: - gst_element_set_state (self->preview_pipeline->pipeline, - GST_STATE_PLAYING); break; default: break; @@ -1121,21 +1047,6 @@ gst_wrapper_camera_bin_src_class_init (GstWrapperCameraBinSrcClass * klass) "The video source element to be used", GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_POST_PREVIEWS, - g_param_spec_boolean ("post-previews", "Post Previews", - "If capture preview images should be posted to the bus", - DEFAULT_POST_PREVIEWS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_PREVIEW_CAPS, - g_param_spec_boxed ("preview-caps", "Preview caps", - "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 = @@ -1181,7 +1092,6 @@ gst_wrapper_camera_bin_src_init (GstWrapperCameraBinSrc * self, self->video_renegotiate = FALSE; self->image_renegotiate = FALSE; self->mode = GST_BASE_CAMERA_SRC_CAST (self)->mode; - self->post_previews = DEFAULT_POST_PREVIEWS; } gboolean diff --git a/gst/camerabin2/gstwrappercamerabinsrc.h b/gst/camerabin2/gstwrappercamerabinsrc.h index 68ce8d7b11..ccc1ef64f9 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.h +++ b/gst/camerabin2/gstwrappercamerabinsrc.h @@ -112,13 +112,6 @@ struct _GstWrapperCameraBinSrc GstCaps *image_capture_caps; gboolean image_renegotiate; gboolean video_renegotiate; - - /* Preview convert pipeline */ - GstCameraBinPreviewPipelineData *preview_pipeline; - gboolean post_previews; - GstCaps *preview_caps; - GstElement *preview_filter; - gboolean preview_filter_changed; };