Commit 49a940f3 authored by Wangao Wang's avatar Wangao Wang Committed by Hans Verkuil
Browse files

media: qcom: iris: Add rotation support for encoder



Add rotation control for encoder, enabling V4L2_CID_ROTATE and handling
 90/180/270 degree rotation.

Reviewed-by: default avatarDikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
Co-developed-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Signed-off-by: default avatarWangao Wang <wangao.wang@oss.qualcomm.com>
Signed-off-by: default avatarBryan O'Donoghue <bod@kernel.org>
Signed-off-by: default avatarHans Verkuil <hverkuil+cisco@kernel.org>
parent 121d6d7a
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
		return PROFILE_AV1;
	case V4L2_CID_MPEG_VIDEO_AV1_LEVEL:
		return LEVEL_AV1;
	case V4L2_CID_ROTATE:
		return ROTATION;
	default:
		return INST_FW_CAP_MAX;
	}
@@ -193,6 +195,8 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
		return V4L2_CID_MPEG_VIDEO_AV1_PROFILE;
	case LEVEL_AV1:
		return V4L2_CID_MPEG_VIDEO_AV1_LEVEL;
	case ROTATION:
		return V4L2_CID_ROTATE;
	default:
		return 0;
	}
@@ -901,6 +905,36 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
				     &range, sizeof(range));
}

int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
{
	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
	u32 hfi_val;

	switch (inst->fw_caps[cap_id].value) {
	case 0:
		hfi_val = HFI_ROTATION_NONE;
		return 0;
	case 90:
		hfi_val = HFI_ROTATION_90;
		break;
	case 180:
		hfi_val = HFI_ROTATION_180;
		break;
	case 270:
		hfi_val = HFI_ROTATION_270;
		break;
	default:
		return -EINVAL;
	}

	return hfi_ops->session_set_property(inst, hfi_id,
					     HFI_HOST_FLAGS_NONE,
					     iris_get_port_info(inst, cap_id),
					     HFI_PAYLOAD_U32,
					     &hfi_val, sizeof(u32));
}

int iris_set_properties(struct iris_inst *inst, u32 plane)
{
	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_i
int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_properties(struct iris_inst *inst, u32 plane);

#endif
+31 −10
Original line number Diff line number Diff line
@@ -182,22 +182,36 @@ static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
						  sizeof(u32));
}

static inline u32 iris_hfi_get_aligned_resolution(struct iris_inst *inst, u32 width, u32 height)
{
	u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;

	return (ALIGN(width, codec_align) << 16 | ALIGN(height, codec_align));
}

static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
{
	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
	u32 port = iris_hfi_gen2_get_port(inst, plane);
	enum hfi_packet_payload_info payload_type;
	u32 resolution, codec_align;
	u32 width, height;
	u32 resolution;

	if (inst->domain == DECODER) {
		resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
			inst->fmt_src->fmt.pix_mp.height;
		width = inst->fmt_src->fmt.pix_mp.width;
		height = inst->fmt_src->fmt.pix_mp.height;
		resolution = iris_hfi_get_aligned_resolution(inst, width, height);
		inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
		payload_type = HFI_PAYLOAD_U32;
	} else {
		codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
		resolution = ALIGN(inst->enc_scale_width, codec_align) << 16 |
			ALIGN(inst->enc_scale_height, codec_align);
		if (is_rotation_90_or_270(inst)) {
			width = inst->enc_scale_height;
			height = inst->enc_scale_width;
		} else {
			width = inst->enc_scale_width;
			height = inst->enc_scale_height;
		}
		resolution = iris_hfi_get_aligned_resolution(inst, width, height);
		inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
		payload_type = HFI_PAYLOAD_32_PACKED;
	}
@@ -238,11 +252,18 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
			right_offset = (inst->enc_raw_width - inst->crop.width);
			left_offset = inst->crop.left;
			top_offset = inst->crop.top;
		} else {
			if (is_rotation_90_or_270(inst)) {
				bottom_offset = (ALIGN(inst->enc_scale_width, codec_align) -
						inst->enc_scale_width);
				right_offset = (ALIGN(inst->enc_scale_height, codec_align) -
					       inst->enc_scale_height);
			} else {
				bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) -
						inst->enc_scale_height);
				right_offset = (ALIGN(inst->enc_scale_width, codec_align) -
					       inst->enc_scale_width);
			}
			left_offset = 0;
			top_offset = 0;
		}
+9 −0
Original line number Diff line number Diff line
@@ -83,6 +83,15 @@ enum hfi_seq_header_mode {
};

#define HFI_PROP_SEQ_HEADER_MODE		0x03000149

enum hfi_rotation {
	HFI_ROTATION_NONE = 0x00000000,
	HFI_ROTATION_90   = 0x00000001,
	HFI_ROTATION_180  = 0x00000002,
	HFI_ROTATION_270  = 0x00000003,
};

#define HFI_PROP_ROTATION			0x0300014b
#define HFI_PROP_SIGNAL_COLOR_INFO		0x03000155
#define HFI_PROP_PICTURE_TYPE			0x03000162
#define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
+1 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ enum platform_inst_fw_cap_type {
	P_FRAME_QP_HEVC,
	B_FRAME_QP_H264,
	B_FRAME_QP_HEVC,
	ROTATION,
	INST_FW_CAP_MAX,
};

Loading