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