Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 659ec4d4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Add support to query current codec profile and level"

parents 5496ab13 fcb38e76
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -662,6 +662,33 @@ int create_pkt_cmd_session_flush(struct hfi_cmd_session_flush_packet *pkt,
	return rc;
}

int create_pkt_cmd_session_get_property(
		struct hfi_cmd_session_get_property_packet *pkt,
		u32 session_id, enum hal_property ptype)
{
	int rc = 0;
	if (!pkt || !session_id) {
		dprintk(VIDC_ERR, "%s Invalid parameters\n", __func__);
		return -EINVAL;
	}
	pkt->size = sizeof(struct hfi_cmd_session_get_property_packet);
	pkt->packet_type = HFI_CMD_SESSION_GET_PROPERTY;
	pkt->session_id = session_id;
	pkt->num_properties = 1;
	switch (ptype) {
	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
			pkt->rg_property_data[0] =
				HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
		break;
	default:
		dprintk(VIDC_ERR, "%s cmd:0x%x not supported\n", __func__,
			ptype);
		rc = -EINVAL;
		break;
	}
	return rc;
}

int create_pkt_cmd_session_set_property(
		struct hfi_cmd_session_set_property_packet *pkt,
		u32 session_id, enum hal_property ptype, void *pdata)
+4 −0
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ int create_pkt_cmd_session_set_property(
		struct hfi_cmd_session_set_property_packet *pkt,
		u32 session_id, enum hal_property ptype, void *pdata);

int create_pkt_cmd_session_get_property(
		struct hfi_cmd_session_get_property_packet *pkt,
		u32 session_id, enum hal_property ptype);

int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type,
		struct hfi_cmd_sys_test_ssr_packet *pkt);

+92 −18
Original line number Diff line number Diff line
@@ -108,7 +108,8 @@ static void hfi_process_sess_evt_seq_changed(
	struct msm_vidc_cb_cmd_done cmd_done;
	struct msm_vidc_cb_event event_notify;
	int num_properties_changed;
	struct hfi_frame_size frame_sz;
	struct hfi_frame_size *frame_sz;
	struct hfi_profile_level *profile_level;
	u8 *data_ptr;
	int prop_id;
	dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY");
@@ -146,17 +147,29 @@ static void hfi_process_sess_evt_seq_changed(
			prop_id = (int) *((u32 *)data_ptr);
			switch (prop_id) {
			case HFI_PROPERTY_PARAM_FRAME_SIZE:
				frame_sz.buffer_type =
					(int) *((((u32 *)data_ptr)+1));
				frame_sz.width =
					event_notify.width =
						*((((u32 *)data_ptr)+2));
				frame_sz.height =
					event_notify.height =
						*((((u32 *)data_ptr)+3));
				data_ptr += 4;
				data_ptr = data_ptr + sizeof(u32);
				frame_sz =
					(struct hfi_frame_size *) data_ptr;
				event_notify.width = frame_sz->width;
				event_notify.height = frame_sz->height;
				dprintk(VIDC_DBG, "height:%d width:%d\n",
					frame_sz->height, frame_sz->width);
				data_ptr +=
					sizeof(struct hfi_frame_size);
				break;
			case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
				data_ptr = data_ptr + sizeof(u32);
				profile_level =
					(struct hfi_profile_level *) data_ptr;
				dprintk(VIDC_DBG, "profile:%d level:%d\n",
					profile_level->profile,
					profile_level->level);
				data_ptr +=
					sizeof(struct hfi_profile_level);
				break;
			default:
				dprintk(VIDC_ERR, "%s cmd:0x%x not supported\n",
							__func__, prop_id);
				break;
			}
			num_properties_changed--;
@@ -440,6 +453,7 @@ enum vidc_status hfi_process_sess_init_done_prop_read(
	u8 *data_ptr;
	u32 status = VIDC_ERR_NONE;
	u32 prop_id, next_offset = 0;
	u32 prop_count = 0;

	rem_bytes = pkt->size - sizeof(struct
			hfi_msg_sys_session_init_done_packet) + sizeof(u32);
@@ -546,10 +560,30 @@ enum vidc_status hfi_process_sess_init_done_prop_read(
		}
		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
		{
			char *ptr = NULL;
			int count = 0;
			struct hfi_profile_level *prop_level;
			struct hfi_profile_level_supported *prop =
				(struct hfi_profile_level_supported *)
				(data_ptr + next_offset);

			ptr = (char *) &prop->rg_profile_level[0];
			dprintk(VIDC_DBG, "prop->profile_count:%d\n",
				prop->profile_count);
			prop_count = prop->profile_count;
			while (prop_count) {
				ptr++;
				prop_level = (struct hfi_profile_level *) ptr;
				sess_init_done->
				profile_level.profile_level[count].profile
					= prop_level->profile;
				sess_init_done->
				profile_level.profile_level[count].level
					= prop_level->level;
				prop_count--;
				count++;
				ptr +=
				sizeof(struct hfi_profile_level) / sizeof(u32);
			}
			next_offset += sizeof(*prop) -
				sizeof(struct hfi_profile_level) +
				prop->profile_count *
@@ -626,6 +660,37 @@ enum vidc_status hfi_process_sess_init_done_prop_read(
	return status;
}

static void hfi_process_sess_get_prop_profile_level(
	struct hfi_msg_session_property_info_packet *prop,
	struct hfi_profile_level *profile_level)
{
	struct hfi_profile_level *hfi_profile_level;
	u32 req_bytes;
	dprintk(VIDC_DBG, "Entered %s\n", __func__);
	if (!prop) {
		dprintk(VIDC_ERR,
			"hal_process_sess_get_profile_level:bad_prop: %p",
			prop);
		return;
	}
	req_bytes = prop->size - sizeof(
	struct hfi_msg_session_property_info_packet);

	if (!req_bytes || (req_bytes % sizeof(struct hfi_profile_level))) {
		dprintk(VIDC_ERR,
			"hal_process_sess_get_profile_level:bad_pkt: %d",
			req_bytes);
		return;
	}
	hfi_profile_level = (struct hfi_profile_level *)
				&prop->rg_property_data[1];
	profile_level->profile = hfi_profile_level->profile;
	profile_level->level = hfi_profile_level->level;
	dprintk(VIDC_DBG, "%s profile:%d level:%d\n",
		__func__, profile_level->profile,
		profile_level->level);
}

static void hfi_process_sess_get_prop_buf_req(
	struct hfi_msg_session_property_info_packet *prop,
	struct buffer_requirements *buffreq)
@@ -744,10 +809,11 @@ static void hfi_process_session_prop_info(
		msm_vidc_callback callback, u32 device_id,
		struct hfi_msg_session_property_info_packet *pkt)
{
	struct msm_vidc_cb_cmd_done cmd_done;
	struct msm_vidc_cb_cmd_done cmd_done = {0};
	struct hfi_profile_level profile_level = {0};
	struct buffer_requirements buff_req;

	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO");
	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO\n");

	if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
		dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size");
@@ -760,11 +826,9 @@ static void hfi_process_session_prop_info(
		return;
	}

	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
	memset(&buff_req, 0, sizeof(struct buffer_requirements));

	switch (pkt->rg_property_data[0]) {
	case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
		memset(&buff_req, 0, sizeof(struct buffer_requirements));
		hfi_process_sess_get_prop_buf_req(pkt, &buff_req);
		cmd_done.device_id = device_id;
		cmd_done.session_id =
@@ -774,6 +838,16 @@ static void hfi_process_session_prop_info(
		cmd_done.size = sizeof(struct buffer_requirements);
		callback(SESSION_PROPERTY_INFO, &cmd_done);
		break;
	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
		hfi_process_sess_get_prop_profile_level(pkt, &profile_level);
		cmd_done.device_id = device_id;
		cmd_done.session_id =
			((struct hal_session *) pkt->session_id)->session_id;
		cmd_done.status = VIDC_ERR_NONE;
		cmd_done.data = &profile_level;
		cmd_done.size = sizeof(struct hal_profile_level);
		callback(SESSION_PROPERTY_INFO, &cmd_done);
		break;
	default:
		dprintk(VIDC_ERR, "hal_process_session_prop_info:"
					"unknown_prop_id: %d",
+257 −1
Original line number Diff line number Diff line
@@ -89,6 +89,37 @@ static const char *const perf_level[] = {
	"Turbo"
};

static const char *const h263_level[] = {
	"1.0",
	"2.0",
	"3.0",
	"4.0",
	"4.5",
	"5.0",
	"6.0",
	"7.0",
};

static const char *const h263_profile[] = {
	"Baseline",
	"H320 Coding",
	"Backward Compatible",
	"ISWV2",
	"ISWV3",
	"High Compression",
	"Internet",
	"Interlace",
	"High Latency",
};

static const char *const vp8_profile_level[] = {
	"Unused",
	"0.0",
	"1.0",
	"2.0",
	"3.0",
};

static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
@@ -321,7 +352,137 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
		.menu_skip_mask = 0,
		.step = 1,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
		.name = "MPEG4 Profile",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
		.maximum =
		V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
		.default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
		.step = 1,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
		.name = "MPEG4 Level",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
		.maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
		.default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
		.step = 1,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
		.name = "H264 Profile",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
		.maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
		.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
		.step = 1,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
		.name = "H264 Level",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
		.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_5_2,
		.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
		.step = 0,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
		.name = "H263 Profile",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY,
		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
		.menu_skip_mask = ~(
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
		),
		.qmenu = h263_profile,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
		.name = "H263 Level",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
		.maximum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0,
		.default_value = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
		.menu_skip_mask = ~(
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0) |
		(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
		),
		.qmenu = h263_level,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL,
		.name = "VP8 Profile Level",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED,
		.maximum = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1,
		.default_value = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0,
		.menu_skip_mask = ~(
			(1 << V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED) |
			(1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0) |
			(1 << V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1)
		),
		.qmenu = vp8_profile_level,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE,
		.name = "MPEG2 Profile",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE,
		.maximum = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_HIGH,
		.default_value = V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE,
		.step = 1,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL,
		.name = "MPEG2 Level",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0,
		.maximum = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_3,
		.default_value = V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0,
		.step = 1,
		.menu_skip_mask = 0,
		.cluster = 0,
		.flags = V4L2_CTRL_FLAG_VOLATILE,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_SCS_THRESHOLD,
@@ -1531,6 +1692,63 @@ static int check_tz_dynamic_buffer_support(void)
	return rc;
}

static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
	int rc = 0;
	struct hfi_device *hdev;
	struct hal_profile_level profile_level;
	union hal_get_property hprop;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
		return -EINVAL;
	}

	hdev = inst->core->device;
	dprintk(VIDC_DBG, "%s ctrl->id:%x\n", __func__, ctrl->id);
	switch (ctrl->id) {
	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
	case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
	case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
	case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
		rc = msm_comm_try_get_prop(inst,
						HAL_PARAM_PROFILE_LEVEL_CURRENT,
						&hprop);
		if (rc) {
			dprintk(VIDC_ERR, "%s Error rc:%d\n", __func__, rc);
			return rc;
		}
		profile_level = hprop.profile_level;
		ctrl->val = profile_level.profile;
		dprintk(VIDC_DBG, "%s: PROFILE ctrl->id:%x ctrl->val:%d\n",
					__func__, ctrl->id, ctrl->val);
		break;
	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
	case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
		rc = msm_comm_try_get_prop(inst,
						HAL_PARAM_PROFILE_LEVEL_CURRENT,
						&hprop);
		if (rc) {
			dprintk(VIDC_ERR, "%s Error rc:%d\n", __func__, rc);
			return rc;
		}
		profile_level = hprop.profile_level;
		ctrl->val = profile_level.level;
		dprintk(VIDC_DBG, "%s: LEVEL ctrl->id:%x ctrl->val:%d\n",
					__func__, ctrl->id, ctrl->val);
		break;
	default:
		dprintk(VIDC_ERR, "%s id:%x not supported\n",
					__func__, ctrl->id);
		rc = -EINVAL;
		break;
	}
	return rc;
}

static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
	int rc = 0;
@@ -1791,7 +2009,33 @@ failed_open_done:

static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
	return 0;
	int rc = 0, c = 0;
	struct msm_vidc_inst *inst = container_of(ctrl->handler,
				struct msm_vidc_inst, ctrl_handler);
	struct v4l2_ctrl *master = ctrl->cluster[0];

	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
	if (rc) {
		dprintk(VIDC_ERR,
			"Failed to move inst: %p to start done state\n", inst);
		goto failed_open_done;
	}
	for (c = 0; c < master->ncontrols; ++c) {
		if (master->cluster[c]->id == ctrl->id) {
			rc = try_get_ctrl(inst, ctrl);
			if (rc) {
				dprintk(VIDC_ERR, "Failed getting %x",
					ctrl->id);
				return rc;
			}
		}
	}
	return rc;

failed_open_done:
	if (rc)
		dprintk(VIDC_ERR, "Failed to get hal property\n");
	return rc;
}

static const struct v4l2_ctrl_ops msm_vdec_ctrl_ops = {
@@ -1891,6 +2135,18 @@ int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
			}
		}

		switch (msm_vdec_ctrls[idx].id) {
		case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
		case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
		case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
		case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
		case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
		case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
		case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
			ctrl->flags |= msm_vdec_ctrls[idx].flags;
			break;
		}

		ret_val = inst->ctrl_handler.error;
		if (ret_val) {
			dprintk(VIDC_ERR,
+2 −0
Original line number Diff line number Diff line
@@ -1143,6 +1143,7 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_LIST_HEAD(&inst->ctrl_clusters);
	INIT_LIST_HEAD(&inst->registered_bufs);
	INIT_LIST_HEAD(&inst->outputbufs);
	INIT_LIST_HEAD(&inst->pending_getpropq);
	init_waitqueue_head(&inst->kernel_event_queue);
	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
	inst->core = core;
@@ -1269,6 +1270,7 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
		mutex_unlock(&inst->lock);
		msm_smem_delete_client(inst->mem_client);
		debugfs_remove_recursive(inst->debugfs_root);
		WARN_ON(!list_empty(&inst->pending_getpropq));
	}
}

Loading