From: Arun Iyengar <aiyengar1990@gmail.com>
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>
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
WARNING: multiple messages have this Message-ID (diff)
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
next prev parent reply other threads:[~2026-11-10 10:05 UTC|newest]
Thread overview: 26+ 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` Arun Iyengar via B4 Relay
2026-11-10 10:05 ` Arun Iyengar [this message]
2026-11-10 10:05 ` [PATCH RFC 02/11] media: h264: Support picture order count type 2 in stateless encode Arun Iyengar via B4 Relay
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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` Arun Iyengar via B4 Relay
2026-11-10 10:05 ` [PATCH RFC 08/11] media: v4l2-core: Re-encode oversized pictures in " Arun Iyengar
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` 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
2026-11-10 10:05 ` Arun Iyengar via B4 Relay
2026-11-11 1:20 ` [PATCH RFC 00/11] media: h264: Stateless encode core follow-ups: parameter sets, POC type 2, CBR and VBR Nicolas Dufresne
2026-11-12 16:20 ` Paul Kocialkowski
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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.