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

Commit c2390126 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: Allow decoder clients to query entropy"

parents 4c2755d9 4a13630c
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -921,6 +921,9 @@ int create_pkt_cmd_session_get_property(
		pkt->rg_property_data[0] =
			HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
		break;
	case HAL_CONFIG_VDEC_ENTROPY:
		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_VDEC_ENTROPY;
		break;
	default:
		dprintk(VIDC_ERR, "%s cmd:%#x not supported\n", __func__,
			ptype);
+35 −0
Original line number Diff line number Diff line
@@ -727,6 +727,27 @@ enum vidc_status hfi_process_sess_init_done_prop_read(
	return status;
}

static void hfi_process_sess_get_prop_dec_entropy(
	struct hfi_msg_session_property_info_packet *prop,
	enum hal_h264_entropy *entropy)
{
	u32 req_bytes, hfi_entropy;

	req_bytes = prop->size - sizeof(
			struct hfi_msg_session_property_info_packet);

	if (!req_bytes || req_bytes % sizeof(hfi_entropy)) {
		dprintk(VIDC_ERR, "%s: bad packet: %d\n", __func__, req_bytes);
		return;
	}

	hfi_entropy = prop->rg_property_data[1];
	*entropy =
		hfi_entropy == HFI_H264_ENTROPY_CAVLC ? HAL_H264_ENTROPY_CAVLC :
		hfi_entropy == HFI_H264_ENTROPY_CABAC ? HAL_H264_ENTROPY_CABAC :
							HAL_UNUSED_ENTROPY;
}

static void hfi_process_sess_get_prop_profile_level(
	struct hfi_msg_session_property_info_packet *prop,
	struct hfi_profile_level *profile_level)
@@ -884,6 +905,7 @@ static int hfi_process_session_prop_info(u32 device_id,
{
	struct msm_vidc_cb_cmd_done cmd_done = {0};
	struct hfi_profile_level profile_level = {0};
	enum hal_h264_entropy entropy;
	struct buffer_requirements buff_req = { { {0} } };

	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%#x]\n",
@@ -926,6 +948,19 @@ static int hfi_process_session_prop_info(u32 device_id,
			};
		cmd_done.size = sizeof(struct hal_profile_level);

		*info = (struct msm_vidc_cb_info) {
			.response_type =  HAL_SESSION_PROPERTY_INFO,
			.response.cmd = cmd_done,
		};
		return 0;
	case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
		hfi_process_sess_get_prop_dec_entropy(pkt, &entropy);
		cmd_done.device_id = device_id;
		cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
		cmd_done.status = VIDC_ERR_NONE;
		cmd_done.data.property.h264_entropy = entropy;
		cmd_done.size = sizeof(enum hal_h264_entropy);

		*info = (struct msm_vidc_cb_info) {
			.response_type =  HAL_SESSION_PROPERTY_INFO,
			.response.cmd = cmd_done,
+153 −44
Original line number Diff line number Diff line
@@ -130,6 +130,10 @@ static const char *const mpeg2_level[] = {
	"2",
	"3",
};
static const char *const mpeg_vidc_video_entropy_mode[] = {
	"CAVLC Entropy Mode",
	"CABAC Entropy Mode",
};

static const char *const mpeg_vidc_video_h264_mvc_layout[] = {
	"Frame packing arrangement sequential",
@@ -576,7 +580,22 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
		.maximum = V4L2_VIDC_QBUF_BATCHED,
		.default_value = V4L2_VIDC_QBUF_STANDARD,
		.step = 1,
	}
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
		.name = "Entropy Mode",
		.type = V4L2_CTRL_TYPE_MENU,
		.minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
		.maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
		.default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
		.step = 0,
		.menu_skip_mask = ~(
		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
		(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
		),
		.qmenu = mpeg_vidc_video_entropy_mode,
		.flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
	},
};

#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
@@ -585,6 +604,7 @@ static int set_buffer_size(struct msm_vidc_inst *inst,
				u32 buffer_size, enum hal_buffer buffer_type);
static int update_output_buffer_size(struct msm_vidc_inst *inst,
		struct v4l2_format *f, int num_planes);
static int vdec_hal_to_v4l2(int id, int value);

static u32 get_frame_size_nv12(int plane,
					u32 height, u32 width)
@@ -1941,16 +1961,21 @@ 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) {
	if (!inst || !inst->core || !inst->core->device || !ctrl) {
		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
		return -EINVAL;
	}

	hdev = inst->core->device;
	dprintk(VIDC_DBG, "%s ctrl->id:%x\n", __func__, ctrl->id);
	/*
	 * HACK: unlock the control prior to querying the hardware.  Otherwise
	 * lower level code that attempts to do g_ctrl() will end up deadlocking
	 * us.
	 */
	v4l2_ctrl_unlock(ctrl);

	switch (ctrl->id) {
	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
@@ -1958,51 +1983,62 @@ static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	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);
				HAL_PARAM_PROFILE_LEVEL_CURRENT, &hprop);
		if (rc) {
			dprintk(VIDC_ERR, "%s Error rc:%d\n", __func__, rc);
			return rc;
			dprintk(VIDC_ERR, "%s: Failed getting profile: %d",
					__func__, rc);
			break;
		}
		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);
		ctrl->val = vdec_hal_to_v4l2(ctrl->id,
				hprop.profile_level.profile);
		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);
				HAL_PARAM_PROFILE_LEVEL_CURRENT, &hprop);
		if (rc) {
			dprintk(VIDC_ERR, "%s Error rc:%d\n", __func__, rc);
			return rc;
			dprintk(VIDC_ERR, "%s: Failed getting level: %d",
					__func__, rc);
			break;
		}
		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);

		ctrl->val = vdec_hal_to_v4l2(ctrl->id,
				hprop.profile_level.level);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD:
		if (!(inst->flags & VIDC_SECURE) ||
			!inst->capability.secure_output2_threshold.max) {
			dprintk(VIDC_ERR, "%s id:%x invalid configuration\n",
					__func__, ctrl->id);
			rc = -EINVAL;
			break;
		}
		dprintk(VIDC_DBG,
				"Secure Scaling Threshold is : %d",
		dprintk(VIDC_DBG, "Secure scaling threshold is: %d",
				inst->capability.secure_output2_threshold.max);
		ctrl->val = inst->capability.secure_output2_threshold.max;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
		rc = msm_comm_try_get_prop(inst,
				HAL_CONFIG_VDEC_ENTROPY, &hprop);
		if (rc) {
			dprintk(VIDC_ERR, "%s: Failed getting entropy type: %d",
					__func__, rc);
			break;
		}
		switch (hprop.h264_entropy) {
		case HAL_H264_ENTROPY_CAVLC:
			ctrl->val = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
			break;
		case HAL_H264_ENTROPY_CABAC:
			ctrl->val = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
			break;
		case HAL_UNUSED_ENTROPY:
			rc = -ENOTSUPP;
			break;
		}
		break;
	default:
		dprintk(VIDC_DBG, "%s id:%x not supported\n",
					__func__, ctrl->id);
		/* Other controls aren't really volatile, shouldn't need to
		 * modify ctrl->value */
		break;
	}
	v4l2_ctrl_lock(ctrl);

	return rc;
}

