summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/aml_vcodec_adapt.c (plain)
blob: b596d4d555ba19074eda50a56a50d00b7a4cfa4e
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/parser/streambuf.h"
36#include "../stream_input/parser/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#define USE_V4L_PORTS (0x80)
56
57#define DATA_DEBUG
58
59static int def_4k_vstreambuf_sizeM =
60 (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
61static int def_vstreambuf_sizeM =
62 (DEFAULT_VIDEO_BUFFER_SIZE >> 20);
63
64static int slow_input = 0;
65
66static int use_bufferlevelx10000 = 10000;
67static unsigned int amstream_buf_num = BUF_MAX_NUM;
68
69static struct stream_buf_s bufs[BUF_MAX_NUM] = {
70 {
71 .reg_base = VLD_MEM_VIFIFO_REG_BASE,
72 .type = BUF_TYPE_VIDEO,
73 .buf_start = 0,
74 .buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
75 .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
76 .first_tstamp = INVALID_PTS
77 },
78 {
79 .reg_base = AIU_MEM_AIFIFO_REG_BASE,
80 .type = BUF_TYPE_AUDIO,
81 .buf_start = 0,
82 .buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
83 .default_buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
84 .first_tstamp = INVALID_PTS
85 },
86 {
87 .reg_base = 0,
88 .type = BUF_TYPE_SUBTITLE,
89 .buf_start = 0,
90 .buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
91 .default_buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
92 .first_tstamp = INVALID_PTS
93 },
94 {
95 .reg_base = 0,
96 .type = BUF_TYPE_USERDATA,
97 .buf_start = 0,
98 .buf_size = 0,
99 .first_tstamp = INVALID_PTS
100 },
101 {
102 .reg_base = HEVC_STREAM_REG_BASE,
103 .type = BUF_TYPE_HEVC,
104 .buf_start = 0,
105 .buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
106 .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
107 .first_tstamp = INVALID_PTS
108 },
109};
110
111extern int aml_set_vfm_path, aml_set_vdec_type;
112extern bool aml_set_vfm_enable, aml_set_vdec_type_enable;
113
114static void set_default_params(struct aml_vdec_adapt *vdec)
115{
116 unsigned long sync_mode = (PTS_OUTSIDE | SYNC_OUTSIDE | USE_V4L_PORTS);
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 = 1080;
121 vdec->dec_prop.rate = 3200;
122}
123
124static 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
150static 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
174static 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
197static void change_vbufsize(struct vdec_s *vdec,
198 struct stream_buf_s *pvbuf)
199{
200 if (pvbuf->buf_start != 0) {
201 pr_info("streambuf is alloced before\n");
202 return;
203 }
204
205 if (pvbuf->for_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
228static 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
238static 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, false);
250 case 1:
251 ;
252 }
253}
254
255static 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 pr_err("aformat not set\n");
262 return 0;
263 }
264
265 r = stbuf_init(pbuf, NULL, false);
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
288static void video_component_release(struct stream_port_s *port,
289struct 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 bool is_multidec = !vdec_single(vdec);
297
298 switch (release_num) {
299 default:
300 case 0:
301 case 4: {
302 if ((port->type & PORT_TYPE_FRAME) == 0)
303 esparser_release(pbuf);
304 }
305
306 case 3: {
307 if (vdec->slave)
308 slave = vdec->slave;
309 vdec_release(vdec);
310
311 if (slave)
312 vdec_release(slave);
313 vdec = NULL;
314 }
315
316 case 2: {
317 if ((port->type & PORT_TYPE_FRAME) == 0)
318 stbuf_release(pbuf, is_multidec);
319 }
320
321 case 1:
322 ;
323 }
324}
325
326static int video_component_init(struct stream_port_s *port,
327 struct stream_buf_s *pbuf)
328{
329 int ret = -1;
330 struct aml_vdec_adapt *ada_ctx
331 = container_of(port, struct aml_vdec_adapt, port);
332 struct vdec_s *vdec = ada_ctx->vdec;
333
334 if ((vdec->port_flag & PORT_FLAG_VFORMAT) == 0) {
335 pr_err("vformat not set\n");
336 return -EPERM;
337 }
338
339 if ((vdec->sys_info->height * vdec->sys_info->width) > 1920 * 1088
340 || port->vformat == VFORMAT_H264_4K2K) {
341 pbuf->for_4k = 1;
342 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
343 && port->vformat == VFORMAT_H264)
344 vdec_poweron(VDEC_HEVC);
345 } else
346 pbuf->for_4k = 0;
347
348 if (port->type & PORT_TYPE_FRAME) {
349 ret = vdec_init(vdec, pbuf->for_4k);
350 if (ret < 0) {
351 pr_err("video_component_init %d, failed\n", __LINE__);
352 video_component_release(port, pbuf, 2);
353 return ret;
354 }
355
356 return 0;
357 }
358
359 change_vbufsize(vdec, pbuf);
360
361 if (has_hevc_vdec()) {
362 if (port->type & PORT_TYPE_MPTS) {
363 if (pbuf->type == BUF_TYPE_HEVC)
364 vdec_poweroff(VDEC_1);
365 else
366 vdec_poweroff(VDEC_HEVC);
367 }
368 }
369
370 ret = stbuf_init(pbuf, vdec, false);
371 if (ret < 0) {
372 pr_err("video_component_init %d, stbuf_init failed\n", __LINE__);
373 return ret;
374 }
375
376 /* todo: set path based on port flag */
377 ret = vdec_init(vdec, pbuf->for_4k);
378 if (ret < 0) {
379 pr_err("video_component_init %d, vdec_init failed\n", __LINE__);
380 video_component_release(port, pbuf, 2);
381 return ret;
382 }
383
384 if (vdec_dual(vdec)) {
385 ret = vdec_init(vdec->slave, pbuf->for_4k);
386 if (ret < 0) {
387 pr_err("video_component_init %d, vdec_init failed\n",
388 __LINE__);
389 video_component_release(port, pbuf, 2);
390 return ret;
391 }
392 }
393
394 if (port->type & PORT_TYPE_ES) {
395 ret = esparser_init(pbuf, vdec);
396 if (ret < 0) {
397 video_component_release(port, pbuf, 3);
398 pr_err("esparser_init() failed\n");
399 return ret;
400 }
401 }
402
403 pbuf->flag |= BUF_FLAG_IN_USE;
404
405 vdec_connect(vdec);
406
407 return 0;
408}
409
410static int vdec_ports_release(struct stream_port_s *port)
411{
412 struct aml_vdec_adapt *ada_ctx
413 = container_of(port, struct aml_vdec_adapt, port);
414 struct vdec_s *vdec = ada_ctx->vdec;
415
416 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
417 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
418 //struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
419 struct vdec_s *slave = NULL;
420
421 if (has_hevc_vdec()) {
422 if (port->vformat == VFORMAT_HEVC
423 || port->vformat == VFORMAT_VP9)
424 pvbuf = &bufs[BUF_TYPE_HEVC];
425 }
426
427 if (port->type & PORT_TYPE_MPTS) {
428 tsync_pcr_stop();
429 tsdemux_release();
430 }
431
432 if (port->type & PORT_TYPE_MPPS)
433 psparser_release();
434
435 if (port->type & PORT_TYPE_VIDEO)
436 video_component_release(port, pvbuf, 0);
437
438 if (port->type & PORT_TYPE_AUDIO)
439 audio_component_release(port, pabuf, 0);
440
441 if (port->type & PORT_TYPE_SUB)
442 //sub_port_release(port, psbuf);
443
444 if (vdec) {
445 if (vdec->slave)
446 slave = vdec->slave;
447
448 vdec_release(vdec);
449
450 if (slave)
451 vdec_release(slave);
452 vdec = NULL;
453 }
454
455 port->pcr_inited = 0;
456 port->flag = 0;
457
458 return 0;
459}
460
461static void set_vdec_properity(struct vdec_s *vdec,
462 struct aml_vdec_adapt *ada_ctx)
463{
464 vdec->sys_info = &ada_ctx->dec_prop;
465 vdec->port = &ada_ctx->port;
466 vdec->format = ada_ctx->dec_prop.format;
467 vdec->sys_info_store = ada_ctx->dec_prop;
468 vdec->vf_receiver_name = ada_ctx->recv_name;
469
470 /* binding v4l2 ctx to vdec. */
471 vdec->private = ada_ctx->ctx;
472
473 /* set video format, sys info and vfm map.*/
474 vdec->port->vformat = vdec->format;
475 vdec->port->type |= PORT_TYPE_VIDEO;
476 vdec->port_flag |= PORT_FLAG_VFORMAT;
477 if (vdec->slave) {
478 vdec->slave->format = ada_ctx->dec_prop.format;
479 vdec->slave->port_flag |= PORT_FLAG_VFORMAT;
480 }
481
482 if (vdec->port->type & PORT_FLAG_DRM) {
483 vdec->type = VDEC_TYPE_STREAM_PARSER;
484 vdec->port->type |= PORT_TYPE_ES;
485 vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_VIDEO;
486 } else {
487 vdec->type = VDEC_TYPE_FRAME_BLOCK;
488 vdec->port->type |= PORT_TYPE_FRAME;
489 vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD;
490 }
491
492 if (aml_set_vdec_type_enable) {
493 if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) {
494 vdec->type = VDEC_TYPE_STREAM_PARSER;
495 vdec->port->type &= ~PORT_TYPE_FRAME;
496 vdec->port->type |= PORT_TYPE_ES;
497 ada_ctx->ctx->is_stream_mode = true;
498 } else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
499 vdec->type = VDEC_TYPE_FRAME_BLOCK;
500 vdec->port->type &= ~PORT_TYPE_ES;
501 vdec->port->type |= PORT_TYPE_FRAME;
502 ada_ctx->ctx->is_stream_mode = false;
503 }
504 }
505
506 if (aml_set_vfm_enable)
507 vdec->frame_base_video_path = aml_set_vfm_path;
508
509 vdec->port->flag = vdec->port_flag;
510 ada_ctx->vfm_path = vdec->frame_base_video_path;
511 ada_ctx->vdec = vdec;
512}
513
514static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx)
515{
516 int ret = -1;
517 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
518 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
519 //struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
520 struct vdec_s *vdec = NULL;
521
522 /* create the vdec instance.*/
523 vdec = vdec_create(&ada_ctx->port, NULL);
524 if (IS_ERR_OR_NULL(vdec))
525 return -1;
526
527 set_vdec_properity(vdec, ada_ctx);
528
529 /* init hw and gate*/
530 ret = enable_hardware(vdec->port);
531 if (ret < 0) {
532 pr_info("enable hw fail.\n");
533 goto error1;
534 }
535
536 stbuf_fetch_init();
537 user_buffer_init();
538
539 if ((vdec->port->type & PORT_TYPE_AUDIO)
540 && (vdec->port_flag & PORT_FLAG_AFORMAT)) {
541 ret = audio_component_init(vdec->port, pabuf);
542 if (ret < 0) {
543 pr_err("audio_component_init failed\n");
544 goto error1;
545 }
546 }
547
548 if ((vdec->port->type & PORT_TYPE_VIDEO)
549 && (vdec->port_flag & PORT_FLAG_VFORMAT)) {
550 pvbuf->for_4k = 0;
551 if (has_hevc_vdec()) {
552 if (vdec->port->vformat == VFORMAT_HEVC
553 || vdec->port->vformat == VFORMAT_VP9)
554 pvbuf = &bufs[BUF_TYPE_HEVC];
555 }
556
557 ret = video_component_init(vdec->port, pvbuf);
558 if (ret < 0) {
559 pr_err("video_component_init failed\n");
560 goto error2;
561 }
562
563 /* connect vdec at the end after all HW initialization */
564 vdec_connect(vdec);
565 }
566
567 return 0;
568
569//error3:
570 //video_component_release(port, pvbuf, 0);
571error2:
572 audio_component_release(vdec->port, pabuf, 0);
573error1:
574 return ret;
575}
576
577int video_decoder_init(struct aml_vdec_adapt *vdec)
578{
579 int ret = -1;
580
581 /* sets configure data */
582 set_default_params(vdec);
583
584 /* init the buffer work space and connect vdec.*/
585 ret = vdec_ports_init(vdec);
586 if (ret < 0) {
587 pr_info("vdec ports init fail.\n");
588 goto out;
589 }
590out:
591 return ret;
592}
593
594int video_decoder_release(struct aml_vdec_adapt *vdec)
595{
596 int ret = -1;
597 struct stream_port_s *port = &vdec->port;
598
599 ret = vdec_ports_release(port);
600 if (ret < 0) {
601 pr_info("vdec ports release fail.\n");
602 goto out;
603 }
604
605 /* disable gates */
606 ret = disable_hardware(port);
607 if (ret < 0) {
608 pr_info("disable hw fail.\n");
609 goto out;
610 }
611out:
612 return ret;
613}
614
615int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
616 const char *buf, unsigned int count)
617{
618 int ret = -1;
619 int try_cnt = 100;
620 struct stream_port_s *port = &ada_ctx->port;
621 struct vdec_s *vdec = ada_ctx->vdec;
622 struct stream_buf_s *pbuf = NULL;
623
624 if (has_hevc_vdec()) {
625 pbuf = (port->type & PORT_TYPE_HEVC) ? &bufs[BUF_TYPE_HEVC] :
626 &bufs[BUF_TYPE_VIDEO];
627 } else
628 pbuf = &bufs[BUF_TYPE_VIDEO];
629
630 /*if (!(port_get_inited(priv))) {
631 r = video_decoder_init(priv);
632 if (r < 0)
633 return r;
634 }*/
635
636 do {
637 if (vdec->port_flag & PORT_FLAG_DRM)
638 ret = drm_write(ada_ctx->filp, pbuf, buf, count);
639 else
640 ret = esparser_write(ada_ctx->filp, pbuf, buf, count);
641
642 if (ret == -EAGAIN)
643 msleep(30);
644 } while (ret == -EAGAIN && try_cnt--);
645
646 if (slow_input) {
647 pr_info("slow_input: es codec write size %x\n", ret);
648 msleep(10);
649 }
650
651#ifdef DATA_DEBUG
652 /* dump to file */
653 //dump_write(vbuf, size);
654 //pr_info("vbuf: %p, size: %u, ret: %d\n", vbuf, size, ret);
655#endif
656
657 return ret;
658}
659
660int is_need_to_buf(struct aml_vdec_adapt *ada_ctx)
661{
662 struct vdec_s *vdec = ada_ctx->vdec;
663
664 if (vdec->input.have_frame_num > 8)
665 return 0;
666 else
667 return 1;
668}
669
670int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
671 const char *buf, unsigned int count, unsigned long int timestamp)
672{
673 int ret = -1;
674 int try_cnt = 100;
675 struct vdec_s *vdec = ada_ctx->vdec;
676
677 /* set timestamp */
678 vdec_set_timestamp(vdec, timestamp);
679
680 do {
681 ret = vdec_write_vframe(vdec, buf, count);
682 if (ret == -EAGAIN) {
683 /*vdec_input_level(&vdec->input);*/
684 msleep(30);
685 }
686 } while (ret == -EAGAIN && try_cnt--);
687
688 if (slow_input) {
689 pr_info("slow_input: frame codec write size %d\n", ret);
690 msleep(30);
691 }
692
693#ifdef DATA_DEBUG
694 /* dump to file */
695 dump_write(buf, count);
696#endif
697 aml_v4l2_debug(2, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x",
698 ada_ctx->ctx->id, buf, count, ret, crc32_le(0, buf, count));
699
700 return ret;
701}
702
703void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx)
704{
705 struct vdec_s *vdec = ada_ctx->vdec;
706
707 if (vdec)
708 vdec_set_eos(vdec, true);
709}
710
711int aml_codec_reset(struct aml_vdec_adapt *ada_ctx)
712{
713 struct vdec_s *vdec = ada_ctx->vdec;
714 int ret = 0;
715
716 if (vdec) {
717 vdec_set_eos(vdec, false);
718 ret = vdec_reset(vdec);
719 }
720
721 return ret;
722}
723
724bool is_input_ready(struct aml_vdec_adapt *ada_ctx)
725{
726 struct vdec_s *vdec = ada_ctx->vdec;
727 int state = VDEC_STATUS_UNINITIALIZED;
728
729 if (vdec) {
730 state = vdec_get_status(vdec);
731
732 if (state == VDEC_STATUS_CONNECTED
733 || state == VDEC_STATUS_ACTIVE)
734 return true;
735 }
736
737 return false;
738}
739
740int vdec_frame_number(struct aml_vdec_adapt *ada_ctx)
741{
742 struct vdec_s *vdec = ada_ctx->vdec;
743
744 if (vdec)
745 return vdec_get_frame_num(vdec);
746 else
747 return -1;
748}
749