summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/vdec_vp9_if.c (plain)
blob: 757be84206c25e77de6547b40352e79ea558c1c2
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_adapt.h"
30#include "../vdec_drv_base.h"
31#include "../aml_vcodec_vfm.h"
32#include "aml_vp9_parser.h"
33#include "vdec_vp9_trigger.h"
34
35#define PREFIX_SIZE (16)
36
37#define NAL_TYPE(value) ((value) & 0x1F)
38#define HEADER_BUFFER_SIZE (32 * 1024)
39
40bool need_trigger;
41int dump_cnt = 0;
42
43/**
44 * struct vp9_fb - vp9 decode frame buffer information
45 * @vdec_fb_va : virtual address of struct vdec_fb
46 * @y_fb_dma : dma address of Y frame buffer (luma)
47 * @c_fb_dma : dma address of C frame buffer (chroma)
48 * @poc : picture order count of frame buffer
49 * @reserved : for 8 bytes alignment
50 */
51struct vp9_fb {
52 uint64_t vdec_fb_va;
53 uint64_t y_fb_dma;
54 uint64_t c_fb_dma;
55 int32_t poc;
56 uint32_t reserved;
57};
58
59/**
60 * struct vdec_vp9_dec_info - decode information
61 * @dpb_sz : decoding picture buffer size
62 * @resolution_changed : resoltion change happen
63 * @reserved : for 8 bytes alignment
64 * @bs_dma : Input bit-stream buffer dma address
65 * @y_fb_dma : Y frame buffer dma address
66 * @c_fb_dma : C frame buffer dma address
67 * @vdec_fb_va : VDEC frame buffer struct virtual address
68 */
69struct vdec_vp9_dec_info {
70 uint32_t dpb_sz;
71 uint32_t resolution_changed;
72 uint32_t reserved;
73 uint64_t bs_dma;
74 uint64_t y_fb_dma;
75 uint64_t c_fb_dma;
76 uint64_t vdec_fb_va;
77};
78
79/**
80 * struct vdec_vp9_vsi - shared memory for decode information exchange
81 * between VPU and Host.
82 * The memory is allocated by VPU then mapping to Host
83 * in vpu_dec_init() and freed in vpu_dec_deinit()
84 * by VPU.
85 * AP-W/R : AP is writer/reader on this item
86 * VPU-W/R: VPU is write/reader on this item
87 * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
88 * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
89 * @list_disp : display frame buffer ring list (AP-R, VPU-W)
90 * @dec : decode information (AP-R, VPU-W)
91 * @pic : picture information (AP-R, VPU-W)
92 * @crop : crop information (AP-R, VPU-W)
93 */
94struct vdec_vp9_vsi {
95 char *header_buf;
96 int sps_size;
97 int pps_size;
98 int sei_size;
99 int head_offset;
100 struct vdec_vp9_dec_info dec;
101 struct vdec_pic_info pic;
102 struct v4l2_rect crop;
103 bool is_combine;
104 int nalu_pos;
105 struct vp9_head_info_t head;
106};
107
108/**
109 * struct vdec_vp9_inst - vp9 decoder instance
110 * @num_nalu : how many nalus be decoded
111 * @ctx : point to aml_vcodec_ctx
112 * @vsi : VPU shared information
113 */
114struct vdec_vp9_inst {
115 unsigned int num_nalu;
116 struct aml_vcodec_ctx *ctx;
117 struct aml_vdec_adapt vdec;
118 struct vdec_vp9_vsi *vsi;
119 struct vcodec_vfm_s vfm;
120};
121
122struct vp9_superframe_split {
123 /*in data*/
124 u8 *data;
125 u32 data_size;
126
127 /*out data*/
128 int nb_frames;
129 int size;
130 int next_frame;
131 u32 next_frame_offset;
132 int sizes[8];
133};
134
135#if 1
136#define DUMP_FILE_NAME "/data/dump/dump.tmp"
137static struct file *filp;
138static loff_t file_pos;
139
140void dump_write(const char __user *buf, size_t count)
141{
142 mm_segment_t old_fs;
143
144 if (!filp)
145 return;
146
147 old_fs = get_fs();
148 set_fs(KERNEL_DS);
149
150 if (count != vfs_write(filp, buf, count, &file_pos))
151 pr_err("Failed to write file\n");
152
153 set_fs(old_fs);
154}
155
156void dump_init(void)
157{
158 filp = filp_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
159 if (IS_ERR(filp)) {
160 pr_err("open dump file failed\n");
161 filp = NULL;
162 }
163}
164
165void dump_deinit(void)
166{
167 if (filp) {
168 filp_close(filp, current->files);
169 filp = NULL;
170 file_pos = 0;
171 }
172}
173
174void swap_uv(void *uv, int size)
175{
176 int i;
177 __u16 *p = uv;
178
179 size /= 2;
180
181 for (i = 0; i < size; i++, p++)
182 *p = __swab16(*p);
183}
184#endif
185
186static void get_pic_info(struct vdec_vp9_inst *inst,
187 struct vdec_pic_info *pic)
188{
189 *pic = inst->vsi->pic;
190
191 aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
192 pic->visible_width, pic->visible_height,
193 pic->coded_width, pic->coded_height);
194 aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
195 pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
196}
197
198static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
199{
200 cr->left = inst->vsi->crop.left;
201 cr->top = inst->vsi->crop.top;
202 cr->width = inst->vsi->crop.width;
203 cr->height = inst->vsi->crop.height;
204
205 aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
206 cr->left, cr->top, cr->width, cr->height);
207}
208
209static void get_dpb_size(struct vdec_vp9_inst *inst, unsigned int *dpb_sz)
210{
211 *dpb_sz = 20;//inst->vsi->dec.dpb_sz;
212 aml_vcodec_debug(inst, "sz=%d", *dpb_sz);
213}
214
215static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
216{
217 struct vdec_vp9_inst *inst = NULL;
218 int ret = -1;
219
220 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
221 if (!inst)
222 return -ENOMEM;
223
224 inst->ctx = ctx;
225
226 inst->vdec.format = VFORMAT_VP9;
227 inst->vdec.dev = ctx->dev->vpu_plat_dev;
228 inst->vdec.filp = ctx->dev->filp;
229 inst->vdec.ctx = ctx;
230
231 /* set play mode.*/
232 if (ctx->is_drm_mode)
233 inst->vdec.port.flag |= PORT_FLAG_DRM;
234
235 /* to eable vp9 hw.*/
236 inst->vdec.port.type = PORT_TYPE_HEVC;
237
238 /* init vfm */
239 inst->vfm.ctx = ctx;
240 inst->vfm.ada_ctx = &inst->vdec;
241 vcodec_vfm_init(&inst->vfm);
242
243 /* probe info from the stream */
244 inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
245 if (!inst->vsi) {
246 ret = -ENOMEM;
247 goto error_free_inst;
248 }
249
250 /* alloc the header buffer to be used cache sps or spp etc.*/
251 inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
252 if (!inst->vsi) {
253 ret = -ENOMEM;
254 goto error_free_vsi;
255 }
256
257 inst->vsi->pic.visible_width = 1920;
258 inst->vsi->pic.visible_height = 1080;
259 inst->vsi->pic.coded_width = 1920;
260 inst->vsi->pic.coded_height = 1088;
261 inst->vsi->pic.y_bs_sz = 0;
262 inst->vsi->pic.y_len_sz = (1920 * 1088);
263 inst->vsi->pic.c_bs_sz = 0;
264 inst->vsi->pic.c_len_sz = (1920 * 1088 / 2);
265
266 aml_vcodec_debug(inst, "vp9 Instance >> %p", inst);
267
268 ctx->ada_ctx = &inst->vdec;
269 *h_vdec = (unsigned long)inst;
270
271 /* init decoder. */
272 ret = video_decoder_init(&inst->vdec);
273 if (ret) {
274 aml_vcodec_err(inst, "vdec_vp9 init err=%d", ret);
275 goto error_free_inst;
276 }
277
278 dump_init();
279
280 return 0;
281
282error_free_vsi:
283 kfree(inst->vsi);
284error_free_inst:
285 kfree(inst);
286 *h_vdec = 0;
287
288 return ret;
289}
290
291#if 0
292static int refer_buffer_num(int level_idc, int poc_cnt,
293 int mb_width, int mb_height)
294{
295 return 20;
296}
297#endif
298
299static void fill_vdec_params(struct vdec_vp9_inst *inst)
300{
301 struct vdec_pic_info *pic = &inst->vsi->pic;
302 struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
303 struct v4l2_rect *rect = &inst->vsi->crop;
304 unsigned int mb_w = 0, mb_h = 0, width, height;
305 //unsigned int crop_unit_x = 0, crop_unit_y = 0;
306 //unsigned int poc_cnt = 0;
307
308 /* calc width & height. */
309 width = 1920;
310 height = 1080;
311
312 /* fill visible area size that be used for EGL. */
313 pic->visible_width = width;
314 pic->visible_height = height;
315
316 /* calc visible ares. */
317 rect->left = 0;
318 rect->top = 0;
319 rect->width = pic->visible_width;
320 rect->height = pic->visible_height;
321
322 /* config canvas size that be used for decoder. */
323 pic->coded_width = ALIGN(mb_w, 4) << 4;
324 pic->coded_height = ALIGN(mb_h, 4) << 4;
325
326 pic->coded_width = 1920;
327 pic->coded_height = 1088;//temp
328
329 pic->y_len_sz = pic->coded_width * pic->coded_height;
330 pic->c_len_sz = pic->y_len_sz >> 1;
331
332 /* calc DPB size */
333 dec->dpb_sz = 20;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
334
335 pr_info("[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n",
336 inst->ctx->id, pic->coded_width, pic->coded_height,
337 pic->visible_width, pic->visible_height, dec->dpb_sz);
338}
339
340#if 0
341static int vp9_parse_nal_header(u32 val)
342{
343 if (val & 0x80) {
344 pr_err("the nal data is invalid.\n");
345 return -1;
346 }
347
348 return (val & 0x7f) >> 1;
349}
350#endif
351
352static void vp9_parse(struct vp9_head_info_t *head, u8 *buf, u32 size)
353{
354 //int ret = -1;
355 //u8 *p = buf;
356
357 head->parsed = true;
358
359 return;
360}
361
362static int stream_parse(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
363{
364 //struct vp9_stream_t s;
365 //struct vp9_SPS_t *sps;
366 //unsigned int nal_type;
367 int nal_idx = 0;
368 int real_data_pos, real_data_size;
369 bool is_combine = false;
370
371 vp9_parse(&inst->vsi->head, buf, size);
372
373 if (!inst->vsi->head.parsed)
374 return -1;
375
376 /* if the st compose from csd + slice that is the combine data. */
377 inst->vsi->is_combine = is_combine;
378 inst->vsi->nalu_pos = nal_idx;
379
380 /* start code plus nal type. */
381 real_data_pos = nal_idx + 1;
382 real_data_size = size - real_data_pos;
383
384 //sps = kzalloc(sizeof(struct vp9_SPS_t), GFP_KERNEL);
385 //if (sps == NULL)
386 //return -ENOMEM;
387
388 /* the extra data would be parsed. */
389 //vp9_stream_set(&s, &buf[real_data_pos], real_data_size);
390 //vp9_sps_parse(&s, sps);
391 //vp9_sps_info(sps);
392
393 //fill_vdec_params(inst, sps);
394 fill_vdec_params(inst);
395
396 //kfree(sps);
397
398 return 0;
399}
400
401static int vdec_vp9_probe(unsigned long h_vdec,
402 struct aml_vcodec_mem *bs, void *out)
403{
404 struct vdec_vp9_inst *inst =
405 (struct vdec_vp9_inst *)h_vdec;
406 struct stream_info *st;
407 u8 *buf = (u8 *)bs->va;
408 u32 size = bs->size;
409 int ret = 0;
410
411 st = (struct stream_info *)buf;
412 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
413 return 0;
414
415 if (st->magic == NORe || st->magic == NORn)
416 ret = stream_parse(inst, st->data, st->length);
417 else
418 ret = stream_parse(inst, buf, size);
419
420 return ret;
421}
422
423static void vdec_vp9_deinit(unsigned long h_vdec)
424{
425 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
426
427 if (!inst)
428 return;
429
430 aml_vcodec_debug_enter(inst);
431
432 video_decoder_release(&inst->vdec);
433
434 vcodec_vfm_release(&inst->vfm);
435
436 dump_deinit();
437
438 if (inst->vsi && inst->vsi->header_buf)
439 kfree(inst->vsi->header_buf);
440
441 if (inst->vsi)
442 kfree(inst->vsi);
443
444 kfree(inst);
445 need_trigger = false;
446 dump_cnt = 0;
447}
448
449static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out)
450{
451 return get_fb_from_queue(inst->ctx, out);
452}
453
454static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_fb **out)
455{
456 struct vframe_s *vf = NULL;
457 struct vdec_fb *fb = NULL;
458
459 aml_vcodec_debug(inst, "%s() [%d], vfm: %p",
460 __func__, __LINE__, &inst->vfm);
461
462 vf = peek_video_frame(&inst->vfm);
463 if (!vf) {
464 aml_vcodec_debug(inst, "there is no vframe.");
465 *out = NULL;
466 return;
467 }
468
469 vf = get_video_frame(&inst->vfm);
470 if (!vf) {
471 aml_vcodec_debug(inst, "the vframe is avalid.");
472 *out = NULL;
473 return;
474 }
475
476 atomic_set(&vf->use_cnt, 1);
477
478 aml_vcodec_debug(inst, "%s() [%d], vf: %p, v4l_mem_handle: %lx, idx: %d\n",
479 __func__, __LINE__, vf, vf->v4l_mem_handle, vf->index);
480
481 fb = (struct vdec_fb *)vf->v4l_mem_handle;
482 fb->vf_handle = (unsigned long)vf;
483 fb->status = FB_ST_DISPLAY;
484
485 *out = fb;
486
487 //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
488 //dump_write(fb->base_y.va, fb->base_y.bytes_used);
489 //dump_write(fb->base_c.va, fb->base_c.bytes_used);
490
491 /* convert yuv format. */
492 //swap_uv(fb->base_c.va, fb->base_c.size);
493
494 aml_vcodec_debug(inst, "%s() [%d], va: %p, phy: %x, size: %zu",
495 __func__, __LINE__, fb->base_y.va,
496 (unsigned int)virt_to_phys(fb->base_y.va), fb->base_y.size);
497 aml_vcodec_debug(inst, "%s() [%d], va: %p, phy: %x, size: %zu",
498 __func__, __LINE__, fb->base_c.va,
499 (unsigned int)virt_to_phys(fb->base_c.va), fb->base_c.size);
500}
501
502static int vp9_superframe_split_filter(struct vp9_superframe_split *s)
503{
504 int i, j, ret, marker;
505 bool is_superframe = false;
506
507 if (!s->data)
508 return -1;
509
510 marker = s->data[s->data_size - 1];
511 if ((marker & 0xe0) == 0xc0) {
512 int length_size = 1 + ((marker >> 3) & 0x3);
513 int nb_frames = 1 + (marker & 0x7);
514 int idx_size = 2 + nb_frames * length_size;
515
516 if (s->data_size >= idx_size &&
517 s->data[s->data_size - idx_size] == marker) {
518 s64 total_size = 0;
519 int idx = s->data_size + 1 - idx_size;
520
521 for (i = 0; i < nb_frames; i++) {
522 int frame_size = 0;
523 for (j = 0; j < length_size; j++)
524 frame_size |= s->data[idx++] << (j * 8);
525
526 total_size += frame_size;
527 if (frame_size < 0 ||
528 total_size > s->data_size - idx_size) {
529 pr_err( "Invalid frame size in a sframe: %d\n",
530 frame_size);
531 ret = -EINVAL;
532 goto fail;
533 }
534 s->sizes[i] = frame_size;
535 }
536
537 s->nb_frames = nb_frames;
538 s->size = total_size;
539 s->next_frame = 0;
540 s->next_frame_offset = 0;
541 is_superframe = true;
542 }
543 }else {
544 s->nb_frames = 1;
545 s->sizes[0] = s->data_size;
546 s->size = s->data_size;
547 }
548
549 /*pr_info("sframe: %d, frames: %d, IN: %x, OUT: %x\n",
550 is_superframe, s->nb_frames,
551 s->data_size, s->size);*/
552
553 /* parse uncompressed header. */
554 if (is_superframe) {
555 /* bitstream profile. */
556 /* frame type. (intra or inter) */
557 /* colorspace descriptor */
558 /* ... */
559
560 pr_info("the frame is a superframe.\n");
561 }
562
563 /*pr_err("in: %x, %d, out: %x, sizes %d,%d,%d,%d,%d,%d,%d,%d\n",
564 s->data_size,
565 s->nb_frames,
566 s->size,
567 s->sizes[0],
568 s->sizes[1],
569 s->sizes[2],
570 s->sizes[3],
571 s->sizes[4],
572 s->sizes[5],
573 s->sizes[6],
574 s->sizes[7]);*/
575
576 return 0;
577fail:
578 return ret;
579}
580
581static void add_prefix_data(struct vp9_superframe_split *s,
582 u8 **out, u32 *out_size)
583{
584 int i;
585 u8 *p = NULL;
586 u32 length;
587
588 length = s->size + s->nb_frames * PREFIX_SIZE;
589 p = vzalloc(length);
590 if (!p) {
591 pr_err("alloc size %d failed.\n" ,length);
592 return;
593 }
594
595 memcpy(p, s->data, s->size);
596 p += s->size;
597
598 for (i = s->nb_frames; i > 0; i--) {
599 u32 frame_size = s->sizes[i - 1];
600 u8 *prefix = NULL;
601
602 p -= frame_size;
603 memmove(p + PREFIX_SIZE * i, p, frame_size);
604 prefix = p + PREFIX_SIZE * (i - 1);
605
606 /*add amlogic frame headers.*/
607 frame_size += 4;
608 prefix[0] = (frame_size >> 24) & 0xff;
609 prefix[1] = (frame_size >> 16) & 0xff;
610 prefix[2] = (frame_size >> 8 ) & 0xff;
611 prefix[3] = (frame_size >> 0 ) & 0xff;
612 prefix[4] = ((frame_size >> 24) & 0xff) ^ 0xff;
613 prefix[5] = ((frame_size >> 16) & 0xff) ^ 0xff;
614 prefix[6] = ((frame_size >> 8 ) & 0xff) ^ 0xff;
615 prefix[7] = ((frame_size >> 0 ) & 0xff) ^ 0xff;
616 prefix[8] = 0;
617 prefix[9] = 0;
618 prefix[10] = 0;
619 prefix[11] = 1;
620 prefix[12] = 'A';
621 prefix[13] = 'M';
622 prefix[14] = 'L';
623 prefix[15] = 'V';
624 frame_size -= 4;
625 }
626
627 *out = p;
628 *out_size = length;
629}
630
631static void trigger_decoder(struct aml_vdec_adapt *vdec)
632{
633 int i, ret;
634 u32 frame_size = 0;
635 u8 *p = vp9_trigger_header;
636
637 for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
638 frame_size = vp9_trigger_framesize[i];
639 ret = vdec_vframe_write(vdec, p,
640 frame_size, 0);
641 pr_err("write trigger frame %d\n", ret);
642 p += frame_size;
643 }
644}
645
646static int vdec_write_nalu(struct vdec_vp9_inst *inst,
647 u8 *buf, u32 size, u64 ts)
648{
649 int ret = 0;
650 struct aml_vdec_adapt *vdec = &inst->vdec;
651 struct vp9_superframe_split s;
652 u8 *data = NULL;
653 u32 length = 0;
654
655 memset(&s, 0, sizeof(s));
656
657 /*trigger.*/
658 if (0 && !need_trigger) {
659 trigger_decoder(vdec);
660 need_trigger = true;
661 }
662
663 /*parse superframe.*/
664 s.data = buf;
665 s.data_size = size;
666 ret = vp9_superframe_split_filter(&s);
667 if (ret) {
668 pr_err("parse frames failed.\n");
669 return ret;
670 }
671
672 /*add headers.*/
673 add_prefix_data(&s, &data, &length);
674
675 ret = vdec_vframe_write(vdec, data, length, ts);
676
677 aml_vcodec_debug(inst, "buf: %p, buf size: %u, write to: %d",
678 data, length, ret);
679
680 vfree(data);
681
682 return 0;
683}
684
685static int vdec_vp9_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
686 unsigned long int timestamp, bool *res_chg)
687{
688 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
689 struct aml_vdec_adapt *vdec = &inst->vdec;
690 struct stream_info *st;
691 u8 *buf;
692 u32 size;
693 int ret = 0;
694
695 /* bs NULL means flush decoder */
696 if (bs == NULL)
697 return 0;
698
699 buf = (u8 *)bs->va;
700 size = bs->size;
701 st = (struct stream_info *)buf;
702
703 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
704 ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm));
705 else if (st->magic == NORe)
706 ret = vdec_vbuf_write(vdec, st->data, st->length);
707 else if (st->magic == NORn)
708 ret = vdec_write_nalu(inst, st->data, st->length, timestamp);
709 else if (inst->ctx->is_stream_mode)
710 ret = vdec_vbuf_write(vdec, buf, size);
711 else
712 ret = vdec_write_nalu(inst, buf, size, timestamp);
713
714 return ret;
715}
716
717static int vdec_vp9_get_param(unsigned long h_vdec,
718 enum vdec_get_param_type type, void *out)
719{
720 int ret = 0;
721 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
722
723 if (!inst) {
724 pr_err("the vp9 inst of dec is invalid.\n");
725 return -1;
726 }
727
728 switch (type) {
729 case GET_PARAM_DISP_FRAME_BUFFER:
730 vdec_vp9_get_vf(inst, out);
731 break;
732
733 case GET_PARAM_FREE_FRAME_BUFFER:
734 ret = vdec_vp9_get_fb(inst, out);
735 break;
736
737 case GET_PARAM_PIC_INFO:
738 get_pic_info(inst, out);
739 break;
740
741 case GET_PARAM_DPB_SIZE:
742 get_dpb_size(inst, out);
743 break;
744
745 case GET_PARAM_CROP_INFO:
746 get_crop_info(inst, out);
747 break;
748
749 default:
750 aml_vcodec_err(inst, "invalid get parameter type=%d", type);
751 ret = -EINVAL;
752 }
753
754 return ret;
755}
756
757static struct vdec_common_if vdec_vp9_if = {
758 vdec_vp9_init,
759 vdec_vp9_probe,
760 vdec_vp9_decode,
761 vdec_vp9_get_param,
762 vdec_vp9_deinit,
763};
764
765struct vdec_common_if *get_vp9_dec_comm_if(void);
766
767struct vdec_common_if *get_vp9_dec_comm_if(void)
768{
769 return &vdec_vp9_if;
770}
771
772