linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging
@ 2021-04-03 18:07 Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 01/10] media: uapi: mpeg2: Rename "quantization" to "quantisation" Ezequiel Garcia
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Hi everyone,

Over the last few weeks Daniel Almeida and Nicolas Dufresne
have been working on GStreamer v4l2codecs support for stateless
MPEG-2 decoding.

This allowed us to re-review the MPEG-2 specification and re-discuss
the API with some additional insight. The API now looks quite cleaner,
and hopefully ready for destaging.

This series is mostly thanks to Daniel and Nicolas!

Patches 1 to 7 cleanup the API, and patches 8 to 10 move it
out of staging.

This is tested on i.MX8M and RK3399 platforms, using GStreamer
v4l2codecs, which will be upstream very soon.

v5:
* Rename "quantization" to "quantisation", so the terminology
  matches the MPEG-2 specification.
  This is the only change in v5, compared to v4.

v4:
* Rework and clarify quantization matrices control semantics.
* Move reference buffer fields to the picture parameter control.
* Remove slice parameters control. This can be added back in the
  future if needed, but for now it's not used.
  See patch 6/9 for details.
* Destage the API.

v3:
* No API changes, just minor boilerplate fixes for the new
  controls to be properly exposed, initialized and validated.

v2:
* Fixed bad use of boolean negation in a flag, which
  was fortunately reported by 0day bot.

Ezequiel Garcia (10):
  media: uapi: mpeg2: Rename "quantization" to "quantisation"
  media: uapi: mpeg2: rework quantisation matrices semantics
  media: uapi: mpeg2: Cleanup flags
  media: uapi: mpeg2: Split sequence and picture parameters
  media: uapi: mpeg2: Move reference buffer fields
  media: hantro/cedrus: Remove unneeded slice size and slice offset
  media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS
  media: controls: Log MPEG-2 stateless control in .std_log
  media: uapi: Move the MPEG-2 stateless control type out of staging
  media: uapi: move MPEG-2 stateless controls out of staging

 .../media/v4l/ext-ctrls-codec-stateless.rst   | 218 +++++
 .../media/v4l/ext-ctrls-codec.rst             | 217 -----
 .../media/v4l/pixfmt-compressed.rst           |  11 +-
 .../media/v4l/vidioc-g-ext-ctrls.rst          |  12 +
 .../media/v4l/vidioc-queryctrl.rst            |  18 +-
 .../media/videodev2.h.rst.exceptions          |   5 +-
 drivers/media/v4l2-core/v4l2-async-core.c     | 880 ++++++++++++++++++
 drivers/media/v4l2-core/v4l2-ctrls.c          | 118 ++-
 drivers/staging/media/hantro/hantro_drv.c     |   9 +-
 .../media/hantro/hantro_g1_mpeg2_dec.c        | 110 +--
 drivers/staging/media/hantro/hantro_hw.h      |   2 +-
 drivers/staging/media/hantro/hantro_mpeg2.c   |   2 +-
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    | 106 +--
 drivers/staging/media/sunxi/cedrus/cedrus.c   |  10 +-
 drivers/staging/media/sunxi/cedrus/cedrus.h   |   5 +-
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |  10 +-
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  97 +-
 include/media/mpeg2-ctrls.h                   |  82 --
 include/media/v4l2-ctrls.h                    |  11 +-
 include/uapi/linux/v4l2-controls.h            | 114 +++
 include/uapi/linux/videodev2.h                |   7 +
 21 files changed, 1492 insertions(+), 552 deletions(-)
 create mode 100644 drivers/media/v4l2-core/v4l2-async-core.c
 delete mode 100644 include/media/mpeg2-ctrls.h

-- 
2.30.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5 01/10] media: uapi: mpeg2: Rename "quantization" to "quantisation"
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics Ezequiel Garcia
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

The MPEG-2 specification refers to the quantisation matrices
using the word "quantisation". Make the V4L2 interface more
ergonomic by matching the MPEG-2 spec.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             | 16 ++++++------
 .../media/v4l/pixfmt-compressed.rst           |  4 +--
 .../media/v4l/vidioc-queryctrl.rst            |  6 ++---
 .../media/videodev2.h.rst.exceptions          |  2 +-
 drivers/media/v4l2-core/v4l2-ctrls.c          | 12 ++++-----
 drivers/staging/media/hantro/hantro_drv.c     |  2 +-
 .../media/hantro/hantro_g1_mpeg2_dec.c        | 17 +++++-------
 drivers/staging/media/hantro/hantro_hw.h      |  2 +-
 drivers/staging/media/hantro/hantro_mpeg2.c   |  2 +-
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    | 14 +++++-----
 drivers/staging/media/sunxi/cedrus/cedrus.c   |  2 +-
 drivers/staging/media/sunxi/cedrus/cedrus.h   |  2 +-
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |  4 +--
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 26 +++++++++----------
 include/media/mpeg2-ctrls.h                   |  6 ++---
 include/media/v4l2-ctrls.h                    |  4 +--
 16 files changed, 58 insertions(+), 63 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 188aef8e40d0..151d1c676b6e 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1722,8 +1722,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 
     \normalsize
 
-``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)``
-    Specifies quantization matrices (as extracted from the bitstream) for the
+``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (struct)``
+    Specifies quantisation matrices (as extracted from the bitstream) for the
     associated MPEG-2 slice data.
 
     .. note::
@@ -1731,7 +1731,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
        This compound control is not yet part of the public kernel API and
        it is expected to change.
 
-.. c:type:: v4l2_ctrl_mpeg2_quantization
+.. c:type:: v4l2_ctrl_mpeg2_quantisation
 
 .. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}|
 
@@ -1741,7 +1741,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 
     \small
 
-.. flat-table:: struct v4l2_ctrl_mpeg2_quantization
+.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation
     :header-rows:  0
     :stub-columns: 0
     :widths:       1 1 2
@@ -1765,24 +1765,24 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 	YUV formats.
     * - __u8
       - ``intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for intra-coded frames, in zigzag
+      - The quantisation matrix coefficients for intra-coded frames, in zigzag
 	scanning order. It is relevant for both luma and chroma components,
 	although it can be superseded by the chroma-specific matrix for
 	non-4:2:0 YUV formats.
     * - __u8
       - ``non_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for non-intra-coded frames, in
+      - The quantisation matrix coefficients for non-intra-coded frames, in
 	zigzag scanning order. It is relevant for both luma and chroma
 	components, although it can be superseded by the chroma-specific matrix
 	for non-4:2:0 YUV formats.
     * - __u8
       - ``chroma_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for the chominance component of
+      - The quantisation matrix coefficients for the chominance component of
 	intra-coded frames, in zigzag scanning order. Only relevant for
 	non-4:2:0 YUV formats.
     * - __u8
       - ``chroma_non_intra_quantiser_matrix[64]``
-      - The quantization matrix coefficients for the chrominance component of
+      - The quantisation matrix coefficients for the chrominance component of
 	non-intra-coded frames, in zigzag scanning order. Only relevant for
 	non-4:2:0 YUV formats.
 
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index 6dba70da822b..cba607f789f0 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -115,8 +115,8 @@ Compressed Formats
 	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
 	Metadata associated with the frame to decode is required to be passed
 	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
-	quantization matrices can optionally be specified through the
-	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control.
+	quantisation matrices can optionally be specified through the
+	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control.
 	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
 	Exactly one output and one capture buffer must be provided for use with
 	this pixel format. The output buffer must contain the appropriate number
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index 8a285daedc6a..4362945fd39b 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -423,12 +423,12 @@ See also the examples in :ref:`control`.
       - n/a
       - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2
 	slice parameters for stateless video decoders.
-    * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION``
+    * - ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``
       - n/a
       - n/a
       - n/a
-      - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
-	quantization matrices for stateless video decoders.
+      - A struct :c:type:`v4l2_ctrl_mpeg2_quantisation`, containing MPEG-2
+	quantisation matrices for stateless video decoders.
     * - ``V4L2_CTRL_TYPE_AREA``
       - n/a
       - n/a
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index afb1552b2d39..d14a807e8f9e 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -135,7 +135,7 @@ replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 39038c6ad8fb..74f5ca1a5f6c 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -962,7 +962,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:		return "Force Key Frame";
 	case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID:		return "Base Layer Priority ID";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:		return "MPEG-2 Slice Parameters";
-	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:		return "MPEG-2 Quantization Matrices";
+	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
 	case V4L2_CID_FWHT_I_FRAME_QP:				return "FWHT I-Frame QP Value";
 	case V4L2_CID_FWHT_P_FRAME_QP:				return "FWHT P-Frame QP Value";
 
@@ -1460,8 +1460,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:
 		*type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS;
 		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:
-		*type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION;
+	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:
+		*type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION;
 		break;
 	case V4L2_CID_STATELESS_FWHT_PARAMS:
 		*type = V4L2_CTRL_TYPE_FWHT_PARAMS;
@@ -1899,7 +1899,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 
 		break;
 
-	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
+	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
 		break;
 
 	case V4L2_CTRL_TYPE_FWHT_PARAMS:
@@ -2804,8 +2804,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
 		elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params);
 		break;
-	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
-		elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization);
+	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
+		elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation);
 		break;
 	case V4L2_CTRL_TYPE_FWHT_PARAMS:
 		elem_size = sizeof(struct v4l2_ctrl_fwht_params);
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 595e82a82728..9e3552cd5cf8 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -294,7 +294,7 @@ static const struct hantro_ctrl controls[] = {
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
+			.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION,
 		},
 	}, {
 		.codec = HANTRO_VP8_DECODER,
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index 6386a3989bfe..dedb5c502ae0 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -82,17 +82,14 @@
 #define PICT_FRAME         3
 
 static void
-hantro_g1_mpeg2_dec_set_quantization(struct hantro_dev *vpu,
+hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 				     struct hantro_ctx *ctx)
 {
-	struct v4l2_ctrl_mpeg2_quantization *quantization;
-
-	quantization = hantro_get_ctrl(ctx,
-				       V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
-	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu,
-				     quantization);
-	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma,
-			   G1_REG_QTABLE_BASE);
+	struct v4l2_ctrl_mpeg2_quantisation *q;
+
+	q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
+	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q);
+	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, G1_REG_QTABLE_BASE);
 }
 
 static void
@@ -238,7 +235,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	reg = G1_REG_APF_THRESHOLD(8);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(55));
 
-	hantro_g1_mpeg2_dec_set_quantization(vpu, ctx);
+	hantro_g1_mpeg2_dec_set_quantisation(vpu, ctx);
 
 	hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					&dst_buf->vb2_buf,
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 13a6e7113001..e446fd102e4f 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -207,7 +207,7 @@ hantro_h264_mv_size(unsigned int width, unsigned int height)
 void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
 void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx);
 void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
-	const struct v4l2_ctrl_mpeg2_quantization *ctrl);
+	const struct v4l2_ctrl_mpeg2_quantisation *ctrl);
 int hantro_mpeg2_dec_init(struct hantro_ctx *ctx);
 void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx);
 
diff --git a/drivers/staging/media/hantro/hantro_mpeg2.c b/drivers/staging/media/hantro/hantro_mpeg2.c
index 1d334e6fcd06..bc77401b02a5 100644
--- a/drivers/staging/media/hantro/hantro_mpeg2.c
+++ b/drivers/staging/media/hantro/hantro_mpeg2.c
@@ -19,7 +19,7 @@ static const u8 zigzag[64] = {
 };
 
 void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
-	const struct v4l2_ctrl_mpeg2_quantization *ctrl)
+	const struct v4l2_ctrl_mpeg2_quantisation *ctrl)
 {
 	int i, n;
 
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index f610fa5b4335..61a54549774d 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -84,16 +84,14 @@
 #define PICT_FRAME         3
 
 static void
-rk3399_vpu_mpeg2_dec_set_quantization(struct hantro_dev *vpu,
+rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 				      struct hantro_ctx *ctx)
 {
-	struct v4l2_ctrl_mpeg2_quantization *quantization;
+	struct v4l2_ctrl_mpeg2_quantisation *q;
 
-	quantization = hantro_get_ctrl(ctx,
-				       V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
-	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, quantization);
-	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma,
-			   VDPU_REG_QTABLE_BASE);
+	q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
+	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q);
+	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, VDPU_REG_QTABLE_BASE);
 }
 
 static void
@@ -243,7 +241,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	      VDPU_REG_MV_ACCURACY_BWD(1);
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136));
 
