From 6a686316d5194dcdbf66fe7746d1187b0013e3c1 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 18 Mar 2011 15:49:12 +0100 Subject: [PATCH] basecamerasrc: camerabin2: wrappercamerabinsrc: Add read-only max-zoom prop This is not implemented in any of our real sources to which wrappercamerabinsrc might connect but this is optional and can be implemented at any time. A limit on the software zoom level using video{crop,scale} would be arbitrary. --- .../gst/basecamerabinsrc/gstbasecamerasrc.c | 19 +++++++++++- .../gst/basecamerabinsrc/gstbasecamerasrc.h | 2 +- gst/camerabin2/gstcamerabin2.c | 30 +++++++++++++++++++ gst/camerabin2/gstcamerabin2.h | 1 + gst/camerabin2/gstwrappercamerabinsrc.c | 18 +++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c index 0138c8231c..b2ae99298d 100644 --- a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c +++ b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c @@ -61,6 +61,7 @@ enum PROP_0, PROP_MODE, PROP_ZOOM, + PROP_MAX_ZOOM, PROP_READY_FOR_CAPTURE, PROP_POST_PREVIEW, PROP_PREVIEW_CAPS, @@ -338,6 +339,12 @@ gst_base_camera_src_set_property (GObject * object, break; case PROP_ZOOM:{ self->zoom = g_value_get_float (value); + /* limit to max-zoom */ + if (self->zoom > self->max_zoom) { + GST_DEBUG_OBJECT (self, "Clipping zoom %f to max-zoom %f", self->zoom, + self->max_zoom); + self->zoom = self->max_zoom; + } /* does not set it if in NULL, the src is not created yet */ if (GST_STATE (self) != GST_STATE_NULL) gst_base_camera_src_setup_zoom (self); @@ -385,6 +392,9 @@ gst_base_camera_src_get_property (GObject * object, case PROP_ZOOM: g_value_set_float (value, self->zoom); break; + case PROP_MAX_ZOOM: + g_value_set_float (value, self->max_zoom); + break; case PROP_POST_PREVIEW: g_value_set_boolean (value, self->post_preview); break; @@ -530,9 +540,15 @@ gst_base_camera_src_class_init (GstBaseCameraSrcClass * klass) g_object_class_install_property (gobject_class, PROP_ZOOM, g_param_spec_float ("zoom", "Zoom", - "Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, MAX_ZOOM, + "Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, G_MAXFLOAT, DEFAULT_ZOOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_ZOOM, + g_param_spec_float ("max-zoom", "Maximum zoom level (note: may change " + "depending on resolution/implementation)", + "Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, G_MAXFLOAT, + MAX_ZOOM, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** * GstBaseCameraSrc:post-previews: * @@ -603,6 +619,7 @@ gst_base_camera_src_init (GstBaseCameraSrc * self, self->width = DEFAULT_WIDTH; self->height = DEFAULT_HEIGHT; self->zoom = DEFAULT_ZOOM; + self->max_zoom = MAX_ZOOM; self->mode = MODE_IMAGE; self->capturing = FALSE; diff --git a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h index b48628f052..c433b6694f 100644 --- a/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h +++ b/gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h @@ -78,8 +78,8 @@ struct _GstBaseCameraSrc gint width; gint height; - /* The digital zoom (from 100% to 1000%) */ gfloat zoom; + gfloat max_zoom; gpointer _gst_reserved[GST_PADDING_LARGE]; }; diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index b44a7a23dd..f90d35817e 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -109,6 +109,7 @@ enum PROP_AUDIO_CAPTURE_SUPPORTED_CAPS, PROP_AUDIO_CAPTURE_CAPS, PROP_ZOOM, + PROP_MAX_ZOOM, PROP_IMAGE_CAPTURE_ENCODER, PROP_IMAGE_CAPTURE_MUXER, PROP_IDLE @@ -571,6 +572,12 @@ gst_camera_bin_class_init (GstCameraBinClass * klass) "Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, MAX_ZOOM, DEFAULT_ZOOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_MAX_ZOOM, + g_param_spec_float ("max-zoom", "Maximum zoom level (note: may change " + "depending on resolution/implementation)", + "Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, G_MAXFLOAT, + MAX_ZOOM, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /* TODO * Review before stable * - We use a profile for video recording properties and here we have @@ -649,6 +656,7 @@ gst_camera_bin_init (GstCameraBin * camera) camera->viewfinderbin = gst_element_factory_make ("viewfinderbin", "vf-bin"); camera->imagebin = gst_element_factory_make ("imagecapturebin", "imagebin"); camera->zoom = DEFAULT_ZOOM; + camera->max_zoom = MAX_ZOOM; /* capsfilters are created here as we proxy their caps properties and * this way we avoid having to store the caps while on NULL state to @@ -901,6 +909,17 @@ videosink_event_probe (GstPad * pad, GstEvent * evt, gpointer data) return TRUE; } +static void +gst_camera_bin_src_notify_max_zoom_cb (GObject * self, GParamSpec * pspec, + gpointer user_data) +{ + GstCameraBin *camera = (GstCameraBin *) user_data; + + g_object_get (self, "max-zoom", &camera->max_zoom, NULL); + GST_DEBUG_OBJECT (camera, "Max zoom updated to %f", camera->max_zoom); + g_object_notify (G_OBJECT (camera), "max-zoom"); +} + /** * gst_camera_bin_create_elements: * @param camera: the #GstCameraBin @@ -1066,6 +1085,8 @@ gst_camera_bin_create_elements (GstCameraBin * camera) camera->preview_filter, NULL); } g_object_set (camera->src, "zoom", camera->zoom, NULL); + g_signal_connect (G_OBJECT (camera->src), "notify::max-zoom", + (GCallback) gst_camera_bin_src_notify_max_zoom_cb, camera); } if (new_src) { gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->src)); @@ -1397,6 +1418,12 @@ gst_camera_bin_set_property (GObject * object, guint prop_id, break; case PROP_ZOOM: camera->zoom = g_value_get_float (value); + /* limit to max-zoom */ + if (camera->zoom > camera->max_zoom) { + GST_DEBUG_OBJECT (camera, "Clipping zoom %f to max-zoom %f", + camera->zoom, camera->max_zoom); + camera->zoom = camera->max_zoom; + } if (camera->src) g_object_set (camera->src, "zoom", camera->zoom, NULL); break; @@ -1557,6 +1584,9 @@ gst_camera_bin_get_property (GObject * object, guint prop_id, case PROP_ZOOM: g_value_set_float (value, camera->zoom); break; + case PROP_MAX_ZOOM: + g_value_set_float (value, camera->max_zoom); + break; case PROP_IMAGE_CAPTURE_ENCODER:{ GstElement *enc; diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h index 7c452e188f..05961e266f 100644 --- a/gst/camerabin2/gstcamerabin2.h +++ b/gst/camerabin2/gstcamerabin2.h @@ -87,6 +87,7 @@ struct _GstCameraBin GstElement *preview_filter; GstEncodingProfile *video_profile; gfloat zoom; + gfloat max_zoom; gboolean elements_created; }; diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c index e26bd5a176..2cf6ac4cc6 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.c +++ b/gst/camerabin2/gstwrappercamerabinsrc.c @@ -336,6 +336,17 @@ gst_wrapper_camera_bin_src_caps_cb (GObject * gobject, GParamSpec * pspec, gst_caps_unref (caps); }; +static void +gst_wrapper_camera_bin_src_max_zoom_cb (GObject * self, GParamSpec * pspec, + gpointer user_data) +{ + GstBaseCameraSrc *bcamsrc = (GstBaseCameraSrc *) user_data; + + g_object_get (self, "max-zoom", &bcamsrc->max_zoom, NULL); + g_object_notify (G_OBJECT (bcamsrc), "max-zoom"); +} + + /** * gst_wrapper_camera_bin_src_construct_pipeline: * @bcamsrc: camerasrc object @@ -379,6 +390,13 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc) /* we lost the reference */ self->app_vid_src = NULL; + /* we listen for changes to max-zoom in the video src so that + * we can proxy them to the basecamerasrc property */ + if (g_object_class_find_property (G_OBJECT_GET_CLASS (bcamsrc), "max-zoom")) { + g_signal_connect (G_OBJECT (self->src_vid_src), "notify::max-zoom", + (GCallback) gst_wrapper_camera_bin_src_max_zoom_cb, bcamsrc); + } + /* add a buffer probe to the src elemento to drop EOS from READY->NULL */ { GstPad *pad;