summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/vdec_h264_if.c (plain)
blob: 02848b89f3e511a66ca29a54ebca73620e1e3415
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
27#include "../vdec_drv_if.h"
28#include "../aml_vcodec_util.h"
29#include "../aml_vcodec_dec.h"
30#include "../aml_vcodec_adapt.h"
31#include "../vdec_drv_base.h"
32#include "../aml_vcodec_vfm.h"
33#include "aml_h264_parser.h"
34#include "../utils/common.h"
35
36/* h264 NALU type */
37#define NAL_NON_IDR_SLICE 0x01
38#define NAL_IDR_SLICE 0x05
39#define NAL_H264_SEI 0x06
40#define NAL_H264_SPS 0x07
41#define NAL_H264_PPS 0x08
42#define NAL_H264_AUD 0x09
43
44#define AVC_NAL_TYPE(value) ((value) & 0x1F)
45
46#define BUF_PREDICTION_SZ (64 * 1024)//(32 * 1024)
47
48#define MB_UNIT_LEN 16
49
50/* motion vector size (bytes) for every macro block */
51#define HW_MB_STORE_SZ 64
52
53#define H264_MAX_FB_NUM 17
54#define HDR_PARSING_BUF_SZ 1024
55
56#define HEADER_BUFFER_SIZE (128 * 1024)
57
58/**
59 * struct h264_fb - h264 decode frame buffer information
60 * @vdec_fb_va : virtual address of struct vdec_fb
61 * @y_fb_dma : dma address of Y frame buffer (luma)
62 * @c_fb_dma : dma address of C frame buffer (chroma)
63 * @poc : picture order count of frame buffer
64 * @reserved : for 8 bytes alignment
65 */
66struct h264_fb {
67 uint64_t vdec_fb_va;
68 uint64_t y_fb_dma;
69 uint64_t c_fb_dma;
70 int32_t poc;
71 uint32_t reserved;
72};
73
74/**
75 * struct h264_ring_fb_list - ring frame buffer list
76 * @fb_list : frame buffer arrary
77 * @read_idx : read index
78 * @write_idx : write index
79 * @count : buffer count in list
80 */
81struct h264_ring_fb_list {
82 struct h264_fb fb_list[H264_MAX_FB_NUM];
83 unsigned int read_idx;
84 unsigned int write_idx;
85 unsigned int count;
86 unsigned int reserved;
87};
88
89/**
90 * struct vdec_h264_dec_info - decode information
91 * @dpb_sz : decoding picture buffer size
92 * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer
93 * @reserved : for 8 bytes alignment
94 * @bs_dma : Input bit-stream buffer dma address
95 * @y_fb_dma : Y frame buffer dma address
96 * @c_fb_dma : C frame buffer dma address
97 * @vdec_fb_va : VDEC frame buffer struct virtual address
98 */
99struct vdec_h264_dec_info {
100 uint32_t dpb_sz;
101 uint32_t realloc_mv_buf;
102 uint32_t reserved;
103 uint64_t bs_dma;
104 uint64_t y_fb_dma;
105 uint64_t c_fb_dma;
106 uint64_t vdec_fb_va;
107};
108
109/**
110 * struct vdec_h264_vsi - shared memory for decode information exchange
111 * between VPU and Host.
112 * The memory is allocated by VPU then mapping to Host
113 * in vpu_dec_init() and freed in vpu_dec_deinit()
114 * by VPU.
115 * AP-W/R : AP is writer/reader on this item
116 * VPU-W/R: VPU is write/reader on this item
117 * @dec : decode information (AP-R, VPU-W)
118 * @pic : picture information (AP-R, VPU-W)
119 * @crop : crop information (AP-R, VPU-W)
120 */
121struct vdec_h264_vsi {
122 unsigned char hdr_buf[HDR_PARSING_BUF_SZ];
123 char *header_buf;
124 int sps_size;
125 int pps_size;
126 int sei_size;
127 int head_offset;
128 struct vdec_h264_dec_info dec;
129 struct vdec_pic_info pic;
130 struct vdec_pic_info cur_pic;
131 struct v4l2_rect crop;
132 bool is_combine;
133 int nalu_pos;
134};
135
136/**
137 * struct vdec_h264_inst - h264 decoder instance
138 * @num_nalu : how many nalus be decoded
139 * @ctx : point to aml_vcodec_ctx
140 * @pred_buf : HW working predication buffer
141 * @mv_buf : HW working motion vector buffer
142 * @vpu : VPU instance
143 * @vsi : VPU shared information
144 */
145struct vdec_h264_inst {
146 unsigned int num_nalu;
147 struct aml_vcodec_ctx *ctx;
148 struct aml_vcodec_mem pred_buf;
149 struct aml_vcodec_mem mv_buf[H264_MAX_FB_NUM];
150 struct aml_vdec_adapt vdec;
151 struct vdec_h264_vsi *vsi;
152 struct vcodec_vfm_s vfm;
153 struct completion comp;
154};
155
156#if 0
157#define DUMP_FILE_NAME "/data/dump/dump.tmp"
158static struct file *filp;
159static loff_t file_pos;
160
161void dump_write(const char __user *buf, size_t count)
162{
163 mm_segment_t old_fs;
164
165 if (!filp)
166 return;
167
168 old_fs = get_fs();
169 set_fs(KERNEL_DS);
170
171 if (count != vfs_write(filp, buf, count, &file_pos))
172 pr_err("Failed to write file\n");
173
174 set_fs(old_fs);
175}
176
177void dump_init(void)
178{
179 filp = filp_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
180 if (IS_ERR(filp)) {
181 pr_err("open dump file failed\n");
182 filp = NULL;
183 }
184}
185
186void dump_deinit(void)
187{
188 if (filp) {
189 filp_close(filp, current->files);
190 filp = NULL;
191 file_pos = 0;
192 }
193}
194
195void swap_uv(void *uv, int size)
196{
197 int i;
198 __u16 *p = uv;
199
200 size /= 2;
201
202 for (i = 0; i < size; i++, p++)
203 *p = __swab16(*p);
204}
205#endif
206
207static void get_pic_info(struct vdec_h264_inst *inst,
208 struct vdec_pic_info *pic)
209{
210 *pic = inst->vsi->pic;
211
212 aml_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
213 pic->visible_width, pic->visible_height,
214 pic->coded_width, pic->coded_height);
215 aml_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
216 pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
217}
218
219static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
220{
221 cr->left = inst->vsi->crop.left;
222 cr->top = inst->vsi->crop.top;
223 cr->width = inst->vsi->crop.width;
224 cr->height = inst->vsi->crop.height;
225
226 aml_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
227 cr->left, cr->top, cr->width, cr->height);
228}
229
230static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz)
231{
232 *dpb_sz = inst->vsi->dec.dpb_sz;
233 aml_vcodec_debug(inst, "sz=%d", *dpb_sz);
234}
235
236static void skip_aud_data(u8 **data, u32 *size)
237{
238 int i;
239
240 i = find_start_code(*data, *size);
241 if (i > 0 && (*data)[i++] == 0x9 && (*data)[i++] == 0xf0) {
242 *size -= i;
243 *data += i;
244 }
245}
246
247static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
248{
249 struct vdec_h264_inst *inst = NULL;
250 int ret = -1;
251
252 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
253 if (!inst)
254 return -ENOMEM;
255
256 inst->ctx = ctx;
257
258 inst->vdec.video_type = VFORMAT_H264;
259 inst->vdec.dev = ctx->dev->vpu_plat_dev;
260 inst->vdec.filp = ctx->dev->filp;
261 inst->vdec.ctx = ctx;
262
263 /* set play mode.*/
264 if (ctx->is_drm_mode)
265 inst->vdec.port.flag |= PORT_FLAG_DRM;
266
267 /* init vfm */
268 inst->vfm.ctx = ctx;
269 inst->vfm.ada_ctx = &inst->vdec;
270 vcodec_vfm_init(&inst->vfm);
271
272 ret = video_decoder_init(&inst->vdec);
273 if (ret) {
274 aml_vcodec_err(inst, "vdec_h264 init err=%d", ret);
275 goto error_free_inst;
276 }
277
278 /* probe info from the stream */
279 inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL);
280 if (!inst->vsi) {
281 ret = -ENOMEM;
282 goto error_free_inst;
283 }
284
285 /* alloc the header buffer to be used cache sps or spp etc.*/
286 inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
287 if (!inst->vsi) {
288 ret = -ENOMEM;
289 goto error_free_vsi;
290 }
291
292 inst->vsi->pic.visible_width = 1920;
293 inst->vsi->pic.visible_height = 1080;
294 inst->vsi->pic.coded_width = 1920;
295 inst->vsi->pic.coded_height = 1088;
296 inst->vsi->pic.y_bs_sz = 0;
297 inst->vsi->pic.y_len_sz = (1920 * 1088);
298 inst->vsi->pic.c_bs_sz = 0;
299 inst->vsi->pic.c_len_sz = (1920 * 1088 / 2);
300
301 init_completion(&inst->comp);
302
303 aml_vcodec_debug(inst, "H264 Instance >> %p", inst);
304
305 ctx->ada_ctx = &inst->vdec;
306 *h_vdec = (unsigned long)inst;
307
308 //dump_init();
309
310 return 0;
311
312error_free_vsi:
313 kfree(inst->vsi);
314error_free_inst:
315 kfree(inst);
316 *h_vdec = 0;
317
318 return ret;
319}
320
321#if 0
322static int refer_buffer_num(int level_idc, int max_poc_cnt,
323 int mb_width, int mb_height)
324{
325 int size;
326 int pic_size = mb_width * mb_height * 384;
327
328 switch (level_idc) {
329 case 9:
330 size = 152064;
331 break;
332 case 10:
333 size = 152064;
334 break;
335 case 11:
336 size = 345600;
337 break;
338 case 12:
339 size = 912384;
340 break;
341 case 13:
342 size = 912384;
343 break;
344 case 20:
345 size = 912384;
346 break;
347 case 21:
348 size = 1824768;
349 break;
350 case 22:
351 size = 3110400;
352 break;
353 case 30:
354 size = 3110400;
355 break;
356 case 31:
357 size = 6912000;
358 break;
359 case 32:
360 size = 7864320;
361 break;
362 case 40:
363 size = 12582912;
364 break;
365 case 41:
366 size = 12582912;
367 break;
368 case 42:
369 size = 13369344;
370 break;
371 case 50:
372 size = 42393600;
373 break;
374 case 51:
375 case 52:
376 default:
377 size = 70778880;
378 break;
379 }
380
381 size /= pic_size;
382 size = size + 1; /* need more buffers */
383
384 if (size > max_poc_cnt)
385 size = max_poc_cnt;
386
387 return size;
388}
389#endif
390
391static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps)
392{
393 struct vdec_pic_info *pic = &inst->vsi->pic;
394 struct vdec_h264_dec_info *dec = &inst->vsi->dec;
395 struct v4l2_rect *rect = &inst->vsi->crop;
396 u32 mb_w, mb_h, width, height;
397
398 mb_w = sps->mb_width;
399 mb_h = sps->mb_height;
400
401 width = mb_w << 4;
402 height = mb_h << 4;
403
404 width -= (sps->crop_left + sps->crop_right);
405 height -= (sps->crop_top + sps->crop_bottom);
406
407 /* fill visible area size that be used for EGL. */
408 pic->visible_width = width;
409 pic->visible_height = height;
410
411 /* calc visible ares. */
412 rect->left = 0;
413 rect->top = 0;
414 rect->width = pic->visible_width;
415 rect->height = pic->visible_height;
416
417 /* config canvas size that be used for decoder. */
418 pic->coded_width = ALIGN(mb_w, 4) << 4;
419 pic->coded_height = ALIGN(mb_h, 4) << 4;
420 pic->y_len_sz = pic->coded_width * pic->coded_height;
421 pic->c_len_sz = pic->y_len_sz >> 1;
422
423 /* calc DPB size */
424 dec->dpb_sz = sps->ref_frame_count;
425
426 aml_vcodec_debug(inst, "[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n",
427 inst->ctx->id, pic->coded_width, pic->coded_height,
428 pic->visible_width, pic->visible_height, dec->dpb_sz);
429}
430
431static bool check_frame_combine(u8 *buf, u32 size, int *pos)
432{
433 bool combine = false;
434 int i = 0, j = 0, cnt = 0;
435 u8 *p = buf;
436
437 for (i = 4; i < size; i++) {
438 j = find_start_code(p, 7);
439 if (j > 0) {
440 if (++cnt > 1) {
441 combine = true;
442 break;
443 }
444
445 *pos = p - buf + j;
446 p += j;
447 i += j;
448 }
449 p++;
450 }
451
452 //pr_info("nal pos: %d, is_combine: %d\n",*pos, *is_combine);
453 return combine;
454}
455
456static int stream_parse_by_ucode(struct vdec_h264_inst *inst, u8 *buf, u32 size)
457{
458 int ret = 0;
459 struct aml_vdec_adapt *vdec = &inst->vdec;
460
461 ret = vdec_vframe_write(vdec, buf, size, 0);
462 if (ret < 0) {
463 pr_err("write frame data failed. err: %d\n", ret);
464 return ret;
465 }
466
467 /* wait ucode parse ending. */
468 wait_for_completion_timeout(&inst->comp,
469 msecs_to_jiffies(1000));
470
471 return inst->vsi->dec.dpb_sz ? 0 : -1;
472}
473
474static int stream_parse(struct vdec_h264_inst *inst, u8 *buf, u32 size)
475{
476 int ret = 0;
477 struct h264_param_sets *ps;
478 u32 nal_type;
479 int nal_idx = 0;
480 bool is_combine = false;
481
482 is_combine = check_frame_combine(buf, size, &nal_idx);
483 if (nal_idx < 0)
484 return -1;
485
486 nal_type = AVC_NAL_TYPE(buf[nal_idx]);
487 if (nal_type != NAL_H264_SPS)
488 return -1;
489
490 /* if the st compose from csd + slice that is the combine data. */
491 inst->vsi->is_combine = is_combine;
492 inst->vsi->nalu_pos = nal_idx;
493
494 ps = kzalloc(sizeof(struct h264_param_sets), GFP_KERNEL);
495 if (ps == NULL)
496 return -ENOMEM;
497
498 ret = h264_decode_extradata_ps(buf, size, ps);
499 if (ret) {
500 pr_err("parse extra data failed. err: %d\n", ret);
501 goto out;
502 }
503
504 if (ps->sps_parsed)
505 fill_vdec_params(inst, &ps->sps);
506
507 ret = ps->sps_parsed ? 0 : -1;
508out:
509 kfree(ps);
510
511 return ret;
512}
513
514static int vdec_h264_probe(unsigned long h_vdec,
515 struct aml_vcodec_mem *bs, void *out)
516{
517 struct vdec_h264_inst *inst =
518 (struct vdec_h264_inst *)h_vdec;
519 struct stream_info *st;
520 u8 *buf = (u8 *)bs->vaddr;
521 u32 size = bs->size;
522 int ret = 0;
523
524 st = (struct stream_info *)buf;
525 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
526 return 0;
527
528 if (st->magic == NORe || st->magic == NORn) {
529 buf = st->data;
530 size = st->length;
531 }
532
533 skip_aud_data(&buf, &size);
534
535 if (inst->ctx->param_sets_from_ucode)
536 ret = stream_parse_by_ucode(inst, buf, size);
537 else
538 ret = stream_parse(inst, buf, size);
539
540 inst->vsi->cur_pic = inst->vsi->pic;
541
542 return ret;
543}
544
545static void vdec_h264_deinit(unsigned long h_vdec)
546{
547 ulong flags;
548 struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
549 struct aml_vcodec_ctx *ctx = inst->ctx;
550
551 aml_vcodec_debug_enter(inst);
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
572static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
573{
574 return get_fb_from_queue(inst->ctx, out);
575}
576
577static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
578{
579 struct vframe_s *vf = NULL;
580 struct vdec_v4l2_buffer *fb = NULL;
581
582 vf = peek_video_frame(&inst->vfm);
583 if (!vf) {
584 aml_vcodec_debug(inst, "there is no vframe.");
585 *out = NULL;
586 return;
587 }
588
589 vf = get_video_frame(&inst->vfm);
590 if (!vf) {
591 aml_vcodec_debug(inst, "the vframe is avalid.");
592 *out = NULL;
593 return;
594 }
595
596 atomic_set(&vf->use_cnt, 1);
597
598 fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
599 fb->vf_handle = (unsigned long)vf;
600 fb->status = FB_ST_DISPLAY;
601
602 *out = fb;
603
604 //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
605 //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
606 //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
607
608 /* convert yuv format. */
609 //swap_uv(fb->base_c.vaddr, fb->base_c.size);
610}
611
612static int vdec_write_nalu(struct vdec_h264_inst *inst,
613 u8 *buf, u32 size, u64 ts)
614{
615 int ret = -1;
616 struct aml_vdec_adapt *vdec = &inst->vdec;
617 bool is_combine = inst->vsi->is_combine;
618 int nalu_pos;
619 u32 nal_type;
620
621 nalu_pos = find_start_code(buf, size);
622 if (nalu_pos < 0)
623 goto err;
624
625 nal_type = AVC_NAL_TYPE(buf[nalu_pos]);
626 //aml_vcodec_debug(inst, "NALU type: %d, size: %u", nal_type, size);
627
628 if (nal_type == NAL_H264_SPS && !is_combine) {
629 if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
630 ret = -EILSEQ;
631 goto err;
632 }
633 inst->vsi->sps_size = size;
634 memcpy(inst->vsi->header_buf + inst->vsi->head_offset, buf, size);
635 inst->vsi->head_offset += inst->vsi->sps_size;
636 ret = size;
637 } else if (nal_type == NAL_H264_PPS && !is_combine) {
638 //buf_sz -= nal_start_idx;
639 if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
640 ret = -EILSEQ;
641 goto err;
642 }
643 inst->vsi->pps_size = size;
644 memcpy(inst->vsi->header_buf + inst->vsi->head_offset, buf, size);
645 inst->vsi->head_offset += inst->vsi->pps_size;
646 ret = size;
647 } else if (nal_type == NAL_H264_SEI && !is_combine) {
648 if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
649 ret = -EILSEQ;
650 goto err;
651 }
652 inst->vsi->sei_size = size;
653 memcpy(inst->vsi->header_buf + inst->vsi->head_offset, buf, size);
654 inst->vsi->head_offset += inst->vsi->sei_size;
655 ret = size;
656 } else if (inst->vsi->head_offset == 0) {
657 ret = vdec_vframe_write(vdec, buf, size, ts);
658 } else {
659 char *write_buf = vmalloc(inst->vsi->head_offset + size);
660 if (!write_buf) {
661 ret = -ENOMEM;
662 goto err;
663 }
664
665 memcpy(write_buf, inst->vsi->header_buf, inst->vsi->head_offset);
666 memcpy(write_buf + inst->vsi->head_offset, buf, size);
667
668 ret = vdec_vframe_write(vdec, write_buf,
669 inst->vsi->head_offset + size, ts);
670
671 memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
672 inst->vsi->head_offset = 0;
673 inst->vsi->sps_size = 0;
674 inst->vsi->pps_size = 0;
675 inst->vsi->sei_size = 0;
676
677 vfree(write_buf);
678 }
679
680 return ret;
681err:
682 aml_vcodec_err(inst, "%s err(%d)", __func__, ret);
683 return ret;
684}
685
686static bool monitor_res_change(struct vdec_h264_inst *inst, u8 *buf, u32 size)
687{
688 int ret = 0, i = 0, j = 0;
689 u8 *p = buf;
690 int len = size;
691 u32 type;
692
693 for (i = 4; i < size; i++) {
694 j = find_start_code(p, len);
695 if (j > 0) {
696 len = size - (p - buf);
697 type = AVC_NAL_TYPE(p[j]);
698 if (type != NAL_H264_AUD &&
699 (type > NAL_H264_PPS || type < NAL_H264_SEI))
700 break;
701
702 if (type == NAL_H264_SPS) {
703 ret = stream_parse(inst, p, len);
704 if (!ret && (inst->vsi->cur_pic.coded_width !=
705 inst->vsi->pic.coded_width ||
706 inst->vsi->cur_pic.coded_height !=
707 inst->vsi->pic.coded_height)) {
708 inst->vsi->cur_pic = inst->vsi->pic;
709 return true;
710 }
711 }
712 p += j;
713 }
714 p++;
715 }
716
717 return false;
718}
719
720static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
721 u64 timestamp, bool *res_chg)
722{
723 struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
724 struct aml_vdec_adapt *vdec = &inst->vdec;
725 struct stream_info *st;
726 u8 *buf;
727 u32 size;
728 int ret = -1;
729
730 /* bs NULL means flush decoder */
731 if (bs == NULL)
732 return -1;
733
734 buf = (u8 *)bs->vaddr;
735 size = bs->size;
736 st = (struct stream_info *)buf;
737
738 if (inst->ctx->is_drm_mode && (st->magic == DRMe || st->magic == DRMn))
739 ret = vdec_vbuf_write(vdec, st->m.buf, sizeof(st->m.drm));
740 else if (st->magic == NORe)
741 ret = vdec_vbuf_write(vdec, st->data, st->length);
742 else if (st->magic == NORn)
743 ret = vdec_write_nalu(inst, st->data, st->length, timestamp);
744 else if (inst->ctx->is_stream_mode)
745 ret = vdec_vbuf_write(vdec, buf, size);
746 else {
747 /*checked whether the resolution changes.*/
748 if ((*res_chg = monitor_res_change(inst, buf, size)))
749 return 0;
750
751 ret = vdec_write_nalu(inst, buf, size, timestamp);
752 }
753
754 return ret;
755}
756
757static int vdec_h264_get_param(unsigned long h_vdec,
758 enum vdec_get_param_type type, void *out)
759{
760 int ret = 0;
761 struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
762
763 if (!inst) {
764 pr_err("the h264 inst of dec is invalid.\n");
765 return -1;
766 }
767
768 switch (type) {
769 case GET_PARAM_DISP_FRAME_BUFFER:
770 vdec_h264_get_vf(inst, out);
771 break;
772
773 case GET_PARAM_FREE_FRAME_BUFFER:
774 ret = vdec_h264_get_fb(inst, out);
775 break;
776
777 case GET_PARAM_PIC_INFO:
778 get_pic_info(inst, out);
779 break;
780
781 case GET_PARAM_DPB_SIZE:
782 get_dpb_size(inst, out);
783 break;
784
785 case GET_PARAM_CROP_INFO:
786 get_crop_info(inst, out);
787 break;
788
789 default:
790 aml_vcodec_err(inst, "invalid get parameter type=%d", type);
791 ret = -EINVAL;
792 }
793
794 return ret;
795}
796
797static void set_param_write_sync(struct vdec_h264_inst *inst)
798{
799 complete(&inst->comp);
800}
801
802static void set_param_pic_info(struct vdec_h264_inst *inst,
803 struct aml_vdec_pic_infos *info)
804{
805 struct vdec_pic_info *pic = &inst->vsi->pic;
806 struct vdec_h264_dec_info *dec = &inst->vsi->dec;
807 struct v4l2_rect *rect = &inst->vsi->crop;
808
809 /* fill visible area size that be used for EGL. */
810 pic->visible_width = info->visible_width;
811 pic->visible_height = info->visible_height;
812
813 /* calc visible ares. */
814 rect->left = 0;
815 rect->top = 0;
816 rect->width = pic->visible_width;
817 rect->height = pic->visible_height;
818
819 /* config canvas size that be used for decoder. */
820 pic->coded_width = info->coded_width;
821 pic->coded_height = info->coded_height;
822 pic->y_len_sz = pic->coded_width * pic->coded_height;
823 pic->c_len_sz = pic->y_len_sz >> 1;
824
825 dec->dpb_sz = info->dpb_size;
826
827 /*wake up*/
828 complete(&inst->comp);
829
830 pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
831 info->visible_width, info->visible_height,
832 info->coded_width, info->coded_height,
833 info->dpb_size);
834}
835
836static int vdec_h264_set_param(unsigned long h_vdec,
837 enum vdec_set_param_type type, void *in)
838{
839 int ret = 0;
840 struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
841
842 if (!inst) {
843 pr_err("the h264 inst of dec is invalid.\n");
844 return -1;
845 }
846
847 switch (type) {
848 case SET_PARAM_WRITE_FRAME_SYNC:
849 set_param_write_sync(inst);
850 break;
851
852 case SET_PARAM_PIC_INFO:
853 set_param_pic_info(inst, in);
854 break;
855
856 default:
857 aml_vcodec_err(inst, "invalid set parameter type=%d", type);
858 ret = -EINVAL;
859 }
860
861 return ret;
862}
863
864static struct vdec_common_if vdec_h264_if = {
865 .init = vdec_h264_init,
866 .probe = vdec_h264_probe,
867 .decode = vdec_h264_decode,
868 .get_param = vdec_h264_get_param,
869 .set_param = vdec_h264_set_param,
870 .deinit = vdec_h264_deinit,
871};
872
873struct vdec_common_if *get_h264_dec_comm_if(void);
874
875struct vdec_common_if *get_h264_dec_comm_if(void)
876{
877 return &vdec_h264_if;
878}
879