From: Arun Iyengar via B4 Relay <devnull+aiyengar1990.gmail.com@kernel.org>
To: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
Paul Kocialkowski <paulk@sys-base.io>,
Nicolas Dufresne <nicolas.dufresne@collabora.com>,
Hans Verkuil <hverkuil@kernel.org>,
Arun Iyengar <aiyengar1990@gmail.com>
Subject: [PATCH RFC 07/10] media: v4l2-hevc-enc: Add a constant bitrate mode
Date: Tue, 10 Nov 2026 10:07:37 +0000 [thread overview]
Message-ID: <20261110-hevc-encode-uapi-v1-7-38ae9fcfedd4@gmail.com> (raw)
In-Reply-To: <20261110-hevc-encode-uapi-v1-0-38ae9fcfedd4@gmail.com>
From: Arun Iyengar <aiyengar1990@gmail.com>
The HEVC encode core leaves the constant bitrate mode to the drivers, so
each driver needs its own frame rate control.
Provide the mode in the core with the codec independent rate control of
the H.264 encode core (v4l2-enc-cbr): one QP state for the stream, I
pictures 4 QP below the P pictures (the default of the Rockchip MPP
library for HEVC), picture size targets from a GOP plan with the I/P
size ratio and IDR period measured on the stream, and the deviation from
that plan spread over the next pictures. The size target of the current
picture is available to drivers whose hardware also controls the rate
within a picture.
A driver rate control with an estimate callback still replaces the mode.
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
drivers/media/v4l2-core/Kconfig | 1 +
drivers/media/v4l2-core/v4l2-hevc-enc.c | 35 +++++++++++++++++++++++++++++++++
include/media/v4l2-hevc-enc.h | 11 +++++++++--
3 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index eb245deb4622..0de0bad58791 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -60,6 +60,7 @@ config V4L2_HEVC_ENC_RBSP
# Used by drivers that need v4l2-hevc-enc.ko
config V4L2_HEVC_ENC
tristate
+ select V4L2_ENC_CBR
select V4L2_HEVC_ENC_RBSP
config V4L2_HEVC_ENC_RBSP_KUNIT_TEST
diff --git a/drivers/media/v4l2-core/v4l2-hevc-enc.c b/drivers/media/v4l2-core/v4l2-hevc-enc.c
index e2aa7d2da96c..a167c4af6288 100644
--- a/drivers/media/v4l2-core/v4l2-hevc-enc.c
+++ b/drivers/media/v4l2-core/v4l2-hevc-enc.c
@@ -18,6 +18,7 @@
#include <linux/sort.h>
#include <linux/v4l2-controls.h>
#include <media/v4l2-ctrls.h>
+#include <media/v4l2-enc-cbr.h>
#include <media/v4l2-hevc.h>
#include <media/v4l2-hevc-enc.h>
#include <media/v4l2-hevc-enc-rbsp.h>
@@ -26,6 +27,12 @@
#define RBSP_UPDATE_AUD BIT(0)
#define RBSP_UPDATE_PARAMETER_SETS BIT(1)
+/*
+ * Constant bitrate mode: I pictures 4 QP below the P pictures, the default
+ * of the Rockchip MPP library for HEVC.
+ */
+#define RC_CBR_QP_DELTA_INTRA 4
+
/* Table A.8: MaxLumaPs and MaxLumaSr (main tier is enough to pick a level) */
static const struct {
u8 level_idc;
@@ -150,6 +157,7 @@ int v4l2_hevc_enc_init(struct v4l2_hevc_enc *enc)
memset(&enc->state_next, 0, sizeof(enc->state_next));
memset(&enc->ref, 0, sizeof(enc->ref));
enc->state_serial = 0;
+ v4l2_enc_cbr_reset(&enc->cbr, RC_CBR_QP_DELTA_INTRA);
if (!enc->max_l0_refs)
enc->max_l0_refs = 1;
@@ -1052,6 +1060,18 @@ static int ref_step(struct v4l2_hevc_enc *enc)
return 0;
}
+/*
+ * The core provides the constant bitrate mode unless the driver has its own
+ * rate control.
+ */
+static bool rc_core_cbr(const struct v4l2_hevc_enc *enc,
+ const struct v4l2_hevc_enc_state *state)
+{
+ return state->frame_rc_enable &&
+ state->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
+ !(enc->rc_ops && enc->rc_ops->estimate);
+}
+
static int rc_step(struct v4l2_hevc_enc *enc)
{
struct v4l2_hevc_enc_state *state = &enc->state_active;
@@ -1074,6 +1094,17 @@ static int rc_step(struct v4l2_hevc_enc *enc)
if (range)
qp -= (state->quality - state->quality_min) *
(state->qp_max - state->qp_min) / range;
+ } else if (rc_core_cbr(enc, state)) {
+ ret = v4l2_enc_cbr_begin(&enc->cbr, state->bitrate,
+ &state->timeperframe,
+ state->sps.pic_width_in_luma_samples *
+ state->sps.pic_height_in_luma_samples,
+ slice_type == V4L2_HEVC_SLICE_TYPE_I,
+ state->qp_min, state->qp_max);
+ if (ret)
+ return ret;
+
+ qp = v4l2_enc_cbr_qp(&enc->cbr);
} else {
if (!enc->rc_ops || !enc->rc_ops->estimate)
return -EOPNOTSUPP;
@@ -1382,6 +1413,10 @@ int v4l2_hevc_enc_complete(struct v4l2_hevc_enc *enc,
!v4l2_hevc_nal_is_sub_layer_non_ref(nal_unit_type))
enc->ref.prev_tid0_poc = encode->pic_order_cnt_val;
+ if (rc_core_cbr(enc, state))
+ v4l2_enc_cbr_end(&enc->cbr, (u64)bytesused * 8,
+ &state->timeperframe, state->qp_min,
+ state->qp_max);
if (enc->rc_ops && enc->rc_ops->complete)
enc->rc_ops->complete(enc, state, bytesused, stats);
diff --git a/include/media/v4l2-hevc-enc.h b/include/media/v4l2-hevc-enc.h
index 4797102e34b3..3db131370c56 100644
--- a/include/media/v4l2-hevc-enc.h
+++ b/include/media/v4l2-hevc-enc.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
+#include <media/v4l2-enc-cbr.h>
#include <media/v4l2-hevc-enc-rbsp.h>
struct v4l2_ctrl_handler;
@@ -186,8 +187,10 @@ struct v4l2_hevc_enc_ops {
/**
* struct v4l2_hevc_enc_rc_ops - driver rate control
*
- * The core selects the QP itself for the direct QP and constant quality
- * modes. These callbacks provide the constant and variable bitrate modes.
+ * The core selects the QP itself for the direct QP, constant quality and
+ * constant bitrate modes. These callbacks replace the constant bitrate
+ * mode of the core (if @estimate is set) and provide the variable bitrate
+ * mode.
*
* @estimate: return the QP of the next picture in @qp
* @complete: account for a completed picture
@@ -231,6 +234,9 @@ struct v4l2_hevc_enc_rc_ops {
* @rbsp: NAL unit writer
* @slice: slice segment header of the current picture
* @qp: SliceQpY of the current picture
+ * @cbr: constant bitrate rate control of the core. In that mode,
+ * @cbr.target_bits is the size target of the current picture in bits,
+ * for hardware with a rate control within the picture.
* @header_size: number of bytes the core wrote at the start of the
* CAPTURE buffer. The hardware writes from that offset.
* @parameter_sets_pending: parameter sets were written for a picture that
@@ -261,6 +267,7 @@ struct v4l2_hevc_enc {
struct v4l2_hevc_enc_rbsp rbsp;
struct v4l2_hevc_slice_header slice;
int qp;
+ struct v4l2_enc_cbr cbr;
unsigned int header_size;
bool parameter_sets_pending;
--
2.55.0
next prev parent reply other threads:[~2026-11-10 10:07 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 10:07 [PATCH RFC 00/10] media: Add a V4L2 HEVC stateless encode uAPI and helpers Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 01/10] media: hevc: Add H.265 syntax definitions Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 02/10] media: uapi: Add HEVC stateless encode support Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 03/10] media: hevc: Add stateless encode RBSP writer Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 04/10] media: hevc: Add KUnit tests for the " Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 05/10] media: hevc: Add stateless encode core Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 06/10] media: hevc: Add KUnit tests for the " Arun Iyengar via B4 Relay
2026-11-10 10:07 ` Arun Iyengar via B4 Relay [this message]
2026-11-10 10:07 ` [PATCH RFC 08/10] media: v4l2-hevc-enc: Add QP limits for the I pictures Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 09/10] media: v4l2-hevc-enc: Re-encode oversized pictures Arun Iyengar via B4 Relay
2026-11-10 10:07 ` [PATCH RFC 10/10] media: docs: Document the HEVC stateless encode uAPI 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-hevc-encode-uapi-v1-7-38ae9fcfedd4@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=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®