Search
SailfishOS Open Build Service
>
Projects
>
home:msameer
:
gst-nokia-videosrc2
>
gst-plugins-bad-free
> 0016-camerabin-rounding-support-for-framerate-setting.patch
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 0016-camerabin-rounding-support-for-framerate-setting.patch of Package gst-plugins-bad-free
From 416f812e57522cf77c184662cbe171b3bda03920 Mon Sep 17 00:00:00 2001 From: Hoseok Chang <hoseok.chang@nokia.com> Date: Wed, 25 Aug 2010 13:41:30 +0300 Subject: [PATCH 16/23] camerabin: rounding support for framerate setting * Add "framerate-rounding" property * round the framerate to the allowed one by video source --- gst/camerabin/gstcamerabin-enum.h | 3 +- gst/camerabin/gstcamerabin.c | 147 ++++++++++++++++++++++++++++++++++++- gst/camerabin/gstcamerabin.h | 1 + 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/gst/camerabin/gstcamerabin-enum.h b/gst/camerabin/gstcamerabin-enum.h index 7fbe6c8..f818319 100644 --- a/gst/camerabin/gstcamerabin-enum.h +++ b/gst/camerabin/gstcamerabin-enum.h @@ -71,7 +71,8 @@ enum ARG_PREVIEW_SOURCE_FILTER, ARG_READY_FOR_CAPTURE, ARG_IDLE, - ARG_AUTOFOCUS + ARG_AUTOFOCUS, + ARG_FRAMERATE_ROUNDING }; /** diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c index 65a4e18..8bb5749 100644 --- a/gst/camerabin/gstcamerabin.c +++ b/gst/camerabin/gstcamerabin.c @@ -225,6 +225,7 @@ static guint camerabin_signals[LAST_SIGNAL]; #define DEFAULT_V4L2CAMSRC_DRIVER_NAME "v4l2camext" #define DEFAULT_BLOCK_VIEWFINDER FALSE +#define DEFAULT_FRAMERATE_ROUNDING FALSE #define DEFAULT_READY_FOR_CAPTURE TRUE /* message names */ @@ -345,6 +346,9 @@ static guint32 get_srcpad_current_format (GstElement * element); static const GValue *gst_camerabin_find_better_framerate (GstCameraBin * camera, GstStructure * st, const GValue * orig_framerate); +static const GValue *gst_camerabin_find_closer_framerate (GstCameraBin * camera, + GstStructure * st, const GValue * orig_framerate); + static void gst_camerabin_update_aspect_filter (GstCameraBin * camera, GstCaps * new_caps); @@ -556,6 +560,8 @@ camerabin_setup_src_elements (GstCameraBin * camera) camera->pre_night_fps_n = camera->app_fps_n; camera->pre_night_fps_d = camera->app_fps_d; detect_framerate = TRUE; + } else if (camera->framerate_rounding) { + detect_framerate = TRUE; } else { gst_structure_set (st, "framerate", GST_TYPE_FRACTION, camera->app_fps_n, @@ -2334,8 +2340,19 @@ gst_camerabin_set_allowed_framerate (GstCameraBin * camera, caps_size = gst_caps_get_size (intersect); for (i = 0; i < caps_size; i++) { structure = gst_caps_get_structure (intersect, i); - framerate = - gst_camerabin_find_better_framerate (camera, structure, framerate); + if (camera->night_mode || camera->fps_n == 0 || camera->fps_d == 0 + || !camera->framerate_rounding) { + /* Find Min. or Max. framerate among the allowed framerate */ + framerate = + gst_camerabin_find_better_framerate (camera, structure, framerate); + } else { + /* Find the closest framerate to the camera->fps_n/camera->fps_d, + * when framerate_rounding is true, fps_n and fps_d is not 0, and + * night_mode is false + */ + framerate = + gst_camerabin_find_closer_framerate (camera, structure, framerate); + } } /* Set found frame rate to original caps */ @@ -2358,7 +2375,6 @@ gst_camerabin_set_allowed_framerate (GstCameraBin * camera, } } - /** * get_srcpad_current_format: * @element: element to get the format from @@ -2470,6 +2486,111 @@ gst_camerabin_find_better_framerate (GstCameraBin * camera, GstStructure * st, return framerate; } +#define FPS_SCALE_FACTOR 10000 +static guint +gst_camerabin_get_fps_abs_scaled (const GValue * a, const GValue * b) +{ + guint a_scaled, b_scaled; + + if (G_VALUE_TYPE (a) != GST_TYPE_FRACTION + || G_VALUE_TYPE (b) != GST_TYPE_FRACTION) { + return G_MAXUINT; + } + + a_scaled = + gst_value_get_fraction_numerator (a) * FPS_SCALE_FACTOR / + gst_value_get_fraction_denominator (a); + b_scaled = + gst_value_get_fraction_numerator (b) * FPS_SCALE_FACTOR / + gst_value_get_fraction_denominator (b); + + return abs (a_scaled - b_scaled); +} + +/* + * gst_camerabin_find_closer_framerate: + * @camera: camerabin object + * @st: structure that contains framerate candidates + * @orig_framerate: closest framerate so far + * + * Looks for framerate closer to the target than @orig_framerate from + * @st structure. + * + * Returns: @orig_framerate or closer one if found + */ +static const GValue * +gst_camerabin_find_closer_framerate (GstCameraBin * camera, GstStructure * st, + const GValue * orig_framerate) +{ + const GValue *framerate = NULL; + GValue *target_fps; + guint i, i_best, list_size; + guint abs, best_abs = G_MAXUINT; + gint res; + + target_fps = g_new0 (GValue, 1); + g_value_init (target_fps, GST_TYPE_FRACTION); + gst_value_set_fraction (target_fps, camera->fps_n, camera->fps_d); + + GST_LOG_OBJECT (camera, "finding best framerate in %" GST_PTR_FORMAT, st); + + if (gst_structure_has_field (st, "framerate")) { + framerate = gst_structure_get_value (st, "framerate"); + /* Handle framerate lists */ + if (GST_VALUE_HOLDS_LIST (framerate)) { + list_size = gst_value_list_get_size (framerate); + GST_LOG_OBJECT (camera, "finding framerate from list"); + for (i = 0, i_best = 0; i < list_size; i++) { + const GValue *framerate_i = NULL; + framerate_i = gst_value_list_get_value (framerate, i); + abs = gst_camerabin_get_fps_abs_scaled (target_fps, framerate_i); + if (best_abs > abs) { + best_abs = abs; + i_best = i; + } + } + GST_LOG_OBJECT (camera, "found best framerate from index %d", i_best); + framerate = gst_value_list_get_value (framerate, i_best); + } + /* Handle framerate ranges */ + if (GST_VALUE_HOLDS_FRACTION_RANGE (framerate)) { + res = + gst_value_compare (gst_value_get_fraction_range_max (framerate), + target_fps); + if (res == GST_VALUE_LESS_THAN) { + framerate = gst_value_get_fraction_range_max (framerate); + } else { + res = + gst_value_compare (gst_value_get_fraction_range_min (framerate), + target_fps); + if (res == GST_VALUE_GREATER_THAN) { + framerate = gst_value_get_fraction_range_min (framerate); + } else { + framerate = target_fps; + } + } + } + } + + /* Check if we found better framerate */ + if (orig_framerate && framerate) { + if (gst_camerabin_get_fps_abs_scaled (framerate, + target_fps) > gst_camerabin_get_fps_abs_scaled (orig_framerate, + target_fps)) { + GST_LOG_OBJECT (camera, "original framerate was the best"); + framerate = orig_framerate; + } + } + + if (framerate != target_fps) { + g_free (target_fps); + } + + return framerate; +} + +#undef FPS_SCALE_FACTOR + /* * gst_camerabin_update_aspect_filter: * @camera: camerabin object @@ -3266,6 +3387,20 @@ gst_camerabin_class_init (GstCameraBinClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** + * GstCameraBin:framerate-rounding: + * + * Round the video-capture-framerate to the nearest framerate + * allowed by video source. + */ + + g_object_class_install_property (gobject_class, ARG_FRAMERATE_ROUNDING, + g_param_spec_boolean ("framerate-rounding", + "Round the framerate to the nearest allowed one", + "Round the framerate to the nearest allowed one by video source", + DEFAULT_FRAMERATE_ROUNDING, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** * GstCameraBin:ready-for-capture: * * When TRUE new capture can be prepared. If FALSE capturing is ongoing @@ -3850,6 +3985,9 @@ gst_camerabin_set_property (GObject * object, guint prop_id, } } break; + case ARG_FRAMERATE_ROUNDING: + camera->framerate_rounding = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3979,6 +4117,9 @@ gst_camerabin_get_property (GObject * object, guint prop_id, case ARG_IDLE: g_value_set_boolean (value, camera->processing_counter == 0); break; + case ARG_FRAMERATE_ROUNDING: + g_value_set_boolean (value, camera->framerate_rounding); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/camerabin/gstcamerabin.h b/gst/camerabin/gstcamerabin.h index 82b82a9..8216619 100644 --- a/gst/camerabin/gstcamerabin.h +++ b/gst/camerabin/gstcamerabin.h @@ -91,6 +91,7 @@ struct _GstCameraBin /* Frames per second configured to camerabin */ gint fps_n; gint fps_d; + gboolean framerate_rounding; /* app configured resolution/framerate */ gint app_width; -- 1.7.10.4