Re: [PATCH] media: Add P010 video format

From: Nicolas Dufresne
Date: Tue Apr 05 2022 - 18:09:16 EST


Le lundi 04 avril 2022 à 16:57 -0300, Ezequiel Garcia a écrit :
> On Mon, Apr 04, 2022 at 11:01:16AM +0200, Benjamin Gaignard wrote:
> > P010 is a YUV format with 10-bits per pixel with interleaved UV.
> >
> > Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx>
> > Acked-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx>
>
> Reviewed-by: Ezequiel Garcia <ezequiel@xxxxxxxxxxxxxxxxxxxx>
>
> > ---
> > Note that P010 is already known in GStreamer, only the mapping with
> > v4l2 pixel format is missing.
> >
> > This patch has been acked in this series but never merged:
> > https://patchwork.kernel.org/project/linux-rockchip/patch/20210618131526.566762-5-benjamin.gaignard@xxxxxxxxxxxxx/
> > After rebased it on v5.18-rc1, resend in standalone mode.
> >
> > .../media/v4l/pixfmt-yuv-planar.rst | 76 +++++++++++++++++++
> > drivers/media/v4l2-core/v4l2-common.c | 1 +
> > drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
> > include/uapi/linux/videodev2.h | 1 +
> > 4 files changed, 79 insertions(+)
> >
> > diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> > index 8dff5906639b..6d65c8ac44f0 100644
> > --- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> > +++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
> > @@ -102,6 +102,13 @@ All components are stored with the same number of bits per component.
> > - 64x32 tiles
> >
> > Horizontal Z order
> > + * - V4L2_PIX_FMT_P010
> > + - 'P010'
> > + - 16
> > + - 4:2:0
> > + - Cb, Cr
> > + - No
> > + - Linear
> > * - V4L2_PIX_FMT_NV12MT_16X16
> > - 'VM12'
> > - 8
> > @@ -171,6 +178,7 @@ horizontally.
> > .. _V4L2-PIX-FMT-NV21:
> > .. _V4L2-PIX-FMT-NV12M:
> > .. _V4L2-PIX-FMT-NV21M:
> > +.. _V4L2-PIX-FMT-P010:
> >
> > NV12, NV21, NV12M and NV21M
> > ---------------------------
> > @@ -519,6 +527,74 @@ number of lines as the luma plane.
> > - Cb\ :sub:`33`
> > - Cr\ :sub:`33`
> >
> > +.. _V4L2_PIX_FMT_P010:
> > +
> > +P010
> > +----
> > +
> > +The number of bytes in one luminance row must be divisible by 16,
> > +which means there will be padded 0 in the right edge when necessary.

So far in GStreamer we have met two form of P010. One has the short stored in
little endian, and the other in big endian. Its probably visible in the table
here (sorry can't read tables from text), but it could be nice to put that in
words if not part of the format name.


Microfost seems to only define "little endian" variation.

https://docs.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats

> > +
> > +.. raw:: latex
> > +
> > + \begingroup
> > + \small
> > + \setlength{\tabcolsep}{2pt}
> > +
> > +.. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
> > +
> > +.. flat-table:: P010 16 Bits per component
> > + :header-rows: 2
> > + :stub-columns: 0
> > +
> > + * - Identifier
> > + - Code
> > + - :cspan:`7` Byte 0 in memory
> > +
> > + - :cspan:`7` Byte 1
> > + * -
> > + -
> > + - 7
> > + - 6
> > + - 5
> > + - 4
> > + - 3
> > + - 2
> > + - 1
> > + - 0
> > +
> > + - 7
> > + - 6
> > + - 5
> > + - 4
> > + - 3
> > + - 2
> > + - 1
> > + - 0
> > + * - ``V4L2_PIX_FMT_P010``
> > + - 'P010'
> > +
> > + - Y\ :sub:`9`
> > + - Y\ :sub:`8`
> > + - Y\ :sub:`7`
> > + - Y\ :sub:`6`
> > + - Y\ :sub:`5`
> > + - Y\ :sub:`4`
> > + - Y\ :sub:`3`
> > + - Y\ :sub:`2`
> > +
> > + - Y\ :sub:`1`
> > + - Y\ :sub:`0`
> > + - 0
> > + - 0
> > + - 0
> > + - 0
> > + - 0
> > + - 0
> > +
> > +.. raw:: latex
> > +
> > + \endgroup
> >
> > Fully Planar YUV Formats
> > ========================
> > diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> > index df34b2a283bc..1e38ad8906a2 100644
> > --- a/drivers/media/v4l2-core/v4l2-common.c
> > +++ b/drivers/media/v4l2-core/v4l2-common.c
> > @@ -266,6 +266,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
> > { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
> > { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
> > { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
> > + { .format = V4L2_PIX_FMT_P010, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
> >
> > { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
> > { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
> > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> > index 96e307fe3aab..e14d7e1a038e 100644
> > --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> > @@ -1301,6 +1301,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> > case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break;
> > case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break;
> > case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break;
> > + case V4L2_PIX_FMT_P010: descr = "10-bit Y/CrCb 4:2:0"; break;
> > case V4L2_PIX_FMT_NV12_4L4: descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
> > case V4L2_PIX_FMT_NV12_16L16: descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
> > case V4L2_PIX_FMT_NV12_32L32: descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index 4c09969e7112..2e451c454db3 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -601,6 +601,7 @@ struct v4l2_pix_format {
> > #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
> > #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */
> > #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */
> > +#define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0') /* 15 Y/CbCr 4:2:0 10-bit per pixel*/
> >
> > /* two non contiguous planes - one Y, one Cr + Cb interleaved */
> > #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
> > --
> > 2.32.0
> >