diff mbox

[RFC,media] v4l2: add V4L2 pixel format array and helper functions

Message ID 1408962839-25165-1-git-send-email-p.zabel@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Philipp Zabel Aug. 25, 2014, 10:33 a.m. UTC
This patch adds an array of V4L2 pixel formats and descriptions that can be
used by drivers so that each driver doesn't have to provide its own slightly
different format descriptions for VIDIOC_ENUM_FMT.

Each array entry also includes two bits per pixel values (for a single line and
one for the whole image) that can be used to determine the v4l2_pix_format
bytesperline and sizeimage values and whether the format is planar or
compressed.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
I have started to convert some drivers on a boring train ride, but it occurred
to me that I probably should get some feedback before carrying on with this:
http://git.pengutronix.de/?p=pza/linux.git;a=shortlog;h=refs/heads/topic/media-pixfmt
---
 drivers/media/v4l2-core/v4l2-common.c | 488 ++++++++++++++++++++++++++++++++++
 include/media/v4l2-common.h           |  44 +++
 2 files changed, 532 insertions(+)

Comments

Hans Verkuil Aug. 25, 2014, 11:38 a.m. UTC | #1
Hi Philipp,

I have to think a bit more about the format names, but in the meantime I have
two other suggestions:

On 08/25/2014 12:33 PM, Philipp Zabel wrote:
> This patch adds an array of V4L2 pixel formats and descriptions that can be
> used by drivers so that each driver doesn't have to provide its own slightly
> different format descriptions for VIDIOC_ENUM_FMT.
> 
> Each array entry also includes two bits per pixel values (for a single line and
> one for the whole image) that can be used to determine the v4l2_pix_format
> bytesperline and sizeimage values and whether the format is planar or
> compressed.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> I have started to convert some drivers on a boring train ride, but it occurred
> to me that I probably should get some feedback before carrying on with this:
> http://git.pengutronix.de/?p=pza/linux.git;a=shortlog;h=refs/heads/topic/media-pixfmt
> ---
>  drivers/media/v4l2-core/v4l2-common.c | 488 ++++++++++++++++++++++++++++++++++
>  include/media/v4l2-common.h           |  44 +++
>  2 files changed, 532 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> index ccaa38f..41692df 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -533,3 +533,491 @@ void v4l2_get_timestamp(struct timeval *tv)
>  	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
>  }
>  EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
> +
> +static const struct v4l2_pixfmt v4l2_pixfmts[] = {

<snip>

> +};
> +
> +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(v4l2_pixfmts); i++) {
> +		if (v4l2_pixfmts[i].pixelformat == fourcc)
> +			return v4l2_pixfmts + i;
> +	}
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_pixfmt_by_fourcc);
> +
> +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc)
> +{
> +	const struct v4l2_pixfmt *fmt;
> +
> +	fmt = v4l2_pixfmt_by_fourcc(fourcc);
> +	if (!fmt)
> +		return -EINVAL;
> +
> +	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
> +	f->pixelformat = fmt->pixelformat;
> +	f->flags = (fmt->bpp_image == 0) ? V4L2_FMT_FLAG_COMPRESSED : 0;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_fill_fmtdesc);
> diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
> index 48f9748..27b084f 100644
> --- a/include/media/v4l2-common.h
> +++ b/include/media/v4l2-common.h
> @@ -204,4 +204,48 @@ const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
>  
>  void v4l2_get_timestamp(struct timeval *tv);
>  
> +/**
> + * struct v4l2_pixfmt - internal V4L2 pixel format description
> + * @name: format description to be returned by enum_fmt
> + * @pixelformat: v4l2 pixel format fourcc
> + * @bpp_line: bits per pixel, averaged over a line (of the first plane
> + *            for planar formats), used to calculate bytesperline
> + *            Zero for compressed and macroblock tiled formats.
> + * @bpp_image: bits per pixel, averaged over the whole image. This is used to
> + *             calculate sizeimage for uncompressed formats.
> + *             Zero for compressed formats.

I would add a 'planes' field as well for use with formats that use non-contiguous
planes.

> + */
> +struct v4l2_pixfmt {
> +	const char	*name;
> +	u32		pixelformat;
> +	u8		bpp_line;
> +	u8		bpp_image;
> +};
> +
> +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc);
> +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc);
> +
> +static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt *fmt,
> +					     unsigned int width)
> +{
> +	return width * fmt->bpp_line / 8;

Round up: return (width * fmt->bpp_line + 7) / 8;

> +}
> +
> +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt *fmt,
> +					  unsigned int width,
> +					  unsigned int height)
> +{
> +	return width * height * fmt->bpp_image / 8;

Ditto: return height * v4l2_bytesperline(fmt, width);

> +}
> +
> +static inline bool v4l2_pixfmt_is_planar(const struct v4l2_pixfmt *fmt)
> +{
> +	return fmt->bpp_line && (fmt->bpp_line != fmt->bpp_image);
> +}
> +
> +static inline bool v4l2_pixfmt_is_compressed(const struct v4l2_pixfmt *fmt)
> +{
> +	return fmt->bpp_image == 0;
> +}
> +
>  #endif /* V4L2_COMMON_H_ */
> 

Regards,

	Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Laurent Pinchart Aug. 25, 2014, 11:53 a.m. UTC | #2
On Monday 25 August 2014 13:38:45 Hans Verkuil wrote:
> Hi Philipp,
> 
> I have to think a bit more about the format names, but in the meantime I
> have two other suggestions:
> 
> On 08/25/2014 12:33 PM, Philipp Zabel wrote:
> > This patch adds an array of V4L2 pixel formats and descriptions that can
> > be used by drivers so that each driver doesn't have to provide its own
> > slightly different format descriptions for VIDIOC_ENUM_FMT.

I've started working on this recently as well, so I can only agree with the 
idea.