-	rk3399_vpu_mpeg2_dec_set_quantization(vpu, ctx);
+	rk3399_vpu_mpeg2_dec_set_quantisation(vpu, ctx);
 
 	rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					 &dst_buf->vb2_buf,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 92812d1a39d4..62a5407664ae 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -37,7 +37,7 @@ static const struct cedrus_control cedrus_controls[] = {
 	},
 	{
 		.cfg = {
-			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
+			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION,
 		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 	},
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 15f147dad4cb..6516bff3d319 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -69,7 +69,7 @@ struct cedrus_h264_run {
 
 struct cedrus_mpeg2_run {
 	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
-	const struct v4l2_ctrl_mpeg2_quantization	*quantization;
+	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
 };
 
 struct cedrus_h265_run {
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index d696b3ec70c0..238f779d2ba4 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -42,8 +42,8 @@ void cedrus_device_run(void *priv)
 	case V4L2_PIX_FMT_MPEG2_SLICE:
 		run.mpeg2.slice_params = cedrus_find_control_data(ctx,
 			V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
-		run.mpeg2.quantization = cedrus_find_control_data(ctx,
-			V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
+		run.mpeg2.quantisation = cedrus_find_control_data(ctx,
+			V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
 		break;
 
 	case V4L2_PIX_FMT_H264_SLICE:
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index 8bcd6b8f9e2d..459f71679a4f 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -13,9 +13,9 @@
 #include "cedrus_hw.h"
 #include "cedrus_regs.h"
 
-/* Default MPEG-2 quantization coefficients, from the specification. */
+/* Default MPEG-2 quantisation coefficients, from the specification. */
 
-static const u8 intra_quantization_matrix_default[64] = {
+static const u8 intra_quantisation_matrix_default[64] = {
 	8,  16, 16, 19, 16, 19, 22, 22,
 	22, 22, 22, 22, 26, 24, 26, 27,
 	27, 27, 26, 26, 26, 26, 27, 27,
@@ -26,7 +26,7 @@ static const u8 intra_quantization_matrix_default[64] = {
 	46, 46, 56, 56, 58, 69, 69, 83
 };
 
-static const u8 non_intra_quantization_matrix_default[64] = {
+static const u8 non_intra_quantisation_matrix_default[64] = {
 	16, 16, 16, 16, 16, 16, 16, 16,
 	16, 16, 16, 16, 16, 16, 16, 16,
 	16, 16, 16, 16, 16, 16, 16, 16,
@@ -77,7 +77,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
 	const struct v4l2_mpeg2_sequence *sequence;
 	const struct v4l2_mpeg2_picture *picture;
-	const struct v4l2_ctrl_mpeg2_quantization *quantization;
+	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
 	dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
 	dma_addr_t fwd_luma_addr, fwd_chroma_addr;
 	dma_addr_t bwd_luma_addr, bwd_chroma_addr;
@@ -93,17 +93,17 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	sequence = &slice_params->sequence;
 	picture = &slice_params->picture;
 
-	quantization = run->mpeg2.quantization;
+	quantisation = run->mpeg2.quantisation;
 
 	/* Activate MPEG engine. */
 	cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2);
 
-	/* Set intra quantization matrix. */
+	/* Set intra quantisation matrix. */
 
-	if (quantization && quantization->load_intra_quantiser_matrix)
-		matrix = quantization->intra_quantiser_matrix;
+	if (quantisation && quantisation->load_intra_quantiser_matrix)
+		matrix = quantisation->intra_quantiser_matrix;
 	else
-		matrix = intra_quantization_matrix_default;
+		matrix = intra_quantisation_matrix_default;
 
 	for (i = 0; i < 64; i++) {
 		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
@@ -112,12 +112,12 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 		cedrus_write(dev, VE_DEC_MPEG_IQMINPUT, reg);
 	}
 
-	/* Set non-intra quantization matrix. */
+	/* Set non-intra quantisation matrix. */
 
-	if (quantization && quantization->load_non_intra_quantiser_matrix)
-		matrix = quantization->non_intra_quantiser_matrix;
+	if (quantisation && quantisation->load_non_intra_quantiser_matrix)
+		matrix = quantisation->non_intra_quantiser_matrix;
 	else
-		matrix = non_intra_quantization_matrix_default;
+		matrix = non_intra_quantisation_matrix_default;
 
 	for (i = 0; i < 64; i++) {
 		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index 2a4ae6701166..b8adf3ac2c1d 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -12,11 +12,11 @@
 #define _MPEG2_CTRLS_H_
 
 #define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS		(V4L2_CID_CODEC_BASE+250)
-#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION		(V4L2_CID_CODEC_BASE+251)
+#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION		(V4L2_CID_CODEC_BASE+251)
 
 /* enum v4l2_ctrl_type type values */
 #define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
-#define	V4L2_CTRL_TYPE_MPEG2_QUANTIZATION 0x0104
+#define	V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104
 
 #define V4L2_MPEG2_PICTURE_CODING_TYPE_I	1
 #define V4L2_MPEG2_PICTURE_CODING_TYPE_P	2
@@ -66,7 +66,7 @@ struct v4l2_ctrl_mpeg2_slice_params {
 	__u32	quantiser_scale_code;
 };
 
-struct v4l2_ctrl_mpeg2_quantization {
+struct v4l2_ctrl_mpeg2_quantisation {
 	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
 	__u8	load_intra_quantiser_matrix;
 	__u8	load_non_intra_quantiser_matrix;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index dea65c92e86b..a560005c575a 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -41,7 +41,7 @@ struct video_device;
  * @p_u32:			Pointer to a 32-bit unsigned value.
  * @p_char:			Pointer to a string.
  * @p_mpeg2_slice_params:	Pointer to a MPEG2 slice parameters structure.
- * @p_mpeg2_quantization:	Pointer to a MPEG2 quantization data structure.
+ * @p_mpeg2_quantisation:	Pointer to a MPEG2 quantisation data structure.
  * @p_fwht_params:		Pointer to a FWHT stateless parameters structure.
  * @p_h264_sps:			Pointer to a struct v4l2_ctrl_h264_sps.
  * @p_h264_pps:			Pointer to a struct v4l2_ctrl_h264_pps.
@@ -65,7 +65,7 @@ union v4l2_ctrl_ptr {
 	u32 *p_u32;
 	char *p_char;
 	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
-	struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
+	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	struct v4l2_ctrl_h264_sps *p_h264_sps;
 	struct v4l2_ctrl_h264_pps *p_h264_pps;
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 01/10] media: uapi: mpeg2: Rename "quantization" to "quantisation" Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-06 10:25   ` Hans Verkuil
  2021-04-03 18:07 ` [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags Ezequiel Garcia
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

As stated in the MPEG-2 specification, section 6.3.7 "Quant matrix
extension":

  Each quantisation matrix has a default set of values. When a
  sequence_header_code is decoded all matrices shall be reset to
  their default values. User defined matrices may be downloaded
  and this can occur in a sequence_header() or in a
  quant_matrix_extension().

The load_intra_quantiser_matrix syntax elements are transmitted
in the bistream headers, signalling that a quantisation matrix
needs to be loaded and used for pictures transmitted afterwards
(until the matrices are reset).

This "load" semantics are implemented in the V4L2 interface
without the need of any "load" flags: passing the control
is effectively a load.

Therefore, rework the V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION
semantics to match the MPEG-2 semantics. Quantisation matrices
values are now initialized by the V4L2 control core to their
reset default value, and applications are expected to reset
their values as specified.

The quantisation control is therefore optional, and used to
load bitstream-defined values in the quantisation matrices.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Co-developed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             | 17 ---------
 drivers/media/v4l2-core/v4l2-ctrls.c          | 21 ++++++++++
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 38 +------------------
 include/media/mpeg2-ctrls.h                   |  5 ---
 4 files changed, 23 insertions(+), 58 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 151d1c676b6e..d9546f0aa2e8 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1746,23 +1746,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     :stub-columns: 0
     :widths:       1 1 2
 
-    * - __u8
-      - ``load_intra_quantiser_matrix``
-      - One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
-    * - __u8
-      - ``load_non_intra_quantiser_matrix``
-      - One bit to indicate whether to load the ``non_intra_quantiser_matrix``
-	data.
-    * - __u8
-      - ``load_chroma_intra_quantiser_matrix``
-      - One bit to indicate whether to load the
-	``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
-	formats.
-    * - __u8
-      - ``load_chroma_non_intra_quantiser_matrix``
-      - One bit to indicate whether to load the
-	``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
-	YUV formats.
     * - __u8
       - ``intra_quantiser_matrix[64]``
       - The quantisation matrix coefficients for intra-coded frames, in zigzag
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 74f5ca1a5f6c..5d92a2b33a6e 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -57,6 +57,18 @@ static bool is_new_manual(const struct v4l2_ctrl *master)
 	return master->is_auto && master->val == master->manual_mode_value;
 }
 
+/* Default MPEG-2 quantisation coefficients, from the specification. */
+static const u8 mpeg2_intra_quant_matrix[64] = {
+	8,  16, 16, 19, 16, 19, 22, 22,
+	22, 22, 22, 22, 26, 24, 26, 27,
+	27, 27, 26, 26, 26, 26, 27, 27,
+	27, 29, 29, 29, 34, 34, 34, 29,
+	29, 29, 27, 27, 29, 29, 32, 32,
+	34, 34, 37, 38, 37, 35, 35, 34,
+	35, 38, 38, 40, 40, 40, 48, 48,
+	46, 46, 56, 56, 58, 69, 69, 83
+};
+
 /* Returns NULL or a character pointer array containing the menu for
    the given control ID. The pointer array ends with a NULL pointer.
    An empty string signifies a menu entry that is invalid. This allows
@@ -1656,6 +1668,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 			      union v4l2_ctrl_ptr ptr)
 {
 	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
+	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	void *p = ptr.p + idx * ctrl->elem_size;
@@ -1680,6 +1693,14 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		p_mpeg2_slice_params->picture.picture_coding_type =
 					V4L2_MPEG2_PICTURE_CODING_TYPE_I;
 		break;
+	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
+		p_mpeg2_quant = p;
+
+		memcpy(p_mpeg2_quant->intra_quantiser_matrix,
+		       mpeg2_intra_quant_matrix,
+		       ARRAY_SIZE(mpeg2_intra_quant_matrix));
+		memset(p_mpeg2_quant->non_intra_quantiser_matrix, 16, 64);
+		break;
 	case V4L2_CTRL_TYPE_VP8_FRAME:
 		p_vp8_frame = p;
 		p_vp8_frame->num_dct_parts = 1;
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index 459f71679a4f..e3154f631858 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -13,30 +13,6 @@
 #include "cedrus_hw.h"
 #include "cedrus_regs.h"
 
-/* Default MPEG-2 quantisation coefficients, from the specification. */
-
-static const u8 intra_quantisation_matrix_default[64] = {
-	8,  16, 16, 19, 16, 19, 22, 22,
-	22, 22, 22, 22, 26, 24, 26, 27,
-	27, 27, 26, 26, 26, 26, 27, 27,
-	27, 29, 29, 29, 34, 34, 34, 29,
-	29, 29, 27, 27, 29, 29, 32, 32,
-	34, 34, 37, 38, 37, 35, 35, 34,
-	35, 38, 38, 40, 40, 40, 48, 48,
-	46, 46, 56, 56, 58, 69, 69, 83
-};
-
-static const u8 non_intra_quantisation_matrix_default[64] = {
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16,
-	16, 16, 16, 16, 16, 16, 16, 16
-};
-
 static enum cedrus_irq_status cedrus_mpeg2_irq_status(struct cedrus_ctx *ctx)
 {
 	struct cedrus_dev *dev = ctx->dev;
@@ -99,12 +75,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2);
 
 	/* Set intra quantisation matrix. */
-
-	if (quantisation && quantisation->load_intra_quantiser_matrix)
-		matrix = quantisation->intra_quantiser_matrix;
-	else
-		matrix = intra_quantisation_matrix_default;
-
+	matrix = quantisation->intra_quantiser_matrix;
 	for (i = 0; i < 64; i++) {
 		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
 		reg |= VE_DEC_MPEG_IQMINPUT_FLAG_INTRA;
@@ -113,12 +84,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	}
 
 	/* Set non-intra quantisation matrix. */
-
-	if (quantisation && quantisation->load_non_intra_quantiser_matrix)
-		matrix = quantisation->non_intra_quantiser_matrix;
-	else
-		matrix = non_intra_quantisation_matrix_default;
-
+	matrix = quantisation->non_intra_quantiser_matrix;
 	for (i = 0; i < 64; i++) {
 		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
 		reg |= VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA;
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index b8adf3ac2c1d..8ea2c7f3a172 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -68,11 +68,6 @@ struct v4l2_ctrl_mpeg2_slice_params {
 
 struct v4l2_ctrl_mpeg2_quantisation {
 	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
-	__u8	load_intra_quantiser_matrix;
-	__u8	load_non_intra_quantiser_matrix;
-	__u8	load_chroma_intra_quantiser_matrix;
-	__u8	load_chroma_non_intra_quantiser_matrix;
-
 	__u8	intra_quantiser_matrix[64];
 	__u8	non_intra_quantiser_matrix[64];
 	__u8	chroma_intra_quantiser_matrix[64];
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 01/10] media: uapi: mpeg2: Rename "quantization" to "quantisation" Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-06 10:27   ` Hans Verkuil
  2021-04-03 18:07 ` [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters Ezequiel Garcia
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Our current MPEG-2 uAPI uses 1-byte fields for MPEG-2
boolean syntax elements. Clean these by adding a 'flags'
field and flag macro for each boolean syntax element.

A follow-up change will refactor this uAPI so we don't need
to add padding fields just yet.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Jonas Karlman <jonas@kwiboo.se>
---
 .../media/v4l/ext-ctrls-codec.rst             |  77 +-
 drivers/media/v4l2-core/v4l2-async-core.c     | 880 ++++++++++++++++++
 drivers/media/v4l2-core/v4l2-ctrls.c          |  14 +-
 .../media/hantro/hantro_g1_mpeg2_dec.c        |  76 +-
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |  76 +-
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  38 +-
 include/media/mpeg2-ctrls.h                   |  36 +-
 7 files changed, 1055 insertions(+), 142 deletions(-)
 create mode 100644 drivers/media/v4l2-core/v4l2-async-core.c

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index d9546f0aa2e8..7d5ac7fb6579 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1654,13 +1654,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
       - ``profile_and_level_indication``
       - The current profile and level indication as extracted from the
 	bitstream.
-    * - __u8
-      - ``progressive_sequence``
-      - Indication that all the frames for the sequence are progressive instead
-	of interlaced.
     * - __u8
       - ``chroma_format``
       - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
+    * - __u32
+      - ``flags``
+      - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
+
+.. _mpeg2_sequence_flags:
+
+``MPEG-2 Sequence Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE``
+      - 0x00000001
+      - Indication that all the frames for the sequence are progressive instead
+	of interlaced.
 
 .. c:type:: v4l2_mpeg2_picture
 
@@ -1693,29 +1708,45 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
       - ``picture_structure``
       - Picture structure (1: interlaced top field, 2: interlaced bottom field,
 	3: progressive frame).
-    * - __u8
-      - ``top_field_first``
-      - If set to 1 and interlaced stream, top field is output first.
-    * - __u8
-      - ``frame_pred_frame_dct``
-      - If set to 1, only frame-DCT and frame prediction are used.
-    * - __u8
-      - ``concealment_motion_vectors``
-      -  If set to 1, motion vectors are coded for intra macroblocks.
-    * - __u8
-      - ``q_scale_type``
+    * - __u32
+      - ``flags``
+      - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
+
+
+.. _mpeg2_picture_flags:
+
+``MPEG-2 Picture Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST``
+      - 0x00000001
+      - If set and it's an interlaced stream, top field is output first.
+    * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT``
+      - 0x00000002
+      - If set only frame-DCT and frame prediction are used.
+    * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV``
+      - 0x00000004
+      -  If set motion vectors are coded for intra macroblocks.
+    * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE``
+      - 0x00000008
       - This flag affects the inverse quantization process.
-    * - __u8
-      - ``intra_vlc_format``
+    * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC``
+      - 0x00000010
       - This flag affects the decoding of transform coefficient data.
-    * - __u8
-      - ``alternate_scan``
+    * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN``
+      - 0x00000020
       - This flag affects the decoding of transform coefficient data.
-    * - __u8
-      - ``repeat_first_field``
+    * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST``
+      - 0x00000040
       - This flag affects the decoding process of progressive frames.
-    * - __u16
-      - ``progressive_frame``
+    * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE``
+      - 0x00000080
       - Indicates whether the current frame is progressive.
 
 .. raw:: latex
diff --git a/drivers/media/v4l2-core/v4l2-async-core.c b/drivers/media/v4l2-core/v4l2-async-core.c
new file mode 100644
index 000000000000..cd9e78c63791
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-async-core.c
@@ -0,0 +1,880 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+					  struct v4l2_subdev *subdev,
+					  struct v4l2_async_subdev *asd)
+{
+	if (!n->ops || !n->ops->bound)
+		return 0;
+
+	return n->ops->bound(n, subdev, asd);
+}
+
+static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+					    struct v4l2_subdev *subdev,
+					    struct v4l2_async_subdev *asd)
+{
+	if (!n->ops || !n->ops->unbind)
+		return;
+
+	n->ops->unbind(n, subdev, asd);
+}
+
+static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
+{
+	if (!n->ops || !n->ops->complete)
+		return 0;
+
+	return n->ops->complete(n);
+}
+
+static bool match_i2c(struct v4l2_async_notifier *notifier,
+		      struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+{
+#if IS_ENABLED(CONFIG_I2C)
+	struct i2c_client *client = i2c_verify_client(sd->dev);
+
+	return client &&
+		asd->match.i2c.adapter_id == client->adapter->nr &&
+		asd->match.i2c.address == client->addr;
+#else
+	return false;
+#endif
+}
+
+static bool match_fwnode(struct v4l2_async_notifier *notifier,
+			 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
+{
+	struct fwnode_handle *other_fwnode;
+	struct fwnode_handle *dev_fwnode;
+	bool asd_fwnode_is_ep;
+	bool sd_fwnode_is_ep;
+	struct device *dev;
+
+	/*
+	 * Both the subdev and the async subdev can provide either an endpoint
+	 * fwnode or a device fwnode. Start with the simple case of direct
+	 * fwnode matching.
+	 */
+	if (sd->fwnode == asd->match.fwnode)
+		return true;
+
+	/*
+	 * Check the same situation for any possible secondary assigned to the
+	 * subdev's fwnode
+	 */
+	if (!IS_ERR_OR_NULL(sd->fwnode->secondary) &&
+	    sd->fwnode->secondary == asd->match.fwnode)
+		return true;
+
+	/*
+	 * Otherwise, check if the sd fwnode and the asd fwnode refer to an
+	 * endpoint or a device. If they're of the same type, there's no match.
+	 * Technically speaking this checks if the nodes refer to a connected
+	 * endpoint, which is the simplest check that works for both OF and
+	 * ACPI. This won't make a difference, as drivers should not try to
+	 * match unconnected endpoints.
+	 */
+	sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode);
+	asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode);
+
+	if (sd_fwnode_is_ep == asd_fwnode_is_ep)
+		return false;
+
+	/*
+	 * The sd and asd fwnodes are of different types. Get the device fwnode
+	 * parent of the endpoint fwnode, and compare it with the other fwnode.
+	 */
+	if (sd_fwnode_is_ep) {
+		dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode);
+		other_fwnode = asd->match.fwnode;
+	} else {
+		dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode);
+		other_fwnode = sd->fwnode;
+	}
+
+	fwnode_handle_put(dev_fwnode);
+
+	if (dev_fwnode != other_fwnode)
+		return false;
+
+	/*
+	 * We have a heterogeneous match. Retrieve the struct device of the side
+	 * that matched on a device fwnode to print its driver name.
+	 */
+	if (sd_fwnode_is_ep)
+		dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev
+		    : notifier->sd->dev;
+	else
+		dev = sd->dev;
+
+	if (dev && dev->driver) {
+		if (sd_fwnode_is_ep)
+			dev_warn(dev, "Driver %s uses device fwnode, incorrect match may occur\n",
+				 dev->driver->name);
+		dev_notice(dev, "Consider updating driver %s to match on endpoints\n",
+			   dev->driver->name);
+	}
+
+	return true;
+}
+
+static LIST_HEAD(subdev_list);
+static LIST_HEAD(notifier_list);
+static DEFINE_MUTEX(list_lock);
+
+static struct v4l2_async_subdev *
+v4l2_async_find_match(struct v4l2_async_notifier *notifier,
+		      struct v4l2_subdev *sd)
+{
+	bool (*match)(struct v4l2_async_notifier *notifier,
+		      struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);
+	struct v4l2_async_subdev *asd;
+
+	list_for_each_entry(asd, &notifier->waiting, list) {
+		/* bus_type has been verified valid before */
+		switch (asd->match_type) {
+		case V4L2_ASYNC_MATCH_I2C:
+			match = match_i2c;
+			break;
+		case V4L2_ASYNC_MATCH_FWNODE:
+			match = match_fwnode;
+			break;
+		default:
+			/* Cannot happen, unless someone breaks us */
+			WARN_ON(true);
+			return NULL;
+		}
+
+		/* match cannot be NULL here */
+		if (match(notifier, sd, asd))
+			return asd;
+	}
+
+	return NULL;
+}
+
+/* Compare two async sub-device descriptors for equivalence */
+static bool asd_equal(struct v4l2_async_subdev *asd_x,
+		      struct v4l2_async_subdev *asd_y)
+{
+	if (asd_x->match_type != asd_y->match_type)
+		return false;
+
+	switch (asd_x->match_type) {
+	case V4L2_ASYNC_MATCH_I2C:
+		return asd_x->match.i2c.adapter_id ==
+			asd_y->match.i2c.adapter_id &&
+			asd_x->match.i2c.address ==
+			asd_y->match.i2c.address;
+	case V4L2_ASYNC_MATCH_FWNODE:
+		return asd_x->match.fwnode == asd_y->match.fwnode;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+/* Find the sub-device notifier registered by a sub-device driver. */
+static struct v4l2_async_notifier *
+v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_notifier *n;
+
+	list_for_each_entry(n, &notifier_list, list)
+		if (n->sd == sd)
+			return n;
+
+	return NULL;
+}
+
+/* Get v4l2_device related to the notifier if one can be found. */
+static struct v4l2_device *
+v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
+{
+	while (notifier->parent)
+		notifier = notifier->parent;
+
+	return notifier->v4l2_dev;
+}
+
+/*
+ * Return true if all child sub-device notifiers are complete, false otherwise.
+ */
+static bool
+v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_subdev *sd;
+
+	if (!list_empty(&notifier->waiting))
+		return false;
+
+	list_for_each_entry(sd, &notifier->done, async_list) {
+		struct v4l2_async_notifier *subdev_notifier =
+			v4l2_async_find_subdev_notifier(sd);
+
+		if (subdev_notifier &&
+		    !v4l2_async_notifier_can_complete(subdev_notifier))
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * Complete the master notifier if possible. This is done when all async
+ * sub-devices have been bound; v4l2_device is also available then.
+ */
+static int
+v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
+{
+	/* Quick check whether there are still more sub-devices here. */
+	if (!list_empty(&notifier->waiting))
+		return 0;
+
+	/* Check the entire notifier tree; find the root notifier first. */
+	while (notifier->parent)
+		notifier = notifier->parent;
+
+	/* This is root if it has v4l2_dev. */
+	if (!notifier->v4l2_dev)
+		return 0;
+
+	/* Is everything ready? */
+	if (!v4l2_async_notifier_can_complete(notifier))
+		return 0;
+
+	return v4l2_async_notifier_call_complete(notifier);
+}
+
+static int
+v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier);
+
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+				   struct v4l2_device *v4l2_dev,
+				   struct v4l2_subdev *sd,
+				   struct v4l2_async_subdev *asd)
+{
+	struct v4l2_async_notifier *subdev_notifier;
+	int ret;
+
+	ret = v4l2_device_register_subdev(v4l2_dev, sd);
+	if (ret < 0)
+		return ret;
+
+	ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
+	if (ret < 0) {
+		v4l2_device_unregister_subdev(sd);
+		return ret;
+	}
+
+	/* Remove from the waiting list */
+	list_del(&asd->list);
+	sd->asd = asd;
+	sd->notifier = notifier;
+
+	/* Move from the global subdevice list to notifier's done */
+	list_move(&sd->async_list, &notifier->done);
+
+	/*
+	 * See if the sub-device has a notifier. If not, return here.
+	 */
+	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+	if (!subdev_notifier || subdev_notifier->parent)
+		return 0;
+
+	/*
+	 * Proceed with checking for the sub-device notifier's async
+	 * sub-devices, and return the result. The error will be handled by the
+	 * caller.
+	 */
+	subdev_notifier->parent = notifier;
+
+	return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
+}
+
+/* Test all async sub-devices in a notifier for a match. */
+static int
+v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_device *v4l2_dev =
+		v4l2_async_notifier_find_v4l2_dev(notifier);
+	struct v4l2_subdev *sd;
+
+	if (!v4l2_dev)
+		return 0;
+
+again:
+	list_for_each_entry(sd, &subdev_list, async_list) {
+		struct v4l2_async_subdev *asd;
+		int ret;
+
+		asd = v4l2_async_find_match(notifier, sd);
+		if (!asd)
+			continue;
+
+		ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * v4l2_async_match_notify() may lead to registering a
+		 * new notifier and thus changing the async subdevs
+		 * list. In order to proceed safely from here, restart
+		 * parsing the list from the beginning.
+		 */
+		goto again;
+	}
+
+	return 0;
+}
+
+static void v4l2_async_cleanup(struct v4l2_subdev *sd)
+{
+	v4l2_device_unregister_subdev(sd);
+	/*
+	 * Subdevice driver will reprobe and put the subdev back
+	 * onto the list
+	 */
+	list_del_init(&sd->async_list);
+	sd->asd = NULL;
+}
+
+/* Unbind all sub-devices in the notifier tree. */
+static void
+v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_subdev *sd, *tmp;
+
+	list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
+		struct v4l2_async_notifier *subdev_notifier =
+			v4l2_async_find_subdev_notifier(sd);
+
+		if (subdev_notifier)
+			v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
+
+		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+		v4l2_async_cleanup(sd);
+
+		list_move(&sd->async_list, &subdev_list);
+	}
+
+	notifier->parent = NULL;
+}
+
+/* See if an async sub-device can be found in a notifier's lists. */
+static bool
+__v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+				       struct v4l2_async_subdev *asd)
+{
+	struct v4l2_async_subdev *asd_y;
+	struct v4l2_subdev *sd;
+
+	list_for_each_entry(asd_y, &notifier->waiting, list)
+		if (asd_equal(asd, asd_y))
+			return true;
+
+	list_for_each_entry(sd, &notifier->done, async_list) {
+		if (WARN_ON(!sd->asd))
+			continue;
+
+		if (asd_equal(asd, sd->asd))
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * Find out whether an async sub-device was set up already or
+ * whether it exists in a given notifier before @this_index.
+ * If @this_index < 0, search the notifier's entire @asd_list.
+ */
+static bool
+v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+				     struct v4l2_async_subdev *asd,
+				     int this_index)
+{
+	struct v4l2_async_subdev *asd_y;
+	int j = 0;
+
+	lockdep_assert_held(&list_lock);
+
+	/* Check that an asd is not being added more than once. */
+	list_for_each_entry(asd_y, &notifier->asd_list, asd_list) {
+		if (this_index >= 0 && j++ >= this_index)
+			break;
+		if (asd_equal(asd, asd_y))
+			return true;
+	}
+
+	/* Check that an asd does not exist in other notifiers. */
+	list_for_each_entry(notifier, &notifier_list, list)
+		if (__v4l2_async_notifier_has_async_subdev(notifier, asd))
+			return true;
+
+	return false;
+}
+
+static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
+					 struct v4l2_async_subdev *asd,
+					 int this_index)
+{
+	struct device *dev =
+		notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
+
+	if (!asd)
+		return -EINVAL;
+
+	switch (asd->match_type) {
+	case V4L2_ASYNC_MATCH_I2C:
+	case V4L2_ASYNC_MATCH_FWNODE:
+		if (v4l2_async_notifier_has_async_subdev(notifier, asd,
+							 this_index)) {
+			dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n");
+			return -EEXIST;
+		}
+		break;
+	default:
+		dev_err(dev, "Invalid match type %u on %p\n",
+			asd->match_type, asd);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier)
+{
+	INIT_LIST_HEAD(&notifier->asd_list);
+}
+EXPORT_SYMBOL(v4l2_async_notifier_init);
+
+static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev *asd;
+	int ret, i = 0;
+
+	INIT_LIST_HEAD(&notifier->waiting);
+	INIT_LIST_HEAD(&notifier->done);
+
+	mutex_lock(&list_lock);
+
+	list_for_each_entry(asd, &notifier->asd_list, asd_list) {
+		ret = v4l2_async_notifier_asd_valid(notifier, asd, i++);
+		if (ret)
+			goto err_unlock;
+
+		list_add_tail(&asd->list, &notifier->waiting);
+	}
+
+	ret = v4l2_async_notifier_try_all_subdevs(notifier);
+	if (ret < 0)
+		goto err_unbind;
+
+	ret = v4l2_async_notifier_try_complete(notifier);
+	if (ret < 0)
+		goto err_unbind;
+
+	/* Keep also completed notifiers on the list */
+	list_add(&notifier->list, &notifier_list);
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+
+err_unbind:
+	/*
+	 * On failure, unbind all sub-devices registered through this notifier.
+	 */
+	v4l2_async_notifier_unbind_all_subdevs(notifier);
+
+err_unlock:
+	mutex_unlock(&list_lock);
+
+	return ret;
+}
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+				 struct v4l2_async_notifier *notifier)
+{
+	int ret;
+
+	if (WARN_ON(!v4l2_dev || notifier->sd))
+		return -EINVAL;
+
+	notifier->v4l2_dev = v4l2_dev;
+
+	ret = __v4l2_async_notifier_register(notifier);
+	if (ret)
+		notifier->v4l2_dev = NULL;
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_async_notifier_register);
+
+int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+					struct v4l2_async_notifier *notifier)
+{
+	int ret;
+
+	if (WARN_ON(!sd || notifier->v4l2_dev))
+		return -EINVAL;
+
+	notifier->sd = sd;
+
+	ret = __v4l2_async_notifier_register(notifier);
+	if (ret)
+		notifier->sd = NULL;
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
+
+static void
+__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+	if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
+		return;
+
+	v4l2_async_notifier_unbind_all_subdevs(notifier);
+
+	notifier->sd = NULL;
+	notifier->v4l2_dev = NULL;
+
+	list_del(&notifier->list);
+}
+
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+	mutex_lock(&list_lock);
+
+	__v4l2_async_notifier_unregister(notifier);
+
+	mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+
+static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev *asd, *tmp;
+
+	if (!notifier || !notifier->asd_list.next)
+		return;
+
+	list_for_each_entry_safe(asd, tmp, &notifier->asd_list, asd_list) {
+		switch (asd->match_type) {
+		case V4L2_ASYNC_MATCH_FWNODE:
+			fwnode_handle_put(asd->match.fwnode);
+			break;
+		default:
+			break;
+		}
+
+		list_del(&asd->asd_list);
+		kfree(asd);
+	}
+}
+
+void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+{
+	mutex_lock(&list_lock);
+
+	__v4l2_async_notifier_cleanup(notifier);
+
+	mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
+
+int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+				   struct v4l2_async_subdev *asd)
+{
+	int ret;
+
+	mutex_lock(&list_lock);
+
+	ret = v4l2_async_notifier_asd_valid(notifier, asd, -1);
+	if (ret)
+		goto unlock;
+
+	list_add_tail(&asd->asd_list, &notifier->asd_list);
+
+unlock:
+	mutex_unlock(&list_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
+
+struct v4l2_async_subdev *
+__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+					struct fwnode_handle *fwnode,
+					unsigned int asd_struct_size)
+{
+	struct v4l2_async_subdev *asd;
+	int ret;
+
+	asd = kzalloc(asd_struct_size, GFP_KERNEL);
+	if (!asd)
+		return ERR_PTR(-ENOMEM);
+
+	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+	asd->match.fwnode = fwnode_handle_get(fwnode);
+
+	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
+	if (ret) {
+		fwnode_handle_put(fwnode);
+		kfree(asd);
+		return ERR_PTR(ret);
+	}
+
+	return asd;
+}
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_subdev);
+
+struct v4l2_async_subdev *
+__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+					       struct fwnode_handle *endpoint,
+					       unsigned int asd_struct_size)
+{
+	struct v4l2_async_subdev *asd;
+	struct fwnode_handle *remote;
+
+	remote = fwnode_graph_get_remote_port_parent(endpoint);
+	if (!remote)
+		return ERR_PTR(-ENOTCONN);
+
+	asd = __v4l2_async_notifier_add_fwnode_subdev(notif, remote,
+						      asd_struct_size);
+	/*
+	 * Calling __v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
+	 * so drop the one we got in fwnode_graph_get_remote_port_parent.
+	 */
+	fwnode_handle_put(remote);
+	return asd;
+}
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_remote_subdev);
+
+struct v4l2_async_subdev *
+__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+				     int adapter_id, unsigned short address,
+				     unsigned int asd_struct_size)
+{
+	struct v4l2_async_subdev *asd;
+	int ret;
+
+	asd = kzalloc(asd_struct_size, GFP_KERNEL);
+	if (!asd)
+		return ERR_PTR(-ENOMEM);
+
+	asd->match_type = V4L2_ASYNC_MATCH_I2C;
+	asd->match.i2c.adapter_id = adapter_id;
+	asd->match.i2c.address = address;
+
+	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
+	if (ret) {
+		kfree(asd);
+		return ERR_PTR(ret);
+	}
+
+	return asd;
+}
+EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_i2c_subdev);
+
+int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_notifier *subdev_notifier;
+	struct v4l2_async_notifier *notifier;
+	int ret;
+
+	/*
+	 * No reference taken. The reference is held by the device
+	 * (struct v4l2_subdev.dev), and async sub-device does not
+	 * exist independently of the device at any point of time.
+	 */
+	if (!sd->fwnode && sd->dev)
+		sd->fwnode = dev_fwnode(sd->dev);
+
+	mutex_lock(&list_lock);
+
+	INIT_LIST_HEAD(&sd->async_list);
+
+	list_for_each_entry(notifier, &notifier_list, list) {
+		struct v4l2_device *v4l2_dev =
+			v4l2_async_notifier_find_v4l2_dev(notifier);
+		struct v4l2_async_subdev *asd;
+
+		if (!v4l2_dev)
+			continue;
+
+		asd = v4l2_async_find_match(notifier, sd);
+		if (!asd)
+			continue;
+
+		ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
+		if (ret)
+			goto err_unbind;
+
+		ret = v4l2_async_notifier_try_complete(notifier);
+		if (ret)
+			goto err_unbind;
+
+		goto out_unlock;
+	}
+
+	/* None matched, wait for hot-plugging */
+	list_add(&sd->async_list, &subdev_list);
+
+out_unlock:
+	mutex_unlock(&list_lock);
+
+	return 0;
+
+err_unbind:
+	/*
+	 * Complete failed. Unbind the sub-devices bound through registering
+	 * this async sub-device.
+	 */
+	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+	if (subdev_notifier)
+		v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
+
+	if (sd->asd)
+		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+	v4l2_async_cleanup(sd);
+
+	mutex_unlock(&list_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_async_register_subdev);
+
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+{
+	if (!sd->async_list.next)
+		return;
+
+	mutex_lock(&list_lock);
+
+	__v4l2_async_notifier_unregister(sd->subdev_notifier);
+	__v4l2_async_notifier_cleanup(sd->subdev_notifier);
+	kfree(sd->subdev_notifier);
+	sd->subdev_notifier = NULL;
+
+	if (sd->asd) {
+		struct v4l2_async_notifier *notifier = sd->notifier;
+
+		list_add(&sd->asd->list, &notifier->waiting);
+
+		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+	}
+
+	v4l2_async_cleanup(sd);
+
+	mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_unregister_subdev);
+
+static void print_waiting_subdev(struct seq_file *s,
+				 struct v4l2_async_subdev *asd)
+{
+	switch (asd->match_type) {
+	case V4L2_ASYNC_MATCH_I2C:
+		seq_printf(s, " [i2c] dev=%d-%04x\n", asd->match.i2c.adapter_id,
+			   asd->match.i2c.address);
+		break;
+	case V4L2_ASYNC_MATCH_FWNODE: {
+		struct fwnode_handle *devnode, *fwnode = asd->match.fwnode;
+
+		devnode = fwnode_graph_is_endpoint(fwnode) ?
+			  fwnode_graph_get_port_parent(fwnode) :
+			  fwnode_handle_get(fwnode);
+
+		seq_printf(s, " [fwnode] dev=%s, node=%pfw\n",
+			   devnode->dev ? dev_name(devnode->dev) : "nil",
+			   fwnode);
+
+		fwnode_handle_put(devnode);
+		break;
+	}
+	}
+}
+
+static const char *
+v4l2_async_notifier_name(struct v4l2_async_notifier *notifier)
+{
+	if (notifier->v4l2_dev)
+		return notifier->v4l2_dev->name;
+	else if (notifier->sd)
+		return notifier->sd->name;
+	else
+		return "nil";
+}
+
+static int pending_subdevs_show(struct seq_file *s, void *data)
+{
+	struct v4l2_async_notifier *notif;
+	struct v4l2_async_subdev *asd;
+
+	mutex_lock(&list_lock);
+
+	list_for_each_entry(notif, &notifier_list, list) {
+		seq_printf(s, "%s:\n", v4l2_async_notifier_name(notif));
+		list_for_each_entry(asd, &notif->waiting, list)
+			print_waiting_subdev(s, asd);
+	}
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(pending_subdevs);
+
+static struct dentry *v4l2_async_debugfs_dir;
+
+static int __init v4l2_async_init(void)
+{
+	v4l2_async_debugfs_dir = debugfs_create_dir("v4l2-async", NULL);
+	debugfs_create_file("pending_async_subdevices", 0444,
+			    v4l2_async_debugfs_dir, NULL,
+			    &pending_subdevs_fops);
+
+	return 0;
+}
+
+static void __exit v4l2_async_exit(void)
+{
+	debugfs_remove_recursive(v4l2_async_debugfs_dir);
+}
+
+subsys_initcall(v4l2_async_init);
+module_exit(v4l2_async_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
+MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 5d92a2b33a6e..99064683cfb5 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1691,7 +1691,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		/* interlaced top field */
 		p_mpeg2_slice_params->picture.picture_structure = 1;
 		p_mpeg2_slice_params->picture.picture_coding_type =
-					V4L2_MPEG2_PICTURE_CODING_TYPE_I;
+					V4L2_MPEG2_PIC_CODING_TYPE_I;
 		break;
 	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
 		p_mpeg2_quant = p;
@@ -1901,18 +1901,18 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		}
 
 		switch (p_mpeg2_slice_params->picture.picture_structure) {
-		case 1: /* interlaced top field */
-		case 2: /* interlaced bottom field */
-		case 3: /* progressive */
+		case V4L2_MPEG2_PIC_TOP_FIELD:
+		case V4L2_MPEG2_PIC_BOTTOM_FIELD:
+		case V4L2_MPEG2_PIC_FRAME:
 			break;
 		default:
 			return -EINVAL;
 		}
 
 		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+		case V4L2_MPEG2_PIC_CODING_TYPE_I:
+		case V4L2_MPEG2_PIC_CODING_TYPE_P:
+		case V4L2_MPEG2_PIC_CODING_TYPE_B:
 			break;
 		default:
 			return -EINVAL;
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index dedb5c502ae0..6ef7ded863b2 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -77,10 +77,6 @@
 
 #define G1_REG_APF_THRESHOLD(v)		(((v) << 0) & GENMASK(13, 0))
 
-#define PICT_TOP_FIELD     1
-#define PICT_BOTTOM_FIELD  2
-#define PICT_FRAME         3
-
 static void
 hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 				     struct hantro_ctx *ctx)
@@ -96,19 +92,19 @@ static void
 hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 				struct vb2_buffer *src_buf,
 				struct vb2_buffer *dst_buf,
-				const struct v4l2_mpeg2_sequence *sequence,
-				const struct v4l2_mpeg2_picture *picture,
+				const struct v4l2_mpeg2_sequence *seq,
+				const struct v4l2_mpeg2_picture *pic,
 				const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
 	dma_addr_t current_addr, addr;
 
-	switch (picture->picture_coding_type) {
-	case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+	switch (pic->picture_coding_type) {
+	case V4L2_MPEG2_PIC_CODING_TYPE_B:
 		backward_addr = hantro_get_ref(ctx,
 					       slice_params->backward_ref_ts);
 		fallthrough;
-	case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+	case V4L2_MPEG2_PIC_CODING_TYPE_P:
 		forward_addr = hantro_get_ref(ctx,
 					      slice_params->forward_ref_ts);
 	}
@@ -121,7 +117,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 	addr = hantro_get_dec_buf_addr(ctx, dst_buf);
 	current_addr = addr;
 
-	if (picture->picture_structure == PICT_BOTTOM_FIELD)
+	if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD)
 		addr += ALIGN(ctx->dst_fmt.width, 16);
 	vdpu_write_relaxed(vpu, addr, G1_REG_DEC_OUT_BASE);
 
@@ -131,18 +127,18 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 		backward_addr = current_addr;
 
 	/* Set forward ref frame (top/bottom field) */
-	if (picture->picture_structure == PICT_FRAME ||
-	    picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
-	    (picture->picture_structure == PICT_TOP_FIELD &&
-	     picture->top_field_first) ||
-	    (picture->picture_structure == PICT_BOTTOM_FIELD &&
-	     !picture->top_field_first)) {
+	if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME ||
+	    pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B ||
+	    (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD &&
+	     pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST) ||
+	    (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD &&
+	     !(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST))) {
 		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
-	} else if (picture->picture_structure == PICT_TOP_FIELD) {
+	} else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) {
 		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER1_BASE);
-	} else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
+	} else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) {
 		vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
 	}
@@ -157,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *sequence;
-	const struct v4l2_mpeg2_picture *picture;
+	const struct v4l2_mpeg2_sequence *seq;
+	const struct v4l2_mpeg2_picture *pic;
 	u32 reg;
 
 	src_buf = hantro_get_src_buf(ctx);
@@ -169,8 +165,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
-	sequence = &slice_params->sequence;
-	picture = &slice_params->picture;
+	seq = &slice_params->sequence;
+	pic = &slice_params->picture;
 
 	reg = G1_REG_DEC_AXI_RD_ID(0) |
 	      G1_REG_DEC_TIMEOUT_E(1) |
