From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1794305257; b=qODU2Rjr+Owv5Kt52zDh0RgixBuTp5GP1NpwK8AY5zwLfaWo4sC5tOXkzecYLuC7Cb58 /jETSDcAJc40OBQmIPGea3HArCTE8PjcyLtWWCSdlwu/X6vJSmL6J2X447+fT5oqQmZrS 8e8Mn+l6xfFXZnsKlz5JnCFQ2oKbHZjmRABcaNSJLALrnFjCDOmPLq2FJplqfOX4S+Veg FpYAH45TKQhUvRfMOQrsKJKs3jQMEI9r+CpTHOCXc40hSI3gDld6MoTaX7JWPAmRIw/U7 2C174G5hd5fYnpGJc8BUKHWmgs5BiW/1YhwiTwhZY3z+6GQ2AcG7ifpvrD67uIQTG+w== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794305257; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=DVSGY+ikZjR75l/iBgjjxuFAk9HeQ6YTF4NOlMUD23U=; b=eWYa6OVjGvFxUSxBQZGVTEbhyGGDl9poFFVaccpN21b021ShIOFGlZ0lF0vTfPWmwDlI dZFYLej02rxk+IPortgoxH9ZuMF2nJkU9RTzwbmkIOCOxNgb+c7sOCu8Ks6oKtFoKO38w teE1VNbrspP4sXlOh048tj+udMk4ngHkk6PRAb0TSdFChrmhaP71QwgoyYWjR1XEWDEJj WmaIFVidTtF7Lr+QuIjKT/ClBkoFynOHSnEF1xSVeTn+yKkuMDrUnwJOJDWYRKeQogMX8 +r/yHaclpJZeAXLqTCcMztJ6FUX8tyNMqTOH2/+8aqloalov/166NNBm/dt2HFWNVrw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Gjb5RIaw; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9206B60A2607; Tue, 10 Nov 2026 10:07:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Gjb5RIaw Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1794305257; b=LIfsKi02U1RZVr7+mtp70QbX6MTGaOu55UYd+UJOeesU0AI7OBCGUpgveLinKeOt6R4n Wh12jUy0jLrMoFvvo8PtuJohg0cJIZNujJfOCimZRRW9BpJzswPvBAWWNuzMW3qcXGL2/ 4LWLZQzAv2NE4dTq29i3fs8aJsNiwuxnMhLZn01KL1SpZ1QC0KPB621PgtVYZTjfYhROT PjNCfw5e2hT/PK+Mep1YlKMvR8Vlb5teyIsAOePG6yBI9ompX1M0480mWWpZu459uiI+y X0vsbz/ep07lratmjVnNTXgJ4CqElrVKt3UDG44yLY7S8rQ27GPJurGA/WGSPGS/Oug== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1794305257; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=DVSGY+ikZjR75l/iBgjjxuFAk9HeQ6YTF4NOlMUD23U=; b=bwyj30sjEXhTF80povIwmQehUJuZ5bM01WUnjQ8V6u+AAjLTW2exE0CemOFNvbygWfXw XPrtJBAUHHEjjYYv+FsbkboqmS2qG1TO3gNZZSlBD+YiWeVfU5d1zECiV0I53GEKt5W+b 9moJ0sgDhjoljsDwtCLt/V90eqiT3+L1wo7DkLqIJudscCeRWxxfwEqEQxLGJVpEfk3w6 p6EVhgZf1cYORrNqqFKXYbP9w9szTkhZr9f/KPXe5DcezhmCNrxBVhepy7lfI8j8goaef jcxojNUB8xOeNHYEKlQ+0JjQCeoeihmsu8YkWIMjCn8+BJpuCl4U593JK981FHC3SvA== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id E81971F008A1; Tue, 10 Nov 2026 10:07:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794305257; bh=DVSGY+ikZjR75l/iBgjjxuFAk9HeQ6YTF4NOlMUD23U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=Gjb5RIawi8F1ELfoluECWnHKpGwyXaKr+v4Bq6R1FNwvmKqSHQQZD3nJZz88s3MPH mcV6KFK0ZEn9/CTspVh312FpcD8EZh4WakDYSQV58vLsTrdpSRddnogMgErSdEXF8o g1DpIKnCyV4lWDZknr79rIvwqOnT/WK5rbo17K/2kTZAWkyyYSt4c53/9Bqva/h0sP uTwvLyUJUmrI0z3iuaOJJm69ANI2OsGiIrywF/O8UueIygufXOgVAhiPH+o/XT7PWn KgMtEiR1+V2nUkdzwVQYwfFnPNEsEitZikrbIigMmB/Fa58sIRc7Kh5fvbeQOoIn9g F7M82JgyOU8ww== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id 5DD9048ABA; Tue, 10 Nov 2026 10:07:32 +0000 (UTC) From: Arun Iyengar via B4 Relay Date: Tue, 10 Nov 2026 10:07:37 +0000 Subject: [PATCH RFC 07/10] media: v4l2-hevc-enc: Add a constant bitrate mode X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261110-hevc-encode-uapi-v1-7-38ae9fcfedd4@gmail.com> References: <20261110-hevc-encode-uapi-v1-0-38ae9fcfedd4@gmail.com> In-Reply-To: <20261110-hevc-encode-uapi-v1-0-38ae9fcfedd4@gmail.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Kocialkowski , Nicolas Dufresne , Hans Verkuil , Arun Iyengar X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1794305251; l=6157; i=aiyengar1990@gmail.com; s=20261110; h=from:subject:message-id; bh=23ba8LskleVLZZbBxcmsP87XKCLHrF2u42oZjR6n+6k=; b=Gttsa90tsSGrgff3Gw4/JqPdfDS28JuD0I+laEZgjKtrfsmHsfMtHkft+VDMK/mlBnQ3tsbcZ RTR6ruVgS3zAAYtAn0bOnbMPX+dCinf+dBHktpxIbP41GibMUIX/rIZ X-Developer-Key: i=aiyengar1990@gmail.com; a=ed25519; pk=zXpRgUTrhaFe6jLyPqbBy3ccfkj04w0g2690Wv3mg+0= X-Endpoint-Received: by B4 Relay for aiyengar1990@gmail.com/20261110 with auth_id=1480 X-Original-From: Arun Iyengar Reply-To: aiyengar1990@gmail.com Content-Transfer-Encoding: 7bit From: Arun Iyengar 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 --- 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include 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