@@ -2076,6 +2112,91 @@ unknown_value:
	return -EINVAL;
}

static int vdec_hal_to_v4l2(int id, int value)
{
	switch (id) {
		/* H264 */
	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
		switch (value) {
		case HAL_H264_PROFILE_BASELINE:
			return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
		case HAL_H264_PROFILE_CONSTRAINED_BASE:
			return
			V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
		case HAL_H264_PROFILE_MAIN:
			return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
		case HAL_H264_PROFILE_EXTENDED:
			return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
		case HAL_H264_PROFILE_HIGH:
			return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
		case HAL_H264_PROFILE_HIGH10:
			return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
		case HAL_H264_PROFILE_HIGH422:
			return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
		case HAL_H264_PROFILE_HIGH444:
			return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
		default:
			goto unknown_value;
		}
	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
		switch (value) {
		case HAL_H264_LEVEL_1:
			return V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
		case HAL_H264_LEVEL_1b:
			return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
		case HAL_H264_LEVEL_11:
			return V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
		case HAL_H264_LEVEL_12:
			return V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
		case HAL_H264_LEVEL_13:
			return V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
		case HAL_H264_LEVEL_2:
			return V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
		case HAL_H264_LEVEL_21:
			return V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
		case HAL_H264_LEVEL_22:
			return V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
		case HAL_H264_LEVEL_3:
			return V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
		case HAL_H264_LEVEL_31:
			return V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
		case HAL_H264_LEVEL_32:
			return V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
		case HAL_H264_LEVEL_4:
			return V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
		case HAL_H264_LEVEL_41:
			return V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
		case HAL_H264_LEVEL_42:
			return V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
		case HAL_H264_LEVEL_5:
			return V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
		case HAL_H264_LEVEL_51:
			return V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
		default:
			goto unknown_value;
		}
	case V4L2_CID_MPEG_VIDEO_MPEG4_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:
	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
	case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
	case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
		/*
		 * Extremely dirty hack: we haven't implemented g_ctrl of
		 * any of these controls and have no intention of doing
		 * so in the near future.  So just return 0 so that we
		 * don't see the annoying "Unknown control" errors at the
		 * bottom of this function.
		 */
		return 0;
	}

unknown_value:
	dprintk(VIDC_WARN, "Unknown control (%x, %d)\n", id, value);
	return -EINVAL;
}