> > Each array entry also includes two bits per pixel values (for a single
> > line and one for the whole image) that can be used to determine the
> > v4l2_pix_format bytesperline and sizeimage values and whether the format
> > is planar or compressed.
> > 
> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> > ---
> > I have started to convert some drivers on a boring train ride, but it
> > occurred to me that I probably should get some feedback before carrying
> > on with this:
> > http://git.pengutronix.de/?p=pza/linux.git;a=shortlog;h=refs/heads/topic/
> > media-pixfmt
> > ---
> > 
> >  drivers/media/v4l2-core/v4l2-common.c | 488 +++++++++++++++++++++++++++++
> >  include/media/v4l2-common.h           |  44 +++
> >  2 files changed, 532 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-common.c
> > b/drivers/media/v4l2-core/v4l2-common.c index ccaa38f..41692df 100644
> > --- a/drivers/media/v4l2-core/v4l2-common.c
> > +++ b/drivers/media/v4l2-core/v4l2-common.c
> > @@ -533,3 +533,491 @@ void v4l2_get_timestamp(struct timeval *tv)
> > 
> >  	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
> >  
> >  }
> >  EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
> > 
> > +
> > +static const struct v4l2_pixfmt v4l2_pixfmts[] = {
> 
> <snip>
> 
> > +};
> > +
> > +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(v4l2_pixfmts); i++) {
> > +		if (v4l2_pixfmts[i].pixelformat == fourcc)
> > +			return v4l2_pixfmts + i;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(v4l2_pixfmt_by_fourcc);
> > +
> > +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc)
> > +{
> > +	const struct v4l2_pixfmt *fmt;
> > +
> > +	fmt = v4l2_pixfmt_by_fourcc(fourcc);
> > +	if (!fmt)
> > +		return -EINVAL;
> > +
> > +	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
> > +	f->pixelformat = fmt->pixelformat;
> > +	f->flags = (fmt->bpp_image == 0) ? V4L2_FMT_FLAG_COMPRESSED : 0;
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(v4l2_fill_fmtdesc);
> > diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
> > index 48f9748..27b084f 100644
> > --- a/include/media/v4l2-common.h
> > +++ b/include/media/v4l2-common.h
> > @@ -204,4 +204,48 @@ const struct v4l2_frmsize_discrete
> > *v4l2_find_nearest_format(> 
> >  void v4l2_get_timestamp(struct timeval *tv);
> > 
> > +/**
> > + * struct v4l2_pixfmt - internal V4L2 pixel format description
> > + * @name: format description to be returned by enum_fmt
> > + * @pixelformat: v4l2 pixel format fourcc
> > + * @bpp_line: bits per pixel, averaged over a line (of the first plane
> > + *            for planar formats), used to calculate bytesperline
> > + *            Zero for compressed and macroblock tiled formats.
> > + * @bpp_image: bits per pixel, averaged over the whole image. This is
> > used to
> > + *             calculate sizeimage for uncompressed formats.
> > + *             Zero for compressed formats.
> 
> I would add a 'planes' field as well for use with formats that use
> non-contiguous planes.
> 
> > + */
> > +struct v4l2_pixfmt {
> > +	const char	*name;
> > +	u32		pixelformat;
> > +	u8		bpp_line;
> > +	u8		bpp_image;
> > +};
> > +
> > +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc);
> > +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc);
> > +
> > +static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt
> > *fmt, +					     unsigned int width)
> > +{
> > +	return width * fmt->bpp_line / 8;
> 
> Round up: return (width * fmt->bpp_line + 7) / 8;

DIV_ROUND_UP(width * fmt->bpp_line, 8) ?

> > +}
> > +
> > +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt *fmt,
> > +					  unsigned int width,
> > +					  unsigned int height)
> > +{
> > +	return width * height * fmt->bpp_image / 8;
> 
> Ditto: return height * v4l2_bytesperline(fmt, width);
>
> > +}
> > +
> > +static inline bool v4l2_pixfmt_is_planar(const struct v4l2_pixfmt *fmt)
> > +{
> > +	return fmt->bpp_line && (fmt->bpp_line != fmt->bpp_image);
> > +}
> > +
> > +static inline bool v4l2_pixfmt_is_compressed(const struct v4l2_pixfmt
> > *fmt)
> > +{
> > +	return fmt->bpp_image == 0;
> > +}
> > +
> > 
> >  #endif /* V4L2_COMMON_H_ */
Philipp Zabel Aug. 25, 2014, 12:50 p.m. UTC | #3
Hi Hans,

Am Montag, den 25.08.2014, 13:38 +0200 schrieb Hans Verkuil:
> Hi Philipp,
> 
> I have to think a bit more about the format names, but in the meantime I have
> two other suggestions:

Thank you, I haven't spent much thought about the actual descriptions
yet. Most are just transcribed from the comments in videodev2.h without
looking at the names used in the drivers.

[...]
> > +/**
> > + * struct v4l2_pixfmt - internal V4L2 pixel format description
> > + * @name: format description to be returned by enum_fmt
> > + * @pixelformat: v4l2 pixel format fourcc
> > + * @bpp_line: bits per pixel, averaged over a line (of the first plane
> > + *            for planar formats), used to calculate bytesperline
> > + *            Zero for compressed and macroblock tiled formats.
> > + * @bpp_image: bits per pixel, averaged over the whole image. This is used to
> > + *             calculate sizeimage for uncompressed formats.
> > + *             Zero for compressed formats.
> 
> I would add a 'planes' field as well for use with formats that use non-contiguous
> planes.

Good point, I'll add that.

[...]
> > +static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt *fmt,
> > +					     unsigned int width)
> > +{
> > +	return width * fmt->bpp_line / 8;
> 
> Round up: return (width * fmt->bpp_line + 7) / 8;

Right, I should use DIV_ROUND_UP(width * fmt->bpp_line, 8) here.

> > +}
> > +
> > +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt *fmt,
> > +					  unsigned int width,
> > +					  unsigned int height)
> > +{
> > +	return width * height * fmt->bpp_image / 8;
> 
> Ditto: return height * v4l2_bytesperline(fmt, width);

I can't use v4l2_bytesperline because that might be zero for macroblock
tiled formats and uses the wrong bpp value for planar formats with
subsampled chroma.

This nearly works:
    return height * DIV_ROUND_UP(width * fmt->bpp_image, 8)

For the planar 4:2:0 subsampled formats and Y41P (bpp_image == 12),
width has to be even, so that is ok.
Most other formats have a bpp_image that is divisible by 8, but there
are the 4:1:0 subsampled formats (bpp_image == 9). Those would round up
width to a multiple of eight, even though it only has to be a multiple
of four. I'd fall back to:

    if (fmt->bpp_image == fmt->bpp_line) {
        return height * DIV_ROUND_UP(width * fmt->bpp_image, 8);
    } else {
        /* we know that v4l2_bytesperline doesn't round for planar */
        return height * width * fmt->bpp_image / 8;
    }

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Laurent Pinchart Aug. 25, 2014, 3:13 p.m. UTC | #4
On Monday 25 August 2014 14:50:53 Philipp Zabel wrote:
> Hi Hans,
> 
> Am Montag, den 25.08.2014, 13:38 +0200 schrieb Hans Verkuil:
> > Hi Philipp,
> > 
> > I have to think a bit more about the format names, but in the meantime I
> > have
> > two other suggestions:
> Thank you, I haven't spent much thought about the actual descriptions
> yet. Most are just transcribed from the comments in videodev2.h without
> looking at the names used in the drivers.
> 
> [...]
> 
> > > +/**
> > > + * struct v4l2_pixfmt - internal V4L2 pixel format description
> > > + * @name: format description to be returned by enum_fmt
> > > + * @pixelformat: v4l2 pixel format fourcc
> > > + * @bpp_line: bits per pixel, averaged over a line (of the first plane
> > > + *            for planar formats), used to calculate bytesperline
> > > + *            Zero for compressed and macroblock tiled formats.
> > > + * @bpp_image: bits per pixel, averaged over the whole image. This is
> > > used to
> > > + *             calculate sizeimage for uncompressed formats.
> > > + *             Zero for compressed formats.
> > 
> > I would add a 'planes' field as well for use with formats that use
> > non-contiguous planes.
> 
> Good point, I'll add that.
> 
> [...]
> 
> > > +static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt
> > > *fmt, +					     unsigned int width)
> > > +{
> > > +	return width * fmt->bpp_line / 8;
> > 
> > Round up: return (width * fmt->bpp_line + 7) / 8;
> 
> Right, I should use DIV_ROUND_UP(width * fmt->bpp_line, 8) here.
> 
> > > +}
> > > +
> > > +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt
> > > *fmt,
> > > +					  unsigned int width,
> > > +					  unsigned int height)
> > > +{
> > > +	return width * height * fmt->bpp_image / 8;
> > 
> > Ditto: return height * v4l2_bytesperline(fmt, width);
> 
> I can't use v4l2_bytesperline because that might be zero for macroblock
> tiled formats and uses the wrong bpp value for planar formats with
> subsampled chroma.
> 
> This nearly works:
>     return height * DIV_ROUND_UP(width * fmt->bpp_image, 8)

Isn't that exactly height * v4l2_bytesperline(fmt, width) ?

> For the planar 4:2:0 subsampled formats and Y41P (bpp_image == 12),
> width has to be even, so that is ok.
> Most other formats have a bpp_image that is divisible by 8, but there
> are the 4:1:0 subsampled formats (bpp_image == 9). Those would round up
> width to a multiple of eight, even though it only has to be a multiple
> of four. I'd fall back to:
> 
>     if (fmt->bpp_image == fmt->bpp_line) {
>         return height * DIV_ROUND_UP(width * fmt->bpp_image, 8);
>     } else {
>         /* we know that v4l2_bytesperline doesn't round for planar */
>         return height * width * fmt->bpp_image / 8;
>     }

Isn't that growing slightly too big for an inline function ?
Philipp Zabel Aug. 25, 2014, 3:41 p.m. UTC | #5
Hi Laurent,

