summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/vdec_vp9_if.c (plain)
blob: 6aa8bd876013c8258017c24b4411416dec3cab27
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
174 return parm - pbuf;
175}
176
177static void vdec_parser_parms(struct vdec_vp9_inst *inst)
178{
179 struct aml_vcodec_ctx *ctx = inst->ctx;
180
181 if (!ctx->config.length) {
182 ctx->config.type = V4L2_CONFIG_PARM_DECODE;
183 ctx->config.parm.dec.double_write_mode = 16;
184 inst->parms = ctx->config.parm.dec;
185
186 ctx->config.length =
187 vdec_config_default_parms(ctx->config.buf);
188 } else {
189 u8 *pbuf = ctx->config.buf;
190
191 inst->parms = ctx->config.parm.dec;
192 pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
193 pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
194 inst->parms.buffer_margin);
195 pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
196 inst->parms.double_write_mode);
197 pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
198 inst->parms.buffer_width);
199 pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
200 inst->parms.buffer_height);
201 pbuf += sprintf(pbuf, "save_buffer_mode:%d;",
202 inst->parms.buffer_mode);
203 pbuf += sprintf(pbuf, "no_head:0;");
204
205 if ((ctx->config.parm.dec.dec_parms_status &
206 V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
207 inst->parms.hdr.color_parms.present_flag) {
208 pbuf += sprintf(pbuf, "mG.x:%d;",
209 inst->parms.hdr.color_parms.primaries[0][0]);
210 pbuf += sprintf(pbuf, "mG.y:%d;",
211 inst->parms.hdr.color_parms.primaries[0][1]);
212 pbuf += sprintf(pbuf, "mB.x:%d;",
213 inst->parms.hdr.color_parms.primaries[1][0]);
214 pbuf += sprintf(pbuf, "mB.y:%d;",
215 inst->parms.hdr.color_parms.primaries[1][1]);
216 pbuf += sprintf(pbuf, "mR.x:%d;",
217 inst->parms.hdr.color_parms.primaries[2][0]);
218 pbuf += sprintf(pbuf, "mR.y:%d;",
219 inst->parms.hdr.color_parms.primaries[2][1]);
220 pbuf += sprintf(pbuf, "mW.x:%d;",
221 inst->parms.hdr.color_parms.white_point[0]);
222 pbuf += sprintf(pbuf, "mW.y:%d;",
223 inst->parms.hdr.color_parms.white_point[1]);
224 pbuf += sprintf(pbuf, "mMaxDL:%d;",
225 inst->parms.hdr.color_parms.luminance[0] / 1000);
226 pbuf += sprintf(pbuf, "mMinDL:%d;",
227 inst->parms.hdr.color_parms.luminance[1]);
228 pbuf += sprintf(pbuf, "mMaxCLL:%d;",
229 inst->parms.hdr.color_parms.content_light_level.max_content);
230 pbuf += sprintf(pbuf, "mMaxFALL:%d;",
231 inst->parms.hdr.color_parms.content_light_level.max_pic_average);
232 }
233
234 ctx->config.length = pbuf - ctx->config.buf;
235 }
236
237 inst->vdec.config = ctx->config;
238
239 inst->parms.dec_parms_status |=
240 V4L2_CONFIG_PARM_DECODE_COMMON;
241}
242
243static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
244{
245 struct vdec_vp9_inst *inst = NULL;
246 int ret = -1;
247
248 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
249 if (!inst)
250 return -ENOMEM;
251
252 inst->vdec.video_type = VFORMAT_VP9;
253 inst->vdec.dev = ctx->dev->vpu_plat_dev;
254 inst->vdec.filp = ctx->dev->filp;
255 inst->vdec.ctx = ctx;
256 inst->ctx = ctx;
257
258 vdec_parser_parms(inst);
259
260 /* set play mode.*/
261 if (ctx->is_drm_mode)
262 inst->vdec.port.flag |= PORT_FLAG_DRM;
263
264 /* to eable vp9 hw.*/
265 inst->vdec.port.type = PORT_TYPE_HEVC;
266
267 /* init vfm */
268 inst->vfm.ctx = ctx;
269 inst->vfm.ada_ctx = &inst->vdec;
270 vcodec_vfm_init(&inst->vfm);
271
272 /* probe info from the stream */
273 inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
274 if (!inst->vsi) {
275 ret = -ENOMEM;
276 goto error_free_inst;
277 }
278
279 /* alloc the header buffer to be used cache sps or spp etc.*/
280 inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
281 if (!inst->vsi) {
282 ret = -ENOMEM;
283 goto error_free_vsi;
284 }
285
286 init_completion(&inst->comp);
287
288 aml_vcodec_debug(inst, "vp9 Instance >> %p", inst);
289
290 ctx->ada_ctx = &inst->vdec;
291 *h_vdec = (unsigned long)inst;
292
293 /* init decoder. */
294 ret = video_decoder_init(&inst->vdec);
295 if (ret) {
296 aml_vcodec_err(inst, "vdec_vp9 init err=%d", ret);
297 goto error_free_inst;
298 }
299
300 //dump_init();
301
302 return 0;
303
304error_free_vsi:
305 kfree(inst->vsi);
306error_free_inst:
307 kfree(inst);
308 *h_vdec = 0;
309
310 return ret;
311}
312
313#if 0
314static int refer_buffer_num(int level_idc, int poc_cnt,
315 int mb_width, int mb_height)
316{
317 return 20;
318}
319#endif
320
321static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
322{
323 u32 valid_dw_mode = inst->parms.double_write_mode;
324 int w = inst->parms.buffer_width;
325 int h = inst->parms.buffer_height;
326 u32 dw = 0x1; /*1:1*/
327
328 switch (valid_dw_mode) {
329 case 0x100:
330 if (w > 1920 && h > 1088)
331 dw = 0x4; /*1:2*/
332 break;
333 case 0x200:
334 if (w > 1920 && h > 1088)
335 dw = 0x2; /*1:4*/
336 break;
337 case 0x300:
338 if (w > 1280 && h > 720)
339 dw = 0x4; /*1:2*/
340 break;
341 default:
342 dw = valid_dw_mode;
343 break;
344 }
345
346 return dw;
347}
348
349static int vdec_pic_scale(struct vdec_vp9_inst *inst, int length, int dw_mode)
350{
351 int ret = 64;
352
353 switch (vdec_get_dw_mode(inst, dw_mode)) {
354 case 0x0: /* only afbc, output afbc */
355 ret = 64;
356 break;
357 case 0x1: /* afbc and (w x h), output YUV420 */
358 ret = length;
359 break;
360 case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
361 case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
362 ret = length >> 2;
363 break;
364 case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
365 ret = length >> 1;
366 break;
367 case 0x10: /* (w x h), output YUV420-8bit) */
368 default:
369 ret = length;
370 break;
371 }
372
373 return ret;
374}
375
376static void fill_vdec_params(struct vdec_vp9_inst *inst,
377 struct VP9Context *vp9_ctx)
378{
379 struct vdec_pic_info *pic = &inst->vsi->pic;
380 struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
381 struct v4l2_rect *rect = &inst->vsi->crop;
382 int dw = inst->parms.double_write_mode;
383 int margin = inst->parms.buffer_margin;
384
385 /* fill visible area size that be used for EGL. */
386 pic->visible_width = vdec_pic_scale(inst, vp9_ctx->render_width, dw);
387 pic->visible_height = vdec_pic_scale(inst, vp9_ctx->render_height, dw);
388
389 /* calc visible ares. */
390 rect->left = 0;
391 rect->top = 0;
392 rect->width = pic->visible_width;
393 rect->height = pic->visible_height;
394
395 /* config canvas size that be used for decoder. */
396 pic->coded_width = vdec_pic_scale(inst, ALIGN(vp9_ctx->width, 32), dw);
397 pic->coded_height = vdec_pic_scale(inst, ALIGN(vp9_ctx->height, 32), dw);
398
399 pic->y_len_sz = pic->coded_width * pic->coded_height;
400 pic->c_len_sz = pic->y_len_sz >> 1;
401
402 /* calc DPB size */
403 dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
404
405 inst->parms.dec_parms_status |=
406 V4L2_CONFIG_PARM_DECODE_PICINFO;
407
408 aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
409 inst->ctx->id, inst->parms.double_write_mode,
410 pic->coded_width, pic->coded_height,
411 pic->visible_width, pic->visible_height,
412 dec->dpb_sz - margin, margin);
413}
414
415static int stream_parse_by_ucode(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
416{
417 int ret = 0;
418
419 ret = vdec_write_nalu(inst, buf, size, 0);
420 if (ret < 0) {
421 pr_err("write frame data failed. err: %d\n", ret);
422 return ret;
423 }
424
425 /* wait ucode parse ending. */
426 wait_for_completion_timeout(&inst->comp,
427 msecs_to_jiffies(1000));
428
429 return inst->vsi->dec.dpb_sz ? 0 : -1;
430}
431
432static int stream_parse(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
433{
434 int ret = 0;
435 struct vp9_param_sets *ps = NULL;
436
437 ps = kzalloc(sizeof(struct vp9_param_sets), GFP_KERNEL);
438 if (ps == NULL)
439 return -ENOMEM;
440
441 ret = vp9_decode_extradata_ps(buf, size, ps);
442 if (ret) {
443 pr_err("parse extra data failed. err: %d\n", ret);
444 goto out;
445 }
446
447 if (ps->head_parsed)
448 fill_vdec_params(inst, &ps->ctx);
449
450 ret = ps->head_parsed ? 0 : -1;
451out:
452 kfree(ps);
453
454 return ret;
455}
456
457static int vdec_vp9_probe(unsigned long h_vdec,
458 struct aml_vcodec_mem *bs, void *out)
459{
460 struct vdec_vp9_inst *inst =
461 (struct vdec_vp9_inst *)h_vdec;
462 struct stream_info *st;
463 u8 *buf = (u8 *)bs->vaddr;
464 u32 size = bs->size;
465 int ret = 0;
466
467 st = (struct stream_info *)buf;
468 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
469 return 0;
470
471 if (st->magic == NORe || st->magic == NORn)
472 ret = stream_parse(inst, st->data, st->length);
473 else {
474 if (inst->ctx->param_sets_from_ucode)
475 ret = stream_parse_by_ucode(inst, buf, size);
476 else
477 ret = stream_parse(inst, buf, size);
478 }
479
480 inst->vsi->cur_pic = inst->vsi->pic;
481
482 return ret;
483}
484
485static void vdec_vp9_deinit(unsigned long h_vdec)
486{
487 ulong flags;
488 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
489 struct aml_vcodec_ctx *ctx = inst->ctx;
490
491 aml_vcodec_debug_enter(inst);
492
493 video_decoder_release(&inst->vdec);
494
495 vcodec_vfm_release(&inst->vfm);
496
497 //dump_deinit();
498
499 spin_lock_irqsave(&ctx->slock, flags);
500 if (inst->vsi && inst->vsi->header_buf)
501 kfree(inst->vsi->header_buf);
502
503 if (inst->vsi)
504 kfree(inst->vsi);
505
506 kfree(inst);
507
508 ctx->drv_handle = 0;
509 spin_unlock_irqrestore(&ctx->slock, flags);
510
511 need_trigger = false;
512 dump_cnt = 0;
513}
514
515static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
516{
517 return get_fb_from_queue(inst->ctx, out);
518}
519
520static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
521{
522 struct vframe_s *vf = NULL;
523 struct vdec_v4l2_buffer *fb = NULL;
524
525 vf = peek_video_frame(&inst->vfm);
526 if (!vf) {
527 aml_vcodec_debug(inst, "there is no vframe.");
528 *out = NULL;
529 return;
530 }
531
532 vf = get_video_frame(&inst->vfm);
533 if (!vf) {
534 aml_vcodec_debug(inst, "the vframe is avalid.");
535 *out = NULL;
536 return;
537 }
538
539 atomic_set(&vf->use_cnt, 1);
540
541 fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
542 fb->vf_handle = (unsigned long)vf;
543 fb->status = FB_ST_DISPLAY;
544
545 *out = fb;
546
547 //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
548 //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
549 //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
550
551 /* convert yuv format. */
552 //swap_uv(fb->base_c.vaddr, fb->base_c.size);
553}
554
555static void add_prefix_data(struct vp9_superframe_split *s,
556 u8 **out, u32 *out_size)
557{
558 int i;
559 u8 *p = NULL;
560 u32 length;
561
562 length = s->size + s->nb_frames * PREFIX_SIZE;
563 p = vzalloc(length);
564 if (!p) {
565 pr_err("alloc size %d failed.\n" ,length);
566 return;
567 }
568
569 memcpy(p, s->data, s->size);
570 p += s->size;
571
572 for (i = s->nb_frames; i > 0; i--) {
573 u32 frame_size = s->sizes[i - 1];
574 u8 *prefix = NULL;
575
576 p -= frame_size;
577 memmove(p + PREFIX_SIZE * i, p, frame_size);
578 prefix = p + PREFIX_SIZE * (i - 1);
579
580 /*add amlogic frame headers.*/
581 frame_size += 16;
582 prefix[0] = (frame_size >> 24) & 0xff;
583 prefix[1] = (frame_size >> 16) & 0xff;
584 prefix[2] = (frame_size >> 8 ) & 0xff;
585 prefix[3] = (frame_size >> 0 ) & 0xff;
586 prefix[4] = ((frame_size >> 24) & 0xff) ^ 0xff;
587 prefix[5] = ((frame_size >> 16) & 0xff) ^ 0xff;
588 prefix[6] = ((frame_size >> 8 ) & 0xff) ^ 0xff;
589 prefix[7] = ((frame_size >> 0 ) & 0xff) ^ 0xff;
590 prefix[8] = 0;
591 prefix[9] = 0;
592 prefix[10] = 0;
593 prefix[11] = 1;
594 prefix[12] = 'A';
595 prefix[13] = 'M';
596 prefix[14] = 'L';
597 prefix[15] = 'V';
598 frame_size -= 16;
599 }
600
601 *out = p;
602 *out_size = length;
603}
604
605static void trigger_decoder(struct aml_vdec_adapt *vdec)
606{
607 int i, ret;
608 u32 frame_size = 0;
609 u8 *p = vp9_trigger_header;
610
611 for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
612 frame_size = vp9_trigger_framesize[i];
613 ret = vdec_vframe_write(vdec, p,
614 frame_size, 0);
615 pr_err("write trigger frame %d\n", ret);
616 p += frame_size;
617 }
618}
619
620static int vdec_write_nalu(struct vdec_vp9_inst *inst,
621 u8 *buf, u32 size, u64 ts)
622{
623 int ret = 0;
624 struct aml_vdec_adapt *vdec = &inst->vdec;
625 struct vp9_superframe_split s;
626 u8 *data = NULL;
627 u32 length = 0;
628 bool need_prefix = vp9_need_prefix;
629
630 memset(&s, 0, sizeof(s));
631
632 /*trigger.*/
633 if (0 && !need_trigger) {
634 trigger_decoder(vdec);
635 need_trigger = true;
636 }
637
638 if (need_prefix) {
639 /*parse superframe.*/
640 s.data = buf;
641 s.data_size = size;
642 ret = vp9_superframe_split_filter(&s);
643 if (ret) {
644 pr_err("parse frames failed.\n");
645 return ret;
646 }
647
648 /*add headers.*/
649 add_prefix_data(&s, &data, &length);
650 ret = vdec_vframe_write(vdec, data, length, ts);
651 vfree(data);
652 } else {
653 ret = vdec_vframe_write(vdec, buf, size, ts);
654 }
655
656 return ret;
657}
658
659static bool monitor_res_change(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
660{
661 int ret = -1;
662 u8 *p = buf;
663 int len = size;
664 u32 synccode = vp9_need_prefix ?
665 ((p[1] << 16) | (p[2] << 8) | p[3]) :
666 ((p[17] << 16) | (p[18] << 8) | p[19]);
667
668 if (synccode == SYNC_CODE) {
669 ret = stream_parse(inst, p, len);
670 if (!ret && (inst->vsi->cur_pic.coded_width !=
671 inst->vsi->pic.coded_width ||
672 inst->vsi->cur_pic.coded_height !=
673 inst->vsi->pic.coded_height)) {
674 inst->vsi->cur_pic = inst->vsi->pic;
675 return true;
676 }
677 }
678
679 return false;
680}
681
682static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
683 u64 timestamp, bool *res_chg)
684{
685 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
686 struct aml_vdec_adapt *vdec = &inst->vdec;
687 struct stream_info *st;
688 u8 *buf;
689 u32 size;
690 int ret = -1;
691
692 /* bs NULL means flush decoder */
693 if (bs == NULL)
694 return -1;
695
696 buf = (u8 *)bs->vaddr;
697 size = bs->size;
698 st = (struct stream_info *)buf;
699
700 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
701 ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm));
702 else if (st->magic == NORe)
703 ret = vdec_vbuf_write(vdec, st->data, st->length);
704 else if (st->magic == NORn)
705 ret = vdec_write_nalu(inst, st->data, st->length, timestamp);
706 else if (inst->ctx->is_stream_mode)
707 ret = vdec_vbuf_write(vdec, buf, size);
708 else {
709 /*checked whether the resolution changes.*/
710 if ((*res_chg = monitor_res_change(inst, buf, size)))
711 return 0;
712
713 ret = vdec_write_nalu(inst, buf, size, timestamp);
714 }
715
716 return ret;
717}
718
719 static void get_param_config_info(struct vdec_vp9_inst *inst,
720 struct aml_dec_params *parms)
721 {
722 *parms = inst->parms;
723
724 aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
725 }
726
727static int vdec_vp9_get_param(unsigned long h_vdec,
728 enum vdec_get_param_type type, void *out)
729{
730 int ret = 0;
731 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
732
733 if (!inst) {
734 pr_err("the vp9 inst of dec is invalid.\n");
735 return -1;
736 }
737
738 switch (type) {
739 case GET_PARAM_DISP_FRAME_BUFFER:
740 vdec_vp9_get_vf(inst, out);
741 break;
742
743 case GET_PARAM_FREE_FRAME_BUFFER:
744 ret = vdec_vp9_get_fb(inst, out);
745 break;
746
747 case GET_PARAM_PIC_INFO:
748 get_pic_info(inst, out);
749 break;
750
751 case GET_PARAM_DPB_SIZE:
752 get_dpb_size(inst, out);
753 break;
754
755 case GET_PARAM_CROP_INFO:
756 get_crop_info(inst, out);
757 break;
758
759 case GET_PARAM_CONFIG_INFO:
760 get_param_config_info(inst, out);
761 break;
762 default:
763 aml_vcodec_err(inst, "invalid get parameter type=%d", type);
764 ret = -EINVAL;
765 }
766
767 return ret;
768}
769
770static void set_param_write_sync(struct vdec_vp9_inst *inst)
771{
772 complete(&inst->comp);
773}
774
775static void set_param_pic_info(struct vdec_vp9_inst *inst,
776 struct aml_vdec_pic_infos *info)
777{
778 struct vdec_pic_info *pic = &inst->vsi->pic;
779 struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
780 struct v4l2_rect *rect = &inst->vsi->crop;
781
782 /* fill visible area size that be used for EGL. */
783 pic->visible_width = info->visible_width;
784 pic->visible_height = info->visible_height;
785
786 /* calc visible ares. */
787 rect->left = 0;
788 rect->top = 0;
789 rect->width = pic->visible_width;
790 rect->height = pic->visible_height;
791
792 /* config canvas size that be used for decoder. */
793 pic->coded_width = info->coded_width;
794 pic->coded_height = info->coded_height;
795
796 pic->y_len_sz = pic->coded_width * pic->coded_height;
797 pic->c_len_sz = pic->y_len_sz >> 1;
798
799 /* calc DPB size */
800 dec->dpb_sz = 5;
801
802 inst->parms.dec_parms_status |=
803 V4L2_CONFIG_PARM_DECODE_PICINFO;
804
805 /*wake up*/
806 complete(&inst->comp);
807
808 pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
809 info->visible_width, info->visible_height,
810 info->coded_width, info->coded_height,
811 info->dpb_size);
812}
813
814static void set_param_hdr_info(struct vdec_vp9_inst *inst,
815 struct aml_vdec_hdr_infos *hdr)
816{
817 inst->parms.hdr = *hdr;
818 inst->parms.dec_parms_status |=
819 V4L2_CONFIG_PARM_DECODE_HDRINFO;
820
821 //pr_info("VP9 set HDR infos\n");
822}
823
824static int vdec_vp9_set_param(unsigned long h_vdec,
825 enum vdec_set_param_type type, void *in)
826{
827 int ret = 0;
828 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
829
830 if (!inst) {
831 pr_err("the vp9 inst of dec is invalid.\n");
832 return -1;
833 }
834
835 switch (type) {
836 case SET_PARAM_WRITE_FRAME_SYNC:
837 set_param_write_sync(inst);
838 break;
839
840 case SET_PARAM_PIC_INFO:
841 set_param_pic_info(inst, in);
842 break;
843
844 case SET_PARAM_HDR_INFO:
845 set_param_hdr_info(inst, in);
846 break;
847 default:
848 aml_vcodec_err(inst, "invalid set parameter type=%d", type);
849 ret = -EINVAL;
850 }
851
852 return ret;
853}
854
855static struct vdec_common_if vdec_vp9_if = {
856 .init = vdec_vp9_init,
857 .probe = vdec_vp9_probe,
858 .decode = vdec_vp9_decode,
859 .get_param = vdec_vp9_get_param,
860 .set_param = vdec_vp9_set_param,
861 .deinit = vdec_vp9_deinit,
862};
863
864struct vdec_common_if *get_vp9_dec_comm_if(void);
865
866struct vdec_common_if *get_vp9_dec_comm_if(void)
867{
868 return &vdec_vp9_if;
869}
870
871