瀏覽代碼

video: driver: Add support to enable output tx sw fence by default

As part of default enablement of output tx type sw fence,
add this support in driver to disable fence based on
below conditions for INPUT_PSC propertities:
- If session is interlace type
- If OUTPUT_ORDER is 0 and HFI_PROP_MAX_NUM_REORDER_FRAMES > 0

Change-Id: If861129ba96329c0277a9c9698f67baf25e5d82e
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 2 年之前
父節點
當前提交
907ea75504

+ 0 - 1
driver/platform/common/inc/msm_vidc_platform.h

@@ -336,7 +336,6 @@ int msm_vidc_adjust_dec_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_roi_info(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_all_intra(void *instance, struct v4l2_ctrl *ctrl);
-int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_outbuf_fence_type(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_outbuf_fence_direction(void *instance,
 	struct v4l2_ctrl *ctrl);

+ 6 - 0
driver/platform/common/inc/msm_vidc_platform_ext.h

@@ -247,6 +247,12 @@ enum v4l2_mpeg_vidc_av1_tier {
 #define V4L2_CID_MPEG_VIDC_GRID_WIDTH                                         \
 	(V4L2_CID_MPEG_VIDC_BASE + 0x49)
 
+#define V4L2_CID_MPEG_VIDC_MAX_NUM_REORDER_FRAMES                             \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x4A)
+
+#define V4L2_CID_MPEG_VIDC_INTERLACE                                          \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x4B)
+
 int msm_vidc_adjust_ir_period(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_frame_rate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_operating_rate(void *instance, struct v4l2_ctrl *ctrl);

+ 0 - 24
driver/platform/common/src/msm_vidc_platform.c

@@ -2234,30 +2234,6 @@ int msm_vidc_adjust_roi_info(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
-int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl)
-{
-	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
-	u32 adjusted_value = 0;
-	s32 picture_order = -1;
-
-	adjusted_value = ctrl ? ctrl->val : inst->capabilities[META_OUTBUF_FENCE].value;
-
-	if (msm_vidc_get_parent_value(inst, META_OUTBUF_FENCE, OUTPUT_ORDER,
-		&picture_order, __func__))
-		return -EINVAL;
-
-	if (picture_order == 0) {
-		/* disable outbuf fence */
-		adjusted_value = MSM_VIDC_META_DISABLE |
-			MSM_VIDC_META_RX_INPUT;
-	}
-
-	msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
-		adjusted_value, __func__);
-
-	return 0;
-}
-
 int msm_vidc_adjust_dec_outbuf_fence_type(void *instance, struct v4l2_ctrl *ctrl)
 {
 	struct msm_vidc_inst_cap *capability;

+ 71 - 8
driver/platform/kalama/src/msm_vidc_kalama.c

@@ -546,7 +546,7 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_OUTBUF_FENCE,
 		HFI_PROP_FENCE,
-		CAP_FLAG_BITMASK | CAP_FLAG_META},
+		CAP_FLAG_BITMASK | CAP_FLAG_META | CAP_FLAG_DYNAMIC_ALLOWED},
 
 	/*
 	 * Client to do set_ctrl with FENCE_ID to set fence_id
@@ -565,6 +565,40 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		0,
 		CAP_FLAG_VOLATILE},
 
+	/* Fence type for input buffer. Currently unused */
+	{INBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
+		MSM_VIDC_FENCE_NONE, MSM_VIDC_FENCE_NONE,
+		BIT(MSM_VIDC_FENCE_NONE),
+		MSM_VIDC_FENCE_NONE,
+		0,
+		HFI_PROP_FENCE_TYPE,
+		CAP_FLAG_MENU | CAP_FLAG_INPUT_PORT},
+
+	{OUTBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
+		MSM_VIDC_FENCE_NONE, MSM_VIDC_SYNX_V2_FENCE,
+		BIT(MSM_VIDC_FENCE_NONE) | BIT(MSM_VIDC_SW_FENCE),
+		MSM_VIDC_FENCE_NONE,
+		0,
+		HFI_PROP_FENCE_TYPE,
+		CAP_FLAG_MENU | CAP_FLAG_OUTPUT_PORT},
+
+	/* Fence direction for input buffer. Currently unused */
+	{INBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1,
+		MSM_VIDC_FENCE_DIR_NONE, MSM_VIDC_FENCE_DIR_NONE,
+		BIT(MSM_VIDC_FENCE_DIR_NONE),
+		MSM_VIDC_FENCE_DIR_NONE,
+		0,
+		HFI_PROP_FENCE_DIRECTION,
+		CAP_FLAG_MENU | CAP_FLAG_INPUT_PORT},
+
+	{OUTBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1,
+		MSM_VIDC_FENCE_DIR_NONE, MSM_VIDC_FENCE_DIR_RX,
+		BIT(MSM_VIDC_FENCE_DIR_NONE) | BIT(MSM_VIDC_FENCE_DIR_TX),
+		MSM_VIDC_FENCE_DIR_NONE,
+		0,
+		HFI_PROP_FENCE_DIRECTION,
+		CAP_FLAG_MENU | CAP_FLAG_OUTPUT_PORT},
+
 	{TS_REORDER, DEC, H264|HEVC,
 		0, 1, 1, 0,
 		V4L2_CID_MPEG_VIDC_TS_REORDER},
@@ -1539,9 +1573,17 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		0,
 		HFI_PROP_PIPE},
 
-	{POC, DEC, H264, 0, 2, 1, 1,
+	{POC, DEC, H264,
+		0, 2, 1, 1,
 		0,
-		HFI_PROP_PIC_ORDER_CNT_TYPE},
+		HFI_PROP_PIC_ORDER_CNT_TYPE,
+		CAP_FLAG_VOLATILE},
+
+	{MAX_NUM_REORDER_FRAMES, DEC, H264 | HEVC,
+		0, 16, 1, 0,
+		V4L2_CID_MPEG_VIDC_MAX_NUM_REORDER_FRAMES,
+		HFI_PROP_MAX_NUM_REORDER_FRAMES,
+		CAP_FLAG_VOLATILE},
 
 	{QUALITY_MODE, ENC, CODECS_ALL,
 		MSM_VIDC_MAX_QUALITY_MODE,
@@ -1551,8 +1593,9 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 	{CODED_FRAMES, DEC, H264|HEVC|HEIC,
 		CODED_FRAMES_PROGRESSIVE, CODED_FRAMES_INTERLACE,
 		1, CODED_FRAMES_PROGRESSIVE,
-		0,
-		HFI_PROP_CODED_FRAMES},
+		V4L2_CID_MPEG_VIDC_INTERLACE,
+		HFI_PROP_CODED_FRAMES,
+		CAP_FLAG_VOLATILE},
 
 	{BIT_DEPTH, DEC, CODECS_ALL, BIT_DEPTH_8, BIT_DEPTH_10, 1, BIT_DEPTH_8,
 		0,
@@ -1982,10 +2025,30 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		msm_vidc_set_u32},
 
 	{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9|AV1,
-		{LOWLATENCY_MODE},
-		msm_vidc_adjust_dec_outbuf_fence,
+		{LOWLATENCY_MODE, OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
+		NULL,
+		NULL},
+
+	{INBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
+		{0},
+		NULL,
 		NULL},
 
+	{OUTBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
+		{0},
+		msm_vidc_adjust_dec_outbuf_fence_type,
+		msm_vidc_set_outbuf_fence_type},
+
+	{INBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1,
+		{0},
+		NULL,
+		NULL},
+
+	{OUTBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1,
+		{0},
+		msm_vidc_adjust_dec_outbuf_fence_direction,
+		msm_vidc_set_outbuf_fence_direction},
+
 	{HFLIP, ENC, CODECS_ALL,
 		{0},
 		NULL,
@@ -2352,7 +2415,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		NULL},
 
 	{OUTPUT_ORDER, DEC, H264|HEVC|VP9|AV1,
-		{META_OUTBUF_FENCE},
+		{0},
 		msm_vidc_adjust_output_order,
 		msm_vidc_set_u32},
 

+ 24 - 25
driver/platform/pineapple/src/msm_vidc_pineapple.c

@@ -607,7 +607,7 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_OUTBUF_FENCE,
 		HFI_PROP_FENCE,
-		CAP_FLAG_BITMASK | CAP_FLAG_META},
+		CAP_FLAG_BITMASK | CAP_FLAG_META | CAP_FLAG_DYNAMIC_ALLOWED},
 
 	/*
 	 * Client to do set_ctrl with FENCE_ID to set fence_id
@@ -626,7 +626,7 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0,
 		CAP_FLAG_VOLATILE},
 
-	/* Fence type for input buffer. Currently unsed */
+	/* Fence type for input buffer. Currently unused */
 	{INBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
 		MSM_VIDC_FENCE_NONE, MSM_VIDC_FENCE_NONE,
 		BIT(MSM_VIDC_FENCE_NONE),
@@ -644,7 +644,7 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		HFI_PROP_FENCE_TYPE,
 		CAP_FLAG_MENU | CAP_FLAG_OUTPUT_PORT},
 
-	/* Fence direction for input buffer. Currently unsed */
+	/* Fence direction for input buffer. Currently unused */
 	{INBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1,
 		MSM_VIDC_FENCE_DIR_NONE, MSM_VIDC_FENCE_DIR_NONE,
 		BIT(MSM_VIDC_FENCE_DIR_NONE),
@@ -1649,9 +1649,17 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0,
 		HFI_PROP_PIPE},
 
-	{POC, DEC, H264, 0, 2, 1, 1,
+	{POC, DEC, H264,
+		0, 2, 1, 1,
 		0,
-		HFI_PROP_PIC_ORDER_CNT_TYPE},
+		HFI_PROP_PIC_ORDER_CNT_TYPE,
+		CAP_FLAG_VOLATILE},
+
+	{MAX_NUM_REORDER_FRAMES, DEC, H264 | HEVC,
+		0, 16, 1, 0,
+		V4L2_CID_MPEG_VIDC_MAX_NUM_REORDER_FRAMES,
+		HFI_PROP_MAX_NUM_REORDER_FRAMES,
+		CAP_FLAG_VOLATILE},
 
 	{QUALITY_MODE, ENC, CODECS_ALL,
 		MSM_VIDC_MAX_QUALITY_MODE,
@@ -1661,8 +1669,9 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 	{CODED_FRAMES, DEC, H264|HEVC|HEIC,
 		CODED_FRAMES_PROGRESSIVE, CODED_FRAMES_INTERLACE,
 		1, CODED_FRAMES_PROGRESSIVE,
-		0,
-		HFI_PROP_CODED_FRAMES},
+		V4L2_CID_MPEG_VIDC_INTERLACE,
+		HFI_PROP_CODED_FRAMES,
+		CAP_FLAG_VOLATILE},
 
 	{BIT_DEPTH, DEC, CODECS_ALL, BIT_DEPTH_8, BIT_DEPTH_10, 1, BIT_DEPTH_8,
 		0,
@@ -1853,7 +1862,7 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_PICTURE_TYPE,
 		HFI_PROP_PICTURE_TYPE,
-		CAP_FLAG_BITMASK | CAP_FLAG_META},
+		CAP_FLAG_BITMASK | CAP_FLAG_META | CAP_FLAG_DYNAMIC_ALLOWED},
 
 	{META_SEI_MASTERING_DISP, ENC, HEVC|HEIC,
 		MSM_VIDC_META_DISABLE,
@@ -1955,7 +1964,7 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0, MSM_VIDC_META_DISABLE,
 		V4L2_CID_MPEG_VIDC_METADATA_BUFFER_TAG,
 		HFI_PROP_BUFFER_TAG,
-		CAP_FLAG_BITMASK | CAP_FLAG_META},
+		CAP_FLAG_BITMASK | CAP_FLAG_META | CAP_FLAG_DYNAMIC_ALLOWED},
 
 	{META_DPB_TAG_LIST, DEC, CODECS_ALL,
 		MSM_VIDC_META_DISABLE,
@@ -2092,15 +2101,9 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		NULL,
 		msm_vidc_set_u32},
 
-	{META_OUTBUF_FENCE, DEC, H264|HEVC|AV1,
-		{LOWLATENCY_MODE, SLICE_DECODE,
-			OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
-		msm_vidc_adjust_dec_outbuf_fence,
-		NULL},
-
-	{META_OUTBUF_FENCE, DEC, VP9,
+	{META_OUTBUF_FENCE, DEC, H264|HEVC|AV1|VP9,
 		{LOWLATENCY_MODE, OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
-		msm_vidc_adjust_dec_outbuf_fence,
+		NULL,
 		NULL},
 
 	{INBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1,
@@ -2257,7 +2260,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		NULL},
 
 	{LOWLATENCY_MODE, DEC, H264|HEVC|AV1,
-		{STAGE, SLICE_DECODE},
+		{STAGE},
 		msm_vidc_adjust_dec_lowlatency_mode,
 		NULL},
 
@@ -2512,13 +2515,8 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		NULL,
 		NULL},
 
-	{OUTPUT_ORDER, DEC, H264|HEVC|AV1,
-		{META_OUTBUF_FENCE, SLICE_DECODE},
-		msm_vidc_adjust_output_order,
-		msm_vidc_set_u32},
-
-	{OUTPUT_ORDER, DEC, VP9,
-		{META_OUTBUF_FENCE},
+	{OUTPUT_ORDER, DEC, H264|HEVC|AV1|VP9,
+		{0},
 		msm_vidc_adjust_output_order,
 		msm_vidc_set_u32},
 
@@ -2794,6 +2792,7 @@ static const u32 pineapple_vdec_psc_hevc[] = {
 	HFI_PROP_LEVEL,
 	HFI_PROP_TIER,
 	HFI_PROP_SIGNAL_COLOR_INFO,
+	HFI_PROP_MAX_NUM_REORDER_FRAMES,
 };
 
 static const u32 pineapple_vdec_psc_vp9[] = {

+ 2 - 0
driver/vidc/inc/msm_vdec.h

@@ -33,6 +33,8 @@ int msm_vdec_start_cmd(struct msm_vidc_inst *inst);
 int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf);
 int msm_vdec_set_num_comv(struct msm_vidc_inst *inst);
+int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
+	enum msm_vidc_port_type port);
 int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst);
 int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst);
 int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst);

+ 2 - 0
driver/vidc/inc/msm_vidc_internal.h

@@ -390,6 +390,7 @@ enum msm_vidc_metadata_bits {
 	CAP(CHROMA_QP_INDEX_OFFSET)               \
 	CAP(PIPE)                                 \
 	CAP(POC)                                  \
+	CAP(MAX_NUM_REORDER_FRAMES)               \
 	CAP(CODED_FRAMES)                         \
 	CAP(BIT_DEPTH)                            \
 	CAP(CODEC_CONFIG)                         \
@@ -822,6 +823,7 @@ struct msm_vidc_subscription_params {
 	u32                    tier;
 	u32                    av1_film_grain_present;
 	u32                    av1_super_block_enabled;
+	u32                    max_num_reorder_frames;
 };
 
 struct msm_vidc_hfi_frame_info {

+ 82 - 23
driver/vidc/src/msm_vdec.c

@@ -399,6 +399,34 @@ static int msm_vdec_set_picture_order_count(struct msm_vidc_inst *inst,
 	return rc;
 }
 
+static int msm_vdec_set_max_num_reorder_frames(struct msm_vidc_inst *inst,
+	enum msm_vidc_port_type port)
+{
+	int rc = 0;
+	u32 reorder_frames = 0;
+
+	if (port != INPUT_PORT && port != OUTPUT_PORT) {
+		i_vpr_e(inst, "%s: invalid port %d\n", __func__, port);
+		return -EINVAL;
+	}
+
+	reorder_frames = inst->subcr_params[port].max_num_reorder_frames;
+	i_vpr_h(inst, "%s: max reorder frames count: %d", __func__, reorder_frames);
+	rc = venus_hfi_session_property(inst,
+			HFI_PROP_MAX_NUM_REORDER_FRAMES,
+			HFI_HOST_FLAGS_NONE,
+			get_hfi_port(inst, port),
+			HFI_PAYLOAD_U32,
+			&reorder_frames,
+			sizeof(u32));
+	if (rc) {
+		i_vpr_e(inst, "%s: set property failed\n", __func__);
+		return rc;
+	}
+
+	return rc;
+}
+
 static int msm_vdec_set_colorspace(struct msm_vidc_inst *inst,
 	enum msm_vidc_port_type port)
 {
@@ -693,6 +721,26 @@ static int msm_vdec_set_output_properties(struct msm_vidc_inst *inst)
 	return rc;
 }
 
+static bool msm_vdec_check_outbuf_fence_allowed(struct msm_vidc_inst *inst)
+{
+	/* no need of checking for reordering/interlace for vp9/av1 */
+	if (inst->codec == MSM_VIDC_VP9 || inst->codec == MSM_VIDC_AV1)
+		return true;
+
+	if (inst->capabilities[CODED_FRAMES].value == CODED_FRAMES_INTERLACE ||
+		(!inst->capabilities[OUTPUT_ORDER].value &&
+		inst->capabilities[MAX_NUM_REORDER_FRAMES].value)) {
+		i_vpr_e(inst,
+			"%s: outbuf tx fence is unsupported for coded frames %d or output order %d and max num reorder frames %d\n",
+			__func__, inst->capabilities[CODED_FRAMES].value,
+			inst->capabilities[OUTPUT_ORDER].value,
+			inst->capabilities[MAX_NUM_REORDER_FRAMES].value);
+		return false;
+	}
+
+	return true;
+}
+
 int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
@@ -843,6 +891,7 @@ static int msm_vdec_subscribe_input_port_settings_change(struct msm_vidc_inst *i
 		{HFI_PROP_CODED_FRAMES,                  msm_vdec_set_coded_frames           },
 		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,    msm_vdec_set_min_output_count       },
 		{HFI_PROP_PIC_ORDER_CNT_TYPE,            msm_vdec_set_picture_order_count    },
+		{HFI_PROP_MAX_NUM_REORDER_FRAMES,        msm_vdec_set_max_num_reorder_frames },
 		{HFI_PROP_SIGNAL_COLOR_INFO,             msm_vdec_set_colorspace             },
 		{HFI_PROP_PROFILE,                       msm_vdec_set_profile                },
 		{HFI_PROP_LEVEL,                         msm_vdec_set_level                  },
@@ -1015,14 +1064,14 @@ static int msm_vdec_subscribe_property(struct msm_vidc_inst *inst,
 	return rc;
 }
 
-static int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
+int msm_vdec_subscribe_metadata(struct msm_vidc_inst *inst,
 	enum msm_vidc_port_type port)
 {
 	int rc = 0;
 	u32 payload[32] = {0};
 	u32 i, count = 0;
 
-	i_vpr_h(inst, "%s()\n", __func__);
+	i_vpr_h(inst, "%s() port %d\n", __func__, port);
 
 	payload[0] = HFI_MODE_METADATA;
 	if (port == INPUT_PORT) {
@@ -1139,7 +1188,7 @@ static int msm_vdec_set_delivery_mode_property(struct msm_vidc_inst *inst,
 	};
 	static const u32 property_input_list[] = {};
 
-	i_vpr_h(inst, "%s()\n", __func__);
+	i_vpr_h(inst, "%s() port %d\n", __func__, port);
 
 	payload[0] = HFI_MODE_PROPERTY;
 
@@ -1153,18 +1202,19 @@ static int msm_vdec_set_delivery_mode_property(struct msm_vidc_inst *inst,
 		}
 	} else if (port == OUTPUT_PORT) {
 		for (i = 0; i < ARRAY_SIZE(property_output_list); i++) {
-			if (property_output_list[i] == META_OUTBUF_FENCE &&
-				is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
-				/*
-				 * if output buffer fence enabled via
-				 * META_OUTBUF_FENCE, then driver will send
-				 * fence id via HFI_PROP_FENCE to firmware.
-				 * So enable HFI_PROP_FENCE property as
-				 * delivery mode property.
-				 */
-				payload[count + 1] =
-					inst->capabilities[property_output_list[i]].hfi_id;
-				count++;
+			if (property_output_list[i] == META_OUTBUF_FENCE) {
+				if (is_meta_rx_inp_enabled(inst,
+					META_OUTBUF_FENCE)) {
+					/*
+					* if output buffer fence enabled via
+					* META_OUTBUF_FENCE, then driver will send
+					* fence id via HFI_PROP_FENCE to firmware.
+					* So enable HFI_PROP_FENCE property as
+					* delivery mode property.
+					*/
+					payload[++count] =
+						inst->capabilities[property_output_list[i]].hfi_id;
+				}
 				continue;
 			}
 			if (inst->capabilities[property_output_list[i]].value) {
@@ -1239,6 +1289,7 @@ int msm_vdec_init_input_subcr_params(struct msm_vidc_inst *inst)
 	subsc_params->level = inst->capabilities[LEVEL].value;
 	subsc_params->tier = inst->capabilities[HEVC_TIER].value;
 	subsc_params->pic_order_cnt = inst->capabilities[POC].value;
+	subsc_params->max_num_reorder_frames = inst->capabilities[MAX_NUM_REORDER_FRAMES].value;
 	subsc_params->bit_depth = inst->capabilities[BIT_DEPTH].value;
 	if (inst->capabilities[CODED_FRAMES].value ==
 			CODED_FRAMES_PROGRESSIVE)
@@ -1363,6 +1414,8 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
 	msm_vidc_update_cap_value(inst, LEVEL, subsc_params.level, __func__);
 	msm_vidc_update_cap_value(inst, HEVC_TIER, subsc_params.tier, __func__);
 	msm_vidc_update_cap_value(inst, POC, subsc_params.pic_order_cnt, __func__);
+	msm_vidc_update_cap_value(inst, MAX_NUM_REORDER_FRAMES,
+		subsc_params.max_num_reorder_frames, __func__);
 	if (subsc_params.bit_depth == BIT_DEPTH_8)
 		msm_vidc_update_cap_value(inst, BIT_DEPTH, BIT_DEPTH_8, __func__);
 	else
@@ -1378,14 +1431,6 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
 			subsc_params.av1_super_block_enabled, __func__);
 	}
 
-	/* disable META_OUTBUF_FENCE if session is Interlace type */
-	if (inst->capabilities[CODED_FRAMES].value ==
-		CODED_FRAMES_INTERLACE) {
-		msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
-			MSM_VIDC_META_RX_INPUT |
-			MSM_VIDC_META_DISABLE, __func__);
-	}
-
 	inst->fw_min_count = subsc_params.fw_min_count;
 	inst->buffers.output.min_count = call_session_op(core,
 		min_count, inst, MSM_VIDC_BUF_OUTPUT);
@@ -1700,6 +1745,11 @@ static int msm_vdec_subscribe_output_port_settings_change(struct msm_vidc_inst *
 			payload_size = sizeof(u32);
 			payload_type = HFI_PAYLOAD_U32;
 			break;
+		case HFI_PROP_MAX_NUM_REORDER_FRAMES:
+			payload[0] = subsc_params.max_num_reorder_frames;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
 		default:
 			i_vpr_e(inst, "%s: unknown property %#x\n", __func__,
 				prop_type);
@@ -1788,6 +1838,13 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
+		if (!msm_vdec_check_outbuf_fence_allowed(inst)) {
+			rc = -EINVAL;
+			goto error;
+		}
+	}
+
 	if (!inst->opsc_properties_set) {
 		memcpy(&inst->subcr_params[OUTPUT_PORT],
 				&inst->subcr_params[INPUT_PORT],
@@ -2130,6 +2187,8 @@ int msm_vdec_start_cmd(struct msm_vidc_inst *inst)
 	if (is_sub_state(inst, MSM_VIDC_DRC) &&
 		is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER) &&
 		is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
+		i_vpr_h(inst, "%s: alloc and queue input internal buffers\n",
+			__func__);
 		rc = msm_vidc_alloc_and_queue_input_internal_buffers(inst);
 		if (rc)
 			return rc;

+ 23 - 0
driver/vidc/src/msm_vidc_driver.c

@@ -1225,6 +1225,19 @@ int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst)
 		rc = msm_vidc_set_pipe(inst, PIPE);
 		if (rc)
 			return rc;
+		/*
+		 * Input port subscription for metadata may be changed.
+		 * For eg: due to IPSC, driver may have disabled tx
+		 * type output fence, hence fence related metadatas
+		 * to recieve on input port will be disabled by HAL.
+		 * Hence, update metadata subscription properties
+		 * on INPUT port before sending RESUME command to FW.
+		 */
+		i_vpr_l(inst, "%s: reset input port subscribe metadata\n",
+			__func__);
+		rc = msm_vdec_subscribe_metadata(inst, INPUT_PORT);
+		if (rc)
+			return rc;
 	}
 
 	/*
@@ -1236,6 +1249,7 @@ int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst)
 		is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER);
 	if (!drain_pending && is_state(inst, MSM_VIDC_INPUT_STREAMING)) {
 		if (is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
+			i_vpr_h(inst, "%s: resume input port\n", __func__);
 			rc = venus_hfi_session_resume(inst, INPUT_PORT,
 					HFI_CMD_SETTINGS_CHANGE);
 			if (rc)
@@ -1480,6 +1494,15 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 			i_vpr_l(inst, "%s: fence fd: %d\n",
 				__func__, ctrl->val);
 		break;
+	case MAX_NUM_REORDER_FRAMES:
+		ctrl->val = inst->capabilities[MAX_NUM_REORDER_FRAMES].value;
+		i_vpr_h(inst, "%s: max num reorder frames: %d\n",
+			__func__, ctrl->val);
+		break;
+	case CODED_FRAMES:
+		ctrl->val = inst->capabilities[CODED_FRAMES].value;
+		i_vpr_h(inst, "%s: coded frames: %d\n", __func__, ctrl->val);
+		break;
 	default:
 		i_vpr_e(inst, "invalid ctrl %s id %d\n",
 			ctrl->name, ctrl->id);

+ 1 - 1
driver/vidc/src/msm_vidc_fence.c

@@ -164,7 +164,7 @@ static void msm_vidc_fence_destroy(struct msm_vidc_inst *inst, u64 fence_id)
 		return;
 	}
 
-	i_vpr_e(inst, "%s: fence %s\n", __func__, fence->name);
+	i_vpr_l(inst, "%s: fence %s\n", __func__, fence->name);
 	list_del_init(&fence->list);
 	dma_fence_set_error(&fence->dma_fence, -EINVAL);
 	dma_fence_signal(&fence->dma_fence);

+ 2 - 2
driver/vidc/src/msm_vidc_state.c

@@ -845,8 +845,8 @@ static int msm_vidc_input_streaming_state(struct msm_vidc_inst *inst,
 		if (is_decode_session(inst)) {
 			/* check dynamic allowed if master port is streaming */
 			if (!(inst->capabilities[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)) {
-				i_vpr_e(inst, "%s: cap_id %#x not allowed in state %s\n",
-					__func__, cap_id, state_name(inst->state));
+				i_vpr_e(inst, "%s: cap_id %#x (%s) not allowed in state %s\n",
+					__func__, cap_id, cap_name(cap_id), state_name(inst->state));
 				return -EINVAL;
 			}
 		}

+ 22 - 15
driver/vidc/src/venus_hfi_response.c

@@ -47,7 +47,7 @@ void print_psc_properties(const char *str, struct msm_vidc_inst *inst,
 {
 	i_vpr_h(inst,
 		"%s: width %d, height %d, crop offsets[0] %#x, crop offsets[1] %#x, bit depth %#x, coded frames %d "
-		"fw min count %d, poc %d, color info %d, profile %d, level %d, tier %d, fg present %d, sb enabled %d\n",
+		"fw min count %d, poc %d, color info %d, profile %d, level %d, tier %d, fg present %d, sb enabled %d max_num_reorder_frames %d\n",
 		str, (subsc_params.bitstream_resolution & HFI_BITMASK_BITSTREAM_WIDTH) >> 16,
 		(subsc_params.bitstream_resolution & HFI_BITMASK_BITSTREAM_HEIGHT),
 		subsc_params.crop_offsets[0], subsc_params.crop_offsets[1],
@@ -55,7 +55,7 @@ void print_psc_properties(const char *str, struct msm_vidc_inst *inst,
 		subsc_params.fw_min_count, subsc_params.pic_order_cnt,
 		subsc_params.color_info, subsc_params.profile, subsc_params.level,
 		subsc_params.tier, subsc_params.av1_film_grain_present,
-		subsc_params.av1_super_block_enabled);
+		subsc_params.av1_super_block_enabled, subsc_params.max_num_reorder_frames);
 }
 
 static void print_sfr_message(struct msm_vidc_core *core)
@@ -849,11 +849,15 @@ static int msm_vidc_handle_fence_signal(struct msm_vidc_inst *inst,
 			return -EINVAL;
 		}
 	} else {
-		if (inst->hfi_frame_info.fence_id)
+		if (!inst->hfi_frame_info.fence_id) {
+			return 0;
+		} else {
 			i_vpr_e(inst,
-				"%s: fence id is received although fencing is not enabled\n",
-				__func__);
-		return 0;
+				"%s: fence id: %d is received although fencing is not enabled\n",
+				__func__, inst->hfi_frame_info.fence_id);
+			signal_error = true;
+			goto signal;
+		}
 	}
 
 	if (inst->capabilities[OUTBUF_FENCE_TYPE].value ==
@@ -874,6 +878,7 @@ static int msm_vidc_handle_fence_signal(struct msm_vidc_inst *inst,
 		return -EINVAL;
 	}
 
+signal:
 	/* fence signalling */
 	if (signal_error) {
 		/* signal fence error */
@@ -1196,7 +1201,14 @@ static bool is_metabuffer_dequeued(struct msm_vidc_inst *inst,
 
 	list_for_each_entry(buffer, &buffers->list, list) {
 		if (buffer->index == buf->index &&
-			buffer->attr & MSM_VIDC_ATTR_DEQUEUED) {
+			(buffer->attr & MSM_VIDC_ATTR_DEQUEUED ||
+			buffer->attr & MSM_VIDC_ATTR_BUFFER_DONE)) {
+			/*
+			 * For META_OUTBUF_FENCE case, meta buffers are
+			 * dequeued ahead in time and completed vb2 done
+			 * as well. Hence, check for vb2 buffer done flag since
+			 * dequeued flag is already cleared for such buffers
+			 */
 			found = true;
 			break;
 		}
@@ -1216,14 +1228,6 @@ static int msm_vidc_check_meta_buffers(struct msm_vidc_inst *inst)
 	};
 
 	for (i = 0; i < ARRAY_SIZE(buffer_type); i++) {
-		/*
-		 * skip input meta buffers check as meta buffers were
-		 * already delivered if output fence enabled.
-		 */
-		if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
-			if (buffer_type[i] == MSM_VIDC_BUF_INPUT)
-				continue;
-		}
 		buffers = msm_vidc_get_buffers(inst, buffer_type[i], __func__);
 		if (!buffers)
 			return -EINVAL;
@@ -1732,6 +1736,9 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
 	case HFI_PROP_AV1_SUPER_BLOCK_ENABLED:
 		inst->subcr_params[port].av1_super_block_enabled = payload_ptr[0];
 		break;
+	case HFI_PROP_MAX_NUM_REORDER_FRAMES:
+		inst->subcr_params[port].max_num_reorder_frames = payload_ptr[0];
+		break;
 	case HFI_PROP_PICTURE_TYPE:
 		inst->hfi_frame_info.picture_type = payload_ptr[0];
 		if (inst->hfi_frame_info.picture_type & HFI_PICTURE_B)