summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/aml_vcodec_adapt.c (plain)
blob: b87d0c882c19f0dc39ceef9af7ccbc7c949e79a8
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
56//#define DATA_DEBUG
57
58static int def_4k_vstreambuf_sizeM =
59 (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
60static int def_vstreambuf_sizeM =
61 (DEFAULT_VIDEO_BUFFER_SIZE >> 20);
62
63static int slow_input = 0;
64
65static int use_bufferlevelx10000 = 10000;
66static unsigned int amstream_buf_num = BUF_MAX_NUM;
67
68static 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
110extern int aml_set_vfm_path, aml_set_vdec_type;
111extern bool aml_set_vfm_enable, aml_set_vdec_type_enable;
112
113static 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
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 v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "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 v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "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 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "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 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n");
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 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n");
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 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
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 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
388 video_component_release(port, pbuf, 2);
389 return ret;
390 }
391 }
392
393 if (port->type & PORT_TYPE_ES) {
394 ret = esparser_init(pbuf, vdec);
395 if (ret < 0) {
396 video_component_release(port, pbuf, 3);
397 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n");
398 return ret;
399 }
400 }
401
402 pbuf->flag |= BUF_FLAG_IN_USE;
403
404 vdec_connect(vdec);
405
406 return 0;
407}
408
409static int vdec_ports_release(struct stream_port_s *port)
410{
411 struct aml_vdec_adapt *ada_ctx
412 = container_of(port, struct aml_vdec_adapt, port);
413 struct vdec_s *vdec = ada_ctx->vdec;
414
415 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
416 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
417 //struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
418 struct vdec_s *slave = NULL;
419
420 if (has_hevc_vdec()) {
421 if (port->vformat == VFORMAT_HEVC
422 || port->vformat == VFORMAT_VP9)
423 pvbuf = &bufs[BUF_TYPE_HEVC];
424 }
425
426 if (port->type & PORT_TYPE_MPTS) {
427 tsync_pcr_stop();
428 tsdemux_release();
429 }
430
431 if (port->type & PORT_TYPE_MPPS)
432 psparser_release();
433
434 if (port->type & PORT_TYPE_VIDEO)
435 video_component_release(port, pvbuf, 0);
436
437 if (port->type & PORT_TYPE_AUDIO)
438 audio_component_release(port, pabuf, 0);
439
440 if (port->type & PORT_TYPE_SUB)
441 //sub_port_release(port, psbuf);
442
443 if (vdec) {
444 if (vdec->slave)
445 slave = vdec->slave;
446
447 vdec_release(vdec);
448
449 if (slave)
450 vdec_release(slave);
451 vdec = NULL;
452 }
453
454 port->pcr_inited = 0;
455 port->flag = 0;
456
457 return 0;
458}
459
460static void set_vdec_properity(struct vdec_s *vdec,
461 struct aml_vdec_adapt *ada_ctx)
462{
463 vdec->sys_info = &ada_ctx->dec_prop;
464 vdec->port = &ada_ctx->port;
465 vdec->format = ada_ctx->video_type;
466 vdec->sys_info_store = ada_ctx->dec_prop;
467 vdec->vf_receiver_name = ada_ctx->recv_name;
468
469 /* binding v4l2 ctx to vdec. */
470 vdec->private = ada_ctx->ctx;
471
472 /* set video format, sys info and vfm map.*/
473 vdec->port->vformat = vdec->format;
474 vdec->port->type |= PORT_TYPE_VIDEO;
475 vdec->port_flag |= (vdec->port->flag | PORT_FLAG_VFORMAT);
476 if (vdec->slave) {
477 vdec->slave->format = ada_ctx->dec_prop.format;
478 vdec->slave->port_flag |= PORT_FLAG_VFORMAT;
479 }
480
481 vdec->type = VDEC_TYPE_FRAME_BLOCK;
482 vdec->port->type |= PORT_TYPE_FRAME;
483 vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD;
484
485 if (aml_set_vdec_type_enable) {
486 if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) {
487 vdec->type = VDEC_TYPE_STREAM_PARSER;
488 vdec->port->type &= ~PORT_TYPE_FRAME;
489 vdec->port->type |= PORT_TYPE_ES;
490 } else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
491 vdec->type = VDEC_TYPE_FRAME_BLOCK;
492 vdec->port->type &= ~PORT_TYPE_ES;
493 vdec->port->type |= PORT_TYPE_FRAME;
494 }
495 }
496
497 if (aml_set_vfm_enable)
498 vdec->frame_base_video_path = aml_set_vfm_path;
499
500 vdec->port->flag = vdec->port_flag;
501 ada_ctx->vfm_path = vdec->frame_base_video_path;
502
503 vdec->config_len = ada_ctx->config.length >
504 PAGE_SIZE ? PAGE_SIZE : ada_ctx->config.length;
505 memcpy(vdec->config, ada_ctx->config.buf, vdec->config_len);
506
507 ada_ctx->vdec = vdec;
508}
509
510static int vdec_ports_init(struct aml_vdec_adapt *ada_ctx)
511{
512 int ret = -1;
513 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
514 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
515 //struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
516 struct vdec_s *vdec = NULL;
517
518 /* create the vdec instance.*/
519 vdec = vdec_create(&ada_ctx->port, NULL);
520 if (IS_ERR_OR_NULL(vdec))
521 return -1;
522
523 set_vdec_properity(vdec, ada_ctx);
524
525 /* init hw and gate*/
526 ret = enable_hardware(vdec->port);
527 if (ret < 0) {
528 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "enable hw fail.\n");
529 goto error1;
530 }
531
532 stbuf_fetch_init();
533 user_buffer_init();
534
535 if ((vdec->port->type & PORT_TYPE_AUDIO)
536 && (vdec->port_flag & PORT_FLAG_AFORMAT)) {
537 ret = audio_component_init(vdec->port, pabuf);
538 if (ret < 0) {
539 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "audio_component_init failed\n");
540 goto error1;
541 }
542 }
543
544 if ((vdec->port->type & PORT_TYPE_VIDEO)
545 && (vdec->port_flag & PORT_FLAG_VFORMAT)) {
546 pvbuf->for_4k = 0;
547 if (has_hevc_vdec()) {
548 if (vdec->port->vformat == VFORMAT_HEVC
549 || vdec->port->vformat == VFORMAT_VP9)
550 pvbuf = &bufs[BUF_TYPE_HEVC];
551 }
552
553 ret = video_component_init(vdec->port, pvbuf);
554 if (ret < 0) {
555 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "video_component_init failed\n");
556 goto error2;
557 }
558
559 /* connect vdec at the end after all HW initialization */
560 vdec_connect(vdec);
561 }
562
563 return 0;
564
565//error3:
566 //video_component_release(port, pvbuf, 0);
567error2:
568 audio_component_release(vdec->port, pabuf, 0);
569error1:
570 return ret;
571}
572
573int video_decoder_init(struct aml_vdec_adapt *vdec)
574{
575 int ret = -1;
576
577 /* sets configure data */
578 set_default_params(vdec);
579
580 /* init the buffer work space and connect vdec.*/
581 ret = vdec_ports_init(vdec);
582 if (ret < 0) {
583 v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports init fail.\n");
584 goto out;
585 }
586out:
587 return ret;
588}
589
590int video_decoder_release(struct aml_vdec_adapt *vdec)
591{
592 int ret = -1;
593 struct stream_port_s *port = &vdec->port;
594
595 ret = vdec_ports_release(port);
596 if (ret < 0) {
597 v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "vdec ports release fail.\n");
598 goto out;
599 }
600
601 /* disable gates */
602 ret = disable_hardware(port);
603 if (ret < 0) {
604 v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "disable hw fail.\n");
605 goto out;
606 }
607out:
608 return ret;
609}
610
611int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
612 const char *buf, unsigned int count)
613{
614 int ret = -1;
615 int try_cnt = 100;
616 struct stream_port_s *port = &ada_ctx->port;
617 struct vdec_s *vdec = ada_ctx->vdec;
618 struct stream_buf_s *pbuf = NULL;
619
620 if (has_hevc_vdec()) {
621 pbuf = (port->type & PORT_TYPE_HEVC) ? &bufs[BUF_TYPE_HEVC] :
622 &bufs[BUF_TYPE_VIDEO];
623 } else
624 pbuf = &bufs[BUF_TYPE_VIDEO];
625
626 /*if (!(port_get_inited(priv))) {
627 r = video_decoder_init(priv);
628 if (r < 0)
629 return r;
630 }*/
631
632 do {
633 if (vdec->port_flag & PORT_FLAG_DRM)
634 ret = drm_write(ada_ctx->filp, pbuf, buf, count);
635 else
636 ret = esparser_write(ada_ctx->filp, pbuf, buf, count);
637
638 if (ret == -EAGAIN)
639 msleep(30);
640 } while (ret == -EAGAIN && try_cnt--);
641
642 if (slow_input) {
643 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
644 "slow_input: es codec write size %x\n", ret);
645 msleep(10);
646 }
647
648#ifdef DATA_DEBUG
649 /* dump to file */
650 //dump_write(vbuf, size);
651 //v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, "vbuf: %p, size: %u, ret: %d\n", vbuf, size, ret);
652#endif
653
654 return ret;
655}
656
657bool vdec_input_full(struct aml_vdec_adapt *ada_ctx)
658{
659 struct vdec_s *vdec = ada_ctx->vdec;
660
661 return (vdec->input.have_frame_num > 600) ? true : false;
662}
663
664int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
665 const char *buf, unsigned int count, u64 timestamp)
666{
667 int ret = -1;
668 struct vdec_s *vdec = ada_ctx->vdec;
669
670 /* set timestamp */
671 vdec_set_timestamp(vdec, timestamp);
672
673 ret = vdec_write_vframe(vdec, buf, count);
674
675 if (slow_input) {
676 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
677 "slow_input: frame codec write size %d\n", ret);
678 msleep(30);
679 }
680
681#ifdef DATA_DEBUG
682 /* dump to file */
683 dump_write(buf, count);
684#endif
685 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
686 "write frames, vbuf: %p, size: %u, ret: %d, crc: %x\n",
687 buf, count, ret, crc32_le(0, buf, count));
688
689 return ret;
690}
691
692int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx,
693 ulong addr, u32 count, u64 timestamp, u32 handle)
694{
695 int ret = -1;
696 struct vdec_s *vdec = ada_ctx->vdec;
697
698 /* set timestamp */
699 vdec_set_timestamp(vdec, timestamp);
700
701 ret = vdec_write_vframe_with_dma(vdec, addr, count, handle);
702
703 if (slow_input) {
704 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
705 "slow_input: frame codec write size %d\n", ret);
706 msleep(30);
707 }
708
709 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
710 "write frames, vbuf: %lx, size: %u, ret: %d\n",
711 addr, count, ret);
712
713 return ret;
714}
715
716void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx)
717{
718 struct vdec_s *vdec = ada_ctx->vdec;
719
720 if (vdec)
721 vdec_set_eos(vdec, true);
722}
723
724int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *mode)
725{
726 struct vdec_s *vdec = ada_ctx->vdec;
727 int ret = 0;
728
729 if (vdec) {
730 if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed)
731 vdec_set_eos(vdec, false);
732 if (*mode == V4L_RESET_MODE_NORMAL &&
733 vdec->input.have_frame_num == 0) {
734 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
735 "no input reset mode: %d\n", *mode);
736 *mode = V4L_RESET_MODE_LIGHT;
737 }
738 if (ada_ctx->ctx->param_sets_from_ucode &&
739 *mode == V4L_RESET_MODE_NORMAL &&
740 ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) {
741 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
742 "resolution_changed reset mode: %d\n", *mode);
743 *mode = V4L_RESET_MODE_LIGHT;
744 }
745 v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
746 "reset mode: %d\n", *mode);
747
748 ret = vdec_v4l2_reset(vdec, *mode);
749 *mode = V4L_RESET_MODE_NORMAL;
750 }
751
752 return ret;
753}
754
755bool is_input_ready(struct aml_vdec_adapt *ada_ctx)
756{
757 struct vdec_s *vdec = ada_ctx->vdec;
758 int state = VDEC_STATUS_UNINITIALIZED;
759
760 if (vdec) {
761 state = vdec_get_status(vdec);
762
763 if (state == VDEC_STATUS_CONNECTED
764 || state == VDEC_STATUS_ACTIVE)
765 return true;
766 }
767
768 return false;
769}
770
771int vdec_frame_number(struct aml_vdec_adapt *ada_ctx)
772{
773 struct vdec_s *vdec = ada_ctx->vdec;
774
775 if (vdec)
776 return vdec_get_frame_num(vdec);
777 else
778 return -1;
779}
780
781void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
782{
783 struct vdec_s *vdec = ada_ctx->vdec;
784
785 vdec->config_len = len > PAGE_SIZE ? PAGE_SIZE : len;
786 memcpy(vdec->config, data, vdec->config_len);
787}
788
789u32 aml_recycle_buffer(struct aml_vdec_adapt *adaptor)
790{
791 return vdec_input_get_freed_handle(adaptor->vdec);
792}
793
794