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@xxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxx > 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html