Commit 1b4420bd authored by Jackson.lee's avatar Jackson.lee Committed by Hans Verkuil
Browse files

media: chips-media: wave5: Support YUV422 raw pixel-formats on the encoder.



Add support for the YUV422P, NV16, NV61, YUV422M, NV16M,
NV61M raw pixel-formats to the Wave5 encoder.

All these formats have a chroma subsampling ratio of 4:2:2 and
therefore require a new image size calculation as the driver
previously only handled a ratio of 4:2:0.

Signed-off-by: default avatarJackson.lee <jackson.lee@chipsnmedia.com>
Signed-off-by: default avatarNas Chung <nas.chung@chipsnmedia.com>
Reviewed-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: default avatarSebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 88ff31fd
Loading
Loading
Loading
Loading
+74 −15
Original line number Diff line number Diff line
@@ -66,6 +66,30 @@ static const struct vpu_format enc_fmt_list[FMT_TYPES][MAX_FMTS] = {
			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21M,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422P,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422M,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16M,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
		{
			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61M,
			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
		},
	}
};

@@ -109,13 +133,26 @@ static int start_encode(struct vpu_instance *inst, u32 *fail_res)
	struct vb2_v4l2_buffer *dst_buf;
	struct frame_buffer frame_buf;
	struct enc_param pic_param;
	u32 stride = ALIGN(inst->dst_fmt.width, 32);
	u32 luma_size = (stride * inst->dst_fmt.height);
	u32 chroma_size = ((stride / 2) * (inst->dst_fmt.height / 2));
	const struct v4l2_format_info *info;
	u32 stride = inst->src_fmt.plane_fmt[0].bytesperline;
	u32 luma_size = 0;
	u32 chroma_size = 0;

	memset(&pic_param, 0, sizeof(struct enc_param));
	memset(&frame_buf, 0, sizeof(struct frame_buffer));

	info = v4l2_format_info(inst->src_fmt.pixelformat);
	if (!info)
		return -EINVAL;

	if (info->mem_planes == 1) {
		luma_size = stride * inst->dst_fmt.height;
		chroma_size = luma_size / (info->hdiv * info->vdiv);
	} else {
		luma_size = inst->src_fmt.plane_fmt[0].sizeimage;
		chroma_size = inst->src_fmt.plane_fmt[1].sizeimage;
	}

	dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx);
	if (!dst_buf) {
		dev_dbg(inst->dev->dev, "%s: No destination buffer found\n", __func__);
@@ -480,6 +517,7 @@ static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_form
{
	struct vpu_instance *inst = wave5_to_vpu_inst(fh);
	const struct vpu_format *vpu_fmt;
	const struct v4l2_format_info *info;
	int i, ret;

	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
@@ -501,16 +539,20 @@ static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_form
		inst->src_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
	}

	if (inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
	    inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV12M) {
		inst->cbcr_interleave = true;
		inst->nv21 = false;
	} else if (inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
		   inst->src_fmt.pixelformat == V4L2_PIX_FMT_NV21M) {
		inst->cbcr_interleave = true;
	info = v4l2_format_info(inst->src_fmt.pixelformat);
	if (!info)
		return -EINVAL;

	inst->cbcr_interleave = (info->comp_planes == 2) ? true : false;

	switch (inst->src_fmt.pixelformat) {
	case V4L2_PIX_FMT_NV21:
	case V4L2_PIX_FMT_NV21M:
	case V4L2_PIX_FMT_NV61:
	case V4L2_PIX_FMT_NV61M:
		inst->nv21 = true;
	} else {
		inst->cbcr_interleave = false;
		break;
	default:
		inst->nv21 = false;
	}

@@ -1095,13 +1137,23 @@ static void wave5_vpu_enc_buf_queue(struct vb2_buffer *vb)
	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
}

static void wave5_set_enc_openparam(struct enc_open_param *open_param,
static int wave5_set_enc_openparam(struct enc_open_param *open_param,
				   struct vpu_instance *inst)
{
	struct enc_wave_param input = inst->enc_param;
	const struct v4l2_format_info *info;
	u32 num_ctu_row = ALIGN(inst->dst_fmt.height, 64) / 64;
	u32 num_mb_row = ALIGN(inst->dst_fmt.height, 16) / 16;

	info = v4l2_format_info(inst->src_fmt.pixelformat);
	if (!info)
		return -EINVAL;

	if (info->hdiv == 2 && info->vdiv == 1)
		open_param->src_format = FORMAT_422;
	else
		open_param->src_format = FORMAT_420;

	open_param->wave_param.gop_preset_idx = PRESET_IDX_IPP_SINGLE;
	open_param->wave_param.hvs_qp_scale = 2;
	open_param->wave_param.hvs_max_delta_qp = 10;
@@ -1190,6 +1242,8 @@ static void wave5_set_enc_openparam(struct enc_open_param *open_param,
			open_param->wave_param.intra_refresh_arg = num_ctu_row;
	}
	open_param->wave_param.forced_idr_header_enable = input.forced_idr_header_enable;

	return 0;
}

static int initialize_sequence(struct vpu_instance *inst)
@@ -1285,7 +1339,12 @@ static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count

		memset(&open_param, 0, sizeof(struct enc_open_param));

		wave5_set_enc_openparam(&open_param, inst);
		ret = wave5_set_enc_openparam(&open_param, inst);
		if (ret) {
			dev_dbg(inst->dev->dev, "%s: wave5_set_enc_openparam, fail: %d\n",
				__func__, ret);
			goto return_buffers;
		}

		ret = wave5_vpu_enc_open(inst, &open_param);
		if (ret) {