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/vmalloc.h>
13 #include <linux/videodev2.h>
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-event.h>
16 #include <media/v4l2-mem2mem.h>
17 #include <media/v4l2-ioctl.h>
18 #include <media/videobuf2-v4l2.h>
19 #include <media/videobuf2-dma-contig.h>
20 #include <media/videobuf2-vmalloc.h>
21 #include "vpu.h"
22 #include "vpu_defs.h"
23 #include "vpu_core.h"
24 #include "vpu_helpers.h"
25 #include "vpu_v4l2.h"
26 #include "vpu_cmds.h"
27 #include "vpu_rpc.h"
28
29 #define VDEC_MIN_BUFFER_CAP 8
30 #define VDEC_MIN_BUFFER_OUT 8
31
32 struct vdec_fs_info {
33 char name[8];
34 u32 type;
35 u32 max_count;
36 u32 req_count;
37 u32 count;
38 u32 index;
39 u32 size;
40 struct vpu_buffer buffer[32];
41 u32 tag;
42 };
43
44 struct vdec_t {
45 u32 seq_hdr_found;
46 struct vpu_buffer udata;
47 struct vpu_decode_params params;
48 struct vpu_dec_codec_info codec_info;
49 enum vpu_codec_state state;
50
51 struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
52 u32 req_frame_count;
53 struct vdec_fs_info mbi;
54 struct vdec_fs_info dcp;
55 u32 seq_tag;
56
57 bool reset_codec;
58 bool fixed_fmt;
59 u32 decoded_frame_count;
60 u32 display_frame_count;
61 u32 sequence;
62 u32 eos_received;
63 bool is_source_changed;
64 u32 source_change;
65 u32 drain;
66 bool aborting;
67 };
68
69 static const struct vpu_format vdec_formats[] = {
70 {
71 .pixfmt = V4L2_PIX_FMT_NV12M_8L128,
72 .mem_planes = 2,
73 .comp_planes = 2,
74 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
75 .sibling = V4L2_PIX_FMT_NV12_8L128,
76 },
77 {
78 .pixfmt = V4L2_PIX_FMT_NV12_8L128,
79 .mem_planes = 1,
80 .comp_planes = 2,
81 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
82 .sibling = V4L2_PIX_FMT_NV12M_8L128,
83 },
84 {
85 .pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128,
86 .mem_planes = 2,
87 .comp_planes = 2,
88 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
89 .sibling = V4L2_PIX_FMT_NV12_10BE_8L128,
90 },
91 {
92 .pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128,
93 .mem_planes = 1,
94 .comp_planes = 2,
95 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
96 .sibling = V4L2_PIX_FMT_NV12M_10BE_8L128
97 },
98 {
99 .pixfmt = V4L2_PIX_FMT_H264,
100 .mem_planes = 1,
101 .comp_planes = 1,
102 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
103 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
104 },
105 {
106 .pixfmt = V4L2_PIX_FMT_H264_MVC,
107 .mem_planes = 1,
108 .comp_planes = 1,
109 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
110 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
111 },
112 {
113 .pixfmt = V4L2_PIX_FMT_HEVC,
114 .mem_planes = 1,
115 .comp_planes = 1,
116 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
117 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
118 },
119 {
120 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
121 .mem_planes = 1,
122 .comp_planes = 1,
123 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
124 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
125 },
126 {
127 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
128 .mem_planes = 1,
129 .comp_planes = 1,
130 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
131 .flags = V4L2_FMT_FLAG_COMPRESSED
132 },
133 {
134 .pixfmt = V4L2_PIX_FMT_MPEG2,
135 .mem_planes = 1,
136 .comp_planes = 1,
137 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
138 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
139 },
140 {
141 .pixfmt = V4L2_PIX_FMT_MPEG4,
142 .mem_planes = 1,
143 .comp_planes = 1,
144 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
145 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
146 },
147 {
148 .pixfmt = V4L2_PIX_FMT_XVID,
149 .mem_planes = 1,
150 .comp_planes = 1,
151 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
152 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
153 },
154 {
155 .pixfmt = V4L2_PIX_FMT_VP8,
156 .mem_planes = 1,
157 .comp_planes = 1,
158 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
159 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
160 },
161 {
162 .pixfmt = V4L2_PIX_FMT_H263,
163 .mem_planes = 1,
164 .comp_planes = 1,
165 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
166 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
167 },
168 {
169 .pixfmt = V4L2_PIX_FMT_SPK,
170 .mem_planes = 1,
171 .comp_planes = 1,
172 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
173 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
174 },
175 {
176 .pixfmt = V4L2_PIX_FMT_RV30,
177 .mem_planes = 1,
178 .comp_planes = 1,
179 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
180 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
181 },
182 {
183 .pixfmt = V4L2_PIX_FMT_RV40,
184 .mem_planes = 1,
185 .comp_planes = 1,
186 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
187 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED
188 },
189 {0, 0, 0, 0},
190 };
191
vdec_op_s_ctrl(struct v4l2_ctrl * ctrl)192 static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
193 {
194 struct vpu_inst *inst = ctrl_to_inst(ctrl);
195 struct vdec_t *vdec = inst->priv;
196 int ret = 0;
197
198 switch (ctrl->id) {
199 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:
200 vdec->params.display_delay_enable = ctrl->val;
201 break;
202 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY:
203 vdec->params.display_delay = ctrl->val;
204 break;
205 default:
206 ret = -EINVAL;
207 break;
208 }
209
210 return ret;
211 }
212
213 static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
214 .s_ctrl = vdec_op_s_ctrl,
215 .g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
216 };
217
vdec_ctrl_init(struct vpu_inst * inst)218 static int vdec_ctrl_init(struct vpu_inst *inst)
219 {
220 struct v4l2_ctrl *ctrl;
221 int ret;
222
223 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
224 if (ret)
225 return ret;
226
227 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
228 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY,
229 0, 0, 1, 0);
230
231 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
232 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
233 0, 1, 1, 0);
234
235 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
236 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
237 if (ctrl)
238 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
239
240 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
241 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
242 if (ctrl)
243 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
244
245 if (inst->ctrl_handler.error) {
246 ret = inst->ctrl_handler.error;
247 v4l2_ctrl_handler_free(&inst->ctrl_handler);
248 return ret;
249 }
250
251 ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
252 if (ret) {
253 dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
254 v4l2_ctrl_handler_free(&inst->ctrl_handler);
255 return ret;
256 }
257
258 return 0;
259 }
260
vdec_handle_resolution_change(struct vpu_inst * inst)261 static void vdec_handle_resolution_change(struct vpu_inst *inst)
262 {
263 struct vdec_t *vdec = inst->priv;
264 struct vb2_queue *q;
265
266 if (!inst->fh.m2m_ctx)
267 return;
268
269 if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
270 return;
271 if (!vdec->source_change)
272 return;
273
274 q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
275 if (!list_empty(&q->done_list))
276 return;
277
278 vdec->source_change--;
279 vpu_notify_source_change(inst);
280 vpu_set_last_buffer_dequeued(inst, false);
281 }
282
vdec_update_state(struct vpu_inst * inst,enum vpu_codec_state state,u32 force)283 static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
284 {
285 struct vdec_t *vdec = inst->priv;
286 enum vpu_codec_state pre_state = inst->state;
287
288 if (state == VPU_CODEC_STATE_SEEK) {
289 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
290 vdec->state = inst->state;
291 else
292 vdec->state = VPU_CODEC_STATE_ACTIVE;
293 }
294 if (inst->state != VPU_CODEC_STATE_SEEK || force)
295 inst->state = state;
296 else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
297 vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
298
299 if (inst->state != pre_state)
300 vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id,
301 vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state));
302
303 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
304 vdec_handle_resolution_change(inst);
305
306 return 0;
307 }
308
vdec_set_last_buffer_dequeued(struct vpu_inst * inst)309 static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
310 {
311 struct vdec_t *vdec = inst->priv;
312
313 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
314 return;
315
316 if (vdec->eos_received) {
317 if (!vpu_set_last_buffer_dequeued(inst, true)) {
318 vdec->eos_received--;
319 vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
320 }
321 }
322 }
323
vdec_querycap(struct file * file,void * fh,struct v4l2_capability * cap)324 static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
325 {
326 strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
327 strscpy(cap->card, "amphion vpu decoder", sizeof(cap->card));
328 strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
329
330 return 0;
331 }
332
vdec_enum_fmt(struct file * file,void * fh,struct v4l2_fmtdesc * f)333 static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
334 {
335 struct vpu_inst *inst = to_inst(file);
336 struct vdec_t *vdec = inst->priv;
337 const struct vpu_format *fmt;
338 int ret = -EINVAL;
339
340 vpu_inst_lock(inst);
341 if (V4L2_TYPE_IS_CAPTURE(f->type) && vdec->fixed_fmt) {
342 fmt = vpu_get_format(inst, f->type);
343 if (f->index == 1)
344 fmt = vpu_helper_find_sibling(inst, f->type, fmt->pixfmt);
345 if (f->index > 1)
346 fmt = NULL;
347 } else {
348 fmt = vpu_helper_enum_format(inst, f->type, f->index);
349 }
350 if (!fmt)
351 goto exit;
352
353 memset(f->reserved, 0, sizeof(f->reserved));
354 f->pixelformat = fmt->pixfmt;
355 f->flags = fmt->flags;
356 ret = 0;
357 exit:
358 vpu_inst_unlock(inst);
359 return ret;
360 }
361
vdec_g_fmt(struct file * file,void * fh,struct v4l2_format * f)362 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
363 {
364 struct vpu_inst *inst = to_inst(file);
365 struct vdec_t *vdec = inst->priv;
366 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
367 struct vpu_format *cur_fmt;
368 int i;
369
370 vpu_inst_lock(inst);
371 cur_fmt = vpu_get_format(inst, f->type);
372
373 pixmp->pixelformat = cur_fmt->pixfmt;
374 pixmp->num_planes = cur_fmt->mem_planes;
375 pixmp->width = cur_fmt->width;
376 pixmp->height = cur_fmt->height;
377 pixmp->field = cur_fmt->field;
378 pixmp->flags = cur_fmt->flags;
379 for (i = 0; i < pixmp->num_planes; i++) {
380 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
381 pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i);
382 }
383
384 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
385 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
386 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
387 f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
388 vpu_inst_unlock(inst);
389
390 return 0;
391 }
392
vdec_try_fmt(struct file * file,void * fh,struct v4l2_format * f)393 static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
394 {
395 struct vpu_inst *inst = to_inst(file);
396 struct vdec_t *vdec = inst->priv;
397 struct vpu_format fmt;
398
399 vpu_inst_lock(inst);
400 if (V4L2_TYPE_IS_CAPTURE(f->type) && vdec->fixed_fmt) {
401 struct vpu_format *cap_fmt = vpu_get_format(inst, f->type);
402
403 if (!vpu_helper_match_format(inst, cap_fmt->type, cap_fmt->pixfmt,
404 f->fmt.pix_mp.pixelformat))
405 f->fmt.pix_mp.pixelformat = cap_fmt->pixfmt;
406 }
407
408 vpu_try_fmt_common(inst, f, &fmt);
409
410 if (vdec->fixed_fmt) {
411 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
412 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
413 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
414 f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
415 } else {
416 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
417 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
418 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
419 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
420 }
421 vpu_inst_unlock(inst);
422
423 return 0;
424 }
425
vdec_s_fmt_common(struct vpu_inst * inst,struct v4l2_format * f)426 static int vdec_s_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
427 {
428 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
429 struct vpu_format fmt;
430 struct vpu_format *cur_fmt;
431 struct vb2_queue *q;
432 struct vdec_t *vdec = inst->priv;
433 int i;
434
435 if (!inst->fh.m2m_ctx)
436 return -EINVAL;
437
438 q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
439 if (!q)
440 return -EINVAL;
441 if (vb2_is_busy(q))
442 return -EBUSY;
443
444 if (vpu_try_fmt_common(inst, f, &fmt))
445 return -EINVAL;
446
447 cur_fmt = vpu_get_format(inst, f->type);
448 if (V4L2_TYPE_IS_OUTPUT(f->type) && inst->state != VPU_CODEC_STATE_DEINIT) {
449 if (cur_fmt->pixfmt != fmt.pixfmt) {
450 vdec->reset_codec = true;
451 vdec->fixed_fmt = false;
452 }
453 }
454 if (V4L2_TYPE_IS_OUTPUT(f->type) || !vdec->fixed_fmt) {
455 memcpy(cur_fmt, &fmt, sizeof(*cur_fmt));
456 } else {
457 if (vpu_helper_match_format(inst, f->type, cur_fmt->pixfmt, pixmp->pixelformat)) {
458 cur_fmt->pixfmt = fmt.pixfmt;
459 cur_fmt->mem_planes = fmt.mem_planes;
460 }
461 pixmp->pixelformat = cur_fmt->pixfmt;
462 pixmp->num_planes = cur_fmt->mem_planes;
463 pixmp->width = cur_fmt->width;
464 pixmp->height = cur_fmt->height;
465 for (i = 0; i < pixmp->num_planes; i++) {
466 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
467 pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i);
468 }
469 pixmp->field = cur_fmt->field;
470 }
471
472 if (!vdec->fixed_fmt) {
473 if (V4L2_TYPE_IS_OUTPUT(f->type)) {
474 vdec->params.codec_format = cur_fmt->pixfmt;
475 vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
476 vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
477 vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
478 vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
479 } else {
480 vdec->params.output_format = cur_fmt->pixfmt;
481 inst->crop.left = 0;
482 inst->crop.top = 0;
483 inst->crop.width = cur_fmt->width;
484 inst->crop.height = cur_fmt->height;
485 }
486 }
487
488 vpu_trace(inst->dev, "[%d] %c%c%c%c %dx%d\n", inst->id,
489 f->fmt.pix_mp.pixelformat,
490 f->fmt.pix_mp.pixelformat >> 8,
491 f->fmt.pix_mp.pixelformat >> 16,
492 f->fmt.pix_mp.pixelformat >> 24,
493 f->fmt.pix_mp.width,
494 f->fmt.pix_mp.height);
495
496 return 0;
497 }
498
vdec_s_fmt(struct file * file,void * fh,struct v4l2_format * f)499 static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
500 {
501 struct vpu_inst *inst = to_inst(file);
502 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
503 struct vdec_t *vdec = inst->priv;
504 int ret = 0;
505
506 vpu_inst_lock(inst);
507 ret = vdec_s_fmt_common(inst, f);
508 if (ret)
509 goto exit;
510
511 if (V4L2_TYPE_IS_OUTPUT(f->type) && !vdec->fixed_fmt) {
512 struct v4l2_format fc;
513
514 memset(&fc, 0, sizeof(fc));
515 fc.type = inst->cap_format.type;
516 fc.fmt.pix_mp.pixelformat = inst->cap_format.pixfmt;
517 fc.fmt.pix_mp.width = pixmp->width;
518 fc.fmt.pix_mp.height = pixmp->height;
519 vdec_s_fmt_common(inst, &fc);
520 }
521
522 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
523 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
524 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
525 f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
526
527 exit:
528 vpu_inst_unlock(inst);
529 return ret;
530 }
531
vdec_g_selection(struct file * file,void * fh,struct v4l2_selection * s)532 static int vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
533 {
534 struct vpu_inst *inst = to_inst(file);
535
536 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
537 return -EINVAL;
538
539 switch (s->target) {
540 case V4L2_SEL_TGT_COMPOSE:
541 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
542 case V4L2_SEL_TGT_COMPOSE_PADDED:
543 s->r = inst->crop;
544 break;
545 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
546 s->r.left = 0;
547 s->r.top = 0;
548 s->r.width = inst->cap_format.width;
549 s->r.height = inst->cap_format.height;
550 break;
551 default:
552 return -EINVAL;
553 }
554
555 return 0;
556 }
557
vdec_drain(struct vpu_inst * inst)558 static int vdec_drain(struct vpu_inst *inst)
559 {
560 struct vdec_t *vdec = inst->priv;
561
562 if (!inst->fh.m2m_ctx)
563 return 0;
564
565 if (!vdec->drain)
566 return 0;
567
568 if (!vpu_is_source_empty(inst))
569 return 0;
570
571 if (!vdec->params.frame_count) {
572 vpu_set_last_buffer_dequeued(inst, true);
573 return 0;
574 }
575
576 vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
577 vdec->params.end_flag = 1;
578 vpu_iface_set_decode_params(inst, &vdec->params, 1);
579 vdec->drain = 0;
580 vpu_trace(inst->dev, "[%d] frame_count = %d\n", inst->id, vdec->params.frame_count);
581
582 return 0;
583 }
584
vdec_cmd_start(struct vpu_inst * inst)585 static int vdec_cmd_start(struct vpu_inst *inst)
586 {
587 struct vdec_t *vdec = inst->priv;
588
589 switch (inst->state) {
590 case VPU_CODEC_STATE_STARTED:
591 case VPU_CODEC_STATE_DRAIN:
592 case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE:
593 vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
594 break;
595 default:
596 break;
597 }
598 vpu_process_capture_buffer(inst);
599 if (vdec->eos_received)
600 vdec_set_last_buffer_dequeued(inst);
601 return 0;
602 }
603
vdec_cmd_stop(struct vpu_inst * inst)604 static int vdec_cmd_stop(struct vpu_inst *inst)
605 {
606 struct vdec_t *vdec = inst->priv;
607
608 vpu_trace(inst->dev, "[%d]\n", inst->id);
609
610 if (inst->state == VPU_CODEC_STATE_DEINIT) {
611 vpu_set_last_buffer_dequeued(inst, true);
612 } else {
613 vdec->drain = 1;
614 vdec_drain(inst);
615 }
616
617 return 0;
618 }
619
vdec_decoder_cmd(struct file * file,void * fh,struct v4l2_decoder_cmd * cmd)620 static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
621 {
622 struct vpu_inst *inst = to_inst(file);
623 int ret;
624
625 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
626 if (ret)
627 return ret;
628
629 vpu_inst_lock(inst);
630 switch (cmd->cmd) {
631 case V4L2_DEC_CMD_START:
632 vdec_cmd_start(inst);
633 break;
634 case V4L2_DEC_CMD_STOP:
635 vdec_cmd_stop(inst);
636 break;
637 default:
638 break;
639 }
640 vpu_inst_unlock(inst);
641
642 return 0;
643 }
644
vdec_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)645 static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
646 {
647 switch (sub->type) {
648 case V4L2_EVENT_EOS:
649 return v4l2_event_subscribe(fh, sub, 0, NULL);
650 case V4L2_EVENT_SOURCE_CHANGE:
651 return v4l2_src_change_event_subscribe(fh, sub);
652 case V4L2_EVENT_CTRL:
653 return v4l2_ctrl_subscribe_event(fh, sub);
654 default:
655 return -EINVAL;
656 }
657
658 return 0;
659 }
660
661 static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
662 .vidioc_querycap = vdec_querycap,
663 .vidioc_enum_fmt_vid_cap = vdec_enum_fmt,
664 .vidioc_enum_fmt_vid_out = vdec_enum_fmt,
665 .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt,
666 .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt,
667 .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
668 .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
669 .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt,
670 .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt,
671 .vidioc_g_selection = vdec_g_selection,
672 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
673 .vidioc_decoder_cmd = vdec_decoder_cmd,
674 .vidioc_subscribe_event = vdec_subscribe_event,
675 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
676 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
677 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
678 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
679 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
680 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
681 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
682 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
683 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
684 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
685 };
686
vdec_check_ready(struct vpu_inst * inst,unsigned int type)687 static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
688 {
689 struct vdec_t *vdec = inst->priv;
690
691 if (V4L2_TYPE_IS_OUTPUT(type))
692 return true;
693
694 if (vdec->req_frame_count)
695 return true;
696
697 return false;
698 }
699
vdec_get_src_buffer(struct vpu_inst * inst,u32 count)700 static struct vb2_v4l2_buffer *vdec_get_src_buffer(struct vpu_inst *inst, u32 count)
701 {
702 if (count > 1)
703 vpu_skip_frame(inst, count - 1);
704
705 return vpu_next_src_buf(inst);
706 }
707
vdec_frame_decoded(struct vpu_inst * inst,void * arg)708 static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
709 {
710 struct vdec_t *vdec = inst->priv;
711 struct vpu_dec_pic_info *info = arg;
712 struct vpu_vb2_buffer *vpu_buf;
713 struct vb2_v4l2_buffer *vbuf;
714 struct vb2_v4l2_buffer *src_buf;
715 int ret = 0;
716
717 if (!info || info->id >= ARRAY_SIZE(vdec->slots))
718 return -EINVAL;
719
720 vpu_inst_lock(inst);
721 vpu_buf = vdec->slots[info->id];
722 if (!vpu_buf) {
723 dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
724 ret = -EINVAL;
725 goto exit;
726 }
727 vbuf = &vpu_buf->m2m_buf.vb;
728 src_buf = vdec_get_src_buffer(inst, info->consumed_count);
729 if (src_buf) {
730 v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
731 if (info->consumed_count) {
732 v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
733 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
734 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
735 } else {
736 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_DECODED);
737 }
738 }
739 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
740 dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
741 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
742 vdec->decoded_frame_count++;
743 if (vdec->params.display_delay_enable) {
744 struct vpu_format *cur_fmt;
745
746 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
747 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
748 for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
749 vb2_set_plane_payload(&vbuf->vb2_buf,
750 i, vpu_get_fmt_plane_size(cur_fmt, i));
751 vbuf->field = cur_fmt->field;
752 vbuf->sequence = vdec->sequence++;
753 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
754
755 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
756 vdec->display_frame_count++;
757 }
758 exit:
759 vpu_inst_unlock(inst);
760
761 return ret;
762 }
763
vdec_find_buffer(struct vpu_inst * inst,u32 luma)764 static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
765 {
766 struct vdec_t *vdec = inst->priv;
767 int i;
768
769 for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
770 if (!vdec->slots[i])
771 continue;
772 if (luma == vdec->slots[i]->luma)
773 return vdec->slots[i];
774 }
775
776 return NULL;
777 }
778
vdec_buf_done(struct vpu_inst * inst,struct vpu_frame_info * frame)779 static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
780 {
781 struct vdec_t *vdec = inst->priv;
782 struct vpu_format *cur_fmt;
783 struct vpu_vb2_buffer *vpu_buf;
784 struct vb2_v4l2_buffer *vbuf;
785 int i;
786
787 if (!frame)
788 return;
789
790 vpu_inst_lock(inst);
791 if (!vdec->params.display_delay_enable)
792 vdec->sequence++;
793 vpu_buf = vdec_find_buffer(inst, frame->luma);
794 vpu_inst_unlock(inst);
795 if (!vpu_buf) {
796 dev_err(inst->dev, "[%d] can't find buffer, id = %d, addr = 0x%x\n",
797 inst->id, frame->id, frame->luma);
798 return;
799 }
800 if (frame->skipped) {
801 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
802 return;
803 }
804
805 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
806 vbuf = &vpu_buf->m2m_buf.vb;
807 if (vbuf->vb2_buf.index != frame->id)
808 dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
809 inst->id, vbuf->vb2_buf.index, frame->id);
810
811 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)
812 return;
813
814 if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
815 dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id);
816
817 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
818 for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
819 vb2_set_plane_payload(&vbuf->vb2_buf, i, vpu_get_fmt_plane_size(cur_fmt, i));
820 vbuf->field = cur_fmt->field;
821 vbuf->sequence = vdec->sequence;
822 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
823
824 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
825 vpu_inst_lock(inst);
826 vdec->display_frame_count++;
827 vpu_inst_unlock(inst);
828 dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
829 inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
830 }
831
vdec_stop_done(struct vpu_inst * inst)832 static void vdec_stop_done(struct vpu_inst *inst)
833 {
834 struct vdec_t *vdec = inst->priv;
835
836 vpu_inst_lock(inst);
837 vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
838 vdec->seq_hdr_found = 0;
839 vdec->req_frame_count = 0;
840 vdec->reset_codec = false;
841 vdec->fixed_fmt = false;
842 vdec->params.end_flag = 0;
843 vdec->drain = 0;
844 vdec->params.frame_count = 0;
845 vdec->decoded_frame_count = 0;
846 vdec->display_frame_count = 0;
847 vdec->sequence = 0;
848 vdec->eos_received = 0;
849 vdec->is_source_changed = false;
850 vdec->source_change = 0;
851 inst->total_input_count = 0;
852 vpu_inst_unlock(inst);
853 }
854
vdec_check_source_change(struct vpu_inst * inst)855 static bool vdec_check_source_change(struct vpu_inst *inst)
856 {
857 struct vdec_t *vdec = inst->priv;
858 const struct vpu_format *sibling;
859
860 if (!inst->fh.m2m_ctx)
861 return false;
862
863 if (vdec->reset_codec)
864 return false;
865
866 sibling = vpu_helper_find_sibling(inst, inst->cap_format.type, inst->cap_format.pixfmt);
867 if (sibling && vdec->codec_info.pixfmt == sibling->pixfmt)
868 vdec->codec_info.pixfmt = inst->cap_format.pixfmt;
869
870 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
871 return true;
872 if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
873 return true;
874 if (inst->cap_format.width != vdec->codec_info.decoded_width)
875 return true;
876 if (inst->cap_format.height != vdec->codec_info.decoded_height)
877 return true;
878 if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
879 return true;
880 if (inst->crop.left != vdec->codec_info.offset_x)
881 return true;
882 if (inst->crop.top != vdec->codec_info.offset_y)
883 return true;
884 if (inst->crop.width != vdec->codec_info.width)
885 return true;
886 if (inst->crop.height != vdec->codec_info.height)
887 return true;
888
889 return false;
890 }
891
vdec_init_fmt(struct vpu_inst * inst)892 static void vdec_init_fmt(struct vpu_inst *inst)
893 {
894 struct vdec_t *vdec = inst->priv;
895 struct v4l2_format f;
896
897 memset(&f, 0, sizeof(f));
898 f.type = inst->cap_format.type;
899 f.fmt.pix_mp.pixelformat = vdec->codec_info.pixfmt;
900 f.fmt.pix_mp.width = vdec->codec_info.decoded_width;
901 f.fmt.pix_mp.height = vdec->codec_info.decoded_height;
902 if (vdec->codec_info.progressive)
903 f.fmt.pix_mp.field = V4L2_FIELD_NONE;
904 else
905 f.fmt.pix_mp.field = V4L2_FIELD_SEQ_TB;
906 vpu_try_fmt_common(inst, &f, &inst->cap_format);
907
908 inst->out_format.width = vdec->codec_info.width;
909 inst->out_format.height = vdec->codec_info.height;
910 }
911
vdec_init_crop(struct vpu_inst * inst)912 static void vdec_init_crop(struct vpu_inst *inst)
913 {
914 struct vdec_t *vdec = inst->priv;
915
916 inst->crop.left = vdec->codec_info.offset_x;
917 inst->crop.top = vdec->codec_info.offset_y;
918 inst->crop.width = vdec->codec_info.width;
919 inst->crop.height = vdec->codec_info.height;
920 }
921
vdec_init_mbi(struct vpu_inst * inst)922 static void vdec_init_mbi(struct vpu_inst *inst)
923 {
924 struct vdec_t *vdec = inst->priv;
925
926 vdec->mbi.size = vdec->codec_info.mbi_size;
927 vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
928 scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
929 vdec->mbi.type = MEM_RES_MBI;
930 vdec->mbi.tag = vdec->seq_tag;
931 }
932
vdec_init_dcp(struct vpu_inst * inst)933 static void vdec_init_dcp(struct vpu_inst *inst)
934 {
935 struct vdec_t *vdec = inst->priv;
936
937 vdec->dcp.size = vdec->codec_info.dcp_size;
938 vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
939 scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
940 vdec->dcp.type = MEM_RES_DCP;
941 vdec->dcp.tag = vdec->seq_tag;
942 }
943
vdec_request_one_fs(struct vdec_fs_info * fs)944 static void vdec_request_one_fs(struct vdec_fs_info *fs)
945 {
946 fs->req_count++;
947 if (fs->req_count > fs->max_count)
948 fs->req_count = fs->max_count;
949 }
950
vdec_alloc_fs_buffer(struct vpu_inst * inst,struct vdec_fs_info * fs)951 static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
952 {
953 struct vpu_buffer *buffer;
954
955 if (!fs->size)
956 return -EINVAL;
957
958 if (fs->count >= fs->req_count)
959 return -EINVAL;
960
961 buffer = &fs->buffer[fs->count];
962 if (buffer->virt && buffer->length >= fs->size)
963 return 0;
964
965 vpu_free_dma(buffer);
966 buffer->length = fs->size;
967 return vpu_alloc_dma(inst->core, buffer);
968 }
969
vdec_alloc_fs(struct vpu_inst * inst,struct vdec_fs_info * fs)970 static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
971 {
972 int ret;
973
974 while (fs->count < fs->req_count) {
975 ret = vdec_alloc_fs_buffer(inst, fs);
976 if (ret)
977 break;
978 fs->count++;
979 }
980 }
981
vdec_clear_fs(struct vdec_fs_info * fs)982 static void vdec_clear_fs(struct vdec_fs_info *fs)
983 {
984 u32 i;
985
986 if (!fs)
987 return;
988
989 for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
990 vpu_free_dma(&fs->buffer[i]);
991 memset(fs, 0, sizeof(*fs));
992 }
993
vdec_response_fs(struct vpu_inst * inst,struct vdec_fs_info * fs)994 static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
995 {
996 struct vpu_fs_info info;
997 int ret;
998
999 if (fs->index >= fs->count)
1000 return 0;
1001
1002 memset(&info, 0, sizeof(info));
1003 info.id = fs->index;
1004 info.type = fs->type;
1005 info.tag = fs->tag;
1006 info.luma_addr = fs->buffer[fs->index].phys;
1007 info.luma_size = fs->buffer[fs->index].length;
1008 ret = vpu_session_alloc_fs(inst, &info);
1009 if (ret)
1010 return ret;
1011
1012 fs->index++;
1013 return 0;
1014 }
1015
vdec_response_frame_abnormal(struct vpu_inst * inst)1016 static int vdec_response_frame_abnormal(struct vpu_inst *inst)
1017 {
1018 struct vdec_t *vdec = inst->priv;
1019 struct vpu_fs_info info;
1020 int ret;
1021
1022 if (!vdec->req_frame_count)
1023 return 0;
1024
1025 memset(&info, 0, sizeof(info));
1026 info.type = MEM_RES_FRAME;
1027 info.tag = vdec->seq_tag + 0xf0;
1028 ret = vpu_session_alloc_fs(inst, &info);
1029 if (ret)
1030 return ret;
1031 vdec->req_frame_count--;
1032
1033 return 0;
1034 }
1035
vdec_response_frame(struct vpu_inst * inst,struct vb2_v4l2_buffer * vbuf)1036 static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
1037 {
1038 struct vdec_t *vdec = inst->priv;
1039 struct vpu_vb2_buffer *vpu_buf;
1040 struct vpu_fs_info info;
1041 int ret;
1042
1043 if (inst->state != VPU_CODEC_STATE_ACTIVE)
1044 return -EINVAL;
1045
1046 if (vdec->aborting)
1047 return -EINVAL;
1048
1049 if (!vdec->req_frame_count)
1050 return -EINVAL;
1051
1052 if (!vbuf)
1053 return -EINVAL;
1054
1055 if (vdec->slots[vbuf->vb2_buf.index]) {
1056 dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
1057 inst->id, vbuf->vb2_buf.index);
1058 return -EINVAL;
1059 }
1060
1061 dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
1062 inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
1063 vpu_buf = to_vpu_vb2_buffer(vbuf);
1064
1065 memset(&info, 0, sizeof(info));
1066 info.id = vbuf->vb2_buf.index;
1067 info.type = MEM_RES_FRAME;
1068 info.tag = vdec->seq_tag;
1069 info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
1070 info.luma_size = inst->cap_format.sizeimage[0];
1071 if (vbuf->vb2_buf.num_planes > 1)
1072 info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
1073 else
1074 info.chroma_addr = info.luma_addr + info.luma_size;
1075 info.chromau_size = inst->cap_format.sizeimage[1];
1076 info.bytesperline = inst->cap_format.bytesperline[0];
1077 ret = vpu_session_alloc_fs(inst, &info);
1078 if (ret)
1079 return ret;
1080
1081 vpu_buf->tag = info.tag;
1082 vpu_buf->luma = info.luma_addr;
1083 vpu_buf->chroma_u = info.chroma_addr;
1084 vpu_buf->chroma_v = 0;
1085 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
1086 vdec->slots[info.id] = vpu_buf;
1087 vdec->req_frame_count--;
1088
1089 return 0;
1090 }
1091
vdec_response_fs_request(struct vpu_inst * inst,bool force)1092 static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
1093 {
1094 struct vdec_t *vdec = inst->priv;
1095 int i;
1096 int ret;
1097
1098 if (force) {
1099 for (i = vdec->req_frame_count; i > 0; i--)
1100 vdec_response_frame_abnormal(inst);
1101 return;
1102 }
1103
1104 for (i = vdec->req_frame_count; i > 0; i--) {
1105 ret = vpu_process_capture_buffer(inst);
1106 if (ret)
1107 break;
1108 if (vdec->eos_received)
1109 break;
1110 }
1111
1112 for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
1113 if (vdec_response_fs(inst, &vdec->mbi))
1114 break;
1115 if (vdec->eos_received)
1116 break;
1117 }
1118 for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
1119 if (vdec_response_fs(inst, &vdec->dcp))
1120 break;
1121 if (vdec->eos_received)
1122 break;
1123 }
1124 }
1125
vdec_response_fs_release(struct vpu_inst * inst,u32 id,u32 tag)1126 static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
1127 {
1128 struct vpu_fs_info info;
1129
1130 memset(&info, 0, sizeof(info));
1131 info.id = id;
1132 info.tag = tag;
1133 vpu_session_release_fs(inst, &info);
1134 }
1135
vdec_recycle_buffer(struct vpu_inst * inst,struct vb2_v4l2_buffer * vbuf)1136 static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
1137 {
1138 if (!inst->fh.m2m_ctx)
1139 return;
1140 if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
1141 return;
1142 if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
1143 return;
1144 v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
1145 }
1146
vdec_clear_slots(struct vpu_inst * inst)1147 static void vdec_clear_slots(struct vpu_inst *inst)
1148 {
1149 struct vdec_t *vdec = inst->priv;
1150 struct vpu_vb2_buffer *vpu_buf;
1151 struct vb2_v4l2_buffer *vbuf;
1152 int i;
1153
1154 for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
1155 if (!vdec->slots[i])
1156 continue;
1157
1158 vpu_buf = vdec->slots[i];
1159 vbuf = &vpu_buf->m2m_buf.vb;
1160
1161 vpu_trace(inst->dev, "clear slot %d\n", i);
1162 vdec_response_fs_release(inst, i, vpu_buf->tag);
1163 vdec_recycle_buffer(inst, vbuf);
1164 vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
1165 vdec->slots[i] = NULL;
1166 }
1167 }
1168
vdec_event_seq_hdr(struct vpu_inst * inst,struct vpu_dec_codec_info * hdr)1169 static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
1170 {
1171 struct vdec_t *vdec = inst->priv;
1172
1173 vpu_inst_lock(inst);
1174 memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
1175
1176 vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
1177 inst->id,
1178 vdec->codec_info.decoded_width,
1179 vdec->codec_info.decoded_height,
1180 vdec->codec_info.offset_x,
1181 vdec->codec_info.offset_y,
1182 vdec->codec_info.width,
1183 vdec->codec_info.height,
1184 hdr->num_ref_frms,
1185 hdr->num_dpb_frms);
1186 inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
1187 vdec->is_source_changed = vdec_check_source_change(inst);
1188 vdec_init_fmt(inst);
1189 vdec_init_crop(inst);
1190 vdec_init_mbi(inst);
1191 vdec_init_dcp(inst);
1192 if (!vdec->seq_hdr_found) {
1193 vdec->seq_tag = vdec->codec_info.tag;
1194 if (vdec->is_source_changed) {
1195 vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
1196 vdec->source_change++;
1197 vdec_handle_resolution_change(inst);
1198 vdec->is_source_changed = false;
1199 }
1200 }
1201 if (vdec->seq_tag != vdec->codec_info.tag) {
1202 vdec_response_fs_request(inst, true);
1203 vpu_trace(inst->dev, "[%d] seq tag change: %d -> %d\n",
1204 inst->id, vdec->seq_tag, vdec->codec_info.tag);
1205 }
1206 vdec->seq_hdr_found++;
1207 vdec->fixed_fmt = true;
1208 vpu_inst_unlock(inst);
1209 }
1210
vdec_event_resolution_change(struct vpu_inst * inst)1211 static void vdec_event_resolution_change(struct vpu_inst *inst)
1212 {
1213 struct vdec_t *vdec = inst->priv;
1214
1215 vpu_trace(inst->dev, "[%d]\n", inst->id);
1216 vpu_inst_lock(inst);
1217 vdec->seq_tag = vdec->codec_info.tag;
1218 vdec_clear_fs(&vdec->mbi);
1219 vdec_clear_fs(&vdec->dcp);
1220 vdec_clear_slots(inst);
1221 vdec_init_mbi(inst);
1222 vdec_init_dcp(inst);
1223 if (vdec->is_source_changed) {
1224 vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
1225 vdec->source_change++;
1226 vdec_handle_resolution_change(inst);
1227 vdec->is_source_changed = false;
1228 }
1229 vpu_inst_unlock(inst);
1230 }
1231
vdec_event_req_fs(struct vpu_inst * inst,struct vpu_fs_info * fs)1232 static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
1233 {
1234 struct vdec_t *vdec = inst->priv;
1235
1236 if (!fs)
1237 return;
1238
1239 vpu_inst_lock(inst);
1240
1241 switch (fs->type) {
1242 case MEM_RES_FRAME:
1243 vdec->req_frame_count++;
1244 break;
1245 case MEM_RES_MBI:
1246 vdec_request_one_fs(&vdec->mbi);
1247 break;
1248 case MEM_RES_DCP:
1249 vdec_request_one_fs(&vdec->dcp);
1250 break;
1251 default:
1252 break;
1253 }
1254
1255 vdec_alloc_fs(inst, &vdec->mbi);
1256 vdec_alloc_fs(inst, &vdec->dcp);
1257
1258 vdec_response_fs_request(inst, false);
1259
1260 vpu_inst_unlock(inst);
1261 }
1262
vdec_evnet_rel_fs(struct vpu_inst * inst,struct vpu_fs_info * fs)1263 static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
1264 {
1265 struct vdec_t *vdec = inst->priv;
1266 struct vpu_vb2_buffer *vpu_buf;
1267 struct vb2_v4l2_buffer *vbuf;
1268
1269 if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
1270 return;
1271 if (fs->type != MEM_RES_FRAME)
1272 return;
1273
1274 if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
1275 dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
1276 return;
1277 }
1278
1279 vpu_inst_lock(inst);
1280 vpu_buf = vdec->slots[fs->id];
1281 vdec->slots[fs->id] = NULL;
1282
1283 if (!vpu_buf) {
1284 dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
1285 goto exit;
1286 }
1287
1288 vbuf = &vpu_buf->m2m_buf.vb;
1289 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
1290 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
1291 vdec->sequence++;
1292 }
1293
1294 vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
1295 if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
1296 vdec_recycle_buffer(inst, vbuf);
1297
1298 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
1299 vpu_process_capture_buffer(inst);
1300
1301 exit:
1302 vpu_inst_unlock(inst);
1303 }
1304
vdec_event_eos(struct vpu_inst * inst)1305 static void vdec_event_eos(struct vpu_inst *inst)
1306 {
1307 struct vdec_t *vdec = inst->priv;
1308
1309 vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
1310 inst->id,
1311 vdec->params.frame_count,
1312 vdec->decoded_frame_count,
1313 vdec->display_frame_count,
1314 vdec->sequence);
1315 vpu_inst_lock(inst);
1316 vdec->eos_received++;
1317 vdec->fixed_fmt = false;
1318 inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
1319 vdec_set_last_buffer_dequeued(inst);
1320 vpu_inst_unlock(inst);
1321 }
1322
vdec_event_notify(struct vpu_inst * inst,u32 event,void * data)1323 static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
1324 {
1325 switch (event) {
1326 case VPU_MSG_ID_SEQ_HDR_FOUND:
1327 vdec_event_seq_hdr(inst, data);
1328 break;
1329 case VPU_MSG_ID_RES_CHANGE:
1330 vdec_event_resolution_change(inst);
1331 break;
1332 case VPU_MSG_ID_FRAME_REQ:
1333 vdec_event_req_fs(inst, data);
1334 break;
1335 case VPU_MSG_ID_FRAME_RELEASE:
1336 vdec_evnet_rel_fs(inst, data);
1337 break;
1338 case VPU_MSG_ID_PIC_EOS:
1339 vdec_event_eos(inst);
1340 break;
1341 default:
1342 break;
1343 }
1344 }
1345
vdec_process_output(struct vpu_inst * inst,struct vb2_buffer * vb)1346 static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
1347 {
1348 struct vdec_t *vdec = inst->priv;
1349 struct vb2_v4l2_buffer *vbuf;
1350 struct vpu_rpc_buffer_desc desc;
1351 u32 free_space;
1352 int ret;
1353
1354 vbuf = to_vb2_v4l2_buffer(vb);
1355 dev_dbg(inst->dev, "[%d] dec output [%d] %d : %ld\n",
1356 inst->id, vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
1357
1358 if (inst->state == VPU_CODEC_STATE_DEINIT)
1359 return -EINVAL;
1360 if (vdec->reset_codec)
1361 return -EINVAL;
1362
1363 if (inst->state == VPU_CODEC_STATE_STARTED)
1364 vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
1365
1366 ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
1367 if (ret)
1368 return ret;
1369
1370 free_space = vpu_helper_get_free_space(inst);
1371 if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
1372 return -ENOMEM;
1373
1374 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
1375 ret = vpu_iface_input_frame(inst, vb);
1376 if (ret < 0)
1377 return -ENOMEM;
1378
1379 dev_dbg(inst->dev, "[%d][INPUT TS]%32lld\n", inst->id, vb->timestamp);
1380 vdec->params.frame_count++;
1381
1382 if (vdec->drain)
1383 vdec_drain(inst);
1384
1385 return 0;
1386 }
1387
vdec_process_capture(struct vpu_inst * inst,struct vb2_buffer * vb)1388 static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
1389 {
1390 struct vdec_t *vdec = inst->priv;
1391 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1392 int ret;
1393
1394 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
1395 return -EINVAL;
1396 if (vdec->reset_codec)
1397 return -EINVAL;
1398
1399 ret = vdec_response_frame(inst, vbuf);
1400 if (ret)
1401 return ret;
1402 v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
1403 return 0;
1404 }
1405
vdec_on_queue_empty(struct vpu_inst * inst,u32 type)1406 static void vdec_on_queue_empty(struct vpu_inst *inst, u32 type)
1407 {
1408 struct vdec_t *vdec = inst->priv;
1409
1410 if (V4L2_TYPE_IS_OUTPUT(type))
1411 return;
1412
1413 vdec_handle_resolution_change(inst);
1414 if (vdec->eos_received)
1415 vdec_set_last_buffer_dequeued(inst);
1416 }
1417
vdec_abort(struct vpu_inst * inst)1418 static void vdec_abort(struct vpu_inst *inst)
1419 {
1420 struct vdec_t *vdec = inst->priv;
1421 struct vpu_rpc_buffer_desc desc;
1422 int ret;
1423
1424 vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state));
1425
1426 vdec->aborting = true;
1427 vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
1428 vdec->params.end_flag = 1;
1429 vpu_iface_set_decode_params(inst, &vdec->params, 1);
1430
1431 vpu_session_abort(inst);
1432
1433 ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
1434 if (!ret)
1435 vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
1436
1437 vpu_session_rst_buf(inst);
1438 vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
1439 inst->id,
1440 vdec->params.frame_count,
1441 vdec->decoded_frame_count,
1442 vdec->display_frame_count,
1443 vdec->sequence);
1444 if (!vdec->seq_hdr_found)
1445 vdec->reset_codec = true;
1446 vdec->params.end_flag = 0;
1447 vdec->drain = 0;
1448 vdec->params.frame_count = 0;
1449 vdec->decoded_frame_count = 0;
1450 vdec->display_frame_count = 0;
1451 vdec->sequence = 0;
1452 vdec->aborting = false;
1453 inst->extra_size = 0;
1454 }
1455
vdec_stop(struct vpu_inst * inst,bool free)1456 static void vdec_stop(struct vpu_inst *inst, bool free)
1457 {
1458 struct vdec_t *vdec = inst->priv;
1459
1460 vdec_clear_slots(inst);
1461 if (inst->state != VPU_CODEC_STATE_DEINIT)
1462 vpu_session_stop(inst);
1463 vdec_clear_fs(&vdec->mbi);
1464 vdec_clear_fs(&vdec->dcp);
1465 if (free) {
1466 vpu_free_dma(&vdec->udata);
1467 vpu_free_dma(&inst->stream_buffer);
1468 }
1469 vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
1470 vdec->reset_codec = false;
1471 }
1472
vdec_release(struct vpu_inst * inst)1473 static void vdec_release(struct vpu_inst *inst)
1474 {
1475 if (inst->id != VPU_INST_NULL_ID)
1476 vpu_trace(inst->dev, "[%d]\n", inst->id);
1477 vdec_stop(inst, true);
1478 }
1479
vdec_cleanup(struct vpu_inst * inst)1480 static void vdec_cleanup(struct vpu_inst *inst)
1481 {
1482 struct vdec_t *vdec;
1483
1484 if (!inst)
1485 return;
1486
1487 vdec = inst->priv;
1488 vfree(vdec);
1489 inst->priv = NULL;
1490 vfree(inst);
1491 }
1492
vdec_init_params(struct vdec_t * vdec)1493 static void vdec_init_params(struct vdec_t *vdec)
1494 {
1495 vdec->params.frame_count = 0;
1496 vdec->params.end_flag = 0;
1497 }
1498
vdec_start(struct vpu_inst * inst)1499 static int vdec_start(struct vpu_inst *inst)
1500 {
1501 struct vdec_t *vdec = inst->priv;
1502 int stream_buffer_size;
1503 int ret;
1504
1505 if (inst->state != VPU_CODEC_STATE_DEINIT)
1506 return 0;
1507
1508 vpu_trace(inst->dev, "[%d]\n", inst->id);
1509 if (!vdec->udata.virt) {
1510 vdec->udata.length = 0x1000;
1511 ret = vpu_alloc_dma(inst->core, &vdec->udata);
1512 if (ret) {
1513 dev_err(inst->dev, "[%d] alloc udata fail\n", inst->id);
1514 goto error;
1515 }
1516 }
1517
1518 if (!inst->stream_buffer.virt) {
1519 stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
1520 if (stream_buffer_size > 0) {
1521 inst->stream_buffer.length = stream_buffer_size;
1522 ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
1523 if (ret) {
1524 dev_err(inst->dev, "[%d] alloc stream buffer fail\n", inst->id);
1525 goto error;
1526 }
1527 inst->use_stream_buffer = true;
1528 }
1529 }
1530
1531 if (inst->use_stream_buffer)
1532 vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
1533 vpu_iface_init_instance(inst);
1534 vdec->params.udata.base = vdec->udata.phys;
1535 vdec->params.udata.size = vdec->udata.length;
1536 ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
1537 if (ret) {
1538 dev_err(inst->dev, "[%d] set decode params fail\n", inst->id);
1539 goto error;
1540 }
1541
1542 vdec_init_params(vdec);
1543 ret = vpu_session_start(inst);
1544 if (ret) {
1545 dev_err(inst->dev, "[%d] start fail\n", inst->id);
1546 goto error;
1547 }
1548
1549 vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
1550
1551 return 0;
1552 error:
1553 vpu_free_dma(&vdec->udata);
1554 vpu_free_dma(&inst->stream_buffer);
1555 return ret;
1556 }
1557
vdec_start_session(struct vpu_inst * inst,u32 type)1558 static int vdec_start_session(struct vpu_inst *inst, u32 type)
1559 {
1560 struct vdec_t *vdec = inst->priv;
1561 int ret = 0;
1562
1563 if (V4L2_TYPE_IS_OUTPUT(type)) {
1564 if (vdec->reset_codec)
1565 vdec_stop(inst, false);
1566 if (inst->state == VPU_CODEC_STATE_DEINIT) {
1567 ret = vdec_start(inst);
1568 if (ret)
1569 return ret;
1570 }
1571 }
1572
1573 if (V4L2_TYPE_IS_OUTPUT(type)) {
1574 vdec_update_state(inst, vdec->state, 1);
1575 vdec->eos_received = 0;
1576 vpu_process_output_buffer(inst);
1577 } else {
1578 vdec_cmd_start(inst);
1579 }
1580 if (inst->state == VPU_CODEC_STATE_ACTIVE)
1581 vdec_response_fs_request(inst, false);
1582
1583 return ret;
1584 }
1585
vdec_stop_session(struct vpu_inst * inst,u32 type)1586 static int vdec_stop_session(struct vpu_inst *inst, u32 type)
1587 {
1588 struct vdec_t *vdec = inst->priv;
1589
1590 if (inst->state == VPU_CODEC_STATE_DEINIT)
1591 return 0;
1592
1593 if (V4L2_TYPE_IS_OUTPUT(type)) {
1594 vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
1595 vdec->drain = 0;
1596 vdec_abort(inst);
1597 } else {
1598 if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {
1599 if (vb2_is_streaming(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx)))
1600 vdec_abort(inst);
1601 vdec->eos_received = 0;
1602 }
1603 vdec_clear_slots(inst);
1604 }
1605
1606 return 0;
1607 }
1608
vdec_get_debug_info(struct vpu_inst * inst,char * str,u32 size,u32 i)1609 static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1610 {
1611 struct vdec_t *vdec = inst->priv;
1612 int num = -1;
1613
1614 switch (i) {
1615 case 0:
1616 num = scnprintf(str, size,
1617 "req_frame_count = %d\ninterlaced = %d\n",
1618 vdec->req_frame_count,
1619 vdec->codec_info.progressive ? 0 : 1);
1620 break;
1621 case 1:
1622 num = scnprintf(str, size,
1623 "mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
1624 vdec->mbi.size,
1625 vdec->mbi.req_count,
1626 vdec->mbi.count,
1627 vdec->mbi.index);
1628 break;
1629 case 2:
1630 num = scnprintf(str, size,
1631 "dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
1632 vdec->dcp.size,
1633 vdec->dcp.req_count,
1634 vdec->dcp.count,
1635 vdec->dcp.index);
1636 break;
1637 case 3:
1638 num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
1639 break;
1640 case 4:
1641 num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
1642 break;
1643 case 5:
1644 num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
1645 break;
1646 case 6:
1647 num = scnprintf(str, size, "sequence = %d\n", vdec->sequence);
1648 break;
1649 case 7:
1650 num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
1651 vdec->drain, vdec->eos_received, vdec->source_change);
1652 break;
1653 case 8:
1654 num = scnprintf(str, size, "fps = %d/%d\n",
1655 vdec->codec_info.frame_rate.numerator,
1656 vdec->codec_info.frame_rate.denominator);
1657 break;
1658 case 9:
1659 num = scnprintf(str, size, "colorspace: %d, %d, %d, %d (%d)\n",
1660 vdec->codec_info.color_primaries,
1661 vdec->codec_info.transfer_chars,
1662 vdec->codec_info.matrix_coeffs,
1663 vdec->codec_info.full_range,
1664 vdec->codec_info.vui_present);
1665 break;
1666 default:
1667 break;
1668 }
1669
1670 return num;
1671 }
1672
1673 static struct vpu_inst_ops vdec_inst_ops = {
1674 .ctrl_init = vdec_ctrl_init,
1675 .check_ready = vdec_check_ready,
1676 .buf_done = vdec_buf_done,
1677 .get_one_frame = vdec_frame_decoded,
1678 .stop_done = vdec_stop_done,
1679 .event_notify = vdec_event_notify,
1680 .release = vdec_release,
1681 .cleanup = vdec_cleanup,
1682 .start = vdec_start_session,
1683 .stop = vdec_stop_session,
1684 .process_output = vdec_process_output,
1685 .process_capture = vdec_process_capture,
1686 .on_queue_empty = vdec_on_queue_empty,
1687 .get_debug_info = vdec_get_debug_info,
1688 .wait_prepare = vpu_inst_unlock,
1689 .wait_finish = vpu_inst_lock,
1690 };
1691
vdec_init(struct file * file)1692 static void vdec_init(struct file *file)
1693 {
1694 struct vpu_inst *inst = to_inst(file);
1695 struct v4l2_format f;
1696
1697 memset(&f, 0, sizeof(f));
1698 f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1699 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
1700 f.fmt.pix_mp.width = 1280;
1701 f.fmt.pix_mp.height = 720;
1702 f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1703 vdec_s_fmt(file, &inst->fh, &f);
1704
1705 memset(&f, 0, sizeof(f));
1706 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1707 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M_8L128;
1708 f.fmt.pix_mp.width = 1280;
1709 f.fmt.pix_mp.height = 720;
1710 f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1711 vdec_s_fmt(file, &inst->fh, &f);
1712 }
1713
vdec_open(struct file * file)1714 static int vdec_open(struct file *file)
1715 {
1716 struct vpu_inst *inst;
1717 struct vdec_t *vdec;
1718 int ret;
1719
1720 inst = vzalloc(sizeof(*inst));
1721 if (!inst)
1722 return -ENOMEM;
1723
1724 vdec = vzalloc(sizeof(*vdec));
1725 if (!vdec) {
1726 vfree(inst);
1727 return -ENOMEM;
1728 }
1729
1730 inst->ops = &vdec_inst_ops;
1731 inst->formats = vdec_formats;
1732 inst->type = VPU_CORE_TYPE_DEC;
1733 inst->priv = vdec;
1734
1735 ret = vpu_v4l2_open(file, inst);
1736 if (ret)
1737 return ret;
1738
1739 vdec->fixed_fmt = false;
1740 vdec->state = VPU_CODEC_STATE_ACTIVE;
1741 inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
1742 inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
1743 vdec_init(file);
1744
1745 return 0;
1746 }
1747
1748 static const struct v4l2_file_operations vdec_fops = {
1749 .owner = THIS_MODULE,
1750 .open = vdec_open,
1751 .release = vpu_v4l2_close,
1752 .unlocked_ioctl = video_ioctl2,
1753 .poll = v4l2_m2m_fop_poll,
1754 .mmap = v4l2_m2m_fop_mmap,
1755 };
1756
vdec_get_ioctl_ops(void)1757 const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void)
1758 {
1759 return &vdec_ioctl_ops;
1760 }
1761
vdec_get_fops(void)1762 const struct v4l2_file_operations *vdec_get_fops(void)
1763 {
1764 return &vdec_fops;
1765 }
1766