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

Commit 94f4085e authored by Praneeth Paladugu's avatar Praneeth Paladugu
Browse files

msm: vidc: Add support for encoder rotation



Venus FW supports rotation. Driver sets the rotation
angle and updated height and width. Rotation support
added for Venus based chips.

Change-Id: I874673d71cc0deeb9d9db03a7099b435dc191eb1
Signed-off-by: default avatarPraneeth Paladugu <ppaladug@codeaurora.org>
parent a650b745
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -1175,7 +1175,50 @@ int create_pkt_cmd_session_set_property(
		break;
	}
	case HAL_CONFIG_VPE_OPERATIONS:
	{
		struct hfi_operations_type *hfi;
		struct hal_operations *prop =
			(struct hal_operations *) pdata;
		pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_VPE_OPERATIONS;
		hfi = (struct hfi_operations_type *) &pkt->rg_property_data[1];
		switch (prop->rotate) {
		case HAL_ROTATE_NONE:
			hfi->rotation = HFI_ROTATE_NONE;
			break;
		case HAL_ROTATE_90:
			hfi->rotation = HFI_ROTATE_90;
			break;
		case HAL_ROTATE_180:
			hfi->rotation = HFI_ROTATE_180;
			break;
		case HAL_ROTATE_270:
			hfi->rotation = HFI_ROTATE_270;
			break;
		default:
			dprintk(VIDC_ERR, "Invalid rotation setting: 0x%x",
				prop->rotate);
			rc = -EINVAL;
			break;
		}
		switch (prop->flip) {
		case HAL_FLIP_NONE:
			hfi->flip = HFI_FLIP_NONE;
			break;
		case HAL_FLIP_HORIZONTAL:
			hfi->flip = HFI_FLIP_HORIZONTAL;
			break;
		case HAL_FLIP_VERTICAL:
			hfi->flip = HFI_FLIP_VERTICAL;
			break;
		default:
			dprintk(VIDC_ERR, "Invalid flip setting: 0x%x",
				prop->flip);
			rc = -EINVAL;
			break;
		}
		pkt->size += sizeof(u32) + sizeof(struct hfi_operations_type);
		break;
	}
	case HAL_PARAM_VENC_INTRA_REFRESH:
	{
		struct hfi_intra_refresh *hfi;
+53 −1
Original line number Diff line number Diff line
@@ -1240,6 +1240,19 @@ static inline int venc_v4l2_to_hal(int id, int value)
		default:
			goto unknown_value;
		}
	case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
		switch (value) {
		case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE:
			return HAL_ROTATE_NONE;
		case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90:
			return HAL_ROTATE_90;
		case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180:
			return HAL_ROTATE_180;
		case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270:
			return HAL_ROTATE_270;
		default:
			goto unknown_value;
		}
	}