Am Montag, den 25.08.2014, 17:13 +0200 schrieb Laurent Pinchart:
[...]
> > > > +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt
> > > > *fmt,
> > > > +					  unsigned int width,
> > > > +					  unsigned int height)
> > > > +{
> > > > +	return width * height * fmt->bpp_image / 8;
> > > 
> > > Ditto: return height * v4l2_bytesperline(fmt, width);
> > 
> > I can't use v4l2_bytesperline because that might be zero for macroblock
> > tiled formats and uses the wrong bpp value for planar formats with
> > subsampled chroma.
> > 
> > This nearly works:
> >     return height * DIV_ROUND_UP(width * fmt->bpp_image, 8)
> 
> Isn't that exactly height * v4l2_bytesperline(fmt, width) ?

Only if bpp_image == bpp_line ...

> > For the planar 4:2:0 subsampled formats and Y41P (bpp_image == 12),
> > width has to be even, so that is ok.
> > Most other formats have a bpp_image that is divisible by 8, but there
> > are the 4:1:0 subsampled formats (bpp_image == 9). Those would round up
> > width to a multiple of eight, even though it only has to be a multiple
> > of four. I'd fall back to:
> > 
> >     if (fmt->bpp_image == fmt->bpp_line) {
> >         return height * DIV_ROUND_UP(width * fmt->bpp_image, 8);

... as is the case here. I'll use v4l2_bytesperline, then.

> >     } else {
> >         /* we know that v4l2_bytesperline doesn't round for planar */
> >         return height * width * fmt->bpp_image / 8;
> >     }
> 
> Isn't that growing slightly too big for an inline function ?

Yes, I think this is slightly over the edge. Is room for a function to
accompany the preexisting v4l2_fill_pix_format (say,
v4l2_fill_pix_format_size) to set both the bytesperline and sizeimage
values in a struct v4l2_pix_format?

Also, is anybody bothered by the v4l2_pix_format / v4l2_pixfmt
similarity in name?

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Laurent Pinchart Aug. 25, 2014, 3:47 p.m. UTC | #6
Hi Philipp,

On Monday 25 August 2014 17:41:17 Philipp Zabel wrote:
> Am Montag, den 25.08.2014, 17:13 +0200 schrieb Laurent Pinchart:
> [...]
> 
> >>>> +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt
> >>>> *fmt,
> >>>> +					  unsigned int width,
> >>>> +					  unsigned int height)
> >>>> +{
> >>>> +	return width * height * fmt->bpp_image / 8;
> >>> 
> >>> Ditto: return height * v4l2_bytesperline(fmt, width);
> >> 
> >> I can't use v4l2_bytesperline because that might be zero for macroblock
> >> tiled formats and uses the wrong bpp value for planar formats with
> >> subsampled chroma.
> >> 
> >> This nearly works:
> >>     return height * DIV_ROUND_UP(width * fmt->bpp_image, 8)
> > 
> > Isn't that exactly height * v4l2_bytesperline(fmt, width) ?
> 
> Only if bpp_image == bpp_line ...

Oops, I've missed that subtle difference, sorry.

> >> For the planar 4:2:0 subsampled formats and Y41P (bpp_image == 12),
> >> width has to be even, so that is ok.
> >> Most other formats have a bpp_image that is divisible by 8, but there
> >> are the 4:1:0 subsampled formats (bpp_image == 9). Those would round up
> >> width to a multiple of eight, even though it only has to be a multiple
> >> 
> >> of four. I'd fall back to:
> >>     if (fmt->bpp_image == fmt->bpp_line) {
> >>     
> >>         return height * DIV_ROUND_UP(width * fmt->bpp_image, 8);
> 
> ... as is the case here. I'll use v4l2_bytesperline, then.
> 
> >>     } else {
> >>     
> >>         /* we know that v4l2_bytesperline doesn't round for planar */
> >>         return height * width * fmt->bpp_image / 8;
> >>     
> >>     }
> > 
> > Isn't that growing slightly too big for an inline function ?
> 
> Yes, I think this is slightly over the edge. Is room for a function to
> accompany the preexisting v4l2_fill_pix_format (say,
> v4l2_fill_pix_format_size) to set both the bytesperline and sizeimage
> values in a struct v4l2_pix_format?

That sounds sensible to me, provided it would be used by drivers of course. I 
wouldn't remove v4l2_bytesperline() and v4l2_sizeimage(), as the values might 
be needed by drivers in places where a v4l2_pix_format structure isn't 
available.

> Also, is anybody bothered by the v4l2_pix_format / v4l2_pixfmt
> similarity in name?

How about renaming v4l2_pixfmt to v4l2_pix_format_info ?
Philipp Zabel Aug. 26, 2014, 9:13 a.m. UTC | #7
Hi Laurent,

Am Montag, den 25.08.2014, 17:47 +0200 schrieb Laurent Pinchart:
> > Yes, I think this is slightly over the edge. Is room for a function to
> > accompany the preexisting v4l2_fill_pix_format (say,
> > v4l2_fill_pix_format_size) to set both the bytesperline and sizeimage
> > values in a struct v4l2_pix_format?
> 
> That sounds sensible to me, provided it would be used by drivers of course. I 
> wouldn't remove v4l2_bytesperline() and v4l2_sizeimage(), as the values might 
> be needed by drivers in places where a v4l2_pix_format structure isn't 
> available.

I think about four of the drivers I've looked at so far could use such a
function, but it probably won't be useful for the majority.

> > Also, is anybody bothered by the v4l2_pix_format / v4l2_pixfmt
> > similarity in name?
> 
> How about renaming v4l2_pixfmt to v4l2_pix_format_info ?

Thanks, but v4l2_pix_format is a userspace API structure. I fear
renaming v4l2_pixfmt to v4l2_pix_format_anything would rather strengthen
that association, while I'd like to achieve the opposite.

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Guennadi Liakhovetski Aug. 26, 2014, 8:18 p.m. UTC | #8
Hi Philipp,

On Mon, 25 Aug 2014, Philipp Zabel wrote:

> This patch adds an array of V4L2 pixel formats and descriptions that can be
> used by drivers so that each driver doesn't have to provide its own slightly
> different format descriptions for VIDIOC_ENUM_FMT.

In case you missed it, soc-camera is doing something rather similar along 
the lines of:

drivers/media/platform/soc_camera/soc_mediabus.c
include/media/soc_mediabus.h

Feel free to re-use.

Thanks
Guennadi

> 
> Each array entry also includes two bits per pixel values (for a single line and
> one for the whole image) that can be used to determine the v4l2_pix_format
> bytesperline and sizeimage values and whether the format is planar or
> compressed.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> I have started to convert some drivers on a boring train ride, but it occurred
> to me that I probably should get some feedback before carrying on with this:
> http://git.pengutronix.de/?p=pza/linux.git;a=shortlog;h=refs/heads/topic/media-pixfmt
> ---
>  drivers/media/v4l2-core/v4l2-common.c | 488 ++++++++++++++++++++++++++++++++++
>  include/media/v4l2-common.h           |  44 +++
>  2 files changed, 532 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> index ccaa38f..41692df 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -533,3 +533,491 @@ void v4l2_get_timestamp(struct timeval *tv)
>  	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
>  }
>  EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
> +
> +static const struct v4l2_pixfmt v4l2_pixfmts[] = {
> +	{
> +		.name = "8-bit RGB 3-3-2",
> +		.pixelformat = V4L2_PIX_FMT_RGB332,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "16-bit RGB 4-4-4",
> +		.pixelformat = V4L2_PIX_FMT_RGB444,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit ARGB 4-4-4-4",
> +		.pixelformat = V4L2_PIX_FMT_ARGB444,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit XRGB 4-4-4-4",
> +		.pixelformat = V4L2_PIX_FMT_XRGB444,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit RGB 5-5-5",
> +		.pixelformat = V4L2_PIX_FMT_RGB555,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit ARGB 1-5-5-5",
> +		.pixelformat = V4L2_PIX_FMT_ARGB555,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit XRGB 1-5-5-5",
> +		.pixelformat = V4L2_PIX_FMT_XRGB555,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit RGB 5-6-5",
> +		.pixelformat = V4L2_PIX_FMT_RGB565,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit RGB 5-5-5 BE",
> +		.pixelformat = V4L2_PIX_FMT_RGB555X,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit RGB 5-6-5 BE",
> +		.pixelformat = V4L2_PIX_FMT_RGB565X,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "18-bit BGR 6-6-6",
> +		.pixelformat = V4L2_PIX_FMT_BGR666,
> +		.bpp_line = 18,
> +		.bpp_image = 18,
> +	}, {
> +		.name = "24-bit BGR 8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_BGR24,
> +		.bpp_line = 24,
> +		.bpp_image = 24,
> +	}, {
> +		.name = "24-bit RGB 8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_RGB24,
> +		.bpp_line = 24,
> +		.bpp_image = 24,
> +	}, {
> +		.name = "32-bit BGR 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_BGR32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "32-bit BGRA 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_ABGR32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "32-bit BGRX 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_XBGR32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "32-bit RGB 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_RGB32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "32-bit ARGB 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_ARGB32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "32-bit XRGB 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_XRGB32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "8-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_GREY,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "4-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_Y4,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "6-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_Y6,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "10-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_Y10,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "12-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_Y12,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit Greyscale",
> +		.pixelformat = V4L2_PIX_FMT_Y16,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "10-bit Greyscale (packed)",
> +		.pixelformat = V4L2_PIX_FMT_Y10BPACK,
> +		.bpp_line = 10,
> +		.bpp_image = 10,
> +	}, {
> +		.name = "8-bit Palette",
> +		.pixelformat = V4L2_PIX_FMT_PAL8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Chrominance UV 4-4",
> +		.pixelformat = V4L2_PIX_FMT_UV8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "Planar YVU 4:1:0",
> +		.pixelformat = V4L2_PIX_FMT_YVU410,
> +		.bpp_line = 8,
> +		.bpp_image = 9,
> +	}, {
> +		.name = "Planar YVU 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_YVU420,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "YUYV 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_YUYV,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "YYUV 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_YYUV,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "YVYU 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_YVYU,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "UYVY 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_UYVY,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "VYUY 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_VYUY,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Planar YVU 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_YUV422P,
> +		.bpp_line = 8,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Planar YUV 4:1:1",
> +		.pixelformat = V4L2_PIX_FMT_YUV411P,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "YUV 4:1:1 (packed)",
> +		.pixelformat = V4L2_PIX_FMT_YUV411P,
> +		.bpp_line = 12,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "16-bit YUV 4-4-4",
> +		.pixelformat = V4L2_PIX_FMT_YUV444,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit YUV 5-5-5",
> +		.pixelformat = V4L2_PIX_FMT_YUV555,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "16-bit YUV 5-6-5",
> +		.pixelformat = V4L2_PIX_FMT_YUV565,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "32-bit YUV 8-8-8-8",
> +		.pixelformat = V4L2_PIX_FMT_YUV32,
> +		.bpp_line = 32,
> +		.bpp_image = 32,
> +	}, {
> +		.name = "Planar YUV 4:1:0",
> +		.pixelformat = V4L2_PIX_FMT_YUV555,
> +		.bpp_line = 8,
> +		.bpp_image = 9,
> +	}, {
> +		.name = "Planar YUV 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_YUV420,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "8-bit dithered RGB (BTTV)",
> +		.pixelformat = V4L2_PIX_FMT_HI240,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "YUV 4:2:0 (16x16 macroblocks)",
> +		.pixelformat = V4L2_PIX_FMT_HM12,
> +		/* bpp_line not applicable for macroblock tiled formats */
> +		.bpp_image = 12,
> +	}, {
> +		.name = "YUV 4:2:0 (M420)",
> +		.pixelformat = V4L2_PIX_FMT_M420,
> +		/* bpp_line not applicable for hybrid line-interleaved planes */
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CbCr 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_NV12,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CrCb 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_NV21,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CbCr 4:2:2",
> +		.pixelformat = V4L2_PIX_FMT_NV16,
> +		.bpp_line = 8,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Y/CrCb 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_NV61,
> +		.bpp_line = 8,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Y/CbCr 4:4:4",
> +		.pixelformat = V4L2_PIX_FMT_NV24,
> +		.bpp_line = 8,
> +		.bpp_image = 24,
> +	}, {
> +		.name = "Y/CrCb 4:2:0",
> +		.pixelformat = V4L2_PIX_FMT_NV42,
> +		.bpp_line = 8,
> +		.bpp_image = 24,
> +	}, {
> +		.name = "Y/CbCr 4:2:0 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_NV12M,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CrCb 4:2:0 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_NV21M,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CbCr 4:2:2 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_NV16M,
> +		.bpp_line = 8,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Y/CrCb 4:2:2 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_NV61M,
> +		.bpp_line = 8,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Y/CbCr 4:2:0 (64x32 MB, non-c.)",
> +		.pixelformat = V4L2_PIX_FMT_NV12MT,
> +		/* bpp_line not applicable for macroblock tiled formats */
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Y/CbCr 4:2:0 (16x16 MB, non-c.)",
> +		.pixelformat = V4L2_PIX_FMT_NV12MT_16X16,
> +		/* bpp_line not applicable for macroblock tiled formats */
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Planar YUV 4:2:0 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_YUV420M,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "Planar YVU 4:2:0 (non-contig.)",
> +		.pixelformat = V4L2_PIX_FMT_YUV420M,
> +		.bpp_line = 8,
> +		.bpp_image = 12,
> +	}, {
> +		.name = "8-bit Bayer BGBG/GRGR",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GBGB/RGRG",
> +		.pixelformat = V4L2_PIX_FMT_SGBRG8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GRGR/BGBG",
> +		.pixelformat = V4L2_PIX_FMT_SGRBG8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer RGRG/GBGB",
> +		.pixelformat = V4L2_PIX_FMT_SRGGB8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "10-bit Bayer BGBG/GRGR",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR10,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "10-bit Bayer GBGB/RGRG",
> +		.pixelformat = V4L2_PIX_FMT_SGBRG10,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "10-bit Bayer GRGR/BGBG",
> +		.pixelformat = V4L2_PIX_FMT_SGRBG10,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "10-bit Bayer RGRG/GBGB",
> +		.pixelformat = V4L2_PIX_FMT_SRGGB10,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "12-bit Bayer BGBG/GRGR",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR12,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "12-bit Bayer GBGB/RGRG",
> +		.pixelformat = V4L2_PIX_FMT_SGBRG12,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "12-bit Bayer GRGR/BGBG",
> +		.pixelformat = V4L2_PIX_FMT_SGRBG12,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "12-bit Bayer RGRG/GBGB",
> +		.pixelformat = V4L2_PIX_FMT_SRGGB12,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "8-bit Bayer BGBG/GRGR (A-law)",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GBGB/RGRG (A-law)",
> +		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GRGR/BGBG (A-law)",
> +		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer RGRG/GBGB (A-law)",
> +		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +
> +		.name = "8-bit Bayer BGBG/GRGR (DPCM)",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GBGB/RGRG (DPCM)",
> +		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer GRGR/BGBG (DPCM)",
> +		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "8-bit Bayer RGRG/GBGB (DPCM)",
> +		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
> +		.bpp_line = 8,
> +		.bpp_image = 8,
> +	}, {
> +		.name = "16-bit Bayer BGBG/GRGR (exp.)",
> +		.pixelformat = V4L2_PIX_FMT_SBGGR16,
> +		.bpp_line = 16,
> +		.bpp_image = 16,
> +	}, {
> +		.name = "Motion-JPEG",
> +		.pixelformat = V4L2_PIX_FMT_MJPEG,
> +	}, {
> +		.name = "JFIF JPEG",
> +		.pixelformat = V4L2_PIX_FMT_JPEG,
> +	}, {
> +		.name = "1394",
> +		.pixelformat = V4L2_PIX_FMT_DV,
> +	}, {
> +		.name = "MPEG-1/2/4",
> +		.pixelformat = V4L2_PIX_FMT_MPEG,
> +	}, {
> +		.name = "H.264",
> +		.pixelformat = V4L2_PIX_FMT_H264,
> +	}, {
> +		.name = "H.264 (without start codes)",
> +		.pixelformat = V4L2_PIX_FMT_H264_NO_SC,
> +	}, {
> +		.name = "H.264 MVC",
> +		.pixelformat = V4L2_PIX_FMT_H264_MVC,
> +	}, {
> +		.name = "H.263",
> +		.pixelformat = V4L2_PIX_FMT_H263,
> +	}, {
> +		.name = "MPEG-1 ES",
> +		.pixelformat = V4L2_PIX_FMT_MPEG1,
> +	}, {
> +		.name = "MPEG-2 ES",
> +		.pixelformat = V4L2_PIX_FMT_MPEG2,
> +	}, {
> +		.name = "MPEG-4 part 2 ES",
> +		.pixelformat = V4L2_PIX_FMT_MPEG4,
> +	}, {
> +		.name = "Xvid",
> +		.pixelformat = V4L2_PIX_FMT_XVID,
> +	}, {
> +		.name = "VC-1 (SMPTE 412M Annex G)",
> +		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
> +	}, {
> +		.name = "VC-1 (SMPTE 412M Annex L)",
> +		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
> +	}, {
> +		.name = "VP8",
> +		.pixelformat = V4L2_PIX_FMT_VP8,
> +	},
> +};
> +
> +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(v4l2_pixfmts); i++) {
> +		if (v4l2_pixfmts[i].pixelformat == fourcc)
> +			return v4l2_pixfmts + i;
> +	}
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_pixfmt_by_fourcc);
> +
> +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc)
> +{
> +	const struct v4l2_pixfmt *fmt;
> +
> +	fmt = v4l2_pixfmt_by_fourcc(fourcc);
> +	if (!fmt)
> +		return -EINVAL;
> +
> +	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
> +	f->pixelformat = fmt->pixelformat;
> +	f->flags = (fmt->bpp_image == 0) ? V4L2_FMT_FLAG_COMPRESSED : 0;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_fill_fmtdesc);
> diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
> index 48f9748..27b084f 100644
> --- a/include/media/v4l2-common.h
> +++ b/include/media/v4l2-common.h
> @@ -204,4 +204,48 @@ const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
>  
>  void v4l2_get_timestamp(struct timeval *tv);
>  
> +/**
> + * struct v4l2_pixfmt - internal V4L2 pixel format description
> + * @name: format description to be returned by enum_fmt
> + * @pixelformat: v4l2 pixel format fourcc
> + * @bpp_line: bits per pixel, averaged over a line (of the first plane
> + *            for planar formats), used to calculate bytesperline
> + *            Zero for compressed and macroblock tiled formats.
> + * @bpp_image: bits per pixel, averaged over the whole image. This is used to
> + *             calculate sizeimage for uncompressed formats.
> + *             Zero for compressed formats.
> + */
> +struct v4l2_pixfmt {
> +	const char	*name;
> +	u32		pixelformat;
> +	u8		bpp_line;
> +	u8		bpp_image;
> +};
> +
> +const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc);
> +int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc);
> +
> +static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt *fmt,
> +					     unsigned int width)
> +{
> +	return width * fmt->bpp_line / 8;
> +}
> +
> +static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt *fmt,
> +					  unsigned int width,
> +					  unsigned int height)
> +{
> +	return width * height * fmt->bpp_image / 8;
> +}
> +
> +static inline bool v4l2_pixfmt_is_planar(const struct v4l2_pixfmt *fmt)
> +{
> +	return fmt->bpp_line && (fmt->bpp_line != fmt->bpp_image);
> +}
> +
> +static inline bool v4l2_pixfmt_is_compressed(const struct v4l2_pixfmt *fmt)
> +{
> +	return fmt->bpp_image == 0;
> +}
> +
>  #endif /* V4L2_COMMON_H_ */
> -- 
> 2.1.0.rc1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Philipp Zabel Aug. 27, 2014, 9:19 a.m. UTC | #9
Hi Guennadi,

