brintos

brintos / linux-shallow public Read only

0
0
Text · 35.1 KiB · 351b4ed Raw
1348 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2020-2021 NXP4 */5 6#include <linux/init.h>7#include <linux/interconnect.h>8#include <linux/ioctl.h>9#include <linux/list.h>10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/delay.h>13#include <linux/videodev2.h>14#include <linux/ktime.h>15#include <linux/rational.h>16#include <linux/vmalloc.h>17#include <media/v4l2-device.h>18#include <media/v4l2-event.h>19#include <media/v4l2-mem2mem.h>20#include <media/v4l2-ioctl.h>21#include <media/videobuf2-v4l2.h>22#include <media/videobuf2-dma-contig.h>23#include <media/videobuf2-vmalloc.h>24#include "vpu.h"25#include "vpu_defs.h"26#include "vpu_core.h"27#include "vpu_helpers.h"28#include "vpu_v4l2.h"29#include "vpu_cmds.h"30#include "vpu_rpc.h"31 32#define VENC_OUTPUT_ENABLE	BIT(0)33#define VENC_CAPTURE_ENABLE	BIT(1)34#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)35#define VENC_MAX_BUF_CNT	836#define VENC_MIN_BUFFER_OUT	637#define VENC_MIN_BUFFER_CAP	638 39struct venc_t {40	struct vpu_encode_params params;41	u32 request_key_frame;42	u32 input_ready;43	u32 cpb_size;44	bool bitrate_change;45 46	struct vpu_buffer enc[VENC_MAX_BUF_CNT];47	struct vpu_buffer ref[VENC_MAX_BUF_CNT];48	struct vpu_buffer act[VENC_MAX_BUF_CNT];49	struct list_head frames;50	u32 frame_count;51	u32 encode_count;52	u32 ready_count;53	u32 enable;54	u32 stopped;55 56	u32 skipped_count;57	u32 skipped_bytes;58 59	wait_queue_head_t wq;60};61 62struct venc_frame_t {63	struct list_head list;64	struct vpu_enc_pic_info info;65	u32 bytesused;66	s64 timestamp;67};68 69static const struct vpu_format venc_formats[] = {70	{71		.pixfmt = V4L2_PIX_FMT_NV12M,72		.mem_planes = 2,73		.comp_planes = 2,74		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,75		.sibling = V4L2_PIX_FMT_NV12,76	},77	{78		.pixfmt = V4L2_PIX_FMT_NV12,79		.mem_planes = 1,80		.comp_planes = 2,81		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,82		.sibling = V4L2_PIX_FMT_NV12M,83	},84	{85		.pixfmt = V4L2_PIX_FMT_H264,86		.mem_planes = 1,87		.comp_planes = 1,88		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,89		.flags = V4L2_FMT_FLAG_COMPRESSED90	},91	{0, 0, 0, 0},92};93 94static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)95{96	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));97	strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));98	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));99 100	return 0;101}102 103static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)104{105	struct vpu_inst *inst = to_inst(file);106	const struct vpu_format *fmt;107 108	memset(f->reserved, 0, sizeof(f->reserved));109	fmt = vpu_helper_enum_format(inst, f->type, f->index);110	if (!fmt)111		return -EINVAL;112 113	f->pixelformat = fmt->pixfmt;114	f->flags = fmt->flags;115 116	return 0;117}118 119static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)120{121	struct vpu_inst *inst = to_inst(file);122	const struct vpu_core_resources *res;123 124	if (!fsize || fsize->index)125		return -EINVAL;126 127	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))128		return -EINVAL;129 130	res = vpu_get_resource(inst);131	if (!res)132		return -EINVAL;133	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;134	fsize->stepwise.max_width = res->max_width;135	fsize->stepwise.max_height = res->max_height;136	fsize->stepwise.min_width = res->min_width;137	fsize->stepwise.min_height = res->min_height;138	fsize->stepwise.step_width = res->step_width;139	fsize->stepwise.step_height = res->step_height;140 141	return 0;142}143 144static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)145{146	struct vpu_inst *inst = to_inst(file);147	const struct vpu_core_resources *res;148 149	if (!fival || fival->index)150		return -EINVAL;151 152	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))153		return -EINVAL;154 155	if (!fival->width || !fival->height)156		return -EINVAL;157 158	res = vpu_get_resource(inst);159	if (!res)160		return -EINVAL;161	if (fival->width < res->min_width || fival->width > res->max_width ||162	    fival->height < res->min_height || fival->height > res->max_height)163		return -EINVAL;164 165	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;166	fival->stepwise.min.numerator = 1;167	fival->stepwise.min.denominator = USHRT_MAX;168	fival->stepwise.max.numerator = USHRT_MAX;169	fival->stepwise.max.denominator = 1;170	fival->stepwise.step.numerator = 1;171	fival->stepwise.step.denominator = 1;172 173	return 0;174}175 176static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)177{178	struct vpu_inst *inst = to_inst(file);179	struct venc_t *venc = inst->priv;180	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;181	struct vpu_format *cur_fmt;182	int i;183 184	cur_fmt = vpu_get_format(inst, f->type);185 186	pixmp->pixelformat = cur_fmt->pixfmt;187	pixmp->num_planes = cur_fmt->mem_planes;188	pixmp->width = cur_fmt->width;189	pixmp->height = cur_fmt->height;190	pixmp->field = cur_fmt->field;191	pixmp->flags = cur_fmt->flags;192	for (i = 0; i < pixmp->num_planes; i++) {193		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];194		pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i);195	}196 197	f->fmt.pix_mp.colorspace = venc->params.color.primaries;198	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;199	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;200	f->fmt.pix_mp.quantization = venc->params.color.full_range;201 202	return 0;203}204 205static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)206{207	struct vpu_inst *inst = to_inst(file);208	struct vpu_format fmt;209 210	vpu_try_fmt_common(inst, f, &fmt);211 212	return 0;213}214 215static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)216{217	struct vpu_inst *inst = to_inst(file);218	struct vpu_format fmt;219	struct vpu_format *cur_fmt;220	struct vb2_queue *q;221	struct venc_t *venc = inst->priv;222	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;223 224	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);225	if (!q)226		return -EINVAL;227	if (vb2_is_busy(q))228		return -EBUSY;229 230	if (vpu_try_fmt_common(inst, f, &fmt))231		return -EINVAL;232 233	cur_fmt = vpu_get_format(inst, f->type);234 235	memcpy(cur_fmt, &fmt, sizeof(*cur_fmt));236 237	if (V4L2_TYPE_IS_OUTPUT(f->type)) {238		venc->params.input_format = cur_fmt->pixfmt;239		venc->params.src_stride = cur_fmt->bytesperline[0];240		venc->params.src_width = cur_fmt->width;241		venc->params.src_height = cur_fmt->height;242		venc->params.crop.left = 0;243		venc->params.crop.top = 0;244		venc->params.crop.width = cur_fmt->width;245		venc->params.crop.height = cur_fmt->height;246	} else {247		venc->params.codec_format = cur_fmt->pixfmt;248		venc->params.out_width = cur_fmt->width;249		venc->params.out_height = cur_fmt->height;250	}251 252	if (V4L2_TYPE_IS_OUTPUT(f->type)) {253		venc->params.color.primaries = pix_mp->colorspace;254		venc->params.color.transfer = pix_mp->xfer_func;255		venc->params.color.matrix = pix_mp->ycbcr_enc;256		venc->params.color.full_range = pix_mp->quantization;257	}258 259	pix_mp->colorspace = venc->params.color.primaries;260	pix_mp->xfer_func = venc->params.color.transfer;261	pix_mp->ycbcr_enc = venc->params.color.matrix;262	pix_mp->quantization = venc->params.color.full_range;263 264	return 0;265}266 267static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)268{269	struct vpu_inst *inst = to_inst(file);270	struct venc_t *venc = inst->priv;271	struct v4l2_fract *timeperframe;272 273	if (!parm)274		return -EINVAL;275 276	if (!V4L2_TYPE_IS_OUTPUT(parm->type))277		return -EINVAL;278 279	if (!vpu_helper_check_type(inst, parm->type))280		return -EINVAL;281 282	timeperframe = &parm->parm.capture.timeperframe;283	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;284	parm->parm.capture.readbuffers = 0;285	timeperframe->numerator = venc->params.frame_rate.numerator;286	timeperframe->denominator = venc->params.frame_rate.denominator;287 288	return 0;289}290 291static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)292{293	struct vpu_inst *inst = to_inst(file);294	struct venc_t *venc = inst->priv;295	struct v4l2_fract *timeperframe;296	unsigned long n, d;297 298	if (!parm)299		return -EINVAL;300 301	if (!V4L2_TYPE_IS_OUTPUT(parm->type))302		return -EINVAL;303 304	if (!vpu_helper_check_type(inst, parm->type))305		return -EINVAL;306 307	timeperframe = &parm->parm.capture.timeperframe;308	if (!timeperframe->numerator)309		timeperframe->numerator = venc->params.frame_rate.numerator;310	if (!timeperframe->denominator)311		timeperframe->denominator = venc->params.frame_rate.denominator;312 313	venc->params.frame_rate.numerator = timeperframe->numerator;314	venc->params.frame_rate.denominator = timeperframe->denominator;315 316	rational_best_approximation(venc->params.frame_rate.numerator,317				    venc->params.frame_rate.denominator,318				    venc->params.frame_rate.numerator,319				    venc->params.frame_rate.denominator,320				    &n, &d);321	venc->params.frame_rate.numerator = n;322	venc->params.frame_rate.denominator = d;323 324	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;325	memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved));326 327	return 0;328}329 330static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)331{332	struct vpu_inst *inst = to_inst(file);333	struct venc_t *venc = inst->priv;334 335	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)336		return -EINVAL;337 338	switch (s->target) {339	case V4L2_SEL_TGT_CROP_DEFAULT:340	case V4L2_SEL_TGT_CROP_BOUNDS:341		s->r.left = 0;342		s->r.top = 0;343		s->r.width = inst->out_format.width;344		s->r.height = inst->out_format.height;345		break;346	case V4L2_SEL_TGT_CROP:347		s->r = venc->params.crop;348		break;349	default:350		return -EINVAL;351	}352 353	return 0;354}355 356static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)357{358	struct v4l2_rect *rect = NULL;359	u32 min_width;360	u32 min_height;361	u32 src_width;362	u32 src_height;363 364	rect = &venc->params.crop;365	min_width = res->min_width;366	min_height = res->min_height;367	src_width = venc->params.src_width;368	src_height = venc->params.src_height;369 370	if (rect->width == 0 || rect->height == 0)371		return -EINVAL;372	if (rect->left > src_width - min_width || rect->top > src_height - min_height)373		return -EINVAL;374 375	rect->width = min(rect->width, src_width - rect->left);376	rect->width = max_t(u32, rect->width, min_width);377 378	rect->height = min(rect->height, src_height - rect->top);379	rect->height = max_t(u32, rect->height, min_height);380 381	return 0;382}383 384static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)385{386	struct vpu_inst *inst = to_inst(file);387	const struct vpu_core_resources *res;388	struct venc_t *venc = inst->priv;389 390	res = vpu_get_resource(inst);391	if (!res)392		return -EINVAL;393 394	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)395		return -EINVAL;396	if (s->target != V4L2_SEL_TGT_CROP)397		return -EINVAL;398 399	venc->params.crop.left = ALIGN(s->r.left, res->step_width);400	venc->params.crop.top = ALIGN(s->r.top, res->step_height);401	venc->params.crop.width = ALIGN(s->r.width, res->step_width);402	venc->params.crop.height = ALIGN(s->r.height, res->step_height);403	if (venc_valid_crop(venc, res)) {404		venc->params.crop.left = 0;405		venc->params.crop.top = 0;406		venc->params.crop.width = venc->params.src_width;407		venc->params.crop.height = venc->params.src_height;408	}409 410	inst->crop = venc->params.crop;411 412	return 0;413}414 415static int venc_drain(struct vpu_inst *inst)416{417	struct venc_t *venc = inst->priv;418	int ret;419 420	if (!inst->fh.m2m_ctx)421		return 0;422 423	if (inst->state != VPU_CODEC_STATE_DRAIN)424		return 0;425 426	if (!vpu_is_source_empty(inst))427		return 0;428 429	if (!venc->input_ready)430		return 0;431 432	venc->input_ready = false;433	vpu_trace(inst->dev, "[%d]\n", inst->id);434	ret = vpu_session_stop(inst);435	if (ret)436		return ret;437	inst->state = VPU_CODEC_STATE_STOP;438	wake_up_all(&venc->wq);439 440	return 0;441}442 443static int venc_request_eos(struct vpu_inst *inst)444{445	inst->state = VPU_CODEC_STATE_DRAIN;446	venc_drain(inst);447 448	return 0;449}450 451static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)452{453	struct vpu_inst *inst = to_inst(file);454	int ret;455 456	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);457	if (ret)458		return ret;459 460	vpu_inst_lock(inst);461	if (cmd->cmd == V4L2_ENC_CMD_STOP) {462		if (inst->state == VPU_CODEC_STATE_DEINIT)463			vpu_set_last_buffer_dequeued(inst, true);464		else465			venc_request_eos(inst);466	}467	vpu_inst_unlock(inst);468 469	return 0;470}471 472static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)473{474	switch (sub->type) {475	case V4L2_EVENT_EOS:476		return v4l2_event_subscribe(fh, sub, 0, NULL);477	case V4L2_EVENT_CTRL:478		return v4l2_ctrl_subscribe_event(fh, sub);479	default:480		return -EINVAL;481	}482}483 484static const struct v4l2_ioctl_ops venc_ioctl_ops = {485	.vidioc_querycap               = venc_querycap,486	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,487	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,488	.vidioc_enum_framesizes        = venc_enum_framesizes,489	.vidioc_enum_frameintervals    = venc_enum_frameintervals,490	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,491	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,492	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,493	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,494	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,495	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,496	.vidioc_g_parm                 = venc_g_parm,497	.vidioc_s_parm                 = venc_s_parm,498	.vidioc_g_selection            = venc_g_selection,499	.vidioc_s_selection            = venc_s_selection,500	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,501	.vidioc_encoder_cmd            = venc_encoder_cmd,502	.vidioc_subscribe_event        = venc_subscribe_event,503	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,504	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,505	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,506	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,507	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,508	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,509	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,510	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,511	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,512	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,513};514 515static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)516{517	struct vpu_inst *inst = ctrl_to_inst(ctrl);518	struct venc_t *venc = inst->priv;519	int ret = 0;520 521	switch (ctrl->id) {522	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:523		venc->params.profile = ctrl->val;524		break;525	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:526		venc->params.level = ctrl->val;527		break;528	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:529		venc->params.rc_enable = ctrl->val;530		break;531	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:532		venc->params.rc_mode = ctrl->val;533		break;534	case V4L2_CID_MPEG_VIDEO_BITRATE:535		if (ctrl->val != venc->params.bitrate)536			venc->bitrate_change = true;537		venc->params.bitrate = ctrl->val;538		break;539	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:540		venc->params.bitrate_max = ctrl->val;541		break;542	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:543		venc->params.gop_length = ctrl->val;544		break;545	case V4L2_CID_MPEG_VIDEO_B_FRAMES:546		venc->params.bframes = ctrl->val;547		break;548	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:549		venc->params.i_frame_qp = ctrl->val;550		break;551	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:552		venc->params.p_frame_qp = ctrl->val;553		break;554	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:555		venc->params.b_frame_qp = ctrl->val;556		break;557	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:558		venc->request_key_frame = 1;559		break;560	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:561		venc->cpb_size = ctrl->val * 1024;562		break;563	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:564		venc->params.sar.enable = ctrl->val;565		break;566	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:567		venc->params.sar.idc = ctrl->val;568		break;569	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:570		venc->params.sar.width = ctrl->val;571		break;572	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:573		venc->params.sar.height = ctrl->val;574		break;575	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:576		break;577	default:578		ret = -EINVAL;579		break;580	}581 582	return ret;583}584 585static const struct v4l2_ctrl_ops venc_ctrl_ops = {586	.s_ctrl = venc_op_s_ctrl,587	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,588};589 590static int venc_ctrl_init(struct vpu_inst *inst)591{592	struct v4l2_ctrl *ctrl;593	int ret;594 595	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);596	if (ret)597		return ret;598 599	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,600			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,601			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,602			       ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |603				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |604				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),605			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);606 607	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,608			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,609			       V4L2_MPEG_VIDEO_H264_LEVEL_5_1,610			       0x0,611			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);612 613	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,614			  V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);615 616	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,617			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,618			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,619			       ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |620				 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),621			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);622 623	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,624			  V4L2_CID_MPEG_VIDEO_BITRATE,625			  BITRATE_MIN,626			  BITRATE_MAX,627			  BITRATE_STEP,628			  BITRATE_DEFAULT);629 630	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,631			  V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,632			  BITRATE_MIN, BITRATE_MAX,633			  BITRATE_STEP,634			  BITRATE_DEFAULT_PEAK);635 636	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,637			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);638 639	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,640			  V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);641 642	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,643			  V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);644	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,645			  V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);646	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,647			  V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);648	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,649			  V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);650	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,651				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);652	if (ctrl)653		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;654	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,655				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);656	if (ctrl)657		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;658 659	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,660			  V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);661 662	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,663			  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);664	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,665			       V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,666			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,667			       0x0,668			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);669	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,670			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,671			  0, USHRT_MAX, 1, 1);672	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,673			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,674			  0, USHRT_MAX, 1, 1);675	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,676			       V4L2_CID_MPEG_VIDEO_HEADER_MODE,677			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,678			       ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),679			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);680 681	v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,682			  V4L2_CID_MPEG_VIDEO_AVERAGE_QP, 0, 51, 1, 0);683 684	if (inst->ctrl_handler.error) {685		ret = inst->ctrl_handler.error;686		v4l2_ctrl_handler_free(&inst->ctrl_handler);687		return ret;688	}689 690	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);691	if (ret) {692		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);693		v4l2_ctrl_handler_free(&inst->ctrl_handler);694		return ret;695	}696 697	return 0;698}699 700static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)701{702	struct venc_t *venc = inst->priv;703 704	if (V4L2_TYPE_IS_OUTPUT(type)) {705		if (vpu_helper_get_free_space(inst) < venc->cpb_size)706			return false;707		return venc->input_ready;708	}709 710	if (list_empty(&venc->frames))711		return false;712	return true;713}714 715static u32 venc_get_enable_mask(u32 type)716{717	if (V4L2_TYPE_IS_OUTPUT(type))718		return VENC_OUTPUT_ENABLE;719	else720		return VENC_CAPTURE_ENABLE;721}722 723static void venc_set_enable(struct venc_t *venc, u32 type, int enable)724{725	u32 mask = venc_get_enable_mask(type);726 727	if (enable)728		venc->enable |= mask;729	else730		venc->enable &= ~mask;731}732 733static u32 venc_get_enable(struct venc_t *venc, u32 type)734{735	return venc->enable & venc_get_enable_mask(type);736}737 738static void venc_input_done(struct vpu_inst *inst)739{740	struct venc_t *venc = inst->priv;741 742	vpu_inst_lock(inst);743	venc->input_ready = true;744	vpu_process_output_buffer(inst);745	if (inst->state == VPU_CODEC_STATE_DRAIN)746		venc_drain(inst);747	vpu_inst_unlock(inst);748}749 750/*751 * It's hardware limitation, that there may be several bytes752 * redundant data at the beginning of frame.753 * For android platform, the redundant data may cause cts test fail754 * So driver will strip them755 */756static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)757{758	struct venc_t *venc;759	int skipped;760 761	if (!frame || !frame->bytesused)762		return -EINVAL;763 764	venc = inst->priv;765	skipped = vpu_helper_find_startcode(&inst->stream_buffer,766					    inst->cap_format.pixfmt,767					    frame->info.wptr - inst->stream_buffer.phys,768					    frame->bytesused);769	if (skipped > 0) {770		frame->bytesused -= skipped;771		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,772							frame->info.wptr, skipped);773		venc->skipped_bytes += skipped;774		venc->skipped_count++;775	}776 777	return 0;778}779 780static int venc_get_one_encoded_frame(struct vpu_inst *inst,781				      struct venc_frame_t *frame,782				      struct vb2_v4l2_buffer *vbuf)783{784	struct venc_t *venc = inst->priv;785	struct vb2_v4l2_buffer *src_buf;786 787	if (!vbuf)788		return -EAGAIN;789 790	src_buf = vpu_find_buf_by_sequence(inst, inst->out_format.type, frame->info.frame_id);791	if (src_buf) {792		v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);793		vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);794		v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, src_buf);795		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);796	} else {797		vbuf->vb2_buf.timestamp = frame->info.timestamp;798	}799	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {800		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);801		return 0;802	}803	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {804		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);805		return -ENOMEM;806	}807 808	venc_precheck_encoded_frame(inst, frame);809 810	if (frame->bytesused) {811		u32 rptr = frame->info.wptr;812		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);813 814		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,815						   &rptr, frame->bytesused, dst);816		vpu_iface_update_stream_buffer(inst, rptr, 0);817	}818	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);819	vbuf->sequence = frame->info.frame_id;820	vbuf->field = inst->cap_format.field;821	vbuf->flags |= frame->info.pic_type;822	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);823	vpu_set_buffer_average_qp(vbuf, frame->info.average_qp);824	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);825	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);826	venc->ready_count++;827 828	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)829		dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);830 831	return 0;832}833 834static int venc_get_encoded_frames(struct vpu_inst *inst)835{836	struct venc_t *venc;837	struct venc_frame_t *frame;838	struct venc_frame_t *tmp;839 840	if (!inst->fh.m2m_ctx)841		return 0;842	venc = inst->priv;843	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {844		if (venc_get_one_encoded_frame(inst, frame,845					       v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))846			break;847		list_del_init(&frame->list);848		vfree(frame);849	}850 851	return 0;852}853 854static int venc_frame_encoded(struct vpu_inst *inst, void *arg)855{856	struct vpu_enc_pic_info *info = arg;857	struct venc_frame_t *frame;858	struct venc_t *venc;859	int ret = 0;860 861	if (!info)862		return -EINVAL;863	venc = inst->priv;864	frame = vzalloc(sizeof(*frame));865	if (!frame)866		return -ENOMEM;867 868	memcpy(&frame->info, info, sizeof(frame->info));869	frame->bytesused = info->frame_size;870 871	vpu_inst_lock(inst);872	list_add_tail(&frame->list, &venc->frames);873	venc->encode_count++;874	venc_get_encoded_frames(inst);875	vpu_inst_unlock(inst);876 877	return ret;878}879 880static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)881{882	struct venc_t *venc = inst->priv;883 884	if (venc->stopped && list_empty(&venc->frames))885		vpu_set_last_buffer_dequeued(inst, true);886}887 888static void venc_stop_done(struct vpu_inst *inst)889{890	struct venc_t *venc = inst->priv;891 892	vpu_inst_lock(inst);893	venc->stopped = true;894	venc_set_last_buffer_dequeued(inst);895	vpu_inst_unlock(inst);896 897	wake_up_all(&venc->wq);898}899 900static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)901{902}903 904static void venc_release(struct vpu_inst *inst)905{906}907 908static void venc_cleanup(struct vpu_inst *inst)909{910	struct venc_t *venc;911 912	if (!inst)913		return;914 915	venc = inst->priv;916	vfree(venc);917	inst->priv = NULL;918	vfree(inst);919}920 921static int venc_start_session(struct vpu_inst *inst, u32 type)922{923	struct venc_t *venc = inst->priv;924	int stream_buffer_size;925	int ret;926 927	venc_set_enable(venc, type, 1);928	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)929		return 0;930 931	vpu_iface_init_instance(inst);932	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);933	if (stream_buffer_size > 0) {934		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);935		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);936		if (ret)937			goto error;938 939		inst->use_stream_buffer = true;940		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);941	}942 943	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);944	if (ret)945		goto error;946	ret = vpu_session_configure_codec(inst);947	if (ret)948		goto error;949 950	inst->state = VPU_CODEC_STATE_CONFIGURED;951	/*vpu_iface_config_memory_resource*/952 953	/*config enc expert mode parameter*/954	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);955	if (ret)956		goto error;957 958	ret = vpu_session_start(inst);959	if (ret)960		goto error;961	inst->state = VPU_CODEC_STATE_STARTED;962 963	venc->bitrate_change = false;964	venc->input_ready = true;965	venc->frame_count = 0;966	venc->encode_count = 0;967	venc->ready_count = 0;968	venc->stopped = false;969	vpu_process_output_buffer(inst);970	if (venc->frame_count == 0)971		dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);972 973	return 0;974error:975	venc_set_enable(venc, type, 0);976	inst->state = VPU_CODEC_STATE_DEINIT;977 978	vpu_free_dma(&inst->stream_buffer);979	return ret;980}981 982static void venc_cleanup_mem_resource(struct vpu_inst *inst)983{984	struct venc_t *venc;985	u32 i;986 987	venc = inst->priv;988 989	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)990		vpu_free_dma(&venc->enc[i]);991	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)992		vpu_free_dma(&venc->ref[i]);993}994 995static void venc_request_mem_resource(struct vpu_inst *inst,996				      u32 enc_frame_size,997				      u32 enc_frame_num,998				      u32 ref_frame_size,999				      u32 ref_frame_num,1000				      u32 act_frame_size,1001				      u32 act_frame_num)1002{1003	struct venc_t *venc;1004	u32 i;1005	int ret;1006 1007	venc = inst->priv;1008	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {1009		dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num);1010		return;1011	}1012	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {1013		dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num);1014		return;1015	}1016	if (act_frame_num > ARRAY_SIZE(venc->act)) {1017		dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num);1018		return;1019	}1020 1021	for (i = 0; i < enc_frame_num; i++) {1022		venc->enc[i].length = enc_frame_size;1023		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);1024		if (ret) {1025			venc_cleanup_mem_resource(inst);1026			return;1027		}1028	}1029	for (i = 0; i < ref_frame_num; i++) {1030		venc->ref[i].length = ref_frame_size;1031		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);1032		if (ret) {1033			venc_cleanup_mem_resource(inst);1034			return;1035		}1036	}1037	if (act_frame_num != 1 || act_frame_size > inst->act.length) {1038		venc_cleanup_mem_resource(inst);1039		return;1040	}1041	venc->act[0].length = act_frame_size;1042	venc->act[0].phys = inst->act.phys;1043	venc->act[0].virt = inst->act.virt;1044 1045	for (i = 0; i < enc_frame_num; i++)1046		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);1047	for (i = 0; i < ref_frame_num; i++)1048		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);1049	for (i = 0; i < act_frame_num; i++)1050		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);1051}1052 1053static void venc_cleanup_frames(struct venc_t *venc)1054{1055	struct venc_frame_t *frame;1056	struct venc_frame_t *tmp;1057 1058	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {1059		list_del_init(&frame->list);1060		vfree(frame);1061	}1062}1063 1064static int venc_stop_session(struct vpu_inst *inst, u32 type)1065{1066	struct venc_t *venc = inst->priv;1067 1068	venc_set_enable(venc, type, 0);1069	if (venc->enable & VENC_ENABLE_MASK)1070		return 0;1071 1072	if (inst->state == VPU_CODEC_STATE_DEINIT)1073		return 0;1074 1075	if (inst->state != VPU_CODEC_STATE_STOP)1076		venc_request_eos(inst);1077 1078	call_void_vop(inst, wait_prepare);1079	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {1080		set_bit(inst->id, &inst->core->hang_mask);1081		vpu_session_debug(inst);1082	}1083	call_void_vop(inst, wait_finish);1084 1085	inst->state = VPU_CODEC_STATE_DEINIT;1086	venc_cleanup_frames(inst->priv);1087	vpu_free_dma(&inst->stream_buffer);1088	venc_cleanup_mem_resource(inst);1089 1090	return 0;1091}1092 1093static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)1094{1095	struct venc_t *venc = inst->priv;1096	struct vb2_v4l2_buffer *vbuf;1097	u32 flags;1098 1099	if (inst->state == VPU_CODEC_STATE_DEINIT)1100		return -EINVAL;1101 1102	vbuf = to_vb2_v4l2_buffer(vb);1103	if (inst->state == VPU_CODEC_STATE_STARTED)1104		inst->state = VPU_CODEC_STATE_ACTIVE;1105 1106	flags = vbuf->flags;1107	if (venc->request_key_frame) {1108		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;1109		venc->request_key_frame = 0;1110	}1111	if (venc->bitrate_change) {1112		vpu_session_update_parameters(inst, &venc->params);1113		venc->bitrate_change = false;1114	}1115	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);1116	vpu_iface_input_frame(inst, vb);1117	vbuf->flags = flags;1118	venc->input_ready = false;1119	venc->frame_count++;1120	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);1121 1122	return 0;1123}1124 1125static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)1126{1127	struct venc_t *venc;1128	struct venc_frame_t *frame = NULL;1129	struct vb2_v4l2_buffer *vbuf;1130	int ret;1131 1132	venc = inst->priv;1133	if (list_empty(&venc->frames))1134		return -EINVAL;1135 1136	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);1137	vbuf = to_vb2_v4l2_buffer(vb);1138	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);1139	ret = venc_get_one_encoded_frame(inst, frame, vbuf);1140	if (ret)1141		return ret;1142 1143	list_del_init(&frame->list);1144	vfree(frame);1145	return 0;1146}1147 1148static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)1149{1150	struct venc_t *venc = inst->priv;1151 1152	if (V4L2_TYPE_IS_OUTPUT(type))1153		return;1154 1155	if (venc->stopped)1156		venc_set_last_buffer_dequeued(inst);1157}1158 1159static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)1160{1161	struct venc_t *venc = inst->priv;1162	int num = -1;1163 1164	switch (i) {1165	case 0:1166		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);1167		break;1168	case 1:1169		num = scnprintf(str, size, "level = %d\n", venc->params.level);1170		break;1171	case 2:1172		num = scnprintf(str, size, "fps = %d/%d\n",1173				venc->params.frame_rate.numerator,1174				venc->params.frame_rate.denominator);1175		break;1176	case 3:1177		num = scnprintf(str, size, "%d x %d -> %d x %d\n",1178				venc->params.src_width,1179				venc->params.src_height,1180				venc->params.out_width,1181				venc->params.out_height);1182		break;1183	case 4:1184		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",1185				venc->params.crop.left,1186				venc->params.crop.top,1187				venc->params.crop.width,1188				venc->params.crop.height);1189		break;1190	case 5:1191		num = scnprintf(str, size,1192				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",1193				venc->enable,1194				venc->frame_count, venc->encode_count,1195				venc->ready_count,1196				venc->stopped);1197		break;1198	case 6:1199		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);1200		break;1201	case 7:1202		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);1203		break;1204	case 8:1205		num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n",1206				venc->params.rc_enable ? "enable" : "disable",1207				venc->params.rc_mode,1208				venc->params.bitrate,1209				venc->params.bitrate_max,1210				venc->params.i_frame_qp);1211		break;1212	case 9:1213		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",1214				venc->params.sar.enable,1215				venc->params.sar.idc,1216				venc->params.sar.width,1217				venc->params.sar.height);1218 1219		break;1220	case 10:1221		num = scnprintf(str, size,1222				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",1223				venc->params.color.primaries,1224				venc->params.color.transfer,1225				venc->params.color.matrix,1226				venc->params.color.full_range);1227		break;1228	case 11:1229		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",1230				venc->skipped_count, venc->skipped_bytes);1231		break;1232	default:1233		break;1234	}1235 1236	return num;1237}1238 1239static struct vpu_inst_ops venc_inst_ops = {1240	.ctrl_init = venc_ctrl_init,1241	.check_ready = venc_check_ready,1242	.input_done = venc_input_done,1243	.get_one_frame = venc_frame_encoded,1244	.stop_done = venc_stop_done,1245	.event_notify = venc_event_notify,1246	.release = venc_release,1247	.cleanup = venc_cleanup,1248	.start = venc_start_session,1249	.mem_request = venc_request_mem_resource,1250	.stop = venc_stop_session,1251	.process_output = venc_process_output,1252	.process_capture = venc_process_capture,1253	.on_queue_empty = venc_on_queue_empty,1254	.get_debug_info = venc_get_debug_info,1255	.wait_prepare = vpu_inst_unlock,1256	.wait_finish = vpu_inst_lock,1257};1258 1259static void venc_init(struct file *file)1260{1261	struct vpu_inst *inst = to_inst(file);1262	struct venc_t *venc;1263	struct v4l2_format f;1264	struct v4l2_streamparm parm;1265 1266	venc = inst->priv;1267	venc->params.qp_min = 1;1268	venc->params.qp_max = 51;1269	venc->params.qp_min_i = 1;1270	venc->params.qp_max_i = 51;1271	venc->params.bitrate_min = BITRATE_MIN;1272 1273	memset(&f, 0, sizeof(f));1274	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;1275	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;1276	f.fmt.pix_mp.width = 1280;1277	f.fmt.pix_mp.height = 720;1278	f.fmt.pix_mp.field = V4L2_FIELD_NONE;1279	venc_s_fmt(file, &inst->fh, &f);1280 1281	memset(&f, 0, sizeof(f));1282	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;1283	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;1284	f.fmt.pix_mp.width = 1280;1285	f.fmt.pix_mp.height = 720;1286	f.fmt.pix_mp.field = V4L2_FIELD_NONE;1287	venc_s_fmt(file, &inst->fh, &f);1288 1289	memset(&parm, 0, sizeof(parm));1290	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;1291	parm.parm.capture.timeperframe.numerator = 1;1292	parm.parm.capture.timeperframe.denominator = 30;1293	venc_s_parm(file, &inst->fh, &parm);1294}1295 1296static int venc_open(struct file *file)1297{1298	struct vpu_inst *inst;1299	struct venc_t *venc;1300	int ret;1301 1302	inst = vzalloc(sizeof(*inst));1303	if (!inst)1304		return -ENOMEM;1305 1306	venc = vzalloc(sizeof(*venc));1307	if (!venc) {1308		vfree(inst);1309		return -ENOMEM;1310	}1311 1312	inst->ops = &venc_inst_ops;1313	inst->formats = venc_formats;1314	inst->type = VPU_CORE_TYPE_ENC;1315	inst->priv = venc;1316	INIT_LIST_HEAD(&venc->frames);1317	init_waitqueue_head(&venc->wq);1318 1319	ret = vpu_v4l2_open(file, inst);1320	if (ret)1321		return ret;1322 1323	inst->min_buffer_out = VENC_MIN_BUFFER_OUT;1324	inst->min_buffer_cap = VENC_MIN_BUFFER_CAP;1325	venc_init(file);1326 1327	return 0;1328}1329 1330static const struct v4l2_file_operations venc_fops = {1331	.owner = THIS_MODULE,1332	.open = venc_open,1333	.release = vpu_v4l2_close,1334	.unlocked_ioctl = video_ioctl2,1335	.poll = v4l2_m2m_fop_poll,1336	.mmap = v4l2_m2m_fop_mmap,1337};1338 1339const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)1340{1341	return &venc_ioctl_ops;1342}1343 1344const struct v4l2_file_operations *venc_get_fops(void)1345{1346	return &venc_fops;1347}1348