소스 검색

video: driver: split ipsc and opsc subscription

Set ipsc subscribe properties once during start input
and opsc subscribe once during start output. Fetch all
property values from ipsc and set the same values to
output port.
added codec config control support.

Change-Id: I3683becdb62096ee4dbed36181a2dc9876c53724
Signed-off-by: Darshana Patil <[email protected]>
Darshana Patil 4 년 전
부모
커밋
a2f47ddf00

+ 20 - 0
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -920,6 +920,26 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 	{STAGE, DEC|ENC, CODECS_ALL, 1, 2, 1, 2},
 	{PIPE, DEC|ENC, CODECS_ALL, 1, 4, 1, 4},
 	{POC, DEC, H264, 0, 1, 1, 0},
+
+	{ENTROPY_MODE, DEC, CODECS_ALL,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		0,
+		HFI_PROP_CABAC_SESSION},
+
+	{CODED_FRAMES, DEC, CODECS_ALL, 0, 1, 1, 0,
+		0,
+		HFI_PROP_CODED_FRAMES},
+
+	{BIT_DEPTH, DEC, CODECS_ALL, 8 << 16 | 8, 10 << 16 | 10, 1, 8 << 16 | 8,
+		0,
+		HFI_PROP_LUMA_CHROMA_BIT_DEPTH},
+
+	{CODEC_CONFIG, DEC, H264|HEVC, 0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDC_CODEC_CONFIG},
 };
 
 /*

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

@@ -119,6 +119,8 @@ struct msm_vidc_inst {
 	struct list_head                   enc_input_crs;
 	struct list_head                   decode_bitrate_data;
 	bool                               once_per_session_set;
+	bool                               ipsc_properties_set;
+	bool                               opsc_properties_set;
 	struct dentry                     *debugfs_root;
 	struct msm_vidc_debug              debug;
 	struct msm_vidc_inst_capability   *capabilities;

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

@@ -141,7 +141,6 @@ enum msm_vidc_buffer_flags {
 	MSM_VIDC_BUF_FLAG_BFRAME           = 0x00000020,
 	MSM_VIDC_BUF_FLAG_ERROR            = 0x00000040,
 	MSM_VIDC_BUF_FLAG_LAST             = 0x00100000,
-	// TODO: remove below flags
 	MSM_VIDC_BUF_FLAG_CODECCONFIG      = 0x01000000,
 	MSM_VIDC_BUF_FLAG_SUBFRAME         = 0x02000000,
 };
@@ -328,6 +327,9 @@ enum msm_vidc_inst_capability_type {
 	STAGE,
 	PIPE,
 	POC,
+	CODED_FRAMES,
+	BIT_DEPTH,
+	CODEC_CONFIG,
 	INST_CAP_MAX,
 };
 

+ 2 - 0
driver/vidc/src/hfi_packet.c

@@ -231,6 +231,8 @@ int get_hfi_buffer(struct msm_vidc_inst *inst,
 		buf->flags |= HFI_BUF_HOST_FLAG_READONLY;
 	if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE)
 		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
+	if (buffer->flags & MSM_VIDC_BUF_FLAG_CODECCONFIG)
+		buf->flags |= HFI_BUF_HOST_FLAG_CODEC_CONFIG;
 	buf->timestamp = buffer->timestamp;
 
 	return 0;

+ 136 - 8
driver/vidc/src/msm_vdec.c

@@ -190,6 +190,7 @@ static int msm_vdec_set_bit_depth(struct msm_vidc_inst *inst,
 		bitdepth = 10 << 16 | 10;
 
 	inst->subcr_params[port].bit_depth = bitdepth;
+	inst->capabilities->cap[BIT_DEPTH].value = bitdepth;
 	s_vpr_h(inst->sid, "%s: bit depth: %d", __func__, bitdepth);
 	rc = venus_hfi_session_property(inst,
 			HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
@@ -215,10 +216,7 @@ static int msm_vdec_set_cabac(struct msm_vidc_inst *inst,
 		return -EINVAL;
 	}
 
-	rc = msm_vidc_v4l2_menu_to_hfi(inst, ENTROPY_MODE, &cabac);
-	if (rc)
-		return rc;
-
+	cabac = inst->capabilities->cap[ENTROPY_MODE].value;
 	inst->subcr_params[port].cabac = cabac;
 	s_vpr_h(inst->sid, "%s: entropy mode: %d", __func__, cabac);
 	rc = venus_hfi_session_property(inst,
@@ -245,8 +243,7 @@ static int msm_vdec_set_coded_frames(struct msm_vidc_inst *inst,
 		return -EINVAL;
 	}
 
-	/* (mb_adaptive_frame_field_flag << 1) | frame_mbs_only_flag */
-	coded_frames = 0;
+	coded_frames = inst->capabilities->cap[CODED_FRAMES].value;
 	inst->subcr_params[port].coded_frames = coded_frames;
 	s_vpr_h(inst->sid, "%s: coded frames: %d", __func__, coded_frames);
 	rc = venus_hfi_session_property(inst,
@@ -870,7 +867,7 @@ static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
 	return 0;
 }
 
