From mboxrd@z Thu Jan 1 00:00:00 1970 From: Arun Iyengar Date: Tue, 10 Nov 2026 10:07:38 +0000 Subject: [PATCH RFC 08/10] media: v4l2-hevc-enc: Add QP limits for the I pictures MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261110-hevc-encode-uapi-v1-8-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=3795; i=aiyengar1990@gmail.com; s=20261110; h=from:subject:message-id; bh=AE4kglGiR5u7/pgWxx7FMl4jnb/lWjlmJsY7hLn1kAM=; b=VLX/BGi7saL9KOTcpT5V6O7pX9fdNr0GoOZRt7wCU3xHbiW6aYEvcFaHsQnXZgxO4sMrgIMEw C/ZhaQo7CJTDHRp7AmwMKg+LeiLa/C0reqCPgbF6AfMAv81KEzRQ92m 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 List-Id: B4 Relay Submissions The frame rate control of the core limits all pictures to the range of V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP and V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP. The I pictures, coded several QP steps below the P pictures, then reach very low QP values at high bitrates, where they cost many bits for little quality. Take the limits of the I pictures from V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP and V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP when the driver has them, with a frame rate control. Without these controls, nothing changes. Signed-off-by: Arun Iyengar --- drivers/media/v4l2-core/v4l2-hevc-enc.c | 24 +++++++++++++++++++++--- include/media/v4l2-hevc-enc.h | 7 +++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-hevc-enc.c b/drivers/media/v4l2-core/v4l2-hevc-enc.c index a167c4af6288..2e0ba832b868 100644 --- a/drivers/media/v4l2-core/v4l2-hevc-enc.c +++ b/drivers/media/v4l2-core/v4l2-hevc-enc.c @@ -645,6 +645,12 @@ static void prepare_rc(struct v4l2_hevc_enc *enc, state->qp_min = enc_ctrl_val(enc, V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, -qp_bd_offset); state->qp_max = enc_ctrl_val(enc, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, 51); + state->qp_min_i = enc_ctrl_val(enc, + V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP, + state->qp_min); + state->qp_max_i = enc_ctrl_val(enc, + V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP, + state->qp_max); state->qp_i = enc_ctrl_val(enc, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, 30); state->qp_p = enc_ctrl_val(enc, V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, state->qp_i); @@ -1072,10 +1078,23 @@ static bool rc_core_cbr(const struct v4l2_hevc_enc *enc, !(enc->rc_ops && enc->rc_ops->estimate); } +/* QP limits of the picture: the I picture ones with a frame rate control */ +static int rc_clamp_qp(const struct v4l2_hevc_enc_state *state, int qp) +{ + int qp_bd_offset = 6 * state->sps.bit_depth_luma_minus8; + + if (state->frame_rc_enable && + state->encode.slice_type == V4L2_HEVC_SLICE_TYPE_I) + qp = clamp(qp, state->qp_min_i, state->qp_max_i); + else + qp = clamp(qp, state->qp_min, state->qp_max); + + return clamp(qp, -qp_bd_offset, 51); +} + static int rc_step(struct v4l2_hevc_enc *enc) { struct v4l2_hevc_enc_state *state = &enc->state_active; - int qp_bd_offset = 6 * state->sps.bit_depth_luma_minus8; u8 slice_type = state->encode.slice_type; unsigned int range; int qp, ret; @@ -1114,8 +1133,7 @@ static int rc_step(struct v4l2_hevc_enc *enc) return ret; } - qp = clamp(qp, state->qp_min, state->qp_max); - enc->qp = clamp(qp, -qp_bd_offset, 51); + enc->qp = rc_clamp_qp(state, qp); return 0; } diff --git a/include/media/v4l2-hevc-enc.h b/include/media/v4l2-hevc-enc.h index 3db131370c56..f1d3da3269f1 100644 --- a/include/media/v4l2-hevc-enc.h +++ b/include/media/v4l2-hevc-enc.h @@ -128,6 +128,11 @@ struct v4l2_hevc_enc_ref { * @frame_rc_enable: V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE * @qp_min: V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP * @qp_max: V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP + * @qp_min_i: V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP, @qp_min if the driver + * has no such control. Limits the I pictures with a frame rate + * control instead of @qp_min. + * @qp_max_i: V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP, @qp_max if the driver + * has no such control * @qp_i: V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP * @qp_p: V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP * @qp_b: V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP @@ -153,6 +158,8 @@ struct v4l2_hevc_enc_state { bool frame_rc_enable; int qp_min; int qp_max; + int qp_min_i; + int qp_max_i; int qp_i; int qp_p; int qp_b; -- 2.55.0