@@ -190,11 +186,11 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	reg = G1_REG_DEC_MODE(5) |
 	      G1_REG_RLC_MODE_E(0) |
-	      G1_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
-	      G1_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
-	      G1_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
-	      G1_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
-	      G1_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
+	      G1_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) |
+	      G1_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) |
+	      G1_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) |
+	      G1_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) |
+	      G1_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) |
 	      G1_REG_FWD_INTERLACE_E(0) |
 	      G1_REG_FILTERING_DIS(1) |
 	      G1_REG_WRITE_MVS_E(0) |
@@ -203,27 +199,27 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
 	      G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
-	      G1_REG_ALT_SCAN_E(picture->alternate_scan) |
-	      G1_REG_TOPFIELDFIRST_E(picture->top_field_first);
+	      G1_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
+	      G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(4));
 
 	reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) |
-	      G1_REG_QSCALE_TYPE(picture->q_scale_type) |
-	      G1_REG_CON_MV_E(picture->concealment_motion_vectors) |
-	      G1_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
-	      G1_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
-	      G1_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
+	      G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
+	      G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
+	      G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
+	      G1_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) |
+	      G1_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(5));
 
 	reg = G1_REG_INIT_QP(1) |
 	      G1_REG_STREAM_LEN(slice_params->bit_size >> 3);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(6));
 
-	reg = G1_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
-	      G1_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
-	      G1_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
-	      G1_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
-	      G1_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
+	reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
+	      G1_REG_FCODE_FWD_HOR(pic->f_code[0][0]) |
+	      G1_REG_FCODE_FWD_VER(pic->f_code[0][1]) |
+	      G1_REG_FCODE_BWD_HOR(pic->f_code[1][0]) |
+	      G1_REG_FCODE_BWD_VER(pic->f_code[1][1]) |
 	      G1_REG_MV_ACCURACY_FWD(1) |
 	      G1_REG_MV_ACCURACY_BWD(1);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(18));
@@ -239,7 +235,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					&dst_buf->vb2_buf,
-					sequence, picture, slice_params);
+					seq, pic, slice_params);
 
 	hantro_end_prepare_run(ctx);
 
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index 61a54549774d..ff54398f6643 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -79,10 +79,6 @@
 #define VDPU_REG_MV_ACCURACY_FWD(v)	((v) ? BIT(2) : 0)
 #define VDPU_REG_MV_ACCURACY_BWD(v)	((v) ? BIT(1) : 0)
 
-#define PICT_TOP_FIELD     1
-#define PICT_BOTTOM_FIELD  2
-#define PICT_FRAME         3
-
 static void
 rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 				      struct hantro_ctx *ctx)
@@ -99,19 +95,19 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 				 struct hantro_ctx *ctx,
 				 struct vb2_buffer *src_buf,
 				 struct vb2_buffer *dst_buf,
-				 const struct v4l2_mpeg2_sequence *sequence,
-				 const struct v4l2_mpeg2_picture *picture,
+				 const struct v4l2_mpeg2_sequence *seq,
+				 const struct v4l2_mpeg2_picture *pic,
 				 const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
 	dma_addr_t current_addr, addr;
 
-	switch (picture->picture_coding_type) {
-	case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+	switch (pic->picture_coding_type) {
+	case V4L2_MPEG2_PIC_CODING_TYPE_B:
 		backward_addr = hantro_get_ref(ctx,
 					       slice_params->backward_ref_ts);
 		fallthrough;
-	case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+	case V4L2_MPEG2_PIC_CODING_TYPE_P:
 		forward_addr = hantro_get_ref(ctx,
 					      slice_params->forward_ref_ts);
 	}
@@ -124,7 +120,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 	addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
 	current_addr = addr;
 
-	if (picture->picture_structure == PICT_BOTTOM_FIELD)
+	if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD)
 		addr += ALIGN(ctx->dst_fmt.width, 16);
 	vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE);
 
@@ -134,18 +130,18 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 		backward_addr = current_addr;
 
 	/* Set forward ref frame (top/bottom field) */
-	if (picture->picture_structure == PICT_FRAME ||
-	    picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
-	    (picture->picture_structure == PICT_TOP_FIELD &&
-	     picture->top_field_first) ||
-	    (picture->picture_structure == PICT_BOTTOM_FIELD &&
-	     !picture->top_field_first)) {
+	if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME ||
+	    pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B ||
+	    (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD &&
+	     pic->flags & V4L2_MPEG2_PIC_TOP_FIELD) ||
+	    (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD &&
+	     !(pic->flags & V4L2_MPEG2_PIC_TOP_FIELD))) {
 		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
-	} else if (picture->picture_structure == PICT_TOP_FIELD) {
+	} else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) {
 		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER1_BASE);
-	} else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
+	} else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) {
 		vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER0_BASE);
 		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
 	}
@@ -160,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *sequence;
-	const struct v4l2_mpeg2_picture *picture;
+	const struct v4l2_mpeg2_sequence *seq;
+	const struct v4l2_mpeg2_picture *pic;
 	u32 reg;
 
 	src_buf = hantro_get_src_buf(ctx);
@@ -171,8 +167,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
-	sequence = &slice_params->sequence;
-	picture = &slice_params->picture;
+	seq = &slice_params->sequence;
+	pic = &slice_params->picture;
 
 	reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
 	      VDPU_REG_DEC_SCMD_DIS(0) |
@@ -207,11 +203,11 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56));
 
 	reg = VDPU_REG_RLC_MODE_E(0) |
-	      VDPU_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
-	      VDPU_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
-	      VDPU_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
-	      VDPU_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
-	      VDPU_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
+	      VDPU_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) |
+	      VDPU_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) |
+	      VDPU_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) |
+	      VDPU_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) |
+	      VDPU_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) |
 	      VDPU_REG_FWD_INTERLACE_E(0) |
 	      VDPU_REG_WRITE_MVS_E(0) |
 	      VDPU_REG_DEC_TIMEOUT_E(1) |
@@ -220,23 +216,23 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
 	      VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
-	      VDPU_REG_ALT_SCAN_E(picture->alternate_scan) |
-	      VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first);
+	      VDPU_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
+	      VDPU_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
 
 	reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) |
-	      VDPU_REG_QSCALE_TYPE(picture->q_scale_type) |
-	      VDPU_REG_CON_MV_E(picture->concealment_motion_vectors) |
-	      VDPU_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
-	      VDPU_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
-	      VDPU_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
+	      VDPU_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
+	      VDPU_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
+	      VDPU_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
+	      VDPU_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) |
+	      VDPU_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(122));
 
-	reg = VDPU_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
-	      VDPU_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
-	      VDPU_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
-	      VDPU_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
-	      VDPU_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
+	reg = VDPU_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
+	      VDPU_REG_FCODE_FWD_HOR(pic->f_code[0][0]) |
+	      VDPU_REG_FCODE_FWD_VER(pic->f_code[0][1]) |
+	      VDPU_REG_FCODE_BWD_HOR(pic->f_code[1][0]) |
+	      VDPU_REG_FCODE_BWD_VER(pic->f_code[1][1]) |
 	      VDPU_REG_MV_ACCURACY_FWD(1) |
 	      VDPU_REG_MV_ACCURACY_BWD(1);
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136));
@@ -245,7 +241,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					 &dst_buf->vb2_buf,
-					 sequence, picture, slice_params);
+					 seq, pic, slice_params);
 
 	/* Kick the watchdog and start decoding */
 	hantro_end_prepare_run(ctx);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index e3154f631858..e39a17d28c7d 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
 static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 {
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *sequence;
-	const struct v4l2_mpeg2_picture *picture;
+	const struct v4l2_mpeg2_sequence *seq;
+	const struct v4l2_mpeg2_picture *pic;
 	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
 	dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
 	dma_addr_t fwd_luma_addr, fwd_chroma_addr;
@@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	u32 reg;
 
 	slice_params = run->mpeg2.slice_params;
-	sequence = &slice_params->sequence;
-	picture = &slice_params->picture;
+	seq = &slice_params->sequence;
+	pic = &slice_params->picture;
 
 	quantisation = run->mpeg2.quantisation;
 
@@ -94,19 +94,19 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 
 	/* Set MPEG picture header. */
 
-	reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(picture->picture_coding_type);
-	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, picture->f_code[0][0]);
-	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, picture->f_code[0][1]);
-	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, picture->f_code[1][0]);
-	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, picture->f_code[1][1]);
-	reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(picture->intra_dc_precision);
-	reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(picture->picture_structure);
-	reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(picture->top_field_first);
-	reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(picture->frame_pred_frame_dct);
-	reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(picture->concealment_motion_vectors);
-	reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(picture->q_scale_type);
-	reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(picture->intra_vlc_format);
-	reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(picture->alternate_scan);
+	reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(pic->picture_coding_type);
+	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, pic->f_code[0][0]);
+	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, pic->f_code[0][1]);
+	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, pic->f_code[1][0]);
+	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, pic->f_code[1][1]);
+	reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(pic->intra_dc_precision);
+	reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(pic->picture_structure);
+	reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
+	reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
+	reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV);
+	reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE);
+	reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC);
+	reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN);
 	reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_FORWARD_VECTOR(0);
 	reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_BACKWARD_VECTOR(0);
 
@@ -114,8 +114,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 
 	/* Set frame dimensions. */
 
-	reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(sequence->horizontal_size);
-	reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(sequence->vertical_size);
+	reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(seq->horizontal_size);
+	reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(seq->vertical_size);
 
 	cedrus_write(dev, VE_DEC_MPEG_PICCODEDSIZE, reg);
 
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index 8ea2c7f3a172..d3190979d574 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -18,10 +18,7 @@
 #define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
 #define	V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104
 
-#define V4L2_MPEG2_PICTURE_CODING_TYPE_I	1
-#define V4L2_MPEG2_PICTURE_CODING_TYPE_P	2
-#define V4L2_MPEG2_PICTURE_CODING_TYPE_B	3
-#define V4L2_MPEG2_PICTURE_CODING_TYPE_D	4
+#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
 
 struct v4l2_mpeg2_sequence {
 	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
@@ -31,10 +28,29 @@ struct v4l2_mpeg2_sequence {
 
 	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
 	__u16	profile_and_level_indication;
-	__u8	progressive_sequence;
 	__u8	chroma_format;
+
+	__u32	flags;
 };
 
+#define V4L2_MPEG2_PIC_CODING_TYPE_I			1
+#define V4L2_MPEG2_PIC_CODING_TYPE_P			2
+#define V4L2_MPEG2_PIC_CODING_TYPE_B			3
+#define V4L2_MPEG2_PIC_CODING_TYPE_D			4
+
+#define V4L2_MPEG2_PIC_TOP_FIELD			0x1
+#define V4L2_MPEG2_PIC_BOTTOM_FIELD			0x2
+#define V4L2_MPEG2_PIC_FRAME				0x3
+
+#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST		0x0001
+#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT		0x0002
+#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV		0x0004
+#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE		0x0008
+#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC			0x0010
+#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN			0x0020
+#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
+#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
+
 struct v4l2_mpeg2_picture {
 	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
 	__u8	picture_coding_type;
@@ -43,14 +59,8 @@ struct v4l2_mpeg2_picture {
 	__u8	f_code[2][2];
 	__u8	intra_dc_precision;
 	__u8	picture_structure;
-	__u8	top_field_first;
-	__u8	frame_pred_frame_dct;
-	__u8	concealment_motion_vectors;
-	__u8	q_scale_type;
-	__u8	intra_vlc_format;
-	__u8	alternate_scan;
-	__u8	repeat_first_field;
-	__u16	progressive_frame;
+
+	__u32	flags;
 };
 
 struct v4l2_ctrl_mpeg2_slice_params {
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (2 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-06 10:37   ` Hans Verkuil
  2021-04-03 18:07 ` [PATCH v5 05/10] media: uapi: mpeg2: Move reference buffer fields Ezequiel Garcia
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Typically, bitstreams are composed of a sequence header,
followed by a number of picture header and picture coding extension
headers. Each picture can be composed by a number of slices.

Let's split the MPEG-2 uAPI to follow these semantics more closely,
allowing more usage flexibility. Having these controls splitted
allows applications to set a sequence control at the beginning
of a sequence, and then set a picture control for each frame.

While here add padding fields where needed, and document
the uAPI header thoroughly.

Note that the V4L2_CTRL_TYPE_{} defines had to be moved because
it clashes with existing ones. This is not really an issue
since they will be re-defined when the controls are moved
out of staging.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Jonas Karlman <jonas@kwiboo.se>
---
 .../media/v4l/ext-ctrls-codec.rst             | 47 ++++++---
 .../media/v4l/pixfmt-compressed.rst           |  5 +-
 .../media/v4l/vidioc-queryctrl.rst            | 12 +++
 .../media/videodev2.h.rst.exceptions          |  2 +
 drivers/media/v4l2-core/v4l2-ctrls.c          | 57 ++++++++---
 drivers/staging/media/hantro/hantro_drv.c     | 10 ++
 .../media/hantro/hantro_g1_mpeg2_dec.c        | 14 +--
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    | 14 +--
 drivers/staging/media/sunxi/cedrus/cedrus.c   | 12 +++
 drivers/staging/media/sunxi/cedrus/cedrus.h   |  2 +
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |  4 +
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  8 +-
 include/media/mpeg2-ctrls.h                   | 97 +++++++++++++++----
 include/media/v4l2-ctrls.h                    |  4 +
 14 files changed, 228 insertions(+), 60 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 7d5ac7fb6579..8a0d6139db34 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1603,14 +1603,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     * - __u32
       - ``data_bit_offset``
       - Offset (in bits) to the video data in the current slice data.
-    * - struct :c:type:`v4l2_mpeg2_sequence`
-      - ``sequence``
-      - Structure with MPEG-2 sequence metadata, merging relevant fields from
-	the sequence header and sequence extension parts of the bitstream.
-    * - struct :c:type:`v4l2_mpeg2_picture`
-      - ``picture``
-      - Structure with MPEG-2 picture metadata, merging relevant fields from
-	the picture header and picture coding extension parts of the bitstream.
     * - __u64
       - ``backward_ref_ts``
       - Timestamp of the V4L2 capture buffer to use as backward reference, used
@@ -1628,14 +1620,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     * - __u32
       - ``quantiser_scale_code``
       - Code used to determine the quantization scale to use for the IDCT.
+    * - __u8
+      - ``reserved``
+      - Applications and drivers must set this to zero.
 
-.. c:type:: v4l2_mpeg2_sequence
+``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)``
+    Specifies the sequence parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes fields matching the syntax
+    elements from the sequence header and sequence extension parts of the
+    bitstream as specified by :ref:`mpeg2part2`.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_mpeg2_sequence
 
 .. cssclass:: longtable
 
 .. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}|
 
-.. flat-table:: struct v4l2_mpeg2_sequence
+.. flat-table:: struct v4l2_ctrl_mpeg2_sequence
     :header-rows:  0
     :stub-columns: 0
     :widths:       1 1 2
@@ -1657,6 +1663,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     * - __u8
       - ``chroma_format``
       - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
+    * - __u8
+      - ``reserved``
+      - Applications and drivers must set this to zero.
     * - __u32
       - ``flags``
       - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
@@ -1677,7 +1686,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
       - Indication that all the frames for the sequence are progressive instead
 	of interlaced.
 
-.. c:type:: v4l2_mpeg2_picture
+``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (struct)``
+    Specifies the picture parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes fields matching the syntax
+    elements from the picture header and picture coding extension parts of the
+    bitstream as specified by :ref:`mpeg2part2`.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_mpeg2_picture
 
 .. raw:: latex
 
@@ -1687,7 +1707,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 
 .. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}|
 
-.. flat-table:: struct v4l2_mpeg2_picture
+.. flat-table:: struct v4l2_ctrl_mpeg2_picture
     :header-rows:  0
     :stub-columns: 0
     :widths:       1 1 2
@@ -1708,6 +1728,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
       - ``picture_structure``
       - Picture structure (1: interlaced top field, 2: interlaced bottom field,
 	3: progressive frame).
+    * - __u8
+      - ``reserved``
+      - Applications and drivers must set this to zero.
     * - __u32
       - ``flags``
       - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index cba607f789f0..bbbacbd65d6f 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -114,8 +114,9 @@ Compressed Formats
 	This format is adapted for stateless video decoders that implement a
 	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
 	Metadata associated with the frame to decode is required to be passed
-	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
-	quantisation matrices can optionally be specified through the
+	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE``,
+        ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE``, and ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS``
+        controls. Quantisation matrices can optionally be specified through the
 	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control.
 	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
 	Exactly one output and one capture buffer must be provided for use with
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index 4362945fd39b..afc1505a3a7e 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -429,6 +429,18 @@ See also the examples in :ref:`control`.
       - n/a
       - A struct :c:type:`v4l2_ctrl_mpeg2_quantisation`, containing MPEG-2
 	quantisation matrices for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_MPEG2_SEQUENCE``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_sequence`, containing MPEG-2
+	sequence parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_MPEG2_PICTURE``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_picture`, containing MPEG-2
+	picture parameters for stateless video decoders.
     * - ``V4L2_CTRL_TYPE_AREA``
       - n/a
       - n/a
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index d14a807e8f9e..6bba3e6d3ef3 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -134,6 +134,8 @@ replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_SEQUENCE :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_PICTURE :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 99064683cfb5..1145dec744e8 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -973,6 +973,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:		return "Repeat Sequence Header";
 	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:		return "Force Key Frame";
 	case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID:		return "Base Layer Priority ID";
+	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:		return "MPEG-2 Sequence Header";
+	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:		return "MPEG-2 Slice Parameters";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
 	case V4L2_CID_FWHT_I_FRAME_QP:				return "FWHT I-Frame QP Value";
@@ -1469,6 +1471,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_RDS_TX_ALT_FREQS:
 		*type = V4L2_CTRL_TYPE_U32;
 		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:
+		*type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE;
+		break;
+	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:
+		*type = V4L2_CTRL_TYPE_MPEG2_PICTURE;
+		break;
 	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:
 		*type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS;
 		break;
@@ -1667,7 +1675,8 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
 static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 			      union v4l2_ctrl_ptr ptr)
 {
-	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
+	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
+	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
 	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
@@ -1684,13 +1693,18 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 	 * v4l2_ctrl_type enum.
 	 */
 	switch ((u32)ctrl->type) {
-	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
-		p_mpeg2_slice_params = p;
+	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
+		p_mpeg2_sequence = p;
+
 		/* 4:2:0 */
-		p_mpeg2_slice_params->sequence.chroma_format = 1;
+		p_mpeg2_sequence->chroma_format = 1;
+		break;
+	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
+		p_mpeg2_picture = p;
+
 		/* interlaced top field */
-		p_mpeg2_slice_params->picture.picture_structure = 1;
-		p_mpeg2_slice_params->picture.picture_coding_type =
+		p_mpeg2_picture->picture_structure = V4L2_MPEG2_PIC_TOP_FIELD;
+		p_mpeg2_picture->picture_coding_type =
 					V4L2_MPEG2_PIC_CODING_TYPE_I;
 		break;
 	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
@@ -1862,6 +1876,8 @@ static void std_log(const struct v4l2_ctrl *ctrl)
 static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 				 union v4l2_ctrl_ptr ptr)
 {
+	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
+	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
 	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
@@ -1878,10 +1894,10 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 	unsigned int i;
 
 	switch ((u32)ctrl->type) {
-	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
-		p_mpeg2_slice_params = p;
+	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
+		p_mpeg2_sequence = p;
 
-		switch (p_mpeg2_slice_params->sequence.chroma_format) {
+		switch (p_mpeg2_sequence->chroma_format) {
 		case 1: /* 4:2:0 */
 		case 2: /* 4:2:2 */
 		case 3: /* 4:4:4 */
@@ -1889,8 +1905,13 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		default:
 			return -EINVAL;
 		}
+		zero_reserved(*p_mpeg2_sequence);
+		break;
+
+	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
+		p_mpeg2_picture = p;
 
-		switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
+		switch (p_mpeg2_picture->intra_dc_precision) {
 		case 0: /* 8 bits */
 		case 1: /* 9 bits */
 		case 2: /* 10 bits */
@@ -1900,7 +1921,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 			return -EINVAL;
 		}
 
-		switch (p_mpeg2_slice_params->picture.picture_structure) {
+		switch (p_mpeg2_picture->picture_structure) {
 		case V4L2_MPEG2_PIC_TOP_FIELD:
 		case V4L2_MPEG2_PIC_BOTTOM_FIELD:
 		case V4L2_MPEG2_PIC_FRAME:
@@ -1909,7 +1930,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 			return -EINVAL;
 		}
 
-		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
+		switch (p_mpeg2_picture->picture_coding_type) {
 		case V4L2_MPEG2_PIC_CODING_TYPE_I:
 		case V4L2_MPEG2_PIC_CODING_TYPE_P:
 		case V4L2_MPEG2_PIC_CODING_TYPE_B:
@@ -1917,7 +1938,13 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		default:
 			return -EINVAL;
 		}
+		zero_reserved(*p_mpeg2_picture);
+		break;
 
+	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
+		p_mpeg2_slice_params = p;
+
+		zero_reserved(*p_mpeg2_slice_params);
 		break;
 
 	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
@@ -2822,6 +2849,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	case V4L2_CTRL_TYPE_U32:
 		elem_size = sizeof(u32);
 		break;
+	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
+		elem_size = sizeof(struct v4l2_ctrl_mpeg2_sequence);
+		break;
+	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
+		elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture);
+		break;
 	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
 		elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params);
 		break;
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 9e3552cd5cf8..067205fb89f6 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -286,6 +286,16 @@ static const struct hantro_ctrl controls[] = {
 			.def = 50,
 			.ops = &hantro_jpeg_ctrl_ops,
 		},
+	}, {
+		.codec = HANTRO_MPEG2_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
+		},
+	}, {
+		.codec = HANTRO_MPEG2_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
+		},
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index 6ef7ded863b2..f3494a70aa12 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -92,8 +92,8 @@ static void
 hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 				struct vb2_buffer *src_buf,
 				struct vb2_buffer *dst_buf,
-				const struct v4l2_mpeg2_sequence *seq,
-				const struct v4l2_mpeg2_picture *pic,
+				const struct v4l2_ctrl_mpeg2_sequence *seq,
+				const struct v4l2_ctrl_mpeg2_picture *pic,
 				const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
@@ -153,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *seq;
-	const struct v4l2_mpeg2_picture *pic;
+	const struct v4l2_ctrl_mpeg2_sequence *seq;
+	const struct v4l2_ctrl_mpeg2_picture *pic;
 	u32 reg;
 
 	src_buf = hantro_get_src_buf(ctx);
@@ -165,8 +165,10 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
-	seq = &slice_params->sequence;
-	pic = &slice_params->picture;
+	seq = hantro_get_ctrl(ctx,
+			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+	pic = hantro_get_ctrl(ctx,
+			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
 
 	reg = G1_REG_DEC_AXI_RD_ID(0) |
 	      G1_REG_DEC_TIMEOUT_E(1) |
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index ff54398f6643..5b383906af59 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -95,8 +95,8 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 				 struct hantro_ctx *ctx,
 				 struct vb2_buffer *src_buf,
 				 struct vb2_buffer *dst_buf,
-				 const struct v4l2_mpeg2_sequence *seq,
-				 const struct v4l2_mpeg2_picture *pic,
+				 const struct v4l2_ctrl_mpeg2_sequence *seq,
+				 const struct v4l2_ctrl_mpeg2_picture *pic,
 				 const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
@@ -156,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *seq;
-	const struct v4l2_mpeg2_picture *pic;
+	const struct v4l2_ctrl_mpeg2_sequence *seq;
+	const struct v4l2_ctrl_mpeg2_picture *pic;
 	u32 reg;
 
 	src_buf = hantro_get_src_buf(ctx);
@@ -167,8 +167,10 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
-	seq = &slice_params->sequence;
-	pic = &slice_params->picture;
+	seq = hantro_get_ctrl(ctx,
+			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+	pic = hantro_get_ctrl(ctx,
+			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
 
 	reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
 	      VDPU_REG_DEC_SCMD_DIS(0) |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 62a5407664ae..878752b30c10 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -29,6 +29,18 @@
 #include "cedrus_hw.h"
 
 static const struct cedrus_control cedrus_controls[] = {
+	{
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
+		},
+		.codec		= CEDRUS_CODEC_MPEG2,
+	},
+	{
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
+		},
+		.codec		= CEDRUS_CODEC_MPEG2,
+	},
 	{
 		.cfg = {
 			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 6516bff3d319..989873ccb98c 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -68,6 +68,8 @@ struct cedrus_h264_run {
 };
 
 struct cedrus_mpeg2_run {
+	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
+	const struct v4l2_ctrl_mpeg2_picture		*picture;
 	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
 	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
 };
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index 238f779d2ba4..f4cc6aebfac9 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -40,6 +40,10 @@ void cedrus_device_run(void *priv)
 
 	switch (ctx->src_fmt.pixelformat) {
 	case V4L2_PIX_FMT_MPEG2_SLICE:
+		run.mpeg2.sequence = cedrus_find_control_data(ctx,
+			V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+		run.mpeg2.picture = cedrus_find_control_data(ctx,
+			V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
 		run.mpeg2.slice_params = cedrus_find_control_data(ctx,
 			V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
 		run.mpeg2.quantisation = cedrus_find_control_data(ctx,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index e39a17d28c7d..65a175c6a5c2 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
 static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 {
 	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
-	const struct v4l2_mpeg2_sequence *seq;
-	const struct v4l2_mpeg2_picture *pic;
+	const struct v4l2_ctrl_mpeg2_sequence *seq;
+	const struct v4l2_ctrl_mpeg2_picture *pic;
 	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
 	dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
 	dma_addr_t fwd_luma_addr, fwd_chroma_addr;
@@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	u32 reg;
 
 	slice_params = run->mpeg2.slice_params;
-	seq = &slice_params->sequence;
-	pic = &slice_params->picture;
+	seq = run->mpeg2.sequence;
+	pic = run->mpeg2.picture;
 
 	quantisation = run->mpeg2.quantisation;
 
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index d3190979d574..2a26c03e3ead 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -13,23 +13,45 @@
 
 #define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS		(V4L2_CID_CODEC_BASE+250)
 #define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION		(V4L2_CID_CODEC_BASE+251)
+#define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE		(V4L2_CID_CODEC_BASE+252)
+#define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE		(V4L2_CID_CODEC_BASE+253)
 
 /* enum v4l2_ctrl_type type values */
-#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
-#define	V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104
+#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0130
+#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131
+#define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132
+#define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133
 
 #define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
 
-struct v4l2_mpeg2_sequence {
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
+/**
+ * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header
+ *
+ * All the members on this structure match the sequence header and sequence
+ * extension syntaxes as specified by the MPEG-2 specification.
+ *
+ * Fields horizontal_size, vertical_size and vbv_buffer_size are a
+ * combination of respective _value and extension syntax elements,
+ * as described in section 6.3.3 "Sequence header".
+ *
+ * @horizontal_size: combination of elements horizontal_size_value and
+ * horizontal_size_extension.
+ * @vertical_size: combination of elements vertical_size_value and
+ * vertical_size_extension.
+ * @vbv_buffer_size: combination of elements vbv_buffer_size_value and
+ * vbv_buffer_size_extension.
+ * @profile_and_level_indication: see MPEG-2 specification.
+ * @chroma_format: see MPEG-2 specification.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @flags: see V4L2_MPEG2_SEQ_FLAG_{}.
+ */
+struct v4l2_ctrl_mpeg2_sequence {
 	__u16	horizontal_size;
 	__u16	vertical_size;
 	__u32	vbv_buffer_size;
-
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
 	__u16	profile_and_level_indication;
 	__u8	chroma_format;
-
+	__u8	reserved;
 	__u32	flags;
 };
 
@@ -51,33 +73,72 @@ struct v4l2_mpeg2_sequence {
 #define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
 #define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
 
-struct v4l2_mpeg2_picture {
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
+/**
+ * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header
+ *
+ * All the members on this structure match the picture header and picture
+ * coding extension syntaxes as specified by the MPEG-2 specification.
+ *
+ * @picture_coding_type: see MPEG-2 specification.
+ * @f_code[2][2]: see MPEG-2 specification.
+ * @intra_dc_precision: see MPEG-2 specification.
+ * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @flags: see V4L2_MPEG2_PIC_FLAG_{}.
+ */
+struct v4l2_ctrl_mpeg2_picture {
 	__u8	picture_coding_type;
-
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
 	__u8	f_code[2][2];
 	__u8	intra_dc_precision;
 	__u8	picture_structure;
-
+	__u8	reserved;
 	__u32	flags;
 };
 
+/**
+ * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header
+ *
+ * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for backward prediction.
+ * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for forward prediction. These timestamp refers to the
+ * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
+ * to convert the struct timeval to a __u64.
+ * @quantiser_scale_code: quantiser scale integer matching an
+ * homonymous syntax element.
+ * @reserved: padding field. Should be zeroed by applications.
+ */
 struct v4l2_ctrl_mpeg2_slice_params {
 	__u32	bit_size;
 	__u32	data_bit_offset;
 	__u64	backward_ref_ts;
 	__u64	forward_ref_ts;
-
-	struct v4l2_mpeg2_sequence sequence;
-	struct v4l2_mpeg2_picture picture;
-
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
 	__u32	quantiser_scale_code;
+	__u32	reserved;
 };
 
+/**
+ * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation
+ *
+ * Quantization matrices as specified by section 6.3.7
+ * "Quant matrix extension".
+ *
+ * @intra_quantiser_matrix: The quantisation matrix coefficients
+ * for intra-coded frames, in zigzag scanning order. It is relevant
+ * for both luma and chroma components, although it can be superseded
+ * by the chroma-specific matrix for non-4:2:0 YUV formats.
+ * @non_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for non-intra-coded frames, in zigzag scanning order. It is relevant
+ * for both luma and chroma components, although it can be superseded
+ * by the chroma-specific matrix for non-4:2:0 YUV formats.
+ * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for the chominance component of intra-coded frames, in zigzag scanning
+ * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
+ * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for the chrominance component of non-intra-coded frames, in zigzag scanning
+ * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
+ */
 struct v4l2_ctrl_mpeg2_quantisation {
-	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
 	__u8	intra_quantiser_matrix[64];
 	__u8	non_intra_quantiser_matrix[64];
 	__u8	chroma_intra_quantiser_matrix[64];
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index a560005c575a..6406cdc3f56d 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -40,6 +40,8 @@ struct video_device;
  * @p_u16:			Pointer to a 16-bit unsigned value.
  * @p_u32:			Pointer to a 32-bit unsigned value.
  * @p_char:			Pointer to a string.
+ * @p_mpeg2_sequence:		Pointer to a MPEG2 sequence structure.
+ * @p_mpeg2_picture:		Pointer to a MPEG2 picture structure.
  * @p_mpeg2_slice_params:	Pointer to a MPEG2 slice parameters structure.
  * @p_mpeg2_quantisation:	Pointer to a MPEG2 quantisation data structure.
  * @p_fwht_params:		Pointer to a FWHT stateless parameters structure.
@@ -64,6 +66,8 @@ union v4l2_ctrl_ptr {
 	u16 *p_u16;
 	u32 *p_u32;
 	char *p_char;
+	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
+	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
 	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
 	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 05/10] media: uapi: mpeg2: Move reference buffer fields
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (3 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 06/10] media: hantro/cedrus: Remove unneeded slice size and slice offset Ezequiel Garcia
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

The forward and backwards references are specified per-picture
and not per-slice. Move it to V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             | 28 +++++++++----------
 .../media/hantro/hantro_g1_mpeg2_dec.c        |  6 ++--
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |  6 ++--
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  4 +--
 include/media/mpeg2-ctrls.h                   | 16 +++++------
 5 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 8a0d6139db34..ebed3d8570f4 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1603,20 +1603,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     * - __u32
       - ``data_bit_offset``
       - Offset (in bits) to the video data in the current slice data.
-    * - __u64
-      - ``backward_ref_ts``
-      - Timestamp of the V4L2 capture buffer to use as backward reference, used
-        with B-coded and P-coded frames. The timestamp refers to the
-	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
-	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``forward_ref_ts``
-      - Timestamp for the V4L2 capture buffer to use as forward reference, used
-        with B-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
     * - __u32
       - ``quantiser_scale_code``
       - Code used to determine the quantization scale to use for the IDCT.
@@ -1712,6 +1698,20 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
     :stub-columns: 0
     :widths:       1 1 2
 
+    * - __u64
+      - ``backward_ref_ts``
+      - Timestamp of the V4L2 capture buffer to use as backward reference, used
+        with B-coded and P-coded frames. The timestamp refers to the
+	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
+	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``forward_ref_ts``
+      - Timestamp for the V4L2 capture buffer to use as forward reference, used
+        with B-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
     * - __u8
       - ``picture_coding_type``
       - Picture coding type for the frame covered by the current slice
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index f3494a70aa12..d35071e88116 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -101,12 +101,10 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 
 	switch (pic->picture_coding_type) {
 	case V4L2_MPEG2_PIC_CODING_TYPE_B:
-		backward_addr = hantro_get_ref(ctx,
-					       slice_params->backward_ref_ts);
+		backward_addr = hantro_get_ref(ctx, pic->backward_ref_ts);
 		fallthrough;
 	case V4L2_MPEG2_PIC_CODING_TYPE_P:
-		forward_addr = hantro_get_ref(ctx,
-					      slice_params->forward_ref_ts);
+		forward_addr = hantro_get_ref(ctx, pic->forward_ref_ts);
 	}
 
 	/* Source bitstream buffer */
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index 5b383906af59..18bd14704ebf 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -104,12 +104,10 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 
 	switch (pic->picture_coding_type) {
 	case V4L2_MPEG2_PIC_CODING_TYPE_B:
-		backward_addr = hantro_get_ref(ctx,
-					       slice_params->backward_ref_ts);
+		backward_addr = hantro_get_ref(ctx, pic->backward_ref_ts);
 		fallthrough;
 	case V4L2_MPEG2_PIC_CODING_TYPE_P:
-		forward_addr = hantro_get_ref(ctx,
-					      slice_params->forward_ref_ts);
+		forward_addr = hantro_get_ref(ctx, pic->forward_ref_ts);
 	}
 
 	/* Source bitstream buffer */
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index 65a175c6a5c2..16e99792cf42 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -128,14 +128,14 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 
 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 
-	forward_idx = vb2_find_timestamp(vq, slice_params->forward_ref_ts, 0);
+	forward_idx = vb2_find_timestamp(vq, pic->forward_ref_ts, 0);
 	fwd_luma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 0);
 	fwd_chroma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 1);
 
 	cedrus_write(dev, VE_DEC_MPEG_FWD_REF_LUMA_ADDR, fwd_luma_addr);
 	cedrus_write(dev, VE_DEC_MPEG_FWD_REF_CHROMA_ADDR, fwd_chroma_addr);
 
-	backward_idx = vb2_find_timestamp(vq, slice_params->backward_ref_ts, 0);
+	backward_idx = vb2_find_timestamp(vq, pic->backward_ref_ts, 0);
 	bwd_luma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 0);
 	bwd_chroma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 1);
 
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index 2a26c03e3ead..27451afcfba3 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -79,6 +79,12 @@ struct v4l2_ctrl_mpeg2_sequence {
  * All the members on this structure match the picture header and picture
  * coding extension syntaxes as specified by the MPEG-2 specification.
  *
+ * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for backward prediction.
+ * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for forward prediction. These timestamp refers to the
+ * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
+ * to convert the struct timeval to a __u64.
  * @picture_coding_type: see MPEG-2 specification.
  * @f_code[2][2]: see MPEG-2 specification.
  * @intra_dc_precision: see MPEG-2 specification.
@@ -87,6 +93,8 @@ struct v4l2_ctrl_mpeg2_sequence {
  * @flags: see V4L2_MPEG2_PIC_FLAG_{}.
  */
 struct v4l2_ctrl_mpeg2_picture {
+	__u64	backward_ref_ts;
+	__u64	forward_ref_ts;
 	__u8	picture_coding_type;
 	__u8	f_code[2][2];
 	__u8	intra_dc_precision;
@@ -98,12 +106,6 @@ struct v4l2_ctrl_mpeg2_picture {
 /**
  * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header
  *
- * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
- * reference for backward prediction.
- * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
- * reference for forward prediction. These timestamp refers to the
- * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
- * to convert the struct timeval to a __u64.
  * @quantiser_scale_code: quantiser scale integer matching an
  * homonymous syntax element.
  * @reserved: padding field. Should be zeroed by applications.
@@ -111,8 +113,6 @@ struct v4l2_ctrl_mpeg2_picture {
 struct v4l2_ctrl_mpeg2_slice_params {
 	__u32	bit_size;
 	__u32	data_bit_offset;
-	__u64	backward_ref_ts;
-	__u64	forward_ref_ts;
 	__u32	quantiser_scale_code;
 	__u32	reserved;
 };
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 06/10] media: hantro/cedrus: Remove unneeded slice size and slice offset
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (4 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 05/10] media: uapi: mpeg2: Move reference buffer fields Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 07/10] media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS Ezequiel Garcia
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

The MPEG2_SLICE_PARAMS control is designed to refer to a
single slice. However, the Hantro and Cedrus drivers operate
in per-frame mode, and so does the current Ffmpeg and GStreamer
implementations that are tested with these two drivers.

In other words, the drivers are expecting all the slices in a picture
(with either frame or field structure) to be contained in
the OUTPUT buffer, which means the slice size and offset shouldn't be used.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c     | 4 ++--
 drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 4 ++--
 drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c      | 7 +++----
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index d35071e88116..c4040fba7c80 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -203,7 +203,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	      G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(4));
 
-	reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) |
+	reg = G1_REG_STRM_START_BIT(0) |
 	      G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
 	      G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
 	      G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
@@ -212,7 +212,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(5));
 
 	reg = G1_REG_INIT_QP(1) |
-	      G1_REG_STREAM_LEN(slice_params->bit_size >> 3);
+	      G1_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0));
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(6));
 
 	reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index 18bd14704ebf..314269811244 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -177,7 +177,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50));
 
 	reg = VDPU_REG_INIT_QP(1) |
-	      VDPU_REG_STREAM_LEN(slice_params->bit_size >> 3);
+	      VDPU_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0));
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51));
 
 	reg = VDPU_REG_APF_THRESHOLD(8) |
@@ -220,7 +220,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	      VDPU_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
 	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
 
-	reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) |
+	reg = VDPU_REG_STRM_START_BIT(0) |
 	      VDPU_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
 	      VDPU_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
 	      VDPU_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index 16e99792cf42..fd71cb175318 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -152,10 +152,9 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 
 	/* Source offset and length in bits. */
 
-	cedrus_write(dev, VE_DEC_MPEG_VLD_OFFSET,
-		     slice_params->data_bit_offset);
+	cedrus_write(dev, VE_DEC_MPEG_VLD_OFFSET, 0);
 
-	reg = slice_params->bit_size - slice_params->data_bit_offset;
+	reg = vb2_get_plane_payload(&run->src->vb2_buf, 0) * 8;
 	cedrus_write(dev, VE_DEC_MPEG_VLD_LEN, reg);
 
 	/* Source beginning and end addresses. */
@@ -169,7 +168,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 
 	cedrus_write(dev, VE_DEC_MPEG_VLD_ADDR, reg);
 
-	reg = src_buf_addr + DIV_ROUND_UP(slice_params->bit_size, 8);
+	reg = src_buf_addr + vb2_get_plane_payload(&run->src->vb2_buf, 0);
 	cedrus_write(dev, VE_DEC_MPEG_VLD_END_ADDR, reg);
 
 	/* Macroblock address: start at the beginning. */
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 07/10] media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (5 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 06/10] media: hantro/cedrus: Remove unneeded slice size and slice offset Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 08/10] media: controls: Log MPEG-2 stateless control in .std_log Ezequiel Garcia
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

The Hantro and Cedrus drivers work in frame-mode,
meaning they expect all the slices in a picture (either frame
or field structure) to be passed in each OUTPUT buffer.

These two are the only V4L2 MPEG-2 stateless decoders currently
supported. Given the VA-API drivers also work per-frame,
coalescing all the MPEG-2 slices in a buffer before the decoding
operation, it makes sense to not expect slice-mode drivers and
therefore remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS.

This is done to avoid carrying an unused interface. If needed,
this control can be added without breaking backwards compatibility.
Note that this would mean introducing a enumerator control to
specify the decoding mode (see V4L2_CID_STATELESS_H264_DECODE_MODE).

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Co-developed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             | 35 -------------------
 .../media/v4l/pixfmt-compressed.rst           |  6 ++--
 .../media/v4l/vidioc-queryctrl.rst            |  6 ----
 .../media/videodev2.h.rst.exceptions          |  1 -
 drivers/media/v4l2-core/v4l2-ctrls.c          | 19 ----------
 drivers/staging/media/hantro/hantro_drv.c     |  5 ---
 .../media/hantro/hantro_g1_mpeg2_dec.c        |  9 ++---
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |  8 ++---
 drivers/staging/media/sunxi/cedrus/cedrus.c   |  6 ----
 drivers/staging/media/sunxi/cedrus/cedrus.h   |  1 -
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |  2 --
 .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  2 --
 include/media/mpeg2-ctrls.h                   | 16 ---------
 include/media/v4l2-ctrls.h                    |  2 --
 14 files changed, 7 insertions(+), 111 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index ebed3d8570f4..7d3bfdbed4ec 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1575,41 +1575,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 
 .. _v4l2-mpeg-mpeg2:
 
-``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
-    Specifies the slice parameters (as extracted from the bitstream) for the
-    associated MPEG-2 slice data. This includes the necessary parameters for
-    configuring a stateless hardware decoding pipeline for MPEG-2.
-    The bitstream parameters are defined according to :ref:`mpeg2part2`.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_slice_params
-
-.. tabularcolumns:: |p{5.6cm}|p{4.6cm}|p{7.1cm}|
-
-.. cssclass:: longtable
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u32
-      - ``bit_size``
-      - Size (in bits) of the current slice data.
-    * - __u32
-      - ``data_bit_offset``
-      - Offset (in bits) to the video data in the current slice data.
-    * - __u32
-      - ``quantiser_scale_code``
-      - Code used to determine the quantization scale to use for the IDCT.
-    * - __u8
-      - ``reserved``
-      - Applications and drivers must set this to zero.
-
 ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)``
     Specifies the sequence parameters (as extracted from the bitstream) for the
     associated MPEG-2 slice data. This includes fields matching the syntax
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index bbbacbd65d6f..6c10a062adac 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -114,9 +114,9 @@ Compressed Formats
 	This format is adapted for stateless video decoders that implement a
 	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
 	Metadata associated with the frame to decode is required to be passed
-	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE``,
-        ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE``, and ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS``
-        controls. Quantisation matrices can optionally be specified through the
+	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE`` and
+        ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE`` controls.
+        Quantisation matrices can optionally be specified through the
 	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control.
 	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
 	Exactly one output and one capture buffer must be provided for use with
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index afc1505a3a7e..07e54029e1e9 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -417,12 +417,6 @@ See also the examples in :ref:`control`.
       - any
       - An unsigned 32-bit valued control ranging from minimum to maximum
 	inclusive. The step value indicates the increment between values.
-    * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS``
-      - n/a
-      - n/a
-      - n/a
-      - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2
-	slice parameters for stateless video decoders.
     * - ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``
       - n/a
       - n/a
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index 6bba3e6d3ef3..f3addaaadc7a 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -136,7 +136,6 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_SEQUENCE :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_PICTURE :c:type:`v4l2_ctrl_type`
-replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 1145dec744e8..575553ee7e4a 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -975,7 +975,6 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID:		return "Base Layer Priority ID";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:		return "MPEG-2 Sequence Header";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
-	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:		return "MPEG-2 Slice Parameters";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
 	case V4L2_CID_FWHT_I_FRAME_QP:				return "FWHT I-Frame QP Value";
 	case V4L2_CID_FWHT_P_FRAME_QP:				return "FWHT P-Frame QP Value";
@@ -1477,9 +1476,6 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:
 		*type = V4L2_CTRL_TYPE_MPEG2_PICTURE;
 		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:
-		*type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS;
-		break;
 	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:
 		*type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION;
 		break;
@@ -1687,11 +1683,6 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 	else
 		memset(p, 0, ctrl->elem_size);
 
-	/*
-	 * The cast is needed to get rid of a gcc warning complaining that
-	 * V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS is not part of the
-	 * v4l2_ctrl_type enum.
-	 */
 	switch ((u32)ctrl->type) {
 	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
 		p_mpeg2_sequence = p;
@@ -1878,7 +1869,6 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 {
 	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
 	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
-	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	struct v4l2_ctrl_h264_sps *p_h264_sps;
@@ -1941,12 +1931,6 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		zero_reserved(*p_mpeg2_picture);
 		break;
 
-	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
-		p_mpeg2_slice_params = p;
-
-		zero_reserved(*p_mpeg2_slice_params);
-		break;
-
 	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
 		break;
 
@@ -2855,9 +2839,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
 		elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture);
 		break;
-	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
-		elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params);
-		break;
 	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
 		elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation);
 		break;
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 067205fb89f6..f5fa7e0940c4 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -296,11 +296,6 @@ static const struct hantro_ctrl controls[] = {
 		.cfg = {
 			.id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
 		},
-	}, {
-		.codec = HANTRO_MPEG2_DECODER,
-		.cfg = {
-			.id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
-		},
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index c4040fba7c80..6d89cae7df45 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -93,8 +93,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
 				struct vb2_buffer *src_buf,
 				struct vb2_buffer *dst_buf,
 				const struct v4l2_ctrl_mpeg2_sequence *seq,
-				const struct v4l2_ctrl_mpeg2_picture *pic,
-				const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
+				const struct v4l2_ctrl_mpeg2_picture *pic)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
 	dma_addr_t current_addr, addr;
@@ -150,7 +149,6 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
-	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
 	const struct v4l2_ctrl_mpeg2_sequence *seq;
 	const struct v4l2_ctrl_mpeg2_picture *pic;
 	u32 reg;
@@ -161,8 +159,6 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	/* Apply request controls if any */
 	hantro_start_prepare_run(ctx);
 
-	slice_params = hantro_get_ctrl(ctx,
-				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
 	seq = hantro_get_ctrl(ctx,
 			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
 	pic = hantro_get_ctrl(ctx,
@@ -232,10 +228,9 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	vdpu_write_relaxed(vpu, reg, G1_SWREG(55));
 
 	hantro_g1_mpeg2_dec_set_quantisation(vpu, ctx);
-
 	hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					&dst_buf->vb2_buf,
-					seq, pic, slice_params);
+					seq, pic);
 
 	hantro_end_prepare_run(ctx);
 
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index 314269811244..d16d76760278 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -96,8 +96,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
 				 struct vb2_buffer *src_buf,
 				 struct vb2_buffer *dst_buf,
 				 const struct v4l2_ctrl_mpeg2_sequence *seq,
-				 const struct v4l2_ctrl_mpeg2_picture *pic,
-				 const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
+				 const struct v4l2_ctrl_mpeg2_picture *pic)
 {
 	dma_addr_t forward_addr = 0, backward_addr = 0;
 	dma_addr_t current_addr, addr;
@@ -153,7 +152,6 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
-	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
 	const struct v4l2_ctrl_mpeg2_sequence *seq;
 	const struct v4l2_ctrl_mpeg2_picture *pic;
 	u32 reg;
@@ -163,8 +161,6 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	hantro_start_prepare_run(ctx);
 
-	slice_params = hantro_get_ctrl(ctx,
-				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
 	seq = hantro_get_ctrl(ctx,
 			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
 	pic = hantro_get_ctrl(ctx,
@@ -241,7 +237,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 
 	rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
 					 &dst_buf->vb2_buf,
-					 seq, pic, slice_params);
+					 seq, pic);
 
 	/* Kick the watchdog and start decoding */
 	hantro_end_prepare_run(ctx);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 878752b30c10..4430c8fa2cc7 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -41,12 +41,6 @@ static const struct cedrus_control cedrus_controls[] = {
 		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 	},
-	{
-		.cfg = {
-			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
-		},
-		.codec		= CEDRUS_CODEC_MPEG2,
-	},
 	{
 		.cfg = {
 			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 989873ccb98c..bbcdcd0787cf 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -70,7 +70,6 @@ struct cedrus_h264_run {
 struct cedrus_mpeg2_run {
 	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
 	const struct v4l2_ctrl_mpeg2_picture		*picture;
-	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
 	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
 };
 
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index f4cc6aebfac9..e98185c1f5a7 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -44,8 +44,6 @@ void cedrus_device_run(void *priv)
 			V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
 		run.mpeg2.picture = cedrus_find_control_data(ctx,
 			V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
-		run.mpeg2.slice_params = cedrus_find_control_data(ctx,
-			V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
 		run.mpeg2.quantisation = cedrus_find_control_data(ctx,
 			V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
 		break;
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index fd71cb175318..5dad2f296c6d 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -50,7 +50,6 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
 
 static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 {
-	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
 	const struct v4l2_ctrl_mpeg2_sequence *seq;
 	const struct v4l2_ctrl_mpeg2_picture *pic;
 	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
@@ -65,7 +64,6 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
 	unsigned int i;
 	u32 reg;
 
-	slice_params = run->mpeg2.slice_params;
 	seq = run->mpeg2.sequence;
 	pic = run->mpeg2.picture;
 
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index 27451afcfba3..2b0084b2519b 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -11,13 +11,11 @@
 #ifndef _MPEG2_CTRLS_H_
 #define _MPEG2_CTRLS_H_
 
-#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS		(V4L2_CID_CODEC_BASE+250)
 #define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION		(V4L2_CID_CODEC_BASE+251)
 #define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE		(V4L2_CID_CODEC_BASE+252)
 #define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE		(V4L2_CID_CODEC_BASE+253)
 
 /* enum v4l2_ctrl_type type values */
-#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0130
 #define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131
 #define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132
 #define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133
@@ -103,20 +101,6 @@ struct v4l2_ctrl_mpeg2_picture {
 	__u32	flags;
 };
 
-/**
- * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header
- *
- * @quantiser_scale_code: quantiser scale integer matching an
- * homonymous syntax element.
- * @reserved: padding field. Should be zeroed by applications.
- */
-struct v4l2_ctrl_mpeg2_slice_params {
-	__u32	bit_size;
-	__u32	data_bit_offset;
-	__u32	quantiser_scale_code;
-	__u32	reserved;
-};
-
 /**
  * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation
  *
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 6406cdc3f56d..cd9846657bbb 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -42,7 +42,6 @@ struct video_device;
  * @p_char:			Pointer to a string.
  * @p_mpeg2_sequence:		Pointer to a MPEG2 sequence structure.
  * @p_mpeg2_picture:		Pointer to a MPEG2 picture structure.
- * @p_mpeg2_slice_params:	Pointer to a MPEG2 slice parameters structure.
  * @p_mpeg2_quantisation:	Pointer to a MPEG2 quantisation data structure.
  * @p_fwht_params:		Pointer to a FWHT stateless parameters structure.
  * @p_h264_sps:			Pointer to a struct v4l2_ctrl_h264_sps.
@@ -68,7 +67,6 @@ union v4l2_ctrl_ptr {
 	char *p_char;
 	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
 	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
-	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
 	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	struct v4l2_ctrl_h264_sps *p_h264_sps;
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 08/10] media: controls: Log MPEG-2 stateless control in .std_log
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (6 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 07/10] media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 09/10] media: uapi: Move the MPEG-2 stateless control type out of staging Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 10/10] media: uapi: move MPEG-2 stateless controls " Ezequiel Garcia
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Simply print the type of the control.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 575553ee7e4a..722a208c647e 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1826,6 +1826,15 @@ static void std_log(const struct v4l2_ctrl *ctrl)
 	case V4L2_CTRL_TYPE_VP8_FRAME:
 		pr_cont("VP8_FRAME");
 		break;
+	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
+		pr_cont("MPEG2_QUANTISATION");
+		break;
+	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
+		pr_cont("MPEG2_SEQUENCE");
+		break;
+	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
+		pr_cont("MPEG2_PICTURE");
+		break;
 	default:
 		pr_cont("unknown type %d", ctrl->type);
 		break;
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 09/10] media: uapi: Move the MPEG-2 stateless control type out of staging
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (7 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 08/10] media: controls: Log MPEG-2 stateless control in .std_log Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  2021-04-03 18:07 ` [PATCH v5 10/10] media: uapi: move MPEG-2 stateless controls " Ezequiel Garcia
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Move the MPEG-2 stateless control types out of staging,
and re-number it to avoid any confusion.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 include/media/mpeg2-ctrls.h    | 4 ----
 include/uapi/linux/videodev2.h | 4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
index 2b0084b2519b..0b0ac8fcd220 100644
--- a/include/media/mpeg2-ctrls.h
+++ b/include/media/mpeg2-ctrls.h
@@ -16,10 +16,6 @@
 #define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE		(V4L2_CID_CODEC_BASE+253)
 
 /* enum v4l2_ctrl_type type values */
-#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131
-#define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132
-#define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133
-
 #define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
 
 /**
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 8d15f6ccc4b4..2206f3cd28a4 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1804,6 +1804,10 @@ enum v4l2_ctrl_type {
 	V4L2_CTRL_TYPE_FWHT_PARAMS	    = 0x0220,
 
 	V4L2_CTRL_TYPE_VP8_FRAME            = 0x0240,
+
+	V4L2_CTRL_TYPE_MPEG2_QUANTISATION   = 0x0250,
+	V4L2_CTRL_TYPE_MPEG2_SEQUENCE       = 0x0251,
+	V4L2_CTRL_TYPE_MPEG2_PICTURE        = 0x0252,
 };
 
 /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 10/10] media: uapi: move MPEG-2 stateless controls out of staging
  2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
                   ` (8 preceding siblings ...)
  2021-04-03 18:07 ` [PATCH v5 09/10] media: uapi: Move the MPEG-2 stateless control type out of staging Ezequiel Garcia
@ 2021-04-03 18:07 ` Ezequiel Garcia
  9 siblings, 0 replies; 14+ messages in thread
From: Ezequiel Garcia @ 2021-04-03 18:07 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Hans Verkuil, Nicolas Dufresne,
	Philipp Zabel, Maxime Ripard, Paul Kocialkowski, Jernej Skrabec,
	Daniel Almeida, Ezequiel Garcia

Until now, the MPEG-2 V4L2 API was not exported as a public API,
and only defined in a private media header (media/mpeg2-ctrls.h).

After reviewing the MPEG-2 specification in detail, and reworking
the controls so they match the MPEG-2 semantics properly,
we can consider it ready.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 .../media/v4l/ext-ctrls-codec-stateless.rst   | 218 +++++++++++++++++
 .../media/v4l/ext-ctrls-codec.rst             | 219 ------------------
 .../media/v4l/pixfmt-compressed.rst           |  10 +-
 .../media/v4l/vidioc-g-ext-ctrls.rst          |  12 +
 drivers/media/v4l2-core/v4l2-ctrls.c          |  12 +-
 drivers/staging/media/hantro/hantro_drv.c     |   6 +-
 .../media/hantro/hantro_g1_mpeg2_dec.c        |   6 +-
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |   6 +-
 drivers/staging/media/sunxi/cedrus/cedrus.c   |   6 +-
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |   6 +-
 include/media/mpeg2-ctrls.h                   | 128 ----------
 include/media/v4l2-ctrls.h                    |   1 -
 include/uapi/linux/v4l2-controls.h            | 114 +++++++++
 include/uapi/linux/videodev2.h                |   3 +
 14 files changed, 373 insertions(+), 374 deletions(-)
 delete mode 100644 include/media/mpeg2-ctrls.h

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
index 3fc04daa9ffb..c38826024c58 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
@@ -1244,3 +1244,221 @@ FWHT Flags
     * - __u8
       - ``padding[3]``
       - Applications and drivers must set this to zero.
+
+.. _v4l2-codec-stateless-mpeg2:
+
+``V4L2_CID_STATELESS_MPEG2_SEQUENCE (struct)``
+    Specifies the sequence parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes fields matching the syntax
+    elements from the sequence header and sequence extension parts of the
+    bitstream as specified by :ref:`mpeg2part2`.
+
+.. c:type:: v4l2_ctrl_mpeg2_sequence
+
+.. raw:: latex
+
+    \small
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_sequence
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u16
+      - ``horizontal_size``
+      - The width of the displayable part of the frame's luminance component.
+    * - __u16
+      - ``vertical_size``
+      - The height of the displayable part of the frame's luminance component.
+    * - __u32
+      - ``vbv_buffer_size``
+      - Used to calculate the required size of the video buffering verifier,
+	defined (in bits) as: 16 * 1024 * vbv_buffer_size.
+    * - __u16
+      - ``profile_and_level_indication``
+      - The current profile and level indication as extracted from the
+	bitstream.
+    * - __u8
+      - ``chroma_format``
+      - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
+    * - __u8
+      - ``reserved``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
+
+.. _mpeg2_sequence_flags:
+
+``MPEG-2 Sequence Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE``
+      - 0x00000001
+      - Indication that all the frames for the sequence are progressive instead
+	of interlaced.
+
+.. raw:: latex
+
+    \normalsize
+
+``V4L2_CID_STATELESS_MPEG2_PICTURE (struct)``
+    Specifies the picture parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes fields matching the syntax
+    elements from the picture header and picture coding extension parts of the
+    bitstream as specified by :ref:`mpeg2part2`.
+
+.. c:type:: v4l2_ctrl_mpeg2_picture
+
+.. raw:: latex
+
+    \small
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}|
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_picture
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u64
+      - ``backward_ref_ts``
+      - Timestamp of the V4L2 capture buffer to use as backward reference, used
+        with B-coded and P-coded frames. The timestamp refers to the
+	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
+	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
+	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``forward_ref_ts``
+      - Timestamp for the V4L2 capture buffer to use as forward reference, used
+        with B-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u8
+      - ``picture_coding_type``
+      - Picture coding type for the frame covered by the current slice
+	(V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or
+	V4L2_MPEG2_PICTURE_CODING_TYPE_B).
+    * - __u8
+      - ``f_code[2][2]``
+      - Motion vector codes.
+    * - __u8
+      - ``intra_dc_precision``
+      - Precision of Discrete Cosine transform (0: 8 bits precision,
+	1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision).
+    * - __u8
+      - ``picture_structure``
+      - Picture structure (1: interlaced top field, 2: interlaced bottom field,
+	3: progressive frame).
+    * - __u8
+      - ``reserved``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
+
+
+.. _mpeg2_picture_flags:
+
+``MPEG-2 Picture Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST``
+      - 0x00000001
+      - If set and it's an interlaced stream, top field is output first.
+    * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT``
+      - 0x00000002
+      - If set only frame-DCT and frame prediction are used.
+    * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV``
+      - 0x00000004
+      -  If set motion vectors are coded for intra macroblocks.
+    * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE``
+      - 0x00000008
+      - This flag affects the inverse quantization process.
+    * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC``
+      - 0x00000010
+      - This flag affects the decoding of transform coefficient data.
+    * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN``
+      - 0x00000020
+      - This flag affects the decoding of transform coefficient data.
+    * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST``
+      - 0x00000040
+      - This flag affects the decoding process of progressive frames.
+    * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE``
+      - 0x00000080
+      - Indicates whether the current frame is progressive.
+
+.. raw:: latex
+
+    \normalsize
+
+``V4L2_CID_STATELESS_MPEG2_QUANTISATION (struct)``
+    Specifies quantisation matrices, in zigzag scanning order, for the
+    associated MPEG-2 slice data. This control is initialized by the kernel
+    to the matrices default values. If a bitstream transmits a user-defined
+    quantisation matrices load, applications are expected to use this control.
+    Applications are also expected to set the control loading the default
+    values, if the quantisation matrices need to be reset, for instance on a
+    sequence header. This process is specified by section 6.3.7.
+    "Quant matrix extension" of the specification.
+
+.. c:type:: v4l2_ctrl_mpeg2_quantisation
+
+.. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}|
+
+.. cssclass:: longtable
+
+.. raw:: latex
+
+    \small
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``intra_quantiser_matrix[64]``
+      - The quantisation matrix coefficients for intra-coded frames, in zigzag
+	scanning order. It is relevant for both luma and chroma components,
+	although it can be superseded by the chroma-specific matrix for
+	non-4:2:0 YUV formats.
+    * - __u8
+      - ``non_intra_quantiser_matrix[64]``
+      - The quantisation matrix coefficients for non-intra-coded frames, in
+	zigzag scanning order. It is relevant for both luma and chroma
+	components, although it can be superseded by the chroma-specific matrix
+	for non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_intra_quantiser_matrix[64]``
+      - The quantisation matrix coefficients for the chominance component of
+	intra-coded frames, in zigzag scanning order. Only relevant for
+	non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_non_intra_quantiser_matrix[64]``
+      - The quantisation matrix coefficients for the chrominance component of
+	non-intra-coded frames, in zigzag scanning order. Only relevant for
+	non-4:2:0 YUV formats.
+
+.. raw:: latex
+
+    \normalsize
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 7d3bfdbed4ec..2664025e0199 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -1573,225 +1573,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 ``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR (integer)``
     Indicates bit rate (bps) for hierarchical coding layer 6 for H264 encoder.
 
-.. _v4l2-mpeg-mpeg2:
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)``
-    Specifies the sequence parameters (as extracted from the bitstream) for the
-    associated MPEG-2 slice data. This includes fields matching the syntax
-    elements from the sequence header and sequence extension parts of the
-    bitstream as specified by :ref:`mpeg2part2`.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_sequence
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}|
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_sequence
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u16
-      - ``horizontal_size``
-      - The width of the displayable part of the frame's luminance component.
-    * - __u16
-      - ``vertical_size``
-      - The height of the displayable part of the frame's luminance component.
-    * - __u32
-      - ``vbv_buffer_size``
-      - Used to calculate the required size of the video buffering verifier,
-	defined (in bits) as: 16 * 1024 * vbv_buffer_size.
-    * - __u16
-      - ``profile_and_level_indication``
-      - The current profile and level indication as extracted from the
-	bitstream.
-    * - __u8
-      - ``chroma_format``
-      - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
-    * - __u8
-      - ``reserved``
-      - Applications and drivers must set this to zero.
-    * - __u32
-      - ``flags``
-      - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
-
-.. _mpeg2_sequence_flags:
-
-``MPEG-2 Sequence Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE``
-      - 0x00000001
-      - Indication that all the frames for the sequence are progressive instead
-	of interlaced.
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (struct)``
-    Specifies the picture parameters (as extracted from the bitstream) for the
-    associated MPEG-2 slice data. This includes fields matching the syntax
-    elements from the picture header and picture coding extension parts of the
-    bitstream as specified by :ref:`mpeg2part2`.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_picture
-
-.. raw:: latex
-
-    \small
-
-.. cssclass:: longtable
-
-.. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}|
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_picture
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u64
-      - ``backward_ref_ts``
-      - Timestamp of the V4L2 capture buffer to use as backward reference, used
-        with B-coded and P-coded frames. The timestamp refers to the
-	``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
-	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
-	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
-    * - __u64
-      - ``forward_ref_ts``
-      - Timestamp for the V4L2 capture buffer to use as forward reference, used
-        with B-coded frames. The timestamp refers to the ``timestamp`` field in
-	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
-	function to convert the struct :c:type:`timeval` in struct
-	:c:type:`v4l2_buffer` to a __u64.
-    * - __u8
-      - ``picture_coding_type``
-      - Picture coding type for the frame covered by the current slice
-	(V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or
-	V4L2_MPEG2_PICTURE_CODING_TYPE_B).
-    * - __u8
-      - ``f_code[2][2]``
-      - Motion vector codes.
-    * - __u8
-      - ``intra_dc_precision``
-      - Precision of Discrete Cosine transform (0: 8 bits precision,
-	1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision).
-    * - __u8
-      - ``picture_structure``
-      - Picture structure (1: interlaced top field, 2: interlaced bottom field,
-	3: progressive frame).
-    * - __u8
-      - ``reserved``
-      - Applications and drivers must set this to zero.
-    * - __u32
-      - ``flags``
-      - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
-
-
-.. _mpeg2_picture_flags:
-
-``MPEG-2 Picture Flags``
-
-.. cssclass:: longtable
-
-.. flat-table::
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST``
-      - 0x00000001
-      - If set and it's an interlaced stream, top field is output first.
-    * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT``
-      - 0x00000002
-      - If set only frame-DCT and frame prediction are used.
-    * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV``
-      - 0x00000004
-      -  If set motion vectors are coded for intra macroblocks.
-    * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE``
-      - 0x00000008
-      - This flag affects the inverse quantization process.
-    * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC``
-      - 0x00000010
-      - This flag affects the decoding of transform coefficient data.
-    * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN``
-      - 0x00000020
-      - This flag affects the decoding of transform coefficient data.
-    * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST``
-      - 0x00000040
-      - This flag affects the decoding process of progressive frames.
-    * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE``
-      - 0x00000080
-      - Indicates whether the current frame is progressive.
-
-.. raw:: latex
-
-    \normalsize
-
-``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (struct)``
-    Specifies quantisation matrices (as extracted from the bitstream) for the
-    associated MPEG-2 slice data.
-
-    .. note::
-
-       This compound control is not yet part of the public kernel API and
-       it is expected to change.
-
-.. c:type:: v4l2_ctrl_mpeg2_quantisation
-
-.. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}|
-
-.. cssclass:: longtable
-
-.. raw:: latex
-
-    \small
-
-.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       1 1 2
-
-    * - __u8
-      - ``intra_quantiser_matrix[64]``
-      - The quantisation matrix coefficients for intra-coded frames, in zigzag
-	scanning order. It is relevant for both luma and chroma components,
-	although it can be superseded by the chroma-specific matrix for
-	non-4:2:0 YUV formats.
-    * - __u8
-      - ``non_intra_quantiser_matrix[64]``
-      - The quantisation matrix coefficients for non-intra-coded frames, in
-	zigzag scanning order. It is relevant for both luma and chroma
-	components, although it can be superseded by the chroma-specific matrix
-	for non-4:2:0 YUV formats.
-    * - __u8
-      - ``chroma_intra_quantiser_matrix[64]``
-      - The quantisation matrix coefficients for the chominance component of
-	intra-coded frames, in zigzag scanning order. Only relevant for
-	non-4:2:0 YUV formats.
-    * - __u8
-      - ``chroma_non_intra_quantiser_matrix[64]``
-      - The quantisation matrix coefficients for the chrominance component of
-	non-intra-coded frames, in zigzag scanning order. Only relevant for
-	non-4:2:0 YUV formats.
-
-.. raw:: latex
-
-    \normalsize
-
 ``V4L2_CID_FWHT_I_FRAME_QP (integer)``
     Quantization parameter for an I frame for FWHT. Valid range: from 1
     to 31.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index 6c10a062adac..0ede39907ee2 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -112,13 +112,13 @@ Compressed Formats
       - 'MG2S'
       - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream.
 	This format is adapted for stateless video decoders that implement a
-	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	MPEG-2 pipeline with the :ref:`stateless_decoder`.
 	Metadata associated with the frame to decode is required to be passed
-	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE`` and
-        ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE`` controls.
+	through the ``V4L2_CID_STATELESS_MPEG2_SEQUENCE`` and
+        ``V4L2_CID_STATELESS_MPEG2_PICTURE`` controls.
         Quantisation matrices can optionally be specified through the
-	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control.
-	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
+	``V4L2_CID_STATELESS_MPEG2_QUANTISATION`` control.
+	See the :ref:`associated Codec Control IDs <v4l2-codec-stateless-mpeg2>`.
 	Exactly one output and one capture buffer must be provided for use with
 	this pixel format. The output buffer must contain the appropriate number
 	of macroblocks to decode a full corresponding frame to the matching
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index c50a76c70491..58d5961ed099 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -221,6 +221,18 @@ still cause this situation.
       - ``p_vp8_frame``
       - A pointer to a struct :c:type:`v4l2_ctrl_vp8_frame`. Valid if this control is
         of type ``V4L2_CTRL_TYPE_VP8_FRAME``.
+    * - struct :c:type:`v4l2_ctrl_mpeg2_sequence` *
+      - ``p_mpeg2_sequence``
+      - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_sequence`. Valid if this control is
+        of type ``V4L2_CTRL_TYPE_MPEG2_SEQUENCE``.
+    * - struct :c:type:`v4l2_ctrl_mpeg2_picture` *
+      - ``p_mpeg2_picture``
+      - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_picture`. Valid if this control is
+        of type ``V4L2_CTRL_TYPE_MPEG2_PICTURE``.
+    * - struct :c:type:`v4l2_ctrl_mpeg2_quantisation` *
+      - ``p_mpeg2_quantisation``
+      - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_quantisation`. Valid if this control is
+        of type ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``.
     * - void *
       - ``ptr``
       - A pointer to a compound type which can be an N-dimensional array
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 722a208c647e..930761e7a83c 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -973,9 +973,6 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:		return "Repeat Sequence Header";
 	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:		return "Force Key Frame";
 	case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID:		return "Base Layer Priority ID";
-	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:		return "MPEG-2 Sequence Header";
-	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
-	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
 	case V4L2_CID_FWHT_I_FRAME_QP:				return "FWHT I-Frame QP Value";
 	case V4L2_CID_FWHT_P_FRAME_QP:				return "FWHT P-Frame QP Value";
 
@@ -1224,6 +1221,9 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_STATELESS_H264_DECODE_PARAMS:		return "H264 Decode Parameters";
 	case V4L2_CID_STATELESS_FWHT_PARAMS:			return "FWHT Stateless Parameters";
 	case V4L2_CID_STATELESS_VP8_FRAME:			return "VP8 Frame Parameters";
+	case V4L2_CID_STATELESS_MPEG2_SEQUENCE:			return "MPEG-2 Sequence Header";
+	case V4L2_CID_STATELESS_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
+	case V4L2_CID_STATELESS_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
 	default:
 		return NULL;
 	}
@@ -1470,13 +1470,13 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_RDS_TX_ALT_FREQS:
 		*type = V4L2_CTRL_TYPE_U32;
 		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:
+	case V4L2_CID_STATELESS_MPEG2_SEQUENCE:
 		*type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE;
 		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:
+	case V4L2_CID_STATELESS_MPEG2_PICTURE:
 		*type = V4L2_CTRL_TYPE_MPEG2_PICTURE;
 		break;
-	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:
+	case V4L2_CID_STATELESS_MPEG2_QUANTISATION:
 		*type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION;
 		break;
 	case V4L2_CID_STATELESS_FWHT_PARAMS:
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index f5fa7e0940c4..b48552bddb3a 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -289,17 +289,17 @@ static const struct hantro_ctrl controls[] = {
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
+			.id = V4L2_CID_STATELESS_MPEG2_SEQUENCE,
 		},
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
+			.id = V4L2_CID_STATELESS_MPEG2_PICTURE,
 		},
 	}, {
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION,
+			.id = V4L2_CID_STATELESS_MPEG2_QUANTISATION,
 		},
 	}, {
 		.codec = HANTRO_VP8_DECODER,
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index 6d89cae7df45..f565e37e397a 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -83,7 +83,7 @@ hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 {
 	struct v4l2_ctrl_mpeg2_quantisation *q;
 
-	q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
+	q = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_MPEG2_QUANTISATION);
 	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q);
 	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, G1_REG_QTABLE_BASE);
 }
@@ -160,9 +160,9 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
 	hantro_start_prepare_run(ctx);
 
 	seq = hantro_get_ctrl(ctx,
-			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+			      V4L2_CID_STATELESS_MPEG2_SEQUENCE);
 	pic = hantro_get_ctrl(ctx,
-			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
+			      V4L2_CID_STATELESS_MPEG2_PICTURE);
 
 	reg = G1_REG_DEC_AXI_RD_ID(0) |
 	      G1_REG_DEC_TIMEOUT_E(1) |
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index d16d76760278..2527dce7eb18 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -85,7 +85,7 @@ rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
 {
 	struct v4l2_ctrl_mpeg2_quantisation *q;
 
-	q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
+	q = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_MPEG2_QUANTISATION);
 	hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q);
 	vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, VDPU_REG_QTABLE_BASE);
 }
@@ -162,9 +162,9 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
 	hantro_start_prepare_run(ctx);
 
 	seq = hantro_get_ctrl(ctx,
-			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+			      V4L2_CID_STATELESS_MPEG2_SEQUENCE);
 	pic = hantro_get_ctrl(ctx,
-			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
+			      V4L2_CID_STATELESS_MPEG2_PICTURE);
 
 	reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
 	      VDPU_REG_DEC_SCMD_DIS(0) |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 4430c8fa2cc7..fa348c09f844 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -31,19 +31,19 @@
 static const struct cedrus_control cedrus_controls[] = {
 	{
 		.cfg = {
-			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
+			.id	= V4L2_CID_STATELESS_MPEG2_SEQUENCE,
 		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 	},
 	{
 		.cfg = {
-			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
+			.id	= V4L2_CID_STATELESS_MPEG2_PICTURE,
 		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 	},
 	{
 		.cfg = {
-			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION,
+			.id	= V4L2_CID_STATELESS_MPEG2_QUANTISATION,
 		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 	},
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index e98185c1f5a7..97e410d92506 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -41,11 +41,11 @@ void cedrus_device_run(void *priv)
 	switch (ctx->src_fmt.pixelformat) {
 	case V4L2_PIX_FMT_MPEG2_SLICE:
 		run.mpeg2.sequence = cedrus_find_control_data(ctx,
-			V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
+			V4L2_CID_STATELESS_MPEG2_SEQUENCE);
 		run.mpeg2.picture = cedrus_find_control_data(ctx,
-			V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
+			V4L2_CID_STATELESS_MPEG2_PICTURE);
 		run.mpeg2.quantisation = cedrus_find_control_data(ctx,
-			V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION);
+			V4L2_CID_STATELESS_MPEG2_QUANTISATION);
 		break;
 
 	case V4L2_PIX_FMT_H264_SLICE:
diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
deleted file mode 100644
index 0b0ac8fcd220..000000000000
--- a/include/media/mpeg2-ctrls.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * These are the MPEG2 state controls for use with stateless MPEG-2
- * codec drivers.
- *
- * It turns out that these structs are not stable yet and will undergo
- * more changes. So keep them private until they are stable and ready to
- * become part of the official public API.
- */
-
-#ifndef _MPEG2_CTRLS_H_
-#define _MPEG2_CTRLS_H_
-
-#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION		(V4L2_CID_CODEC_BASE+251)
-#define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE		(V4L2_CID_CODEC_BASE+252)
-#define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE		(V4L2_CID_CODEC_BASE+253)
-
-/* enum v4l2_ctrl_type type values */
-#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
-
-/**
- * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header
- *
- * All the members on this structure match the sequence header and sequence
- * extension syntaxes as specified by the MPEG-2 specification.
- *
- * Fields horizontal_size, vertical_size and vbv_buffer_size are a
- * combination of respective _value and extension syntax elements,
- * as described in section 6.3.3 "Sequence header".
- *
- * @horizontal_size: combination of elements horizontal_size_value and
- * horizontal_size_extension.
- * @vertical_size: combination of elements vertical_size_value and
- * vertical_size_extension.
- * @vbv_buffer_size: combination of elements vbv_buffer_size_value and
- * vbv_buffer_size_extension.
- * @profile_and_level_indication: see MPEG-2 specification.
- * @chroma_format: see MPEG-2 specification.
- * @reserved: padding field. Should be zeroed by applications.
- * @flags: see V4L2_MPEG2_SEQ_FLAG_{}.
- */
-struct v4l2_ctrl_mpeg2_sequence {
-	__u16	horizontal_size;
-	__u16	vertical_size;
-	__u32	vbv_buffer_size;
-	__u16	profile_and_level_indication;
-	__u8	chroma_format;
-	__u8	reserved;
-	__u32	flags;
-};
-
-#define V4L2_MPEG2_PIC_CODING_TYPE_I			1
-#define V4L2_MPEG2_PIC_CODING_TYPE_P			2
-#define V4L2_MPEG2_PIC_CODING_TYPE_B			3
-#define V4L2_MPEG2_PIC_CODING_TYPE_D			4
-
-#define V4L2_MPEG2_PIC_TOP_FIELD			0x1
-#define V4L2_MPEG2_PIC_BOTTOM_FIELD			0x2
-#define V4L2_MPEG2_PIC_FRAME				0x3
-
-#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST		0x0001
-#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT		0x0002
-#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV		0x0004
-#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE		0x0008
-#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC			0x0010
-#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN			0x0020
-#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
-#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
-
-/**
- * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header
- *
- * All the members on this structure match the picture header and picture
- * coding extension syntaxes as specified by the MPEG-2 specification.
- *
- * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
- * reference for backward prediction.
- * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
- * reference for forward prediction. These timestamp refers to the
- * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
- * to convert the struct timeval to a __u64.
- * @picture_coding_type: see MPEG-2 specification.
- * @f_code[2][2]: see MPEG-2 specification.
- * @intra_dc_precision: see MPEG-2 specification.
- * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD.
- * @reserved: padding field. Should be zeroed by applications.
- * @flags: see V4L2_MPEG2_PIC_FLAG_{}.
- */
-struct v4l2_ctrl_mpeg2_picture {
-	__u64	backward_ref_ts;
-	__u64	forward_ref_ts;
-	__u8	picture_coding_type;
-	__u8	f_code[2][2];
-	__u8	intra_dc_precision;
-	__u8	picture_structure;
-	__u8	reserved;
-	__u32	flags;
-};
-
-/**
- * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation
- *
- * Quantization matrices as specified by section 6.3.7
- * "Quant matrix extension".
- *
- * @intra_quantiser_matrix: The quantisation matrix coefficients
- * for intra-coded frames, in zigzag scanning order. It is relevant
- * for both luma and chroma components, although it can be superseded
- * by the chroma-specific matrix for non-4:2:0 YUV formats.
- * @non_intra_quantiser_matrix: The quantisation matrix coefficients
- * for non-intra-coded frames, in zigzag scanning order. It is relevant
- * for both luma and chroma components, although it can be superseded
- * by the chroma-specific matrix for non-4:2:0 YUV formats.
- * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients
- * for the chominance component of intra-coded frames, in zigzag scanning
- * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
- * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients
- * for the chrominance component of non-intra-coded frames, in zigzag scanning
- * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
- */
-struct v4l2_ctrl_mpeg2_quantisation {
-	__u8	intra_quantiser_matrix[64];
-	__u8	non_intra_quantiser_matrix[64];
-	__u8	chroma_intra_quantiser_matrix[64];
-	__u8	chroma_non_intra_quantiser_matrix[64];
-};
-
-#endif
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index cd9846657bbb..0923eb60f075 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -17,7 +17,6 @@
  * Include the stateless codec compound control definitions.
  * This will move to the public headers once this API is fully stable.
  */
-#include <media/mpeg2-ctrls.h>
 #include <media/hevc-ctrls.h>
 
 /* forward references */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index f3376aafea65..8b171b536d2c 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1857,6 +1857,120 @@ struct v4l2_ctrl_vp8_frame {
 	__u64 flags;
 };
 
+/* Stateless MPEG-2 controls */
+
+#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE	0x0001
+
+#define V4L2_CID_STATELESS_MPEG2_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE+220)
+/**
+ * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header
+ *
+ * All the members on this structure match the sequence header and sequence
+ * extension syntaxes as specified by the MPEG-2 specification.
+ *
+ * Fields horizontal_size, vertical_size and vbv_buffer_size are a
+ * combination of respective _value and extension syntax elements,
+ * as described in section 6.3.3 "Sequence header".
+ *
+ * @horizontal_size: combination of elements horizontal_size_value and
+ * horizontal_size_extension.
+ * @vertical_size: combination of elements vertical_size_value and
+ * vertical_size_extension.
+ * @vbv_buffer_size: combination of elements vbv_buffer_size_value and
+ * vbv_buffer_size_extension.
+ * @profile_and_level_indication: see MPEG-2 specification.
+ * @chroma_format: see MPEG-2 specification.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @flags: see V4L2_MPEG2_SEQ_FLAG_{}.
+ */
+struct v4l2_ctrl_mpeg2_sequence {
+	__u16	horizontal_size;
+	__u16	vertical_size;
+	__u32	vbv_buffer_size;
+	__u16	profile_and_level_indication;
+	__u8	chroma_format;
+	__u8	reserved;
+	__u32	flags;
+};
+
+#define V4L2_MPEG2_PIC_CODING_TYPE_I			1
+#define V4L2_MPEG2_PIC_CODING_TYPE_P			2
+#define V4L2_MPEG2_PIC_CODING_TYPE_B			3
+#define V4L2_MPEG2_PIC_CODING_TYPE_D			4
+
+#define V4L2_MPEG2_PIC_TOP_FIELD			0x1
+#define V4L2_MPEG2_PIC_BOTTOM_FIELD			0x2
+#define V4L2_MPEG2_PIC_FRAME				0x3
+
+#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST		0x0001
+#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT		0x0002
+#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV		0x0004
+#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE		0x0008
+#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC			0x0010
+#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN			0x0020
+#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
+#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
+
+#define V4L2_CID_STATELESS_MPEG2_PICTURE (V4L2_CID_CODEC_STATELESS_BASE+221)
+/**
+ * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header
+ *
+ * All the members on this structure match the picture header and picture
+ * coding extension syntaxes as specified by the MPEG-2 specification.
+ *
+ * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for backward prediction.
+ * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
+ * reference for forward prediction. These timestamp refers to the
+ * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
+ * to convert the struct timeval to a __u64.
+ * @picture_coding_type: see MPEG-2 specification.
+ * @f_code: see MPEG-2 specification.
+ * @intra_dc_precision: see MPEG-2 specification.
+ * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @flags: see V4L2_MPEG2_PIC_FLAG_{}.
+ */
+struct v4l2_ctrl_mpeg2_picture {
+	__u64	backward_ref_ts;
+	__u64	forward_ref_ts;
+	__u8	picture_coding_type;
+	__u8	f_code[2][2];
+	__u8	intra_dc_precision;
+	__u8	picture_structure;
+	__u8	reserved;
+	__u32	flags;
+};
+
+#define V4L2_CID_STATELESS_MPEG2_QUANTISATION (V4L2_CID_CODEC_STATELESS_BASE+222)
+/**
+ * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation
+ *
+ * Quantisation matrices as specified by section 6.3.7
+ * "Quant matrix extension".
+ *
+ * @intra_quantiser_matrix: The quantisation matrix coefficients
+ * for intra-coded frames, in zigzag scanning order. It is relevant
+ * for both luma and chroma components, although it can be superseded
+ * by the chroma-specific matrix for non-4:2:0 YUV formats.
+ * @non_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for non-intra-coded frames, in zigzag scanning order. It is relevant
+ * for both luma and chroma components, although it can be superseded
+ * by the chroma-specific matrix for non-4:2:0 YUV formats.
+ * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for the chominance component of intra-coded frames, in zigzag scanning
+ * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
+ * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients
+ * for the chrominance component of non-intra-coded frames, in zigzag scanning
+ * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
+ */
+struct v4l2_ctrl_mpeg2_quantisation {
+	__u8	intra_quantiser_matrix[64];
+	__u8	non_intra_quantiser_matrix[64];
+	__u8	chroma_intra_quantiser_matrix[64];
+	__u8	chroma_non_intra_quantiser_matrix[64];
+};
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEG            V4L2_CTRL_CLASS_CODEC
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 2206f3cd28a4..5d559becf358 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1747,6 +1747,9 @@ struct v4l2_ext_control {
 		struct v4l2_ctrl_h264_decode_params __user *p_h264_decode_params;
 		struct v4l2_ctrl_fwht_params __user *p_fwht_params;
 		struct v4l2_ctrl_vp8_frame __user *p_vp8_frame;
+		struct v4l2_ctrl_mpeg2_sequence __user *p_mpeg2_sequence;
+		struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture;
+		struct v4l2_ctrl_mpeg2_quantisation __user *p_mpeg2_quantisation;
 		void __user *ptr;
 	};
 } __attribute__ ((packed));
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics
  2021-04-03 18:07 ` [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics Ezequiel Garcia
@ 2021-04-06 10:25   ` Hans Verkuil
  0 siblings, 0 replies; 14+ messages in thread
From: Hans Verkuil @ 2021-04-06 10:25 UTC (permalink / raw)
  To: Ezequiel Garcia, linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Nicolas Dufresne, Philipp Zabel,
	Maxime Ripard, Paul Kocialkowski, Jernej Skrabec, Daniel Almeida

On 03/04/2021 20:07, Ezequiel Garcia wrote:
> As stated in the MPEG-2 specification, section 6.3.7 "Quant matrix
> extension":
> 
>   Each quantisation matrix has a default set of values. When a
>   sequence_header_code is decoded all matrices shall be reset to
>   their default values. User defined matrices may be downloaded
>   and this can occur in a sequence_header() or in a
>   quant_matrix_extension().
> 
> The load_intra_quantiser_matrix syntax elements are transmitted
> in the bistream headers, signalling that a quantisation matrix

bistream -> bitstream

> needs to be loaded and used for pictures transmitted afterwards
> (until the matrices are reset).
> 
> This "load" semantics are implemented in the V4L2 interface
> without the need of any "load" flags: passing the control
> is effectively a load.
> 
> Therefore, rework the V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION
> semantics to match the MPEG-2 semantics. Quantisation matrices
> values are now initialized by the V4L2 control core to their
> reset default value, and applications are expected to reset
> their values as specified.
> 
> The quantisation control is therefore optional, and used to
> load bitstream-defined values in the quantisation matrices.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Co-developed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
>  .../media/v4l/ext-ctrls-codec.rst             | 17 ---------
>  drivers/media/v4l2-core/v4l2-ctrls.c          | 21 ++++++++++
>  .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 38 +------------------
>  include/media/mpeg2-ctrls.h                   |  5 ---
>  4 files changed, 23 insertions(+), 58 deletions(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index 151d1c676b6e..d9546f0aa2e8 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -1746,23 +1746,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>      :stub-columns: 0
>      :widths:       1 1 2
>  
> -    * - __u8
> -      - ``load_intra_quantiser_matrix``
> -      - One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
> -    * - __u8
> -      - ``load_non_intra_quantiser_matrix``
> -      - One bit to indicate whether to load the ``non_intra_quantiser_matrix``
> -	data.
> -    * - __u8
> -      - ``load_chroma_intra_quantiser_matrix``
> -      - One bit to indicate whether to load the
> -	``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
> -	formats.
> -    * - __u8
> -      - ``load_chroma_non_intra_quantiser_matrix``
> -      - One bit to indicate whether to load the
> -	``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
> -	YUV formats.
>      * - __u8
>        - ``intra_quantiser_matrix[64]``
>        - The quantisation matrix coefficients for intra-coded frames, in zigzag
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index 74f5ca1a5f6c..5d92a2b33a6e 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -57,6 +57,18 @@ static bool is_new_manual(const struct v4l2_ctrl *master)
>  	return master->is_auto && master->val == master->manual_mode_value;
>  }
>  
> +/* Default MPEG-2 quantisation coefficients, from the specification. */

Default -> Default intra

> +static const u8 mpeg2_intra_quant_matrix[64] = {
> +	8,  16, 16, 19, 16, 19, 22, 22,
> +	22, 22, 22, 22, 26, 24, 26, 27,
> +	27, 27, 26, 26, 26, 26, 27, 27,
> +	27, 29, 29, 29, 34, 34, 34, 29,
> +	29, 29, 27, 27, 29, 29, 32, 32,
> +	34, 34, 37, 38, 37, 35, 35, 34,
> +	35, 38, 38, 40, 40, 40, 48, 48,
> +	46, 46, 56, 56, 58, 69, 69, 83
> +};
> +
>  /* Returns NULL or a character pointer array containing the menu for
>     the given control ID. The pointer array ends with a NULL pointer.
>     An empty string signifies a menu entry that is invalid. This allows
> @@ -1656,6 +1668,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  			      union v4l2_ctrl_ptr ptr)
>  {
>  	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> +	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
>  	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
>  	struct v4l2_ctrl_fwht_params *p_fwht_params;
>  	void *p = ptr.p + idx * ctrl->elem_size;
> @@ -1680,6 +1693,14 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  		p_mpeg2_slice_params->picture.picture_coding_type =
>  					V4L2_MPEG2_PICTURE_CODING_TYPE_I;
>  		break;
> +	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
> +		p_mpeg2_quant = p;
> +
> +		memcpy(p_mpeg2_quant->intra_quantiser_matrix,
> +		       mpeg2_intra_quant_matrix,
> +		       ARRAY_SIZE(mpeg2_intra_quant_matrix));
> +		memset(p_mpeg2_quant->non_intra_quantiser_matrix, 16, 64);

64 -> sizeof(p_mpeg2_quant->non_intra_quantiser_matrix)

Also add a comment before the memset:

	/*
	 * The default non-intra MPEG-2 quantisation coefficients are all 16,
	 * as per the specification.
	 */

> +		break;
>  	case V4L2_CTRL_TYPE_VP8_FRAME:
>  		p_vp8_frame = p;
>  		p_vp8_frame->num_dct_parts = 1;
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> index 459f71679a4f..e3154f631858 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> @@ -13,30 +13,6 @@
>  #include "cedrus_hw.h"
>  #include "cedrus_regs.h"
>  
> -/* Default MPEG-2 quantisation coefficients, from the specification. */
> -
> -static const u8 intra_quantisation_matrix_default[64] = {
> -	8,  16, 16, 19, 16, 19, 22, 22,
> -	22, 22, 22, 22, 26, 24, 26, 27,
> -	27, 27, 26, 26, 26, 26, 27, 27,
> -	27, 29, 29, 29, 34, 34, 34, 29,
> -	29, 29, 27, 27, 29, 29, 32, 32,
> -	34, 34, 37, 38, 37, 35, 35, 34,
> -	35, 38, 38, 40, 40, 40, 48, 48,
> -	46, 46, 56, 56, 58, 69, 69, 83
> -};
> -
> -static const u8 non_intra_quantisation_matrix_default[64] = {
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16,
> -	16, 16, 16, 16, 16, 16, 16, 16
> -};
> -
>  static enum cedrus_irq_status cedrus_mpeg2_irq_status(struct cedrus_ctx *ctx)
>  {
>  	struct cedrus_dev *dev = ctx->dev;
> @@ -99,12 +75,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  	cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2);
>  
>  	/* Set intra quantisation matrix. */
> -
> -	if (quantisation && quantisation->load_intra_quantiser_matrix)
> -		matrix = quantisation->intra_quantiser_matrix;
> -	else
> -		matrix = intra_quantisation_matrix_default;
> -
> +	matrix = quantisation->intra_quantiser_matrix;
>  	for (i = 0; i < 64; i++) {
>  		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
>  		reg |= VE_DEC_MPEG_IQMINPUT_FLAG_INTRA;
> @@ -113,12 +84,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  	}
>  
>  	/* Set non-intra quantisation matrix. */
> -
> -	if (quantisation && quantisation->load_non_intra_quantiser_matrix)
> -		matrix = quantisation->non_intra_quantiser_matrix;
> -	else
> -		matrix = non_intra_quantisation_matrix_default;
> -
> +	matrix = quantisation->non_intra_quantiser_matrix;
>  	for (i = 0; i < 64; i++) {
>  		reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
>  		reg |= VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA;
> diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
> index b8adf3ac2c1d..8ea2c7f3a172 100644
> --- a/include/media/mpeg2-ctrls.h
> +++ b/include/media/mpeg2-ctrls.h
> @@ -68,11 +68,6 @@ struct v4l2_ctrl_mpeg2_slice_params {
>  
>  struct v4l2_ctrl_mpeg2_quantisation {
>  	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
> -	__u8	load_intra_quantiser_matrix;
> -	__u8	load_non_intra_quantiser_matrix;
> -	__u8	load_chroma_intra_quantiser_matrix;
> -	__u8	load_chroma_non_intra_quantiser_matrix;
> -
>  	__u8	intra_quantiser_matrix[64];
>  	__u8	non_intra_quantiser_matrix[64];
>  	__u8	chroma_intra_quantiser_matrix[64];
> 

Regards,

	Hans

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags
  2021-04-03 18:07 ` [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags Ezequiel Garcia
@ 2021-04-06 10:27   ` Hans Verkuil
  0 siblings, 0 replies; 14+ messages in thread
From: Hans Verkuil @ 2021-04-06 10:27 UTC (permalink / raw)
  To: Ezequiel Garcia, linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Nicolas Dufresne, Philipp Zabel,
	Maxime Ripard, Paul Kocialkowski, Jernej Skrabec, Daniel Almeida

On 03/04/2021 20:07, Ezequiel Garcia wrote:
> Our current MPEG-2 uAPI uses 1-byte fields for MPEG-2
> boolean syntax elements. Clean these by adding a 'flags'
> field and flag macro for each boolean syntax element.
> 
> A follow-up change will refactor this uAPI so we don't need
> to add padding fields just yet.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Tested-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  .../media/v4l/ext-ctrls-codec.rst             |  77 +-
>  drivers/media/v4l2-core/v4l2-async-core.c     | 880 ++++++++++++++++++

This doesn't belong in this patch!

Regards,

	Hans

>  drivers/media/v4l2-core/v4l2-ctrls.c          |  14 +-
>  .../media/hantro/hantro_g1_mpeg2_dec.c        |  76 +-
>  .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |  76 +-
>  .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  38 +-
>  include/media/mpeg2-ctrls.h                   |  36 +-
>  7 files changed, 1055 insertions(+), 142 deletions(-)
>  create mode 100644 drivers/media/v4l2-core/v4l2-async-core.c
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index d9546f0aa2e8..7d5ac7fb6579 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -1654,13 +1654,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>        - ``profile_and_level_indication``
>        - The current profile and level indication as extracted from the
>  	bitstream.
> -    * - __u8
> -      - ``progressive_sequence``
> -      - Indication that all the frames for the sequence are progressive instead
> -	of interlaced.
>      * - __u8
>        - ``chroma_format``
>        - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
> +    * - __u32
> +      - ``flags``
> +      - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
> +
> +.. _mpeg2_sequence_flags:
> +
> +``MPEG-2 Sequence Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE``
> +      - 0x00000001
> +      - Indication that all the frames for the sequence are progressive instead
> +	of interlaced.
>  
>  .. c:type:: v4l2_mpeg2_picture
>  
> @@ -1693,29 +1708,45 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>        - ``picture_structure``
>        - Picture structure (1: interlaced top field, 2: interlaced bottom field,
>  	3: progressive frame).
> -    * - __u8
> -      - ``top_field_first``
> -      - If set to 1 and interlaced stream, top field is output first.
> -    * - __u8
> -      - ``frame_pred_frame_dct``
> -      - If set to 1, only frame-DCT and frame prediction are used.
> -    * - __u8
> -      - ``concealment_motion_vectors``
> -      -  If set to 1, motion vectors are coded for intra macroblocks.
> -    * - __u8
> -      - ``q_scale_type``
> +    * - __u32
> +      - ``flags``
> +      - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
> +
> +
> +.. _mpeg2_picture_flags:
> +
> +``MPEG-2 Picture Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST``
> +      - 0x00000001
> +      - If set and it's an interlaced stream, top field is output first.
> +    * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT``
> +      - 0x00000002
> +      - If set only frame-DCT and frame prediction are used.
> +    * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV``
> +      - 0x00000004
> +      -  If set motion vectors are coded for intra macroblocks.
> +    * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE``
> +      - 0x00000008
>        - This flag affects the inverse quantization process.
> -    * - __u8
> -      - ``intra_vlc_format``
> +    * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC``
> +      - 0x00000010
>        - This flag affects the decoding of transform coefficient data.
> -    * - __u8
> -      - ``alternate_scan``
> +    * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN``
> +      - 0x00000020
>        - This flag affects the decoding of transform coefficient data.
> -    * - __u8
> -      - ``repeat_first_field``
> +    * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST``
> +      - 0x00000040
>        - This flag affects the decoding process of progressive frames.
> -    * - __u16
> -      - ``progressive_frame``
> +    * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE``
> +      - 0x00000080
>        - Indicates whether the current frame is progressive.
>  
>  .. raw:: latex
> diff --git a/drivers/media/v4l2-core/v4l2-async-core.c b/drivers/media/v4l2-core/v4l2-async-core.c
> new file mode 100644
> index 000000000000..cd9e78c63791
> --- /dev/null
> +++ b/drivers/media/v4l2-core/v4l2-async-core.c
> @@ -0,0 +1,880 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * V4L2 asynchronous subdevice registration API
> + *
> + * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/list.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/seq_file.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include <media/v4l2-async.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
> +					  struct v4l2_subdev *subdev,
> +					  struct v4l2_async_subdev *asd)
> +{
> +	if (!n->ops || !n->ops->bound)
> +		return 0;
> +
> +	return n->ops->bound(n, subdev, asd);
> +}
> +
> +static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
> +					    struct v4l2_subdev *subdev,
> +					    struct v4l2_async_subdev *asd)
> +{
> +	if (!n->ops || !n->ops->unbind)
> +		return;
> +
> +	n->ops->unbind(n, subdev, asd);
> +}
> +
> +static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
> +{
> +	if (!n->ops || !n->ops->complete)
> +		return 0;
> +
> +	return n->ops->complete(n);
> +}
> +
> +static bool match_i2c(struct v4l2_async_notifier *notifier,
> +		      struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
> +{
> +#if IS_ENABLED(CONFIG_I2C)
> +	struct i2c_client *client = i2c_verify_client(sd->dev);
> +
> +	return client &&
> +		asd->match.i2c.adapter_id == client->adapter->nr &&
> +		asd->match.i2c.address == client->addr;
> +#else
> +	return false;
> +#endif
> +}
> +
> +static bool match_fwnode(struct v4l2_async_notifier *notifier,
> +			 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
> +{
> +	struct fwnode_handle *other_fwnode;
> +	struct fwnode_handle *dev_fwnode;
> +	bool asd_fwnode_is_ep;
> +	bool sd_fwnode_is_ep;
> +	struct device *dev;
> +
> +	/*
> +	 * Both the subdev and the async subdev can provide either an endpoint
> +	 * fwnode or a device fwnode. Start with the simple case of direct
> +	 * fwnode matching.
> +	 */
> +	if (sd->fwnode == asd->match.fwnode)
> +		return true;
> +
> +	/*
> +	 * Check the same situation for any possible secondary assigned to the
> +	 * subdev's fwnode
> +	 */
> +	if (!IS_ERR_OR_NULL(sd->fwnode->secondary) &&
> +	    sd->fwnode->secondary == asd->match.fwnode)
> +		return true;
> +
> +	/*
> +	 * Otherwise, check if the sd fwnode and the asd fwnode refer to an
> +	 * endpoint or a device. If they're of the same type, there's no match.
> +	 * Technically speaking this checks if the nodes refer to a connected
> +	 * endpoint, which is the simplest check that works for both OF and
> +	 * ACPI. This won't make a difference, as drivers should not try to
> +	 * match unconnected endpoints.
> +	 */
> +	sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode);
> +	asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode);
> +
> +	if (sd_fwnode_is_ep == asd_fwnode_is_ep)
> +		return false;
> +
> +	/*
> +	 * The sd and asd fwnodes are of different types. Get the device fwnode
> +	 * parent of the endpoint fwnode, and compare it with the other fwnode.
> +	 */
> +	if (sd_fwnode_is_ep) {
> +		dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode);
> +		other_fwnode = asd->match.fwnode;
> +	} else {
> +		dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode);
> +		other_fwnode = sd->fwnode;
> +	}
> +
> +	fwnode_handle_put(dev_fwnode);
> +
> +	if (dev_fwnode != other_fwnode)
> +		return false;
> +
> +	/*
> +	 * We have a heterogeneous match. Retrieve the struct device of the side
> +	 * that matched on a device fwnode to print its driver name.
> +	 */
> +	if (sd_fwnode_is_ep)
> +		dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev
> +		    : notifier->sd->dev;
> +	else
> +		dev = sd->dev;
> +
> +	if (dev && dev->driver) {
> +		if (sd_fwnode_is_ep)
> +			dev_warn(dev, "Driver %s uses device fwnode, incorrect match may occur\n",
> +				 dev->driver->name);
> +		dev_notice(dev, "Consider updating driver %s to match on endpoints\n",
> +			   dev->driver->name);
> +	}
> +
> +	return true;
> +}
> +
> +static LIST_HEAD(subdev_list);
> +static LIST_HEAD(notifier_list);
> +static DEFINE_MUTEX(list_lock);
> +
> +static struct v4l2_async_subdev *
> +v4l2_async_find_match(struct v4l2_async_notifier *notifier,
> +		      struct v4l2_subdev *sd)
> +{
> +	bool (*match)(struct v4l2_async_notifier *notifier,
> +		      struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);
> +	struct v4l2_async_subdev *asd;
> +
> +	list_for_each_entry(asd, &notifier->waiting, list) {
> +		/* bus_type has been verified valid before */
> +		switch (asd->match_type) {
> +		case V4L2_ASYNC_MATCH_I2C:
> +			match = match_i2c;
> +			break;
> +		case V4L2_ASYNC_MATCH_FWNODE:
> +			match = match_fwnode;
> +			break;
> +		default:
> +			/* Cannot happen, unless someone breaks us */
> +			WARN_ON(true);
> +			return NULL;
> +		}
> +
> +		/* match cannot be NULL here */
> +		if (match(notifier, sd, asd))
> +			return asd;
> +	}
> +
> +	return NULL;
> +}
> +
> +/* Compare two async sub-device descriptors for equivalence */
> +static bool asd_equal(struct v4l2_async_subdev *asd_x,
> +		      struct v4l2_async_subdev *asd_y)
> +{
> +	if (asd_x->match_type != asd_y->match_type)
> +		return false;
> +
> +	switch (asd_x->match_type) {
> +	case V4L2_ASYNC_MATCH_I2C:
> +		return asd_x->match.i2c.adapter_id ==
> +			asd_y->match.i2c.adapter_id &&
> +			asd_x->match.i2c.address ==
> +			asd_y->match.i2c.address;
> +	case V4L2_ASYNC_MATCH_FWNODE:
> +		return asd_x->match.fwnode == asd_y->match.fwnode;
> +	default:
> +		break;
> +	}
> +
> +	return false;
> +}
> +
> +/* Find the sub-device notifier registered by a sub-device driver. */
> +static struct v4l2_async_notifier *
> +v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
> +{
> +	struct v4l2_async_notifier *n;
> +
> +	list_for_each_entry(n, &notifier_list, list)
> +		if (n->sd == sd)
> +			return n;
> +
> +	return NULL;
> +}
> +
> +/* Get v4l2_device related to the notifier if one can be found. */
> +static struct v4l2_device *
> +v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
> +{
> +	while (notifier->parent)
> +		notifier = notifier->parent;
> +
> +	return notifier->v4l2_dev;
> +}
> +
> +/*
> + * Return true if all child sub-device notifiers are complete, false otherwise.
> + */
> +static bool
> +v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
> +{
> +	struct v4l2_subdev *sd;
> +
> +	if (!list_empty(&notifier->waiting))
> +		return false;
> +
> +	list_for_each_entry(sd, &notifier->done, async_list) {
> +		struct v4l2_async_notifier *subdev_notifier =
> +			v4l2_async_find_subdev_notifier(sd);
> +
> +		if (subdev_notifier &&
> +		    !v4l2_async_notifier_can_complete(subdev_notifier))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
> +/*
> + * Complete the master notifier if possible. This is done when all async
> + * sub-devices have been bound; v4l2_device is also available then.
> + */
> +static int
> +v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
> +{
> +	/* Quick check whether there are still more sub-devices here. */
> +	if (!list_empty(&notifier->waiting))
> +		return 0;
> +
> +	/* Check the entire notifier tree; find the root notifier first. */
> +	while (notifier->parent)
> +		notifier = notifier->parent;
> +
> +	/* This is root if it has v4l2_dev. */
> +	if (!notifier->v4l2_dev)
> +		return 0;
> +
> +	/* Is everything ready? */
> +	if (!v4l2_async_notifier_can_complete(notifier))
> +		return 0;
> +
> +	return v4l2_async_notifier_call_complete(notifier);
> +}
> +
> +static int
> +v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier);
> +
> +static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
> +				   struct v4l2_device *v4l2_dev,
> +				   struct v4l2_subdev *sd,
> +				   struct v4l2_async_subdev *asd)
> +{
> +	struct v4l2_async_notifier *subdev_notifier;
> +	int ret;
> +
> +	ret = v4l2_device_register_subdev(v4l2_dev, sd);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
> +	if (ret < 0) {
> +		v4l2_device_unregister_subdev(sd);
> +		return ret;
> +	}
> +
> +	/* Remove from the waiting list */
> +	list_del(&asd->list);
> +	sd->asd = asd;
> +	sd->notifier = notifier;
> +
> +	/* Move from the global subdevice list to notifier's done */
> +	list_move(&sd->async_list, &notifier->done);
> +
> +	/*
> +	 * See if the sub-device has a notifier. If not, return here.
> +	 */
> +	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
> +	if (!subdev_notifier || subdev_notifier->parent)
> +		return 0;
> +
> +	/*
> +	 * Proceed with checking for the sub-device notifier's async
> +	 * sub-devices, and return the result. The error will be handled by the
> +	 * caller.
> +	 */
> +	subdev_notifier->parent = notifier;
> +
> +	return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
> +}
> +
> +/* Test all async sub-devices in a notifier for a match. */
> +static int
> +v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier)
> +{
> +	struct v4l2_device *v4l2_dev =
> +		v4l2_async_notifier_find_v4l2_dev(notifier);
> +	struct v4l2_subdev *sd;
> +
> +	if (!v4l2_dev)
> +		return 0;
> +
> +again:
> +	list_for_each_entry(sd, &subdev_list, async_list) {
> +		struct v4l2_async_subdev *asd;
> +		int ret;
> +
> +		asd = v4l2_async_find_match(notifier, sd);
> +		if (!asd)
> +			continue;
> +
> +		ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
> +		if (ret < 0)
> +			return ret;
> +
> +		/*
> +		 * v4l2_async_match_notify() may lead to registering a
> +		 * new notifier and thus changing the async subdevs
> +		 * list. In order to proceed safely from here, restart
> +		 * parsing the list from the beginning.
> +		 */
> +		goto again;
> +	}
> +
> +	return 0;
> +}
> +
> +static void v4l2_async_cleanup(struct v4l2_subdev *sd)
> +{
> +	v4l2_device_unregister_subdev(sd);
> +	/*
> +	 * Subdevice driver will reprobe and put the subdev back
> +	 * onto the list
> +	 */
> +	list_del_init(&sd->async_list);
> +	sd->asd = NULL;
> +}
> +
> +/* Unbind all sub-devices in the notifier tree. */
> +static void
> +v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
> +{
> +	struct v4l2_subdev *sd, *tmp;
> +
> +	list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
> +		struct v4l2_async_notifier *subdev_notifier =
> +			v4l2_async_find_subdev_notifier(sd);
> +
> +		if (subdev_notifier)
> +			v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
> +
> +		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
> +		v4l2_async_cleanup(sd);
> +
> +		list_move(&sd->async_list, &subdev_list);
> +	}
> +
> +	notifier->parent = NULL;
> +}
> +
> +/* See if an async sub-device can be found in a notifier's lists. */
> +static bool
> +__v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
> +				       struct v4l2_async_subdev *asd)
> +{
> +	struct v4l2_async_subdev *asd_y;
> +	struct v4l2_subdev *sd;
> +
> +	list_for_each_entry(asd_y, &notifier->waiting, list)
> +		if (asd_equal(asd, asd_y))
> +			return true;
> +
> +	list_for_each_entry(sd, &notifier->done, async_list) {
> +		if (WARN_ON(!sd->asd))
> +			continue;
> +
> +		if (asd_equal(asd, sd->asd))
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +/*
> + * Find out whether an async sub-device was set up already or
> + * whether it exists in a given notifier before @this_index.
> + * If @this_index < 0, search the notifier's entire @asd_list.
> + */
> +static bool
> +v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
> +				     struct v4l2_async_subdev *asd,
> +				     int this_index)
> +{
> +	struct v4l2_async_subdev *asd_y;
> +	int j = 0;
> +
> +	lockdep_assert_held(&list_lock);
> +
> +	/* Check that an asd is not being added more than once. */
> +	list_for_each_entry(asd_y, &notifier->asd_list, asd_list) {
> +		if (this_index >= 0 && j++ >= this_index)
> +			break;
> +		if (asd_equal(asd, asd_y))
> +			return true;
> +	}
> +
> +	/* Check that an asd does not exist in other notifiers. */
> +	list_for_each_entry(notifier, &notifier_list, list)
> +		if (__v4l2_async_notifier_has_async_subdev(notifier, asd))
> +			return true;
> +
> +	return false;
> +}
> +
> +static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
> +					 struct v4l2_async_subdev *asd,
> +					 int this_index)
> +{
> +	struct device *dev =
> +		notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
> +
> +	if (!asd)
> +		return -EINVAL;
> +
> +	switch (asd->match_type) {
> +	case V4L2_ASYNC_MATCH_I2C:
> +	case V4L2_ASYNC_MATCH_FWNODE:
> +		if (v4l2_async_notifier_has_async_subdev(notifier, asd,
> +							 this_index)) {
> +			dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n");
> +			return -EEXIST;
> +		}
> +		break;
> +	default:
> +		dev_err(dev, "Invalid match type %u on %p\n",
> +			asd->match_type, asd);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier)
> +{
> +	INIT_LIST_HEAD(&notifier->asd_list);
> +}
> +EXPORT_SYMBOL(v4l2_async_notifier_init);
> +
> +static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
> +{
> +	struct v4l2_async_subdev *asd;
> +	int ret, i = 0;
> +
> +	INIT_LIST_HEAD(&notifier->waiting);
> +	INIT_LIST_HEAD(&notifier->done);
> +
> +	mutex_lock(&list_lock);
> +
> +	list_for_each_entry(asd, &notifier->asd_list, asd_list) {
> +		ret = v4l2_async_notifier_asd_valid(notifier, asd, i++);
> +		if (ret)
> +			goto err_unlock;
> +
> +		list_add_tail(&asd->list, &notifier->waiting);
> +	}
> +
> +	ret = v4l2_async_notifier_try_all_subdevs(notifier);
> +	if (ret < 0)
> +		goto err_unbind;
> +
> +	ret = v4l2_async_notifier_try_complete(notifier);
> +	if (ret < 0)
> +		goto err_unbind;
> +
> +	/* Keep also completed notifiers on the list */
> +	list_add(&notifier->list, &notifier_list);
> +
> +	mutex_unlock(&list_lock);
> +
> +	return 0;
> +
> +err_unbind:
> +	/*
> +	 * On failure, unbind all sub-devices registered through this notifier.
> +	 */
> +	v4l2_async_notifier_unbind_all_subdevs(notifier);
> +
> +err_unlock:
> +	mutex_unlock(&list_lock);
> +
> +	return ret;
> +}
> +
> +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> +				 struct v4l2_async_notifier *notifier)
> +{
> +	int ret;
> +
> +	if (WARN_ON(!v4l2_dev || notifier->sd))
> +		return -EINVAL;
> +
> +	notifier->v4l2_dev = v4l2_dev;
> +
> +	ret = __v4l2_async_notifier_register(notifier);
> +	if (ret)
> +		notifier->v4l2_dev = NULL;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(v4l2_async_notifier_register);
> +
> +int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
> +					struct v4l2_async_notifier *notifier)
> +{
> +	int ret;
> +
> +	if (WARN_ON(!sd || notifier->v4l2_dev))
> +		return -EINVAL;
> +
> +	notifier->sd = sd;
> +
> +	ret = __v4l2_async_notifier_register(notifier);
> +	if (ret)
> +		notifier->sd = NULL;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
> +
> +static void
> +__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> +{
> +	if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
> +		return;
> +
> +	v4l2_async_notifier_unbind_all_subdevs(notifier);
> +
> +	notifier->sd = NULL;
> +	notifier->v4l2_dev = NULL;
> +
> +	list_del(&notifier->list);
> +}
> +
> +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> +{
> +	mutex_lock(&list_lock);
> +
> +	__v4l2_async_notifier_unregister(notifier);
> +
> +	mutex_unlock(&list_lock);
> +}
> +EXPORT_SYMBOL(v4l2_async_notifier_unregister);
> +
> +static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
> +{
> +	struct v4l2_async_subdev *asd, *tmp;
> +
> +	if (!notifier || !notifier->asd_list.next)
> +		return;
> +
> +	list_for_each_entry_safe(asd, tmp, &notifier->asd_list, asd_list) {
> +		switch (asd->match_type) {
> +		case V4L2_ASYNC_MATCH_FWNODE:
> +			fwnode_handle_put(asd->match.fwnode);
> +			break;
> +		default:
> +			break;
> +		}
> +
> +		list_del(&asd->asd_list);
> +		kfree(asd);
> +	}
> +}
> +
> +void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
> +{
> +	mutex_lock(&list_lock);
> +
> +	__v4l2_async_notifier_cleanup(notifier);
> +
> +	mutex_unlock(&list_lock);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
> +
> +int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
> +				   struct v4l2_async_subdev *asd)
> +{
> +	int ret;
> +
> +	mutex_lock(&list_lock);
> +
> +	ret = v4l2_async_notifier_asd_valid(notifier, asd, -1);
> +	if (ret)
> +		goto unlock;
> +
> +	list_add_tail(&asd->asd_list, &notifier->asd_list);
> +
> +unlock:
> +	mutex_unlock(&list_lock);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
> +
> +struct v4l2_async_subdev *
> +__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
> +					struct fwnode_handle *fwnode,
> +					unsigned int asd_struct_size)
> +{
> +	struct v4l2_async_subdev *asd;
> +	int ret;
> +
> +	asd = kzalloc(asd_struct_size, GFP_KERNEL);
> +	if (!asd)
> +		return ERR_PTR(-ENOMEM);
> +
> +	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
> +	asd->match.fwnode = fwnode_handle_get(fwnode);
> +
> +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
> +	if (ret) {
> +		fwnode_handle_put(fwnode);
> +		kfree(asd);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return asd;
> +}
> +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_subdev);
> +
> +struct v4l2_async_subdev *
> +__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
> +					       struct fwnode_handle *endpoint,
> +					       unsigned int asd_struct_size)
> +{
> +	struct v4l2_async_subdev *asd;
> +	struct fwnode_handle *remote;
> +
> +	remote = fwnode_graph_get_remote_port_parent(endpoint);
> +	if (!remote)
> +		return ERR_PTR(-ENOTCONN);
> +
> +	asd = __v4l2_async_notifier_add_fwnode_subdev(notif, remote,
> +						      asd_struct_size);
> +	/*
> +	 * Calling __v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
> +	 * so drop the one we got in fwnode_graph_get_remote_port_parent.
> +	 */
> +	fwnode_handle_put(remote);
> +	return asd;
> +}
> +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_remote_subdev);
> +
> +struct v4l2_async_subdev *
> +__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
> +				     int adapter_id, unsigned short address,
> +				     unsigned int asd_struct_size)
> +{
> +	struct v4l2_async_subdev *asd;
> +	int ret;
> +
> +	asd = kzalloc(asd_struct_size, GFP_KERNEL);
> +	if (!asd)
> +		return ERR_PTR(-ENOMEM);
> +
> +	asd->match_type = V4L2_ASYNC_MATCH_I2C;
> +	asd->match.i2c.adapter_id = adapter_id;
> +	asd->match.i2c.address = address;
> +
> +	ret = __v4l2_async_notifier_add_subdev(notifier, asd);
> +	if (ret) {
> +		kfree(asd);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return asd;
> +}
> +EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_i2c_subdev);
> +
> +int v4l2_async_register_subdev(struct v4l2_subdev *sd)
> +{
> +	struct v4l2_async_notifier *subdev_notifier;
> +	struct v4l2_async_notifier *notifier;
> +	int ret;
> +
> +	/*
> +	 * No reference taken. The reference is held by the device
> +	 * (struct v4l2_subdev.dev), and async sub-device does not
> +	 * exist independently of the device at any point of time.
> +	 */
> +	if (!sd->fwnode && sd->dev)
> +		sd->fwnode = dev_fwnode(sd->dev);
> +
> +	mutex_lock(&list_lock);
> +
> +	INIT_LIST_HEAD(&sd->async_list);
> +
> +	list_for_each_entry(notifier, &notifier_list, list) {
> +		struct v4l2_device *v4l2_dev =
> +			v4l2_async_notifier_find_v4l2_dev(notifier);
> +		struct v4l2_async_subdev *asd;
> +
> +		if (!v4l2_dev)
> +			continue;
> +
> +		asd = v4l2_async_find_match(notifier, sd);
> +		if (!asd)
> +			continue;
> +
> +		ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
> +		if (ret)
> +			goto err_unbind;
> +
> +		ret = v4l2_async_notifier_try_complete(notifier);
> +		if (ret)
> +			goto err_unbind;
> +
> +		goto out_unlock;
> +	}
> +
> +	/* None matched, wait for hot-plugging */
> +	list_add(&sd->async_list, &subdev_list);
> +
> +out_unlock:
> +	mutex_unlock(&list_lock);
> +
> +	return 0;
> +
> +err_unbind:
> +	/*
> +	 * Complete failed. Unbind the sub-devices bound through registering
> +	 * this async sub-device.
> +	 */
> +	subdev_notifier = v4l2_async_find_subdev_notifier(sd);
> +	if (subdev_notifier)
> +		v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
> +
> +	if (sd->asd)
> +		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
> +	v4l2_async_cleanup(sd);
> +
> +	mutex_unlock(&list_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(v4l2_async_register_subdev);
> +
> +void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
> +{
> +	if (!sd->async_list.next)
> +		return;
> +
> +	mutex_lock(&list_lock);
> +
> +	__v4l2_async_notifier_unregister(sd->subdev_notifier);
> +	__v4l2_async_notifier_cleanup(sd->subdev_notifier);
> +	kfree(sd->subdev_notifier);
> +	sd->subdev_notifier = NULL;
> +
> +	if (sd->asd) {
> +		struct v4l2_async_notifier *notifier = sd->notifier;
> +
> +		list_add(&sd->asd->list, &notifier->waiting);
> +
> +		v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
> +	}
> +
> +	v4l2_async_cleanup(sd);
> +
> +	mutex_unlock(&list_lock);
> +}
> +EXPORT_SYMBOL(v4l2_async_unregister_subdev);
> +
> +static void print_waiting_subdev(struct seq_file *s,
> +				 struct v4l2_async_subdev *asd)
> +{
> +	switch (asd->match_type) {
> +	case V4L2_ASYNC_MATCH_I2C:
> +		seq_printf(s, " [i2c] dev=%d-%04x\n", asd->match.i2c.adapter_id,
> +			   asd->match.i2c.address);
> +		break;
> +	case V4L2_ASYNC_MATCH_FWNODE: {
> +		struct fwnode_handle *devnode, *fwnode = asd->match.fwnode;
> +
> +		devnode = fwnode_graph_is_endpoint(fwnode) ?
> +			  fwnode_graph_get_port_parent(fwnode) :
> +			  fwnode_handle_get(fwnode);
> +
> +		seq_printf(s, " [fwnode] dev=%s, node=%pfw\n",
> +			   devnode->dev ? dev_name(devnode->dev) : "nil",
> +			   fwnode);
> +
> +		fwnode_handle_put(devnode);
> +		break;
> +	}
> +	}
> +}
> +
> +static const char *
> +v4l2_async_notifier_name(struct v4l2_async_notifier *notifier)
> +{
> +	if (notifier->v4l2_dev)
> +		return notifier->v4l2_dev->name;
> +	else if (notifier->sd)
> +		return notifier->sd->name;
> +	else
> +		return "nil";
> +}
> +
> +static int pending_subdevs_show(struct seq_file *s, void *data)
> +{
> +	struct v4l2_async_notifier *notif;
> +	struct v4l2_async_subdev *asd;
> +
> +	mutex_lock(&list_lock);
> +
> +	list_for_each_entry(notif, &notifier_list, list) {
> +		seq_printf(s, "%s:\n", v4l2_async_notifier_name(notif));
> +		list_for_each_entry(asd, &notif->waiting, list)
> +			print_waiting_subdev(s, asd);
> +	}
> +
> +	mutex_unlock(&list_lock);
> +
> +	return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(pending_subdevs);
> +
> +static struct dentry *v4l2_async_debugfs_dir;
> +
> +static int __init v4l2_async_init(void)
> +{
> +	v4l2_async_debugfs_dir = debugfs_create_dir("v4l2-async", NULL);
> +	debugfs_create_file("pending_async_subdevices", 0444,
> +			    v4l2_async_debugfs_dir, NULL,
> +			    &pending_subdevs_fops);
> +
> +	return 0;
> +}
> +
> +static void __exit v4l2_async_exit(void)
> +{
> +	debugfs_remove_recursive(v4l2_async_debugfs_dir);
> +}
> +
> +subsys_initcall(v4l2_async_init);
> +module_exit(v4l2_async_exit);
> +
> +MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
> +MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
> +MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index 5d92a2b33a6e..99064683cfb5 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -1691,7 +1691,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  		/* interlaced top field */
>  		p_mpeg2_slice_params->picture.picture_structure = 1;
>  		p_mpeg2_slice_params->picture.picture_coding_type =
> -					V4L2_MPEG2_PICTURE_CODING_TYPE_I;
> +					V4L2_MPEG2_PIC_CODING_TYPE_I;
>  		break;
>  	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
>  		p_mpeg2_quant = p;
> @@ -1901,18 +1901,18 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  		}
>  
>  		switch (p_mpeg2_slice_params->picture.picture_structure) {
> -		case 1: /* interlaced top field */
> -		case 2: /* interlaced bottom field */
> -		case 3: /* progressive */
> +		case V4L2_MPEG2_PIC_TOP_FIELD:
> +		case V4L2_MPEG2_PIC_BOTTOM_FIELD:
> +		case V4L2_MPEG2_PIC_FRAME:
>  			break;
>  		default:
>  			return -EINVAL;
>  		}
>  
>  		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
> -		case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
> -		case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
> -		case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
> +		case V4L2_MPEG2_PIC_CODING_TYPE_I:
> +		case V4L2_MPEG2_PIC_CODING_TYPE_P:
> +		case V4L2_MPEG2_PIC_CODING_TYPE_B:
>  			break;
>  		default:
>  			return -EINVAL;
> diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> index dedb5c502ae0..6ef7ded863b2 100644
> --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> @@ -77,10 +77,6 @@
>  
>  #define G1_REG_APF_THRESHOLD(v)		(((v) << 0) & GENMASK(13, 0))
>  
> -#define PICT_TOP_FIELD     1
> -#define PICT_BOTTOM_FIELD  2
> -#define PICT_FRAME         3
> -
>  static void
>  hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
>  				     struct hantro_ctx *ctx)
> @@ -96,19 +92,19 @@ static void
>  hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
>  				struct vb2_buffer *src_buf,
>  				struct vb2_buffer *dst_buf,
> -				const struct v4l2_mpeg2_sequence *sequence,
> -				const struct v4l2_mpeg2_picture *picture,
> +				const struct v4l2_mpeg2_sequence *seq,
> +				const struct v4l2_mpeg2_picture *pic,
>  				const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
>  {
>  	dma_addr_t forward_addr = 0, backward_addr = 0;
>  	dma_addr_t current_addr, addr;
>  
> -	switch (picture->picture_coding_type) {
> -	case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
> +	switch (pic->picture_coding_type) {
> +	case V4L2_MPEG2_PIC_CODING_TYPE_B:
>  		backward_addr = hantro_get_ref(ctx,
>  					       slice_params->backward_ref_ts);
>  		fallthrough;
> -	case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
> +	case V4L2_MPEG2_PIC_CODING_TYPE_P:
>  		forward_addr = hantro_get_ref(ctx,
>  					      slice_params->forward_ref_ts);
>  	}
> @@ -121,7 +117,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
>  	addr = hantro_get_dec_buf_addr(ctx, dst_buf);
>  	current_addr = addr;
>  
> -	if (picture->picture_structure == PICT_BOTTOM_FIELD)
> +	if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD)
>  		addr += ALIGN(ctx->dst_fmt.width, 16);
>  	vdpu_write_relaxed(vpu, addr, G1_REG_DEC_OUT_BASE);
>  
> @@ -131,18 +127,18 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
>  		backward_addr = current_addr;
>  
>  	/* Set forward ref frame (top/bottom field) */
> -	if (picture->picture_structure == PICT_FRAME ||
> -	    picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
> -	    (picture->picture_structure == PICT_TOP_FIELD &&
> -	     picture->top_field_first) ||
> -	    (picture->picture_structure == PICT_BOTTOM_FIELD &&
> -	     !picture->top_field_first)) {
> +	if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME ||
> +	    pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B ||
> +	    (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD &&
> +	     pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST) ||
> +	    (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD &&
> +	     !(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST))) {
>  		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
> -	} else if (picture->picture_structure == PICT_TOP_FIELD) {
> +	} else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) {
>  		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER1_BASE);
> -	} else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
> +	} else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) {
>  		vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
>  	}
> @@ -157,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct vb2_v4l2_buffer *src_buf, *dst_buf;
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *sequence;
> -	const struct v4l2_mpeg2_picture *picture;
> +	const struct v4l2_mpeg2_sequence *seq;
> +	const struct v4l2_mpeg2_picture *pic;
>  	u32 reg;
>  
>  	src_buf = hantro_get_src_buf(ctx);
> @@ -169,8 +165,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	slice_params = hantro_get_ctrl(ctx,
>  				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
> -	sequence = &slice_params->sequence;
> -	picture = &slice_params->picture;
> +	seq = &slice_params->sequence;
> +	pic = &slice_params->picture;
>  
>  	reg = G1_REG_DEC_AXI_RD_ID(0) |
>  	      G1_REG_DEC_TIMEOUT_E(1) |
> @@ -190,11 +186,11 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	reg = G1_REG_DEC_MODE(5) |
>  	      G1_REG_RLC_MODE_E(0) |
> -	      G1_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
> -	      G1_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
> -	      G1_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
> -	      G1_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
> -	      G1_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
> +	      G1_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) |
> +	      G1_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) |
> +	      G1_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) |
> +	      G1_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) |
> +	      G1_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) |
>  	      G1_REG_FWD_INTERLACE_E(0) |
>  	      G1_REG_FILTERING_DIS(1) |
>  	      G1_REG_WRITE_MVS_E(0) |
> @@ -203,27 +199,27 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
>  	      G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
> -	      G1_REG_ALT_SCAN_E(picture->alternate_scan) |
> -	      G1_REG_TOPFIELDFIRST_E(picture->top_field_first);
> +	      G1_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
> +	      G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
>  	vdpu_write_relaxed(vpu, reg, G1_SWREG(4));
>  
>  	reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) |
> -	      G1_REG_QSCALE_TYPE(picture->q_scale_type) |
> -	      G1_REG_CON_MV_E(picture->concealment_motion_vectors) |
> -	      G1_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
> -	      G1_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
> -	      G1_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
> +	      G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
> +	      G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
> +	      G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
> +	      G1_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) |
> +	      G1_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
>  	vdpu_write_relaxed(vpu, reg, G1_SWREG(5));
>  
>  	reg = G1_REG_INIT_QP(1) |
>  	      G1_REG_STREAM_LEN(slice_params->bit_size >> 3);
>  	vdpu_write_relaxed(vpu, reg, G1_SWREG(6));
>  
> -	reg = G1_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
> -	      G1_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
> -	      G1_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
> -	      G1_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
> -	      G1_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
> +	reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
> +	      G1_REG_FCODE_FWD_HOR(pic->f_code[0][0]) |
> +	      G1_REG_FCODE_FWD_VER(pic->f_code[0][1]) |
> +	      G1_REG_FCODE_BWD_HOR(pic->f_code[1][0]) |
> +	      G1_REG_FCODE_BWD_VER(pic->f_code[1][1]) |
>  	      G1_REG_MV_ACCURACY_FWD(1) |
>  	      G1_REG_MV_ACCURACY_BWD(1);
>  	vdpu_write_relaxed(vpu, reg, G1_SWREG(18));
> @@ -239,7 +235,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
>  					&dst_buf->vb2_buf,
> -					sequence, picture, slice_params);
> +					seq, pic, slice_params);
>  
>  	hantro_end_prepare_run(ctx);
>  
> diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> index 61a54549774d..ff54398f6643 100644
> --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> @@ -79,10 +79,6 @@
>  #define VDPU_REG_MV_ACCURACY_FWD(v)	((v) ? BIT(2) : 0)
>  #define VDPU_REG_MV_ACCURACY_BWD(v)	((v) ? BIT(1) : 0)
>  
> -#define PICT_TOP_FIELD     1
> -#define PICT_BOTTOM_FIELD  2
> -#define PICT_FRAME         3
> -
>  static void
>  rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu,
>  				      struct hantro_ctx *ctx)
> @@ -99,19 +95,19 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
>  				 struct hantro_ctx *ctx,
>  				 struct vb2_buffer *src_buf,
>  				 struct vb2_buffer *dst_buf,
> -				 const struct v4l2_mpeg2_sequence *sequence,
> -				 const struct v4l2_mpeg2_picture *picture,
> +				 const struct v4l2_mpeg2_sequence *seq,
> +				 const struct v4l2_mpeg2_picture *pic,
>  				 const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
>  {
>  	dma_addr_t forward_addr = 0, backward_addr = 0;
>  	dma_addr_t current_addr, addr;
>  
> -	switch (picture->picture_coding_type) {
> -	case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
> +	switch (pic->picture_coding_type) {
> +	case V4L2_MPEG2_PIC_CODING_TYPE_B:
>  		backward_addr = hantro_get_ref(ctx,
>  					       slice_params->backward_ref_ts);
>  		fallthrough;
> -	case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
> +	case V4L2_MPEG2_PIC_CODING_TYPE_P:
>  		forward_addr = hantro_get_ref(ctx,
>  					      slice_params->forward_ref_ts);
>  	}
> @@ -124,7 +120,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
>  	addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
>  	current_addr = addr;
>  
> -	if (picture->picture_structure == PICT_BOTTOM_FIELD)
> +	if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD)
>  		addr += ALIGN(ctx->dst_fmt.width, 16);
>  	vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE);
>  
> @@ -134,18 +130,18 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
>  		backward_addr = current_addr;
>  
>  	/* Set forward ref frame (top/bottom field) */
> -	if (picture->picture_structure == PICT_FRAME ||
> -	    picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
> -	    (picture->picture_structure == PICT_TOP_FIELD &&
> -	     picture->top_field_first) ||
> -	    (picture->picture_structure == PICT_BOTTOM_FIELD &&
> -	     !picture->top_field_first)) {
> +	if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME ||
> +	    pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B ||
> +	    (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD &&
> +	     pic->flags & V4L2_MPEG2_PIC_TOP_FIELD) ||
> +	    (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD &&
> +	     !(pic->flags & V4L2_MPEG2_PIC_TOP_FIELD))) {
>  		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
> -	} else if (picture->picture_structure == PICT_TOP_FIELD) {
> +	} else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) {
>  		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER1_BASE);
> -	} else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
> +	} else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) {
>  		vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER0_BASE);
>  		vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE);
>  	}
> @@ -160,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct vb2_v4l2_buffer *src_buf, *dst_buf;
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *sequence;
> -	const struct v4l2_mpeg2_picture *picture;
> +	const struct v4l2_mpeg2_sequence *seq;
> +	const struct v4l2_mpeg2_picture *pic;
>  	u32 reg;
>  
>  	src_buf = hantro_get_src_buf(ctx);
> @@ -171,8 +167,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	slice_params = hantro_get_ctrl(ctx,
>  				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
> -	sequence = &slice_params->sequence;
> -	picture = &slice_params->picture;
> +	seq = &slice_params->sequence;
> +	pic = &slice_params->picture;
>  
>  	reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
>  	      VDPU_REG_DEC_SCMD_DIS(0) |
> @@ -207,11 +203,11 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56));
>  
>  	reg = VDPU_REG_RLC_MODE_E(0) |
> -	      VDPU_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
> -	      VDPU_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
> -	      VDPU_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
> -	      VDPU_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
> -	      VDPU_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
> +	      VDPU_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) |
> +	      VDPU_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) |
> +	      VDPU_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) |
> +	      VDPU_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) |
> +	      VDPU_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) |
>  	      VDPU_REG_FWD_INTERLACE_E(0) |
>  	      VDPU_REG_WRITE_MVS_E(0) |
>  	      VDPU_REG_DEC_TIMEOUT_E(1) |
> @@ -220,23 +216,23 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
>  	      VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
> -	      VDPU_REG_ALT_SCAN_E(picture->alternate_scan) |
> -	      VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first);
> +	      VDPU_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
> +	      VDPU_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
>  	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
>  
>  	reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) |
> -	      VDPU_REG_QSCALE_TYPE(picture->q_scale_type) |
> -	      VDPU_REG_CON_MV_E(picture->concealment_motion_vectors) |
> -	      VDPU_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
> -	      VDPU_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
> -	      VDPU_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
> +	      VDPU_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
> +	      VDPU_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
> +	      VDPU_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
> +	      VDPU_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) |
> +	      VDPU_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
>  	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(122));
>  
> -	reg = VDPU_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
> -	      VDPU_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
> -	      VDPU_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
> -	      VDPU_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
> -	      VDPU_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
> +	reg = VDPU_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
> +	      VDPU_REG_FCODE_FWD_HOR(pic->f_code[0][0]) |
> +	      VDPU_REG_FCODE_FWD_VER(pic->f_code[0][1]) |
> +	      VDPU_REG_FCODE_BWD_HOR(pic->f_code[1][0]) |
> +	      VDPU_REG_FCODE_BWD_VER(pic->f_code[1][1]) |
>  	      VDPU_REG_MV_ACCURACY_FWD(1) |
>  	      VDPU_REG_MV_ACCURACY_BWD(1);
>  	vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136));
> @@ -245,7 +241,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
>  					 &dst_buf->vb2_buf,
> -					 sequence, picture, slice_params);
> +					 seq, pic, slice_params);
>  
>  	/* Kick the watchdog and start decoding */
>  	hantro_end_prepare_run(ctx);
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> index e3154f631858..e39a17d28c7d 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> @@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
>  static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  {
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *sequence;
> -	const struct v4l2_mpeg2_picture *picture;
> +	const struct v4l2_mpeg2_sequence *seq;
> +	const struct v4l2_mpeg2_picture *pic;
>  	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
>  	dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
>  	dma_addr_t fwd_luma_addr, fwd_chroma_addr;
> @@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  	u32 reg;
>  
>  	slice_params = run->mpeg2.slice_params;
> -	sequence = &slice_params->sequence;
> -	picture = &slice_params->picture;
> +	seq = &slice_params->sequence;
> +	pic = &slice_params->picture;
>  
>  	quantisation = run->mpeg2.quantisation;
>  
> @@ -94,19 +94,19 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  
>  	/* Set MPEG picture header. */
>  
> -	reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(picture->picture_coding_type);
> -	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, picture->f_code[0][0]);
> -	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, picture->f_code[0][1]);
> -	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, picture->f_code[1][0]);
> -	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, picture->f_code[1][1]);
> -	reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(picture->intra_dc_precision);
> -	reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(picture->picture_structure);
> -	reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(picture->top_field_first);
> -	reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(picture->frame_pred_frame_dct);
> -	reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(picture->concealment_motion_vectors);
> -	reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(picture->q_scale_type);
> -	reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(picture->intra_vlc_format);
> -	reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(picture->alternate_scan);
> +	reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(pic->picture_coding_type);
> +	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, pic->f_code[0][0]);
> +	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, pic->f_code[0][1]);
> +	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, pic->f_code[1][0]);
> +	reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, pic->f_code[1][1]);
> +	reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(pic->intra_dc_precision);
> +	reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(pic->picture_structure);
> +	reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
> +	reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
> +	reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV);
> +	reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE);
> +	reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC);
> +	reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN);
>  	reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_FORWARD_VECTOR(0);
>  	reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_BACKWARD_VECTOR(0);
>  
> @@ -114,8 +114,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  
>  	/* Set frame dimensions. */
>  
> -	reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(sequence->horizontal_size);
> -	reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(sequence->vertical_size);
> +	reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(seq->horizontal_size);
> +	reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(seq->vertical_size);
>  
>  	cedrus_write(dev, VE_DEC_MPEG_PICCODEDSIZE, reg);
>  
> diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
> index 8ea2c7f3a172..d3190979d574 100644
> --- a/include/media/mpeg2-ctrls.h
> +++ b/include/media/mpeg2-ctrls.h
> @@ -18,10 +18,7 @@
>  #define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
>  #define	V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104
>  
> -#define V4L2_MPEG2_PICTURE_CODING_TYPE_I	1
> -#define V4L2_MPEG2_PICTURE_CODING_TYPE_P	2
> -#define V4L2_MPEG2_PICTURE_CODING_TYPE_B	3
> -#define V4L2_MPEG2_PICTURE_CODING_TYPE_D	4
> +#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
>  
>  struct v4l2_mpeg2_sequence {
>  	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
> @@ -31,10 +28,29 @@ struct v4l2_mpeg2_sequence {
>  
>  	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
>  	__u16	profile_and_level_indication;
> -	__u8	progressive_sequence;
>  	__u8	chroma_format;
> +
> +	__u32	flags;
>  };
>  
> +#define V4L2_MPEG2_PIC_CODING_TYPE_I			1
> +#define V4L2_MPEG2_PIC_CODING_TYPE_P			2
> +#define V4L2_MPEG2_PIC_CODING_TYPE_B			3
> +#define V4L2_MPEG2_PIC_CODING_TYPE_D			4
> +
> +#define V4L2_MPEG2_PIC_TOP_FIELD			0x1
> +#define V4L2_MPEG2_PIC_BOTTOM_FIELD			0x2
> +#define V4L2_MPEG2_PIC_FRAME				0x3
> +
> +#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST		0x0001
> +#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT		0x0002
> +#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV		0x0004
> +#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE		0x0008
> +#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC			0x0010
> +#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN			0x0020
> +#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
> +#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
> +
>  struct v4l2_mpeg2_picture {
>  	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
>  	__u8	picture_coding_type;
> @@ -43,14 +59,8 @@ struct v4l2_mpeg2_picture {
>  	__u8	f_code[2][2];
>  	__u8	intra_dc_precision;
>  	__u8	picture_structure;
> -	__u8	top_field_first;
> -	__u8	frame_pred_frame_dct;
> -	__u8	concealment_motion_vectors;
> -	__u8	q_scale_type;
> -	__u8	intra_vlc_format;
> -	__u8	alternate_scan;
> -	__u8	repeat_first_field;
> -	__u16	progressive_frame;
> +
> +	__u32	flags;
>  };
>  
>  struct v4l2_ctrl_mpeg2_slice_params {
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters
  2021-04-03 18:07 ` [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters Ezequiel Garcia
@ 2021-04-06 10:37   ` Hans Verkuil
  0 siblings, 0 replies; 14+ messages in thread
From: Hans Verkuil @ 2021-04-06 10:37 UTC (permalink / raw)
  To: Ezequiel Garcia, linux-media, linux-kernel
  Cc: kernel, Jonas Karlman, Nicolas Dufresne, Philipp Zabel,
	Maxime Ripard, Paul Kocialkowski, Jernej Skrabec, Daniel Almeida

On 03/04/2021 20:07, Ezequiel Garcia wrote:
> Typically, bitstreams are composed of a sequence header,
> followed by a number of picture header and picture coding extension
> headers. Each picture can be composed by a number of slices.

by -> of

> 
> Let's split the MPEG-2 uAPI to follow these semantics more closely,
> allowing more usage flexibility. Having these controls splitted

splitted -> split up

> allows applications to set a sequence control at the beginning
> of a sequence, and then set a picture control for each frame.
> 
> While here add padding fields where needed, and document
> the uAPI header thoroughly.
> 
> Note that the V4L2_CTRL_TYPE_{} defines had to be moved because
> it clashes with existing ones. This is not really an issue
> since they will be re-defined when the controls are moved
> out of staging.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> Tested-by: Jonas Karlman <jonas@kwiboo.se>
> ---
>  .../media/v4l/ext-ctrls-codec.rst             | 47 ++++++---
>  .../media/v4l/pixfmt-compressed.rst           |  5 +-
>  .../media/v4l/vidioc-queryctrl.rst            | 12 +++
>  .../media/videodev2.h.rst.exceptions          |  2 +
>  drivers/media/v4l2-core/v4l2-ctrls.c          | 57 ++++++++---
>  drivers/staging/media/hantro/hantro_drv.c     | 10 ++
>  .../media/hantro/hantro_g1_mpeg2_dec.c        | 14 +--
>  .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    | 14 +--
>  drivers/staging/media/sunxi/cedrus/cedrus.c   | 12 +++
>  drivers/staging/media/sunxi/cedrus/cedrus.h   |  2 +
>  .../staging/media/sunxi/cedrus/cedrus_dec.c   |  4 +
>  .../staging/media/sunxi/cedrus/cedrus_mpeg2.c |  8 +-
>  include/media/mpeg2-ctrls.h                   | 97 +++++++++++++++----
>  include/media/v4l2-ctrls.h                    |  4 +
>  14 files changed, 228 insertions(+), 60 deletions(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index 7d5ac7fb6579..8a0d6139db34 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -1603,14 +1603,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>      * - __u32
>        - ``data_bit_offset``
>        - Offset (in bits) to the video data in the current slice data.
> -    * - struct :c:type:`v4l2_mpeg2_sequence`
> -      - ``sequence``
> -      - Structure with MPEG-2 sequence metadata, merging relevant fields from
> -	the sequence header and sequence extension parts of the bitstream.
> -    * - struct :c:type:`v4l2_mpeg2_picture`
> -      - ``picture``
> -      - Structure with MPEG-2 picture metadata, merging relevant fields from
> -	the picture header and picture coding extension parts of the bitstream.
>      * - __u64
>        - ``backward_ref_ts``
>        - Timestamp of the V4L2 capture buffer to use as backward reference, used
> @@ -1628,14 +1620,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>      * - __u32
>        - ``quantiser_scale_code``
>        - Code used to determine the quantization scale to use for the IDCT.
> +    * - __u8
> +      - ``reserved``
> +      - Applications and drivers must set this to zero.
>  
> -.. c:type:: v4l2_mpeg2_sequence
> +``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)``
> +    Specifies the sequence parameters (as extracted from the bitstream) for the
> +    associated MPEG-2 slice data. This includes fields matching the syntax
> +    elements from the sequence header and sequence extension parts of the
> +    bitstream as specified by :ref:`mpeg2part2`.
> +
> +    .. note::
> +
> +       This compound control is not yet part of the public kernel API and
> +       it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_mpeg2_sequence
>  
>  .. cssclass:: longtable
>  
>  .. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}|
>  
> -.. flat-table:: struct v4l2_mpeg2_sequence
> +.. flat-table:: struct v4l2_ctrl_mpeg2_sequence
>      :header-rows:  0
>      :stub-columns: 0
>      :widths:       1 1 2
> @@ -1657,6 +1663,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>      * - __u8
>        - ``chroma_format``
>        - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
> +    * - __u8
> +      - ``reserved``
> +      - Applications and drivers must set this to zero.
>      * - __u32
>        - ``flags``
>        - See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.
> @@ -1677,7 +1686,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>        - Indication that all the frames for the sequence are progressive instead
>  	of interlaced.
>  
> -.. c:type:: v4l2_mpeg2_picture
> +``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (struct)``
> +    Specifies the picture parameters (as extracted from the bitstream) for the
> +    associated MPEG-2 slice data. This includes fields matching the syntax
> +    elements from the picture header and picture coding extension parts of the
> +    bitstream as specified by :ref:`mpeg2part2`.
> +
> +    .. note::
> +
> +       This compound control is not yet part of the public kernel API and
> +       it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_mpeg2_picture
>  
>  .. raw:: latex
>  
> @@ -1687,7 +1707,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>  
>  .. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}|
>  
> -.. flat-table:: struct v4l2_mpeg2_picture
> +.. flat-table:: struct v4l2_ctrl_mpeg2_picture
>      :header-rows:  0
>      :stub-columns: 0
>      :widths:       1 1 2
> @@ -1708,6 +1728,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
>        - ``picture_structure``
>        - Picture structure (1: interlaced top field, 2: interlaced bottom field,
>  	3: progressive frame).
> +    * - __u8
> +      - ``reserved``
> +      - Applications and drivers must set this to zero.
>      * - __u32
>        - ``flags``
>        - See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.
> diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> index cba607f789f0..bbbacbd65d6f 100644
> --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> @@ -114,8 +114,9 @@ Compressed Formats
>  	This format is adapted for stateless video decoders that implement a
>  	MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
>  	Metadata associated with the frame to decode is required to be passed
> -	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
> -	quantisation matrices can optionally be specified through the
> +	through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE``,
> +        ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE``, and ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS``
> +        controls. Quantisation matrices can optionally be specified through the
>  	``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control.
>  	See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
>  	Exactly one output and one capture buffer must be provided for use with
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> index 4362945fd39b..afc1505a3a7e 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> @@ -429,6 +429,18 @@ See also the examples in :ref:`control`.
>        - n/a
>        - A struct :c:type:`v4l2_ctrl_mpeg2_quantisation`, containing MPEG-2
>  	quantisation matrices for stateless video decoders.
> +    * - ``V4L2_CTRL_TYPE_MPEG2_SEQUENCE``
> +      - n/a
> +      - n/a
> +      - n/a
> +      - A struct :c:type:`v4l2_ctrl_mpeg2_sequence`, containing MPEG-2
> +	sequence parameters for stateless video decoders.
> +    * - ``V4L2_CTRL_TYPE_MPEG2_PICTURE``
> +      - n/a
> +      - n/a
> +      - n/a
> +      - A struct :c:type:`v4l2_ctrl_mpeg2_picture`, containing MPEG-2
> +	picture parameters for stateless video decoders.
>      * - ``V4L2_CTRL_TYPE_AREA``
>        - n/a
>        - n/a
> diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> index d14a807e8f9e..6bba3e6d3ef3 100644
> --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> @@ -134,6 +134,8 @@ replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_MPEG2_SEQUENCE :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_MPEG2_PICTURE :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index 99064683cfb5..1145dec744e8 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -973,6 +973,8 @@ const char *v4l2_ctrl_get_name(u32 id)
>  	case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:		return "Repeat Sequence Header";
>  	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:		return "Force Key Frame";
>  	case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID:		return "Base Layer Priority ID";
> +	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:		return "MPEG-2 Sequence Header";
> +	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
>  	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:		return "MPEG-2 Slice Parameters";
>  	case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
>  	case V4L2_CID_FWHT_I_FRAME_QP:				return "FWHT I-Frame QP Value";
> @@ -1469,6 +1471,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>  	case V4L2_CID_RDS_TX_ALT_FREQS:
>  		*type = V4L2_CTRL_TYPE_U32;
>  		break;
> +	case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE:
> +		*type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE:
> +		*type = V4L2_CTRL_TYPE_MPEG2_PICTURE;
> +		break;
>  	case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:
>  		*type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS;
>  		break;
> @@ -1667,7 +1675,8 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
>  static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  			      union v4l2_ctrl_ptr ptr)
>  {
> -	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> +	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
> +	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
>  	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
>  	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
>  	struct v4l2_ctrl_fwht_params *p_fwht_params;
> @@ -1684,13 +1693,18 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  	 * v4l2_ctrl_type enum.
>  	 */
>  	switch ((u32)ctrl->type) {
> -	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
> -		p_mpeg2_slice_params = p;
> +	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
> +		p_mpeg2_sequence = p;
> +
>  		/* 4:2:0 */
> -		p_mpeg2_slice_params->sequence.chroma_format = 1;
> +		p_mpeg2_sequence->chroma_format = 1;
> +		break;
> +	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
> +		p_mpeg2_picture = p;
> +
>  		/* interlaced top field */
> -		p_mpeg2_slice_params->picture.picture_structure = 1;
> -		p_mpeg2_slice_params->picture.picture_coding_type =
> +		p_mpeg2_picture->picture_structure = V4L2_MPEG2_PIC_TOP_FIELD;
> +		p_mpeg2_picture->picture_coding_type =
>  					V4L2_MPEG2_PIC_CODING_TYPE_I;
>  		break;
>  	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
> @@ -1862,6 +1876,8 @@ static void std_log(const struct v4l2_ctrl *ctrl)
>  static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  				 union v4l2_ctrl_ptr ptr)
>  {
> +	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
> +	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
>  	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
>  	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
>  	struct v4l2_ctrl_fwht_params *p_fwht_params;
> @@ -1878,10 +1894,10 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  	unsigned int i;
>  
>  	switch ((u32)ctrl->type) {
> -	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
> -		p_mpeg2_slice_params = p;
> +	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
> +		p_mpeg2_sequence = p;
>  
> -		switch (p_mpeg2_slice_params->sequence.chroma_format) {
> +		switch (p_mpeg2_sequence->chroma_format) {
>  		case 1: /* 4:2:0 */
>  		case 2: /* 4:2:2 */
>  		case 3: /* 4:4:4 */
> @@ -1889,8 +1905,13 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  		default:
>  			return -EINVAL;
>  		}
> +		zero_reserved(*p_mpeg2_sequence);
> +		break;
> +
> +	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
> +		p_mpeg2_picture = p;
>  
> -		switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
> +		switch (p_mpeg2_picture->intra_dc_precision) {
>  		case 0: /* 8 bits */
>  		case 1: /* 9 bits */
>  		case 2: /* 10 bits */
> @@ -1900,7 +1921,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  			return -EINVAL;
>  		}
>  
> -		switch (p_mpeg2_slice_params->picture.picture_structure) {
> +		switch (p_mpeg2_picture->picture_structure) {
>  		case V4L2_MPEG2_PIC_TOP_FIELD:
>  		case V4L2_MPEG2_PIC_BOTTOM_FIELD:
>  		case V4L2_MPEG2_PIC_FRAME:
> @@ -1909,7 +1930,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  			return -EINVAL;
>  		}
>  
> -		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
> +		switch (p_mpeg2_picture->picture_coding_type) {
>  		case V4L2_MPEG2_PIC_CODING_TYPE_I:
>  		case V4L2_MPEG2_PIC_CODING_TYPE_P:
>  		case V4L2_MPEG2_PIC_CODING_TYPE_B:
> @@ -1917,7 +1938,13 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  		default:
>  			return -EINVAL;
>  		}
> +		zero_reserved(*p_mpeg2_picture);
> +		break;
>  
> +	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
> +		p_mpeg2_slice_params = p;
> +
> +		zero_reserved(*p_mpeg2_slice_params);
>  		break;
>  
>  	case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
> @@ -2822,6 +2849,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>  	case V4L2_CTRL_TYPE_U32:
>  		elem_size = sizeof(u32);
>  		break;
> +	case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
> +		elem_size = sizeof(struct v4l2_ctrl_mpeg2_sequence);
> +		break;
> +	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
> +		elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture);
> +		break;
>  	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
>  		elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params);
>  		break;
> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
> index 9e3552cd5cf8..067205fb89f6 100644
> --- a/drivers/staging/media/hantro/hantro_drv.c
> +++ b/drivers/staging/media/hantro/hantro_drv.c
> @@ -286,6 +286,16 @@ static const struct hantro_ctrl controls[] = {
>  			.def = 50,
>  			.ops = &hantro_jpeg_ctrl_ops,
>  		},
> +	}, {
> +		.codec = HANTRO_MPEG2_DECODER,
> +		.cfg = {
> +			.id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
> +		},
> +	}, {
> +		.codec = HANTRO_MPEG2_DECODER,
> +		.cfg = {
> +			.id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
> +		},
>  	}, {
>  		.codec = HANTRO_MPEG2_DECODER,
>  		.cfg = {
> diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> index 6ef7ded863b2..f3494a70aa12 100644
> --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
> @@ -92,8 +92,8 @@ static void
>  hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
>  				struct vb2_buffer *src_buf,
>  				struct vb2_buffer *dst_buf,
> -				const struct v4l2_mpeg2_sequence *seq,
> -				const struct v4l2_mpeg2_picture *pic,
> +				const struct v4l2_ctrl_mpeg2_sequence *seq,
> +				const struct v4l2_ctrl_mpeg2_picture *pic,
>  				const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
>  {
>  	dma_addr_t forward_addr = 0, backward_addr = 0;
> @@ -153,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct vb2_v4l2_buffer *src_buf, *dst_buf;
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *seq;
> -	const struct v4l2_mpeg2_picture *pic;
> +	const struct v4l2_ctrl_mpeg2_sequence *seq;
> +	const struct v4l2_ctrl_mpeg2_picture *pic;
>  	u32 reg;
>  
>  	src_buf = hantro_get_src_buf(ctx);
> @@ -165,8 +165,10 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	slice_params = hantro_get_ctrl(ctx,
>  				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
> -	seq = &slice_params->sequence;
> -	pic = &slice_params->picture;
> +	seq = hantro_get_ctrl(ctx,
> +			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
> +	pic = hantro_get_ctrl(ctx,
> +			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
>  
>  	reg = G1_REG_DEC_AXI_RD_ID(0) |
>  	      G1_REG_DEC_TIMEOUT_E(1) |
> diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> index ff54398f6643..5b383906af59 100644
> --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
> @@ -95,8 +95,8 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
>  				 struct hantro_ctx *ctx,
>  				 struct vb2_buffer *src_buf,
>  				 struct vb2_buffer *dst_buf,
> -				 const struct v4l2_mpeg2_sequence *seq,
> -				 const struct v4l2_mpeg2_picture *pic,
> +				 const struct v4l2_ctrl_mpeg2_sequence *seq,
> +				 const struct v4l2_ctrl_mpeg2_picture *pic,
>  				 const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
>  {
>  	dma_addr_t forward_addr = 0, backward_addr = 0;
> @@ -156,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct vb2_v4l2_buffer *src_buf, *dst_buf;
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *seq;
> -	const struct v4l2_mpeg2_picture *pic;
> +	const struct v4l2_ctrl_mpeg2_sequence *seq;
> +	const struct v4l2_ctrl_mpeg2_picture *pic;
>  	u32 reg;
>  
>  	src_buf = hantro_get_src_buf(ctx);
> @@ -167,8 +167,10 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
>  
>  	slice_params = hantro_get_ctrl(ctx,
>  				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
> -	seq = &slice_params->sequence;
> -	pic = &slice_params->picture;
> +	seq = hantro_get_ctrl(ctx,
> +			      V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
> +	pic = hantro_get_ctrl(ctx,
> +			      V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
>  
>  	reg = VDPU_REG_DEC_ADV_PRE_DIS(0) |
>  	      VDPU_REG_DEC_SCMD_DIS(0) |
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
> index 62a5407664ae..878752b30c10 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
> @@ -29,6 +29,18 @@
>  #include "cedrus_hw.h"
>  
>  static const struct cedrus_control cedrus_controls[] = {
> +	{
> +		.cfg = {
> +			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE,
> +		},
> +		.codec		= CEDRUS_CODEC_MPEG2,
> +	},
> +	{
> +		.cfg = {
> +			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE,
> +		},
> +		.codec		= CEDRUS_CODEC_MPEG2,
> +	},
>  	{
>  		.cfg = {
>  			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
> index 6516bff3d319..989873ccb98c 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
> @@ -68,6 +68,8 @@ struct cedrus_h264_run {
>  };
>  
>  struct cedrus_mpeg2_run {
> +	const struct v4l2_ctrl_mpeg2_sequence		*sequence;
> +	const struct v4l2_ctrl_mpeg2_picture		*picture;
>  	const struct v4l2_ctrl_mpeg2_slice_params	*slice_params;
>  	const struct v4l2_ctrl_mpeg2_quantisation	*quantisation;
>  };
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> index 238f779d2ba4..f4cc6aebfac9 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> @@ -40,6 +40,10 @@ void cedrus_device_run(void *priv)
>  
>  	switch (ctx->src_fmt.pixelformat) {
>  	case V4L2_PIX_FMT_MPEG2_SLICE:
> +		run.mpeg2.sequence = cedrus_find_control_data(ctx,
> +			V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE);
> +		run.mpeg2.picture = cedrus_find_control_data(ctx,
> +			V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE);
>  		run.mpeg2.slice_params = cedrus_find_control_data(ctx,
>  			V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
>  		run.mpeg2.quantisation = cedrus_find_control_data(ctx,
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> index e39a17d28c7d..65a175c6a5c2 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
> @@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
>  static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  {
>  	const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> -	const struct v4l2_mpeg2_sequence *seq;
> -	const struct v4l2_mpeg2_picture *pic;
> +	const struct v4l2_ctrl_mpeg2_sequence *seq;
> +	const struct v4l2_ctrl_mpeg2_picture *pic;
>  	const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
>  	dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
>  	dma_addr_t fwd_luma_addr, fwd_chroma_addr;
> @@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
>  	u32 reg;
>  
>  	slice_params = run->mpeg2.slice_params;
> -	seq = &slice_params->sequence;
> -	pic = &slice_params->picture;
> +	seq = run->mpeg2.sequence;
> +	pic = run->mpeg2.picture;
>  
>  	quantisation = run->mpeg2.quantisation;
>  
> diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h
> index d3190979d574..2a26c03e3ead 100644
> --- a/include/media/mpeg2-ctrls.h
> +++ b/include/media/mpeg2-ctrls.h
> @@ -13,23 +13,45 @@
>  
>  #define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS		(V4L2_CID_CODEC_BASE+250)
>  #define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION		(V4L2_CID_CODEC_BASE+251)
> +#define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE		(V4L2_CID_CODEC_BASE+252)
> +#define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE		(V4L2_CID_CODEC_BASE+253)
>  
>  /* enum v4l2_ctrl_type type values */
> -#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
> -#define	V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104
> +#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0130
> +#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131
> +#define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132
> +#define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133
>  
>  #define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE		0x0001
>  
> -struct v4l2_mpeg2_sequence {
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
> +/**
> + * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header
> + *
> + * All the members on this structure match the sequence header and sequence
> + * extension syntaxes as specified by the MPEG-2 specification.
> + *
> + * Fields horizontal_size, vertical_size and vbv_buffer_size are a
> + * combination of respective _value and extension syntax elements,
> + * as described in section 6.3.3 "Sequence header".
> + *
> + * @horizontal_size: combination of elements horizontal_size_value and
> + * horizontal_size_extension.
> + * @vertical_size: combination of elements vertical_size_value and
> + * vertical_size_extension.
> + * @vbv_buffer_size: combination of elements vbv_buffer_size_value and
> + * vbv_buffer_size_extension.
> + * @profile_and_level_indication: see MPEG-2 specification.
> + * @chroma_format: see MPEG-2 specification.
> + * @reserved: padding field. Should be zeroed by applications.
> + * @flags: see V4L2_MPEG2_SEQ_FLAG_{}.
> + */
> +struct v4l2_ctrl_mpeg2_sequence {
>  	__u16	horizontal_size;
>  	__u16	vertical_size;
>  	__u32	vbv_buffer_size;
> -
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
>  	__u16	profile_and_level_indication;
>  	__u8	chroma_format;
> -
> +	__u8	reserved;
>  	__u32	flags;

I really don't like to have 'reserved' in the middle of a struct.

Can we make flags a u8? There is just a single flag at the
moment, so it's not as if we are about to run out of bits.


>  };
>  
> @@ -51,33 +73,72 @@ struct v4l2_mpeg2_sequence {
>  #define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST		0x0040
>  #define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE			0x0080
>  
> -struct v4l2_mpeg2_picture {
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
> +/**
> + * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header
> + *
> + * All the members on this structure match the picture header and picture
> + * coding extension syntaxes as specified by the MPEG-2 specification.
> + *
> + * @picture_coding_type: see MPEG-2 specification.
> + * @f_code[2][2]: see MPEG-2 specification.
> + * @intra_dc_precision: see MPEG-2 specification.
> + * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD.
> + * @reserved: padding field. Should be zeroed by applications.
> + * @flags: see V4L2_MPEG2_PIC_FLAG_{}.
> + */
> +struct v4l2_ctrl_mpeg2_picture {
>  	__u8	picture_coding_type;
> -
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
>  	__u8	f_code[2][2];
>  	__u8	intra_dc_precision;
>  	__u8	picture_structure;
> -
> +	__u8	reserved;
>  	__u32	flags;

Here all the bits are in use, so changing u32 to u8 might not be an
option. But is it possible to move flags up in the struct to avoid
having a reserved field in the middle? I prefer to have reserved fields
at the end, if at all possible.

>  };
>  
> +/**
> + * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header
> + *
> + * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as
> + * reference for backward prediction.
> + * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as
> + * reference for forward prediction. These timestamp refers to the
> + * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns()
> + * to convert the struct timeval to a __u64.
> + * @quantiser_scale_code: quantiser scale integer matching an
> + * homonymous syntax element.
> + * @reserved: padding field. Should be zeroed by applications.
> + */
>  struct v4l2_ctrl_mpeg2_slice_params {
>  	__u32	bit_size;
>  	__u32	data_bit_offset;
>  	__u64	backward_ref_ts;
>  	__u64	forward_ref_ts;
> -
> -	struct v4l2_mpeg2_sequence sequence;
> -	struct v4l2_mpeg2_picture picture;
> -
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
>  	__u32	quantiser_scale_code;
> +	__u32	reserved;
>  };
>  
> +/**
> + * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation
> + *
> + * Quantization matrices as specified by section 6.3.7
> + * "Quant matrix extension".
> + *
> + * @intra_quantiser_matrix: The quantisation matrix coefficients
> + * for intra-coded frames, in zigzag scanning order. It is relevant
> + * for both luma and chroma components, although it can be superseded
> + * by the chroma-specific matrix for non-4:2:0 YUV formats.
> + * @non_intra_quantiser_matrix: The quantisation matrix coefficients
> + * for non-intra-coded frames, in zigzag scanning order. It is relevant
> + * for both luma and chroma components, although it can be superseded
> + * by the chroma-specific matrix for non-4:2:0 YUV formats.
> + * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients
> + * for the chominance component of intra-coded frames, in zigzag scanning
> + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
> + * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients
> + * for the chrominance component of non-intra-coded frames, in zigzag scanning
> + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats.
> + */
>  struct v4l2_ctrl_mpeg2_quantisation {
> -	/* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
>  	__u8	intra_quantiser_matrix[64];
>  	__u8	non_intra_quantiser_matrix[64];
>  	__u8	chroma_intra_quantiser_matrix[64];
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index a560005c575a..6406cdc3f56d 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -40,6 +40,8 @@ struct video_device;
>   * @p_u16:			Pointer to a 16-bit unsigned value.
>   * @p_u32:			Pointer to a 32-bit unsigned value.
>   * @p_char:			Pointer to a string.
> + * @p_mpeg2_sequence:		Pointer to a MPEG2 sequence structure.
> + * @p_mpeg2_picture:		Pointer to a MPEG2 picture structure.
>   * @p_mpeg2_slice_params:	Pointer to a MPEG2 slice parameters structure.
>   * @p_mpeg2_quantisation:	Pointer to a MPEG2 quantisation data structure.
>   * @p_fwht_params:		Pointer to a FWHT stateless parameters structure.
> @@ -64,6 +66,8 @@ union v4l2_ctrl_ptr {
>  	u16 *p_u16;
>  	u32 *p_u32;
>  	char *p_char;
> +	struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
> +	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
>  	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
>  	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
>  	struct v4l2_ctrl_fwht_params *p_fwht_params;
> 

Regards,

	Hans

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-04-06 10:38 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-03 18:07 [PATCH v5 00/10] MPEG-2 stateless API cleanup and destaging Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 01/10] media: uapi: mpeg2: Rename "quantization" to "quantisation" Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 02/10] media: uapi: mpeg2: rework quantisation matrices semantics Ezequiel Garcia
2021-04-06 10:25   ` Hans Verkuil
2021-04-03 18:07 ` [PATCH v5 03/10] media: uapi: mpeg2: Cleanup flags Ezequiel Garcia
2021-04-06 10:27   ` Hans Verkuil
2021-04-03 18:07 ` [PATCH v5 04/10] media: uapi: mpeg2: Split sequence and picture parameters Ezequiel Garcia
2021-04-06 10:37   ` Hans Verkuil
2021-04-03 18:07 ` [PATCH v5 05/10] media: uapi: mpeg2: Move reference buffer fields Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 06/10] media: hantro/cedrus: Remove unneeded slice size and slice offset Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 07/10] media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 08/10] media: controls: Log MPEG-2 stateless control in .std_log Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 09/10] media: uapi: Move the MPEG-2 stateless control type out of staging Ezequiel Garcia
2021-04-03 18:07 ` [PATCH v5 10/10] media: uapi: move MPEG-2 stateless controls " Ezequiel Garcia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).