Re: [RFC PATCH 06/20] lib: Add video format information library

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 19 Mar 2019 22:57:11 +0100
Maxime Ripard <maxime.ripard@xxxxxxxxxxx> wrote:

> Move the DRM formats API to turn this into a more generic image formats API
> to be able to leverage it into some other places of the kernel, such as
> v4l2 drivers.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@xxxxxxxxxxx>
> ---
>  include/linux/image-formats.h | 240 +++++++++++-
>  lib/Kconfig                   |   7 +-
>  lib/Makefile                  |   3 +-
>  lib/image-formats-selftests.c | 326 +++++++++++++++-
>  lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
>  5 files changed, 1336 insertions(+)
>  create mode 100644 include/linux/image-formats.h
>  create mode 100644 lib/image-formats-selftests.c
>  create mode 100644 lib/image-formats.c
> 

[...]

> --- /dev/null
> +++ b/lib/image-formats.c
> @@ -0,0 +1,760 @@
> +#include <linux/bug.h>
> +#include <linux/image-formats.h>
> +#include <linux/kernel.h>
> +#include <linux/math64.h>
> +
> +#include <uapi/drm/drm_fourcc.h>
> +
> +static const struct image_format_info formats[] = {
> +	{

...

> +	},
> +};
> +
> +#define __image_format_lookup(_field, _fmt)			\
> +	({							\
> +		const struct image_format_info *format = NULL;	\
> +		unsigned i;					\
> +								\
> +		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
> +			if (formats[i]._field == _fmt)		\
> +				format = &formats[i];		\
> +								\
> +		format;						\
> +	})
> +
> +/**
> + * __image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> +{
> +	return __image_format_lookup(drm_fmt, drm);
> +}
> +EXPORT_SYMBOL(__image_format_drm_lookup);
> +
> +/**
> + * image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_drm_lookup(u32 drm)
> +{
> +	const struct image_format_info *format;
> +
> +	format = __image_format_drm_lookup(drm);
> +
> +	WARN_ON(!format);
> +	return format;
> +}
> +EXPORT_SYMBOL(image_format_drm_lookup);

I think this function and the DRM formats table should be moved in
drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
remaining functions can IMHO be placed in include/linux/image-formats.h
as static inline funcs. This way you can get rid of lib/image-formats.c
and the associated Kconfig entry.

> +
> +/**
> + * image_format_plane_cpp - determine the bytes per pixel value
> + * @format: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The bytes per pixel value for the specified plane.
> + */
> +unsigned int image_format_plane_cpp(const struct image_format_info *format,
> +				    int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	return format->cpp[plane];
> +}
> +EXPORT_SYMBOL(image_format_plane_cpp);
> +
> +/**
> + * image_format_plane_width - width of the plane given the first plane
> + * @format: pointer to the image_format
> + * @width: width of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The width of @plane, given that the width of the first plane is @width.
> + */
> +unsigned int image_format_plane_width(int width,
> +				      const struct image_format_info *format,
> +				      int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	if (plane == 0)
> +		return width;
> +
> +	return width / format->hsub;
> +}
> +EXPORT_SYMBOL(image_format_plane_width);
> +
> +/**
> + * image_format_plane_height - height of the plane given the first plane
> + * @format: pointer to the image_format
> + * @height: height of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The height of @plane, given that the height of the first plane is @height.
> + */
> +unsigned int image_format_plane_height(int height,
> +				       const struct image_format_info *format,
> +				       int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	if (plane == 0)
> +		return height;
> +
> +	return height / format->vsub;
> +}
> +EXPORT_SYMBOL(image_format_plane_height);
> +
> +/**
> + * image_format_block_width - width in pixels of block.
> + * @format: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The width in pixels of a block, depending on the plane index.
> + */
> +unsigned int image_format_block_width(const struct image_format_info *format,
> +				      int plane)
> +{
> +	if (!format || plane < 0 || plane >= format->num_planes)
> +		return 0;
> +
> +	if (!format->block_w[plane])
> +		return 1;
> +
> +	return format->block_w[plane];
> +}
> +EXPORT_SYMBOL(image_format_block_width);
> +
> +/**
> + * image_format_block_height - height in pixels of a block
> + * @info: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The height in pixels of a block, depending on the plane index.
> + */
> +unsigned int image_format_block_height(const struct image_format_info *format,
> +				       int plane)
> +{
> +	if (!format || plane < 0 || plane >= format->num_planes)
> +		return 0;
> +
> +	if (!format->block_h[plane])
> +		return 1;
> +
> +	return format->block_h[plane];
> +}
> +EXPORT_SYMBOL(image_format_block_height);
> +
> +/**
> + * image_format_min_pitch - computes the minimum required pitch in bytes
> + * @info: pixel format info
> + * @plane: plane index
> + * @buffer_width: buffer width in pixels
> + *
> + * Returns:
> + * The minimum required pitch in bytes for a buffer by taking into consideration
> + * the pixel format information and the buffer width.
> + */
> +uint64_t image_format_min_pitch(const struct image_format_info *info,
> +				int plane, unsigned int buffer_width)
> +{
> +	if (!info || plane < 0 || plane >= info->num_planes)
> +		return 0;
> +
> +	return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],
> +			    image_format_block_width(info, plane) *
> +			    image_format_block_height(info, plane));
> +}
> +EXPORT_SYMBOL(image_format_min_pitch);




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux