mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
media: v4l2-common: add v4l2_fill_pixfmt_mp_aligned helper
Add a v4l2_fill_pixfmt_mp_aligned helper which allows the user to specify a custom stride alignment in bytes. This is necessary for hardware like the Rockchip RGA3, which requires the stride value to be aligned to a 16 bytes boundary. The code makes some assumptions about the v4l2 format to simplify the calculation. They currently hold for all known v4l2 formats. v4l2_format_plane_stride uses an unsigned int as argument type to avoid the later multiplication from overflowing the u8 value. All other places use u8, as no practical use cases for a larger alignment are known at the moment. Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
parent
84fbe791a6
commit
2c22584627
|
|
@ -432,14 +432,33 @@ static inline unsigned int v4l2_format_block_height(const struct v4l2_format_inf
|
|||
}
|
||||
|
||||
static inline unsigned int v4l2_format_plane_stride(const struct v4l2_format_info *info, int plane,
|
||||
unsigned int width)
|
||||
unsigned int width, unsigned int byte_alignment)
|
||||
{
|
||||
unsigned int hdiv = plane ? info->hdiv : 1;
|
||||
unsigned int aligned_width =
|
||||
ALIGN(width, v4l2_format_block_width(info, plane));
|
||||
|
||||
return DIV_ROUND_UP(aligned_width, hdiv) *
|
||||
info->bpp[plane] / info->bpp_div[plane];
|
||||
/*
|
||||
* Formats with a single memory plane derive the stride of the
|
||||
* other planes from the y stride. To avoid hardware or software
|
||||
* deriving a different stride for the composite plane,
|
||||
* multiply the alignment accordingly.
|
||||
*
|
||||
* It assumes the following format properties:
|
||||
* - bpp_div[0] == bpp_div[1]
|
||||
* - The multiplication factor doesn't differ between the non y planes
|
||||
* - The multiplication factor is a power of 2
|
||||
*/
|
||||
if (info->mem_planes == 1 && info->comp_planes > 1) {
|
||||
if (plane == 0)
|
||||
byte_alignment *= DIV_ROUND_UP(info->hdiv * info->bpp[0], info->bpp[1]);
|
||||
else
|
||||
byte_alignment *= DIV_ROUND_UP(info->bpp[1], info->hdiv * info->bpp[0]);
|
||||
}
|
||||
|
||||
return ALIGN(DIV_ROUND_UP(aligned_width, hdiv) * info->bpp[plane] /
|
||||
info->bpp_div[plane],
|
||||
byte_alignment);
|
||||
}
|
||||
|
||||
static inline unsigned int v4l2_format_plane_height(const struct v4l2_format_info *info, int plane,
|
||||
|
|
@ -453,9 +472,10 @@ static inline unsigned int v4l2_format_plane_height(const struct v4l2_format_inf
|
|||
}
|
||||
|
||||
static inline unsigned int v4l2_format_plane_size(const struct v4l2_format_info *info, int plane,
|
||||
unsigned int width, unsigned int height)
|
||||
unsigned int width, unsigned int height,
|
||||
u8 stride_alignment)
|
||||
{
|
||||
return v4l2_format_plane_stride(info, plane, width) *
|
||||
return v4l2_format_plane_stride(info, plane, width, stride_alignment) *
|
||||
v4l2_format_plane_height(info, plane, height);
|
||||
}
|
||||
|
||||
|
|
@ -476,8 +496,9 @@ void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints);
|
||||
|
||||
int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
|
||||
u32 pixelformat, u32 width, u32 height)
|
||||
int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt,
|
||||
u32 pixelformat, u32 width, u32 height,
|
||||
u8 stride_alignment)
|
||||
{
|
||||
const struct v4l2_format_info *info;
|
||||
struct v4l2_plane_pix_format *plane;
|
||||
|
|
@ -494,23 +515,34 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
|
|||
|
||||
if (info->mem_planes == 1) {
|
||||
plane = &pixfmt->plane_fmt[0];
|
||||
plane->bytesperline = v4l2_format_plane_stride(info, 0, width);
|
||||
plane->bytesperline = v4l2_format_plane_stride(info, 0, width,
|
||||
stride_alignment);
|
||||
plane->sizeimage = 0;
|
||||
|
||||
for (i = 0; i < info->comp_planes; i++)
|
||||
plane->sizeimage +=
|
||||
v4l2_format_plane_size(info, i, width, height);
|
||||
v4l2_format_plane_size(info, i, width, height,
|
||||
stride_alignment);
|
||||
} else {
|
||||
for (i = 0; i < info->comp_planes; i++) {
|
||||
plane = &pixfmt->plane_fmt[i];
|
||||
plane->bytesperline =
|
||||
v4l2_format_plane_stride(info, i, width);
|
||||
v4l2_format_plane_stride(info, i, width,
|
||||
stride_alignment);
|
||||
plane->sizeimage = plane->bytesperline *
|
||||
v4l2_format_plane_height(info, i, height);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp_aligned);
|
||||
|
||||
int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
|
||||
u32 pixelformat, u32 width, u32 height)
|
||||
{
|
||||
return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat,
|
||||
width, height, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
|
||||
|
||||
int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
|
||||
|
|
@ -530,12 +562,12 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
|
|||
pixfmt->width = width;
|
||||
pixfmt->height = height;
|
||||
pixfmt->pixelformat = pixelformat;
|
||||
pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width);
|
||||
pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width, 1);
|
||||
pixfmt->sizeimage = 0;
|
||||
|
||||
for (i = 0; i < info->comp_planes; i++)
|
||||
pixfmt->sizeimage +=
|
||||
v4l2_format_plane_size(info, i, width, height);
|
||||
v4l2_format_plane_size(info, i, width, height, 1);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
|
||||
|
|
|
|||
|
|
@ -558,6 +558,10 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
|
|||
u32 width, u32 height);
|
||||
int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
|
||||
u32 width, u32 height);
|
||||
/* @stride_alignment is a power of 2 value in bytes */
|
||||
int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt,
|
||||
u32 pixelformat, u32 width, u32 height,
|
||||
u8 stride_alignment);
|
||||
|
||||
/**
|
||||
* v4l2_get_link_freq - Get link rate from transmitter
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user