File Index
Files and directories
Sign in
FILE

venc.c

File preview with syntax highlighting.

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