• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/amvdec_ports/decoder/vdec_hevc_if.c
3  *
4  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  */
17 
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/timer.h>
21 #include <linux/delay.h>
22 #include <linux/kernel.h>
23 #include <uapi/linux/swab.h>
24 #include "../vdec_drv_if.h"
25 #include "../aml_vcodec_util.h"
26 #include "../aml_vcodec_dec.h"
27 #include "../aml_vcodec_drv.h"
28 #include "../aml_vcodec_adapt.h"
29 #include "../vdec_drv_base.h"
30 #include "../aml_vcodec_vfm.h"
31 #include "aml_hevc_parser.h"
32 
33 #define HEVC_NAL_TYPE(value)				((value >> 1) & 0x3F)
34 #define HEADER_BUFFER_SIZE			(32 * 1024)
35 
36 /**
37  * struct hevc_fb - hevc decode frame buffer information
38  * @vdec_fb_va  : virtual address of struct vdec_fb
39  * @y_fb_dma    : dma address of Y frame buffer (luma)
40  * @c_fb_dma    : dma address of C frame buffer (chroma)
41  * @poc         : picture order count of frame buffer
42  * @reserved    : for 8 bytes alignment
43  */
44 struct hevc_fb {
45 	uint64_t vdec_fb_va;
46 	uint64_t y_fb_dma;
47 	uint64_t c_fb_dma;
48 	int32_t poc;
49 	uint32_t reserved;
50 };
51 
52 /**
53  * struct vdec_hevc_dec_info - decode information
54  * @dpb_sz		: decoding picture buffer size
55  * @resolution_changed  : resoltion change happen
56  * @reserved		: for 8 bytes alignment
57  * @bs_dma		: Input bit-stream buffer dma address
58  * @y_fb_dma		: Y frame buffer dma address
59  * @c_fb_dma		: C frame buffer dma address
60  * @vdec_fb_va		: VDEC frame buffer struct virtual address
61  */
62 struct vdec_hevc_dec_info {
63 	uint32_t dpb_sz;
64 	uint32_t resolution_changed;
65 	uint32_t reserved;
66 	uint64_t bs_dma;
67 	uint64_t y_fb_dma;
68 	uint64_t c_fb_dma;
69 	uint64_t vdec_fb_va;
70 };
71 
72 /**
73  * struct vdec_hevc_vsi - shared memory for decode information exchange
74  *                        between VPU and Host.
75  *                        The memory is allocated by VPU then mapping to Host
76  *                        in vpu_dec_init() and freed in vpu_dec_deinit()
77  *                        by VPU.
78  *                        AP-W/R : AP is writer/reader on this item
79  *                        VPU-W/R: VPU is write/reader on this item
80  * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
81  * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
82  * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
83  * @dec          : decode information (AP-R, VPU-W)
84  * @pic          : picture information (AP-R, VPU-W)
85  * @crop         : crop information (AP-R, VPU-W)
86  */
87 struct vdec_hevc_vsi {
88 	char *header_buf;
89 	int sps_size;
90 	int pps_size;
91 	int sei_size;
92 	int head_offset;
93 	struct vdec_hevc_dec_info dec;
94 	struct vdec_pic_info pic;
95 	struct vdec_pic_info cur_pic;
96 	struct v4l2_rect crop;
97 	bool is_combine;
98 	int nalu_pos;
99 	struct h265_param_sets ps;
100 };
101 
102 /**
103  * struct vdec_hevc_inst - hevc decoder instance
104  * @num_nalu : how many nalus be decoded
105  * @ctx      : point to aml_vcodec_ctx
106  * @vsi      : VPU shared information
107  */
108 struct vdec_hevc_inst {
109 	unsigned int num_nalu;
110 	struct aml_vcodec_ctx *ctx;
111 	struct aml_vdec_adapt vdec;
112 	struct vdec_hevc_vsi *vsi;
113 	struct vcodec_vfm_s vfm;
114 	struct aml_dec_params parms;
115 	struct completion comp;
116 };
117 
get_pic_info(struct vdec_hevc_inst * inst,struct vdec_pic_info * pic)118 static void get_pic_info(struct vdec_hevc_inst *inst,
119 			 struct vdec_pic_info *pic)
120 {
121 	*pic = inst->vsi->pic;
122 
123 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
124 		"pic(%d, %d), buf(%d, %d)\n",
125 		 pic->visible_width, pic->visible_height,
126 		 pic->coded_width, pic->coded_height);
127 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
128 		"Y(%d, %d), C(%d, %d)\n", pic->y_bs_sz,
129 		 pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
130 }
131 
get_crop_info(struct vdec_hevc_inst * inst,struct v4l2_rect * cr)132 static void get_crop_info(struct vdec_hevc_inst *inst, struct v4l2_rect *cr)
133 {
134 	cr->left = inst->vsi->crop.left;
135 	cr->top = inst->vsi->crop.top;
136 	cr->width = inst->vsi->crop.width;
137 	cr->height = inst->vsi->crop.height;
138 
139 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
140 		"l=%d, t=%d, w=%d, h=%d\n",
141 		 cr->left, cr->top, cr->width, cr->height);
142 }
143 
get_dpb_size(struct vdec_hevc_inst * inst,unsigned int * dpb_sz)144 static void get_dpb_size(struct vdec_hevc_inst *inst, unsigned int *dpb_sz)
145 {
146 	*dpb_sz = inst->vsi->dec.dpb_sz;
147 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
148 }
149 
vdec_config_default_parms(u8 * parm)150 static u32 vdec_config_default_parms(u8 *parm)
151 {
152 	u8 *pbuf = parm;
153 
154 	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
155 	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
156 	pbuf += sprintf(pbuf, "hevc_double_write_mode:16;");
157 	pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
158 	pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
159 	pbuf += sprintf(pbuf, "save_buffer_mode:0;");
160 	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
161 	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
162 
163 	return parm - pbuf;
164 }
165 
vdec_parser_parms(struct vdec_hevc_inst * inst)166 static void vdec_parser_parms(struct vdec_hevc_inst *inst)
167 {
168 	struct aml_vcodec_ctx *ctx = inst->ctx;
169 
170 	if (ctx->config.parm.dec.parms_status &
171 		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
172 		u8 *pbuf = ctx->config.buf;
173 
174 		pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
175 		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
176 			ctx->config.parm.dec.cfg.ref_buf_margin);
177 		pbuf += sprintf(pbuf, "hevc_double_write_mode:%d;",
178 			ctx->config.parm.dec.cfg.double_write_mode);
179 		pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
180 		pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
181 		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
182 		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
183 			ctx->config.parm.dec.cfg.canvas_mem_mode);
184 		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
185 			ctx->config.parm.dec.cfg.canvas_mem_endian);
186 		ctx->config.length = pbuf - ctx->config.buf;
187 	} else {
188 		ctx->config.parm.dec.cfg.double_write_mode = 16;
189 		ctx->config.parm.dec.cfg.ref_buf_margin = 7;
190 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
191 	}
192 
193 	inst->vdec.config	= ctx->config;
194 	inst->parms.cfg		= ctx->config.parm.dec.cfg;
195 	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
196 }
197 
vdec_hevc_init(struct aml_vcodec_ctx * ctx,unsigned long * h_vdec)198 static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
199 {
200 	struct vdec_hevc_inst *inst = NULL;
201 	int ret = -1;
202 
203 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
204 	if (!inst)
205 		return -ENOMEM;
206 
207 	inst->vdec.video_type	= VFORMAT_HEVC;
208 	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
209 	inst->vdec.filp		= ctx->dev->filp;
210 	inst->vdec.ctx		= ctx;
211 	inst->ctx		= ctx;
212 
213 	vdec_parser_parms(inst);
214 
215 	/* set play mode.*/
216 	if (ctx->is_drm_mode)
217 		inst->vdec.port.flag |= PORT_FLAG_DRM;
218 
219 	/* to eable hevc hw.*/
220 	inst->vdec.port.type = PORT_TYPE_HEVC;
221 
222 	/* init vfm */
223 	inst->vfm.ctx		= ctx;
224 	inst->vfm.ada_ctx	= &inst->vdec;
225 	ret = vcodec_vfm_init(&inst->vfm);
226 	if (ret) {
227 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
228 			"init vfm failed.\n");
229 		goto err;
230 	}
231 
232 	ret = video_decoder_init(&inst->vdec);
233 	if (ret) {
234 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
235 			"vdec_hevc init err=%d\n", ret);
236 		goto err;
237 	}
238 
239 	/* probe info from the stream */
240 	inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL);
241 	if (!inst->vsi) {
242 		ret = -ENOMEM;
243 		goto err;
244 	}
245 
246 	/* alloc the header buffer to be used cache sps or spp etc.*/
247 	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
248 	if (!inst->vsi->header_buf) {
249 		ret = -ENOMEM;
250 		goto err;
251 	}
252 
253 	init_completion(&inst->comp);
254 
255 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
256 		"hevc Instance >> %lx\n", (ulong) inst);
257 
258 	ctx->ada_ctx	= &inst->vdec;
259 	*h_vdec		= (unsigned long)inst;
260 
261 	//dump_init();
262 
263 	return 0;
264 err:
265 	if (inst)
266 		vcodec_vfm_release(&inst->vfm);
267 	if (inst && inst->vsi && inst->vsi->header_buf)
268 		kfree(inst->vsi->header_buf);
269 	if (inst && inst->vsi)
270 		kfree(inst->vsi);
271 	if (inst)
272 		kfree(inst);
273 	*h_vdec = 0;
274 
275 	return ret;
276 }
277 
278 
refer_buffer_num(struct h265_SPS_t * sps)279 static int refer_buffer_num(struct h265_SPS_t *sps)
280 {
281 	int used_buf_num = 0;
282 	int sps_pic_buf_diff = 0;
283 
284 	if ((!sps->temporal_layer[0].num_reorder_pics) &&
285 		(sps->temporal_layer[0].max_dec_pic_buffering)) {
286 		/* the range of sps_num_reorder_pics_0 is in
287 		[0, sps_max_dec_pic_buffering_minus1_0] */
288 		used_buf_num = sps->temporal_layer[0].max_dec_pic_buffering;
289 	} else
290 		used_buf_num = sps->temporal_layer[0].num_reorder_pics;
291 
292 	sps_pic_buf_diff = sps->temporal_layer[0].max_dec_pic_buffering -
293 		sps->temporal_layer[0].num_reorder_pics - 1;
294 
295 	if (sps_pic_buf_diff >= 4)
296 		used_buf_num += 1;
297 
298 	/*need one more for multi instance, as
299 	apply_ref_pic_set() has no chanch to run to
300 	to clear referenced flag in some case */
301 	used_buf_num++;
302 
303 	/* for eos add more buffer to flush.*/
304 	used_buf_num++;
305 
306 	return used_buf_num;
307 }
308 
vdec_get_dw_mode(struct vdec_hevc_inst * inst,int dw_mode)309 static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
310 {
311 	u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
312 	int w = inst->parms.cfg.init_width;
313 	int h = inst->parms.cfg.init_height;
314 	u32 dw = 0x1; /*1:1*/
315 
316 	switch (valid_dw_mode) {
317 	case 0x100:
318 		if (w > 1920 && h > 1088)
319 			dw = 0x4; /*1:2*/
320 		break;
321 	case 0x200:
322 		if (w > 1920 && h > 1088)
323 			dw = 0x2; /*1:4*/
324 		break;
325 	case 0x300:
326 		if (w > 1280 && h > 720)
327 			dw = 0x4; /*1:2*/
328 		break;
329 	default:
330 		dw = valid_dw_mode;
331 		break;
332 	}
333 
334 	return dw;
335 }
336 
vdec_pic_scale(struct vdec_hevc_inst * inst,int length,int dw_mode)337 static int vdec_pic_scale(struct vdec_hevc_inst *inst, int length, int dw_mode)
338 {
339 	int ret = 64;
340 
341 	switch (vdec_get_dw_mode(inst, dw_mode)) {
342 	case 0x0: /* only afbc, output afbc */
343 		ret = 64;
344 		break;
345 	case 0x1: /* afbc and (w x h), output YUV420 */
346 		ret = length;
347 		break;
348 	case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
349 	case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
350 		ret = length >> 2;
351 		break;
352 	case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
353 		ret = length >> 1;
354 		break;
355 	case 0x10: /* (w x h), output YUV420-8bit)*/
356 	default:
357 		ret = length;
358 		break;
359 	}
360 
361 	return ret;
362 }
363 
fill_vdec_params(struct vdec_hevc_inst * inst,struct h265_SPS_t * sps)364 static void fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps)
365 {
366 	struct vdec_pic_info *pic = &inst->vsi->pic;
367 	struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
368 	struct v4l2_rect *rect = &inst->vsi->crop;
369 	int dw = inst->parms.cfg.double_write_mode;
370 	int margin = inst->parms.cfg.ref_buf_margin;
371 
372 	/* fill visible area size that be used for EGL. */
373 	pic->visible_width = sps->width - (sps->output_window.left_offset +
374 		sps->output_window.right_offset);
375 	pic->visible_height = sps->height - (sps->output_window.top_offset +
376 		sps->output_window.bottom_offset);
377 	pic->visible_width = vdec_pic_scale(inst, pic->visible_width, dw);
378 	pic->visible_height = vdec_pic_scale(inst, pic->visible_height, dw);
379 
380 	/* calc visible ares. */
381 	rect->left		= 0;
382 	rect->top		= 0;
383 	rect->width		= pic->visible_width;
384 	rect->height		= pic->visible_height;
385 
386 	/* config canvas size that be used for decoder. */
387 	pic->coded_width	= vdec_pic_scale(inst, ALIGN(sps->width, 32), dw);
388 	pic->coded_height	= vdec_pic_scale(inst, ALIGN(sps->height, 32), dw);
389 
390 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
391 	pic->c_len_sz		= pic->y_len_sz >> 1;
392 
393 	/* calc DPB size */
394 	dec->dpb_sz		= refer_buffer_num(sps) + margin;
395 
396 	inst->parms.ps.visible_width	= pic->visible_width;
397 	inst->parms.ps.visible_height	= pic->visible_height;
398 	inst->parms.ps.coded_width	= pic->coded_width;
399 	inst->parms.ps.coded_height	= pic->coded_height;
400 	inst->parms.ps.dpb_size		= dec->dpb_sz;
401 	inst->parms.parms_status	|= V4L2_CONFIG_PARM_DECODE_PSINFO;
402 
403 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
404 		"The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
405 		dw, pic->coded_width, pic->coded_height,
406 		pic->visible_width, pic->visible_height,
407 		dec->dpb_sz - margin, margin);
408 }
409 
parse_stream_ucode(struct vdec_hevc_inst * inst,u8 * buf,u32 size)410 static int parse_stream_ucode(struct vdec_hevc_inst *inst, u8 *buf, u32 size)
411 {
412 	int ret = 0;
413 	struct aml_vdec_adapt *vdec = &inst->vdec;
414 
415 	ret = vdec_vframe_write(vdec, buf, size, 0);
416 	if (ret < 0) {
417 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
418 			"write frame data failed. err: %d\n", ret);
419 		return ret;
420 	}
421 
422 	/* wait ucode parse ending. */
423 	wait_for_completion_timeout(&inst->comp,
424 		msecs_to_jiffies(1000));
425 
426 	return inst->vsi->dec.dpb_sz ? 0 : -1;
427 }
428 
parse_stream_ucode_dma(struct vdec_hevc_inst * inst,ulong buf,u32 size,u32 handle)429 static int parse_stream_ucode_dma(struct vdec_hevc_inst *inst,
430 	ulong buf, u32 size, u32 handle)
431 {
432 	int ret = 0;
433 	struct aml_vdec_adapt *vdec = &inst->vdec;
434 
435 	ret = vdec_vframe_write_with_dma(vdec, buf, size, 0, handle);
436 	if (ret < 0) {
437 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
438 			"write frame data failed. err: %d\n", ret);
439 		return ret;
440 	}
441 
442 	/* wait ucode parse ending. */
443 	wait_for_completion_timeout(&inst->comp,
444 		msecs_to_jiffies(1000));
445 
446 	return inst->vsi->dec.dpb_sz ? 0 : -1;
447 }
448 
parse_stream_cpu(struct vdec_hevc_inst * inst,u8 * buf,u32 size)449 static int parse_stream_cpu(struct vdec_hevc_inst *inst, u8 *buf, u32 size)
450 {
451 	int ret = 0;
452 	struct h265_param_sets *ps = NULL;
453 
454 	ps = vzalloc(sizeof(struct h265_param_sets));
455 	if (ps == NULL)
456 		return -ENOMEM;
457 
458 	ret = h265_decode_extradata_ps(buf, size, ps);
459 	if (ret) {
460 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
461 			"parse extra data failed. err: %d\n", ret);
462 		goto out;
463 	}
464 
465 	if (ps->sps_parsed)
466 		fill_vdec_params(inst, &ps->sps);
467 
468 	ret = ps->sps_parsed ? 0 : -1;
469 out:
470 	vfree(ps);
471 
472 	return ret;
473 }
474 
vdec_hevc_probe(unsigned long h_vdec,struct aml_vcodec_mem * bs,void * out)475 static int vdec_hevc_probe(unsigned long h_vdec,
476 	struct aml_vcodec_mem *bs, void *out)
477 {
478 	struct vdec_hevc_inst *inst =
479 		(struct vdec_hevc_inst *)h_vdec;
480 	u8 *buf = (u8 *)bs->vaddr;
481 	u32 size = bs->size;
482 	int ret = 0;
483 
484 	if (inst->ctx->is_drm_mode) {
485 		if (bs->model == VB2_MEMORY_MMAP) {
486 			struct aml_video_stream *s =
487 				(struct aml_video_stream *) buf;
488 
489 			if ((s->magic != AML_VIDEO_MAGIC) &&
490 				(s->type != V4L_STREAM_TYPE_MATEDATA))
491 				return -1;
492 
493 			if (inst->ctx->param_sets_from_ucode) {
494 				ret = parse_stream_ucode(inst, s->data, s->len);
495 			} else {
496 				ret = parse_stream_cpu(inst, s->data, s->len);
497 			}
498 		} else if (bs->model == VB2_MEMORY_DMABUF ||
499 			bs->model == VB2_MEMORY_USERPTR) {
500 			ret = parse_stream_ucode_dma(inst, bs->addr, size,
501 				BUFF_IDX(bs, bs->index));
502 		}
503 	} else {
504 		if (inst->ctx->param_sets_from_ucode) {
505 			ret = parse_stream_ucode(inst, buf, size);
506 		} else {
507 			ret = parse_stream_cpu(inst, buf, size);
508 		}
509 	}
510 
511 	inst->vsi->cur_pic = inst->vsi->pic;
512 
513 	return ret;
514 }
515 
vdec_hevc_deinit(unsigned long h_vdec)516 static void vdec_hevc_deinit(unsigned long h_vdec)
517 {
518 	ulong flags;
519 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
520 	struct aml_vcodec_ctx *ctx = inst->ctx;
521 
522 	video_decoder_release(&inst->vdec);
523 
524 	vcodec_vfm_release(&inst->vfm);
525 
526 	//dump_deinit();
527 
528 	spin_lock_irqsave(&ctx->slock, flags);
529 	if (inst->vsi && inst->vsi->header_buf)
530 		kfree(inst->vsi->header_buf);
531 
532 	if (inst->vsi)
533 		kfree(inst->vsi);
534 
535 	kfree(inst);
536 
537 	ctx->drv_handle = 0;
538 	spin_unlock_irqrestore(&ctx->slock, flags);
539 }
540 
vdec_hevc_get_fb(struct vdec_hevc_inst * inst,struct vdec_v4l2_buffer ** out)541 static int vdec_hevc_get_fb(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
542 {
543 	return get_fb_from_queue(inst->ctx, out);
544 }
545 
vdec_hevc_get_vf(struct vdec_hevc_inst * inst,struct vdec_v4l2_buffer ** out)546 static void vdec_hevc_get_vf(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
547 {
548 	struct vframe_s *vf = NULL;
549 	struct vdec_v4l2_buffer *fb = NULL;
550 
551 	vf = peek_video_frame(&inst->vfm);
552 	if (!vf) {
553 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
554 			"there is no vframe.\n");
555 		*out = NULL;
556 		return;
557 	}
558 
559 	vf = get_video_frame(&inst->vfm);
560 	if (!vf) {
561 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
562 			"the vframe is avalid.\n");
563 		*out = NULL;
564 		return;
565 	}
566 
567 	atomic_set(&vf->use_cnt, 1);
568 
569 	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
570 	fb->vf_handle = (unsigned long)vf;
571 	fb->status = FB_ST_DISPLAY;
572 
573 	*out = fb;
574 
575 	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
576 	//dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
577 	//dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
578 
579 	/* convert yuv format. */
580 	//swap_uv(fb->base_c.vaddr, fb->base_c.size);
581 }
582 
vdec_write_nalu(struct vdec_hevc_inst * inst,u8 * buf,u32 size,u64 ts)583 static int vdec_write_nalu(struct vdec_hevc_inst *inst,
584 	u8 *buf, u32 size, u64 ts)
585 {
586 	int ret = 0;
587 	struct aml_vdec_adapt *vdec = &inst->vdec;
588 
589 	ret = vdec_vframe_write(vdec, buf, size, ts);
590 
591 	return ret;
592 }
593 
monitor_res_change(struct vdec_hevc_inst * inst,u8 * buf,u32 size)594 static bool monitor_res_change(struct vdec_hevc_inst *inst, u8 *buf, u32 size)
595 {
596 	int ret = 0, i = 0, j = 0;
597 	u8 *p = buf;
598 	int len = size;
599 	u32 type;
600 
601 	for (i = 4; i < size; i++) {
602 		j = find_start_code(p, len);
603 		if (j > 0) {
604 			len = size - (p - buf);
605 			type = HEVC_NAL_TYPE(p[j]);
606 			if (type != HEVC_NAL_AUD &&
607 				(type > HEVC_NAL_PPS || type < HEVC_NAL_VPS))
608 				break;
609 
610 			if (type == HEVC_NAL_SPS) {
611 				ret = parse_stream_cpu(inst, p, len);
612 				if (ret)
613 					break;
614 			}
615 			p += j;
616 		}
617 		p++;
618 	}
619 
620 	if (!ret && (inst->vsi->cur_pic.coded_width !=
621 		inst->vsi->pic.coded_width ||
622 		inst->vsi->cur_pic.coded_height !=
623 		inst->vsi->pic.coded_height)) {
624 		inst->vsi->cur_pic = inst->vsi->pic;
625 		return true;
626 	}
627 
628 	return false;
629 }
630 
vdec_hevc_decode(unsigned long h_vdec,struct aml_vcodec_mem * bs,u64 timestamp,bool * res_chg)631 static int vdec_hevc_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
632 			 u64 timestamp, bool *res_chg)
633 {
634 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
635 	struct aml_vdec_adapt *vdec = &inst->vdec;
636 	u8 *buf = (u8 *) bs->vaddr;
637 	u32 size = bs->size;
638 	int ret = -1;
639 
640 	if (bs == NULL)
641 		return -1;
642 
643 	if (vdec_input_full(vdec))
644 		return -EAGAIN;
645 
646 	if (inst->ctx->is_drm_mode) {
647 		if (bs->model == VB2_MEMORY_MMAP) {
648 			struct aml_video_stream *s =
649 				(struct aml_video_stream *) buf;
650 
651 			if (s->magic != AML_VIDEO_MAGIC)
652 				return -1;
653 
654 			if (!inst->ctx->param_sets_from_ucode &&
655 				(s->type == V4L_STREAM_TYPE_MATEDATA)) {
656 				if ((*res_chg = monitor_res_change(inst,
657 					s->data, s->len)))
658 					return 0;
659 			}
660 
661 			ret = vdec_vframe_write(vdec,
662 				s->data,
663 				s->len,
664 				timestamp);
665 		} else if (bs->model == VB2_MEMORY_DMABUF ||
666 			bs->model == VB2_MEMORY_USERPTR) {
667 			ret = vdec_vframe_write_with_dma(vdec,
668 				bs->addr, size, timestamp,
669 				BUFF_IDX(bs, bs->index));
670 		}
671 	} else {
672 		if (!inst->ctx->param_sets_from_ucode) {
673 			/*checked whether the resolution changes.*/
674 			if ((*res_chg = monitor_res_change(inst, buf, size)))
675 				return 0;
676 		}
677 		ret = vdec_write_nalu(inst, buf, size, timestamp);
678 	}
679 
680 	return ret;
681 }
682 
get_param_config_info(struct vdec_hevc_inst * inst,struct aml_dec_params * parms)683  static void get_param_config_info(struct vdec_hevc_inst *inst,
684 	struct aml_dec_params *parms)
685  {
686 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
687 		 parms->cfg = inst->parms.cfg;
688 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
689 		 parms->ps = inst->parms.ps;
690 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
691 		 parms->hdr = inst->parms.hdr;
692 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
693 		 parms->cnt = inst->parms.cnt;
694 
695 	 parms->parms_status |= inst->parms.parms_status;
696 
697 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
698 		"parms status: %u\n", parms->parms_status);
699  }
700 
vdec_hevc_get_param(unsigned long h_vdec,enum vdec_get_param_type type,void * out)701 static int vdec_hevc_get_param(unsigned long h_vdec,
702 			       enum vdec_get_param_type type, void *out)
703 {
704 	int ret = 0;
705 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
706 
707 	if (!inst) {
708 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
709 			"the hevc inst of dec is invalid.\n");
710 		return -1;
711 	}
712 
713 	switch (type) {
714 	case GET_PARAM_DISP_FRAME_BUFFER:
715 		vdec_hevc_get_vf(inst, out);
716 		break;
717 
718 	case GET_PARAM_FREE_FRAME_BUFFER:
719 		ret = vdec_hevc_get_fb(inst, out);
720 		break;
721 
722 	case GET_PARAM_PIC_INFO:
723 		get_pic_info(inst, out);
724 		break;
725 
726 	case GET_PARAM_DPB_SIZE:
727 		get_dpb_size(inst, out);
728 		break;
729 
730 	case GET_PARAM_CROP_INFO:
731 		get_crop_info(inst, out);
732 		break;
733 
734 	case GET_PARAM_CONFIG_INFO:
735 		get_param_config_info(inst, out);
736 		break;
737 	default:
738 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
739 			"invalid get parameter type=%d\n", type);
740 		ret = -EINVAL;
741 	}
742 
743 	return ret;
744 }
745 
set_param_write_sync(struct vdec_hevc_inst * inst)746 static void set_param_write_sync(struct vdec_hevc_inst *inst)
747 {
748 	complete(&inst->comp);
749 }
750 
set_param_ps_info(struct vdec_hevc_inst * inst,struct aml_vdec_ps_infos * ps)751 static void set_param_ps_info(struct vdec_hevc_inst *inst,
752 	struct aml_vdec_ps_infos *ps)
753 {
754 	struct vdec_pic_info *pic = &inst->vsi->pic;
755 	struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
756 	struct v4l2_rect *rect = &inst->vsi->crop;
757 
758 	/* fill visible area size that be used for EGL. */
759 	pic->visible_width	= ps->visible_width;
760 	pic->visible_height	= ps->visible_height;
761 
762 	/* calc visible ares. */
763 	rect->left		= 0;
764 	rect->top		= 0;
765 	rect->width		= pic->visible_width;
766 	rect->height		= pic->visible_height;
767 
768 	/* config canvas size that be used for decoder. */
769 
770 	pic->coded_width 	= ps->coded_width;
771 	pic->coded_height 	= ps->coded_height;
772 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
773 	pic->c_len_sz		= pic->y_len_sz >> 1;
774 
775 	dec->dpb_sz		= ps->dpb_size;
776 
777 	inst->parms.ps		= *ps;
778 	inst->parms.parms_status |=
779 		V4L2_CONFIG_PARM_DECODE_PSINFO;
780 
781 	/*wake up*/
782 	complete(&inst->comp);
783 
784 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
785 		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
786 		pic->visible_width, pic->visible_height,
787 		pic->coded_width, pic->coded_height,
788 		dec->dpb_sz);
789 }
790 
set_param_hdr_info(struct vdec_hevc_inst * inst,struct aml_vdec_hdr_infos * hdr)791 static void set_param_hdr_info(struct vdec_hevc_inst *inst,
792 	struct aml_vdec_hdr_infos *hdr)
793 {
794 	if (!(inst->parms.parms_status &
795 		V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
796 		inst->parms.hdr = *hdr;
797 		inst->parms.parms_status |=
798 			V4L2_CONFIG_PARM_DECODE_HDRINFO;
799 		aml_vdec_dispatch_event(inst->ctx,
800 			V4L2_EVENT_SRC_CH_HDRINFO);
801 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
802 			"H265 set HDR infos\n");
803 	}
804 }
805 
set_param_post_event(struct vdec_hevc_inst * inst,u32 * event)806 static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event)
807 {
808 	aml_vdec_dispatch_event(inst->ctx, *event);
809 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
810 		"H265 post event: %d\n", *event);
811 }
812 
vdec_hevc_set_param(unsigned long h_vdec,enum vdec_set_param_type type,void * in)813 static int vdec_hevc_set_param(unsigned long h_vdec,
814 	enum vdec_set_param_type type, void *in)
815 {
816 	int ret = 0;
817 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
818 
819 	if (!inst) {
820 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
821 			"the hevc inst of dec is invalid.\n");
822 		return -1;
823 	}
824 
825 	switch (type) {
826 	case SET_PARAM_WRITE_FRAME_SYNC:
827 		set_param_write_sync(inst);
828 		break;
829 
830 	case SET_PARAM_PS_INFO:
831 		set_param_ps_info(inst, in);
832 		break;
833 
834 	case SET_PARAM_HDR_INFO:
835 		set_param_hdr_info(inst, in);
836 		break;
837 
838 	case SET_PARAM_POST_EVENT:
839 		set_param_post_event(inst, in);
840 		break;
841 	default:
842 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
843 			"invalid set parameter type=%d\n", type);
844 		ret = -EINVAL;
845 	}
846 
847 	return ret;
848 }
849 
850 static struct vdec_common_if vdec_hevc_if = {
851 	.init		= vdec_hevc_init,
852 	.probe		= vdec_hevc_probe,
853 	.decode		= vdec_hevc_decode,
854 	.get_param	= vdec_hevc_get_param,
855 	.set_param	= vdec_hevc_set_param,
856 	.deinit		= vdec_hevc_deinit,
857 };
858 
859 struct vdec_common_if *get_hevc_dec_comm_if(void);
860 
get_hevc_dec_comm_if(void)861 struct vdec_common_if *get_hevc_dec_comm_if(void)
862 {
863 	return &vdec_hevc_if;
864 }
865