mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +00:00
basecamerasrc: wrappercamerabinsrc: camerabin2: Expose/add floating point
zoom property
This commit is contained in:
parent
b38bf37218
commit
5fd15521e2
6 changed files with 97 additions and 30 deletions
|
@ -191,14 +191,11 @@ void
|
||||||
gst_base_camera_src_setup_zoom (GstBaseCameraSrc * self)
|
gst_base_camera_src_setup_zoom (GstBaseCameraSrc * self)
|
||||||
{
|
{
|
||||||
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
|
GstBaseCameraSrcClass *bclass = GST_BASE_CAMERA_SRC_GET_CLASS (self);
|
||||||
gint zoom;
|
|
||||||
|
|
||||||
zoom = g_atomic_int_get (&self->zoom);
|
g_return_if_fail (self->zoom);
|
||||||
|
|
||||||
g_return_if_fail (zoom);
|
|
||||||
g_return_if_fail (bclass->set_zoom);
|
g_return_if_fail (bclass->set_zoom);
|
||||||
|
|
||||||
bclass->set_zoom (self, zoom);
|
bclass->set_zoom (self, self->zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,7 +334,7 @@ gst_base_camera_src_set_property (GObject * object,
|
||||||
g_value_get_enum (value));
|
g_value_get_enum (value));
|
||||||
break;
|
break;
|
||||||
case PROP_ZOOM:{
|
case PROP_ZOOM:{
|
||||||
g_atomic_int_set (&self->zoom, g_value_get_int (value));
|
self->zoom = g_value_get_float (value);
|
||||||
/* does not set it if in NULL, the src is not created yet */
|
/* does not set it if in NULL, the src is not created yet */
|
||||||
if (GST_STATE (self) != GST_STATE_NULL)
|
if (GST_STATE (self) != GST_STATE_NULL)
|
||||||
gst_base_camera_src_setup_zoom (self);
|
gst_base_camera_src_setup_zoom (self);
|
||||||
|
@ -378,7 +375,7 @@ gst_base_camera_src_get_property (GObject * object,
|
||||||
g_value_set_boolean (value, !self->capturing);
|
g_value_set_boolean (value, !self->capturing);
|
||||||
break;
|
break;
|
||||||
case PROP_ZOOM:
|
case PROP_ZOOM:
|
||||||
g_value_set_int (value, g_atomic_int_get (&self->zoom));
|
g_value_set_float (value, self->zoom);
|
||||||
break;
|
break;
|
||||||
case PROP_POST_PREVIEW:
|
case PROP_POST_PREVIEW:
|
||||||
g_value_set_boolean (value, self->post_preview);
|
g_value_set_boolean (value, self->post_preview);
|
||||||
|
@ -522,6 +519,11 @@ gst_base_camera_src_class_init (GstBaseCameraSrcClass * klass)
|
||||||
GST_TYPE_CAMERABIN_MODE, MODE_IMAGE,
|
GST_TYPE_CAMERABIN_MODE, MODE_IMAGE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
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,
|
||||||
|
DEFAULT_ZOOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstBaseCameraSrc:post-previews:
|
* GstBaseCameraSrc:post-previews:
|
||||||
*
|
*
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct _GstBaseCameraSrc
|
||||||
gint height;
|
gint height;
|
||||||
|
|
||||||
/* The digital zoom (from 100% to 1000%) */
|
/* The digital zoom (from 100% to 1000%) */
|
||||||
gint zoom;
|
gfloat zoom;
|
||||||
|
|
||||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ struct _GstBaseCameraSrcClass
|
||||||
gboolean (*setup_pipeline) (GstBaseCameraSrc *self);
|
gboolean (*setup_pipeline) (GstBaseCameraSrc *self);
|
||||||
|
|
||||||
/* set the zoom */
|
/* set the zoom */
|
||||||
void (*set_zoom) (GstBaseCameraSrc *self, gint zoom);
|
void (*set_zoom) (GstBaseCameraSrc *self, gfloat zoom);
|
||||||
|
|
||||||
/* set the mode */
|
/* set the mode */
|
||||||
gboolean (*set_mode) (GstBaseCameraSrc *self,
|
gboolean (*set_mode) (GstBaseCameraSrc *self,
|
||||||
|
@ -125,8 +125,8 @@ struct _GstBaseCameraSrcClass
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define MIN_ZOOM 100
|
#define MIN_ZOOM 1.0f
|
||||||
#define MAX_ZOOM 1000
|
#define MAX_ZOOM 10.0f
|
||||||
#define ZOOM_1X MIN_ZOOM
|
#define ZOOM_1X MIN_ZOOM
|
||||||
|
|
||||||
GstPhotography * gst_base_camera_src_get_photography (GstBaseCameraSrc *self);
|
GstPhotography * gst_base_camera_src_get_photography (GstBaseCameraSrc *self);
|
||||||
|
|
|
@ -85,7 +85,8 @@ enum
|
||||||
PROP_AUDIO_SRC,
|
PROP_AUDIO_SRC,
|
||||||
PROP_MUTE_AUDIO,
|
PROP_MUTE_AUDIO,
|
||||||
PROP_AUDIO_CAPTURE_SUPPORTED_CAPS,
|
PROP_AUDIO_CAPTURE_SUPPORTED_CAPS,
|
||||||
PROP_AUDIO_CAPTURE_CAPS
|
PROP_AUDIO_CAPTURE_CAPS,
|
||||||
|
PROP_ZOOM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -531,6 +532,11 @@ gst_camera_bin_class_init (GstCameraBinClass * klass)
|
||||||
"Restricts the caps that can be used on the viewfinder",
|
"Restricts the caps that can be used on the viewfinder",
|
||||||
GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_ZOOM,
|
||||||
|
g_param_spec_float ("zoom", "Zoom",
|
||||||
|
"Digital zoom factor (e.g. 1.5 means 1.5x)", MIN_ZOOM, MAX_ZOOM,
|
||||||
|
DEFAULT_ZOOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/* TODO review before going stable
|
/* TODO review before going stable
|
||||||
* We have viewfinder-supported-caps that returns the caps that the
|
* We have viewfinder-supported-caps that returns the caps that the
|
||||||
* camerasrc can produce on its viewfinder pad, this could easily be
|
* camerasrc can produce on its viewfinder pad, this could easily be
|
||||||
|
@ -579,6 +585,7 @@ gst_camera_bin_init (GstCameraBin * camera)
|
||||||
camera->video_location = g_strdup (DEFAULT_VID_LOCATION);
|
camera->video_location = g_strdup (DEFAULT_VID_LOCATION);
|
||||||
camera->image_location = g_strdup (DEFAULT_IMG_LOCATION);
|
camera->image_location = g_strdup (DEFAULT_IMG_LOCATION);
|
||||||
camera->viewfinderbin = gst_element_factory_make ("viewfinderbin", "vf-bin");
|
camera->viewfinderbin = gst_element_factory_make ("viewfinderbin", "vf-bin");
|
||||||
|
camera->zoom = DEFAULT_ZOOM;
|
||||||
|
|
||||||
/* capsfilters are created here as we proxy their caps properties and
|
/* 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
|
* this way we avoid having to store the caps while on NULL state to
|
||||||
|
@ -917,12 +924,14 @@ gst_camera_bin_create_elements (GstCameraBin * camera)
|
||||||
|
|
||||||
g_assert (camera->src != NULL);
|
g_assert (camera->src != NULL);
|
||||||
g_object_set (camera->src, "mode", camera->mode, NULL);
|
g_object_set (camera->src, "mode", camera->mode, NULL);
|
||||||
if (camera->src
|
if (camera->src) {
|
||||||
&& g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src),
|
if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src),
|
||||||
"preview-caps")) {
|
"preview-caps")) {
|
||||||
g_object_set (camera->src, "post-previews", camera->post_previews,
|
g_object_set (camera->src, "post-previews", camera->post_previews,
|
||||||
"preview-caps", camera->preview_caps, "preview-filter",
|
"preview-caps", camera->preview_caps, "preview-filter",
|
||||||
camera->preview_filter, NULL);
|
camera->preview_filter, NULL);
|
||||||
|
}
|
||||||
|
g_object_set (camera->src, "zoom", camera->zoom, NULL);
|
||||||
}
|
}
|
||||||
if (new_src) {
|
if (new_src) {
|
||||||
gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->src));
|
gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (camera->src));
|
||||||
|
@ -1252,6 +1261,11 @@ gst_camera_bin_set_property (GObject * object, guint prop_id,
|
||||||
g_object_set (camera->viewfinderbin, "video-sink",
|
g_object_set (camera->viewfinderbin, "video-sink",
|
||||||
g_value_get_object (value), NULL);
|
g_value_get_object (value), NULL);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ZOOM:
|
||||||
|
camera->zoom = g_value_get_float (value);
|
||||||
|
if (camera->src)
|
||||||
|
g_object_set (camera->src, "zoom", camera->zoom, NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1398,6 +1412,9 @@ gst_camera_bin_get_property (GObject * object, guint prop_id,
|
||||||
g_value_take_object (value, sink);
|
g_value_take_object (value, sink);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PROP_ZOOM:
|
||||||
|
g_value_set_float (value, camera->zoom);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct _GstCameraBin
|
||||||
GstCaps *preview_caps;
|
GstCaps *preview_caps;
|
||||||
GstElement *preview_filter;
|
GstElement *preview_filter;
|
||||||
GstEncodingProfile *video_profile;
|
GstEncodingProfile *video_profile;
|
||||||
|
gfloat zoom;
|
||||||
|
|
||||||
gboolean elements_created;
|
gboolean elements_created;
|
||||||
};
|
};
|
||||||
|
|
|
@ -295,6 +295,46 @@ gst_wrapper_camera_src_src_event_probe (GstPad * pad, GstEvent * evt,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_wrapper_camera_bin_src_caps_cb (GObject * gobject, GParamSpec * pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (user_data);
|
||||||
|
GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (user_data);
|
||||||
|
GstPad *src_caps_src_pad;
|
||||||
|
GstCaps *caps = NULL;
|
||||||
|
GstStructure *in_st = NULL;
|
||||||
|
|
||||||
|
/* get the new caps that were set on the capsfilter that configures the
|
||||||
|
* source */
|
||||||
|
src_caps_src_pad = gst_element_get_static_pad (self->src_filter, "src");
|
||||||
|
caps = gst_pad_get_caps_reffed (src_caps_src_pad);
|
||||||
|
gst_object_unref (src_caps_src_pad);
|
||||||
|
GST_DEBUG_OBJECT (self, "src-filter caps changed to %s",
|
||||||
|
gst_caps_to_string (caps));
|
||||||
|
|
||||||
|
if (gst_caps_get_size (caps)) {
|
||||||
|
in_st = gst_caps_get_structure (caps, 0);
|
||||||
|
if (in_st) {
|
||||||
|
gst_structure_get_int (in_st, "width", &bcamsrc->width);
|
||||||
|
gst_structure_get_int (in_st, "height", &bcamsrc->height);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "Source dimensions now: %dx%d", bcamsrc->width,
|
||||||
|
bcamsrc->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update zoom */
|
||||||
|
gst_base_camera_src_setup_zoom (bcamsrc);
|
||||||
|
|
||||||
|
/* Update post-zoom capsfilter */
|
||||||
|
if (self->src_zoom_filter)
|
||||||
|
g_object_set (G_OBJECT (self->src_zoom_filter), "caps", caps, NULL);
|
||||||
|
|
||||||
|
/* drop our ref on the caps */
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_wrapper_camera_bin_src_construct_pipeline:
|
* gst_wrapper_camera_bin_src_construct_pipeline:
|
||||||
* @bcamsrc: camerasrc object
|
* @bcamsrc: camerasrc object
|
||||||
|
@ -318,6 +358,7 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
|
||||||
GstElement *videoscale;
|
GstElement *videoscale;
|
||||||
GstPad *vf_pad;
|
GstPad *vf_pad;
|
||||||
GstPad *tee_capture_pad;
|
GstPad *tee_capture_pad;
|
||||||
|
GstPad *src_caps_src_pad;
|
||||||
|
|
||||||
if (!self->elements_created) {
|
if (!self->elements_created) {
|
||||||
|
|
||||||
|
@ -356,6 +397,14 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
|
||||||
"src-capsfilter")))
|
"src-capsfilter")))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* attach to notify::caps on the first capsfilter and use a callback
|
||||||
|
* to recalculate the zoom properties when these caps change and to
|
||||||
|
* propagate the caps to the second capsfilter */
|
||||||
|
src_caps_src_pad = gst_element_get_static_pad (self->src_filter, "src");
|
||||||
|
g_signal_connect (src_caps_src_pad, "notify::caps",
|
||||||
|
G_CALLBACK (gst_wrapper_camera_bin_src_caps_cb), self);
|
||||||
|
gst_object_unref (src_caps_src_pad);
|
||||||
|
|
||||||
if (!(self->src_zoom_crop =
|
if (!(self->src_zoom_crop =
|
||||||
gst_camerabin_create_and_add_element (cbin, "videocrop",
|
gst_camerabin_create_and_add_element (cbin, "videocrop",
|
||||||
"zoom-crop")))
|
"zoom-crop")))
|
||||||
|
@ -650,21 +699,20 @@ gst_wrapper_camera_bin_src_set_mode (GstBaseCameraSrc * bcamsrc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
set_videosrc_zoom (GstWrapperCameraBinSrc * self, gint zoom)
|
set_videosrc_zoom (GstWrapperCameraBinSrc * self, gfloat zoom)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS (self->src_vid_src),
|
if (g_object_class_find_property (G_OBJECT_GET_CLASS (self->src_vid_src),
|
||||||
"zoom")) {
|
"zoom")) {
|
||||||
g_object_set (G_OBJECT (self->src_vid_src), "zoom",
|
g_object_set (G_OBJECT (self->src_vid_src), "zoom", zoom, NULL);
|
||||||
(gfloat) zoom / 100, NULL);
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
set_element_zoom (GstWrapperCameraBinSrc * self, gint zoom)
|
set_element_zoom (GstWrapperCameraBinSrc * self, gfloat zoom)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
|
GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
|
||||||
|
@ -677,12 +725,13 @@ set_element_zoom (GstWrapperCameraBinSrc * self, gint zoom)
|
||||||
|
|
||||||
if (self->src_zoom_crop) {
|
if (self->src_zoom_crop) {
|
||||||
/* Update capsfilters to apply the zoom */
|
/* Update capsfilters to apply the zoom */
|
||||||
GST_INFO_OBJECT (self, "zoom: %d, orig size: %dx%d", zoom,
|
GST_INFO_OBJECT (self, "zoom: %f, orig size: %dx%d", zoom,
|
||||||
bcamsrc->width, bcamsrc->height);
|
bcamsrc->width, bcamsrc->height);
|
||||||
|
|
||||||
if (zoom != ZOOM_1X) {
|
if (zoom != ZOOM_1X) {
|
||||||
w2_crop = (bcamsrc->width - (bcamsrc->width * ZOOM_1X / zoom)) / 2;
|
w2_crop = (bcamsrc->width - (gint) (bcamsrc->width * ZOOM_1X / zoom)) / 2;
|
||||||
h2_crop = (bcamsrc->height - (bcamsrc->height * ZOOM_1X / zoom)) / 2;
|
h2_crop =
|
||||||
|
(bcamsrc->height - (gint) (bcamsrc->height * ZOOM_1X / zoom)) / 2;
|
||||||
|
|
||||||
left += w2_crop;
|
left += w2_crop;
|
||||||
right += w2_crop;
|
right += w2_crop;
|
||||||
|
@ -711,11 +760,11 @@ set_element_zoom (GstWrapperCameraBinSrc * self, gint zoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_wrapper_camera_bin_src_set_zoom (GstBaseCameraSrc * bcamsrc, gint zoom)
|
gst_wrapper_camera_bin_src_set_zoom (GstBaseCameraSrc * bcamsrc, gfloat zoom)
|
||||||
{
|
{
|
||||||
GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
|
GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
|
||||||
|
|
||||||
GST_INFO_OBJECT (self, "setting zoom %d", zoom);
|
GST_INFO_OBJECT (self, "setting zoom %f", zoom);
|
||||||
|
|
||||||
if (set_videosrc_zoom (self, zoom)) {
|
if (set_videosrc_zoom (self, zoom)) {
|
||||||
set_element_zoom (self, ZOOM_1X);
|
set_element_zoom (self, ZOOM_1X);
|
||||||
|
@ -904,7 +953,7 @@ set_capsfilter_caps (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
|
||||||
if (self->src_zoom_filter)
|
if (self->src_zoom_filter)
|
||||||
g_object_set (G_OBJECT (self->src_zoom_filter), "caps", new_caps, NULL);
|
g_object_set (G_OBJECT (self->src_zoom_filter), "caps", new_caps, NULL);
|
||||||
update_aspect_filter (self, new_caps);
|
update_aspect_filter (self, new_caps);
|
||||||
GST_INFO_OBJECT (self, "udpated");
|
GST_INFO_OBJECT (self, "updated");
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -666,9 +666,7 @@ run_pipeline (gpointer user_data)
|
||||||
}
|
}
|
||||||
g_object_unref (video_source);
|
g_object_unref (video_source);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
g_object_set (camerabin, "zoom", zoom / 100.0f, NULL);
|
g_object_set (camerabin, "zoom", zoom / 100.0f, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
capture_count++;
|
capture_count++;
|
||||||
g_timer_start (timer);
|
g_timer_start (timer);
|
||||||
|
|
Loading…
Reference in a new issue