From: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
To: Vikash Garodia <vikash.garodia@oss.qualcomm.com>,
Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>,
Abhinav Kumar <abhinav.kumar@linux.dev>,
Bryan O'Donoghue <bod@kernel.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Add support for multi_slice in iris encoder
Date: Fri, 17 Jul 2026 13:51:10 +0530 [thread overview]
Message-ID: <4f7bc381-364e-40a2-b627-9388982fcf80@oss.qualcomm.com> (raw)
In-Reply-To: <766404b0-2252-47e0-b728-be9985067569@oss.qualcomm.com>
On 6/26/2026 5:58 PM, Vikash Garodia wrote:
>
> On 4/28/2026 12:44 PM, Sachin Kumar Garg wrote:
>> Add multi-slice encoding support with MAX_MB and MAX_BYTES modes.
>>
>> Clients can enable slice mode using V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE
>> control and configure slice size via
>> V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
>> or V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES controls.
>>
>> Signed-off-by: Sachin Kumar Garg <sachin.garg@oss.qualcomm.com>
>> ---
>> This series adds the support for multi slice feature in the
>
> series ?
>
>> Qualcomm Iris driver.
>>
>> Multi-slice mode allows encoding a single frame into multiple slices,
>> which can improve error resilience and enable parallel processing.
>> The feature supports two slice modes:
>> - MAX_MB mode: Slices are created based on macroblock count, controlled
>> via V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB
>> - MAX_BYTES mode: Slices are created based on byte size, controlled via
>> V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES
>>
>> Clients can enable slice mode using the
>> V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE control.
>>
>> This series adds multi-slice support for HFI Gen2 targets (SM8550 and
>> later).
>> Support for HFI Gen1 targets will be added in a follow-up series.
>>
>> This Patch has been verified with GST level.
>
> specify the platform tested.>
Hi Vikash, updated the platform tested list in v2 posting.
>> Command used:
>> gst-launch-1.0 -v videotestsrc ! video/x-raw,format=NV12, \
>> width=1280,height=720,framerate=30/1 ! v4l2h264enc output-io-mode=4 |
>> capture-io-mode=4 extra-controls="controls,video_bitrate_mode=1, \
>> slice_partitioning_method=1,number_of_mbs_in_a_slice=460;" \
>> ! filesink location=/opt/test_enc.h264
>> ---
>> drivers/media/platform/qcom/iris/iris_ctrls.c | 89 ++++++++++++
>> ++++++++++
>> drivers/media/platform/qcom/iris/iris_ctrls.h | 1 +
>> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 2 +
>> .../platform/qcom/iris/iris_platform_common.h | 3 +
>> .../media/platform/qcom/iris/iris_platform_gen2.c | 31 ++++++++
>> 5 files changed, 126 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/
>> media/platform/qcom/iris/iris_ctrls.c
>> index 3cec957580f5..52b92241e7f0 100644
>> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
>> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
>> @@ -13,6 +13,15 @@
>> #define CABAC_MAX_BITRATE 160000000
>> #define CAVLC_MAX_BITRATE 220000000
>> +#define MAX_SLICES_PER_FRAME 10
>
> can you reconfirm this if this is indeed limited to 10 ?
>
Hi Vikash, This has been replaced with a
per-platform capability (max_slices_per_frame), currently set to 128.
>> +#define MAX_SLICES_FRAME_RATE 60
>> +#define MAX_MB_SLICE_WIDTH 4096
>> +#define MAX_MB_SLICE_HEIGHT 2160
>> +#define MAX_BYTES_SLICE_WIDTH 1920
>> +#define MAX_BYTES_SLICE_HEIGHT 1088
>> +#define MIN_HEVC_SLICE_WIDTH 384
>> +#define MIN_AVC_SLICE_WIDTH 192
>> +#define MIN_SLICE_HEIGHT 128
>> static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type
>> cap_id)
>> {
>> @@ -112,6 +121,12 @@ static enum platform_inst_fw_cap_type
>> iris_get_cap_id(u32 id)
>> return IR_TYPE;
>> case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
>> return IR_PERIOD;
>> + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
>> + return SLICE_MODE;
>> + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
>> + return SLICE_MAX_BYTES;
>> + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
>> + return SLICE_MAX_MB;
>> default:
>> return INST_FW_CAP_MAX;
>> }
>> @@ -213,6 +228,12 @@ static u32 iris_get_v4l2_id(enum
>> platform_inst_fw_cap_type cap_id)
>> return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE;
>> case IR_PERIOD:
>> return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD;
>> + case SLICE_MODE:
>> + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
>> + case SLICE_MAX_BYTES:
>> + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
>> + case SLICE_MAX_MB:
>> + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
>> default:
>> return 0;
>> }
>> @@ -996,6 +1017,74 @@ int iris_set_ir_period(struct iris_inst *inst,
>> enum platform_inst_fw_cap_type ca
>> &ir_period, sizeof(u32));
>> }
>> +int iris_set_slice_count(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap_id)
>> +{
>> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
>> + u32 slice_mode = inst->fw_caps[SLICE_MODE].value;
>> + u32 bitrate = inst->fw_caps[BITRATE].value;
>> + u32 rc_type = inst->fw_caps[BITRATE_MODE].value;
>> + u32 fps = inst->frame_rate;
>> + u32 output_width = inst->fmt_dst->fmt.pix_mp.width;
>> + u32 output_height = inst->fmt_dst->fmt.pix_mp.height;
>> + u32 mbpf = NUM_MBS_PER_FRAME(output_height, output_width);
>> + u32 max_width, max_height, min_width, min_height;
>> + u32 max_avg_slicesize, hfi_value, hfi_id;
>> +
>> + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
>> + dev_dbg(inst->core->dev, "slice mode is: %u, ignore setting
>> to fw\n", slice_mode);
>> + return 0;
>> + }
>> + if (!fps) {
>> + dev_err(inst->core->dev, "Invalid frame rate %d\n", fps);
>> + return -EINVAL;
>> + }
>> + if (fps > MAX_SLICES_FRAME_RATE ||
>> + (rc_type != HFI_RC_OFF && rc_type != HFI_RC_CBR_CFR &&
>> + rc_type != HFI_RC_CBR_VFR)) {
>> + dev_err(inst->core->dev, "slice unsupported, fps: %u,
>> rc_type: %#x\n",
>> + fps, rc_type);
>> + return -EINVAL;
>> + }
>> +
>> + max_width = (slice_mode ==
>> V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
>> + MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH;
>> + max_height = (slice_mode ==
>> V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
>> + MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT;
>> + min_width = (inst->codec == V4L2_PIX_FMT_HEVC) ?
>> + MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH;
>> + min_height = MIN_SLICE_HEIGHT;
>
> All these values are made into common setter, if there is a SOC, which
> supports different capabilities, these need to be redesigned. Can you
> see on how to make this platform specific capabilities and then make the
> checks generic to be used for all SOCs ?
>
Hi Vikash, reworked as suggested. All the slice limits parameters
are now fields on struct platform_inst_caps (iris_platform_common.h),
populated per-SoC in platform files.
>> +
>> + if (output_width < min_width || output_height < min_height ||
>> + output_width > max_width || output_height > max_height) {
>> + dev_err(inst->core->dev, "slice unsupported, codec: %#x wxh:
>> [%dx%d]\n",
>> + inst->codec, output_width, output_height);
>> + return -EINVAL;
>> + }
>> +
>> + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
>> + hfi_value = inst->fw_caps[SLICE_MAX_MB].value;
>> + hfi_value = max(hfi_value, mbpf / MAX_SLICES_PER_FRAME);
>> + if (inst->codec == V4L2_PIX_FMT_HEVC)
>> + hfi_value = (hfi_value + 3) / 4;
>> + hfi_id = inst->fw_caps[SLICE_MAX_MB].hfi_id;
>> + } else if (slice_mode ==
>> V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
>> + hfi_value = inst->fw_caps[SLICE_MAX_BYTES].value;
>> + if (rc_type != HFI_RC_OFF) {
>> + max_avg_slicesize = ((bitrate / fps) / 8) /
>> MAX_SLICES_PER_FRAME;
>> + hfi_value = max(hfi_value, max_avg_slicesize);
>> + }
>> + hfi_id = inst->fw_caps[SLICE_MAX_BYTES].hfi_id;
>> + } else {
>> + return -EINVAL;
>> + }
>> +
>> + return hfi_ops->session_set_property(inst, hfi_id,
>> + HFI_HOST_FLAGS_NONE,
>> + iris_get_port_info(inst, cap_id),
>> + HFI_PAYLOAD_U32,
>> + &hfi_value, sizeof(u32));
>> +}
>> +
>> int iris_set_properties(struct iris_inst *inst, u32 plane)
>> {
>> const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
>> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/
>> media/platform/qcom/iris/iris_ctrls.h
>> index 9518803577bc..5280ee00d9a0 100644
>> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
>> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
>> @@ -35,6 +35,7 @@ int iris_set_qp_range(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap
>> int iris_set_rotation(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap_id);
>> int iris_set_flip(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap_id);
>> int iris_set_ir_period(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap_id);
>> +int iris_set_slice_count(struct iris_inst *inst, enum
>> platform_inst_fw_cap_type cap_id);
>> int iris_set_properties(struct iris_inst *inst, u32 plane);
>> #endif
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> index cecf771c55dd..8a27f246e114 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> @@ -71,6 +71,8 @@ enum hfi_rate_control {
>> #define HFI_PROP_MIN_QP_PACKED 0x0300012f
>> #define HFI_PROP_MAX_QP_PACKED 0x03000130
>> #define HFI_PROP_IR_RANDOM_PERIOD 0x03000131
>> +#define HFI_PROP_MULTI_SLICE_MB_COUNT 0x03000132
>> +#define HFI_PROP_MULTI_SLICE_BYTES_COUNT 0x03000133
>> #define HFI_PROP_TOTAL_BITRATE 0x0300013b
>> #define HFI_PROP_MAX_GOP_FRAMES 0x03000146
>> #define HFI_PROP_MAX_B_FRAMES 0x03000147
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> index 5a489917580e..05962d8fbb25 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> @@ -159,6 +159,9 @@ enum platform_inst_fw_cap_type {
>> VFLIP,
>> IR_TYPE,
>> IR_PERIOD,
>> + SLICE_MODE,
>> + SLICE_MAX_BYTES,
>> + SLICE_MAX_MB,
>> INST_FW_CAP_MAX,
>> };
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/
>> drivers/media/platform/qcom/iris/iris_platform_gen2.c
>> index 5da90d47f9c6..191154a8ab8d 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
>> @@ -18,6 +18,8 @@
>> #define VIDEO_ARCH_LX 1
>> #define BITRATE_MAX 245000000
>> +#define MAX_SLICE_MB_SIZE \
>> + (((4096 + 15) >> 4) * ((2304 + 15) >> 4))
>
> Why is 2304 inconsistent with "MAX_MB_SLICE_HEIGHT 2160" ?
>
> Regards,
> Vikash
>
Hi Vikash, thanks for pointing out. I have fixed it in v2 posting.
Regards,
Sachin
prev parent reply other threads:[~2026-07-17 8:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-28 7:14 Sachin Kumar Garg
2026-06-26 12:28 ` Vikash Garodia
2026-07-17 8:21 ` Sachin Kumar Garg [this message]
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=4f7bc381-364e-40a2-b627-9388982fcf80@oss.qualcomm.com \
--to=sachin.garg@oss.qualcomm.com \
--cc=abhinav.kumar@linux.dev \
--cc=bod@kernel.org \
--cc=dikshita.agarwal@oss.qualcomm.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=vikash.garodia@oss.qualcomm.com \
/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