unknown_value:
@@ -1558,9 +1571,19 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		pdata = &profile_level;
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
		if (!(inst->capability.pixelprocess_capabilities &
			HAL_VIDEO_ENCODER_ROTATION_CAPABILITY)) {
			dprintk(VIDC_ERR, "Rotation not supported: 0x%x",
				ctrl->id);
			rc = -ENOTSUPP;
			break;
		}
		property_id =
			HAL_CONFIG_VPE_OPERATIONS;
		operations.rotate = ctrl->val;
		operations.rotate = venc_v4l2_to_hal(
				V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
				ctrl->val);
		operations.flip = HAL_FLIP_NONE;
		pdata = &operations;
		break;
	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: {
@@ -1936,8 +1959,16 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
{

	int rc = 0, c = 0;
	struct hfi_device *hdev;

	struct msm_vidc_inst *inst = container_of(ctrl->handler,
					struct msm_vidc_inst, ctrl_handler);

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

	rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);

	if (rc) {
@@ -1946,6 +1977,10 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
		goto failed_open_done;
	}

	hdev = inst->core->device;
	inst->capability.pixelprocess_capabilities =
		call_hfi_op(hdev, get_core_capabilities);

	for (c = 0; c < ctrl->ncontrols; ++c) {
		if (ctrl->cluster[c]->is_new) {
			struct v4l2_ctrl *temp = ctrl->cluster[c];
@@ -1993,6 +2028,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
	inst->prop.height = DEFAULT_HEIGHT;
	inst->prop.width = DEFAULT_WIDTH;
	inst->prop.fps = 15;
	inst->capability.pixelprocess_capabilities = 0;
	return rc;
}

@@ -2188,6 +2224,8 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
			rc = -EINVAL;
			goto exit;
		}
		inst->prop.width = f->fmt.pix_mp.width;
		inst->prop.height = f->fmt.pix_mp.height;
	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		struct hal_uncompressed_format_select hal_fmt = {0};
		struct hal_frame_size frame_sz;
@@ -2264,11 +2302,25 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
		}
		inst->fmts[fmt->type] = fmt;
		if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
			struct hal_frame_size frame_sz;
			rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
			if (rc) {
				dprintk(VIDC_ERR, "Failed to open instance\n");
				goto exit;
			}
			inst->capability.pixelprocess_capabilities =
				call_hfi_op(hdev, get_core_capabilities);
			frame_sz.width = inst->prop.width;
			frame_sz.height = inst->prop.height;
			frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
			rc = call_hfi_op(hdev, session_set_property,
				(void *)inst->session, HAL_PARAM_FRAME_SIZE,
				&frame_sz);
			if (rc) {
				dprintk(VIDC_ERR,
					"Failed to set OUTPUT framesize\n");
				goto exit;
			}
		}
	} else {
		dprintk(VIDC_ERR, "Buf type not recognized, type = %d\n",
+1 −0
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ struct msm_vidc_core_capability {
	struct hal_capability_supported width;
	struct hal_capability_supported height;
	struct hal_capability_supported frame_rate;
	u32 pixelprocess_capabilities;
	u32 capability_set;
};

+9 −0
Original line number Diff line number Diff line
@@ -3288,6 +3288,14 @@ int venus_hfi_get_stride_scanline(int color_fmt,
	return 0;
}

int venus_hfi_get_core_capabilities(void)
{
	return HAL_VIDEO_ENCODER_ROTATION_CAPABILITY |
		HAL_VIDEO_ENCODER_SCALING_CAPABILITY |
		HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY |
		HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY;
}

int venus_hfi_capability_check(u32 fourcc, u32 width,
		u32 *max_width, u32 *max_height)
{
@@ -3460,6 +3468,7 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev)
	hdev->get_fw_info = venus_hfi_get_fw_info;
	hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
	hdev->capability_check = venus_hfi_capability_check;
	hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
}

int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
+9 −0
Original line number Diff line number Diff line
@@ -188,6 +188,14 @@ enum hal_domain {
	HAL_UNUSED_DOMAIN = 0x10000000,
};

enum hal_core_capabilities {
	HAL_VIDEO_ENCODER_ROTATION_CAPABILITY = 0x00000001,
	HAL_VIDEO_ENCODER_SCALING_CAPABILITY = 0x00000002,
	HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY = 0x00000004,
	HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY = 0x00000008,
	HAL_VIDEO_UNUSED_CAPABILITY      = 0x10000000,
};

enum hal_video_codec {
	HAL_VIDEO_CODEC_UNKNOWN  = 0x00000000,
	HAL_VIDEO_CODEC_MVC      = 0x00000001,
@@ -1110,6 +1118,7 @@ struct hfi_device {
	int (*capability_check)(u32 fourcc, u32 width,
		u32 *max_width, u32 *max_height);
	int (*session_clean)(void *sess);
	int (*get_core_capabilities)(void);
};

typedef void (*hfi_cmd_response_callback) (enum command_response cmd,
Loading