Am Dienstag, den 26.08.2014, 22:18 +0200 schrieb Guennadi Liakhovetski:
> Hi Philipp,
> 
> On Mon, 25 Aug 2014, Philipp Zabel wrote:
> 
> > This patch adds an array of V4L2 pixel formats and descriptions that can be
> > used by drivers so that each driver doesn't have to provide its own slightly
> > different format descriptions for VIDIOC_ENUM_FMT.
> 
> In case you missed it, soc-camera is doing something rather similar along 
> the lines of:
> 
> drivers/media/platform/soc_camera/soc_mediabus.c
> include/media/soc_mediabus.h
> 
> Feel free to re-use.

thank you for the pointer. It is unfortunate that there is a bit of
overlap in the names, but not much in the rest of the information.
I don't see how the data could be reused in a meaningful way, but maybe
I should try to match the patterns.

I like the idea of soc_mbus_find_fmtdesc being called with a driver
specific lookup array. Although that currently causes drivers to again
duplicate all the names, it side-steps the issue of a linear lookup in a
large global array. Maybe a helper to fill this driver specific array
from the global array would be a good idea for consistency?

What is the reason for the separation between struct soc_mbus_lookup and
struct soc_mbus pixelformat (as opposed to including enum
v4l2_mbus_pixelcode in struct soc_mbus_pixelformat directly)?

regards
Philipp


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index ccaa38f..41692df 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -533,3 +533,491 @@  void v4l2_get_timestamp(struct timeval *tv)
 	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 }
 EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
+
+static const struct v4l2_pixfmt v4l2_pixfmts[] = {
+	{
+		.name = "8-bit RGB 3-3-2",
+		.pixelformat = V4L2_PIX_FMT_RGB332,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "16-bit RGB 4-4-4",
+		.pixelformat = V4L2_PIX_FMT_RGB444,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit ARGB 4-4-4-4",
+		.pixelformat = V4L2_PIX_FMT_ARGB444,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit XRGB 4-4-4-4",
+		.pixelformat = V4L2_PIX_FMT_XRGB444,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit RGB 5-5-5",
+		.pixelformat = V4L2_PIX_FMT_RGB555,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit ARGB 1-5-5-5",
+		.pixelformat = V4L2_PIX_FMT_ARGB555,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit XRGB 1-5-5-5",
+		.pixelformat = V4L2_PIX_FMT_XRGB555,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit RGB 5-6-5",
+		.pixelformat = V4L2_PIX_FMT_RGB565,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit RGB 5-5-5 BE",
+		.pixelformat = V4L2_PIX_FMT_RGB555X,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit RGB 5-6-5 BE",
+		.pixelformat = V4L2_PIX_FMT_RGB565X,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "18-bit BGR 6-6-6",
+		.pixelformat = V4L2_PIX_FMT_BGR666,
+		.bpp_line = 18,
+		.bpp_image = 18,
+	}, {
+		.name = "24-bit BGR 8-8-8",
+		.pixelformat = V4L2_PIX_FMT_BGR24,
+		.bpp_line = 24,
+		.bpp_image = 24,
+	}, {
+		.name = "24-bit RGB 8-8-8",
+		.pixelformat = V4L2_PIX_FMT_RGB24,
+		.bpp_line = 24,
+		.bpp_image = 24,
+	}, {
+		.name = "32-bit BGR 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_BGR32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "32-bit BGRA 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_ABGR32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "32-bit BGRX 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_XBGR32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "32-bit RGB 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_RGB32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "32-bit ARGB 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_ARGB32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "32-bit XRGB 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_XRGB32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "8-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_GREY,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "4-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_Y4,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "6-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_Y6,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "10-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_Y10,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "12-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_Y12,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit Greyscale",
+		.pixelformat = V4L2_PIX_FMT_Y16,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "10-bit Greyscale (packed)",
+		.pixelformat = V4L2_PIX_FMT_Y10BPACK,
+		.bpp_line = 10,
+		.bpp_image = 10,
+	}, {
+		.name = "8-bit Palette",
+		.pixelformat = V4L2_PIX_FMT_PAL8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Chrominance UV 4-4",
+		.pixelformat = V4L2_PIX_FMT_UV8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "Planar YVU 4:1:0",
+		.pixelformat = V4L2_PIX_FMT_YVU410,
+		.bpp_line = 8,
+		.bpp_image = 9,
+	}, {
+		.name = "Planar YVU 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_YVU420,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "YUYV 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_YUYV,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "YYUV 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_YYUV,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "YVYU 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_YVYU,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "UYVY 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "VYUY 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_VYUY,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "Planar YVU 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_YUV422P,
+		.bpp_line = 8,
+		.bpp_image = 16,
+	}, {
+		.name = "Planar YUV 4:1:1",
+		.pixelformat = V4L2_PIX_FMT_YUV411P,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "YUV 4:1:1 (packed)",
+		.pixelformat = V4L2_PIX_FMT_YUV411P,
+		.bpp_line = 12,
+		.bpp_image = 12,
+	}, {
+		.name = "16-bit YUV 4-4-4",
+		.pixelformat = V4L2_PIX_FMT_YUV444,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit YUV 5-5-5",
+		.pixelformat = V4L2_PIX_FMT_YUV555,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "16-bit YUV 5-6-5",
+		.pixelformat = V4L2_PIX_FMT_YUV565,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "32-bit YUV 8-8-8-8",
+		.pixelformat = V4L2_PIX_FMT_YUV32,
+		.bpp_line = 32,
+		.bpp_image = 32,
+	}, {
+		.name = "Planar YUV 4:1:0",
+		.pixelformat = V4L2_PIX_FMT_YUV555,
+		.bpp_line = 8,
+		.bpp_image = 9,
+	}, {
+		.name = "Planar YUV 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_YUV420,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "8-bit dithered RGB (BTTV)",
+		.pixelformat = V4L2_PIX_FMT_HI240,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "YUV 4:2:0 (16x16 macroblocks)",
+		.pixelformat = V4L2_PIX_FMT_HM12,
+		/* bpp_line not applicable for macroblock tiled formats */
+		.bpp_image = 12,
+	}, {
+		.name = "YUV 4:2:0 (M420)",
+		.pixelformat = V4L2_PIX_FMT_M420,
+		/* bpp_line not applicable for hybrid line-interleaved planes */
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CbCr 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_NV12,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CrCb 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_NV21,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CbCr 4:2:2",
+		.pixelformat = V4L2_PIX_FMT_NV16,
+		.bpp_line = 8,
+		.bpp_image = 16,
+	}, {
+		.name = "Y/CrCb 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_NV61,
+		.bpp_line = 8,
+		.bpp_image = 16,
+	}, {
+		.name = "Y/CbCr 4:4:4",
+		.pixelformat = V4L2_PIX_FMT_NV24,
+		.bpp_line = 8,
+		.bpp_image = 24,
+	}, {
+		.name = "Y/CrCb 4:2:0",
+		.pixelformat = V4L2_PIX_FMT_NV42,
+		.bpp_line = 8,
+		.bpp_image = 24,
+	}, {
+		.name = "Y/CbCr 4:2:0 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_NV12M,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CrCb 4:2:0 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_NV21M,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CbCr 4:2:2 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_NV16M,
+		.bpp_line = 8,
+		.bpp_image = 16,
+	}, {
+		.name = "Y/CrCb 4:2:2 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_NV61M,
+		.bpp_line = 8,
+		.bpp_image = 16,
+	}, {
+		.name = "Y/CbCr 4:2:0 (64x32 MB, non-c.)",
+		.pixelformat = V4L2_PIX_FMT_NV12MT,
+		/* bpp_line not applicable for macroblock tiled formats */
+		.bpp_image = 12,
+	}, {
+		.name = "Y/CbCr 4:2:0 (16x16 MB, non-c.)",
+		.pixelformat = V4L2_PIX_FMT_NV12MT_16X16,
+		/* bpp_line not applicable for macroblock tiled formats */
+		.bpp_image = 12,
+	}, {
+		.name = "Planar YUV 4:2:0 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_YUV420M,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "Planar YVU 4:2:0 (non-contig.)",
+		.pixelformat = V4L2_PIX_FMT_YUV420M,
+		.bpp_line = 8,
+		.bpp_image = 12,
+	}, {
+		.name = "8-bit Bayer BGBG/GRGR",
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GBGB/RGRG",
+		.pixelformat = V4L2_PIX_FMT_SGBRG8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GRGR/BGBG",
+		.pixelformat = V4L2_PIX_FMT_SGRBG8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer RGRG/GBGB",
+		.pixelformat = V4L2_PIX_FMT_SRGGB8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "10-bit Bayer BGBG/GRGR",
+		.pixelformat = V4L2_PIX_FMT_SBGGR10,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "10-bit Bayer GBGB/RGRG",
+		.pixelformat = V4L2_PIX_FMT_SGBRG10,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "10-bit Bayer GRGR/BGBG",
+		.pixelformat = V4L2_PIX_FMT_SGRBG10,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "10-bit Bayer RGRG/GBGB",
+		.pixelformat = V4L2_PIX_FMT_SRGGB10,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "12-bit Bayer BGBG/GRGR",
+		.pixelformat = V4L2_PIX_FMT_SBGGR12,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "12-bit Bayer GBGB/RGRG",
+		.pixelformat = V4L2_PIX_FMT_SGBRG12,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "12-bit Bayer GRGR/BGBG",
+		.pixelformat = V4L2_PIX_FMT_SGRBG12,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "12-bit Bayer RGRG/GBGB",
+		.pixelformat = V4L2_PIX_FMT_SRGGB12,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "8-bit Bayer BGBG/GRGR (A-law)",
+		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GBGB/RGRG (A-law)",
+		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GRGR/BGBG (A-law)",
+		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer RGRG/GBGB (A-law)",
+		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+
+		.name = "8-bit Bayer BGBG/GRGR (DPCM)",
+		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GBGB/RGRG (DPCM)",
+		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer GRGR/BGBG (DPCM)",
+		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "8-bit Bayer RGRG/GBGB (DPCM)",
+		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
+		.bpp_line = 8,
+		.bpp_image = 8,
+	}, {
+		.name = "16-bit Bayer BGBG/GRGR (exp.)",
+		.pixelformat = V4L2_PIX_FMT_SBGGR16,
+		.bpp_line = 16,
+		.bpp_image = 16,
+	}, {
+		.name = "Motion-JPEG",
+		.pixelformat = V4L2_PIX_FMT_MJPEG,
+	}, {
+		.name = "JFIF JPEG",
+		.pixelformat = V4L2_PIX_FMT_JPEG,
+	}, {
+		.name = "1394",
+		.pixelformat = V4L2_PIX_FMT_DV,
+	}, {
+		.name = "MPEG-1/2/4",
+		.pixelformat = V4L2_PIX_FMT_MPEG,
+	}, {
+		.name = "H.264",
+		.pixelformat = V4L2_PIX_FMT_H264,
+	}, {
+		.name = "H.264 (without start codes)",
+		.pixelformat = V4L2_PIX_FMT_H264_NO_SC,
+	}, {
+		.name = "H.264 MVC",
+		.pixelformat = V4L2_PIX_FMT_H264_MVC,
+	}, {
+		.name = "H.263",
+		.pixelformat = V4L2_PIX_FMT_H263,
+	}, {
+		.name = "MPEG-1 ES",
+		.pixelformat = V4L2_PIX_FMT_MPEG1,
+	}, {
+		.name = "MPEG-2 ES",
+		.pixelformat = V4L2_PIX_FMT_MPEG2,
+	}, {
+		.name = "MPEG-4 part 2 ES",
+		.pixelformat = V4L2_PIX_FMT_MPEG4,
+	}, {
+		.name = "Xvid",
+		.pixelformat = V4L2_PIX_FMT_XVID,
+	}, {
+		.name = "VC-1 (SMPTE 412M Annex G)",
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
+	}, {
+		.name = "VC-1 (SMPTE 412M Annex L)",
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
+	}, {
+		.name = "VP8",
+		.pixelformat = V4L2_PIX_FMT_VP8,
+	},
+};
+
+const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(v4l2_pixfmts); i++) {
+		if (v4l2_pixfmts[i].pixelformat == fourcc)
+			return v4l2_pixfmts + i;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_pixfmt_by_fourcc);
+
+int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc)
+{
+	const struct v4l2_pixfmt *fmt;
+
+	fmt = v4l2_pixfmt_by_fourcc(fourcc);
+	if (!fmt)
+		return -EINVAL;
+
+	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
+	f->pixelformat = fmt->pixelformat;
+	f->flags = (fmt->bpp_image == 0) ? V4L2_FMT_FLAG_COMPRESSED : 0;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fill_fmtdesc);
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 48f9748..27b084f 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -204,4 +204,48 @@  const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
 
 void v4l2_get_timestamp(struct timeval *tv);
 
