camerabin2: Moving preview image properties to basecamerasrc

Moves preview image related properties to basecamerasrc as that
should be present on all camerasrcs
This commit is contained in:
Thiago Santos 2011-02-04 14:53:49 -03:00
parent b5fdacc5c0
commit b3abf91232
4 changed files with 127 additions and 103 deletions

View file

@ -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");
}
}

View file

@ -27,6 +27,7 @@
#include <gst/interfaces/photography.h>
#include <gst/interfaces/colorbalance.h>
#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__ */

View file

@ -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

View file

@ -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;
};