summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/vdec_vp9_if.c (plain)
blob: 0a5ceda4bb47b3276c6ed20e63810bcdc09338c6
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 <linux/module.h>
21#include <linux/slab.h>
22#include <linux/timer.h>
23#include <linux/delay.h>
24#include <linux/kernel.h>
25#include <uapi/linux/swab.h>
26#include "../vdec_drv_if.h"
27#include "../aml_vcodec_util.h"
28#include "../aml_vcodec_dec.h"
29#include "../aml_vcodec_drv.h"
30#include "../aml_vcodec_adapt.h"
31#include "../vdec_drv_base.h"
32#include "../aml_vcodec_vfm.h"
33#include "aml_vp9_parser.h"
34#include "vdec_vp9_trigger.h"
35
36#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
37#include <trace/events/meson_atrace.h>
38
39#define PREFIX_SIZE (16)
40
41#define NAL_TYPE(value) ((value) & 0x1F)
42#define HEADER_BUFFER_SIZE (32 * 1024)
43#define SYNC_CODE (0x498342)
44
45extern int vp9_need_prefix;
46bool need_trigger;
47int dump_cnt = 0;
48
49/**
50 * struct vp9_fb - vp9 decode frame buffer information
51 * @vdec_fb_va : virtual address of struct vdec_fb
52 * @y_fb_dma : dma address of Y frame buffer (luma)
53 * @c_fb_dma : dma address of C frame buffer (chroma)
54 * @poc : picture order count of frame buffer
55 * @reserved : for 8 bytes alignment
56 */
57struct vp9_fb {
58 uint64_t vdec_fb_va;
59 uint64_t y_fb_dma;
60 uint64_t c_fb_dma;
61 int32_t poc;
62 uint32_t reserved;
63};
64
65/**
66 * struct vdec_vp9_dec_info - decode information
67 * @dpb_sz : decoding picture buffer size
68 * @resolution_changed : resoltion change happen
69 * @reserved : for 8 bytes alignment
70 * @bs_dma : Input bit-stream buffer dma address
71 * @y_fb_dma : Y frame buffer dma address
72 * @c_fb_dma : C frame buffer dma address
73 * @vdec_fb_va : VDEC frame buffer struct virtual address
74 */
75struct vdec_vp9_dec_info {
76 uint32_t dpb_sz;
77 uint32_t resolution_changed;
78 uint32_t reserved;
79 uint64_t bs_dma;
80 uint64_t y_fb_dma;
81 uint64_t c_fb_dma;
82 uint64_t vdec_fb_va;
83};
84
85/**
86 * struct vdec_vp9_vsi - shared memory for decode information exchange
87 * between VPU and Host.
88 * The memory is allocated by VPU then mapping to Host
89 * in vpu_dec_init() and freed in vpu_dec_deinit()
90 * by VPU.
91 * AP-W/R : AP is writer/reader on this item
92 * VPU-W/R: VPU is write/reader on this item
93 * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
94 * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
95 * @list_disp : display frame buffer ring list (AP-R, VPU-W)
96 * @dec : decode information (AP-R, VPU-W)
97 * @pic : picture information (AP-R, VPU-W)
98 * @crop : crop information (AP-R, VPU-W)
99 */
100struct vdec_vp9_vsi {
101 char *header_buf;
102 int sps_size;
103 int pps_size;
104 int sei_size;
105 int head_offset;
106 struct vdec_vp9_dec_info dec;
107 struct vdec_pic_info pic;
108 struct vdec_pic_info cur_pic;
109 struct v4l2_rect crop;
110 bool is_combine;
111 int nalu_pos;
112 struct vp9_param_sets ps;
113};
114
115/**
116 * struct vdec_vp9_inst - vp9 decoder instance
117 * @num_nalu : how many nalus be decoded
118 * @ctx : point to aml_vcodec_ctx
119 * @vsi : VPU shared information
120 */
121struct vdec_vp9_inst {
122 unsigned int num_nalu;
123 struct aml_vcodec_ctx *ctx;
124 struct aml_vdec_adapt vdec;
125 struct vdec_vp9_vsi *vsi;
126 struct vcodec_vfm_s vfm;
127 struct aml_dec_params parms;
128 struct completion comp;
129};
130
131static int vdec_write_nalu(struct vdec_vp9_inst *inst,
132 u8 *buf, u32 size, u64 ts);
133
134static void get_pic_info(struct vdec_vp9_inst *inst,
135 struct vdec_pic_info *pic)
136{
137 *pic = inst->vsi->pic;
138
139 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
140 "pic(%d, %d), buf(%d, %d)\n",
141 pic->visible_width, pic->visible_height,
142 pic->coded_width, pic->coded_height);
143 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
144 "Y(%d, %d), C(%d, %d)\n",
145 pic->y_bs_sz, pic->y_len_sz,
146 pic->c_bs_sz, pic->c_len_sz);
147}
148
149static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
150{
151 cr->left = inst->vsi->crop.left;
152 cr->top = inst->vsi->crop.top;
153 cr->width = inst->vsi->crop.width;
154 cr->height = inst->vsi->crop.height;
155
156 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
157 "l=%d, t=%d, w=%d, h=%d\n",
158 cr->left, cr->top, cr->width, cr->height);
159}
160
161static void get_dpb_size(struct vdec_vp9_inst *inst, unsigned int *dpb_sz)
162{
163 *dpb_sz = inst->vsi->dec.dpb_sz;
164 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
165}
166
167static u32 vdec_config_default_parms(u8 *parm)
168{
169 u8 *pbuf = parm;
170
171 pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
172 pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
173 pbuf += sprintf(pbuf, "vp9_double_write_mode:16;");
174 pbuf += sprintf(pbuf, "vp9_buf_width:1920;");
175 pbuf += sprintf(pbuf, "vp9_buf_height:1088;");
176 pbuf += sprintf(pbuf, "vp9_max_pic_w:4096;");
177 pbuf += sprintf(pbuf, "vp9_max_pic_h:2304;");
178 pbuf += sprintf(pbuf, "save_buffer_mode:0;");
179 pbuf += sprintf(pbuf, "no_head:0;");
180 pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
181 pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
182
183 return parm - pbuf;
184}
185
186static void vdec_parser_parms(struct vdec_vp9_inst *inst)
187{
188 struct aml_vcodec_ctx *ctx = inst->ctx;
189
190 if (ctx->config.parm.dec.parms_status &
191 V4L2_CONFIG_PARM_DECODE_CFGINFO) {
192 u8 *pbuf = ctx->config.buf;
193
194 pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
195 pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
196 ctx->config.parm.dec.cfg.ref_buf_margin);
197 pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
198 ctx->config.parm.dec.cfg.double_write_mode);
199 pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
200 ctx->config.parm.dec.cfg.init_width);
201 pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
202 ctx->config.parm.dec.cfg.init_height);
203 pbuf += sprintf(pbuf, "save_buffer_mode:0;");
204 pbuf += sprintf(pbuf, "no_head:0;");
205 pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
206 ctx->config.parm.dec.cfg.canvas_mem_mode);
207 pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
208 ctx->config.parm.dec.cfg.canvas_mem_endian);
209 ctx->config.length = pbuf - ctx->config.buf;
210 } else {
211 ctx->config.parm.dec.cfg.double_write_mode = 16;
212 ctx->config.parm.dec.cfg.ref_buf_margin = 7;
213 ctx->config.length = vdec_config_default_parms(ctx->config.buf);
214 }
215
216 if ((ctx->config.parm.dec.parms_status &
217 V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
218 inst->parms.hdr.color_parms.present_flag) {
219 u8 *pbuf = ctx->config.buf + ctx->config.length;
220
221 pbuf += sprintf(pbuf, "mG.x:%d;",
222 ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
223 pbuf += sprintf(pbuf, "mG.y:%d;",
224 ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
225 pbuf += sprintf(pbuf, "mB.x:%d;",
226 ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
227 pbuf += sprintf(pbuf, "mB.y:%d;",
228 ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
229 pbuf += sprintf(pbuf, "mR.x:%d;",
230 ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
231 pbuf += sprintf(pbuf, "mR.y:%d;",
232 ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
233 pbuf += sprintf(pbuf, "mW.x:%d;",
234 ctx->config.parm.dec.hdr.color_parms.white_point[0]);
235 pbuf += sprintf(pbuf, "mW.y:%d;",
236 ctx->config.parm.dec.hdr.color_parms.white_point[1]);
237 pbuf += sprintf(pbuf, "mMaxDL:%d;",
238 ctx->config.parm.dec.hdr.color_parms.luminance[0] / 1000);
239 pbuf += sprintf(pbuf, "mMinDL:%d;",
240 ctx->config.parm.dec.hdr.color_parms.luminance[1]);
241 pbuf += sprintf(pbuf, "mMaxCLL:%d;",
242 ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
243 pbuf += sprintf(pbuf, "mMaxFALL:%d;",
244 ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
245 ctx->config.length = pbuf - ctx->config.buf;
246 inst->parms.hdr = ctx->config.parm.dec.hdr;
247 inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
248 }
249
250 inst->vdec.config = ctx->config;
251 inst->parms.cfg = ctx->config.parm.dec.cfg;
252 inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
253}
254
255static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
256{
257 struct vdec_vp9_inst *inst = NULL;
258 int ret = -1;
259
260 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
261 if (!inst)
262 return -ENOMEM;
263
264 inst->vdec.video_type = VFORMAT_VP9;
265 inst->vdec.dev = ctx->dev->vpu_plat_dev;
266 inst->vdec.filp = ctx->dev->filp;
267 inst->vdec.ctx = ctx;
268 inst->ctx = ctx;
269
270 vdec_parser_parms(inst);
271
272 /* set play mode.*/
273 if (ctx->is_drm_mode)
274 inst->vdec.port.flag |= PORT_FLAG_DRM;
275
276 /* to eable vp9 hw.*/
277 inst->vdec.port.type = PORT_TYPE_HEVC;
278
279 /* init vfm */
280 inst->vfm.ctx = ctx;
281 inst->vfm.ada_ctx = &inst->vdec;
282 ret = vcodec_vfm_init(&inst->vfm);
283 if (ret) {
284 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
285 "init vfm failed.\n");
286 goto err;
287 }
288
289 /* probe info from the stream */
290 inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
291 if (!inst->vsi) {
292 ret = -ENOMEM;
293 goto err;
294 }
295
296 /* alloc the header buffer to be used cache sps or spp etc.*/
297 inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
298 if (!inst->vsi->header_buf) {
299 ret = -ENOMEM;
300 goto err;
301 }
302
303 init_completion(&inst->comp);
304
305 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
306 "vp9 Instance >> %lx\n", (ulong) inst);
307
308 ctx->ada_ctx = &inst->vdec;
309 *h_vdec = (unsigned long)inst;
310
311 /* init decoder. */
312 ret = video_decoder_init(&inst->vdec);
313 if (ret) {
314 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
315 "vdec_vp9 init err=%d\n", ret);
316 goto err;
317 }
318
319 //dump_init();
320
321 return 0;
322err:
323 if (inst)
324 vcodec_vfm_release(&inst->vfm);
325 if (inst && inst->vsi && inst->vsi->header_buf)
326 kfree(inst->vsi->header_buf);
327 if (inst && inst->vsi)
328 kfree(inst->vsi);
329 if (inst)
330 kfree(inst);
331 *h_vdec = 0;
332
333 return ret;
334}
335
336#if 0
337static int refer_buffer_num(int level_idc, int poc_cnt,
338 int mb_width, int mb_height)
339{
340 return 20;
341}
342#endif
343
344static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
345{
346 u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
347 int w = inst->parms.cfg.init_width;
348 int h = inst->parms.cfg.init_height;
349 u32 dw = 0x1; /*1:1*/
350
351 switch (valid_dw_mode) {
352 case 0x100:
353 if (w > 1920 && h > 1088)
354 dw = 0x4; /*1:2*/
355 break;
356 case 0x200:
357 if (w > 1920 && h > 1088)
358 dw = 0x2; /*1:4*/
359 break;
360 case 0x300:
361 if (w > 1280 && h > 720)
362 dw = 0x4; /*1:2*/
363 break;
364 default:
365 dw = valid_dw_mode;
366 break;
367 }
368
369 return dw;
370}
371
372static int vdec_pic_scale(struct vdec_vp9_inst *inst, int length, int dw_mode)
373{
374 int ret = 64;
375
376 switch (vdec_get_dw_mode(inst, dw_mode)) {
377 case 0x0: /* only afbc, output afbc */
378 ret = 64;
379 break;
380 case 0x1: /* afbc and (w x h), output YUV420 */
381 ret = length;
382 break;
383 case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
384 case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
385 ret = length >> 2;
386 break;
387 case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
388 ret = length >> 1;
389 break;
390 case 0x10: /* (w x h), output YUV420-8bit) */
391 default:
392 ret = length;
393 break;
394 }
395
396 return ret;
397}
398
399static void fill_vdec_params(struct vdec_vp9_inst *inst,
400 struct VP9Context *vp9_ctx)
401{
402 struct vdec_pic_info *pic = &inst->vsi->pic;
403 struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
404 struct v4l2_rect *rect = &inst->vsi->crop;
405 int dw = inst->parms.cfg.double_write_mode;
406 int margin = inst->parms.cfg.ref_buf_margin;
407
408 /* fill visible area size that be used for EGL. */
409 pic->visible_width = vdec_pic_scale(inst, vp9_ctx->render_width, dw);
410 pic->visible_height = vdec_pic_scale(inst, vp9_ctx->render_height, dw);
411
412 /* calc visible ares. */
413 rect->left = 0;
414 rect->top = 0;
415 rect->width = pic->visible_width;
416 rect->height = pic->visible_height;
417
418 /* config canvas size that be used for decoder. */
419 pic->coded_width = vdec_pic_scale(inst, ALIGN(vp9_ctx->width, 32), dw);
420 pic->coded_height = vdec_pic_scale(inst, ALIGN(vp9_ctx->height, 32), dw);
421
422 pic->y_len_sz = pic->coded_width * pic->coded_height;
423 pic->c_len_sz = pic->y_len_sz >> 1;
424
425 /* calc DPB size */
426 dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
427
428 inst->parms.ps.visible_width = pic->visible_width;
429 inst->parms.ps.visible_height = pic->visible_height;
430 inst->parms.ps.coded_width = pic->coded_width;
431 inst->parms.ps.coded_height = pic->coded_height;
432 inst->parms.ps.dpb_size = dec->dpb_sz;
433 inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
434
435 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
436 "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
437 dw, pic->coded_width, pic->coded_height,
438 pic->visible_width, pic->visible_height,
439 dec->dpb_sz - margin, margin);
440}
441
442static int parse_stream_ucode(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
443{
444 int ret = 0;
445
446 ret = vdec_write_nalu(inst, buf, size, 0);
447 if (ret < 0) {
448 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
449 "write frame data failed. err: %d\n", ret);
450 return ret;
451 }
452
453 /* wait ucode parse ending. */
454 wait_for_completion_timeout(&inst->comp,
455 msecs_to_jiffies(1000));
456
457 return inst->vsi->dec.dpb_sz ? 0 : -1;
458}
459
460static int parse_stream_ucode_dma(struct vdec_vp9_inst *inst,
461 ulong buf, u32 size, u32 handle)
462{
463 int ret = 0;
464 struct aml_vdec_adapt *vdec = &inst->vdec;
465
466 ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle);
467 if (ret < 0) {
468 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
469 "write frame data failed. err: %d\n", ret);
470 return ret;
471 }
472
473 /* wait ucode parse ending. */
474 wait_for_completion_timeout(&inst->comp,
475 msecs_to_jiffies(1000));
476
477 return inst->vsi->dec.dpb_sz ? 0 : -1;
478}
479
480static int parse_stream_cpu(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
481{
482 int ret = 0;
483 struct vp9_param_sets *ps = NULL;
484
485 ps = vzalloc(sizeof(struct vp9_param_sets));
486 if (ps == NULL)
487 return -ENOMEM;
488
489 ret = vp9_decode_extradata_ps(buf, size, ps);
490 if (ret) {
491 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
492 "parse extra data failed. err: %d\n", ret);
493 goto out;
494 }
495
496 if (ps->head_parsed)
497 fill_vdec_params(inst, &ps->ctx);
498
499 ret = ps->head_parsed ? 0 : -1;
500out:
501 vfree(ps);
502
503 return ret;
504}
505
506static int vdec_vp9_probe(unsigned long h_vdec,
507 struct aml_vcodec_mem *bs, void *out)
508{
509 struct vdec_vp9_inst *inst =
510 (struct vdec_vp9_inst *)h_vdec;
511 u8 *buf = (u8 *)bs->vaddr;
512 u32 size = bs->size;
513 int ret = 0;
514
515 if (inst->ctx->is_drm_mode) {
516 if (bs->model == VB2_MEMORY_MMAP) {
517 struct aml_video_stream *s =
518 (struct aml_video_stream *) buf;
519
520 if ((s->magic != AML_VIDEO_MAGIC) &&
521 (s->type != V4L_STREAM_TYPE_MATEDATA))
522 return -1;
523
524 if (inst->ctx->param_sets_from_ucode) {
525 ret = parse_stream_ucode(inst, s->data, s->len);
526 } else {
527 ret = parse_stream_cpu(inst, s->data, s->len);
528 }
529 } else if (bs->model == VB2_MEMORY_DMABUF ||
530 bs->model == VB2_MEMORY_USERPTR) {
531 ret = parse_stream_ucode_dma(inst, bs->addr, size,
532 BUFF_IDX(bs, bs->index));
533 }
534 } else {
535 if (inst->ctx->param_sets_from_ucode) {
536 ret = parse_stream_ucode(inst, buf, size);
537 } else {
538 ret = parse_stream_cpu(inst, buf, size);
539 }
540 }
541
542 inst->vsi->cur_pic = inst->vsi->pic;
543
544 return ret;
545}
546
547static void vdec_vp9_deinit(unsigned long h_vdec)
548{
549 ulong flags;
550 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
551 struct aml_vcodec_ctx *ctx = inst->ctx;
552
553 video_decoder_release(&inst->vdec);
554
555 vcodec_vfm_release(&inst->vfm);
556
557 //dump_deinit();
558
559 spin_lock_irqsave(&ctx->slock, flags);
560 if (inst->vsi && inst->vsi->header_buf)
561 kfree(inst->vsi->header_buf);
562
563 if (inst->vsi)
564 kfree(inst->vsi);
565
566 kfree(inst);
567
568 ctx->drv_handle = 0;
569 spin_unlock_irqrestore(&ctx->slock, flags);
570
571 need_trigger = false;
572 dump_cnt = 0;
573}
574
575static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
576{
577 return get_fb_from_queue(inst->ctx, out);
578}
579
580static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
581{
582 struct vframe_s *vf = NULL;
583 struct vdec_v4l2_buffer *fb = NULL;
584
585 vf = peek_video_frame(&inst->vfm);
586 if (!vf) {
587 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
588 "there is no vframe.\n");
589 *out = NULL;
590 return;
591 }
592
593 vf = get_video_frame(&inst->vfm);
594 if (!vf) {
595 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
596 "the vframe is avalid.\n");
597 *out = NULL;
598 return;
599 }
600
601 atomic_set(&vf->use_cnt, 1);
602
603 fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
604 fb->vf_handle = (unsigned long)vf;
605 fb->status = FB_ST_DISPLAY;
606
607 *out = fb;
608
609 //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
610 //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
611 //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
612
613 /* convert yuv format. */
614 //swap_uv(fb->base_c.vaddr, fb->base_c.size);
615}
616
617static void add_prefix_data(struct vp9_superframe_split *s,
618 u8 **out, u32 *out_size)
619{
620 int i;
621 u8 *p = NULL;
622 u32 length;
623
624 length = s->size + s->nb_frames * PREFIX_SIZE;
625 p = vzalloc(length);
626 if (!p) {
627 v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
628 "alloc size %d failed.\n" ,length);
629 return;
630 }
631
632 memcpy(p, s->data, s->size);
633 p += s->size;
634
635 for (i = s->nb_frames; i > 0; i--) {
636 u32 frame_size = s->sizes[i - 1];
637 u8 *prefix = NULL;
638
639 p -= frame_size;
640 memmove(p + PREFIX_SIZE * i, p, frame_size);
641 prefix = p + PREFIX_SIZE * (i - 1);
642
643 /*add amlogic frame headers.*/
644 frame_size += 16;
645 prefix[0] = (frame_size >> 24) & 0xff;
646 prefix[1] = (frame_size >> 16) & 0xff;
647 prefix[2] = (frame_size >> 8 ) & 0xff;
648 prefix[3] = (frame_size >> 0 ) & 0xff;
649 prefix[4] = ((frame_size >> 24) & 0xff) ^ 0xff;
650 prefix[5] = ((frame_size >> 16) & 0xff) ^ 0xff;
651 prefix[6] = ((frame_size >> 8 ) & 0xff) ^ 0xff;
652 prefix[7] = ((frame_size >> 0 ) & 0xff) ^ 0xff;
653 prefix[8] = 0;
654 prefix[9] = 0;
655 prefix[10] = 0;
656 prefix[11] = 1;
657 prefix[12] = 'A';
658 prefix[13] = 'M';
659 prefix[14] = 'L';
660 prefix[15] = 'V';
661 frame_size -= 16;
662 }
663
664 *out = p;
665 *out_size = length;
666}
667
668static void trigger_decoder(struct aml_vdec_adapt *vdec)
669{
670 int i, ret;
671 u32 frame_size = 0;
672 u8 *p = vp9_trigger_header;
673
674 for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
675 frame_size = vp9_trigger_framesize[i];
676 ret = vdec_vframe_write(vdec, p,
677 frame_size, 0);
678 v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR,
679 "write trigger frame %d\n", ret);
680 p += frame_size;
681 }
682}
683
684static int vdec_write_nalu(struct vdec_vp9_inst *inst,
685 u8 *buf, u32 size, u64 ts)
686{
687 int ret = 0;
688 struct aml_vdec_adapt *vdec = &inst->vdec;
689 struct vp9_superframe_split s;
690 u8 *data = NULL;
691 u32 length = 0;
692 bool need_prefix = vp9_need_prefix;
693
694 memset(&s, 0, sizeof(s));
695
696 /*trigger.*/
697 if (0 && !need_trigger) {
698 trigger_decoder(vdec);
699 need_trigger = true;
700 }
701
702 if (need_prefix) {
703 /*parse superframe.*/
704 s.data = buf;
705 s.data_size = size;
706 ret = vp9_superframe_split_filter(&s);
707 if (ret) {
708 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
709 "parse frames failed.\n");
710 return ret;
711 }
712
713 /*add headers.*/
714 add_prefix_data(&s, &data, &length);
715 ret = vdec_vframe_write(vdec, data, length, ts);
716 vfree(data);
717 } else {
718 ret = vdec_vframe_write(vdec, buf, size, ts);
719 }
720
721 return ret;
722}
723
724static bool monitor_res_change(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
725{
726 int ret = -1;
727 u8 *p = buf;
728 int len = size;
729 u32 synccode = vp9_need_prefix ?
730 ((p[1] << 16) | (p[2] << 8) | p[3]) :
731 ((p[17] << 16) | (p[18] << 8) | p[19]);
732
733 if (synccode == SYNC_CODE) {
734 ret = parse_stream_cpu(inst, p, len);
735 if (!ret && (inst->vsi->cur_pic.coded_width !=
736 inst->vsi->pic.coded_width ||
737 inst->vsi->cur_pic.coded_height !=
738 inst->vsi->pic.coded_height)) {
739 inst->vsi->cur_pic = inst->vsi->pic;
740 return true;
741 }
742 }
743
744 return false;
745}
746
747static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
748 u64 timestamp, bool *res_chg)
749{
750 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
751 struct aml_vdec_adapt *vdec = &inst->vdec;
752 u8 *buf = (u8 *) bs->vaddr;
753 u32 size = bs->size;
754 int ret = -1;
755
756 if (bs == NULL)
757 return -1;
758
759 if (vdec_input_full(vdec)) {
760 ATRACE_COUNTER("vdec_input_full", 0);
761 return -EAGAIN;
762 }
763
764 if (inst->ctx->is_drm_mode) {
765 if (bs->model == VB2_MEMORY_MMAP) {
766 struct aml_video_stream *s =
767 (struct aml_video_stream *) buf;
768
769 if (s->magic != AML_VIDEO_MAGIC)
770 return -1;
771
772 if (!inst->ctx->param_sets_from_ucode &&
773 (s->type == V4L_STREAM_TYPE_MATEDATA)) {
774 if ((*res_chg = monitor_res_change(inst,
775 s->data, s->len)))
776 return 0;
777 }
778
779 ret = vdec_vframe_write(vdec,
780 s->data,
781 s->len,
782 timestamp);
783 } else if (bs->model == VB2_MEMORY_DMABUF ||
784 bs->model == VB2_MEMORY_USERPTR) {
785 ret = vdec_vframe_write_with_dma(vdec,
786 bs->addr, size, timestamp,
787 BUFF_IDX(bs, bs->index));
788 }
789 } else {
790 /*checked whether the resolution changes.*/
791 if ((!inst->ctx->param_sets_from_ucode) &&
792 (*res_chg = monitor_res_change(inst, buf, size)))
793 return 0;
794
795 ret = vdec_write_nalu(inst, buf, size, timestamp);
796 }
797 ATRACE_COUNTER("v4l2_decode_write", ret);
798
799 return ret;
800}
801
802 static void get_param_config_info(struct vdec_vp9_inst *inst,
803 struct aml_dec_params *parms)
804 {
805 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
806 parms->cfg = inst->parms.cfg;
807 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
808 parms->ps = inst->parms.ps;
809 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
810 parms->hdr = inst->parms.hdr;
811 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
812 parms->cnt = inst->parms.cnt;
813
814 parms->parms_status |= inst->parms.parms_status;
815
816 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
817 "parms status: %u\n", parms->parms_status);
818 }
819
820static int vdec_vp9_get_param(unsigned long h_vdec,
821 enum vdec_get_param_type type, void *out)
822{
823 int ret = 0;
824 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
825
826 if (!inst) {
827 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
828 "the vp9 inst of dec is invalid.\n");
829 return -1;
830 }
831
832 switch (type) {
833 case GET_PARAM_DISP_FRAME_BUFFER:
834 vdec_vp9_get_vf(inst, out);
835 break;
836
837 case GET_PARAM_FREE_FRAME_BUFFER:
838 ret = vdec_vp9_get_fb(inst, out);
839 break;
840
841 case GET_PARAM_PIC_INFO:
842 get_pic_info(inst, out);
843 break;
844
845 case GET_PARAM_DPB_SIZE:
846 get_dpb_size(inst, out);
847 break;
848
849 case GET_PARAM_CROP_INFO:
850 get_crop_info(inst, out);
851 break;
852
853 case GET_PARAM_CONFIG_INFO:
854 get_param_config_info(inst, out);
855 break;
856 default:
857 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
858 "invalid get parameter type=%d\n", type);
859 ret = -EINVAL;
860 }
861
862 return ret;
863}
864
865static void set_param_write_sync(struct vdec_vp9_inst *inst)
866{
867 complete(&inst->comp);
868}
869
870static void set_param_ps_info(struct vdec_vp9_inst *inst,
871 struct aml_vdec_ps_infos *ps)
872{
873 struct vdec_pic_info *pic = &inst->vsi->pic;
874 struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
875 struct v4l2_rect *rect = &inst->vsi->crop;
876
877 /* fill visible area size that be used for EGL. */
878 pic->visible_width = ps->visible_width;
879 pic->visible_height = ps->visible_height;
880
881 /* calc visible ares. */
882 rect->left = 0;
883 rect->top = 0;
884 rect->width = pic->visible_width;
885 rect->height = pic->visible_height;
886
887 /* config canvas size that be used for decoder. */
888 pic->coded_width = ps->coded_width;
889 pic->coded_height = ps->coded_height;
890
891 pic->y_len_sz = pic->coded_width * pic->coded_height;
892 pic->c_len_sz = pic->y_len_sz >> 1;
893
894 /* calc DPB size */
895 dec->dpb_sz = ps->dpb_size;
896
897 inst->parms.ps = *ps;
898 inst->parms.parms_status |=
899 V4L2_CONFIG_PARM_DECODE_PSINFO;
900
901 /*wake up*/
902 complete(&inst->comp);
903
904 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
905 "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
906 ps->visible_width, ps->visible_height,
907 ps->coded_width, ps->coded_height,
908 ps->dpb_size);
909}
910
911static void set_param_hdr_info(struct vdec_vp9_inst *inst,
912 struct aml_vdec_hdr_infos *hdr)
913{
914 if ((inst->parms.parms_status &
915 V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
916 inst->parms.hdr = *hdr;
917 inst->parms.parms_status |=
918 V4L2_CONFIG_PARM_DECODE_HDRINFO;
919 aml_vdec_dispatch_event(inst->ctx,
920 V4L2_EVENT_SRC_CH_HDRINFO);
921 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
922 "VP9 set HDR infos\n");
923 }
924}
925
926static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event)
927{
928 aml_vdec_dispatch_event(inst->ctx, *event);
929 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
930 "VP9 post event: %d\n", *event);
931}
932
933static int vdec_vp9_set_param(unsigned long h_vdec,
934 enum vdec_set_param_type type, void *in)
935{
936 int ret = 0;
937 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
938
939 if (!inst) {
940 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
941 "the vp9 inst of dec is invalid.\n");
942 return -1;
943 }
944
945 switch (type) {
946 case SET_PARAM_WRITE_FRAME_SYNC:
947 set_param_write_sync(inst);
948 break;
949
950 case SET_PARAM_PS_INFO:
951 set_param_ps_info(inst, in);
952 break;
953
954 case SET_PARAM_HDR_INFO:
955 set_param_hdr_info(inst, in);
956 break;
957
958 case SET_PARAM_POST_EVENT:
959 set_param_post_event(inst, in);
960 break;
961 default:
962 v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
963 "invalid set parameter type=%d\n", type);
964 ret = -EINVAL;
965 }
966
967 return ret;
968}
969
970static struct vdec_common_if vdec_vp9_if = {
971 .init = vdec_vp9_init,
972 .probe = vdec_vp9_probe,
973 .decode = vdec_vp9_decode,
974 .get_param = vdec_vp9_get_param,
975 .set_param = vdec_vp9_set_param,
976 .deinit = vdec_vp9_deinit,
977};
978
979struct vdec_common_if *get_vp9_dec_comm_if(void);
980
981struct vdec_common_if *get_vp9_dec_comm_if(void)
982{
983 return &vdec_vp9_if;
984}
985
986