static struct v4l2_ctrl *get_ctrl_from_cluster(int id,
		struct v4l2_ctrl **cluster, int ncontrols)
{
@@ -2696,19 +2817,6 @@ int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
			return -EINVAL;
		}

		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:
		case V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD:
			ctrl->flags |= msm_vdec_ctrls[idx].flags;
			break;
		}

		ret_val = inst->ctrl_handler.error;
		if (ret_val) {
			dprintk(VIDC_ERR,
@@ -2718,6 +2826,7 @@ int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
			return ret_val;
		}

		ctrl->flags |= msm_vdec_ctrls[idx].flags;
		inst->ctrls[idx] = ctrl;
	}

+29 −27
Original line number Diff line number Diff line
@@ -3566,47 +3566,48 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
		return -EINVAL;
	}

	if (inst->state == MSM_VIDC_CORE_INVALID ||
			inst->core->state == VIDC_CORE_INVALID) {
		dprintk(VIDC_ERR,
			"Core is in bad state can't query get_bufreqs()\n");
		return -EAGAIN;
	}
	hdev = inst->core->device;
	mutex_lock(&inst->sync_lock);
	if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
	if (inst->state < MSM_VIDC_OPEN_DONE ||
			inst->state >= MSM_VIDC_CLOSE) {

		/* No need to check inst->state == MSM_VIDC_INVALID since
		 * INVALID is > CLOSE_DONE. When core went to INVALID state,
		 * we put all the active instances in INVALID. So > CLOSE_DONE
		 * is enough check to have.
		 */

		dprintk(VIDC_ERR,
			"%s Not in proper state\n", __func__);
			"In Wrong state to call Buf Req: Inst %p or Core %p\n",
				inst, inst->core);
		rc = -EAGAIN;
		mutex_unlock(&inst->sync_lock);
		goto exit;
	}
	mutex_unlock(&inst->sync_lock);

	init_completion(&inst->completions[
			SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)]);
	switch (ptype) {
	case HAL_PARAM_PROFILE_LEVEL_CURRENT:
		rc = call_hfi_op(hdev, session_get_property,
					(void *) inst->session, ptype);
		if (rc) {
			dprintk(VIDC_ERR, "%s Failed: PROFILE_LEVEL_INFO\n",
						__func__);
			rc = -EAGAIN;
			goto exit;
		}
	case HAL_CONFIG_VDEC_ENTROPY:
		rc = call_hfi_op(hdev, session_get_property, inst->session,
				ptype);
		break;
	case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
		rc = call_hfi_op(hdev, session_get_buf_req,
						(void *) inst->session);
		if (rc) {
			dprintk(VIDC_ERR, "Failed to get property\n");
			rc = -EAGAIN;
			goto exit;
		}
		rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
		break;
	default:
		rc = -EAGAIN;
		dprintk(VIDC_ERR, "%s id:%d not supported\n", __func__, ptype);
		break;
	}

	if (rc) {
		dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
				rc);
		goto exit;
	}

	rc = wait_for_completion_timeout(&inst->completions[
			SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
@@ -3617,8 +3618,11 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
			SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
		inst->state = MSM_VIDC_CORE_INVALID;
		msm_comm_kill_session(inst);
		rc = -EIO;
		rc = -ETIMEDOUT;
		goto exit;
	} else {
		/* wait_for_completion_timeout returns jiffies before expiry */
		rc = 0;
	}

	mutex_lock(&inst->pending_getpropq.lock);
@@ -3629,14 +3633,12 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
		kfree(buf->data);
		list_del(&buf->list);
		kfree(buf);
		rc = 0;
	} else {
		dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
		rc = -EINVAL;
	}
	mutex_unlock(&inst->pending_getpropq.lock);
exit:
	mutex_unlock(&inst->sync_lock);
	return rc;
}

+3 −1
Original line number Diff line number Diff line
@@ -220,13 +220,15 @@ struct hfi_extradata_header {
	(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001C)

#define HFI_PROPERTY_CONFIG_VDEC_OX_START				\
	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000)
	(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000)
#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER	\
	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x001)
#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING	\
	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x002)
#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP			\
	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x003)
#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY \
	(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x004)

#define HFI_PROPERTY_PARAM_VENC_OX_START				\
	(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x5000)
Loading