-int msm_vdec_subscribe_port_settings_change(struct msm_vidc_inst *inst,
+static int msm_vdec_subscribe_input_port_settings_change(struct msm_vidc_inst *inst,
 	enum msm_vidc_port_type port)
 {
 	int rc = 0;
@@ -1064,7 +1061,7 @@ static int msm_vdec_session_resume(struct msm_vidc_inst *inst,
 	return rc;
 }
 
-static msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
+static int msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_subscription_params subsc_params;
 	u32 width, height;
@@ -1110,6 +1107,8 @@ static msm_vdec_update_input_properties(struct msm_vidc_inst *inst)
 	inst->capabilities->cap[HEVC_TIER].value = subsc_params.tier;
 	inst->capabilities->cap[ENTROPY_MODE].value = subsc_params.cabac;
 	inst->capabilities->cap[POC].value = subsc_params.pic_order_cnt;
+	inst->capabilities->cap[BIT_DEPTH].value = subsc_params.bit_depth;
+	inst->capabilities->cap[CODED_FRAMES].value = subsc_params.coded_frames;
 
 	return 0;
 }
@@ -1224,6 +1223,14 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	if (!inst->ipsc_properties_set) {
+		rc = msm_vdec_subscribe_input_port_settings_change(
+			inst, INPUT_PORT);
+		if (rc)
+			return rc;
+		inst->ipsc_properties_set = true;
+	}
+
 	rc = msm_vdec_subscribe_property(inst, INPUT_PORT);
 	if (rc)
 		return rc;
@@ -1261,6 +1268,118 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst)
 	return 0;
 }
 
+static int msm_vdec_subscribe_output_port_settings_change(struct msm_vidc_inst *inst,
+	enum msm_vidc_port_type port)
+{
+	int rc = 0;
+	u32 payload[32] = {0};
+	u32 prop_type, payload_size, payload_type;
+	u32 i;
+	struct msm_vidc_subscription_params subsc_params;
+
+	d_vpr_h("%s()\n", __func__);
+
+	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
+	for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change);
+	     i++)
+		payload[i + 1] = msm_vdec_subscribe_for_port_settings_change[i];
+
+	rc = venus_hfi_session_command(inst,
+			HFI_CMD_SUBSCRIBE_MODE,
+			port,
+			HFI_PAYLOAD_U32_ARRAY,
+			&payload[0],
+			(ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change) + 1) *
+			sizeof(u32));
+
+	subsc_params = inst->subcr_params[port];
+	for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change);
+		i++) {
+		payload[0] = 0;
+		payload[1] = 0;
+		payload_size = 0;
+		payload_type = 0;
+		prop_type = msm_vdec_subscribe_for_port_settings_change[i];
+		switch (prop_type) {
+		case HFI_PROP_BITSTREAM_RESOLUTION:
+			payload[0] = subsc_params.bitstream_resolution;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_CROP_OFFSETS:
+			payload[0] = subsc_params.crop_offsets >> 32;
+			payload[1] = subsc_params.crop_offsets;
+			payload_size = sizeof(u64);
+			payload_type = HFI_PAYLOAD_64_PACKED;
+			break;
+		case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
+			payload[0] = subsc_params.bit_depth;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_CABAC_SESSION:
+			payload[0] = subsc_params.cabac;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_CODED_FRAMES:
+			payload[0] = subsc_params.coded_frames;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+			payload[0] = subsc_params.fw_min_count;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_PIC_ORDER_CNT_TYPE:
+			payload[0] = subsc_params.pic_order_cnt;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_SIGNAL_COLOR_INFO:
+			payload[0] = subsc_params.color_info;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_PROFILE:
+			payload[0] = subsc_params.profile;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_LEVEL:
+			payload[0] = subsc_params.level;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_TIER:
+			payload[0] = subsc_params.tier;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		default:
+			d_vpr_e("%s: unknown property %#x\n", __func__,
+				prop_type);
+			prop_type = 0;
+			rc = -EINVAL;
+			break;
+		}
+		if (prop_type) {
+			rc = venus_hfi_session_property(inst,
+					prop_type,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, port),
+					payload_type,
+					&payload,
+					payload_size);
+			if (rc)
+				return rc;
+		}
+	}
+
+	return rc;
+}
+
 int msm_vdec_start_output(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
@@ -1275,6 +1394,15 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	if (!inst->opsc_properties_set) {
+		memcpy(&inst->subcr_params[OUTPUT_PORT],
+			&inst->subcr_params[INPUT_PORT], sizeof(inst->subcr_params[INPUT_PORT]));
+		rc = msm_vdec_subscribe_output_port_settings_change(inst, OUTPUT_PORT);
+		if (rc)
+			return rc;
+		inst->opsc_properties_set = true;
+	}
+
 	rc = msm_vdec_subscribe_metadata(inst, OUTPUT_PORT);
 	if (rc)
 		return rc;

+ 2 - 0
driver/vidc/src/msm_vidc.c

@@ -802,6 +802,8 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	inst->domain = session_type;
 	inst->state = MSM_VIDC_OPEN;
 	inst->request = false;
+	inst->ipsc_properties_set = false;
+	inst->opsc_properties_set = false;
 	for (i = 0; i < MAX_SIGNAL; i++)
 		init_completion(&inst->completions[i]);
 

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

@@ -763,6 +763,12 @@ int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
 		return 0;
 	}
 