+/**
+ * struct v4l2_pixfmt - internal V4L2 pixel format description
+ * @name: format description to be returned by enum_fmt
+ * @pixelformat: v4l2 pixel format fourcc
+ * @bpp_line: bits per pixel, averaged over a line (of the first plane
+ *            for planar formats), used to calculate bytesperline
+ *            Zero for compressed and macroblock tiled formats.
+ * @bpp_image: bits per pixel, averaged over the whole image. This is used to
+ *             calculate sizeimage for uncompressed formats.
+ *             Zero for compressed formats.
+ */
+struct v4l2_pixfmt {
+	const char	*name;
+	u32		pixelformat;
+	u8		bpp_line;
+	u8		bpp_image;
+};
+
+const struct v4l2_pixfmt *v4l2_pixfmt_by_fourcc(u32 fourcc);
+int v4l2_fill_fmtdesc(struct v4l2_fmtdesc *f, u32 fourcc);
+
+static inline unsigned int v4l2_bytesperline(const struct v4l2_pixfmt *fmt,
+					     unsigned int width)
+{
+	return width * fmt->bpp_line / 8;
+}
+
+static inline unsigned int v4l2_sizeimage(const struct v4l2_pixfmt *fmt,
+					  unsigned int width,
+					  unsigned int height)
+{
+	return width * height * fmt->bpp_image / 8;
+}
+
+static inline bool v4l2_pixfmt_is_planar(const struct v4l2_pixfmt *fmt)
+{
+	return fmt->bpp_line && (fmt->bpp_line != fmt->bpp_image);
+}
+
+static inline bool v4l2_pixfmt_is_compressed(const struct v4l2_pixfmt *fmt)
+{
+	return fmt->bpp_image == 0;
+}
+
 #endif /* V4L2_COMMON_H_ */