* [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder
2025-11-27 7:44 [PATCH 0/4] media: qcom: iris: encoder feature enhancements batch2 Wangao Wang
@ 2025-11-27 7:44 ` Wangao Wang
2025-11-27 10:35 ` Bryan O'Donoghue
2025-12-03 4:28 ` Dikshita Agarwal
2025-11-27 7:44 ` [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder Wangao Wang
` (2 subsequent siblings)
3 siblings, 2 replies; 17+ messages in thread
From: Wangao Wang @ 2025-11-27 7:44 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, Wangao Wang, linux-media,
linux-arm-msm, linux-kernel
Add support for intra refresh configuration on gen1 encoder by enabling
V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD and
V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE controls.
Key changes:
Added intra refresh capability for gen1 encoder.
Implemented handler for intra refresh period and type.
Defined HFI property and structure for gen1.
Renamed iris_set_ir_period_gen2() for gen2 to keep implementation separate.
Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 36 +++++++++++++++++++++-
drivers/media/platform/qcom/iris/iris_ctrls.h | 3 +-
.../platform/qcom/iris/iris_hfi_gen1_command.c | 8 +++++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 13 ++++++++
.../media/platform/qcom/iris/iris_platform_gen1.c | 19 ++++++++++++
.../media/platform/qcom/iris/iris_platform_gen2.c | 2 +-
6 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 1910aa31a9b9218e9423f2916aa40b85185f0dfb..cdf38c285b9133f20bdb9bc3dd0f5e916d3ed7f8 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -962,7 +962,41 @@ int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
&hfi_val, sizeof(u32));
}
-int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+int iris_set_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ struct v4l2_pix_format_mplane *fmt = &inst->fmt_dst->fmt.pix_mp;
+ u32 ir_period = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_intra_refresh hfi_val;
+
+ if (!ir_period)
+ return -EINVAL;
+
+ if (inst->fw_caps[IR_TYPE].value ==
+ V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
+ hfi_val.mode = HFI_INTRA_REFRESH_RANDOM;
+ } else if (inst->fw_caps[IR_TYPE].value ==
+ V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
+ hfi_val.mode = HFI_INTRA_REFRESH_CYCLIC;
+ } else {
+ return -EINVAL;
+ }
+
+ hfi_val.mbs = fmt->width * fmt->height;
+ hfi_val.mbs /= 16 * 16;
+ if (hfi_val.mbs % ir_period)
+ hfi_val.mbs++;
+ hfi_val.mbs /= ir_period;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_STRUCTURE,
+ &hfi_val, sizeof(hfi_val));
+}
+
+int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
struct vb2_queue *q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
index 9518803577bc39f5c1339a49878dd0c3e8f510ad..a0d5338bdc910bd30407132e8b700c333ad74e4c 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -34,7 +34,8 @@ int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
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_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_ir_period_gen2(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 52da7ef7bab08fb1cb2ac804ccc6e3c7f9677890..4d9632ba86bc8f629cee6d726eb44efcdeba2475 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -685,6 +685,14 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
packet->shdr.hdr.size += sizeof(u32) + sizeof(*plane_actual_info);
break;
}
+ case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: {
+ struct hfi_intra_refresh *in = pdata, *intra_refresh = prop_data;
+
+ intra_refresh->mode = in->mode;
+ intra_refresh->mbs = in->mbs;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_refresh);
+ break;
+ }
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 42226ccee3d9b9eb5f793c3be127acd8afad2138..04c79ee0463d7f32a2042044fe4564718cc01561 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -139,6 +139,14 @@
#define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL 0x2005003
#define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL 0x2005004
#define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2 0x2005009
+
+#define HFI_INTRA_REFRESH_NONE 0x1
+#define HFI_INTRA_REFRESH_CYCLIC 0x2
+#define HFI_INTRA_REFRESH_ADAPTIVE 0x3
+#define HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE 0x4
+#define HFI_INTRA_REFRESH_RANDOM 0x5
+
+#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH 0x200500d
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
@@ -447,6 +455,11 @@ struct hfi_framerate {
u32 framerate;
};
+struct hfi_intra_refresh {
+ u32 mode;
+ u32 mbs;
+};
+
struct hfi_event_data {
u32 error;
u32 height;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
index 34cbeb8f52e248b6aec3e0ee911e14d50df07cce..e7645bd60eb46785e0110a34f3257f7c37bbfca5 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
@@ -230,6 +230,25 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.flags = CAP_FLAG_OUTPUT_PORT,
.set = iris_set_qp_range,
},
+ {
+ .cap_id = IR_TYPE,
+ .min = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+ .max = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC,
+ .step_or_mask = BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) |
+ BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC),
+ .value = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = IR_PERIOD,
+ .min = 0,
+ .max = INT_MAX,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_ir_period_gen1,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8250 = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index a2025d32b3235aaff25793ba77db143000e54bae..b3425dcea22ceadbd56021e5859a24134100d5df 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -635,7 +635,7 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
.value = 0,
.flags = CAP_FLAG_OUTPUT_PORT |
CAP_FLAG_DYNAMIC_ALLOWED,
- .set = iris_set_ir_period,
+ .set = iris_set_ir_period_gen2,
},
};
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder
2025-11-27 7:44 ` [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder Wangao Wang
@ 2025-11-27 10:35 ` Bryan O'Donoghue
2025-12-02 6:35 ` Wangao Wang
2025-12-03 4:28 ` Dikshita Agarwal
1 sibling, 1 reply; 17+ messages in thread
From: Bryan O'Donoghue @ 2025-11-27 10:35 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 27/11/2025 07:44, Wangao Wang wrote:
> + hfi_val.mbs = fmt->width * fmt->height;
> + hfi_val.mbs /= 16 * 16;
256
But why ? Also why express it as 16 * 16 ?
> + if (hfi_val.mbs % ir_period)
> + hfi_val.mbs++;
> + hfi_val.mbs /= ir_period;
This code deserves some commentary.
---
bod
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder
2025-11-27 10:35 ` Bryan O'Donoghue
@ 2025-12-02 6:35 ` Wangao Wang
0 siblings, 0 replies; 17+ messages in thread
From: Wangao Wang @ 2025-12-02 6:35 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab
Cc: wangao.wang, quic_qiweil, Renjiang Han, linux-media,
linux-arm-msm, linux-kernel
On 2025/11/27 18:35, Bryan O'Donoghue wrote:
> On 27/11/2025 07:44, Wangao Wang wrote:
>> + hfi_val.mbs = fmt->width * fmt->height;
>> + hfi_val.mbs /= 16 * 16;
>
> 256
>
> But why ? Also why express it as 16 * 16 ?
>
>> + if (hfi_val.mbs % ir_period)
>> + hfi_val.mbs++;
>> + hfi_val.mbs /= ir_period;
>
> This code deserves some commentary.
>
> ---
> bod
16 * 16 is the size of a macroblock.
Here, we first calculate the total number of macroblocks in one frame,
then determine the number of macroblocks that need intra refresh in each
frame based on the ir_period. All macroblocks must be refreshed within a
single ir_period.
However, there is an issue: the macroblock sizes for AVC and HEVC are
different. I will address this in a later patch and add comments
accordingly.
--
Best Regards,
Wangao
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder
2025-11-27 7:44 ` [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder Wangao Wang
2025-11-27 10:35 ` Bryan O'Donoghue
@ 2025-12-03 4:28 ` Dikshita Agarwal
2025-12-04 2:21 ` Wangao Wang
1 sibling, 1 reply; 17+ messages in thread
From: Dikshita Agarwal @ 2025-12-03 4:28 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Abhinav Kumar, Bryan O'Donoghue,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 11/27/2025 1:14 PM, Wangao Wang wrote:
> Add support for intra refresh configuration on gen1 encoder by enabling
> V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD and
> V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE controls.
>
> Key changes:
> Added intra refresh capability for gen1 encoder.
> Implemented handler for intra refresh period and type.
> Defined HFI property and structure for gen1.
> Renamed iris_set_ir_period_gen2() for gen2 to keep implementation separate.
No need to explain the code in commit text.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 36 +++++++++++++++++++++-
> drivers/media/platform/qcom/iris/iris_ctrls.h | 3 +-
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 8 +++++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 13 ++++++++
> .../media/platform/qcom/iris/iris_platform_gen1.c | 19 ++++++++++++
> .../media/platform/qcom/iris/iris_platform_gen2.c | 2 +-
> 6 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 1910aa31a9b9218e9423f2916aa40b85185f0dfb..cdf38c285b9133f20bdb9bc3dd0f5e916d3ed7f8 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -962,7 +962,41 @@ int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> &hfi_val, sizeof(u32));
> }
>
> -int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +int iris_set_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct v4l2_pix_format_mplane *fmt = &inst->fmt_dst->fmt.pix_mp;
> + u32 ir_period = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_intra_refresh hfi_val;
> +
> + if (!ir_period)
> + return -EINVAL;
> +
> + if (inst->fw_caps[IR_TYPE].value ==
> + V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
> + hfi_val.mode = HFI_INTRA_REFRESH_RANDOM;
> + } else if (inst->fw_caps[IR_TYPE].value ==
> + V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
> + hfi_val.mode = HFI_INTRA_REFRESH_CYCLIC;
> + } else {
> + return -EINVAL;
> + }
> +
> + hfi_val.mbs = fmt->width * fmt->height;
> + hfi_val.mbs /= 16 * 16;
> + if (hfi_val.mbs % ir_period)
> + hfi_val.mbs++;
> + hfi_val.mbs /= ir_period;
Can we have some comment here to explain what is this calculation for?
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + &hfi_val, sizeof(hfi_val));
> +}
> +
> +int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> {
> const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> struct vb2_queue *q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
> index 9518803577bc39f5c1339a49878dd0c3e8f510ad..a0d5338bdc910bd30407132e8b700c333ad74e4c 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -34,7 +34,8 @@ int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
> int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> 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_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_ir_period_gen2(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> index 52da7ef7bab08fb1cb2ac804ccc6e3c7f9677890..4d9632ba86bc8f629cee6d726eb44efcdeba2475 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -685,6 +685,14 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
> packet->shdr.hdr.size += sizeof(u32) + sizeof(*plane_actual_info);
> break;
> }
> + case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: {
> + struct hfi_intra_refresh *in = pdata, *intra_refresh = prop_data;
> +
> + intra_refresh->mode = in->mode;
> + intra_refresh->mbs = in->mbs;
> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_refresh);
> + break;
> + }
> default:
> return -EINVAL;
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index 42226ccee3d9b9eb5f793c3be127acd8afad2138..04c79ee0463d7f32a2042044fe4564718cc01561 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -139,6 +139,14 @@
> #define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL 0x2005003
> #define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL 0x2005004
> #define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2 0x2005009
> +
> +#define HFI_INTRA_REFRESH_NONE 0x1
> +#define HFI_INTRA_REFRESH_CYCLIC 0x2
> +#define HFI_INTRA_REFRESH_ADAPTIVE 0x3
> +#define HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE 0x4
HFI_INTRA_REFRESH_ADAPTIVE and HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE are not
being used, do we need these macros here?
> +#define HFI_INTRA_REFRESH_RANDOM 0x5
> +
> +#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH 0x200500d
> #define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
> #define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
> #define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
> @@ -447,6 +455,11 @@ struct hfi_framerate {
> u32 framerate;
> };
>
> +struct hfi_intra_refresh {
> + u32 mode;
> + u32 mbs;
> +};
> +
> struct hfi_event_data {
> u32 error;
> u32 height;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> index 34cbeb8f52e248b6aec3e0ee911e14d50df07cce..e7645bd60eb46785e0110a34f3257f7c37bbfca5 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> @@ -230,6 +230,25 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> .flags = CAP_FLAG_OUTPUT_PORT,
> .set = iris_set_qp_range,
> },
> + {
> + .cap_id = IR_TYPE,
> + .min = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
> + .max = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC,
> + .step_or_mask = BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) |
> + BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC),
> + .value = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + },
> + {
> + .cap_id = IR_PERIOD,
> + .min = 0,
> + .max = INT_MAX,
is this value correct? please recheck.
Thanks,
Dikshita
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + .set = iris_set_ir_period_gen1,
> + },
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8250 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> index a2025d32b3235aaff25793ba77db143000e54bae..b3425dcea22ceadbd56021e5859a24134100d5df 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> @@ -635,7 +635,7 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
> .value = 0,
> .flags = CAP_FLAG_OUTPUT_PORT |
> CAP_FLAG_DYNAMIC_ALLOWED,
> - .set = iris_set_ir_period,
> + .set = iris_set_ir_period_gen2,
> },
> };
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder
2025-12-03 4:28 ` Dikshita Agarwal
@ 2025-12-04 2:21 ` Wangao Wang
0 siblings, 0 replies; 17+ messages in thread
From: Wangao Wang @ 2025-12-04 2:21 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab
Cc: wangao.wang, quic_qiweil, Renjiang Han, linux-media,
linux-arm-msm, linux-kernel
On 2025/12/3 12:28, Dikshita Agarwal wrote:
>> +
>> +#define HFI_INTRA_REFRESH_NONE 0x1
>> +#define HFI_INTRA_REFRESH_CYCLIC 0x2
>> +#define HFI_INTRA_REFRESH_ADAPTIVE 0x3
>> +#define HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE 0x4
>
> HFI_INTRA_REFRESH_ADAPTIVE and HFI_INTRA_REFRESH_CYCLIC_ADAPTIVE are not
> being used, do we need these macros here?
>
I referred to the Venus driver, which also defines it but does not use it.
>> + {
>> + .cap_id = IR_PERIOD,
>> + .min = 0,
>> + .max = INT_MAX,
>
> is this value correct? please recheck.
>
This value is incorrect; I will fix it in v2.
--
Best Regards,
Wangao
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder
2025-11-27 7:44 [PATCH 0/4] media: qcom: iris: encoder feature enhancements batch2 Wangao Wang
2025-11-27 7:44 ` [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder Wangao Wang
@ 2025-11-27 7:44 ` Wangao Wang
2025-11-27 10:41 ` Bryan O'Donoghue
` (2 more replies)
2025-11-27 7:44 ` [PATCH 3/4] media: qcom: iris: Add B frames " Wangao Wang
2025-11-27 7:44 ` [PATCH 4/4] media: qcom: iris: Add hierarchical coding " Wangao Wang
3 siblings, 3 replies; 17+ messages in thread
From: Wangao Wang @ 2025-11-27 7:44 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, Wangao Wang, linux-media,
linux-arm-msm, linux-kernel
Add Long-Term Reference(LTR) frame support for both gen1 and gen2
encoders by enabling the following V4L2 controls:
V4L2_CID_MPEG_VIDEO_LTR_COUNT
V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES
V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX
Key changes:
Added LTR capability IDs and V4L2 controls.
Implemented handlers for LTR count, use, and mark (gen1/gen2).
Defined new HFI properties and structures for LTR.
Updated platform capability tables and buffer size calculations.
Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 126 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_ctrls.h | 5 +
.../platform/qcom/iris/iris_hfi_gen1_command.c | 25 ++++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 24 ++++
.../platform/qcom/iris/iris_hfi_gen2_defines.h | 3 +
.../platform/qcom/iris/iris_platform_common.h | 6 +
.../media/platform/qcom/iris/iris_platform_gen1.c | 30 +++++
.../media/platform/qcom/iris/iris_platform_gen2.c | 30 +++++
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 33 ++++--
9 files changed, 270 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index cdf38c285b9133f20bdb9bc3dd0f5e916d3ed7f8..33e104142a5bb51c952550fa45e81b3bdc723ac2 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -108,6 +108,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_LTR_COUNT:
+ return LTR_COUNT;
+ case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES:
+ return USE_LTR;
+ case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
+ return MARK_LTR;
default:
return INST_FW_CAP_MAX;
}
@@ -205,6 +211,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 LTR_COUNT:
+ return V4L2_CID_MPEG_VIDEO_LTR_COUNT;
+ case USE_LTR:
+ return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
+ case MARK_LTR:
+ return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
default:
return 0;
}
@@ -1022,6 +1034,120 @@ int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ty
&ir_period, sizeof(u32));
}
+int iris_set_ltr_count_gen1(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 ltr_count = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_ltr_mode ltr_mode;
+
+ if (!ltr_count)
+ return -EINVAL;
+
+ ltr_mode.count = ltr_count;
+ ltr_mode.mode = HFI_LTR_MODE_MANUAL;
+ ltr_mode.trust_mode = 1;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_STRUCTURE,
+ <r_mode, sizeof(ltr_mode));
+}
+
+int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+ struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+ u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_ltr_use ltr_use;
+
+ if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
+ return -EINVAL;
+
+ if (!ltr_count)
+ return -EINVAL;
+
+ ltr_use.ref_ltr = inst->fw_caps[cap_id].value;
+ ltr_use.use_constrnt = true;
+ ltr_use.frames = 0;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_STRUCTURE,
+ <r_use, sizeof(ltr_use));
+}
+
+int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+ struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+ u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_ltr_mark ltr_mark;
+
+ if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
+ return -EINVAL;
+
+ if (!ltr_count)
+ return -EINVAL;
+
+ ltr_mark.mark_frame = inst->fw_caps[cap_id].value;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_STRUCTURE,
+ <r_mark, sizeof(ltr_mark));
+}
+
+int iris_set_ltr_count_gen2(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 ltr_count = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+
+ if (!ltr_count)
+ return -EINVAL;
+
+ if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
+ inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
+ inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
+ 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,
+ <r_count, sizeof(u32));
+}
+
+int iris_set_use_and_mark_ltr(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 ltr_count = inst->fw_caps[LTR_COUNT].value;
+ u32 hfi_val = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+
+ if (!ltr_count || hfi_val == INVALID_DEFAULT_MARK_OR_USE_LTR)
+ return -EINVAL;
+
+ if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
+ inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
+ inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
+ 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_val, 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 a0d5338bdc910bd30407132e8b700c333ad74e4c..996c83fdc6f492dc252771129fc1d62e8b7a7e07 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -36,6 +36,11 @@ int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_ltr_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_ltr_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_use_and_mark_ltr(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 4d9632ba86bc8f629cee6d726eb44efcdeba2475..139e7a9321d30d3e348671f99b0fa81afed4827e 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -693,6 +693,31 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_refresh);
break;
}
+ case HFI_PROPERTY_PARAM_VENC_LTRMODE: {
+ struct hfi_ltr_mode *in = pdata, *ltr_mode = prop_data;
+
+ ltr_mode->mode = in->mode;
+ ltr_mode->count = in->count;
+ ltr_mode->trust_mode = in->trust_mode;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mode);
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_VENC_USELTRFRAME: {
+ struct hfi_ltr_use *in = pdata, *ltr_use = prop_data;
+
+ ltr_use->frames = in->frames;
+ ltr_use->ref_ltr = in->ref_ltr;
+ ltr_use->use_constrnt = in->use_constrnt;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_use);
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME: {
+ struct hfi_ltr_mark *in = pdata, *ltr_mark = prop_data;
+
+ ltr_mark->mark_frame = in->mark_frame;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
+ break;
+ }
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 04c79ee0463d7f32a2042044fe4564718cc01561..34249fc0d047918c2463517b8303e30df3666b97 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -147,8 +147,16 @@
#define HFI_INTRA_REFRESH_RANDOM 0x5
#define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH 0x200500d
+
+#define HFI_LTR_MODE_DISABLE 0x0
+#define HFI_LTR_MODE_MANUAL 0x1
+#define HFI_LTR_MODE_PERIODIC 0x2
+
+#define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
+#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
+#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
struct hfi_pkt_hdr {
@@ -460,6 +468,22 @@ struct hfi_intra_refresh {
u32 mbs;
};
+struct hfi_ltr_mode {
+ u32 mode;
+ u32 count;
+ u32 trust_mode;
+};
+
+struct hfi_ltr_use {
+ u32 ref_ltr;
+ u32 use_constrnt;
+ u32 frames;
+};
+
+struct hfi_ltr_mark {
+ u32 mark_frame;
+};
+
struct hfi_event_data {
u32 error;
u32 height;
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 f6a214a6815420f299be70f80732943d02168f0c..2b8c87c25a066ead30bb1b134bdc3fe1e84e8f05 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,9 @@ 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_LTR_COUNT 0x03000134
+#define HFI_PROP_LTR_MARK 0x03000135
+#define HFI_PROP_LTR_USE 0x03000136
#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 dd0a4210a2647ff4dadf8d67b71c6f4a22deb548..c48dfb6d47734fadd4f2e4123c93560f55355b86 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -29,6 +29,9 @@ struct iris_inst;
#define MAX_QP_HEVC 63
#define DEFAULT_QP 20
#define BITRATE_DEFAULT 20000000
+#define INVALID_DEFAULT_MARK_OR_USE_LTR -1
+#define MAX_LTR_FRAME_COUNT_GEN1 4
+#define MAX_LTR_FRAME_COUNT_GEN2 2
enum stage_type {
STAGE_1 = 1,
@@ -148,6 +151,9 @@ enum platform_inst_fw_cap_type {
VFLIP,
IR_TYPE,
IR_PERIOD,
+ LTR_COUNT,
+ USE_LTR,
+ MARK_LTR,
INST_FW_CAP_MAX,
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
index e7645bd60eb46785e0110a34f3257f7c37bbfca5..13cee5f72a443b85136d30b41b589aeb0db8eb9a 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
@@ -249,6 +249,36 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.flags = CAP_FLAG_OUTPUT_PORT,
.set = iris_set_ir_period_gen1,
},
+ {
+ .cap_id = LTR_COUNT,
+ .min = 0,
+ .max = MAX_LTR_FRAME_COUNT_GEN1,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_LTRMODE,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_ltr_count_gen1,
+ },
+ {
+ .cap_id = USE_LTR,
+ .min = 0,
+ .max = ((1 << MAX_LTR_FRAME_COUNT_GEN1) - 1),
+ .step_or_mask = 0,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_USELTRFRAME,
+ .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_use_ltr,
+ },
+ {
+ .cap_id = MARK_LTR,
+ .min = 0,
+ .max = (MAX_LTR_FRAME_COUNT_GEN1 - 1),
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME,
+ .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_mark_ltr,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8250 = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index b3425dcea22ceadbd56021e5859a24134100d5df..6ae34312f50d4a3709ca20b3aadcfee12338a2f7 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -637,6 +637,36 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_ir_period_gen2,
},
+ {
+ .cap_id = LTR_COUNT,
+ .min = 0,
+ .max = MAX_LTR_FRAME_COUNT_GEN2,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROP_LTR_COUNT,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_ltr_count_gen2,
+ },
+ {
+ .cap_id = USE_LTR,
+ .min = 0,
+ .max = ((1 << MAX_LTR_FRAME_COUNT_GEN2) - 1),
+ .step_or_mask = 0,
+ .value = 0,
+ .hfi_id = HFI_PROP_LTR_USE,
+ .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_use_and_mark_ltr,
+ },
+ {
+ .cap_id = MARK_LTR,
+ .min = INVALID_DEFAULT_MARK_OR_USE_LTR,
+ .max = (MAX_LTR_FRAME_COUNT_GEN2 - 1),
+ .step_or_mask = 1,
+ .value = INVALID_DEFAULT_MARK_OR_USE_LTR,
+ .hfi_id = HFI_PROP_LTR_MARK,
+ .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_use_and_mark_ltr,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8550 = {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index 1e54ace966c74956208d88f06837b97b1fd48e17..8139fefe40fe179ff7862bbca879ce94c71c1f89 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -668,6 +668,19 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
num_vpp_pipes, inst->hfi_rc_type);
}
+static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
+{
+ u32 num_ref = 1;
+ u32 ltr_count;
+
+ ltr_count = inst->fw_caps[LTR_COUNT].value;
+
+ if (ltr_count)
+ num_ref = num_ref + ltr_count;
+
+ return num_ref + 1;
+}
+
static inline
u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
u32 num_recon, u32 standard)
@@ -693,17 +706,14 @@ static u32 iris_vpu_enc_comv_size(struct iris_inst *inst)
{
u32 height = iris_vpu_enc_get_bitstream_height(inst);
u32 width = iris_vpu_enc_get_bitstream_width(inst);
- u32 num_recon = 1;
- u32 lcu_size = 16;
+ u32 num_recon = hfi_buffer_get_recon_count(inst);
+ u32 standard, lcu_size;
- if (inst->codec == V4L2_PIX_FMT_HEVC) {
- lcu_size = 32;
- return hfi_buffer_comv_enc(width, height, lcu_size,
- num_recon + 1, HFI_CODEC_ENCODE_HEVC);
- }
+ standard = (inst->codec == V4L2_PIX_FMT_HEVC) ?
+ HFI_CODEC_ENCODE_HEVC : HFI_CODEC_ENCODE_AVC;
+ lcu_size = (inst->codec == V4L2_PIX_FMT_HEVC) ? 32 : 16;
- return hfi_buffer_comv_enc(width, height, lcu_size,
- num_recon + 1, HFI_CODEC_ENCODE_AVC);
+ return hfi_buffer_comv_enc(width, height, lcu_size, num_recon, standard);
}
static inline
@@ -1402,10 +1412,9 @@ static u32 iris_vpu_enc_scratch2_size(struct iris_inst *inst)
{
u32 frame_height = iris_vpu_enc_get_bitstream_height(inst);
u32 frame_width = iris_vpu_enc_get_bitstream_width(inst);
- u32 num_ref = 1;
+ u32 num_ref = hfi_buffer_get_recon_count(inst);
- return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref,
- false);
+ return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref, false);
}
static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst)
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder
2025-11-27 7:44 ` [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder Wangao Wang
@ 2025-11-27 10:41 ` Bryan O'Donoghue
2025-12-02 6:38 ` Wangao Wang
2025-12-03 6:29 ` Dikshita Agarwal
2025-12-03 6:56 ` Dikshita Agarwal
2 siblings, 1 reply; 17+ messages in thread
From: Bryan O'Donoghue @ 2025-11-27 10:41 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 27/11/2025 07:44, Wangao Wang wrote:
> Add Long-Term Reference(LTR) frame support for both gen1 and gen2
> encoders by enabling the following V4L2 controls:
> V4L2_CID_MPEG_VIDEO_LTR_COUNT
> V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES
> V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX
>
> Key changes:
> Added LTR capability IDs and V4L2 controls.
> Implemented handlers for LTR count, use, and mark (gen1/gen2).
> Defined new HFI properties and structures for LTR.
> Updated platform capability tables and buffer size calculations.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 126 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 5 +
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 25 ++++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 24 ++++
> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 3 +
> .../platform/qcom/iris/iris_platform_common.h | 6 +
> .../media/platform/qcom/iris/iris_platform_gen1.c | 30 +++++
> .../media/platform/qcom/iris/iris_platform_gen2.c | 30 +++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 33 ++++--
> 9 files changed, 270 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index cdf38c285b9133f20bdb9bc3dd0f5e916d3ed7f8..33e104142a5bb51c952550fa45e81b3bdc723ac2 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -108,6 +108,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_LTR_COUNT:
> + return LTR_COUNT;
> + case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES:
> + return USE_LTR;
> + case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
> + return MARK_LTR;
> default:
> return INST_FW_CAP_MAX;
> }
> @@ -205,6 +211,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 LTR_COUNT:
> + return V4L2_CID_MPEG_VIDEO_LTR_COUNT;
> + case USE_LTR:
> + return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
> + case MARK_LTR:
> + return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
> default:
> return 0;
> }
> @@ -1022,6 +1034,120 @@ int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ty
> &ir_period, sizeof(u32));
> }
>
> +int iris_set_ltr_count_gen1(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 ltr_count = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_mode ltr_mode;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + ltr_mode.count = ltr_count;
> + ltr_mode.mode = HFI_LTR_MODE_MANUAL;
> + ltr_mode.trust_mode = 1;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_mode, sizeof(ltr_mode));
> +}
> +
> +int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> + u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_use ltr_use;
> +
> + if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
> + return -EINVAL;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + ltr_use.ref_ltr = inst->fw_caps[cap_id].value;
> + ltr_use.use_constrnt = true;
> + ltr_use.frames = 0;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_use, sizeof(ltr_use));
> +}
> +
> +int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> + u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_mark ltr_mark;
> +
> + if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
> + return -EINVAL;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + ltr_mark.mark_frame = inst->fw_caps[cap_id].value;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_mark, sizeof(ltr_mark));
> +}
> +
> +int iris_set_ltr_count_gen2(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 ltr_count = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
> + 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,
> + <r_count, sizeof(u32));
> +}
> +
> +int iris_set_use_and_mark_ltr(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 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_val = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> +
> + if (!ltr_count || hfi_val == INVALID_DEFAULT_MARK_OR_USE_LTR)
> + return -EINVAL;
> +
> + if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
> + 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_val, 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 a0d5338bdc910bd30407132e8b700c333ad74e4c..996c83fdc6f492dc252771129fc1d62e8b7a7e07 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -36,6 +36,11 @@ int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
> int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_ir_period_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_ltr_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_ltr_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_use_and_mark_ltr(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> index 4d9632ba86bc8f629cee6d726eb44efcdeba2475..139e7a9321d30d3e348671f99b0fa81afed4827e 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -693,6 +693,31 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
> packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_refresh);
> break;
> }
> + case HFI_PROPERTY_PARAM_VENC_LTRMODE: {
> + struct hfi_ltr_mode *in = pdata, *ltr_mode = prop_data;
> +
> + ltr_mode->mode = in->mode;
> + ltr_mode->count = in->count;
> + ltr_mode->trust_mode = in->trust_mode;
> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mode);
This looks like an unconditional pattern in this code
packet->shdr.hdr.size += sizeof(u32) for each one of the switch cases.
Could you at least add a patch to the end of this series to tidy this up
- either always incrmenting by sizeof(u32) before the swich - or making
a macro or static inline that packs the header appropriately.
Also what is the sizeof(u32) representative of ? "Some field in the
header" - get that but right now its just a literal unnamed dword.
> + break;
> + }
> + case HFI_PROPERTY_CONFIG_VENC_USELTRFRAME: {
> + struct hfi_ltr_use *in = pdata, *ltr_use = prop_data;
> +
> + ltr_use->frames = in->frames;
> + ltr_use->ref_ltr = in->ref_ltr;
> + ltr_use->use_constrnt = in->use_constrnt;
> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_use);
> + break;
> + }
> + case HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME: {
> + struct hfi_ltr_mark *in = pdata, *ltr_mark = prop_data;
> +
> + ltr_mark->mark_frame = in->mark_frame;
> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
> + break;
> + }
> default:
> return -EINVAL;
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index 04c79ee0463d7f32a2042044fe4564718cc01561..34249fc0d047918c2463517b8303e30df3666b97 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -147,8 +147,16 @@
> #define HFI_INTRA_REFRESH_RANDOM 0x5
>
> #define HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH 0x200500d
> +
> +#define HFI_LTR_MODE_DISABLE 0x0
> +#define HFI_LTR_MODE_MANUAL 0x1
> +#define HFI_LTR_MODE_PERIODIC 0x2
> +
> +#define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
> #define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
> #define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
> +#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
> +#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
> #define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
>
> struct hfi_pkt_hdr {
> @@ -460,6 +468,22 @@ struct hfi_intra_refresh {
> u32 mbs;
> };
>
> +struct hfi_ltr_mode {
> + u32 mode;
> + u32 count;
> + u32 trust_mode;
> +};
> +
> +struct hfi_ltr_use {
> + u32 ref_ltr;
> + u32 use_constrnt;
> + u32 frames;
> +};
> +
> +struct hfi_ltr_mark {
> + u32 mark_frame;
> +};
> +
> struct hfi_event_data {
> u32 error;
> u32 height;
> 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 f6a214a6815420f299be70f80732943d02168f0c..2b8c87c25a066ead30bb1b134bdc3fe1e84e8f05 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,9 @@ 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_LTR_COUNT 0x03000134
> +#define HFI_PROP_LTR_MARK 0x03000135
> +#define HFI_PROP_LTR_USE 0x03000136
> #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 dd0a4210a2647ff4dadf8d67b71c6f4a22deb548..c48dfb6d47734fadd4f2e4123c93560f55355b86 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -29,6 +29,9 @@ struct iris_inst;
> #define MAX_QP_HEVC 63
> #define DEFAULT_QP 20
> #define BITRATE_DEFAULT 20000000
> +#define INVALID_DEFAULT_MARK_OR_USE_LTR -1
> +#define MAX_LTR_FRAME_COUNT_GEN1 4
> +#define MAX_LTR_FRAME_COUNT_GEN2 2
>
> enum stage_type {
> STAGE_1 = 1,
> @@ -148,6 +151,9 @@ enum platform_inst_fw_cap_type {
> VFLIP,
> IR_TYPE,
> IR_PERIOD,
> + LTR_COUNT,
> + USE_LTR,
> + MARK_LTR,
> INST_FW_CAP_MAX,
> };
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> index e7645bd60eb46785e0110a34f3257f7c37bbfca5..13cee5f72a443b85136d30b41b589aeb0db8eb9a 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> @@ -249,6 +249,36 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> .flags = CAP_FLAG_OUTPUT_PORT,
> .set = iris_set_ir_period_gen1,
> },
> + {
> + .cap_id = LTR_COUNT,
> + .min = 0,
> + .max = MAX_LTR_FRAME_COUNT_GEN1,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_PARAM_VENC_LTRMODE,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + .set = iris_set_ltr_count_gen1,
> + },
> + {
> + .cap_id = USE_LTR,
> + .min = 0,
> + .max = ((1 << MAX_LTR_FRAME_COUNT_GEN1) - 1),
> + .step_or_mask = 0,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_CONFIG_VENC_USELTRFRAME,
> + .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + .set = iris_set_use_ltr,
> + },
> + {
> + .cap_id = MARK_LTR,
> + .min = 0,
> + .max = (MAX_LTR_FRAME_COUNT_GEN1 - 1),
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME,
> + .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + .set = iris_set_mark_ltr,
> + },
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8250 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> index b3425dcea22ceadbd56021e5859a24134100d5df..6ae34312f50d4a3709ca20b3aadcfee12338a2f7 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> @@ -637,6 +637,36 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
> CAP_FLAG_DYNAMIC_ALLOWED,
> .set = iris_set_ir_period_gen2,
> },
> + {
> + .cap_id = LTR_COUNT,
> + .min = 0,
> + .max = MAX_LTR_FRAME_COUNT_GEN2,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROP_LTR_COUNT,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + .set = iris_set_ltr_count_gen2,
> + },
> + {
> + .cap_id = USE_LTR,
> + .min = 0,
> + .max = ((1 << MAX_LTR_FRAME_COUNT_GEN2) - 1),
> + .step_or_mask = 0,
> + .value = 0,
> + .hfi_id = HFI_PROP_LTR_USE,
> + .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + .set = iris_set_use_and_mark_ltr,
> + },
> + {
> + .cap_id = MARK_LTR,
> + .min = INVALID_DEFAULT_MARK_OR_USE_LTR,
> + .max = (MAX_LTR_FRAME_COUNT_GEN2 - 1),
> + .step_or_mask = 1,
> + .value = INVALID_DEFAULT_MARK_OR_USE_LTR,
> + .hfi_id = HFI_PROP_LTR_MARK,
> + .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + .set = iris_set_use_and_mark_ltr,
> + },
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8550 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index 1e54ace966c74956208d88f06837b97b1fd48e17..8139fefe40fe179ff7862bbca879ce94c71c1f89 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -668,6 +668,19 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
> num_vpp_pipes, inst->hfi_rc_type);
> }
>
> +static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
> +{
> + u32 num_ref = 1;
> + u32 ltr_count;
> +
> + ltr_count = inst->fw_caps[LTR_COUNT].value;
> +
> + if (ltr_count)
> + num_ref = num_ref + ltr_count;
> +
> + return num_ref + 1;
> +}
> +
> static inline
> u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
> u32 num_recon, u32 standard)
> @@ -693,17 +706,14 @@ static u32 iris_vpu_enc_comv_size(struct iris_inst *inst)
> {
> u32 height = iris_vpu_enc_get_bitstream_height(inst);
> u32 width = iris_vpu_enc_get_bitstream_width(inst);
> - u32 num_recon = 1;
> - u32 lcu_size = 16;
> + u32 num_recon = hfi_buffer_get_recon_count(inst);
> + u32 standard, lcu_size;
>
> - if (inst->codec == V4L2_PIX_FMT_HEVC) {
> - lcu_size = 32;
> - return hfi_buffer_comv_enc(width, height, lcu_size,
> - num_recon + 1, HFI_CODEC_ENCODE_HEVC);
> - }
> + standard = (inst->codec == V4L2_PIX_FMT_HEVC) ?
> + HFI_CODEC_ENCODE_HEVC : HFI_CODEC_ENCODE_AVC;
> + lcu_size = (inst->codec == V4L2_PIX_FMT_HEVC) ? 32 : 16;
>
> - return hfi_buffer_comv_enc(width, height, lcu_size,
> - num_recon + 1, HFI_CODEC_ENCODE_AVC);
> + return hfi_buffer_comv_enc(width, height, lcu_size, num_recon, standard);
> }
>
> static inline
> @@ -1402,10 +1412,9 @@ static u32 iris_vpu_enc_scratch2_size(struct iris_inst *inst)
> {
> u32 frame_height = iris_vpu_enc_get_bitstream_height(inst);
> u32 frame_width = iris_vpu_enc_get_bitstream_width(inst);
> - u32 num_ref = 1;
> + u32 num_ref = hfi_buffer_get_recon_count(inst);
>
> - return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref,
> - false);
> + return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref, false);
> }
>
> static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst)
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder
2025-11-27 10:41 ` Bryan O'Donoghue
@ 2025-12-02 6:38 ` Wangao Wang
0 siblings, 0 replies; 17+ messages in thread
From: Wangao Wang @ 2025-12-02 6:38 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab
Cc: wangao.wang, quic_qiweil, Renjiang Han, linux-media,
linux-arm-msm, linux-kernel
On 2025/11/27 18:41, Bryan O'Donoghue wrote:
>> @@ -693,6 +693,31 @@ iris_hfi_gen1_packet_session_set_property(struct
>> hfi_session_set_property_pkt *p
>> packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_refresh);
>> break;
>> }
>> + case HFI_PROPERTY_PARAM_VENC_LTRMODE: {
>> + struct hfi_ltr_mode *in = pdata, *ltr_mode = prop_data;
>> +
>> + ltr_mode->mode = in->mode;
>> + ltr_mode->count = in->count;
>> + ltr_mode->trust_mode = in->trust_mode;
>> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mode);
>
> This looks like an unconditional pattern in this code
>
> packet->shdr.hdr.size += sizeof(u32) for each one of the switch cases.
>
> Could you at least add a patch to the end of this series to tidy this up
> - either always incrmenting by sizeof(u32) before the swich - or making
> a macro or static inline that packs the header appropriately.
>
> Also what is the sizeof(u32) representative of ? "Some field in the
> header" - get that but right now its just a literal unnamed dword.
>
A patch will be added in v2 to optimize the code structure here.
--
Best Regards,
Wangao
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder
2025-11-27 7:44 ` [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder Wangao Wang
2025-11-27 10:41 ` Bryan O'Donoghue
@ 2025-12-03 6:29 ` Dikshita Agarwal
2025-12-03 6:56 ` Dikshita Agarwal
2 siblings, 0 replies; 17+ messages in thread
From: Dikshita Agarwal @ 2025-12-03 6:29 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Abhinav Kumar, Bryan O'Donoghue,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 11/27/2025 1:14 PM, Wangao Wang wrote:
> Add Long-Term Reference(LTR) frame support for both gen1 and gen2
> encoders by enabling the following V4L2 controls:
> V4L2_CID_MPEG_VIDEO_LTR_COUNT
> V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES
> V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX
>
> Key changes:
> Added LTR capability IDs and V4L2 controls.
> Implemented handlers for LTR count, use, and mark (gen1/gen2).
> Defined new HFI properties and structures for LTR.
> Updated platform capability tables and buffer size calculations.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 126 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 5 +
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 25 ++++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 24 ++++
> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 3 +
> .../platform/qcom/iris/iris_platform_common.h | 6 +
> .../media/platform/qcom/iris/iris_platform_gen1.c | 30 +++++
> .../media/platform/qcom/iris/iris_platform_gen2.c | 30 +++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 33 ++++--
> 9 files changed, 270 insertions(+), 12 deletions(-)
>
> static struct platform_inst_caps platform_inst_cap_sm8550 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index 1e54ace966c74956208d88f06837b97b1fd48e17..8139fefe40fe179ff7862bbca879ce94c71c1f89 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -668,6 +668,19 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
> num_vpp_pipes, inst->hfi_rc_type);
> }
>
> +static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
> +{
> + u32 num_ref = 1;
> + u32 ltr_count;
> +
> + ltr_count = inst->fw_caps[LTR_COUNT].value;
> +
> + if (ltr_count)
> + num_ref = num_ref + ltr_count;
> +
> + return num_ref + 1;
> +}
Here you are always returning num_ref+1 which might break
iris_vpu_enc_scratch2_size calculation since you are using this as common
API for calculating ref buffers. Please recheck.
> +
> static inline
> u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
> u32 num_recon, u32 standard)
> @@ -693,17 +706,14 @@ static u32 iris_vpu_enc_comv_size(struct iris_inst *inst)
> {
> u32 height = iris_vpu_enc_get_bitstream_height(inst);
> u32 width = iris_vpu_enc_get_bitstream_width(inst);
> - u32 num_recon = 1;
> - u32 lcu_size = 16;
> + u32 num_recon = hfi_buffer_get_recon_count(inst);
> + u32 standard, lcu_size;
>
> - if (inst->codec == V4L2_PIX_FMT_HEVC) {
> - lcu_size = 32;
> - return hfi_buffer_comv_enc(width, height, lcu_size,
> - num_recon + 1, HFI_CODEC_ENCODE_HEVC);
> - }
> + standard = (inst->codec == V4L2_PIX_FMT_HEVC) ?
> + HFI_CODEC_ENCODE_HEVC : HFI_CODEC_ENCODE_AVC;
> + lcu_size = (inst->codec == V4L2_PIX_FMT_HEVC) ? 32 : 16;
these code optimization is not in the scope of this change. pls have in a
spearate patch if needed.
Thanks,
Dikshita
>
> - return hfi_buffer_comv_enc(width, height, lcu_size,
> - num_recon + 1, HFI_CODEC_ENCODE_AVC);
> + return hfi_buffer_comv_enc(width, height, lcu_size, num_recon, standard);
> }
>
> static inline
> @@ -1402,10 +1412,9 @@ static u32 iris_vpu_enc_scratch2_size(struct iris_inst *inst)
> {
> u32 frame_height = iris_vpu_enc_get_bitstream_height(inst);
> u32 frame_width = iris_vpu_enc_get_bitstream_width(inst);
> - u32 num_ref = 1;
> + u32 num_ref = hfi_buffer_get_recon_count(inst);
>
> - return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref,
> - false);
> + return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref, false);
> }
>
> static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst)
>
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder
2025-11-27 7:44 ` [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder Wangao Wang
2025-11-27 10:41 ` Bryan O'Donoghue
2025-12-03 6:29 ` Dikshita Agarwal
@ 2025-12-03 6:56 ` Dikshita Agarwal
2 siblings, 0 replies; 17+ messages in thread
From: Dikshita Agarwal @ 2025-12-03 6:56 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Abhinav Kumar, Bryan O'Donoghue,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 11/27/2025 1:14 PM, Wangao Wang wrote:
> Add Long-Term Reference(LTR) frame support for both gen1 and gen2
> encoders by enabling the following V4L2 controls:
> V4L2_CID_MPEG_VIDEO_LTR_COUNT
> V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES
> V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX
>
> Key changes:
> Added LTR capability IDs and V4L2 controls.
> Implemented handlers for LTR count, use, and mark (gen1/gen2).
> Defined new HFI properties and structures for LTR.
> Updated platform capability tables and buffer size calculations.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 126 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 5 +
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 25 ++++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 24 ++++
> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 3 +
> .../platform/qcom/iris/iris_platform_common.h | 6 +
> .../media/platform/qcom/iris/iris_platform_gen1.c | 30 +++++
> .../media/platform/qcom/iris/iris_platform_gen2.c | 30 +++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 33 ++++--
> 9 files changed, 270 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index cdf38c285b9133f20bdb9bc3dd0f5e916d3ed7f8..33e104142a5bb51c952550fa45e81b3bdc723ac2 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -108,6 +108,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_LTR_COUNT:
> + return LTR_COUNT;
> + case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES:
> + return USE_LTR;
> + case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
> + return MARK_LTR;
> default:
> return INST_FW_CAP_MAX;
> }
> @@ -205,6 +211,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 LTR_COUNT:
> + return V4L2_CID_MPEG_VIDEO_LTR_COUNT;
> + case USE_LTR:
> + return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
> + case MARK_LTR:
> + return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
> default:
> return 0;
> }
> @@ -1022,6 +1034,120 @@ int iris_set_ir_period_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ty
> &ir_period, sizeof(u32));
> }
>
> +int iris_set_ltr_count_gen1(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 ltr_count = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_mode ltr_mode;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + ltr_mode.count = ltr_count;
> + ltr_mode.mode = HFI_LTR_MODE_MANUAL;
> + ltr_mode.trust_mode = 1;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_mode, sizeof(ltr_mode));
> +}
> +
> +int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> + u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_use ltr_use;
> +
> + if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
> + return -EINVAL;
RC check not required here?
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + ltr_use.ref_ltr = inst->fw_caps[cap_id].value;
> + ltr_use.use_constrnt = true;
> + ltr_use.frames = 0;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_use, sizeof(ltr_use));
> +}
> +
> +int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> + u32 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_ltr_mark ltr_mark;
> +
> + if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq))
> + return -EINVAL;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
RC check not required here?
> + ltr_mark.mark_frame = inst->fw_caps[cap_id].value;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + <r_mark, sizeof(ltr_mark));
> +}
> +
> +int iris_set_ltr_count_gen2(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 ltr_count = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> +
> + if (!ltr_count)
> + return -EINVAL;
> +
> + if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
> + 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,
> + <r_count, sizeof(u32));
> +}
> +
> +int iris_set_use_and_mark_ltr(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 ltr_count = inst->fw_caps[LTR_COUNT].value;
> + u32 hfi_val = inst->fw_caps[cap_id].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> +
> + if (!ltr_count || hfi_val == INVALID_DEFAULT_MARK_OR_USE_LTR)
> + return -EINVAL;
> +
> + if (inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_VFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_VBR_CFR ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_CQ)
> + return -EINVAL;
> +
Streaming check is not required here?
Thanks,
Dikshita
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_U32,
> + &hfi_val, sizeof(u32));
> +}
> +
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 3/4] media: qcom: iris: Add B frames support for encoder
2025-11-27 7:44 [PATCH 0/4] media: qcom: iris: encoder feature enhancements batch2 Wangao Wang
2025-11-27 7:44 ` [PATCH 1/4] media: qcom: iris: Add intra refresh support for gen1 encoder Wangao Wang
2025-11-27 7:44 ` [PATCH 2/4] media: qcom: iris: Add Long-Term Reference support for encoder Wangao Wang
@ 2025-11-27 7:44 ` Wangao Wang
2025-11-27 10:43 ` Bryan O'Donoghue
2025-12-03 6:55 ` Dikshita Agarwal
2025-11-27 7:44 ` [PATCH 4/4] media: qcom: iris: Add hierarchical coding " Wangao Wang
3 siblings, 2 replies; 17+ messages in thread
From: Wangao Wang @ 2025-11-27 7:44 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, Wangao Wang, linux-media,
linux-arm-msm, linux-kernel
Add support for B-frame configuration on both gen1 and gen2 encoders by
enabling V4L2_CID_MPEG_VIDEO_B_FRAMES control.
Key changes:
Added capability IDs for B-frame and intra period.
Implemented handler for GOP structure with B-frames.
Defined HFI property and structure for gen1.
Updated platform tables and buffer logic for gen2.
Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 25 ++++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_ctrls.h | 1 +
.../platform/qcom/iris/iris_hfi_gen1_command.c | 8 +++++++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 6 ++++++
.../platform/qcom/iris/iris_platform_common.h | 2 ++
.../media/platform/qcom/iris/iris_platform_gen1.c | 19 +++++++++++++++-
.../media/platform/qcom/iris/iris_platform_gen2.c | 10 +++++++++
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 6 +++++-
8 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 33e104142a5bb51c952550fa45e81b3bdc723ac2..9aec8a2006e9f8e545d05e40cb68ef0ae8502f79 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -114,6 +114,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return USE_LTR;
case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
return MARK_LTR;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ return B_FRAME;
default:
return INST_FW_CAP_MAX;
}
@@ -217,6 +219,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
case MARK_LTR:
return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
+ case B_FRAME:
+ return V4L2_CID_MPEG_VIDEO_B_FRAMES;
default:
return 0;
}
@@ -1148,6 +1152,27 @@ int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_
&hfi_val, sizeof(u32));
}
+int iris_set_intra_period(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 gop_size = inst->fw_caps[GOP_SIZE].value;
+ u32 b_frame = inst->fw_caps[B_FRAME].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_intra_period intra_period;
+
+ if (!gop_size || b_frame >= gop_size)
+ return -EINVAL;
+
+ intra_period.pframes = (gop_size - 1) / (b_frame + 1);
+ intra_period.bframes = b_frame;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_STRUCTURE,
+ &intra_period, sizeof(intra_period));
+}
+
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 996c83fdc6f492dc252771129fc1d62e8b7a7e07..609258c81517b71523b682ca994786cdd020b07f 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -41,6 +41,7 @@ int iris_set_ltr_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ty
int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_intra_period(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 139e7a9321d30d3e348671f99b0fa81afed4827e..fe51eccb903be146e83a4fb2faf4b4092875dea4 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -718,6 +718,14 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
break;
}
+ case HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD: {
+ struct hfi_intra_period *in = pdata, *intra_period = prop_data;
+
+ intra_period->pframes = in->pframes;
+ intra_period->bframes = in->bframes;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_period);
+ break;
+ }
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 34249fc0d047918c2463517b8303e30df3666b97..476177add1ec860d46d85960dd09617ad347f60a 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -155,6 +155,7 @@
#define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
+#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD 0x2006003
#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
@@ -484,6 +485,11 @@ struct hfi_ltr_mark {
u32 mark_frame;
};
+struct hfi_intra_period {
+ u32 pframes;
+ u32 bframes;
+};
+
struct hfi_event_data {
u32 error;
u32 height;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index c48dfb6d47734fadd4f2e4123c93560f55355b86..34deb32eb5be0899fee779ff99b3f4b8bd91529f 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -154,6 +154,8 @@ enum platform_inst_fw_cap_type {
LTR_COUNT,
USE_LTR,
MARK_LTR,
+ B_FRAME,
+ INTRA_PERIOD,
INST_FW_CAP_MAX,
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
index 13cee5f72a443b85136d30b41b589aeb0db8eb9a..b76f0ecaa721f3469bc63b7ff4ce5fc6ea19a8e1 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
@@ -177,7 +177,6 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.max = (1 << 16) - 1,
.step_or_mask = 1,
.value = 30,
- .set = iris_set_u32
},
{
.cap_id = ENTROPY_MODE,
@@ -279,6 +278,24 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_mark_ltr,
},
+ {
+ .cap_id = B_FRAME,
+ .min = 0,
+ .max = 3,
+ .step_or_mask = 1,
+ .value = 0,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = INTRA_PERIOD,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_intra_period,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8250 = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index 6ae34312f50d4a3709ca20b3aadcfee12338a2f7..7c9a71755685d195a7adc8064523e1c33a572089 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -667,6 +667,16 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
.flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
.set = iris_set_use_and_mark_ltr,
},
+ {
+ .cap_id = B_FRAME,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROP_MAX_B_FRAMES,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_u32,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8550 = {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index 8139fefe40fe179ff7862bbca879ce94c71c1f89..4a854a4dab322eabb16a52b1cf816c18d78acc81 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -670,11 +670,15 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
{
+ u32 bframe_count, ltr_count;
u32 num_ref = 1;
- u32 ltr_count;
+ bframe_count = inst->fw_caps[B_FRAME].value;
ltr_count = inst->fw_caps[LTR_COUNT].value;
+ if (bframe_count)
+ num_ref = 2;
+
if (ltr_count)
num_ref = num_ref + ltr_count;
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 3/4] media: qcom: iris: Add B frames support for encoder
2025-11-27 7:44 ` [PATCH 3/4] media: qcom: iris: Add B frames " Wangao Wang
@ 2025-11-27 10:43 ` Bryan O'Donoghue
2025-12-02 6:46 ` Wangao Wang
2025-12-03 6:55 ` Dikshita Agarwal
1 sibling, 1 reply; 17+ messages in thread
From: Bryan O'Donoghue @ 2025-11-27 10:43 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 27/11/2025 07:44, Wangao Wang wrote:
> + intra_period.pframes = (gop_size - 1) / (b_frame + 1);
> + intra_period.bframes = b_frame;
Why do you need to set pframes when setting bframes ?
---
bod
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/4] media: qcom: iris: Add B frames support for encoder
2025-11-27 10:43 ` Bryan O'Donoghue
@ 2025-12-02 6:46 ` Wangao Wang
0 siblings, 0 replies; 17+ messages in thread
From: Wangao Wang @ 2025-12-02 6:46 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab
Cc: wangao.wang, quic_qiweil, Renjiang Han, linux-media,
linux-arm-msm, linux-kernel
On 2025/11/27 18:43, Bryan O'Donoghue wrote:
> On 27/11/2025 07:44, Wangao Wang wrote:
>> + intra_period.pframes = (gop_size - 1) / (b_frame + 1);
>> + intra_period.bframes = b_frame;
>
> Why do you need to set pframes when setting bframes ?
>
> ---
> bod
intra_period represents the length of a GOP, which includes both
P-frames and B-frames. The counts of P-frames and B-frames within a GOP
must be communicated to the firmware.
--
Best Regards,
Wangao
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/4] media: qcom: iris: Add B frames support for encoder
2025-11-27 7:44 ` [PATCH 3/4] media: qcom: iris: Add B frames " Wangao Wang
2025-11-27 10:43 ` Bryan O'Donoghue
@ 2025-12-03 6:55 ` Dikshita Agarwal
1 sibling, 0 replies; 17+ messages in thread
From: Dikshita Agarwal @ 2025-12-03 6:55 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Abhinav Kumar, Bryan O'Donoghue,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 11/27/2025 1:14 PM, Wangao Wang wrote:
> Add support for B-frame configuration on both gen1 and gen2 encoders by
> enabling V4L2_CID_MPEG_VIDEO_B_FRAMES control.
>
> Key changes:
> Added capability IDs for B-frame and intra period.
> Implemented handler for GOP structure with B-frames.
> Defined HFI property and structure for gen1.
> Updated platform tables and buffer logic for gen2.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 25 ++++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 1 +
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 8 +++++++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 6 ++++++
> .../platform/qcom/iris/iris_platform_common.h | 2 ++
> .../media/platform/qcom/iris/iris_platform_gen1.c | 19 +++++++++++++++-
> .../media/platform/qcom/iris/iris_platform_gen2.c | 10 +++++++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 6 +++++-
> 8 files changed, 75 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 33e104142a5bb51c952550fa45e81b3bdc723ac2..9aec8a2006e9f8e545d05e40cb68ef0ae8502f79 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -114,6 +114,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
> return USE_LTR;
> case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX:
> return MARK_LTR;
> + case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> + return B_FRAME;
> default:
> return INST_FW_CAP_MAX;
> }
> @@ -217,6 +219,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
> return V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES;
> case MARK_LTR:
> return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
> + case B_FRAME:
> + return V4L2_CID_MPEG_VIDEO_B_FRAMES;
> default:
> return 0;
> }
> @@ -1148,6 +1152,27 @@ int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_
> &hfi_val, sizeof(u32));
> }
>
> +int iris_set_intra_period(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 gop_size = inst->fw_caps[GOP_SIZE].value;
> + u32 b_frame = inst->fw_caps[B_FRAME].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + struct hfi_intra_period intra_period;
> +
> + if (!gop_size || b_frame >= gop_size)
> + return -EINVAL;
> +
> + intra_period.pframes = (gop_size - 1) / (b_frame + 1);
> + intra_period.bframes = b_frame;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_STRUCTURE,
> + &intra_period, sizeof(intra_period));
> +}
> +
> 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 996c83fdc6f492dc252771129fc1d62e8b7a7e07..609258c81517b71523b682ca994786cdd020b07f 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -41,6 +41,7 @@ int iris_set_ltr_count_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ty
> int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_intra_period(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> index 139e7a9321d30d3e348671f99b0fa81afed4827e..fe51eccb903be146e83a4fb2faf4b4092875dea4 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -718,6 +718,14 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
> packet->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
> break;
> }
> + case HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD: {
> + struct hfi_intra_period *in = pdata, *intra_period = prop_data;
> +
> + intra_period->pframes = in->pframes;
> + intra_period->bframes = in->bframes;
> + packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_period);
> + break;
> + }
> default:
> return -EINVAL;
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index 34249fc0d047918c2463517b8303e30df3666b97..476177add1ec860d46d85960dd09617ad347f60a 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -155,6 +155,7 @@
> #define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
> #define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
> #define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
> +#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD 0x2006003
do we need to set HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES as well for
gen1? Please check.
> #define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
> #define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
> #define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
> @@ -484,6 +485,11 @@ struct hfi_ltr_mark {
> u32 mark_frame;
> };
>
> +struct hfi_intra_period {
> + u32 pframes;
> + u32 bframes;
> +};
> +
> struct hfi_event_data {
> u32 error;
> u32 height;
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index c48dfb6d47734fadd4f2e4123c93560f55355b86..34deb32eb5be0899fee779ff99b3f4b8bd91529f 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -154,6 +154,8 @@ enum platform_inst_fw_cap_type {
> LTR_COUNT,
> USE_LTR,
> MARK_LTR,
> + B_FRAME,
> + INTRA_PERIOD,
> INST_FW_CAP_MAX,
> };
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> index 13cee5f72a443b85136d30b41b589aeb0db8eb9a..b76f0ecaa721f3469bc63b7ff4ce5fc6ea19a8e1 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> @@ -177,7 +177,6 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> .max = (1 << 16) - 1,
> .step_or_mask = 1,
> .value = 30,
> - .set = iris_set_u32
what is being removed here and why?
> },
> {
> .cap_id = ENTROPY_MODE,
> @@ -279,6 +278,24 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> .flags = CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> .set = iris_set_mark_ltr,
> },
> + {
> + .cap_id = B_FRAME,
> + .min = 0,
> + .max = 3,
> + .step_or_mask = 1,
> + .value = 0,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + },
> + {
> + .cap_id = INTRA_PERIOD,
> + .min = 0,
> + .max = 1,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + .set = iris_set_intra_period,
> + },
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8550 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index 8139fefe40fe179ff7862bbca879ce94c71c1f89..4a854a4dab322eabb16a52b1cf816c18d78acc81 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -670,11 +670,15 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
>
> static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
> {
> + u32 bframe_count, ltr_count;
> u32 num_ref = 1;
> - u32 ltr_count;
>
> + bframe_count = inst->fw_caps[B_FRAME].value;
> ltr_count = inst->fw_caps[LTR_COUNT].value;
>
> + if (bframe_count)
> + num_ref = 2;
this would impact the scratch2 size calculation as well, please check if
this is as expected for scratch2.
Thanks,
Dikshita
> +
> if (ltr_count)
> num_ref = num_ref + ltr_count;
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 4/4] media: qcom: iris: Add hierarchical coding support for encoder
2025-11-27 7:44 [PATCH 0/4] media: qcom: iris: encoder feature enhancements batch2 Wangao Wang
` (2 preceding siblings ...)
2025-11-27 7:44 ` [PATCH 3/4] media: qcom: iris: Add B frames " Wangao Wang
@ 2025-11-27 7:44 ` Wangao Wang
2025-11-27 10:50 ` Bryan O'Donoghue
3 siblings, 1 reply; 17+ messages in thread
From: Wangao Wang @ 2025-11-27 7:44 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Bryan O'Donoghue, Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, Wangao Wang, linux-media,
linux-arm-msm, linux-kernel
Add hierarchical coding support for both gen1 and gen2 encoders by enabling
the following V4L2 controls:
H264:
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER
HEVC(gen2 only):
V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER
Key changes:
Added capability IDs for hierarchical coding enable, type, and layer count.
Implemented handlers for layer type and layer count (gen1/gen2).
Defined new HFI properties and enums for hierarchical coding.
Updated platform capability tables and buffer logic to handle hierarchical
coding.
Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_ctrls.c | 150 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_ctrls.h | 3 +
.../platform/qcom/iris/iris_hfi_gen1_command.c | 14 ++
.../platform/qcom/iris/iris_hfi_gen1_defines.h | 2 +
.../platform/qcom/iris/iris_hfi_gen2_defines.h | 9 ++
drivers/media/platform/qcom/iris/iris_instance.h | 4 +
.../platform/qcom/iris/iris_platform_common.h | 11 ++
.../media/platform/qcom/iris/iris_platform_gen1.c | 26 ++++
.../media/platform/qcom/iris/iris_platform_gen2.c | 48 +++++++
drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 21 +++
10 files changed, 288 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 9aec8a2006e9f8e545d05e40cb68ef0ae8502f79..99b6cfdd726258f753b3d1920144044e5aa76f29 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -116,6 +116,16 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return MARK_LTR;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
return B_FRAME;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
+ return LAYER_ENABLE;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
+ return LAYER_TYPE_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
+ return LAYER_TYPE_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
+ return LAYER_COUNT_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
+ return LAYER_COUNT_HEVC;
default:
return INST_FW_CAP_MAX;
}
@@ -221,6 +231,16 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
case B_FRAME:
return V4L2_CID_MPEG_VIDEO_B_FRAMES;
+ case LAYER_ENABLE:
+ return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
+ case LAYER_TYPE_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
+ case LAYER_TYPE_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE;
+ case LAYER_COUNT_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
+ case LAYER_COUNT_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER;
default:
return 0;
}
@@ -1173,6 +1193,136 @@ int iris_set_intra_period(struct iris_inst *inst, enum platform_inst_fw_cap_type
&intra_period, sizeof(intra_period));
}
+int iris_set_layer_type(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 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 layer_type;
+
+ if (inst->hfi_rc_type == HFI_RATE_CONTROL_CQ ||
+ inst->hfi_rc_type == HFI_RATE_CONTROL_OFF)
+ return -EINVAL;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ if (!layer_enable || !inst->fw_caps[LAYER_COUNT_H264].value)
+ return -EINVAL;
+
+ if (inst->fw_caps[LAYER_TYPE_H264].value ==
+ V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P) {
+ if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
+ layer_type = HFI_HIER_P_HYBRID_LTR;
+ else
+ layer_type = HFI_HIER_P_SLIDING_WINDOW;
+ } else if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
+ V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) {
+ if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
+ layer_type = HFI_HIER_B;
+ else
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+ } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ if (!inst->fw_caps[LAYER_COUNT_HEVC].value)
+ return -EINVAL;
+
+ if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
+ V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) {
+ layer_type = HFI_HIER_P_SLIDING_WINDOW;
+ } else if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
+ V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) {
+ if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
+ layer_type = HFI_HIER_B;
+ else
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+ }
+
+ inst->hfi_layer_type = layer_type;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &layer_type, sizeof(u32));
+}
+
+int iris_set_layer_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+ struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+ u32 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
+ u32 layer_count = inst->fw_caps[cap_id].value;
+ u32 hfi_id;
+
+ if (!layer_enable || !layer_count)
+ return -EINVAL;
+
+ inst->hfi_layer_count = layer_count;
+
+ if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq)) {
+ hfi_id = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER;
+ hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &layer_count, sizeof(u32));
+ }
+
+ hfi_id = inst->fw_caps[cap_id].hfi_id;
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &layer_count, sizeof(u32));
+}
+
+int iris_set_layer_count_gen2(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 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 layer_type = inst->hfi_layer_type;
+ u32 layer_count, layer_count_max;
+
+ layer_count = (inst->codec == V4L2_PIX_FMT_H264) ?
+ inst->fw_caps[LAYER_COUNT_H264].value :
+ inst->fw_caps[LAYER_COUNT_HEVC].value;
+
+ if (!layer_type || !layer_count)
+ return -EINVAL;
+
+ if (layer_type == HFI_HIER_B) {
+ layer_count_max = MAX_LAYER_HB;
+ } else if (layer_type == HFI_HIER_P_HYBRID_LTR) {
+ layer_count_max = MAX_AVC_LAYER_HP_HYBRID_LTR;
+ } else if (layer_type == HFI_HIER_P_SLIDING_WINDOW) {
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ layer_count_max = MAX_AVC_LAYER_HP_SLIDING_WINDOW;
+ } else {
+ if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
+ layer_count_max = MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW;
+ else
+ layer_count_max = MAX_HEVC_LAYER_HP_SLIDING_WINDOW;
+ }
+ }
+
+ if (layer_count > layer_count_max)
+ layer_count = layer_count_max;
+
+ layer_count += 1; /* base layer */
+ inst->hfi_layer_count = layer_count;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &layer_count, 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 609258c81517b71523b682ca994786cdd020b07f..d7db8749273c73348e7dc1c344d720a97d571e24 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -42,6 +42,9 @@ int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_intra_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_layer_type(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_layer_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_layer_count_gen2(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index fe51eccb903be146e83a4fb2faf4b4092875dea4..1e001e2639a1d913c81ed643f8071cd561767651 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -726,6 +726,20 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_period);
break;
}
+ case HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER: {
+ u32 *in = pdata;
+
+ packet->data[1] = *in;
+ packet->shdr.hdr.size += sizeof(u32) * 2;
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER: {
+ u32 *in = pdata;
+
+ packet->data[1] = *in;
+ packet->shdr.hdr.size += sizeof(u32) * 2;
+ break;
+ }
default:
return -EINVAL;
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 476177add1ec860d46d85960dd09617ad347f60a..7ecfd23a925c83d82912c1ab4ca148e5cc35e142 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -154,11 +154,13 @@
#define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
+#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER 0x2005026
#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
#define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD 0x2006003
#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
+#define HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER 0x200600b
struct hfi_pkt_hdr {
u32 size;
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 2b8c87c25a066ead30bb1b134bdc3fe1e84e8f05..3a689d3f53b4e8750a33e8bc78a8df7a023d7a56 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -74,6 +74,15 @@ enum hfi_rate_control {
#define HFI_PROP_LTR_COUNT 0x03000134
#define HFI_PROP_LTR_MARK 0x03000135
#define HFI_PROP_LTR_USE 0x03000136
+
+enum hfi_layer_encoding_type {
+ HFI_HIER_P_SLIDING_WINDOW = 0x1,
+ HFI_HIER_P_HYBRID_LTR = 0x2,
+ HFI_HIER_B = 0x3,
+};
+
+#define HFI_PROP_LAYER_ENCODING_TYPE 0x03000138
+#define HFI_PROP_LAYER_COUNT 0x03000139
#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_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
index 0a0d4ace0bb6bee6ab11bd47fddb27432cd524f7..f4aa904f94ebb3c87bcdeeb6c3732b616d030b96 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -73,6 +73,8 @@ struct iris_fmt {
* @enc_raw_height: source image height for encoder instance
* @enc_scale_width: scale width for encoder instance
* @enc_scale_height: scale height for encoder instance
+ * @hfi_layer_type: hierarchical coding layer type
+ * @hfi_layer_count: hierarchical coding layer count
*/
struct iris_inst {
@@ -115,6 +117,8 @@ struct iris_inst {
u32 enc_raw_height;
u32 enc_scale_width;
u32 enc_scale_height;
+ u32 hfi_layer_type;
+ u32 hfi_layer_count;
};
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 34deb32eb5be0899fee779ff99b3f4b8bd91529f..db80617dbdc865c5a10708968f34987972d935f7 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -32,6 +32,12 @@ struct iris_inst;
#define INVALID_DEFAULT_MARK_OR_USE_LTR -1
#define MAX_LTR_FRAME_COUNT_GEN1 4
#define MAX_LTR_FRAME_COUNT_GEN2 2
+#define MAX_LAYER_HB 3
+#define MAX_AVC_LAYER_HP_HYBRID_LTR 5
+#define MAX_AVC_LAYER_HP_SLIDING_WINDOW 3
+#define MAX_HEVC_LAYER_HP_SLIDING_WINDOW 3
+#define MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW 5
+#define MAX_HIER_CODING_LAYER_GEN1 6
enum stage_type {
STAGE_1 = 1,
@@ -156,6 +162,11 @@ enum platform_inst_fw_cap_type {
MARK_LTR,
B_FRAME,
INTRA_PERIOD,
+ LAYER_ENABLE,
+ LAYER_TYPE_H264,
+ LAYER_TYPE_HEVC,
+ LAYER_COUNT_H264,
+ LAYER_COUNT_HEVC,
INST_FW_CAP_MAX,
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
index b76f0ecaa721f3469bc63b7ff4ce5fc6ea19a8e1..ba5d0ddb87f4b3dc21f81027e7011a6acda3854d 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
@@ -296,6 +296,32 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
.flags = CAP_FLAG_OUTPUT_PORT,
.set = iris_set_intra_period,
},
+ {
+ .cap_id = LAYER_ENABLE,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = LAYER_TYPE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .max = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
+ .value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = LAYER_COUNT_H264,
+ .min = 0,
+ .max = MAX_HIER_CODING_LAYER_GEN1,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_layer_count_gen1,
+ },
};
static struct platform_inst_caps platform_inst_cap_sm8250 = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index 7c9a71755685d195a7adc8064523e1c33a572089..e9c4a62a891c34bc0969c0fd4ea33a9d9b11c93d 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -677,6 +677,54 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
.flags = CAP_FLAG_OUTPUT_PORT,
.set = iris_set_u32,
},
+ {
+ .cap_id = LAYER_ENABLE,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = LAYER_TYPE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
+ .max = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) |
+ BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
+ .value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .hfi_id = HFI_PROP_LAYER_ENCODING_TYPE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = LAYER_TYPE_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+ .max = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P),
+ .value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+ .hfi_id = HFI_PROP_LAYER_ENCODING_TYPE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_layer_type,
+ },
+ {
+ .cap_id = LAYER_COUNT_H264,
+ .min = 0,
+ .max = 5,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROP_LAYER_COUNT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = LAYER_COUNT_HEVC,
+ .min = 0,
+ .max = 5,
+ .step_or_mask = 1,
+ .value = 0,
+ .hfi_id = HFI_PROP_LAYER_COUNT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_layer_count_gen2,
+ }
};
static struct platform_inst_caps platform_inst_cap_sm8550 = {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index 4a854a4dab322eabb16a52b1cf816c18d78acc81..dfdffcf08b6837936b7be1f1a1f109d2bb8203c6 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -670,6 +670,8 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
{
+ u32 layer_count = inst->hfi_layer_count;
+ u32 layer_type = inst->hfi_layer_type;
u32 bframe_count, ltr_count;
u32 num_ref = 1;
@@ -679,9 +681,28 @@ static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
if (bframe_count)
num_ref = 2;
+ if (layer_type == HFI_HIER_P_HYBRID_LTR)
+ num_ref = (layer_count + 1) >> 1;
+
+ if (layer_type == HFI_HIER_P_SLIDING_WINDOW) {
+ if (inst->codec == V4L2_PIX_FMT_HEVC)
+ num_ref = (layer_count + 1) >> 1;
+ else if (inst->codec == V4L2_PIX_FMT_H264 && layer_count < 4)
+ num_ref = (layer_count - 1);
+ else
+ num_ref = layer_count;
+ }
+
if (ltr_count)
num_ref = num_ref + ltr_count;
+ if (layer_type == HFI_HIER_B) {
+ if (inst->codec == V4L2_PIX_FMT_HEVC)
+ num_ref = layer_count;
+ else
+ num_ref = (1 << (layer_count - 2)) + 1;
+ }
+
return num_ref + 1;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH 4/4] media: qcom: iris: Add hierarchical coding support for encoder
2025-11-27 7:44 ` [PATCH 4/4] media: qcom: iris: Add hierarchical coding " Wangao Wang
@ 2025-11-27 10:50 ` Bryan O'Donoghue
0 siblings, 0 replies; 17+ messages in thread
From: Bryan O'Donoghue @ 2025-11-27 10:50 UTC (permalink / raw)
To: Wangao Wang, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab
Cc: quic_qiweil, Renjiang Han, linux-media, linux-arm-msm,
linux-kernel
On 27/11/2025 07:44, Wangao Wang wrote:
> Add hierarchical coding support for both gen1 and gen2 encoders by enabling
> the following V4L2 controls:
> H264:
> V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
> V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
> V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER
> HEVC(gen2 only):
> V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
> V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER
>
> Key changes:
> Added capability IDs for hierarchical coding enable, type, and layer count.
> Implemented handlers for layer type and layer count (gen1/gen2).
> Defined new HFI properties and enums for hierarchical coding.
> Updated platform capability tables and buffer logic to handle hierarchical
> coding.
>
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_ctrls.c | 150 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_ctrls.h | 3 +
> .../platform/qcom/iris/iris_hfi_gen1_command.c | 14 ++
> .../platform/qcom/iris/iris_hfi_gen1_defines.h | 2 +
> .../platform/qcom/iris/iris_hfi_gen2_defines.h | 9 ++
> drivers/media/platform/qcom/iris/iris_instance.h | 4 +
> .../platform/qcom/iris/iris_platform_common.h | 11 ++
> .../media/platform/qcom/iris/iris_platform_gen1.c | 26 ++++
> .../media/platform/qcom/iris/iris_platform_gen2.c | 48 +++++++
> drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 21 +++
> 10 files changed, 288 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
> index 9aec8a2006e9f8e545d05e40cb68ef0ae8502f79..99b6cfdd726258f753b3d1920144044e5aa76f29 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.c
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
> @@ -116,6 +116,16 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
> return MARK_LTR;
> case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> return B_FRAME;
> + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
> + return LAYER_ENABLE;
> + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
> + return LAYER_TYPE_H264;
> + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
> + return LAYER_TYPE_HEVC;
> + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
> + return LAYER_COUNT_H264;
> + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
> + return LAYER_COUNT_HEVC;
> default:
> return INST_FW_CAP_MAX;
> }
> @@ -221,6 +231,16 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
> return V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX;
> case B_FRAME:
> return V4L2_CID_MPEG_VIDEO_B_FRAMES;
> + case LAYER_ENABLE:
> + return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
> + case LAYER_TYPE_H264:
> + return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
> + case LAYER_TYPE_HEVC:
> + return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE;
> + case LAYER_COUNT_H264:
> + return V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
> + case LAYER_COUNT_HEVC:
> + return V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER;
> default:
> return 0;
> }
> @@ -1173,6 +1193,136 @@ int iris_set_intra_period(struct iris_inst *inst, enum platform_inst_fw_cap_type
> &intra_period, sizeof(intra_period));
> }
>
> +int iris_set_layer_type(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 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
> + u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + u32 layer_type;
> +
> + if (inst->hfi_rc_type == HFI_RATE_CONTROL_CQ ||
> + inst->hfi_rc_type == HFI_RATE_CONTROL_OFF)
> + return -EINVAL;
> +
> + if (inst->codec == V4L2_PIX_FMT_H264) {
> + if (!layer_enable || !inst->fw_caps[LAYER_COUNT_H264].value)
> + return -EINVAL;
> +
> + if (inst->fw_caps[LAYER_TYPE_H264].value ==
> + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P) {
> + if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
> + layer_type = HFI_HIER_P_HYBRID_LTR;
> + else
> + layer_type = HFI_HIER_P_SLIDING_WINDOW;
> + } else if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
> + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) {
> + if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
> + layer_type = HFI_HIER_B;
> + else
> + return -EINVAL;
> + } else {
> + return -EINVAL;
> + }
> + } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
> + if (!inst->fw_caps[LAYER_COUNT_HEVC].value)
> + return -EINVAL;
> +
> + if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
> + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P) {
> + layer_type = HFI_HIER_P_SLIDING_WINDOW;
> + } else if (inst->fw_caps[LAYER_TYPE_HEVC].value ==
> + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) {
> + if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
> + layer_type = HFI_HIER_B;
> + else
> + return -EINVAL;
> + } else {
> + return -EINVAL;
> + }
> + }
> +
> + inst->hfi_layer_type = layer_type;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_U32_ENUM,
> + &layer_type, sizeof(u32));
> +}
> +
> +int iris_set_layer_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
> +{
> + const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
> + struct vb2_queue *sq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
> + struct vb2_queue *dq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
> + u32 layer_enable = inst->fw_caps[LAYER_ENABLE].value;
> + u32 layer_count = inst->fw_caps[cap_id].value;
> + u32 hfi_id;
> +
> + if (!layer_enable || !layer_count)
> + return -EINVAL;
> +
> + inst->hfi_layer_count = layer_count;
> +
> + if (!vb2_is_streaming(sq) && !vb2_is_streaming(dq)) {
> + hfi_id = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER;
> + hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_U32,
> + &layer_count, sizeof(u32));
Shouldn't you catch the result code and bug out if this fails ?
> + }
> +
> + hfi_id = inst->fw_caps[cap_id].hfi_id;
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_U32,
> + &layer_count, sizeof(u32));
> +}
> +
> +int iris_set_layer_count_gen2(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 hfi_id = inst->fw_caps[cap_id].hfi_id;
> + u32 layer_type = inst->hfi_layer_type;
> + u32 layer_count, layer_count_max;
> +
> + layer_count = (inst->codec == V4L2_PIX_FMT_H264) ?
> + inst->fw_caps[LAYER_COUNT_H264].value :
> + inst->fw_caps[LAYER_COUNT_HEVC].value;
> +
> + if (!layer_type || !layer_count)
> + return -EINVAL;
> +
> + if (layer_type == HFI_HIER_B) {
> + layer_count_max = MAX_LAYER_HB;
> + } else if (layer_type == HFI_HIER_P_HYBRID_LTR) {
> + layer_count_max = MAX_AVC_LAYER_HP_HYBRID_LTR;
> + } else if (layer_type == HFI_HIER_P_SLIDING_WINDOW) {
> + if (inst->codec == V4L2_PIX_FMT_H264) {
> + layer_count_max = MAX_AVC_LAYER_HP_SLIDING_WINDOW;
> + } else {
> + if (inst->hfi_rc_type == HFI_RC_VBR_CFR)
> + layer_count_max = MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW;
> + else
> + layer_count_max = MAX_HEVC_LAYER_HP_SLIDING_WINDOW;
> + }
> + }
> +
> + if (layer_count > layer_count_max)
> + layer_count = layer_count_max;
> +
> + layer_count += 1; /* base layer */
> + inst->hfi_layer_count = layer_count;
> +
> + return hfi_ops->session_set_property(inst, hfi_id,
> + HFI_HOST_FLAGS_NONE,
> + iris_get_port_info(inst, cap_id),
> + HFI_PAYLOAD_U32,
> + &layer_count, 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 609258c81517b71523b682ca994786cdd020b07f..d7db8749273c73348e7dc1c344d720a97d571e24 100644
> --- a/drivers/media/platform/qcom/iris/iris_ctrls.h
> +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
> @@ -42,6 +42,9 @@ int iris_set_use_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_
> int iris_set_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_use_and_mark_ltr(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> int iris_set_intra_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_layer_type(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_layer_count_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
> +int iris_set_layer_count_gen2(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_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> index fe51eccb903be146e83a4fb2faf4b4092875dea4..1e001e2639a1d913c81ed643f8071cd561767651 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
> @@ -726,6 +726,20 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
> packet->shdr.hdr.size += sizeof(u32) + sizeof(*intra_period);
> break;
> }
> + case HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER: {
> + u32 *in = pdata;
> +
> + packet->data[1] = *in;
> + packet->shdr.hdr.size += sizeof(u32) * 2;
> + break;
> + }
> + case HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER: {
> + u32 *in = pdata;
> +
> + packet->data[1] = *in;
> + packet->shdr.hdr.size += sizeof(u32) * 2;
This feels inconsistent.
You have a u32 header part and then a u32 data part right ?
> + break;
> + }
> default:
> return -EINVAL;
> }
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> index 476177add1ec860d46d85960dd09617ad347f60a..7ecfd23a925c83d82912c1ab4ca148e5cc35e142 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
> @@ -154,11 +154,13 @@
>
> #define HFI_PROPERTY_PARAM_VENC_LTRMODE 0x200501c
> #define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
> +#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER 0x2005026
> #define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
> #define HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD 0x2006003
> #define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME 0x2006009
> #define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME 0x200600a
> #define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
> +#define HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER 0x200600b
>
> struct hfi_pkt_hdr {
> u32 size;
> 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 2b8c87c25a066ead30bb1b134bdc3fe1e84e8f05..3a689d3f53b4e8750a33e8bc78a8df7a023d7a56 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
> @@ -74,6 +74,15 @@ enum hfi_rate_control {
> #define HFI_PROP_LTR_COUNT 0x03000134
> #define HFI_PROP_LTR_MARK 0x03000135
> #define HFI_PROP_LTR_USE 0x03000136
> +
> +enum hfi_layer_encoding_type {
> + HFI_HIER_P_SLIDING_WINDOW = 0x1,
> + HFI_HIER_P_HYBRID_LTR = 0x2,
> + HFI_HIER_B = 0x3,
> +};
> +
> +#define HFI_PROP_LAYER_ENCODING_TYPE 0x03000138
> +#define HFI_PROP_LAYER_COUNT 0x03000139
> #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_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
> index 0a0d4ace0bb6bee6ab11bd47fddb27432cd524f7..f4aa904f94ebb3c87bcdeeb6c3732b616d030b96 100644
> --- a/drivers/media/platform/qcom/iris/iris_instance.h
> +++ b/drivers/media/platform/qcom/iris/iris_instance.h
> @@ -73,6 +73,8 @@ struct iris_fmt {
> * @enc_raw_height: source image height for encoder instance
> * @enc_scale_width: scale width for encoder instance
> * @enc_scale_height: scale height for encoder instance
> + * @hfi_layer_type: hierarchical coding layer type
> + * @hfi_layer_count: hierarchical coding layer count
> */
>
> struct iris_inst {
> @@ -115,6 +117,8 @@ struct iris_inst {
> u32 enc_raw_height;
> u32 enc_scale_width;
> u32 enc_scale_height;
> + u32 hfi_layer_type;
> + u32 hfi_layer_count;
> };
>
> #endif
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 34deb32eb5be0899fee779ff99b3f4b8bd91529f..db80617dbdc865c5a10708968f34987972d935f7 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -32,6 +32,12 @@ struct iris_inst;
> #define INVALID_DEFAULT_MARK_OR_USE_LTR -1
> #define MAX_LTR_FRAME_COUNT_GEN1 4
> #define MAX_LTR_FRAME_COUNT_GEN2 2
> +#define MAX_LAYER_HB 3
> +#define MAX_AVC_LAYER_HP_HYBRID_LTR 5
> +#define MAX_AVC_LAYER_HP_SLIDING_WINDOW 3
> +#define MAX_HEVC_LAYER_HP_SLIDING_WINDOW 3
> +#define MAX_HEVC_VBR_LAYER_HP_SLIDING_WINDOW 5
> +#define MAX_HIER_CODING_LAYER_GEN1 6
>
> enum stage_type {
> STAGE_1 = 1,
> @@ -156,6 +162,11 @@ enum platform_inst_fw_cap_type {
> MARK_LTR,
> B_FRAME,
> INTRA_PERIOD,
> + LAYER_ENABLE,
> + LAYER_TYPE_H264,
> + LAYER_TYPE_HEVC,
> + LAYER_COUNT_H264,
> + LAYER_COUNT_HEVC,
> INST_FW_CAP_MAX,
> };
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> index b76f0ecaa721f3469bc63b7ff4ce5fc6ea19a8e1..ba5d0ddb87f4b3dc21f81027e7011a6acda3854d 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
> @@ -296,6 +296,32 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
> .flags = CAP_FLAG_OUTPUT_PORT,
> .set = iris_set_intra_period,
> },
> + {
> + .cap_id = LAYER_ENABLE,
> + .min = 0,
> + .max = 1,
> + .step_or_mask = 1,
> + .value = 0,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + },
> + {
> + .cap_id = LAYER_TYPE_H264,
> + .min = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
> + .max = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
> + .value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + },
> + {
> + .cap_id = LAYER_COUNT_H264,
> + .min = 0,
> + .max = MAX_HIER_CODING_LAYER_GEN1,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + .set = iris_set_layer_count_gen1,
> + },
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8250 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> index 7c9a71755685d195a7adc8064523e1c33a572089..e9c4a62a891c34bc0969c0fd4ea33a9d9b11c93d 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
> @@ -677,6 +677,54 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
> .flags = CAP_FLAG_OUTPUT_PORT,
> .set = iris_set_u32,
> },
> + {
> + .cap_id = LAYER_ENABLE,
> + .min = 0,
> + .max = 1,
> + .step_or_mask = 1,
> + .value = 0,
> + .flags = CAP_FLAG_OUTPUT_PORT,
> + },
> + {
> + .cap_id = LAYER_TYPE_H264,
> + .min = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
> + .max = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) |
> + BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
> + .value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
> + .hfi_id = HFI_PROP_LAYER_ENCODING_TYPE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + },
> + {
> + .cap_id = LAYER_TYPE_HEVC,
> + .min = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
> + .max = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) |
> + BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P),
> + .value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
> + .hfi_id = HFI_PROP_LAYER_ENCODING_TYPE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_layer_type,
> + },
> + {
> + .cap_id = LAYER_COUNT_H264,
> + .min = 0,
> + .max = 5,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROP_LAYER_COUNT,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + },
> + {
> + .cap_id = LAYER_COUNT_HEVC,
> + .min = 0,
> + .max = 5,
> + .step_or_mask = 1,
> + .value = 0,
> + .hfi_id = HFI_PROP_LAYER_COUNT,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
> + .set = iris_set_layer_count_gen2,
> + }
> };
>
> static struct platform_inst_caps platform_inst_cap_sm8550 = {
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> index 4a854a4dab322eabb16a52b1cf816c18d78acc81..dfdffcf08b6837936b7be1f1a1f109d2bb8203c6 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
> @@ -670,6 +670,8 @@ static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
>
> static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
> {
> + u32 layer_count = inst->hfi_layer_count;
> + u32 layer_type = inst->hfi_layer_type;
> u32 bframe_count, ltr_count;
> u32 num_ref = 1;
>
> @@ -679,9 +681,28 @@ static inline u32 hfi_buffer_get_recon_count(struct iris_inst *inst)
> if (bframe_count)
> num_ref = 2;
>
> + if (layer_type == HFI_HIER_P_HYBRID_LTR)
> + num_ref = (layer_count + 1) >> 1;
> +
> + if (layer_type == HFI_HIER_P_SLIDING_WINDOW) {
> + if (inst->codec == V4L2_PIX_FMT_HEVC)
> + num_ref = (layer_count + 1) >> 1;
> + else if (inst->codec == V4L2_PIX_FMT_H264 && layer_count < 4)
> + num_ref = (layer_count - 1);
> + else
> + num_ref = layer_count;
> + }
Why are some of these num_refs shifted but others are not ?
> +
> if (ltr_count)
> num_ref = num_ref + ltr_count;
>
> + if (layer_type == HFI_HIER_B) {
> + if (inst->codec == V4L2_PIX_FMT_HEVC)
> + num_ref = layer_count;
> + else
> + num_ref = (1 << (layer_count - 2)) + 1;
> + }
> +
> return num_ref + 1;
> }
>
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread