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