From 6206f58c3a7db843d3aebe11993090e153449d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tommi=20My=C3=B6h=C3=A4nen?= Date: Tue, 26 Jan 2010 15:18:24 +0200 Subject: [PATCH] GstPhotography: Add flicker and focus mode settings to photography API Adds flicker and focus mode settings to photography API and also implement it in camerabin. --- gst-libs/gst/interfaces/photography.c | 60 +++++++++++++ gst-libs/gst/interfaces/photography.h | 39 +++++++++ gst/camerabin/gstcamerabin-enum.h | 4 +- gst/camerabin/gstcamerabin.c | 6 ++ gst/camerabin/gstcamerabinphotography.c | 112 ++++++++++++++++++++++++ tests/check/elements/camerabin.c | 50 +++++++++++ 6 files changed, 270 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/interfaces/photography.c b/gst-libs/gst/interfaces/photography.c index 0f98d1b941..2207033791 100644 --- a/gst-libs/gst/interfaces/photography.c +++ b/gst-libs/gst/interfaces/photography.c @@ -82,6 +82,8 @@ gst_photography_iface_base_init (GstPhotographyInterface * iface) iface->get_scene_mode = NULL; iface->get_flash_mode = NULL; iface->get_zoom = NULL; + iface->get_flicker_mode = NULL; + iface->get_focus_mode = NULL; iface->set_ev_compensation = NULL; iface->set_iso_speed = NULL; @@ -92,6 +94,8 @@ gst_photography_iface_base_init (GstPhotographyInterface * iface) iface->set_scene_mode = NULL; iface->set_flash_mode = NULL; iface->set_zoom = NULL; + iface->set_flicker_mode = NULL; + iface->set_focus_mode = NULL; iface->get_capabilities = NULL; iface->prepare_for_capture = NULL; @@ -306,6 +310,46 @@ GST_PHOTOGRAPHY_FUNC_TEMPLATE (flash_mode, GstFlashMode); */ GST_PHOTOGRAPHY_FUNC_TEMPLATE (zoom, gfloat); +/** + * gst_photography_set_flicker_mode: + * @photo: #GstPhotography interface of a #GstElement + * @flicker_mode: flicker mode value to set + * + * Set the flicker mode value for the #GstElement. + * + * Returns: %TRUE if setting the value succeeded, %FALSE otherwise + */ +/** + * gst_photography_get_flicker_mode: + * @photo: #GstPhotography interface of a #GstElement + * @flicker_mode: flicker mode value to get + * + * Get the flicker mode value for the #GstElement + * + * Returns: %TRUE if getting the value succeeded, %FALSE otherwise + */ +GST_PHOTOGRAPHY_FUNC_TEMPLATE (flicker_mode, GstFlickerReductionMode); + +/** + * gst_photography_set_focus_mode: + * @photo: #GstPhotography interface of a #GstElement + * @focus_mode: focus mode value to set + * + * Set the focus mode value for the #GstElement. + * + * Returns: %TRUE if setting the value succeeded, %FALSE otherwise + */ +/** + * gst_photography_get_focus_mode: + * @photo: #GstPhotography interface of a #GstElement + * @focus_mode: focus_mode value to get + * + * Get the focus mode value for the #GstElement + * + * Returns: %TRUE if getting the value succeeded, %FALSE otherwise + */ +GST_PHOTOGRAPHY_FUNC_TEMPLATE (focus_mode, GstFocusMode); + /** * gst_photography_get_capabilities: * @photo: #GstPhotography interface of a #GstElement @@ -466,6 +510,22 @@ gst_photography_iface_class_init (gpointer g_class) GST_TYPE_FLASH_MODE, GST_PHOTOGRAPHY_FLASH_MODE_AUTO, G_PARAM_READWRITE)); + /* Flicker reduction mode */ + g_object_interface_install_property (g_class, + g_param_spec_enum (GST_PHOTOGRAPHY_PROP_FLICKER_MODE, + "Flicker reduction mode property", + "Flicker reduction mode defines a line frequency for flickering prevention", + GST_TYPE_FLICKER_REDUCTION_MODE, + GST_PHOTOGRAPHY_FLICKER_REDUCTION_OFF, G_PARAM_READWRITE)); + + /* Focus mode */ + g_object_interface_install_property (g_class, + g_param_spec_enum (GST_PHOTOGRAPHY_PROP_FOCUS_MODE, + "Focus mode property", + "Focus mode defines the range of focal lengths to use in autofocus search", + GST_TYPE_FOCUS_MODE, + GST_PHOTOGRAPHY_FOCUS_MODE_AUTO, G_PARAM_READWRITE)); + /* Capabilities */ g_object_interface_install_property (g_class, g_param_spec_ulong (GST_PHOTOGRAPHY_PROP_CAPABILITIES, diff --git a/gst-libs/gst/interfaces/photography.h b/gst-libs/gst/interfaces/photography.h index 65a638fdd6..66ec6ac3a1 100644 --- a/gst-libs/gst/interfaces/photography.h +++ b/gst-libs/gst/interfaces/photography.h @@ -65,6 +65,8 @@ G_BEGIN_DECLS #define GST_PHOTOGRAPHY_PROP_EXPOSURE "exposure" #define GST_PHOTOGRAPHY_PROP_IMAGE_CAPTURE_SUPPORTED_CAPS \ "image-capture-supported-caps" +#define GST_PHOTOGRAPHY_PROP_FLICKER_MODE "flicker-mode" +#define GST_PHOTOGRAPHY_PROP_FOCUS_MODE "focus-mode" /** * GstPhotography: @@ -147,6 +149,25 @@ typedef enum GST_PHOTOGRAPHY_SHAKE_RISK_HIGH, } GstPhotoShakeRisk; +typedef enum +{ + GST_PHOTOGRAPHY_FLICKER_REDUCTION_OFF = 0, + GST_PHOTOGRAPHY_FLICKER_REDUCTION_50HZ, + GST_PHOTOGRAPHY_FLICKER_REDUCTION_60HZ, + GST_PHOTOGRAPHY_FLICKER_REDUCTION_AUTO, +} GstFlickerReductionMode; + +typedef enum { + GST_PHOTOGRAPHY_FOCUS_MODE_AUTO = 0, + GST_PHOTOGRAPHY_FOCUS_MODE_MACRO, + GST_PHOTOGRAPHY_FOCUS_MODE_PORTRAIT, + GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY, + GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL, + GST_PHOTOGRAPHY_FOCUS_MODE_EXTENDED, + GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL, + GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_EXTENDED, +} GstFocusMode; + typedef struct { GstWhiteBalanceMode wb_mode; @@ -158,6 +179,8 @@ typedef struct gfloat ev_compensation; guint iso_speed; gfloat zoom; + GstFlickerReductionMode flicker_mode; + GstFocusMode focus_mode; } GstPhotoSettings; /** @@ -220,6 +243,10 @@ typedef struct _GstPhotographyInterface gboolean (*get_flash_mode) (GstPhotography * photo, GstFlashMode * flash_mode); gboolean (*get_zoom) (GstPhotography * photo, gfloat * zoom); + gboolean (*get_flicker_mode) (GstPhotography * photo, + GstFlickerReductionMode * flicker_mode); + gboolean (*get_focus_mode) (GstPhotography * photo, + GstFocusMode * focus_mode); gboolean (*set_ev_compensation) (GstPhotography * photo, gfloat ev_comp); gboolean (*set_iso_speed) (GstPhotography * photo, guint iso_speed); @@ -234,6 +261,10 @@ typedef struct _GstPhotographyInterface gboolean (*set_flash_mode) (GstPhotography * photo, GstFlashMode flash_mode); gboolean (*set_zoom) (GstPhotography * photo, gfloat zoom); + gboolean (*set_flicker_mode) (GstPhotography * photo, + GstFlickerReductionMode flicker_mode); + gboolean (*set_focus_mode) (GstPhotography * photo, + GstFocusMode focus_mode); GstPhotoCaps (*get_capabilities) (GstPhotography * photo); gboolean (*prepare_for_capture) (GstPhotography * photo, @@ -266,6 +297,10 @@ gboolean gst_photography_get_scene_mode (GstPhotography * photo, gboolean gst_photography_get_flash_mode (GstPhotography * photo, GstFlashMode * flash_mode); gboolean gst_photography_get_zoom (GstPhotography * photo, gfloat * zoom); +gboolean gst_photography_get_flicker_mode (GstPhotography * photo, + GstFlickerReductionMode *mode); +gboolean gst_photography_get_focus_mode (GstPhotography * photo, + GstFocusMode *mode); gboolean gst_photography_set_ev_compensation (GstPhotography * photo, gfloat ev_comp); @@ -282,6 +317,10 @@ gboolean gst_photography_set_scene_mode (GstPhotography * photo, gboolean gst_photography_set_flash_mode (GstPhotography * photo, GstFlashMode flash_mode); gboolean gst_photography_set_zoom (GstPhotography * photo, gfloat zoom); +gboolean gst_photography_set_flicker_mode (GstPhotography * photo, + GstFlickerReductionMode mode); +gboolean gst_photography_set_focus_mode (GstPhotography * photo, + GstFocusMode mode); GstPhotoCaps gst_photography_get_capabilities (GstPhotography * photo); diff --git a/gst/camerabin/gstcamerabin-enum.h b/gst/camerabin/gstcamerabin-enum.h index 80d00fcd14..43e87ba46e 100644 --- a/gst/camerabin/gstcamerabin-enum.h +++ b/gst/camerabin/gstcamerabin-enum.h @@ -58,7 +58,9 @@ enum ARG_EXPOSURE, ARG_VIDEO_SOURCE_FILTER, ARG_IMAGE_CAPTURE_SUPPORTED_CAPS, - ARG_VIEWFINDER_FILTER + ARG_VIEWFINDER_FILTER, + ARG_FLICKER_MODE, + ARG_FOCUS_MODE }; /** diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c index 86e1eec78d..b7ed540472 100644 --- a/gst/camerabin/gstcamerabin.c +++ b/gst/camerabin/gstcamerabin.c @@ -3020,6 +3020,12 @@ gst_camerabin_override_photo_properties (GObjectClass * gobject_class) g_object_class_override_property (gobject_class, ARG_IMAGE_CAPTURE_SUPPORTED_CAPS, GST_PHOTOGRAPHY_PROP_IMAGE_CAPTURE_SUPPORTED_CAPS); + + g_object_class_override_property (gobject_class, ARG_FLICKER_MODE, + GST_PHOTOGRAPHY_PROP_FLICKER_MODE); + + g_object_class_override_property (gobject_class, ARG_FOCUS_MODE, + GST_PHOTOGRAPHY_PROP_FOCUS_MODE); } static void diff --git a/gst/camerabin/gstcamerabinphotography.c b/gst/camerabin/gstcamerabinphotography.c index 33721d6a33..7148151653 100644 --- a/gst/camerabin/gstcamerabinphotography.c +++ b/gst/camerabin/gstcamerabinphotography.c @@ -443,6 +443,86 @@ gst_camerabin_handle_scene_mode (GstCameraBin * camera, GstSceneMode scene_mode) } } +static gboolean +gst_camerabin_set_flicker_mode (GstPhotography * photo, + GstFlickerReductionMode flicker_mode) +{ + GstCameraBin *camera; + gboolean ret = TRUE; + + g_return_val_if_fail (photo != NULL, FALSE); + + camera = GST_CAMERABIN (photo); + + /* Cache the setting */ + camera->photo_settings.flicker_mode = flicker_mode; + + if (PHOTOGRAPHY_IS_OK (camera->src_vid_src)) { + ret = + gst_photography_set_flicker_mode (GST_PHOTOGRAPHY (camera->src_vid_src), + flicker_mode); + } + return ret; +} + +static gboolean +gst_camerabin_get_flicker_mode (GstPhotography * photo, + GstFlickerReductionMode * flicker_mode) +{ + GstCameraBin *camera; + gboolean ret = FALSE; + + g_return_val_if_fail (photo != NULL, FALSE); + + camera = GST_CAMERABIN (photo); + + if (PHOTOGRAPHY_IS_OK (camera->src_vid_src)) { + ret = + gst_photography_get_flicker_mode (GST_PHOTOGRAPHY (camera->src_vid_src), + flicker_mode); + } + return ret; +} + +static gboolean +gst_camerabin_set_focus_mode (GstPhotography * photo, GstFocusMode focus_mode) +{ + GstCameraBin *camera; + gboolean ret = TRUE; + + g_return_val_if_fail (photo != NULL, FALSE); + + camera = GST_CAMERABIN (photo); + + /* Cache the setting */ + camera->photo_settings.focus_mode = focus_mode; + + if (PHOTOGRAPHY_IS_OK (camera->src_vid_src)) { + ret = + gst_photography_set_focus_mode (GST_PHOTOGRAPHY (camera->src_vid_src), + focus_mode); + } + return ret; +} + +static gboolean +gst_camerabin_get_focus_mode (GstPhotography * photo, GstFocusMode * focus_mode) +{ + GstCameraBin *camera; + gboolean ret = FALSE; + + g_return_val_if_fail (photo != NULL, FALSE); + + camera = GST_CAMERABIN (photo); + + if (PHOTOGRAPHY_IS_OK (camera->src_vid_src)) { + ret = + gst_photography_get_focus_mode (GST_PHOTOGRAPHY (camera->src_vid_src), + focus_mode); + } + return ret; +} + gboolean gst_camerabin_photography_get_property (GstCameraBin * camera, guint prop_id, GValue * value) @@ -556,6 +636,26 @@ gst_camerabin_photography_get_property (GstCameraBin * camera, guint prop_id, ret = TRUE; break; } + case ARG_FLICKER_MODE: + { + GstFlickerReductionMode mode; + GST_DEBUG_OBJECT (camera, "==== GETTING PROP_FLICKER_MODE ===="); + if (gst_camerabin_get_flicker_mode ((GstPhotography *) camera, &mode)) { + g_value_set_enum (value, mode); + } + ret = TRUE; + break; + } + case ARG_FOCUS_MODE: + { + GstFocusMode mode; + GST_DEBUG_OBJECT (camera, "==== GETTING PROP_FOCUS_MODE ===="); + if (gst_camerabin_get_focus_mode ((GstPhotography *) camera, &mode)) { + g_value_set_enum (value, mode); + } + ret = TRUE; + break; + } default: break; } @@ -622,6 +722,18 @@ gst_camerabin_photography_set_property (GstCameraBin * camera, guint prop_id, g_value_get_uint (value)); ret = TRUE; break; + case ARG_FLICKER_MODE: + GST_DEBUG_OBJECT (camera, "==== SETTING PROP_FLICKER_MODE ===="); + gst_camerabin_set_flicker_mode ((GstPhotography *) camera, + g_value_get_enum (value)); + ret = TRUE; + break; + case ARG_FOCUS_MODE: + GST_DEBUG_OBJECT (camera, "==== SETTING PROP_FOCUS_MODE ===="); + gst_camerabin_set_focus_mode ((GstPhotography *) camera, + g_value_get_enum (value)); + ret = TRUE; + break; default: break; } diff --git a/tests/check/elements/camerabin.c b/tests/check/elements/camerabin.c index f0a84f36b0..be6a96a11c 100644 --- a/tests/check/elements/camerabin.c +++ b/tests/check/elements/camerabin.c @@ -324,6 +324,8 @@ test_photography_settings (GstElement * cam) GstWhiteBalanceMode wb, orig_wb; GstColourToneMode ct, orig_ct; GstSceneMode sm, orig_sm; + GstFlickerReductionMode flm, orig_flm; + GstFocusMode fm, orig_fm; gfloat zoom, orig_zoom; if (!GST_IS_PHOTOGRAPHY (cam)) { @@ -398,6 +400,28 @@ test_photography_settings (GstElement * cam) } g_type_class_unref (tclass); + tclass = g_type_class_ref (GST_TYPE_FOCUS_MODE); + for (fm = 0; fm < G_ENUM_CLASS (tclass)->n_values; fm++) { + orig_fm = fm; + gst_photography_set_focus_mode (GST_PHOTOGRAPHY (cam), fm); + gst_photography_get_focus_mode (GST_PHOTOGRAPHY (cam), &fm); + fail_if (orig_fm != fm, "setting photography focus mode failed"); + fm = orig_fm; + g_usleep (PHOTO_SETTING_DELAY_US); + } + g_type_class_unref (tclass); + + tclass = g_type_class_ref (GST_TYPE_FLICKER_REDUCTION_MODE); + for (flm = 0; flm < G_ENUM_CLASS (tclass)->n_values; flm++) { + orig_flm = flm; + gst_photography_set_flicker_mode (GST_PHOTOGRAPHY (cam), flm); + gst_photography_get_flicker_mode (GST_PHOTOGRAPHY (cam), &flm); + fail_if (orig_flm != flm, "setting photography flicker mode failed"); + flm = orig_flm; + g_usleep (PHOTO_SETTING_DELAY_US); + } + g_type_class_unref (tclass); + for (zoom = 1.0; zoom <= 10.0; zoom += 1.0) { orig_zoom = zoom; gst_photography_set_zoom (GST_PHOTOGRAPHY (cam), zoom); @@ -421,6 +445,8 @@ test_photography_properties (GstElement * cam) GstWhiteBalanceMode wb, orig_wb; GstColourToneMode ct, orig_ct; GstSceneMode sm, orig_sm; + GstFocusMode fm, orig_fm; + GstFlickerReductionMode flm, orig_flm; GstCaps *caps = NULL; if (!GST_IS_PHOTOGRAPHY (cam)) { @@ -517,6 +543,30 @@ test_photography_properties (GstElement * cam) sm = orig_sm; } g_type_class_unref (tclass); + + tclass = g_type_class_ref (GST_TYPE_FOCUS_MODE); + for (fm = 0; fm < G_ENUM_CLASS (tclass)->n_values; fm++) { + orig_fm = fm; + g_object_set (G_OBJECT (cam), "focus-mode", fm, NULL); + g_object_get (G_OBJECT (cam), "focus-mode", &fm, NULL); + fail_if (fm < 0 || fm > G_ENUM_CLASS (tclass)->n_values, + "setting photography focus mode failed"); + fm = orig_fm; + g_usleep (PHOTO_SETTING_DELAY_US); + } + g_type_class_unref (tclass); + + tclass = g_type_class_ref (GST_TYPE_FLICKER_REDUCTION_MODE); + for (flm = 0; flm < G_ENUM_CLASS (tclass)->n_values; flm++) { + orig_flm = flm; + g_object_set (G_OBJECT (cam), "flicker-mode", flm, NULL); + g_object_get (G_OBJECT (cam), "flicker-mode", &flm, NULL); + fail_if (flm < 0 || flm > G_ENUM_CLASS (tclass)->n_values, + "setting photography flicker reduction mode failed"); + flm = orig_flm; + g_usleep (PHOTO_SETTING_DELAY_US); + } + g_type_class_unref (tclass); } static void