Re: [PATCH v2] [RFC v2] v4l2: add support for colorspace conversion for video capture

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Philipp,

It is much appreciated that this old RFC of mine is picked up again.
I always wanted to get this in, but I never had a driver where it would
make sense to do so.

On 09/05/2018 07:09 PM, Philipp Zabel wrote:
> For video capture it is the driver that reports the colorspace,

add: "transfer function,"

> Y'CbCr/HSV encoding and quantization range used by the video, and there
> is no way to request something different, even though many HDTV
> receivers have some sort of colorspace conversion capabilities.
> 
> For output video this feature already exists since the application
> specifies this information for the video format it will send out, and
> the transmitter will enable any available CSC if a format conversion has
> to be performed in order to match the capabilities of the sink.
> 
> For video capture we propose adding new pix_format flags:
> V4L2_PIX_FMT_FLAG_CSC_COLORSPACE, V4L2_PIX_FMT_FLAG_CSC_YCBCR_ENC,
> V4L2_PIX_FMT_FLAG_CSC_HSV_ENC, V4L2_PIX_FMT_FLAG_CSC_QUANTIZATION, and
> V4L2_PIX_FMT_FLAG_CSC_XFER_FUNC. These are set by the driver to indicate
> its conversion features. When set by the application, the driver will
> interpret the colorspace, ycbcr_enc/hsv_enc, quantization and xfer_func
> fields as the requested colorspace information and will attempt to do
> the conversion it supports.
> 
> Drivers do not have to actually look at the flags: if the flags are not
> set, then the colorspace, ycbcr_enc and quantization fields are set to
> the default values by the core, i.e. just pass on the received format
> without conversion.

Thinking about this some more, I don't think this is quite the right approach.
Having userspace set these flags with S_FMT if they want to do explicit
conversions makes sense, and that part we can keep.

But to signal the capabilities I think should be done via new flags for
VIDIOC_ENUM_FMT. Basically the same set of flags, but for the flags field
of struct v4l2_fmtdesc.

One thing that's not clear to me is what happens if userspace sets one or
more flags and calls S_FMT for a driver that doesn't support this. Are the
flags zeroed in that case upon return? I don't think so, but I think that
is already true for the existing flag V4L2_PIX_FMT_FLAG_PREMUL_ALPHA.

I wonder if V4L2_PIX_FMT_FLAG_PREMUL_ALPHA should also get an equivalent
flag for v4l2_fmtdesc.

Then we can just document that v4l2_format flags are only valid if they
are also defined in v4l2_fmtdesc.

Does anyone have better ideas for this?

Regards,

	Hans

> 
> Signed-off-by: Hans Verkuil <Hans Verkuil@xxxxxxxxx>
> Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
> ---
> Changes since v1 [1]
>  - convert to rst
>  - split V4L2_PIX_FMT_FLAG_REQUEST_CSC into four separate flags for
>    colorspace, ycbcr_enc/hsv_enc, quantization, and xfer_func
>  - let driver set flags to indicate supported features
> 
> [1] https://patchwork.linuxtv.org/patch/28847/
> ---
>  .../media/uapi/v4l/pixfmt-reserved.rst        | 41 +++++++++++++++++++
>  .../media/uapi/v4l/pixfmt-v4l2-mplane.rst     | 16 ++------
>  Documentation/media/uapi/v4l/pixfmt-v4l2.rst  | 37 ++++++++++++++---
>  drivers/media/v4l2-core/v4l2-ioctl.c          | 12 ++++++
>  include/uapi/linux/videodev2.h                |  5 +++
>  5 files changed, 94 insertions(+), 17 deletions(-)
> 
> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> index 38af1472a4b4..c1090027626c 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> @@ -261,3 +261,44 @@ please make a proposal on the linux-media mailing list.
>  	by RGBA values (128, 192, 255, 128), the same pixel described with
>  	premultiplied colors would be described by RGBA values (64, 96,
>  	128, 128)
> +    * - ``V4L2_PIX_FMT_FLAG_CSC_COLORSPACE``
> +      - 0x00000002
> +      - Set by the driver to indicate colorspace conversion support. Set by the
> +	application to request conversion to the specified colorspace. It is
> +	only used for capture and is ignored for output streams. If set by the
> +	application, then request the driver to do colorspace conversion from
> +	the received colorspace to the requested colorspace by setting the
> +	``colorspace`` field of struct :c:type:`v4l2_pix_format`.
> +    * - ``V4L2_PIX_FMT_FLAG_CSC_YCBCR_ENC``
> +      - 0x00000004
> +      - Set by the driver to indicate Y'CbCr encoding conversion support. Set
> +	by the application to request conversion to the specified Y'CbCr
> +	encoding.  It is only used for capture and is ignored for output
> +	streams. If set by the application, then request the driver to convert
> +	from the received Y'CbCr encoding to the requested encoding by setting
> +	the ``ycbcr_enc`` field of struct :c:type:`v4l2_pix_format`.
> +    * - ``V4L2_PIX_FMT_FLAG_CSC_HSV_ENC``
> +      - 0x00000004
> +      - Set by the driver to indicate HSV encoding conversion support. Set
> +	by the application to request conversion to the specified HSV encoding.
> +	It is only used for capture and is ignored for output streams. If set
> +	by the application, then request the driver to convert from the
> +	received HSV encoding to the requested encoding by setting the
> +	``hsv_enc`` field of struct :c:type:`v4l2_pix_format`.
> +    * - ``V4L2_PIX_FMT_FLAG_CSC_QUANTIZATION``
> +      - 0x00000008
> +      - Set by the driver to indicate quantization range conversion support.
> +	Set by the application to request conversion to the specified
> +	quantization range. It is only used for capture and is ignored for
> +	output streams. If set by the application, then request the driver to
> +	convert from the received quantization range to the requested
> +	quantization by setting the ``quantization`` field of struct
> +	:c:type:`v4l2_pix_format`.
> +    * - ``V4L2_PIX_FMT_FLAG_CSC_XFER_FUNC``
> +      - 0x00000010
> +      - Set by the driver to indicate transfer function conversion support.
> +	Set by the application to request conversion to the specified transfer
> +	function. It is only used for capture and is ignored for output
> +	streams. If set by the application, then request the driver to convert
> +	from the received transfer function to the requested transfer function
> +	by setting the ``xfer_func`` field of struct :c:type:`v4l2_pix_format`.
> diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst
> index ef52f637d8e9..7ff07411db77 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst
> @@ -81,30 +81,22 @@ describing all planes of that format.
>      * - __u8
>        - ``ycbcr_enc``
>        - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
> -        This information supplements the ``colorspace`` and must be set by
> -	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	See struct :c:type:`v4l2_pix_format`.
>      * - __u8
>        - ``hsv_enc``
>        - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
> -        This information supplements the ``colorspace`` and must be set by
> -	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	See struct :c:type:`v4l2_pix_format`.
>      * - }
>        -
>        -
>      * - __u8
>        - ``quantization``
>        - Quantization range, from enum :c:type:`v4l2_quantization`.
> -        This information supplements the ``colorspace`` and must be set by
> -	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	See struct :c:type:`v4l2_pix_format`.
>      * - __u8
>        - ``xfer_func``
>        - Transfer function, from enum :c:type:`v4l2_xfer_func`.
> -        This information supplements the ``colorspace`` and must be set by
> -	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	See struct :c:type:`v4l2_pix_format`.
>      * - __u8
>        - ``reserved[7]``
>        - Reserved for future extensions. Should be zeroed by drivers and
> diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
> index 826f2305da01..932b6a546e61 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
> @@ -88,7 +88,12 @@ Single-planar format structure
>        - Image colorspace, from enum :c:type:`v4l2_colorspace`.
>          This information supplements the ``pixelformat`` and must be set
>  	by the driver for capture streams and by the application for
> -	output streams, see :ref:`colorspaces`.
> +	output streams, see :ref:`colorspaces`. If the application sets the
> +	flag ``V4L2_PIX_FMT_FLAG_CSC_COLORSPACE`` then the application can set
> +	this field for a capture stream to request a specific colorspace for
> +	the captured image data. The driver will attempt to do colorspace
> +	conversion to the specified colorspace or return the colorspace it will
> +	use if it can't do the conversion.
>      * - __u32
>        - ``priv``
>        - This field indicates whether the remaining fields of the
> @@ -126,13 +131,25 @@ Single-planar format structure
>        - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
>          This information supplements the ``colorspace`` and must be set by
>  	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	streams, see :ref:`colorspaces`. If the application sets the
> +	flag ``V4L2_PIX_FMT_FLAG_CSC_YCBCR_ENC`` then the application can set
> +	this field for a capture stream to request a specific Y'CbCr encoding
> +	for the captured image data. The driver will attempt to do the
> +	conversion to the specified Y'CbCr encoding or return the encoding it
> +	will use if it can't do the conversion. This field is ignored for
> +	non-Y'CbCr pixelformats.
>      * - __u32
>        - ``hsv_enc``
>        - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`.
>          This information supplements the ``colorspace`` and must be set by
>  	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	streams, see :ref:`colorspaces`. If the application sets the flag
> +	``V4L2_PIX_FMT_FLAG_CSC_HSV_ENC`` then the application can set this
> +	field for a capture stream to request a specific HSV encoding for the
> +	captured image data. The driver will attempt to do the conversion to
> +	the specified HSV encoding or return the encoding it will use if it
> +	can't do the conversion. This field is ignored for non-HSV
> +	pixelformats.
>      * - }
>        -
>        -
> @@ -141,10 +158,20 @@ Single-planar format structure
>        - Quantization range, from enum :c:type:`v4l2_quantization`.
>          This information supplements the ``colorspace`` and must be set by
>  	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	streams, see :ref:`colorspaces`. If the application sets the flag
> +	``V4L2_PIX_FMT_FLAG_CSC_QUANTIZATION`` then the application can set
> +	this field for a capture stream to request a specific quantization
> +	range for the captured image data. The driver will attempt to do the
> +	conversion to the specified quantization range or return the
> +	quantization it will use if it can't do the conversion.
>      * - __u32
>        - ``xfer_func``
>        - Transfer function, from enum :c:type:`v4l2_xfer_func`.
>          This information supplements the ``colorspace`` and must be set by
>  	the driver for capture streams and by the application for output
> -	streams, see :ref:`colorspaces`.
> +	streams, see :ref:`colorspaces`. If the application sets the flag
> +	``V4L2_PIX_FMT_FLAG_CSC_XFER_FUNC`` then the application can set
> +	this field for a capture stream to request a specific transfer function
> +	for the captured image data. The driver will attempt to do the
> +	conversion to the specified transfer function or return the transfer
> +	function it will use if it can't do the conversion.
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 54afc9c7ee6e..39def068f13e 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1019,6 +1019,18 @@ static void v4l_sanitize_format(struct v4l2_format *fmt)
>  	 * isn't used by applications.
>  	 */
>  
> +	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
> +	    fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> +		if (!(fmt->fmt.pix.flags & V4L2_PIX_FMT_FLAG_CSC_COLORSPACE))
> +			fmt->fmt.pix.colorspace = V4L2_COLORSPACE_DEFAULT;
> +		if (!(fmt->fmt.pix.flags & V4L2_PIX_FMT_FLAG_CSC_YCBCR_ENC))
> +			fmt->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +		if (!(fmt->fmt.pix.flags & V4L2_PIX_FMT_FLAG_CSC_QUANTIZATION))
> +			fmt->fmt.pix.quantization = V4L2_QUANTIZATION_DEFAULT;
> +		if (!(fmt->fmt.pix.flags & V4L2_PIX_FMT_FLAG_CSC_XFER_FUNC))
> +			fmt->fmt.pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +	}
> +
>  	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
>  	    fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
>  		return;
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 622f0479d668..4cbc8f23b828 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -709,6 +709,11 @@ struct v4l2_pix_format {
>  
>  /* Flags */
>  #define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA	0x00000001
> +#define V4L2_PIX_FMT_FLAG_CSC_COLORSPACE	0x00000002
> +#define V4L2_PIX_FMT_FLAG_CSC_YCBCR_ENC		0x00000004
> +#define V4L2_PIX_FMT_FLAG_CSC_HSV_ENC		0x00000004
> +#define V4L2_PIX_FMT_FLAG_CSC_QUANTIZATION	0x00000008
> +#define V4L2_PIX_FMT_FLAG_CSC_XFER_FUNC		0x00000010
>  
>  /*
>   *	F O R M A T   E N U M E R A T I O N
> 




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux