Browse Source

video: driver: add restrictions for dec fence enablement

- Allow dec sw fence enablement only if decode order is set and
 non interlace type session.
- Enable low latency mode if sw fence is enabled.
- Signal fence if FBD length > 0.

Change-Id: Ib59c2de51f621b796e68fe2aba68d9fca3ff4272
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 3 years ago
parent
commit
047ed11bf7

+ 26 - 5
driver/platform/kalama/src/msm_vidc_kalama.c

@@ -330,7 +330,7 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 	 * Client will enable V4L2_CID_MPEG_VIDC_METADATA_OUTBUF_FENCE
 	 * to get fence_id in input metadata buffer done.
 	 */
-	{META_OUTBUF_FENCE, DEC, CODECS_ALL,
+	{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9|AV1,
 		V4L2_MPEG_VIDC_META_DISABLE,
 		V4L2_MPEG_VIDC_META_ENABLE | V4L2_MPEG_VIDC_META_RX_INPUT,
 		0, V4L2_MPEG_VIDC_META_DISABLE,
@@ -1327,7 +1327,10 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = {
 		0,
 		HFI_PROP_PIPE},
 
-	{POC, DEC, H264, 0, 18, 1, 1},
+	{POC, DEC, H264,
+		0, 18, 1, 1,
+		0,
+		HFI_PROP_PIC_ORDER_CNT_TYPE},
 
 	{QUALITY_MODE, ENC, CODECS_ALL,
 		MSM_VIDC_MAX_QUALITY_MODE,
@@ -1729,6 +1732,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		NULL,
 		msm_vidc_set_u32},
 
+	{META_OUTBUF_FENCE, DEC, H264|HEVC|VP9|AV1,
+		{OUTPUT_ORDER},
+		{LOWLATENCY_MODE},
+		msm_vidc_adjust_dec_outbuf_fence,
+		NULL},
+
 	{HFLIP, ENC, CODECS_ALL,
 		{0},
 		{0},
@@ -1860,7 +1869,13 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 	{LOWLATENCY_MODE, ENC, H264 | HEVC,
 		{BITRATE_MODE},
 		{STAGE},
-		msm_vidc_adjust_lowlatency_mode,
+		msm_vidc_adjust_enc_lowlatency_mode,
+		NULL},
+
+	{LOWLATENCY_MODE, DEC, H264|HEVC|VP9|AV1,
+		{META_OUTBUF_FENCE},
+		{STAGE},
+		msm_vidc_adjust_dec_lowlatency_mode,
 		NULL},
 
 	{LTR_COUNT, ENC, H264|HEVC,
@@ -2150,7 +2165,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 
 	{OUTPUT_ORDER, DEC, H264|HEVC|VP9|AV1,
 		{THUMBNAIL_MODE, DISPLAY_DELAY, DISPLAY_DELAY_ENABLE},
-		{0},
+		{META_OUTBUF_FENCE},
 		msm_vidc_adjust_output_order,
 		msm_vidc_set_u32},
 
@@ -2190,7 +2205,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		NULL,
 		msm_vidc_set_u32_packed},
 
-	{STAGE, DEC|ENC, CODECS_ALL,
+	{STAGE, ENC | DEC, CODECS_ALL,
 		{0},
 		{0},
 		NULL,
@@ -2202,6 +2217,12 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala
 		NULL,
 		msm_vidc_set_stage},
 
+	{STAGE, DEC, H264|HEVC|VP9|AV1,
+		{LOWLATENCY_MODE},
+		{0},
+		NULL,
+		msm_vidc_set_stage},
+
 	{PIPE, DEC|ENC, CODECS_ALL,
 		{0},
 		{0},

+ 3 - 1
driver/vidc/inc/msm_vidc_control.h

@@ -46,7 +46,8 @@ int msm_vidc_adjust_blur_resolution(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_brs(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_min_quality(void *instance, struct v4l2_ctrl *ctrl);
-int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_enc_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_dec_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_set_v4l2_properties(struct msm_vidc_inst *inst);
 int msm_vidc_prepare_dependency_list(struct msm_vidc_inst *inst);
 int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl);
@@ -54,6 +55,7 @@ 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_frame_rate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_operating_rate(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl);
 
 int msm_vidc_set_header_mode(void *instance,

+ 5 - 0
driver/vidc/inc/msm_vidc_driver.h

@@ -197,6 +197,11 @@ static inline bool is_meta_enabled(struct msm_vidc_inst *inst, unsigned int type
 	return enabled;
 }
 
+static inline bool is_outbuf_fence_enabled(struct msm_vidc_inst *inst)
+{
+	return is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE);
+}
+
 static inline bool is_linear_yuv_colorformat(enum msm_vidc_colorformat_type colorformat)
 {
 	return colorformat == MSM_VIDC_FMT_NV12 ||

+ 3 - 1
driver/vidc/inc/msm_vidc_fence.h

@@ -13,10 +13,12 @@ struct msm_vidc_fence *msm_vidc_fence_create(
 		struct msm_vidc_inst *inst);
 int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
 		struct msm_vidc_fence *fence);
+struct msm_vidc_fence *msm_vidc_get_fence_from_id(
+	struct msm_vidc_inst *inst, u32 fence_id);
 int msm_vidc_fence_signal(struct msm_vidc_inst *inst,
 		u32 fence_id);
 void msm_vidc_fence_destroy(struct msm_vidc_inst *inst,
-		struct msm_vidc_fence *fence);
+		u32 fence_id);
 int msm_vidc_fence_init(struct msm_vidc_inst *inst);
 void msm_vidc_fence_deinit(struct msm_vidc_inst *inst);
 

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

@@ -762,6 +762,7 @@ struct msm_vidc_hfi_frame_info {
 	u32                    cf;
 	u32                    data_corrupt;
 	u32                    overflow;
+	u32                    fence_id;
 };
 
 struct msm_vidc_decode_vpp_delay {

+ 9 - 1
driver/vidc/src/msm_vdec.c

@@ -1190,7 +1190,7 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
 	u32 colour_description_present_flag = 0;
 	u32 video_signal_type_present_flag = 0;
 
-	if (!inst || !inst->core) {
+	if (!inst || !inst->core || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 	}
@@ -1298,6 +1298,14 @@ 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->cap[CODED_FRAMES].value ==
+		CODED_FRAMES_INTERLACE) {
+		msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
+			V4L2_MPEG_VIDC_META_RX_INPUT |
+			V4L2_MPEG_VIDC_META_DISABLE, __func__);
+	}
+
 	return 0;
 }
 

+ 64 - 8
driver/vidc/src/msm_vidc_control.c

@@ -443,7 +443,6 @@ int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap_id,
 	s32 adjusted_val, const char *func)
 {
 	int prev_value = 0;
-	bool is_updated = false;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -464,19 +463,15 @@ int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap_id,
 			/* disable metadata */
 			inst->capabilities->cap[cap_id].value &= ~adjusted_val;
 		}
-		if (prev_value != (prev_value | adjusted_val))
-			is_updated = true;
 	} else {
 		inst->capabilities->cap[cap_id].value = adjusted_val;
-		if (prev_value != adjusted_val)
-			is_updated = true;
 	}
 
-	if (is_updated) {
+	if (prev_value != inst->capabilities->cap[cap_id].value) {
 		i_vpr_h(inst,
 			"%s: updated database: name: %s, value: %#x -> %#x\n",
 			func, cap_name(cap_id),
-			prev_value, adjusted_val);
+			prev_value, inst->capabilities->cap[cap_id].value);
 	}
 
 	return 0;
@@ -2743,7 +2738,7 @@ int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
-int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
+int msm_vidc_adjust_enc_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
 {
 	struct msm_vidc_inst_capability *capability;
 	s32 adjusted_value;
@@ -2773,6 +2768,36 @@ int msm_vidc_adjust_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
+int msm_vidc_adjust_dec_lowlatency_mode(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	s32 outbuf_fence = V4L2_MPEG_VIDC_META_DISABLE;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val :
+		capability->cap[LOWLATENCY_MODE].value;
+
+	if (msm_vidc_get_parent_value(inst, LOWLATENCY_MODE, META_OUTBUF_FENCE,
+		&outbuf_fence, __func__))
+		return -EINVAL;
+
+	if (outbuf_fence & V4L2_MPEG_VIDC_META_ENABLE &&
+		outbuf_fence & V4L2_MPEG_VIDC_META_RX_INPUT)
+		adjusted_value = 1;
+
+	msm_vidc_update_cap_value(inst, LOWLATENCY_MODE,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
 int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl)
 {
 	int adjusted_value;
@@ -2893,6 +2918,37 @@ int msm_vidc_adjust_dec_operating_rate(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_capability *capability;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	u32 adjusted_value = 0;
+	s32 picture_order = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	adjusted_value = ctrl ? ctrl->val : capability->cap[META_OUTBUF_FENCE].value;
+
+	if (msm_vidc_get_parent_value(inst, META_OUTBUF_FENCE, OUTPUT_ORDER,
+		&picture_order, __func__))
+		return -EINVAL;
+
+	if (picture_order == V4L2_MPEG_MSM_VIDC_DISABLE) {
+		/* disable outbuf fence */
+		adjusted_value = V4L2_MPEG_VIDC_META_DISABLE |
+			V4L2_MPEG_VIDC_META_RX_INPUT;
+	}
+
+	msm_vidc_update_cap_value(inst, META_OUTBUF_FENCE,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
 int msm_vidc_prepare_dependency_list(struct msm_vidc_inst *inst)
 {
 	struct list_head root_list, opt_list;

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

@@ -3481,7 +3481,7 @@ exit:
 	if (rc) {
 		i_vpr_e(inst, "%s: qbuf failed\n", __func__);
 		if (fence)
-			msm_vidc_fence_destroy(inst, fence);
+			msm_vidc_fence_destroy(inst, (u32)fence->dma_fence.seqno);
 	}
 	return rc;
 }
@@ -5569,7 +5569,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
 	list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
 		i_vpr_e(inst, "%s: destroying fence id: %llu\n",
 			__func__, fence->dma_fence.seqno);
-		msm_vidc_fence_destroy(inst, fence);
+		msm_vidc_fence_destroy(inst, (u32)fence->dma_fence.seqno);
 	}
 
 	/* destroy buffers from pool */

+ 28 - 20
driver/vidc/src/msm_vidc_fence.c

@@ -117,15 +117,15 @@ err_fd:
 	return rc;
 }
 
-int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
+struct msm_vidc_fence *msm_vidc_get_fence_from_id(
+	struct msm_vidc_inst *inst, u32 fence_id)
 {
-	int rc = 0;
 	struct msm_vidc_fence *fence, *dummy_fence;
 	bool found = false;
 
 	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
+		return NULL;
 	}
 
 	list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
@@ -135,12 +135,30 @@ int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
 		}
 	}
 
-	if (!found) {
+	if (!found)
+		return NULL;
+
+	return fence;
+}
+
+int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
+{
+	int rc = 0;
+	struct msm_vidc_fence *fence;
+
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	fence = msm_vidc_get_fence_from_id(inst, fence_id);
+	if (!fence) {
 		i_vpr_e(inst, "%s: no fence available to signal with id: %u",
 			__func__, fence_id);
 		rc = -EINVAL;
 		goto exit;
 	}
+
 	i_vpr_l(inst, "%s: fence %s\n", __func__, fence->name);
 	dma_fence_signal(&fence->dma_fence);
 	dma_fence_put(&fence->dma_fence);
@@ -150,28 +168,18 @@ exit:
 	return rc;
 }
 
-void msm_vidc_fence_destroy(struct msm_vidc_inst *inst,
-		struct msm_vidc_fence *fence_to_destroy)
+
+void msm_vidc_fence_destroy(struct msm_vidc_inst *inst, u32 fence_id)
 {
-	struct msm_vidc_fence *fence, *dummy_fence;
-	bool found = false;
+	struct msm_vidc_fence *fence;
 
-	if (!inst || !fence_to_destroy) {
+	if (!inst) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return;
 	}
 
-	list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
-		if (fence->dma_fence.seqno ==
-			fence_to_destroy->dma_fence.seqno) {
-			found = true;
-			break;
-		}
-	}
-
-	if (!found) {
-		i_vpr_e(inst, "%s: no fence available to destroy with id: %llu",
-			__func__, fence_to_destroy->dma_fence.seqno);
+	fence = msm_vidc_get_fence_from_id(inst, fence_id);
+	if (!fence) {
 		return;
 	}
 

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

@@ -864,7 +864,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
 		if (buffer->data_size) {
 			i_vpr_e(inst, "%s: reset data size to zero for last flag buffer\n",
 				__func__);
-			buffer->data_size = 0;
+			buf->data_size = 0;
 		}
 		if (buffer->flags & HFI_BUF_FW_FLAG_READONLY) {
 			i_vpr_e(inst, "%s: reset RO flag for last flag buffer\n",
@@ -895,6 +895,19 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
 	buf->flags = 0;
 	buf->flags = get_driver_buffer_flags(inst, buffer->flags);
 
+	/* fence signalling */
+	if (inst->hfi_frame_info.fence_id) {
+		if (buf->data_size) {
+			/* signal fence */
+			msm_vidc_fence_signal(inst,
+				inst->hfi_frame_info.fence_id);
+		} else {
+			/* destroy fence */
+			msm_vidc_fence_destroy(inst,
+				inst->hfi_frame_info.fence_id);
+		}
+	}
+
 	if (is_decode_session(inst)) {
 		inst->power.fw_cr = inst->hfi_frame_info.cr;
 		inst->power.fw_cf = inst->hfi_frame_info.cf;
@@ -1435,7 +1448,6 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
 {
 	int rc = 0;
 	u32 *payload_ptr = NULL;
-	u32 fence_id = 0;
 
 	payload_ptr = (u32 *)((u8 *)pkt + sizeof(struct hfi_packet));
 	if (!payload_ptr) {
@@ -1536,13 +1548,7 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst,
 				__func__,  payload_ptr[0], inst->capabilities->cap[PIPE].value);
 		break;
 	case HFI_PROP_FENCE:
-		if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
-			fence_id = payload_ptr[0];
-			rc = msm_vidc_fence_signal(inst, fence_id);
-		} else {
-			i_vpr_e(inst, "%s: fence is not enabled for this session\n",
-				__func__);
-		}
+		inst->hfi_frame_info.fence_id = payload_ptr[0];
 		break;
 	default:
 		i_vpr_e(inst, "%s: invalid property %#x\n",

+ 10 - 0
include/uapi/vidc/media/v4l2_vidc_extensions.h

@@ -389,6 +389,16 @@ enum meta_interlace_info {
 	META_INTERLACE_FRAME_INTERLACE_BOTTOMFIELD_FIRST    = 0x00000020,
 };
 
+enum meta_picture_type {
+	META_PICTURE_TYPE_IDR                            = 0x00000001,
+	META_PICTURE_TYPE_P                              = 0x00000002,
+	META_PICTURE_TYPE_B                              = 0x00000004,
+	META_PICTURE_TYPE_I                              = 0x00000008,
+	META_PICTURE_TYPE_CRA                            = 0x00000010,
+	META_PICTURE_TYPE_BLA                            = 0x00000020,
+	META_PICTURE_TYPE_NOSHOW                         = 0x00000040,
+};
+
 /* vendor controls end */
 
 /* vendor events start */