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