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