+	if (is_decode_session(inst) &&
+			inst->capabilities->cap[CODEC_CONFIG].value) {
+		buf->flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG;
+		inst->capabilities->cap[CODEC_CONFIG].value = 0;
+	}
+
 	print_vidc_buffer(VIDC_HIGH, "qbuf", inst, buf);
 	meta = get_meta_buffer(inst, buf);
 	rc = venus_hfi_queue_buffer(inst, buf, meta);

+ 0 - 10
driver/vidc/src/msm_vidc_vb2.c

@@ -169,16 +169,6 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
 		rc = msm_vidc_session_set_codec(inst);
 		if (rc)
 			return rc;
-		if (is_decode_session(inst)) {
-			rc = msm_vdec_subscribe_port_settings_change(
-				inst, INPUT_PORT);
-			if (rc)
-				return rc;
-			rc = msm_vdec_subscribe_port_settings_change(
-				inst, OUTPUT_PORT);
-			if (rc)
-				return rc;
-		}
 	}
 
 	/*

+ 20 - 0
driver/vidc/src/venus_hfi_response.c

@@ -10,6 +10,22 @@
 #include "msm_vidc_driver.h"
 #include "msm_vdec.h"
 
+void print_psc_properties(u32 tag, const char *str, struct msm_vidc_inst *inst,
+	struct msm_vidc_subscription_params subsc_params)
+{
+	if (!(tag & msm_vidc_debug) || !inst)
+		return;
+
+	dprintk(tag, inst->sid,
+		"%s: resolution %d, crop offsets %lld, bit depth %d, cabac %d, coded frames %d "
+		"fw min count %d, poc %d, color info %d, profile %d, level %d, tier %d ",
+		str, subsc_params.bitstream_resolution, subsc_params.crop_offsets,
+		subsc_params.bit_depth, subsc_params.cabac, subsc_params.coded_frames,
+		subsc_params.fw_min_count, subsc_params.pic_order_cnt,
+		subsc_params.color_info, subsc_params.profile, subsc_params.level,
+		subsc_params.tier);
+}
+
 u32 vidc_port_from_hfi(struct msm_vidc_inst *inst,
 	enum hfi_packet_port_type hfi_port)
 {
@@ -1014,10 +1030,14 @@ static int handle_session_response(struct msm_vidc_core *core,
 
 	if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
 		if (hfi_port == HFI_PORT_BITSTREAM) {
+			print_psc_properties(VIDC_HIGH, "INPUT_PSC", inst,
+				inst->subcr_params[INPUT_PORT]);
 			rc = msm_vdec_input_port_settings_change(inst);
 			if (rc)
 				goto exit;
 		} else if (hfi_port == HFI_PORT_RAW) {
+			print_psc_properties(VIDC_HIGH, "OUTPUT_PSC", inst,
+				inst->subcr_params[OUTPUT_PORT]);
 			rc = msm_vdec_output_port_settings_change(inst);
 			if (rc)
 				goto exit;