summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/aml_vcodec_dec.c (plain)
blob: 6989153b2fd3858a14b93e52b47822a769f1cff4
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20#include <media/v4l2-event.h>
21#include <media/v4l2-mem2mem.h>
22#include <media/videobuf2-dma-contig.h>
23
24#include "aml_vcodec_drv.h"
25#include "aml_vcodec_dec.h"
26//#include "aml_vcodec_intr.h"
27#include "aml_vcodec_util.h"
28#include "vdec_drv_if.h"
29#include "aml_vcodec_dec_pm.h"
30#include <linux/delay.h>
31#include <linux/atomic.h>
32#include <linux/crc32.h>
33#include "aml_vcodec_adapt.h"
34#include <linux/spinlock.h>
35
36#include "aml_vcodec_vfm.h"
37#include "../frame_provider/decoder/utils/decoder_bmmu_box.h"
38#include "../frame_provider/decoder/utils/decoder_mmu_box.h"
39
40#define OUT_FMT_IDX 0 //default h264
41#define CAP_FMT_IDX 8 //capture nv21
42
43#define AML_VDEC_MIN_W 64U
44#define AML_VDEC_MIN_H 64U
45#define DFT_CFG_WIDTH AML_VDEC_MIN_W
46#define DFT_CFG_HEIGHT AML_VDEC_MIN_H
47
48#define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100)
49#define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
50
51#define WORK_ITEMS_MAX (32)
52
53//#define USEC_PER_SEC 1000000
54
55#define call_void_memop(vb, op, args...) \
56 do { \
57 if ((vb)->vb2_queue->mem_ops->op) \
58 (vb)->vb2_queue->mem_ops->op(args); \
59 } while (0)
60
61static struct aml_video_fmt aml_video_formats[] = {
62 {
63 .fourcc = V4L2_PIX_FMT_H264,
64 .type = AML_FMT_DEC,
65 .num_planes = 1,
66 },
67 {
68 .fourcc = V4L2_PIX_FMT_HEVC,
69 .type = AML_FMT_DEC,
70 .num_planes = 1,
71 },
72 {
73 .fourcc = V4L2_PIX_FMT_VP9,
74 .type = AML_FMT_DEC,
75 .num_planes = 1,
76 },
77 {
78 .fourcc = V4L2_PIX_FMT_MPEG1,
79 .type = AML_FMT_DEC,
80 .num_planes = 1,
81 },
82 {
83 .fourcc = V4L2_PIX_FMT_MPEG2,
84 .type = AML_FMT_DEC,
85 .num_planes = 1,
86 },
87 {
88 .fourcc = V4L2_PIX_FMT_MPEG4,
89 .type = AML_FMT_DEC,
90 .num_planes = 1,
91 },
92 {
93 .fourcc = V4L2_PIX_FMT_MJPEG,
94 .type = AML_FMT_DEC,
95 .num_planes = 1,
96 },
97 {
98 .fourcc = V4L2_PIX_FMT_NV21,
99 .type = AML_FMT_FRAME,
100 .num_planes = 1,
101 },
102 {
103 .fourcc = V4L2_PIX_FMT_NV21M,
104 .type = AML_FMT_FRAME,
105 .num_planes = 2,
106 },
107 {
108 .fourcc = V4L2_PIX_FMT_NV12,
109 .type = AML_FMT_FRAME,
110 .num_planes = 1,
111 },
112 {
113 .fourcc = V4L2_PIX_FMT_NV12M,
114 .type = AML_FMT_FRAME,
115 .num_planes = 2,
116 },
117};
118
119static const struct aml_codec_framesizes aml_vdec_framesizes[] = {
120 {
121 .fourcc = V4L2_PIX_FMT_H264,
122 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
123 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
124 },
125 {
126 .fourcc = V4L2_PIX_FMT_HEVC,
127 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
128 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
129 },
130 {
131 .fourcc = V4L2_PIX_FMT_VP9,
132 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
133 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
134 },
135 {
136 .fourcc = V4L2_PIX_FMT_MPEG1,
137 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
138 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
139 },
140 {
141 .fourcc = V4L2_PIX_FMT_MPEG2,
142 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
143 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
144 },
145 {
146 .fourcc = V4L2_PIX_FMT_MPEG4,
147 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
148 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
149 },
150 {
151 .fourcc = V4L2_PIX_FMT_MJPEG,
152 .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
153 AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
154 },
155};
156
157#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes)
158#define NUM_FORMATS ARRAY_SIZE(aml_video_formats)
159
160extern bool multiplanar;
161
162extern int dmabuf_fd_install_data(int fd, void* data, u32 size);
163extern bool is_v4l2_buf_file(struct file *file);
164
165static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
166{
167 ulong flags;
168
169 spin_lock_irqsave(&ctx->slock, flags);
170
171 return flags;
172}
173
174static void aml_vcodec_ctx_unlock(struct aml_vcodec_ctx *ctx, ulong flags)
175{
176 spin_unlock_irqrestore(&ctx->slock, flags);
177}
178
179static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f)
180{
181 struct aml_video_fmt *fmt;
182 unsigned int k;
183
184 aml_v4l2_debug(4, "%s, type: %u, planes: %u, fmt: %u\n",
185 __func__, f->type, f->fmt.pix_mp.num_planes,
186 f->fmt.pix_mp.pixelformat);
187
188 for (k = 0; k < NUM_FORMATS; k++) {
189 fmt = &aml_video_formats[k];
190 if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
191 return fmt;
192 }
193
194 return NULL;
195}
196
197static struct aml_q_data *aml_vdec_get_q_data(struct aml_vcodec_ctx *ctx,
198 enum v4l2_buf_type type)
199{
200 if (V4L2_TYPE_IS_OUTPUT(type))
201 return &ctx->q_data[AML_Q_DATA_SRC];
202
203 return &ctx->q_data[AML_Q_DATA_DST];
204}
205
206void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes)
207{
208 struct v4l2_event event = {0};
209
210 if (ctx->receive_cmd_stop) {
211 ctx->state = AML_STATE_ABORT;
212 changes = V4L2_EVENT_REQUEST_EXIT;
213 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
214 ctx->id, __func__);
215 }
216
217 switch (changes) {
218 case V4L2_EVENT_SRC_CH_RESOLUTION:
219 case V4L2_EVENT_SRC_CH_HDRINFO:
220 case V4L2_EVENT_REQUEST_RESET:
221 case V4L2_EVENT_REQUEST_EXIT:
222 event.type = V4L2_EVENT_SOURCE_CHANGE;
223 event.u.src_change.changes = changes;
224 break;
225 default:
226 pr_err("unsupport dispatch event %x\n", changes);
227 return;
228 }
229
230 v4l2_event_queue_fh(&ctx->fh, &event);
231 aml_v4l2_debug(3, "[%d] %s() changes: %x",
232 ctx->id, __func__, changes);
233}
234
235static void aml_vdec_flush_decoder(struct aml_vcodec_ctx *ctx)
236{
237 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
238
239 aml_decoder_flush(ctx->ada_ctx);
240}
241
242static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
243{
244 unsigned int dpbsize = 0;
245 int ret;
246
247 if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
248 aml_v4l2_err("[%d] Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
249 return;
250 }
251
252 if (ctx->last_decoded_picinfo.visible_width == 0 ||
253 ctx->last_decoded_picinfo.visible_height == 0 ||
254 ctx->last_decoded_picinfo.coded_width == 0 ||
255 ctx->last_decoded_picinfo.coded_height == 0) {
256 aml_v4l2_err("Cannot get correct pic info");
257 return;
258 }
259
260 /*if ((ctx->last_decoded_picinfo.visible_width == ctx->picinfo.visible_width) ||
261 (ctx->last_decoded_picinfo.visible_height == ctx->picinfo.visible_height))
262 return;*/
263
264 aml_v4l2_debug(4, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
265 ctx->id, ctx->last_decoded_picinfo.visible_width,
266 ctx->last_decoded_picinfo.visible_height,
267 ctx->picinfo.visible_width, ctx->picinfo.visible_height,
268 ctx->last_decoded_picinfo.coded_width,
269 ctx->last_decoded_picinfo.coded_width);
270
271 ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
272 if (dpbsize == 0)
273 aml_v4l2_err("[%d] Incorrect dpb size, ret=%d", ctx->id, ret);
274
275 /* update picture information */
276 ctx->dpb_size = dpbsize;
277 ctx->picinfo = ctx->last_decoded_picinfo;
278}
279
280void vdec_frame_buffer_release(void *data)
281{
282 struct file_private_data *priv_data =
283 (struct file_private_data *) data;
284 struct vframe_s *vf = &priv_data->vf;
285
286 if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) {
287 decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box,
288 vf->mm_box.bmmu_idx);
289 decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box);
290 }
291
292 if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) {
293 decoder_mmu_box_free_idx(vf->mm_box.mmu_box,
294 vf->mm_box.mmu_idx);
295 decoder_mmu_try_to_release_box(vf->mm_box.mmu_box);
296 }
297
298 aml_v4l2_debug(2, "%s vf idx: %d, bmmu idx: %d, bmmu_box: %p",
299 __func__, vf->index, vf->mm_box.bmmu_idx, vf->mm_box.bmmu_box);
300 aml_v4l2_debug(2, "%s vf idx: %d, mmu_idx: %d, mmu_box: %p",
301 __func__, vf->index, vf->mm_box.mmu_idx, vf->mm_box.mmu_box);
302
303 memset(data, 0, sizeof(struct file_private_data));
304 kfree(data);
305}
306
307int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb)
308{
309 ulong flags;
310 struct vb2_buffer *dst_buf = NULL;
311 struct vdec_v4l2_buffer *pfb;
312 struct aml_video_dec_buf *dst_buf_info, *info;
313 struct vb2_v4l2_buffer *dst_vb2_v4l2;
314
315 flags = aml_vcodec_ctx_lock(ctx);
316
317 if (ctx->state == AML_STATE_ABORT) {
318 aml_vcodec_ctx_unlock(ctx, flags);
319 return -1;
320 }
321
322 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
323 if (!dst_buf) {
324 aml_vcodec_ctx_unlock(ctx, flags);
325 return -1;
326 }
327
328 aml_v4l2_debug(2, "[%d] %s() vbuf idx: %d, state: %d, ready: %d",
329 ctx->id, __func__, dst_buf->index, dst_buf->state,
330 v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
331
332 dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
333 dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
334
335 if (ctx->scatter_mem_enable) {
336 pfb = &dst_buf_info->frame_buffer;
337 pfb->mem_type = VDEC_SCATTER_MEMORY_TYPE;
338 pfb->status = FB_ST_NORMAL;
339 } else if (dst_buf->num_planes == 1) {
340 pfb = &dst_buf_info->frame_buffer;
341 pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
342 pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
343 pfb->m.mem[0].size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
344 pfb->m.mem[0].offset = ctx->picinfo.y_len_sz;
345 pfb->num_planes = dst_buf->num_planes;
346 pfb->status = FB_ST_NORMAL;
347
348 aml_v4l2_debug(4, "[%d] idx: %u, 1 plane, y:(0x%lx, %d)",
349 ctx->id, dst_buf->index,
350 pfb->m.mem[0].addr, pfb->m.mem[0].size);
351 } else if (dst_buf->num_planes == 2) {
352 pfb = &dst_buf_info->frame_buffer;
353 pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
354 pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
355 pfb->m.mem[0].size = ctx->picinfo.y_len_sz;
356 pfb->m.mem[0].offset = 0;
357
358 pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
359 pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr);
360 pfb->m.mem[1].size = ctx->picinfo.c_len_sz;
361 pfb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
362 pfb->num_planes = dst_buf->num_planes;
363 pfb->status = FB_ST_NORMAL;
364
365 aml_v4l2_debug(4, "[%d] idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)",
366 ctx->id, dst_buf->index,
367 pfb->m.mem[0].addr, pfb->m.mem[0].size,
368 pfb->m.mem[1].addr, pfb->m.mem[1].size);
369 } else {
370 pfb = &dst_buf_info->frame_buffer;
371 pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
372 pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
373 pfb->m.mem[0].size = ctx->picinfo.y_len_sz;
374 pfb->m.mem[0].offset = 0;
375
376 pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
377 pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[2].dma_addr);
378 pfb->m.mem[1].size = ctx->picinfo.c_len_sz >> 1;
379 pfb->m.mem[1].offset = 0;
380
381 pfb->m.mem[2].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 2);
382 pfb->m.mem[2].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr);
383 pfb->m.mem[2].size = ctx->picinfo.c_len_sz >> 1;
384 pfb->m.mem[2].offset = 0;
385 pfb->num_planes = dst_buf->num_planes;
386 pfb->status = FB_ST_NORMAL;
387
388 aml_v4l2_debug(4, "[%d] idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)",
389 ctx->id, dst_buf->index,
390 pfb->m.mem[0].addr, pfb->m.mem[0].size,
391 pfb->m.mem[1].addr, pfb->m.mem[1].size,
392 pfb->m.mem[2].addr, pfb->m.mem[2].size);
393 }
394
395 dst_buf_info->used = true;
396 ctx->buf_used_count++;
397
398 *out_fb = pfb;
399
400 info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
401
402 v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
403
404 aml_vcodec_ctx_unlock(ctx, flags);
405
406 return 0;
407}
408EXPORT_SYMBOL(get_fb_from_queue);
409
410int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb)
411{
412 struct aml_video_dec_buf *dstbuf;
413
414 pr_info("[%d] %s() [%d]\n", ctx->id, __func__, __LINE__);
415
416 if (in_fb == NULL) {
417 aml_v4l2_debug(4, "[%d] No free frame buffer", ctx->id);
418 return -1;
419 }
420
421 aml_v4l2_debug(4, "[%d] tmp_frame_addr = 0x%p", ctx->id, in_fb);
422
423 dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer);
424
425 mutex_lock(&ctx->lock);
426
427 if (!dstbuf->used)
428 goto out;
429
430 aml_v4l2_debug(4,
431 "[%d] status=%x queue id=%d to rdy_queue",
432 ctx->id, in_fb->status,
433 dstbuf->vb.vb2_buf.index);
434
435 v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
436
437 dstbuf->used = false;
438out:
439 mutex_unlock(&ctx->lock);
440
441 return 0;
442
443}
444EXPORT_SYMBOL(put_fb_to_queue);
445
446void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb)
447{
448 struct aml_video_dec_buf *dstbuf = NULL;
449 struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
450
451 aml_v4l2_debug(3, "[%d] FROM (%s %s) vf: %p, ts: %llx, idx: %d",
452 ctx->id, vf_get_provider(ctx->ada_ctx->recv_name)->name,
453 ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO",
454 vf, vf->timestamp, vf->index);
455
456 aml_v4l2_debug(4, "[%d] FROM Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)",
457 ctx->id, fb->m.mem[0].addr, fb->m.mem[0].size,
458 fb->m.mem[1].addr, fb->m.mem[1].size,
459 fb->m.mem[2].addr, fb->m.mem[2].size);
460
461 dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
462 if (dstbuf->frame_buffer.num_planes == 1) {
463 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
464 } else if (dstbuf->frame_buffer.num_planes == 2) {
465 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
466 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->m.mem[1].bytes_used);
467 }
468 dstbuf->vb.vb2_buf.timestamp = vf->timestamp;
469 dstbuf->ready_to_display = true;
470
471 if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
472 dstbuf->lastframe = true;
473 dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
474 if (dstbuf->frame_buffer.num_planes == 1) {
475 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
476 } else if (dstbuf->frame_buffer.num_planes == 2) {
477 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
478 vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
479 }
480 ctx->has_receive_eos = true;
481 pr_info("[%d] recevie a empty frame. idx: %d, state: %d\n",
482 ctx->id, dstbuf->vb.vb2_buf.index,
483 dstbuf->vb.vb2_buf.state);
484 }
485
486 aml_v4l2_debug(4, "[%d] receive vbuf idx: %d, state: %d",
487 ctx->id, dstbuf->vb.vb2_buf.index,
488 dstbuf->vb.vb2_buf.state);
489
490 if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) {
491 /* binding vframe handle. */
492 vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
493 dstbuf->privdata.vf = *vf;
494 dstbuf->privdata.vf.omx_index =
495 dstbuf->vb.vb2_buf.index;
496
497 v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
498 }
499
500 mutex_lock(&ctx->state_lock);
501 if (ctx->state == AML_STATE_FLUSHING &&
502 ctx->has_receive_eos) {
503 ctx->state = AML_STATE_FLUSHED;
504 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHED)",
505 ctx->id, __func__);
506 }
507 mutex_unlock(&ctx->state_lock);
508
509 if (dstbuf->lastframe &&
510 ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
511
512 /* make the run to stanby until new buffs to enque. */
513 ctx->v4l_codec_dpb_ready = false;
514
515 /*
516 * After all buffers containing decoded frames from
517 * before the resolution change point ready to be
518 * dequeued on the CAPTURE queue, the driver sends a
519 * V4L2_EVENT_SOURCE_CHANGE event for source change
520 * type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper
521 * layer will get new information from cts->picinfo.
522 */
523 aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
524 }
525
526 ctx->decoded_frame_cnt++;
527}
528
529static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out)
530{
531 int ret = -1;
532
533 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
534
535 ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out);
536 if (ret) {
537 aml_v4l2_err("[%d] Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id);
538 return -1;
539 }
540
541 if (!*out) {
542 aml_v4l2_debug(4, "[%d] No display frame buffer", ctx->id);
543 return -1;
544 }
545
546 return ret;
547}
548
549static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
550{
551 if (!ctx->v4l_codec_dpb_ready) {
552 int buf_ready_num;
553
554 /* is there enough dst bufs for decoding? */
555 buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
556 if ((ctx->dpb_size) &&
557 ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size))
558 ctx->v4l_codec_dpb_ready = true;
559 aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d, dpb is ready: %s",
560 ctx->id, __func__, ctx->dpb_size,
561 buf_ready_num, ctx->buf_used_count,
562 ctx->v4l_codec_dpb_ready ? "yes" : "no");
563 }
564}
565
566static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
567{
568 struct aml_vcodec_dev *dev = ctx->dev;
569
570 if (!is_input_ready(ctx->ada_ctx)) {
571 pr_err("[%d] %s() the decoder intput has not ready.\n",
572 ctx->id, __func__);
573 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
574 return 0;
575 }
576
577 if (ctx->state == AML_STATE_PROBE) {
578 mutex_lock(&ctx->state_lock);
579 if (ctx->state == AML_STATE_PROBE) {
580 ctx->state = AML_STATE_READY;
581 ctx->v4l_codec_ready = true;
582 wake_up_interruptible(&ctx->wq);
583 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)",
584 ctx->id, __func__);
585 }
586 mutex_unlock(&ctx->state_lock);
587 }
588
589 mutex_lock(&ctx->state_lock);
590 if (ctx->state == AML_STATE_READY) {
591 if (ctx->m2m_ctx->out_q_ctx.q.streaming &&
592 ctx->m2m_ctx->cap_q_ctx.q.streaming) {
593 ctx->state = AML_STATE_ACTIVE;
594 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ACTIVE)",
595 ctx->id, __func__);
596 }
597 }
598 mutex_unlock(&ctx->state_lock);
599
600 /* check dpb ready */
601 //aml_check_dpb_ready(ctx);
602
603 return 1;
604}
605
606static bool is_enough_work_items(struct aml_vcodec_ctx *ctx)
607{
608 struct aml_vcodec_dev *dev = ctx->dev;
609
610 if (vdec_frame_number(ctx->ada_ctx) >= WORK_ITEMS_MAX) {
611 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
612 return false;
613 }
614
615 return true;
616}
617
618static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx)
619{
620 ulong expires;
621
622 expires = jiffies + msecs_to_jiffies(1000);
623 while (!ctx->v4l_codec_dpb_ready) {
624 u32 ready_num = 0;
625
626 if (time_after(jiffies, expires)) {
627 pr_err("the DPB state has not ready.\n");
628 break;
629 }
630
631 ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
632 if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size)
633 ctx->v4l_codec_dpb_ready = true;
634 }
635}
636
637static void aml_vdec_worker(struct work_struct *work)
638{
639 struct aml_vcodec_ctx *ctx =
640 container_of(work, struct aml_vcodec_ctx, decode_work);
641 struct aml_vcodec_dev *dev = ctx->dev;
642 struct vb2_buffer *src_buf;
643 struct aml_vcodec_mem buf;
644 bool res_chg = false;
645 int ret;
646 struct aml_video_dec_buf *src_buf_info;
647 struct vb2_v4l2_buffer *src_vb2_v4l2;
648
649 aml_v4l2_debug(4, "[%d] entry [%d] [%s]", ctx->id, __LINE__, __func__);
650
651 if (ctx->state < AML_STATE_INIT ||
652 ctx->state > AML_STATE_FLUSHED) {
653 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
654 goto out;
655 }
656
657 if (!is_vdec_ready(ctx)) {
658 pr_err("[%d] %s() the decoder has not ready.\n",
659 ctx->id, __func__);
660 goto out;
661 }
662
663 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
664 if (src_buf == NULL) {
665 pr_err("[%d] src_buf empty!\n", ctx->id);
666 goto out;
667 }
668
669 /*this case for google, but some frames are droped on ffmpeg, so disabled temp.*/
670 if (0 && !is_enough_work_items(ctx))
671 goto out;
672
673 src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf);
674 src_buf_info = container_of(src_vb2_v4l2, struct aml_video_dec_buf, vb);
675
676 if (src_buf_info->lastframe) {
677 /*the empty data use to flushed the decoder.*/
678 aml_v4l2_debug(2, "[%d] Got empty flush input buffer.", ctx->id);
679
680 /*
681 * when inputs a small amount of src buff, then soon to
682 * switch state FLUSHING, must to wait the DBP to be ready.
683 */
684 if (!ctx->v4l_codec_dpb_ready) {
685 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
686 goto out;
687 }
688
689 mutex_lock(&ctx->state_lock);
690 if (ctx->state == AML_STATE_ACTIVE) {
691 ctx->state = AML_STATE_FLUSHING;// prepare flushing
692 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-LASTFRM)",
693 ctx->id, __func__);
694 }
695 mutex_unlock(&ctx->state_lock);
696
697 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
698 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
699
700 /* sets eos data for vdec input. */
701 aml_vdec_flush_decoder(ctx);
702
703 goto out;
704 }
705
706 buf.vaddr = vb2_plane_vaddr(src_buf, 0);
707 buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
708
709 buf.size = src_buf->planes[0].bytesused;
710 if (!buf.vaddr) {
711 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
712 aml_v4l2_err("[%d] id=%d src_addr is NULL!!",
713 ctx->id, src_buf->index);
714 goto out;
715 }
716
717 src_buf_info->used = true;
718
719 /* pr_err("%s() [%d], size: 0x%zx, crc: 0x%x\n",
720 __func__, __LINE__, buf.size, crc32(0, buf.va, buf.size));*/
721
722 /* pts = (time / 10e6) * (90k / fps) */
723 aml_v4l2_debug(4, "[%d] %s() timestamp: 0x%llx", ctx->id , __func__,
724 src_buf->timestamp);
725
726 ret = vdec_if_decode(ctx, &buf, src_buf->timestamp, &res_chg);
727 if (ret > 0) {
728 /*
729 * we only return src buffer with VB2_BUF_STATE_DONE
730 * when decode success without resolution change.
731 */
732 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
733 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
734 } else if (ret && ret != -EAGAIN) {
735 src_buf_info->error = (ret == -EIO ? true : false);
736 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
737 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
738 aml_v4l2_err("[%d] %s() error processing src data. %d.",
739 ctx->id, __func__, ret);
740 } else if (res_chg) {
741 /* wait the DPB state to be ready. */
742 aml_wait_dpb_ready(ctx);
743
744 src_buf_info->used = false;
745 aml_vdec_pic_info_update(ctx);
746 /*
747 * On encountering a resolution change in the stream.
748 * The driver must first process and decode all
749 * remaining buffers from before the resolution change
750 * point, so call flush decode here
751 */
752 mutex_lock(&ctx->state_lock);
753 if (ctx->state == AML_STATE_ACTIVE) {
754 ctx->state = AML_STATE_FLUSHING;// prepare flushing
755 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-RESCHG)",
756 ctx->id, __func__);
757 }
758 mutex_unlock(&ctx->state_lock);
759
760 ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
761 v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
762
763 aml_vdec_flush_decoder(ctx);
764
765 goto out;
766 }
767
768 v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
769out:
770 return;
771}
772
773static void aml_vdec_reset(struct aml_vcodec_ctx *ctx)
774{
775 if (ctx->state == AML_STATE_ABORT) {
776 pr_err("[%d] %s() the decoder will be exited.\n",
777 ctx->id, __func__);
778 goto out;
779 }
780
781 if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) {
782 ctx->state = AML_STATE_ABORT;
783 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
784 ctx->id, __func__);
785 goto out;
786 }
787
788 if (ctx->state == AML_STATE_RESET) {
789 ctx->state = AML_STATE_PROBE;
790 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)",
791 ctx->id, __func__);
792
793 aml_v4l2_debug(0, "[%d] %s() dpb: %d, ready: %d, used: %d",
794 ctx->id, __func__, ctx->dpb_size,
795 v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), ctx->buf_used_count);
796
797 /* vdec has ready to decode subsequence data of new resolution. */
798 ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false;
799 v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
800 }
801
802out:
803 complete(&ctx->comp);
804 return;
805}
806
807void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
808{
809 struct aml_vcodec_dev *dev = ctx->dev;
810
811 /* pause inject output data to vdec. */
812 v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
813
814 /* flush worker. */
815 flush_workqueue(dev->decode_workqueue);
816
817 ctx->v4l_codec_ready = false;
818 ctx->v4l_codec_dpb_ready = false;
819
820 /* stop decoder. */
821 if (ctx->state > AML_STATE_INIT)
822 aml_vdec_reset(ctx);
823}
824
825void try_to_capture(struct aml_vcodec_ctx *ctx)
826{
827 int ret = 0;
828 struct vdec_v4l2_buffer *fb = NULL;
829
830 ret = get_display_buffer(ctx, &fb);
831 if (ret) {
832 aml_v4l2_debug(4, "[%d] %s() [%d], the que have no disp buf,ret: %d",
833 ctx->id, __func__, __LINE__, ret);
834 return;
835 }
836
837 trans_vframe_to_user(ctx, fb);
838}
839EXPORT_SYMBOL_GPL(try_to_capture);
840
841static int vdec_thread(void *data)
842{
843 struct sched_param param =
844 {.sched_priority = MAX_RT_PRIO / 2};
845 struct aml_vdec_thread *thread =
846 (struct aml_vdec_thread *) data;
847 struct aml_vcodec_ctx *ctx =
848 (struct aml_vcodec_ctx *) thread->priv;
849
850 sched_setscheduler(current, SCHED_FIFO, &param);
851
852 for (;;) {
853 aml_v4l2_debug(3, "[%d] %s() state: %d", ctx->id,
854 __func__, ctx->state);
855
856 if (down_interruptible(&thread->sem))
857 break;
858
859 if (thread->stop)
860 break;
861
862 /* handle event. */
863 thread->func(ctx);
864 }
865
866 while (!kthread_should_stop()) {
867 set_current_state(TASK_INTERRUPTIBLE);
868 schedule();
869 }
870
871 return 0;
872}
873
874void aml_thread_notify(struct aml_vcodec_ctx *ctx,
875 enum aml_thread_type type)
876{
877 struct aml_vdec_thread *thread = NULL;
878
879 list_for_each_entry(thread, &ctx->vdec_thread_list, node) {
880 if (thread->task == NULL)
881 continue;
882
883 if (thread->type == type)
884 up(&thread->sem);
885 }
886}
887EXPORT_SYMBOL_GPL(aml_thread_notify);
888
889int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
890 enum aml_thread_type type, const char *thread_name)
891{
892 struct aml_vdec_thread *thread;
893 int ret = 0;
894
895 thread = kzalloc(sizeof(*thread), GFP_KERNEL);
896 if (thread == NULL)
897 return -ENOMEM;
898
899 thread->type = type;
900 thread->func = func;
901 thread->priv = ctx;
902 sema_init(&thread->sem, 0);
903
904 thread->task = kthread_run(vdec_thread, thread, "aml-%s", thread_name);
905 if (IS_ERR(thread->task)) {
906 ret = PTR_ERR(thread->task);
907 thread->task = NULL;
908 goto err;
909 }
910
911 list_add(&thread->node, &ctx->vdec_thread_list);
912
913 return 0;
914
915err:
916 kfree(thread);
917
918 return ret;
919}
920EXPORT_SYMBOL_GPL(aml_thread_start);
921
922void aml_thread_stop(struct aml_vcodec_ctx *ctx)
923{
924 struct aml_vdec_thread *thread = NULL;
925
926 while (!list_empty(&ctx->vdec_thread_list)) {
927 thread = list_entry(ctx->vdec_thread_list.next,
928 struct aml_vdec_thread, node);
929 list_del(&thread->node);
930 thread->stop = true;
931 up(&thread->sem);
932 kthread_stop(thread->task);
933 thread->task = NULL;
934 kfree(thread);
935 }
936}
937EXPORT_SYMBOL_GPL(aml_thread_stop);
938
939static int vidioc_try_decoder_cmd(struct file *file, void *priv,
940 struct v4l2_decoder_cmd *cmd)
941{
942 switch (cmd->cmd) {
943 case V4L2_DEC_CMD_STOP:
944 case V4L2_DEC_CMD_START:
945 if (cmd->flags != 0) {
946 aml_v4l2_err("cmd->flags=%u", cmd->flags);
947 return -EINVAL;
948 }
949 break;
950 default:
951 return -EINVAL;
952 }
953
954 return 0;
955}
956
957static int vidioc_decoder_cmd(struct file *file, void *priv,
958 struct v4l2_decoder_cmd *cmd)
959{
960 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
961 struct vb2_queue *src_vq, *dst_vq;
962 int ret;
963
964 ret = vidioc_try_decoder_cmd(file, priv, cmd);
965 if (ret)
966 return ret;
967
968 aml_v4l2_debug(2, "[%d] %s() [%d], cmd: %u",
969 ctx->id, __func__, __LINE__, cmd->cmd);
970 dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
971 multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
972 V4L2_BUF_TYPE_VIDEO_CAPTURE);
973 switch (cmd->cmd) {
974 case V4L2_DEC_CMD_STOP:
975 if (ctx->state != AML_STATE_ACTIVE) {
976 if (ctx->state >= AML_STATE_IDLE &&
977 ctx->state <= AML_STATE_PROBE) {
978 ctx->state = AML_STATE_ABORT;
979 aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
980 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
981 ctx->id, __func__);
982 return 0;
983 }
984 }
985
986 src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
987 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
988 if (!vb2_is_streaming(src_vq)) {
989 pr_err("[%d] Output stream is off. No need to flush.\n", ctx->id);
990 return 0;
991 }
992
993 if (!vb2_is_streaming(dst_vq)) {
994 pr_err("[%d] Capture stream is off. No need to flush.\n", ctx->id);
995 return 0;
996 }
997
998 /* flush src */
999 v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
1000 v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
1001 ctx->receive_cmd_stop = true;
1002 break;
1003
1004 case V4L2_DEC_CMD_START:
1005 aml_v4l2_debug(4, "[%d] CMD V4L2_DEC_CMD_START ", ctx->id);
1006 vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
1007 break;
1008
1009 default:
1010 return -EINVAL;
1011 }
1012
1013 return 0;
1014}
1015
1016static int vidioc_decoder_streamon(struct file *file, void *priv,
1017 enum v4l2_buf_type i)
1018{
1019 struct v4l2_fh *fh = file->private_data;
1020 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
1021 struct vb2_queue *q;
1022
1023 q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
1024 if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
1025 if (ctx->is_stream_off) {
1026 mutex_lock(&ctx->state_lock);
1027 if ((ctx->state == AML_STATE_ACTIVE ||
1028 ctx->state == AML_STATE_FLUSHING ||
1029 ctx->state == AML_STATE_FLUSHED) ||
1030 (ctx->reset_flag == 2)) {
1031 ctx->state = AML_STATE_RESET;
1032 ctx->v4l_codec_ready = false;
1033 ctx->v4l_codec_dpb_ready = false;
1034
1035 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_RESET)",
1036 ctx->id, __func__);
1037 aml_vdec_reset(ctx);
1038 }
1039 mutex_unlock(&ctx->state_lock);
1040
1041 ctx->is_stream_off = false;
1042 }
1043 }
1044 return v4l2_m2m_ioctl_streamon(file, priv, i);
1045}
1046
1047static int vidioc_decoder_streamoff(struct file *file, void *priv,
1048 enum v4l2_buf_type i)
1049{
1050 struct v4l2_fh *fh = file->private_data;
1051 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
1052 struct vb2_queue *q;
1053
1054 q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
1055 if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
1056 ctx->is_stream_off = true;
1057 }
1058
1059 return v4l2_m2m_ioctl_streamoff(file, priv, i);
1060}
1061
1062static int vidioc_decoder_reqbufs(struct file *file, void *priv,
1063 struct v4l2_requestbuffers *rb)
1064{
1065 struct v4l2_fh *fh = file->private_data;
1066 struct vb2_queue *q;
1067
1068 q = v4l2_m2m_get_vq(fh->m2m_ctx, rb->type);
1069
1070 if (!rb->count)
1071 vb2_queue_release(q);
1072
1073 return v4l2_m2m_ioctl_reqbufs(file, priv, rb);
1074}
1075
1076void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx)
1077{
1078 ulong flags;
1079
1080 flags = aml_vcodec_ctx_lock(ctx);
1081 ctx->state = AML_STATE_ABORT;
1082 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
1083 ctx->id, __func__);
1084 aml_vcodec_ctx_unlock(ctx, flags);
1085
1086 vdec_if_deinit(ctx);
1087}
1088
1089void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx)
1090{
1091 struct aml_q_data *q_data;
1092
1093 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
1094 ctx->fh.m2m_ctx = ctx->m2m_ctx;
1095 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1096 INIT_WORK(&ctx->decode_work, aml_vdec_worker);
1097 ctx->colorspace = V4L2_COLORSPACE_REC709;
1098 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1099 ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
1100 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1101 ctx->dev->dec_capability = 0;//VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
1102
1103 q_data = &ctx->q_data[AML_Q_DATA_SRC];
1104 memset(q_data, 0, sizeof(struct aml_q_data));
1105 q_data->visible_width = DFT_CFG_WIDTH;
1106 q_data->visible_height = DFT_CFG_HEIGHT;
1107 q_data->fmt = &aml_video_formats[OUT_FMT_IDX];
1108 q_data->field = V4L2_FIELD_NONE;
1109
1110 q_data->sizeimage[0] = (1024 * 1024);//DFT_CFG_WIDTH * DFT_CFG_HEIGHT; //1m
1111 q_data->bytesperline[0] = 0;
1112
1113 q_data = &ctx->q_data[AML_Q_DATA_DST];
1114 memset(q_data, 0, sizeof(struct aml_q_data));
1115 q_data->visible_width = DFT_CFG_WIDTH;
1116 q_data->visible_height = DFT_CFG_HEIGHT;
1117 q_data->coded_width = DFT_CFG_WIDTH;
1118 q_data->coded_height = DFT_CFG_HEIGHT;
1119 q_data->fmt = &aml_video_formats[CAP_FMT_IDX];
1120 q_data->field = V4L2_FIELD_NONE;
1121
1122 v4l_bound_align_image(&q_data->coded_width,
1123 AML_VDEC_MIN_W,
1124 AML_VDEC_MAX_W, 4,
1125 &q_data->coded_height,
1126 AML_VDEC_MIN_H,
1127 AML_VDEC_MAX_H, 5, 6);
1128
1129 q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
1130 q_data->bytesperline[0] = q_data->coded_width;
1131 q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
1132 q_data->bytesperline[1] = q_data->coded_width;
1133
1134 ctx->state = AML_STATE_IDLE;
1135 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_IDLE)",
1136 ctx->id, __func__);
1137}
1138
1139static int vidioc_vdec_qbuf(struct file *file, void *priv,
1140 struct v4l2_buffer *buf)
1141{
1142 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1143
1144 if (ctx->state == AML_STATE_ABORT) {
1145 aml_v4l2_err("[%d] Call on QBUF after unrecoverable error, type = %s",
1146 ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ?
1147 "OUT" : "IN");
1148 return -EIO;
1149 }
1150
1151 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
1152}
1153
1154static int vidioc_vdec_dqbuf(struct file *file, void *priv,
1155 struct v4l2_buffer *buf)
1156{
1157 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1158 int ret;
1159
1160 if (ctx->state == AML_STATE_ABORT) {
1161 aml_v4l2_err("[%d] Call on DQBUF after unrecoverable error, type = %s",
1162 ctx->id, V4L2_TYPE_IS_OUTPUT(buf->type) ?
1163 "OUT" : "IN");
1164 if (!V4L2_TYPE_IS_OUTPUT(buf->type))
1165 return -EIO;
1166 }
1167
1168 ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
1169
1170 if (!ret && !V4L2_TYPE_IS_OUTPUT(buf->type)) {
1171 struct vb2_queue *vq;
1172 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1173 struct aml_video_dec_buf *aml_buf = NULL;
1174 struct file *file = NULL;
1175
1176 mutex_lock(&ctx->lock);
1177 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
1178 vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]);
1179 aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1180
1181 file = fget(vb2_v4l2->private);
1182 if (is_v4l2_buf_file(file) &&
1183 !aml_buf->is_install_privdata) {
1184 dmabuf_fd_install_data(vb2_v4l2->private,
1185 (void*)&aml_buf->privdata,
1186 sizeof(struct file_private_data));
1187 aml_buf->is_install_privdata = true;
1188 }
1189 fput(file);
1190 mutex_unlock(&ctx->lock);
1191 }
1192
1193 return ret;
1194}
1195
1196static int vidioc_vdec_querycap(struct file *file, void *priv,
1197 struct v4l2_capability *cap)
1198{
1199 strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver));
1200 strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info));
1201 strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card));
1202
1203 return 0;
1204}
1205
1206static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
1207 const struct v4l2_event_subscription *sub)
1208{
1209 switch (sub->type) {
1210 case V4L2_EVENT_EOS:
1211 return v4l2_event_subscribe(fh, sub, 2, NULL);
1212 case V4L2_EVENT_SOURCE_CHANGE:
1213 return v4l2_src_change_event_subscribe(fh, sub);
1214 default:
1215 return v4l2_ctrl_subscribe_event(fh, sub);
1216 }
1217}
1218
1219static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
1220{
1221 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
1222 int i;
1223
1224 pix_fmt_mp->field = V4L2_FIELD_NONE;
1225
1226 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1227 pix_fmt_mp->num_planes = 1;
1228 pix_fmt_mp->plane_fmt[0].bytesperline = 0;
1229 } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
1230 int tmp_w, tmp_h;
1231
1232 pix_fmt_mp->height = clamp(pix_fmt_mp->height,
1233 AML_VDEC_MIN_H,
1234 AML_VDEC_MAX_H);
1235 pix_fmt_mp->width = clamp(pix_fmt_mp->width,
1236 AML_VDEC_MIN_W,
1237 AML_VDEC_MAX_W);
1238
1239 /*
1240 * Find next closer width align 64, heign align 64, size align
1241 * 64 rectangle
1242 * Note: This only get default value, the real HW needed value
1243 * only available when ctx in AML_STATE_PROBE state
1244 */
1245 tmp_w = pix_fmt_mp->width;
1246 tmp_h = pix_fmt_mp->height;
1247 v4l_bound_align_image(&pix_fmt_mp->width,
1248 AML_VDEC_MIN_W,
1249 AML_VDEC_MAX_W, 6,
1250 &pix_fmt_mp->height,
1251 AML_VDEC_MIN_H,
1252 AML_VDEC_MAX_H, 6, 9);
1253
1254 if (pix_fmt_mp->width < tmp_w &&
1255 (pix_fmt_mp->width + 64) <= AML_VDEC_MAX_W)
1256 pix_fmt_mp->width += 64;
1257 if (pix_fmt_mp->height < tmp_h &&
1258 (pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H)
1259 pix_fmt_mp->height += 64;
1260
1261 aml_v4l2_debug(4,
1262 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
1263 tmp_w, tmp_h, pix_fmt_mp->width,
1264 pix_fmt_mp->height,
1265 pix_fmt_mp->width * pix_fmt_mp->height);
1266
1267 pix_fmt_mp->num_planes = fmt->num_planes;
1268 pix_fmt_mp->plane_fmt[0].sizeimage =
1269 pix_fmt_mp->width * pix_fmt_mp->height;
1270 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
1271
1272 if (pix_fmt_mp->num_planes == 2) {
1273 pix_fmt_mp->plane_fmt[1].sizeimage =
1274 (pix_fmt_mp->width * pix_fmt_mp->height) / 2;
1275 pix_fmt_mp->plane_fmt[1].bytesperline =
1276 pix_fmt_mp->width;
1277 }
1278 }
1279
1280 for (i = 0; i < pix_fmt_mp->num_planes; i++)
1281 memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0,
1282 sizeof(pix_fmt_mp->plane_fmt[0].reserved));
1283
1284 pix_fmt_mp->flags = 0;
1285 memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved));
1286 return 0;
1287}
1288
1289static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
1290 struct v4l2_format *f)
1291{
1292 struct aml_video_fmt *fmt = NULL;
1293
1294 fmt = aml_vdec_find_format(f);
1295 if (!fmt)
1296 return -EINVAL;
1297
1298 return vidioc_try_fmt(f, fmt);
1299}
1300
1301static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
1302 struct v4l2_format *f)
1303{
1304 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
1305 struct aml_video_fmt *fmt = NULL;
1306
1307 fmt = aml_vdec_find_format(f);
1308 if (!fmt)
1309 return -EINVAL;
1310
1311 if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
1312 aml_v4l2_err("sizeimage of output format must be given");
1313 return -EINVAL;
1314 }
1315
1316 return vidioc_try_fmt(f, fmt);
1317}
1318
1319static int vidioc_vdec_g_selection(struct file *file, void *priv,
1320 struct v4l2_selection *s)
1321{
1322 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1323 struct aml_q_data *q_data;
1324
1325 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1326 return -EINVAL;
1327
1328 q_data = &ctx->q_data[AML_Q_DATA_DST];
1329
1330 switch (s->target) {
1331 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1332 s->r.left = 0;
1333 s->r.top = 0;
1334 s->r.width = ctx->picinfo.visible_width;
1335 s->r.height = ctx->picinfo.visible_height;
1336 break;
1337 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1338 s->r.left = 0;
1339 s->r.top = 0;
1340 s->r.width = ctx->picinfo.coded_width;
1341 s->r.height = ctx->picinfo.coded_height;
1342 break;
1343 case V4L2_SEL_TGT_COMPOSE:
1344 if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
1345 /* set to default value if header info not ready yet*/
1346 s->r.left = 0;
1347 s->r.top = 0;
1348 s->r.width = q_data->visible_width;
1349 s->r.height = q_data->visible_height;
1350 }
1351 break;
1352 default:
1353 return -EINVAL;
1354 }
1355
1356 if (ctx->state < AML_STATE_PROBE) {
1357 /* set to default value if header info not ready yet*/
1358 s->r.left = 0;
1359 s->r.top = 0;
1360 s->r.width = q_data->visible_width;
1361 s->r.height = q_data->visible_height;
1362 return 0;
1363 }
1364
1365 return 0;
1366}
1367
1368static int vidioc_vdec_s_selection(struct file *file, void *priv,
1369 struct v4l2_selection *s)
1370{
1371 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1372
1373 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1374 return -EINVAL;
1375
1376 switch (s->target) {
1377 case V4L2_SEL_TGT_COMPOSE:
1378 s->r.left = 0;
1379 s->r.top = 0;
1380 s->r.width = ctx->picinfo.visible_width;
1381 s->r.height = ctx->picinfo.visible_height;
1382 break;
1383 default:
1384 return -EINVAL;
1385 }
1386
1387 return 0;
1388}
1389
1390static int vidioc_vdec_s_fmt(struct file *file, void *priv,
1391 struct v4l2_format *f)
1392{
1393 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1394 struct v4l2_pix_format_mplane *pix_mp;
1395 struct aml_q_data *q_data;
1396 int ret = 0;
1397 struct aml_video_fmt *fmt;
1398
1399 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
1400
1401 q_data = aml_vdec_get_q_data(ctx, f->type);
1402 if (!q_data)
1403 return -EINVAL;
1404
1405 pix_mp = &f->fmt.pix_mp;
1406 if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
1407 vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
1408 aml_v4l2_err("[%d] out_q_ctx buffers already requested", ctx->id);
1409 }
1410
1411 if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
1412 vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
1413 aml_v4l2_err("[%d] cap_q_ctx buffers already requested", ctx->id);
1414 }
1415
1416 fmt = aml_vdec_find_format(f);
1417 if (fmt == NULL) {
1418 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1419 f->fmt.pix.pixelformat =
1420 aml_video_formats[OUT_FMT_IDX].fourcc;
1421 fmt = aml_vdec_find_format(f);
1422 } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
1423 f->fmt.pix.pixelformat =
1424 aml_video_formats[CAP_FMT_IDX].fourcc;
1425 fmt = aml_vdec_find_format(f);
1426 }
1427 }
1428
1429 q_data->fmt = fmt;
1430 vidioc_try_fmt(f, q_data->fmt);
1431 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1432 q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
1433 q_data->coded_width = pix_mp->width;
1434 q_data->coded_height = pix_mp->height;
1435
1436 aml_v4l2_debug(4, "[%d] %s() [%d], w: %d, h: %d, size: %d",
1437 ctx->id, __func__, __LINE__, pix_mp->width, pix_mp->height,
1438 pix_mp->plane_fmt[0].sizeimage);
1439
1440 ctx->colorspace = f->fmt.pix_mp.colorspace;
1441 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
1442 ctx->quantization = f->fmt.pix_mp.quantization;
1443 ctx->xfer_func = f->fmt.pix_mp.xfer_func;
1444
1445 mutex_lock(&ctx->state_lock);
1446 if (ctx->state == AML_STATE_IDLE) {
1447 ret = vdec_if_init(ctx, q_data->fmt->fourcc);
1448 if (ret) {
1449 aml_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
1450 ctx->id, ret);
1451 mutex_unlock(&ctx->state_lock);
1452 return -EINVAL;
1453 }
1454 ctx->state = AML_STATE_INIT;
1455 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_INIT)",
1456 ctx->id, __func__);
1457 }
1458 mutex_unlock(&ctx->state_lock);
1459 }
1460
1461 return 0;
1462}
1463
1464static int vidioc_enum_framesizes(struct file *file, void *priv,
1465 struct v4l2_frmsizeenum *fsize)
1466{
1467 int i = 0;
1468 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1469
1470 if (fsize->index != 0)
1471 return -EINVAL;
1472
1473 for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) {
1474 if (fsize->pixel_format != aml_vdec_framesizes[i].fourcc)
1475 continue;
1476
1477 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1478 fsize->stepwise = aml_vdec_framesizes[i].stepwise;
1479 if (!(ctx->dev->dec_capability &
1480 VCODEC_CAPABILITY_4K_DISABLED)) {
1481 aml_v4l2_debug(4, "[%d] 4K is enabled", ctx->id);
1482 fsize->stepwise.max_width =
1483 VCODEC_DEC_4K_CODED_WIDTH;
1484 fsize->stepwise.max_height =
1485 VCODEC_DEC_4K_CODED_HEIGHT;
1486 }
1487 aml_v4l2_debug(4, "[%d] %x, %d %d %d %d %d %d",
1488 ctx->id, ctx->dev->dec_capability,
1489 fsize->stepwise.min_width,
1490 fsize->stepwise.max_width,
1491 fsize->stepwise.step_width,
1492 fsize->stepwise.min_height,
1493 fsize->stepwise.max_height,
1494 fsize->stepwise.step_height);
1495 return 0;
1496 }
1497
1498 return -EINVAL;
1499}
1500
1501static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
1502{
1503 struct aml_video_fmt *fmt;
1504 int i, j = 0;
1505
1506 for (i = 0; i < NUM_FORMATS; i++) {
1507 if (output_queue && (aml_video_formats[i].type != AML_FMT_DEC))
1508 continue;
1509 if (!output_queue && (aml_video_formats[i].type != AML_FMT_FRAME))
1510 continue;
1511
1512 if (j == f->index) {
1513 fmt = &aml_video_formats[i];
1514 f->pixelformat = fmt->fourcc;
1515 return 0;
1516 }
1517 ++j;
1518 }
1519
1520 return -EINVAL;
1521}
1522
1523static int vidioc_vdec_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
1524 struct v4l2_fmtdesc *f)
1525{
1526 return vidioc_enum_fmt(f, false);
1527}
1528
1529static int vidioc_vdec_enum_fmt_vid_out_mplane(struct file *file, void *priv,
1530 struct v4l2_fmtdesc *f)
1531{
1532 return vidioc_enum_fmt(f, true);
1533}
1534
1535static int vidioc_vdec_g_fmt(struct file *file, void *priv,
1536 struct v4l2_format *f)
1537{
1538 struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
1539 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
1540 struct vb2_queue *vq;
1541 struct aml_q_data *q_data;
1542
1543 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
1544 if (!vq) {
1545 aml_v4l2_err("[%d] no vb2 queue for type=%d", ctx->id, f->type);
1546 return -EINVAL;
1547 }
1548
1549 q_data = aml_vdec_get_q_data(ctx, f->type);
1550
1551 pix_mp->field = V4L2_FIELD_NONE;
1552 pix_mp->colorspace = ctx->colorspace;
1553 pix_mp->ycbcr_enc = ctx->ycbcr_enc;
1554 pix_mp->quantization = ctx->quantization;
1555 pix_mp->xfer_func = ctx->xfer_func;
1556
1557 if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
1558 (ctx->state >= AML_STATE_PROBE)) {
1559 /* Until STREAMOFF is called on the CAPTURE queue
1560 * (acknowledging the event), the driver operates as if
1561 * the resolution hasn't changed yet.
1562 * So we just return picinfo yet, and update picinfo in
1563 * stop_streaming hook function
1564 */
1565 /* it is used for alloc the decode buffer size. */
1566 q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
1567 q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
1568
1569 /* it is used for alloc the EGL image buffer size. */
1570 q_data->coded_width = ctx->picinfo.coded_width;
1571 q_data->coded_height = ctx->picinfo.coded_height;
1572
1573 q_data->bytesperline[0] = ctx->picinfo.coded_width;
1574 q_data->bytesperline[1] = ctx->picinfo.coded_width;
1575
1576 /*
1577 * Width and height are set to the dimensions
1578 * of the movie, the buffer is bigger and
1579 * further processing stages should crop to this
1580 * rectangle.
1581 */
1582 pix_mp->width = q_data->coded_width;
1583 pix_mp->height = q_data->coded_height;
1584
1585 /*
1586 * Set pixelformat to the format in which mt vcodec
1587 * outputs the decoded frame
1588 */
1589 pix_mp->num_planes = q_data->fmt->num_planes;
1590 pix_mp->pixelformat = q_data->fmt->fourcc;
1591 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1592 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1593 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
1594 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
1595 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1596 /*
1597 * This is run on OUTPUT
1598 * The buffer contains compressed image
1599 * so width and height have no meaning.
1600 * Assign value here to pass v4l2-compliance test
1601 */
1602 pix_mp->width = q_data->visible_width;
1603 pix_mp->height = q_data->visible_height;
1604 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1605 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1606 pix_mp->pixelformat = q_data->fmt->fourcc;
1607 pix_mp->num_planes = q_data->fmt->num_planes;
1608 } else {
1609 pix_mp->width = q_data->coded_width;
1610 pix_mp->height = q_data->coded_height;
1611 pix_mp->num_planes = q_data->fmt->num_planes;
1612 pix_mp->pixelformat = q_data->fmt->fourcc;
1613 pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
1614 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
1615 pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
1616 pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
1617
1618 aml_v4l2_debug(4, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
1619 ctx->id, f->type, ctx->state);
1620 return -EINVAL;
1621 }
1622
1623 return 0;
1624}
1625
1626/*int vidioc_vdec_g_ctrl(struct file *file, void *fh,
1627 struct v4l2_control *a)
1628{
1629 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
1630
1631 if (a->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE)
1632 a->value = 20;
1633
1634 return 0;
1635}*/
1636
1637static int vb2ops_vdec_queue_setup(struct vb2_queue *vq,
1638 unsigned int *nbuffers,
1639 unsigned int *nplanes,
1640 unsigned int sizes[], struct device *alloc_devs[])
1641{
1642 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
1643 struct aml_q_data *q_data;
1644 unsigned int i;
1645
1646 q_data = aml_vdec_get_q_data(ctx, vq->type);
1647
1648 if (q_data == NULL) {
1649 aml_v4l2_err("[%d] vq->type=%d err", ctx->id, vq->type);
1650 return -EINVAL;
1651 }
1652
1653 if (*nplanes) {
1654 for (i = 0; i < *nplanes; i++) {
1655 if (sizes[i] < q_data->sizeimage[i])
1656 return -EINVAL;
1657 //alloc_devs[i] = &ctx->dev->plat_dev->dev;
1658 alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
1659 }
1660 } else {
1661 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1662 *nplanes = 2;
1663 else
1664 *nplanes = 1;
1665
1666 for (i = 0; i < *nplanes; i++) {
1667 sizes[i] = q_data->sizeimage[i];
1668 //alloc_devs[i] = &ctx->dev->plat_dev->dev;
1669 alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
1670 }
1671 }
1672
1673 pr_info("[%d] type: %d, plane: %d, buf cnt: %d, size: [Y: %u, C: %u]\n",
1674 ctx->id, vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]);
1675
1676 return 0;
1677}
1678
1679static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
1680{
1681 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1682 struct aml_q_data *q_data;
1683 int i;
1684
1685 aml_v4l2_debug(4, "[%d] (%d) id=%d",
1686 ctx->id, vb->vb2_queue->type, vb->index);
1687
1688 q_data = aml_vdec_get_q_data(ctx, vb->vb2_queue->type);
1689
1690 for (i = 0; i < q_data->fmt->num_planes; i++) {
1691 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
1692 aml_v4l2_err("[%d] data will not fit into plane %d (%lu < %d)",
1693 ctx->id, i, vb2_plane_size(vb, i),
1694 q_data->sizeimage[i]);
1695 }
1696 }
1697
1698 return 0;
1699}
1700
1701static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
1702{
1703 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1704 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1705 struct aml_video_dec_buf *buf = NULL;
1706 struct aml_vcodec_mem src_mem;
1707 unsigned int dpb = 0;
1708
1709 vb2_v4l2 = to_vb2_v4l2_buffer(vb);
1710 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1711
1712 aml_v4l2_debug(3, "[%d] %s(), vb: %p, type: %d, idx: %d, state: %d, used: %d",
1713 ctx->id, __func__, vb, vb->vb2_queue->type,
1714 vb->index, vb->state, buf->used);
1715 /*
1716 * check if this buffer is ready to be used after decode
1717 */
1718 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1719 aml_v4l2_debug(3, "[%d] %s() [%d], y_addr: %lx, vf_h: %lx, state: %d", ctx->id,
1720 __func__, __LINE__, buf->frame_buffer.m.mem[0].addr,
1721 buf->frame_buffer.vf_handle, buf->frame_buffer.status);
1722
1723 if (!buf->que_in_m2m) {
1724 aml_v4l2_debug(2, "[%d] enque capture buf idx %d, %p",
1725 ctx->id, vb->index, vb);
1726
1727 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
1728 buf->que_in_m2m = true;
1729 buf->queued_in_vb2 = true;
1730 buf->queued_in_v4l2 = true;
1731 buf->ready_to_display = false;
1732
1733 /* check dpb ready */
1734 aml_check_dpb_ready(ctx);
1735 } else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
1736 buf->queued_in_vb2 = false;
1737 buf->queued_in_v4l2 = true;
1738 buf->ready_to_display = false;
1739
1740 /* recycle vf */
1741 video_vf_put(ctx->ada_ctx->recv_name,
1742 &buf->frame_buffer, ctx->id);
1743 }
1744 return;
1745 }
1746
1747 v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
1748
1749 if (ctx->state != AML_STATE_INIT) {
1750 aml_v4l2_debug(4, "[%d] already init driver %d",
1751 ctx->id, ctx->state);
1752 return;
1753 }
1754
1755 vb2_v4l2 = to_vb2_v4l2_buffer(vb);
1756 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1757 if (buf->lastframe) {
1758 /* This shouldn't happen. Just in case. */
1759 aml_v4l2_err("[%d] Invalid flush buffer.", ctx->id);
1760 v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1761 return;
1762 }
1763
1764 src_mem.vaddr = vb2_plane_vaddr(vb, 0);
1765 src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1766 src_mem.size = vb->planes[0].bytesused;
1767 if (vdec_if_probe(ctx, &src_mem, NULL)) {
1768 v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1769 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE);
1770 return;
1771 }
1772
1773 if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
1774 pr_err("[%d] GET_PARAM_PICTURE_INFO err\n", ctx->id);
1775 return;
1776 }
1777
1778 if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) {
1779 pr_err("[%d] GET_PARAM_DPB_SIZE err\n", ctx->id);
1780 return;
1781 }
1782
1783 if (!dpb)
1784 return;
1785
1786 ctx->dpb_size = dpb;
1787 ctx->last_decoded_picinfo = ctx->picinfo;
1788 aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
1789
1790 mutex_lock(&ctx->state_lock);
1791 if (ctx->state == AML_STATE_INIT) {
1792 ctx->state = AML_STATE_PROBE;
1793 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)",
1794 ctx->id, __func__);
1795 }
1796 mutex_unlock(&ctx->state_lock);
1797}
1798
1799static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
1800{
1801 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1802 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1803 struct aml_video_dec_buf *buf = NULL;
1804 bool buf_error;
1805
1806 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
1807 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1808
1809 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1810 buf->queued_in_v4l2 = false;
1811 buf->queued_in_vb2 = false;
1812 }
1813 buf_error = buf->error;
1814
1815 if (buf_error) {
1816 aml_v4l2_err("[%d] Unrecoverable error on buffer.", ctx->id);
1817 ctx->state = AML_STATE_ABORT;
1818 aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
1819 ctx->id, __func__);
1820 }
1821}
1822
1823static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
1824{
1825 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1826 struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
1827 struct vb2_v4l2_buffer, vb2_buf);
1828 struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
1829 struct aml_video_dec_buf, vb);
1830 unsigned int size, phy_addr = 0;
1831 char *owner = __getname();
1832
1833 aml_v4l2_debug(4, "[%d] (%d) id=%d",
1834 ctx->id, vb->vb2_queue->type, vb->index);
1835
1836 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1837 buf->used = false;
1838 buf->ready_to_display = false;
1839 buf->queued_in_v4l2 = false;
1840 buf->frame_buffer.status = FB_ST_NORMAL;
1841 } else {
1842 buf->lastframe = false;
1843 }
1844
1845 /* codec_mm buffers count */
1846 if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
1847 size = vb->planes[0].length;
1848 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1849 snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id);
1850 strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
1851 buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
1852
1853 buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1854 phy_addr, size, vb->index);
1855 aml_v4l2_debug(3, "[%d] IN alloc, addr: %x, size: %u, idx: %u",
1856 ctx->id, phy_addr, size, vb->index);
1857 } else {
1858 snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
1859 strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
1860 buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
1861
1862 if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 1)) {
1863 size = vb->planes[0].length;
1864 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1865 buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1866 phy_addr, size, vb->index);
1867 aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
1868 ctx->id, phy_addr, size, vb->index);
1869 } else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) {
1870 size = vb->planes[0].length;
1871 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1872 buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1873 phy_addr, size, vb->index);
1874 aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
1875 ctx->id, phy_addr, size, vb->index);
1876
1877 size = vb->planes[1].length;
1878 phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
1879 buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
1880 phy_addr, size, vb->index);
1881 aml_v4l2_debug(3, "[%d] OUT C alloc, addr: %x, size: %u, idx: %u",
1882 ctx->id, phy_addr, size, vb->index);
1883 }
1884 }
1885
1886 __putname(owner);
1887
1888 return 0;
1889}
1890
1891static void codec_mm_bufs_cnt_clean(struct vb2_queue *q)
1892{
1893 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1894 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1895 struct aml_video_dec_buf *buf = NULL;
1896 int i;
1897
1898 for (i = 0; i < q->num_buffers; ++i) {
1899 vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
1900 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1901 if (IS_ERR_OR_NULL(buf->mem[0]))
1902 return;
1903
1904 if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) {
1905 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
1906
1907 aml_v4l2_debug(3, "[%d] IN clean, addr: %lx, size: %u, idx: %u",
1908 ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
1909 buf->mem[0] = NULL;
1910 continue;
1911 }
1912
1913 if (q->memory == VB2_MEMORY_MMAP) {
1914 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
1915 v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
1916
1917 aml_v4l2_debug(3, "[%d] OUT Y clean, addr: %lx, size: %u, idx: %u",
1918 ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
1919 aml_v4l2_debug(3, "[%d] OUT C clean, addr: %lx, size: %u, idx: %u",
1920 ctx->id, buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
1921 buf->mem[0] = NULL;
1922 buf->mem[1] = NULL;
1923 }
1924 }
1925}
1926
1927static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
1928{
1929 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1930
1931 ctx->has_receive_eos = false;
1932 v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
1933
1934 return 0;
1935}
1936
1937static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
1938{
1939 struct aml_video_dec_buf *buf = NULL;
1940 struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
1941 struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
1942 int i;
1943
1944 aml_v4l2_debug(3, "[%d] (%d) state=(%x) frame_cnt=%d",
1945 ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
1946
1947 codec_mm_bufs_cnt_clean(q);
1948
1949 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1950 while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
1951 v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
1952 } else {
1953 for (i = 0; i < q->num_buffers; ++i) {
1954 vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
1955 buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
1956 buf->frame_buffer.status = FB_ST_NORMAL;
1957 buf->que_in_m2m = false;
1958 buf->is_install_privdata = false;
1959
1960 if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
1961 v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
1962
1963 /*pr_info("idx: %d, state: %d\n",
1964 q->bufs[i]->index, q->bufs[i]->state);*/
1965 }
1966 }
1967 ctx->buf_used_count = 0;
1968}
1969
1970static void m2mops_vdec_device_run(void *priv)
1971{
1972 struct aml_vcodec_ctx *ctx = priv;
1973 struct aml_vcodec_dev *dev = ctx->dev;
1974
1975 aml_v4l2_debug(4, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
1976
1977 queue_work(dev->decode_workqueue, &ctx->decode_work);
1978}
1979
1980void vdec_device_vf_run(struct aml_vcodec_ctx *ctx)
1981{
1982 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
1983
1984 if (ctx->state < AML_STATE_INIT ||
1985 ctx->state > AML_STATE_FLUSHED)
1986 return;
1987
1988 aml_thread_notify(ctx, AML_THREAD_CAPTURE);
1989}
1990
1991static int m2mops_vdec_job_ready(void *m2m_priv)
1992{
1993 struct aml_vcodec_ctx *ctx = m2m_priv;
1994
1995 aml_v4l2_debug(4, "[%d] %s(), state: %d", ctx->id,
1996 __func__, ctx->state);
1997
1998 if (ctx->state < AML_STATE_PROBE ||
1999 ctx->state > AML_STATE_FLUSHED)
2000 return 0;
2001
2002 return 1;
2003}
2004
2005static void m2mops_vdec_job_abort(void *priv)
2006{
2007 struct aml_vcodec_ctx *ctx = priv;
2008
2009 aml_v4l2_debug(3, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
2010}
2011
2012static int aml_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
2013{
2014 struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
2015 int ret = 0;
2016
2017 aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__);
2018
2019 switch (ctrl->id) {
2020 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
2021 if (ctx->state >= AML_STATE_PROBE) {
2022 ctrl->val = ctx->dpb_size;
2023 } else {
2024 pr_err("Seqinfo not ready.\n");
2025 ctrl->val = 0;
2026 ret = -EINVAL;
2027 }
2028 break;
2029 default:
2030 ret = -EINVAL;
2031 }
2032 return ret;
2033}
2034
2035static int aml_vdec_try_s_v_ctrl(struct v4l2_ctrl *ctrl)
2036{
2037 struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
2038
2039 aml_v4l2_debug(4, "%s() [%d]", __func__, __LINE__);
2040
2041 if (ctrl->id == AML_V4L2_SET_DECMODE) {
2042 ctx->is_drm_mode = ctrl->val;
2043 pr_info("set stream mode: %x\n", ctrl->val);
2044 }
2045
2046 return 0;
2047}
2048
2049static const struct v4l2_ctrl_ops aml_vcodec_dec_ctrl_ops = {
2050 .g_volatile_ctrl = aml_vdec_g_v_ctrl,
2051 .try_ctrl = aml_vdec_try_s_v_ctrl,
2052};
2053
2054static const struct v4l2_ctrl_config ctrl_st_mode = {
2055 .name = "stream mode",
2056 .id = AML_V4L2_SET_DECMODE,
2057 .ops = &aml_vcodec_dec_ctrl_ops,
2058 .type = V4L2_CTRL_TYPE_BOOLEAN,
2059 .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
2060 .min = 0,
2061 .max = 1,
2062 .step = 1,
2063 .def = 0,
2064};
2065
2066int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
2067{
2068 int ret;
2069 struct v4l2_ctrl *ctrl;
2070
2071 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1);
2072 ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl,
2073 &aml_vcodec_dec_ctrl_ops,
2074 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
2075 0, 32, 1, 1);
2076 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2077 if (ctx->ctrl_hdl.error) {
2078 ret = ctx->ctrl_hdl.error;
2079 goto err;
2080 }
2081
2082 ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_mode, NULL);
2083 if (ctx->ctrl_hdl.error) {
2084 ret = ctx->ctrl_hdl.error;
2085 goto err;
2086 }
2087
2088 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
2089
2090 return 0;
2091err:
2092 aml_v4l2_err("[%d] Adding control failed %d",
2093 ctx->id, ctx->ctrl_hdl.error);
2094 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
2095 return ret;
2096}
2097
2098static int vidioc_vdec_g_parm(struct file *file, void *fh,
2099 struct v4l2_streamparm *a)
2100{
2101 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
2102
2103 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2104 if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO,
2105 &ctx->config.parm.dec)) {
2106 pr_err("[%d] GET_PARAM_CONFIG_INFO err\n", ctx->id);
2107 return -1;
2108 }
2109 memcpy(a->parm.raw_data, ctx->config.parm.data,
2110 sizeof(a->parm.raw_data));
2111 }
2112
2113 return 0;
2114}
2115
2116static int vidioc_vdec_s_parm(struct file *file, void *fh,
2117 struct v4l2_streamparm *a)
2118{
2119 struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
2120
2121 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2122 struct aml_dec_params *in =
2123 (struct aml_dec_params *) a->parm.raw_data;
2124 struct aml_dec_params *dec = &ctx->config.parm.dec;
2125
2126 ctx->config.type = V4L2_CONFIG_PARM_DECODE;
2127
2128 if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
2129 dec->cfg = in->cfg;
2130 if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
2131 dec->ps = in->ps;
2132 if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
2133 dec->hdr = in->hdr;
2134 if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
2135 dec->cnt = in->cnt;
2136
2137 dec->parms_status |= in->parms_status;
2138 }
2139
2140 return 0;
2141}
2142
2143static void m2mops_vdec_lock(void *m2m_priv)
2144{
2145 struct aml_vcodec_ctx *ctx = m2m_priv;
2146
2147 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
2148 mutex_lock(&ctx->dev->dev_mutex);
2149}
2150
2151static void m2mops_vdec_unlock(void *m2m_priv)
2152{
2153 struct aml_vcodec_ctx *ctx = m2m_priv;
2154
2155 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
2156 mutex_unlock(&ctx->dev->dev_mutex);
2157}
2158
2159const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
2160 .device_run = m2mops_vdec_device_run,
2161 .job_ready = m2mops_vdec_job_ready,
2162 .job_abort = m2mops_vdec_job_abort,
2163 .lock = m2mops_vdec_lock,
2164 .unlock = m2mops_vdec_unlock,
2165};
2166
2167static const struct vb2_ops aml_vdec_vb2_ops = {
2168 .queue_setup = vb2ops_vdec_queue_setup,
2169 .buf_prepare = vb2ops_vdec_buf_prepare,
2170 .buf_queue = vb2ops_vdec_buf_queue,
2171 .wait_prepare = vb2_ops_wait_prepare,
2172 .wait_finish = vb2_ops_wait_finish,
2173 .buf_init = vb2ops_vdec_buf_init,
2174 .buf_finish = vb2ops_vdec_buf_finish,
2175 .start_streaming = vb2ops_vdec_start_streaming,
2176 .stop_streaming = vb2ops_vdec_stop_streaming,
2177};
2178
2179const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = {
2180 .vidioc_streamon = vidioc_decoder_streamon,
2181 .vidioc_streamoff = vidioc_decoder_streamoff,
2182 .vidioc_reqbufs = vidioc_decoder_reqbufs,
2183 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
2184 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,//??
2185 //.vidioc_g_ctrl = vidioc_vdec_g_ctrl,
2186
2187 .vidioc_qbuf = vidioc_vdec_qbuf,
2188 .vidioc_dqbuf = vidioc_vdec_dqbuf,
2189
2190 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
2191 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_mplane,
2192 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
2193 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out_mplane,
2194
2195 .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
2196 .vidioc_s_fmt_vid_cap = vidioc_vdec_s_fmt,
2197 .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt,
2198 .vidioc_s_fmt_vid_out = vidioc_vdec_s_fmt,
2199 .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt,
2200 .vidioc_g_fmt_vid_cap = vidioc_vdec_g_fmt,
2201 .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt,
2202 .vidioc_g_fmt_vid_out = vidioc_vdec_g_fmt,
2203
2204 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
2205
2206 .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane,
2207 .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap_mplane,
2208 .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
2209 .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out_mplane,
2210 .vidioc_enum_framesizes = vidioc_enum_framesizes,
2211
2212 .vidioc_querycap = vidioc_vdec_querycap,
2213 .vidioc_subscribe_event = vidioc_vdec_subscribe_evt,
2214 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2215 .vidioc_g_selection = vidioc_vdec_g_selection,
2216 .vidioc_s_selection = vidioc_vdec_s_selection,
2217
2218 .vidioc_decoder_cmd = vidioc_decoder_cmd,
2219 .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
2220
2221 .vidioc_g_parm = vidioc_vdec_g_parm,
2222 .vidioc_s_parm = vidioc_vdec_s_parm,
2223};
2224
2225int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
2226 struct vb2_queue *dst_vq)
2227{
2228 struct aml_vcodec_ctx *ctx = priv;
2229 int ret = 0;
2230
2231 aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
2232
2233 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2234 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
2235 src_vq->drv_priv = ctx;
2236 src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
2237 src_vq->ops = &aml_vdec_vb2_ops;
2238 src_vq->mem_ops = &vb2_dma_contig_memops;
2239 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2240 src_vq->lock = &ctx->dev->dev_mutex;
2241 ret = vb2_queue_init(src_vq);
2242 if (ret) {
2243 aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(output)", ctx->id);
2244 return ret;
2245 }
2246
2247 dst_vq->type = multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
2248 V4L2_BUF_TYPE_VIDEO_CAPTURE;
2249 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
2250 dst_vq->drv_priv = ctx;
2251 dst_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
2252 dst_vq->ops = &aml_vdec_vb2_ops;
2253 dst_vq->mem_ops = &vb2_dma_contig_memops;
2254 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2255 dst_vq->lock = &ctx->dev->dev_mutex;
2256 ret = vb2_queue_init(dst_vq);
2257 if (ret) {
2258 vb2_queue_release(src_vq);
2259 aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(capture)", ctx->id);
2260 }
2261
2262 return ret;
2263}
2264
2265