mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
media: common: Add v4l2_find_nearest_size_conditional()
v4l2_find_nearest_size() returns a mode from sensor driver's mode list that is a best match width and height wise for the sensor. Some drivers have different set of available modes depending on the number of lanes. While this could be handled within a driver by providing different lists of modes, provide a helper v4l2_find_nearest_size_conditional() to ignore modes that aren't available. Also use size_t for the array index and remove extra commas while at it. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
parent
65e52d07f1
commit
454ad0169c
2 changed files with 66 additions and 24 deletions
|
|
@ -154,13 +154,18 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
|
|||
EXPORT_SYMBOL_GPL(v4l_bound_align_image);
|
||||
|
||||
const void *
|
||||
__v4l2_find_nearest_size(const void *array, size_t array_size,
|
||||
size_t entry_size, size_t width_offset,
|
||||
size_t height_offset, s32 width, s32 height)
|
||||
__v4l2_find_nearest_size_conditional(const void *array, size_t array_size,
|
||||
size_t entry_size, size_t width_offset,
|
||||
size_t height_offset, s32 width,
|
||||
s32 height,
|
||||
bool (*func)(const void *array,
|
||||
size_t index,
|
||||
const void *context),
|
||||
const void *context)
|
||||
{
|
||||
u32 error, min_error = U32_MAX;
|
||||
const void *best = NULL;
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
|
@ -169,6 +174,9 @@ __v4l2_find_nearest_size(const void *array, size_t array_size,
|
|||
const u32 *entry_width = array + width_offset;
|
||||
const u32 *entry_height = array + height_offset;
|
||||
|
||||
if (func && !func(array, i, context))
|
||||
continue;
|
||||
|
||||
error = abs(*entry_width - width) + abs(*entry_height - height);
|
||||
if (error > min_error)
|
||||
continue;
|
||||
|
|
@ -181,7 +189,7 @@ __v4l2_find_nearest_size(const void *array, size_t array_size,
|
|||
|
||||
return best;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size);
|
||||
EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size_conditional);
|
||||
|
||||
int v4l2_g_parm_cap(struct video_device *vdev,
|
||||
struct v4l2_subdev *sd, struct v4l2_streamparm *a)
|
||||
|
|
|
|||
|
|
@ -390,15 +390,59 @@ void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
|
|||
unsigned int salign);
|
||||
|
||||
/**
|
||||
* v4l2_find_nearest_size - Find the nearest size among a discrete
|
||||
* set of resolutions contained in an array of a driver specific struct.
|
||||
* v4l2_find_nearest_size_conditional - Find the nearest size among a discrete
|
||||
* set of resolutions contained in an array of a driver specific struct,
|
||||
* with conditionally exlusion of certain modes
|
||||
*
|
||||
* @array: a driver specific array of image sizes
|
||||
* @array_size: the length of the driver specific array of image sizes
|
||||
* @width_field: the name of the width field in the driver specific struct
|
||||
* @height_field: the name of the height field in the driver specific struct
|
||||
* @width: desired width.
|
||||
* @height: desired height.
|
||||
* @width: desired width
|
||||
* @height: desired height
|
||||
* @func: ignores mode if returns false
|
||||
* @context: context for the function
|
||||
*
|
||||
* Finds the closest resolution to minimize the width and height differences
|
||||
* between what requested and the supported resolutions. The size of the width
|
||||
* and height fields in the driver specific must equal to that of u32, i.e. four
|
||||
* bytes. @func is called for each mode considered, a mode is ignored if @func
|
||||
* returns false for it.
|
||||
*
|
||||
* Returns the best match or NULL if the length of the array is zero.
|
||||
*/
|
||||
#define v4l2_find_nearest_size_conditional(array, array_size, width_field, \
|
||||
height_field, width, height, \
|
||||
func, context) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof((array)->width_field) != sizeof(u32) || \
|
||||
sizeof((array)->height_field) != sizeof(u32)); \
|
||||
(typeof(&(array)[0]))__v4l2_find_nearest_size_conditional( \
|
||||
(array), array_size, sizeof(*(array)), \
|
||||
offsetof(typeof(*(array)), width_field), \
|
||||
offsetof(typeof(*(array)), height_field), \
|
||||
width, height, func, context); \
|
||||
})
|
||||
const void *
|
||||
__v4l2_find_nearest_size_conditional(const void *array, size_t array_size,
|
||||
size_t entry_size, size_t width_offset,
|
||||
size_t height_offset, s32 width,
|
||||
s32 height,
|
||||
bool (*func)(const void *array,
|
||||
size_t index,
|
||||
const void *context),
|
||||
const void *context);
|
||||
|
||||
/**
|
||||
* v4l2_find_nearest_size - Find the nearest size among a discrete set of
|
||||
* resolutions contained in an array of a driver specific struct
|
||||
*
|
||||
* @array: a driver specific array of image sizes
|
||||
* @array_size: the length of the driver specific array of image sizes
|
||||
* @width_field: the name of the width field in the driver specific struct
|
||||
* @height_field: the name of the height field in the driver specific struct
|
||||
* @width: desired width
|
||||
* @height: desired height
|
||||
*
|
||||
* Finds the closest resolution to minimize the width and height differences
|
||||
* between what requested and the supported resolutions. The size of the width
|
||||
|
|
@ -407,21 +451,11 @@ void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
|
|||
*
|
||||
* Returns the best match or NULL if the length of the array is zero.
|
||||
*/
|
||||
#define v4l2_find_nearest_size(array, array_size, width_field, height_field, \
|
||||
width, height) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof((array)->width_field) != sizeof(u32) || \
|
||||
sizeof((array)->height_field) != sizeof(u32)); \
|
||||
(typeof(&(array)[0]))__v4l2_find_nearest_size( \
|
||||
(array), array_size, sizeof(*(array)), \
|
||||
offsetof(typeof(*(array)), width_field), \
|
||||
offsetof(typeof(*(array)), height_field), \
|
||||
width, height); \
|
||||
})
|
||||
const void *
|
||||
__v4l2_find_nearest_size(const void *array, size_t array_size,
|
||||
size_t entry_size, size_t width_offset,
|
||||
size_t height_offset, s32 width, s32 height);
|
||||
#define v4l2_find_nearest_size(array, array_size, width_field, \
|
||||
height_field, width, height) \
|
||||
v4l2_find_nearest_size_conditional(array, array_size, width_field, \
|
||||
height_field, width, height, NULL, \
|
||||
NULL)
|
||||
|
||||
/**
|
||||
* v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue