mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Arun Iyengar via B4 Relay <devnull+aiyengar1990.gmail.com@kernel.org>
To: Mauro Carvalho Chehab <mchehab@kernel.org>,
	 Paul Kocialkowski <paulk@sys-base.io>
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
	 Nicolas Dufresne <nicolas.dufresne@collabora.com>,
	 Hans Verkuil <hverkuil@kernel.org>,
	Marco Felsch <m.felsch@pengutronix.de>,
	 Michael Tretter <m.tretter@pengutronix.de>,
	 Arun Iyengar <aiyengar1990@gmail.com>
Subject: [PATCH RFC 02/11] media: h264: Support picture order count type 2 in stateless encode
Date: Tue, 10 Nov 2026 10:05:16 +0000	[thread overview]
Message-ID: <20261110-h264-encode-fixes-v1-2-7a64486df499@gmail.com> (raw)
In-Reply-To: <20261110-h264-encode-fixes-v1-0-7a64486df499@gmail.com>

From: Arun Iyengar <aiyengar1990@gmail.com>

Some encoders write the slice header in hardware and can't put a
pic_order_cnt_lsb in it: the Hantro H1 and Rockchip VEPU1/VEPU2 encoders
only produce slice headers for pic_order_cnt_type 2, where the picture
order count is derived from frame_num.

Accept pic_order_cnt_type 2, which drivers can then select in their
state_constrain operation, and compute the picture order count as
specified in ITU-T H.264 section 8.2.1.3. This needs the frame_num and
FrameNumOffset of the previous picture in decoding order, which are now
tracked for every picture, reference or not.

Type 2 implies that the output order is the decoding order, which is
always the case without B frames. Type 1 is still rejected.

Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
 drivers/media/v4l2-core/v4l2-h264-enc-rbsp.c |  3 +-
 drivers/media/v4l2-core/v4l2-h264-enc.c      | 51 +++++++++++++++++++++++++---
 include/media/v4l2-h264-enc.h                |  3 ++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-h264-enc-rbsp.c b/drivers/media/v4l2-core/v4l2-h264-enc-rbsp.c
index a165f8114ce9..2d751855195b 100644
--- a/drivers/media/v4l2-core/v4l2-h264-enc-rbsp.c
+++ b/drivers/media/v4l2-core/v4l2-h264-enc-rbsp.c
@@ -758,7 +758,8 @@ int v4l2_h264_enc_rbsp_sps(struct v4l2_h264_enc_rbsp *rbsp,
 			if (ret)
 				return ret;
 		}
-	} else {
+	} else if (sps->pic_order_cnt_type != 2) {
+		/* Type 2 has no further syntax elements. */
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/v4l2-core/v4l2-h264-enc.c b/drivers/media/v4l2-core/v4l2-h264-enc.c
index af925b6626cf..9745c0e85ee5 100644
--- a/drivers/media/v4l2-core/v4l2-h264-enc.c
+++ b/drivers/media/v4l2-core/v4l2-h264-enc.c
@@ -200,10 +200,11 @@ static int state_prepare_params(struct v4l2_h264_enc *enc)
 	sps->pic_height_in_map_units_minus1 = state->height_mbs - 1;
 
 	/*
-	 * Only pic_order_cnt_type = 0 is currently supported.
-	 * Error out since no pic_order_cnt_lsb was provided.
+	 * Only pic_order_cnt_type 0 and 2 are currently supported. Type 2
+	 * derives the picture order count from frame_num, for hardware that
+	 * can't write pic_order_cnt_lsb in the slice header.
 	 */
-	if (sps->pic_order_cnt_type)
+	if (sps->pic_order_cnt_type == 1)
 		return -EINVAL;
 
 	/* SPS Video */
@@ -933,6 +934,41 @@ static int ref_step_buffers(struct v4l2_h264_enc *enc)
 	return 0;
 }
 
+/* Picture order count type 2, see ITU-T H.264 section 8.2.1.3. */
+static int ref_step_poc_type2(struct v4l2_h264_enc *enc)
+{
+	struct v4l2_h264_enc_state *state = &enc->state_active;
+	struct v4l2_ctrl_h264_sps *sps = &state->sps;
+	struct v4l2_ctrl_h264_encode_params *encode = &state->encode;
+	struct v4l2_h264_enc_ref *ref = &enc->ref;
+	unsigned int max_frame_num = BIT(sps->log2_max_frame_num_minus4 + 4);
+	unsigned int frame_num_offset;
+	unsigned int pic_order_cnt;
+
+	if (encode->flags & V4L2_H264_ENCODE_FLAG_IDR_PIC)
+		frame_num_offset = 0;
+	else if (ref->prev_frame_num > encode->frame_num)
+		frame_num_offset = ref->prev_frame_num_offset + max_frame_num;
+	else
+		frame_num_offset = ref->prev_frame_num_offset;
+
+	if (encode->flags & V4L2_H264_ENCODE_FLAG_IDR_PIC)
+		pic_order_cnt = 0;
+	else if (!encode->nal_ref_idc)
+		pic_order_cnt = 2 * (frame_num_offset + encode->frame_num) - 1;
+	else
+		pic_order_cnt = 2 * (frame_num_offset + encode->frame_num);
+
+	ref->frame_num_offset = frame_num_offset;
+	ref->pic_order_cnt_msb = 0;
+	ref->pic_order_cnt_lsb = 0;
+	ref->top_field_order_cnt = pic_order_cnt;
+	ref->bottom_field_order_cnt = pic_order_cnt;
+	ref->pic_order_cnt = pic_order_cnt;
+
+	return 0;
+}
+
 static int ref_step_poc(struct v4l2_h264_enc *enc)
 {
 	struct v4l2_h264_enc_state *state = &enc->state_active;
@@ -949,7 +985,10 @@ static int ref_step_poc(struct v4l2_h264_enc *enc)
 	unsigned int top_field_order_cnt;
 	unsigned int bottom_field_order_cnt;
 
-	/* Only pic_order_cnt_type = 0 is currently supported. */
+	if (sps->pic_order_cnt_type == 2)
+		return ref_step_poc_type2(enc);
+
+	/* Only pic_order_cnt_type 0 and 2 are currently supported. */
 	if (sps->pic_order_cnt_type)
 		return -EINVAL;
 
@@ -1174,6 +1213,10 @@ static int ref_complete(struct v4l2_h264_enc *enc,
 	unsigned int index;
 	int ret;
 
+	/* Keep the frame number of the previous picture for POC type 2. */
+	ref->prev_frame_num = encode->frame_num;
+	ref->prev_frame_num_offset = ref->frame_num_offset;
+
 	if (!encode->nal_ref_idc)
 		return 0;
 
diff --git a/include/media/v4l2-h264-enc.h b/include/media/v4l2-h264-enc.h
index 6debdc95232c..ff7166109551 100644
--- a/include/media/v4l2-h264-enc.h
+++ b/include/media/v4l2-h264-enc.h
@@ -54,6 +54,9 @@ struct v4l2_h264_enc_ref {
 
 	struct v4l2_h264_reflist_builder builder;
 
+	unsigned int prev_frame_num;
+	unsigned int prev_frame_num_offset;
+	unsigned int frame_num_offset;
 	unsigned int prev_pic_order_cnt_msb;
 	unsigned int prev_pic_order_cnt_lsb;
 	unsigned int pic_order_cnt_msb;

-- 
2.55.0



  parent reply	other threads:[~2026-11-10 10:05 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 10:05 [PATCH RFC 00/11] media: h264: Stateless encode core follow-ups: parameter sets, POC type 2, CBR and VBR Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 01/11] media: h264: Only write the SPS and PPS of a stateless encode when they change Arun Iyengar via B4 Relay
2026-11-10 10:05 ` Arun Iyengar via B4 Relay [this message]
2026-11-10 10:05 ` [PATCH RFC 03/11] media: h264: Write the stateless encode SPS and PPS with nal_ref_idc 3 Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 04/11] media: v4l2-h264-enc-rc: Rework the constant bitrate mode Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 05/11] media: v4l2-core: Move the H.264 encode CBR rate control to a helper Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 06/11] media: v4l2-core: Bound the I picture size in the encode CBR rate control Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 07/11] media: v4l2-core: Halve the I picture QP increase of the encode CBR Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 08/11] media: v4l2-core: Re-encode oversized pictures in " Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 09/11] media: v4l2-core: Fix all-intra streams in the encode CBR rate control Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 10/11] media: v4l2-core: Add a peak bitrate to the encode " Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 11/11] media: h264: Add a VBR mode to the stateless " Arun Iyengar via B4 Relay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261110-h264-encode-fixes-v1-2-7a64486df499@gmail.com \
    --to=devnull+aiyengar1990.gmail.com@kernel.org \
    --cc=aiyengar1990@gmail.com \
    --cc=hverkuil@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=m.felsch@pengutronix.de \
    --cc=m.tretter@pengutronix.de \
    --cc=mchehab@kernel.org \
    --cc=nicolas.dufresne@collabora.com \
    --cc=paulk@sys-base.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®