lkml.org 
[lkml]   [2019]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC PATCH 06/20] lib: Add video format information library
    On Tue, 19 Mar 2019 22:57:11 +0100
    Maxime Ripard <maxime.ripard@bootlin.com> 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@bootlin.com>
    > ---
    > 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);

    \
     
     \ /
      Last update: 2019-03-20 14:40    [W:2.729 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site