• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/types.h>
21 #include <linux/amlogic/media/utils/amstream.h>
22 #include <linux/amlogic/media/utils/vformat.h>
23 #include <linux/amlogic/media/utils/aformat.h>
24 #include <linux/amlogic/media/frame_sync/tsync.h>
25 #include <linux/amlogic/media/frame_sync/ptsserv.h>
26 #include <linux/amlogic/media/frame_sync/timestamp.h>
27 #include <linux/amlogic/media/utils/amports_config.h>
28 #include <linux/amlogic/media/frame_sync/tsync_pcr.h>
29 #include <linux/amlogic/media/codec_mm/codec_mm.h>
30 #include <linux/amlogic/media/codec_mm/configs.h>
31 #include <linux/amlogic/media/utils/vformat.h>
32 #include <linux/amlogic/media/utils/aformat.h>
33 #include <linux/amlogic/media/registers/register.h>
34 #include "../stream_input/amports/adec.h"
35 #include "../stream_input/amports/streambuf.h"
36 #include "../stream_input/amports/streambuf_reg.h"
37 #include "../stream_input/parser/tsdemux.h"
38 #include "../stream_input/parser/psparser.h"
39 #include "../stream_input/parser/esparser.h"
40 #include "../frame_provider/decoder/utils/vdec.h"
41 #include "../common/media_clock/switch/amports_gate.h"
42 #include <linux/delay.h>
43 #include "aml_vcodec_adapt.h"
44 #include <linux/crc32.h>
45 
46 #define DEFAULT_VIDEO_BUFFER_SIZE		(1024 * 1024 * 3)
47 #define DEFAULT_VIDEO_BUFFER_SIZE_4K		(1024 * 1024 * 6)
48 #define DEFAULT_VIDEO_BUFFER_SIZE_TVP		(1024 * 1024 * 10)
49 #define DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP	(1024 * 1024 * 15)
50 #define DEFAULT_AUDIO_BUFFER_SIZE		(1024*768*2)
51 #define DEFAULT_SUBTITLE_BUFFER_SIZE		(1024*256)
52 
53 #define PTS_OUTSIDE	(1)
54 #define SYNC_OUTSIDE	(2)
55 
56 //#define DATA_DEBUG
57 
58 static int def_4k_vstreambuf_sizeM =
59 	(DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
60 static int def_vstreambuf_sizeM =
61 	(DEFAULT_VIDEO_BUFFER_SIZE >> 20);
62 
63 static int slow_input = 0;
64 
65 static int use_bufferlevelx10000 = 10000;
66 static unsigned int amstream_buf_num = BUF_MAX_NUM;
67 
68 static struct stream_buf_s bufs[BUF_MAX_NUM] = {
69 	{
70 		.reg_base = VLD_MEM_VIFIFO_REG_BASE,
71 		.type = BUF_TYPE_VIDEO,
72 		.buf_start = 0,
73 		.buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
74 		.default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
75 		.first_tstamp = INVALID_PTS
76 	},
77 	{
78 		.reg_base = AIU_MEM_AIFIFO_REG_BASE,
79 		.type = BUF_TYPE_AUDIO,
80 		.buf_start = 0,
81 		.buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
82 		.default_buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
83 		.first_tstamp = INVALID_PTS
84 	},
85 	{
86 		.reg_base = 0,
87 		.type = BUF_TYPE_SUBTITLE,
88 		.buf_start = 0,
89 		.buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
90 		.default_buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
91 		.first_tstamp = INVALID_PTS
92 	},
93 	{
94 		.reg_base = 0,
95 		.type = BUF_TYPE_USERDATA,
96 		.buf_start = 0,
97 		.buf_size = 0,
98 		.first_tstamp = INVALID_PTS
99 	},
100 	{
101 		.reg_base = HEVC_STREAM_REG_BASE,
102 		.type = BUF_TYPE_HEVC,
103 		.buf_start = 0,
104 		.buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
105 		.default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
106 		.first_tstamp = INVALID_PTS
107 	},
108 };
109 
110 extern int aml_set_vfm_path, aml_set_vdec_type;
111 extern bool aml_set_vfm_enable, aml_set_vdec_type_enable;
112 
set_default_params(struct aml_vdec_adapt * vdec)113 static void set_default_params(struct aml_vdec_adapt *vdec)
114 {
115 	ulong sync_mode = (PTS_OUTSIDE | SYNC_OUTSIDE);
116 
117 	vdec->dec_prop.param = (void *)sync_mode;
118 	vdec->dec_prop.format = vdec->format;
119 	vdec->dec_prop.width = 1920;
120 	vdec->dec_prop.height = 1088;
121 	vdec->dec_prop.rate = 3200;
122 }
123 
enable_hardware(struct stream_port_s * port)124 static int enable_hardware(struct stream_port_s *port)
125 {
126 	if (get_cpu_type() < MESON_CPU_MAJOR_ID_M6)
127 		return -1;
128 
129 	amports_switch_gate("demux", 1);
130 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8)
131 		amports_switch_gate("parser_top", 1);
132 
133 	if (port->type & PORT_TYPE_VIDEO) {
134 		amports_switch_gate("vdec", 1);
135 
136 		if (has_hevc_vdec()) {
137 			if (port->type & PORT_TYPE_HEVC)
138 				vdec_poweron(VDEC_HEVC);
139 			else
140 				vdec_poweron(VDEC_1);
141 		} else {
142 			if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8)
143 				vdec_poweron(VDEC_1);
144 		}
145 	}
146 
147 	return 0;
148 }
149 
disable_hardware(struct stream_port_s * port)150 static int disable_hardware(struct stream_port_s *port)
151 {
152 	if (get_cpu_type() < MESON_CPU_MAJOR_ID_M6)
153 		return -1;
154 
155 	if (port->type & PORT_TYPE_VIDEO) {
156 		if (has_hevc_vdec()) {
157 			if (port->type & PORT_TYPE_HEVC)
158 				vdec_poweroff(VDEC_HEVC);
159 			else
160 				vdec_poweroff(VDEC_1);
161 		}
162 
163 		amports_switch_gate("vdec", 0);
164 	}
165 
166 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8)
167 		amports_switch_gate("parser_top", 0);
168 
169 	amports_switch_gate("demux", 0);
170 
171 	return 0;
172 }
173 
reset_canuse_buferlevel(int levelx10000)174 static int reset_canuse_buferlevel(int levelx10000)
175 {
176 	int i;
177 	struct stream_buf_s *p = NULL;
178 
179 	if (levelx10000 >= 0 && levelx10000 <= 10000)
180 		use_bufferlevelx10000 = levelx10000;
181 	else
182 		use_bufferlevelx10000 = 10000;
183 	for (i = 0; i < amstream_buf_num; i++) {
184 		p = &bufs[i];
185 		p->canusebuf_size = ((p->buf_size / 1024) *
186 			use_bufferlevelx10000 / 10000) * 1024;
187 		p->canusebuf_size += 1023;
188 		p->canusebuf_size &= ~1023;
189 
190 		if (p->canusebuf_size > p->buf_size)
191 			p->canusebuf_size = p->buf_size;
192 	}
193 
194 	return 0;
195 }
196 
change_vbufsize(struct vdec_s * vdec,struct stream_buf_s * pvbuf)197 static void change_vbufsize(struct vdec_s *vdec,
198 	struct stream_buf_s *pvbuf)
199 {
200 	if (pvbuf->buf_start != 0) {
201 		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "streambuf is alloced before\n");
202 		return;
203 	}
204 
205 	if (vdec->port->is_4k) {
206 		pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M;
207 
208 		if (vdec->port_flag & PORT_FLAG_DRM)
209 			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP;
210 
211 		if ((pvbuf->buf_size > 30 * SZ_1M)
212 			&& (codec_mm_get_total_size() < 220 * SZ_1M)) {
213 			/*if less than 250M, used 20M for 4K & 265*/
214 			pvbuf->buf_size = pvbuf->buf_size >> 1;
215 		}
216 	} else if (pvbuf->buf_size > def_vstreambuf_sizeM * SZ_1M) {
217 		if (vdec->port_flag & PORT_FLAG_DRM)
218 			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
219 	} else {
220 		pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M;
221 		if (vdec->port_flag & PORT_FLAG_DRM)
222 			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
223 	}
224 
225 	reset_canuse_buferlevel(10000);
226 }
227 
user_buffer_init(void)228 static void user_buffer_init(void)
229 {
230 	struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA];
231 
232 	pubuf->buf_size = 0;
233 	pubuf->buf_start = 0;
234 	pubuf->buf_wp = 0;
235 	pubuf->buf_rp = 0;
236 }
237 
audio_component_release(struct stream_port_s * port,struct stream_buf_s * pbuf,int release_num)238 static void audio_component_release(struct stream_port_s *port,
239 	struct stream_buf_s *pbuf, int release_num)
240 {
241 	switch (release_num) {
242 		default:
243 		case 0:
244 		case 4:
245 			esparser_release(pbuf);
246 		case 3:
247 			adec_release(port->vformat);
248 		case 2:
249 			stbuf_release(pbuf);
250 		case 1:
251 			;
252 	}
253 }
254 
audio_component_init(struct stream_port_s * port,struct stream_buf_s * pbuf)255 static int audio_component_init(struct stream_port_s *port,
256 	struct stream_buf_s *pbuf)
257 {
258 	int r;
259 
260 	if ((port->flag & PORT_FLAG_AFORMAT) == 0) {
261 		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "aformat not set\n");
262 		return 0;
263 	}
264 
265 	r = stbuf_init(pbuf, NULL);
266 	if (r < 0)
267 		return r;
268 
269 	r = adec_init(port);
270 	if (r < 0) {
271 		audio_component_release(port, pbuf, 2);
272 		return r;
273 	}
274 
275 	if (port->type & PORT_TYPE_ES) {
276 		r = esparser_init(pbuf, NULL);
277 		if (r < 0) {
278 			audio_component_release(port, pbuf, 3);
279 			return r;
280 		}
281 	}
282 
283 	pbuf->flag |= BUF_FLAG_IN_USE;
284 
285 	return 0;
286 }
287 
video_component_release(struct stream_port_s * port,struct stream_buf_s * pbuf,int release_num)288 static void video_component_release(struct stream_port_s *port,
289 struct stream_buf_s *pbuf, int release_num)
290 {
291 	struct aml_vdec_adapt *ada_ctx
292 		= container_of(port, struct aml_vdec_adapt, port);
293 	struct vdec_s *vdec = ada_ctx->vdec;
294 
295 	struct vdec_s *slave = NULL;
296 
297 	switch (release_num) {
298 	default:
299 	case 0:
300 	case 4: {
301 		if ((port->type & PORT_TYPE_FRAME) == 0)
302 		esparser_release(pbuf);
303 	}
304 
305 	case 3: {
306 		if (vdec->slave)
307 			slave = vdec->slave;
308 		vdec_release(vdec);
309 
310 		if (slave)
311 			vdec_release(slave);
312 		vdec = NULL;
313 	}
314 
315 	case 2: {
316 		if ((port->type & PORT_TYPE_FRAME) == 0)
317 		stbuf_release(pbuf);
318 	}
319 
320 	case 1:
321 		;
322 	}
323 }
324 
video_component_init(struct stream_port_s * port,struct stream_buf_s * pbuf)325 static int video_component_init(struct stream_port_s *port,
326 			  struct stream_buf_s *pbuf)
327 {
328 	int ret = -1;
329 	struct aml_vdec_adapt *ada_ctx
330 		= container_of(port, struct aml_vdec_adapt, port);
331 	struct vdec_s *vdec = ada_ctx->vdec;
332 
333 	if ((vdec->port_flag & PORT_FLAG_VFORMAT) == 0) {
334 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vformat not set\n");
335 		return -EPERM;
336 	}
337 
338 	if ((vdec->sys_info->height * vdec->sys_info->width) > 1920 * 1088
339 		|| port->vformat == VFORMAT_H264_4K2K) {
340 		port->is_4k = true;
341 		if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
342 				&& port->vformat == VFORMAT_H264)
343 			vdec_poweron(VDEC_HEVC);
344 	} else
345 		port->is_4k = false;
346 
347 	if (port->type & PORT_TYPE_FRAME) {
348 		ret = vdec_init(vdec, port->is_4k);
349 		if (ret < 0) {
350 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n");
351 			video_component_release(port, pbuf, 2);
352 			return ret;
353 		}
354 
355 		return 0;
356 	}
357 
358 	change_vbufsize(vdec, pbuf);
359 
360 	if (has_hevc_vdec()) {
361 		if (port->type & PORT_TYPE_MPTS) {
362 			if (pbuf->type == BUF_TYPE_HEVC)
363 				vdec_poweroff(VDEC_1);
364 			else
365 				vdec_poweroff(VDEC_HEVC);
366 		}
367 	}
368 
369 	ret = stbuf_init(pbuf, vdec);
370 	if (ret < 0) {
371 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n");
372 		return ret;
373 	}
374 
375 	/* todo: set path based on port flag */
376 	ret = vdec_init(vdec, port->is_4k);
377 	if (ret < 0) {
378 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
379 		video_component_release(port, pbuf, 2);
380 		return ret;
381 	}
382 
383 	if (vdec_dual(vdec)) {
384 		ret = vdec_init(vdec->slave, port->is_4k);
385 		if (ret < 0) {
386 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
387 			video_component_release(port, pbuf, 2);
388 			return ret;
389 		}
390 	}
391 
392 	if (port->type & PORT_TYPE_ES) {
393 		ret = esparser_init(pbuf, vdec);
394 		if (ret < 0) {
395 			video_component_release(port, pbuf, 3);
396 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n");
397 			return ret;
398 		}
399 	}
400 
401 	pbuf->flag |= BUF_FLAG_IN_USE;
402 
403 	vdec_connect(vdec);
404 
405 	return 0;
406 }
407 
vdec_ports_release(struct stream_port_s * port)408 static int vdec_ports_release(struct stream_port_s *port)
409 {
410 	struct aml_vdec_adapt *ada_ctx
411 		= container_of(port, struct aml_vdec_adapt, port);
412 	struct vdec_s *vdec = ada_ctx->vdec;
413 
414 	struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
415 	struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
416 	//struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
417 	struct vdec_s *slave = NULL;
418 
419 	if (has_hevc_vdec()) {
420 		if (port->vformat == VFORMAT_HEVC
421 			|| port->vformat == VFORMAT_VP9)
422 			pvbuf = &bufs[BUF_TYPE_HEVC];
423 	}
424 
425 	if (port->type & PORT_TYPE_MPTS) {
426 		tsync_pcr_stop();
427 		tsdemux_release();
428 	}
429 
430 	if (port->type & PORT_TYPE_MPPS)
431 		psparser_release();
432 
433 	if (port->type & PORT_TYPE_VIDEO)
434 		video_component_release(port, pvbuf, 0);
435 
436 	if (port->type & PORT_TYPE_AUDIO)
437 		audio_component_release(port, pabuf, 0);
438 
439 	if (port->type & PORT_TYPE_SUB)
440 		//sub_port_release(port, psbuf);
441 
442 	if (vdec) {
443 		if (vdec->slave)
444 			slave = vdec->slave;
445 
446 		vdec_release(vdec);
447 
448 		if (slave)
449 			vdec_release(slave);
450 		vdec = NULL;
451 	}
452 
453 	port->pcr_inited = 0;
454 	port->flag = 0;
455 
456 	return 0;
457 }
458 
set_vdec_properity(struct vdec_s * vdec,struct aml_vdec_adapt * ada_ctx)459 static void set_vdec_properity(struct vdec_s *vdec,
460 	struct aml_vdec_adapt *ada_ctx)
461 {
462 	vdec->sys_info	= &ada_ctx->dec_prop;
463 	vdec->port	= &ada_ctx->port;
464 	vdec->format	= ada_ctx->video_type;
465 	vdec->sys_info_store = ada_ctx->dec_prop;
466 	vdec->vf_receiver_name = ada_ctx->recv_name;
467 
468 	/* binding v4l2 ctx to vdec. */
469 	vdec->private = ada_ctx->ctx;
470 
471 	/* set video format, sys info and vfm map.*/
472 	vdec->port->vformat = vdec->format;
473 	vdec->port->type |= PORT_TYPE_VIDEO;
474 	vdec->port_flag |= (vdec->port->flag | PORT_FLAG_VFORMAT);
475 	if (vdec->slave) {
476 		vdec->slave->format = ada_ctx->dec_prop.format;
477 		vdec->slave->port_flag |= PORT_FLAG_VFORMAT;
478 	}
479 
480 	vdec->type = VDEC_TYPE_FRAME_BLOCK;
481 	vdec->port->type |= PORT_TYPE_FRAME;
482 	vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD;
483 
484 	if (aml_set_vdec_type_enable) {
485 		if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) {
486 			vdec->type = VDEC_TYPE_STREAM_PARSER;
487 			vdec->port->type &= ~PORT_TYPE_FRAME;
488 			vdec->port->type |= PORT_TYPE_ES;
489 		} else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
490 			vdec->type = VDEC_TYPE_FRAME_BLOCK;
491 			vdec->port->type &= ~PORT_TYPE_ES;
492 			vdec->port->type |= PORT_TYPE_FRAME;
493 		}
494 	}
495 
496 	if (aml_set_vfm_enable)
497 		vdec->frame_base_video_path = aml_set_vfm_path;
498 
499 	vdec->port->flag = vdec->port_flag;
500 	ada_ctx->vfm_path = vdec->frame_base_video_path;
501 
502 	vdec->config_len = ada_ctx->config.length >
503 		PAGE_SIZE ? PAGE_SIZE : ada_ctx->config.length;
504 	memcpy(vdec->config, ada_ctx->config.buf, vdec->config_len);
505 
506 	ada_ctx->vdec = vdec;
507 }
508 
vdec_ports_init(struct aml_vdec_adapt * ada_ctx)509 static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx)
510 {
511 	int ret = -1;
512 	struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
513 	struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
514 	//struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
515 	struct vdec_s *vdec = NULL;
516 
517 	/* create the vdec instance.*/
518 	vdec = vdec_create(&ada_ctx->port, NULL);
519 	if (IS_ERR_OR_NULL(vdec))
520 		return -1;
521 
522 	set_vdec_properity(vdec, ada_ctx);
523 
524 	/* init hw and gate*/
525 	ret = enable_hardware(vdec->port);
526 	if (ret < 0) {
527 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "enable hw fail.\n");
528 		goto error1;
529 	}
530 
531 	stbuf_fetch_init();
532 	user_buffer_init();
533 
534 	if ((vdec->port->type & PORT_TYPE_AUDIO)
535 		&& (vdec->port_flag & PORT_FLAG_AFORMAT)) {
536 		ret = audio_component_init(vdec->port, pabuf);
537 		if (ret < 0) {
538 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "audio_component_init  failed\n");
539 			goto error1;
540 		}
541 	}
542 
543 	if ((vdec->port->type & PORT_TYPE_VIDEO)
544 		&& (vdec->port_flag & PORT_FLAG_VFORMAT)) {
545 		vdec->port->is_4k = false;
546 		if (has_hevc_vdec()) {
547 			if (vdec->port->vformat == VFORMAT_HEVC
548 				|| vdec->port->vformat == VFORMAT_VP9)
549 				pvbuf = &bufs[BUF_TYPE_HEVC];
550 		}
551 
552 		ret = video_component_init(vdec->port, pvbuf);
553 		if (ret < 0) {
554 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "video_component_init  failed\n");
555 			goto error2;
556 		}
557 
558 		/* connect vdec at the end after all HW initialization */
559 		vdec_connect(vdec);
560 	}
561 
562 	return 0;
563 
564 //error3:
565 	//video_component_release(port, pvbuf, 0);
566 error2:
567 	audio_component_release(vdec->port, pabuf, 0);
568 error1:
569 	return ret;
570 }
571 
video_decoder_init(struct aml_vdec_adapt * vdec)572 int video_decoder_init(struct aml_vdec_adapt *vdec)
573 {
574 	int ret = -1;
575 
576 	/* sets configure data */
577 	set_default_params(vdec);
578 
579 	/* init the buffer work space and connect vdec.*/
580 	ret = vdec_ports_init(vdec);
581 	if (ret < 0) {
582 		v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports init fail.\n");
583 		goto out;
584 	}
585 out:
586 	return ret;
587 }
588 
video_decoder_release(struct aml_vdec_adapt * vdec)589 int video_decoder_release(struct aml_vdec_adapt *vdec)
590 {
591 	int ret = -1;
592 	struct stream_port_s *port = &vdec->port;
593 
594 	ret = vdec_ports_release(port);
595 	if (ret < 0) {
596 		v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports release fail.\n");
597 		goto out;
598 	}
599 
600 	/* disable gates */
601 	ret = disable_hardware(port);
602 	if (ret < 0) {
603 		v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "disable hw fail.\n");
604 		goto out;
605 	}
606 out:
607 	return ret;
608 }
609 
vdec_vbuf_write(struct aml_vdec_adapt * ada_ctx,const char * buf,unsigned int count)610 int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
611 	const char *buf, unsigned int count)
612 {
613 	int ret = -1;
614 	int try_cnt = 100;
615 	struct stream_port_s *port = &ada_ctx->port;
616 	struct vdec_s *vdec = ada_ctx->vdec;
617 	struct stream_buf_s *pbuf = NULL;
618 
619 	if (has_hevc_vdec()) {
620 		pbuf = (port->type & PORT_TYPE_HEVC) ? &bufs[BUF_TYPE_HEVC] :
621 			&bufs[BUF_TYPE_VIDEO];
622 	} else
623 		pbuf = &bufs[BUF_TYPE_VIDEO];
624 
625 	/*if (!(port_get_inited(priv))) {
626 		r = video_decoder_init(priv);
627 		if (r < 0)
628 			return r;
629 	}*/
630 
631 	do {
632 		if (vdec->port_flag & PORT_FLAG_DRM)
633 			ret = drm_write(ada_ctx->filp, pbuf, buf, count);
634 		else
635 			ret = esparser_write(ada_ctx->filp, pbuf, buf, count);
636 
637 		if (ret == -EAGAIN)
638 			msleep(30);
639 	} while (ret == -EAGAIN && try_cnt--);
640 
641 	if (slow_input) {
642 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
643 			"slow_input: es codec write size %x\n", ret);
644 		msleep(10);
645 	}
646 
647 #ifdef DATA_DEBUG
648 	/* dump to file */
649 	//dump_write(vbuf, size);
650 	//v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, "vbuf: %p, size: %u, ret: %d\n", vbuf, size, ret);
651 #endif
652 
653 	return ret;
654 }
655 
vdec_input_full(struct aml_vdec_adapt * ada_ctx)656 bool vdec_input_full(struct aml_vdec_adapt *ada_ctx)
657 {
658 	struct vdec_s *vdec = ada_ctx->vdec;
659 
660 	return (vdec->input.have_frame_num > 600) ? true : false;
661 }
662 
vdec_vframe_write(struct aml_vdec_adapt * ada_ctx,const char * buf,unsigned int count,u64 timestamp)663 int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
664 	const char *buf, unsigned int count, u64 timestamp)
665 {
666 	int ret = -1;
667 	struct vdec_s *vdec = ada_ctx->vdec;
668 
669 	/* set timestamp */
670 	vdec_set_timestamp(vdec, timestamp);
671 
672 	ret = vdec_write_vframe(vdec, buf, count);
673 
674 	if (slow_input) {
675 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
676 			"slow_input: frame codec write size %d\n", ret);
677 		msleep(30);
678 	}
679 
680 #ifdef DATA_DEBUG
681 	/* dump to file */
682 	dump_write(buf, count);
683 #endif
684 	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
685 		"write frames, vbuf: %p, size: %u, ret: %d, crc: %x\n",
686 		buf, count, ret, crc32_le(0, buf, count));
687 
688 	return ret;
689 }
690 
vdec_vframe_write_with_dma(struct aml_vdec_adapt * ada_ctx,ulong addr,u32 count,u64 timestamp,u32 handle)691 int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx,
692 	ulong addr, u32 count, u64 timestamp, u32 handle)
693 {
694 	int ret = -1;
695 	struct vdec_s *vdec = ada_ctx->vdec;
696 
697 	/* set timestamp */
698 	vdec_set_timestamp(vdec, timestamp);
699 
700 	ret = vdec_write_vframe_with_dma(vdec, addr, count, handle);
701 
702 	if (slow_input) {
703 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
704 			"slow_input: frame codec write size %d\n", ret);
705 		msleep(30);
706 	}
707 
708 	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
709 		"write frames, vbuf: %lx, size: %u, ret: %d\n",
710 		addr, count, ret);
711 
712 	return ret;
713 }
714 
aml_decoder_flush(struct aml_vdec_adapt * ada_ctx)715 void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx)
716 {
717 	struct vdec_s *vdec = ada_ctx->vdec;
718 
719 	if (vdec)
720 		vdec_set_eos(vdec, true);
721 }
722 
aml_codec_reset(struct aml_vdec_adapt * ada_ctx,int * mode)723 int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *mode)
724 {
725 	struct vdec_s *vdec = ada_ctx->vdec;
726 	int ret = 0;
727 
728 	if (vdec) {
729 		if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed)
730 			vdec_set_eos(vdec, false);
731 		if (*mode == V4L_RESET_MODE_NORMAL &&
732 			vdec->input.have_frame_num == 0) {
733 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
734 			"no input reset mode: %d\n", *mode);
735 			*mode = V4L_RESET_MODE_LIGHT;
736 		}
737 		if (ada_ctx->ctx->param_sets_from_ucode &&
738 			*mode == V4L_RESET_MODE_NORMAL &&
739 			ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) {
740 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
741 			"resolution_changed reset mode: %d\n", *mode);
742 			*mode = V4L_RESET_MODE_LIGHT;
743 		}
744 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
745 			"reset mode: %d\n", *mode);
746 
747 		ret = vdec_v4l2_reset(vdec, *mode);
748 		*mode = V4L_RESET_MODE_NORMAL;
749 	}
750 
751 	return ret;
752 }
753 
is_input_ready(struct aml_vdec_adapt * ada_ctx)754 bool is_input_ready(struct aml_vdec_adapt *ada_ctx)
755 {
756 	struct vdec_s *vdec = ada_ctx->vdec;
757 	int state = VDEC_STATUS_UNINITIALIZED;
758 
759 	if (vdec) {
760 		state = vdec_get_status(vdec);
761 
762 		if (state == VDEC_STATUS_CONNECTED
763 			|| state == VDEC_STATUS_ACTIVE)
764 			return true;
765 	}
766 
767 	return false;
768 }
769 
vdec_frame_number(struct aml_vdec_adapt * ada_ctx)770 int vdec_frame_number(struct aml_vdec_adapt *ada_ctx)
771 {
772 	struct vdec_s *vdec = ada_ctx->vdec;
773 
774 	if (vdec)
775 		return vdec_get_frame_num(vdec);
776 	else
777 		return -1;
778 }
779 
v4l2_config_vdec_parm(struct aml_vdec_adapt * ada_ctx,u8 * data,u32 len)780 void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
781 {
782 	struct vdec_s *vdec = ada_ctx->vdec;
783 
784 	vdec->config_len = len > PAGE_SIZE ? PAGE_SIZE : len;
785 	memcpy(vdec->config, data, vdec->config_len);
786 }
787 
aml_recycle_buffer(struct aml_vdec_adapt * adaptor)788 u32 aml_recycle_buffer(struct aml_vdec_adapt *adaptor)
789 {
790 	return vdec_input_get_freed_handle(adaptor->vdec);
791 }
792 
793