Project import generated by Copybara.
GitOrigin-RevId: c52e92328723791fd1b14149053ef1a25223a45e
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..39eb163
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,68 @@
+load("//build/kernel/kleaf:kernel.bzl", "kernel_module")
+
+kernel_module(
+ name = "media",
+ srcs = glob(
+ ["**"],
+ exclude = [
+ "BUILD.bazel",
+ "**/*.bzl",
+ "**/*.mk",
+ "**/*.bp",
+ ],
+ ),
+ outs = [
+ "amvdec_ports/amvdec_ports.ko",
+ "common/firmware/firmware.ko",
+ "common/media_clock/media_clock.ko",
+ "frame_provider/decoder/avs2/amvdec_avs2.ko",
+ "frame_provider/decoder/avs2_fb/amvdec_avs2_fb.ko",
+ "frame_provider/decoder/avs3/amvdec_avs3.ko",
+ "frame_provider/decoder/avs_multi/amvdec_mavs.ko",
+ "frame_provider/decoder/h264_multi/amvdec_mh264.ko",
+ "frame_provider/decoder/h264_mvc/amvdec_h264mvc.ko",
+ "frame_provider/decoder/h265/amvdec_h265.ko",
+ "frame_provider/decoder/h265_fb/amvdec_h265_fb.ko",
+ "frame_provider/decoder/mjpeg/amvdec_mmjpeg.ko",
+ "frame_provider/decoder/mpeg12/amvdec_mmpeg12.ko",
+ "frame_provider/decoder/mpeg4/amvdec_mmpeg4.ko",
+ "frame_provider/decoder/utils/amvdec_debug_port.ko",
+ "frame_provider/decoder/utils/decoder_common.ko",
+ "frame_provider/decoder_v4l/avs2/amvdec_avs2_v4l.ko",
+ "frame_provider/decoder_v4l/avs2_fb/amvdec_avs2_fb_v4l.ko",
+ "frame_provider/decoder_v4l/avs3/amvdec_avs3_v4l.ko",
+ "frame_provider/decoder_v4l/avs_multi/amvdec_mavs_v4l.ko",
+ "frame_provider/decoder_v4l/h264_multi/amvdec_mh264_v4l.ko",
+ "frame_provider/decoder_v4l/h265/amvdec_h265_v4l.ko",
+ "frame_provider/decoder_v4l/h265_fb/amvdec_h265_fb_v4l.ko",
+ "frame_provider/decoder_v4l/mjpeg/amvdec_mmjpeg_v4l.ko",
+ "frame_provider/decoder_v4l/mpeg12/amvdec_mmpeg12_v4l.ko",
+ "frame_provider/decoder_v4l/mpeg4/amvdec_mmpeg4_v4l.ko",
+ "frame_provider/decoder_v4l/vav1/amvdec_av1_v4l.ko",
+ "frame_provider/decoder_v4l/vav1_fb/amvdec_av1_fb_v4l.ko",
+ "frame_provider/decoder_v4l/vav1_t5d/amvdec_av1_t5d_v4l.ko",
+ "frame_provider/decoder_v4l/vp9/amvdec_vp9_v4l.ko",
+ "frame_provider/decoder_v4l/vp9_fb/amvdec_vp9_fb_v4l.ko",
+ "frame_provider/decoder/vav1/amvdec_av1.ko",
+ "frame_provider/decoder/vav1_fb/amvdec_av1_fb.ko",
+ "frame_provider/decoder/vc1/amvdec_vc1.ko",
+ "frame_provider/decoder_v4l/vc1/amvdec_vc1_v4l.ko",
+ "frame_provider/decoder/vp9/amvdec_vp9.ko",
+ "frame_provider/decoder/vp9_fb/amvdec_vp9_fb.ko",
+ "framerate_adapter/video_framerate_adapter.ko",
+ "frame_sink/encoder/h264/amlogic-encoder.ko",
+ "frame_sink/encoder/h265/amlogic-vpu.ko",
+ "frame_sink/encoder/jpeg/amlogic-jpegenc.ko",
+ "frame_sink/encoder/memalloc/amlogic-memalloc.ko",
+ "frame_sink/encoder/multi/amlogic-multienc.ko",
+ "frame_sink/encoder/vcenc/amlogic-vc8000.ko",
+ "media_sync/av_sync/media_sync.ko",
+ "media_sync/pts_server/pts_server.ko",
+ "stream_input/parser/hw_demux/aml_hardware_dmx.ko",
+ "stream_input/stream_input.ko",
+ ],
+ kernel_build = "//common:amlogic",
+ visibility = [
+ "//common:__pkg__",
+ ],
+)
diff --git a/Makefile b/Makefile
old mode 100755
new mode 100644
index 7481eee..56e42d3
--- a/Makefile
+++ b/Makefile
@@ -21,10 +21,19 @@
CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS3=m \
CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
CONFIG_AMLOGIC_MEDIA_GE2D=y \
CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
- CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+ CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_VP9_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H265_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1_T5D=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_MEMALLOC=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_VCENC=m \
+ CONFIG_AMLOGIC_HW_DEMUX=m
EXTRA_INCLUDE := -I$(KERNEL_SRC)/$(M)/drivers/include
@@ -35,6 +44,23 @@
KBUILD_CFLAGS_MODULE += $(GKI_EXT_MODULE_PREDEFINE)
+ifeq ($(strip $(CONFIG_AMLOGIC_ZAPPER_CUT)),)
+ CONFIGS += CONFIG_AMLOGIC_MEDIA_V4L_DEC=y
+endif
+
+ifeq (${VERSION},5)
+ifeq (${PATCHLEVEL},15)
+ CONFIGS += CONFIG_AMLOGIC_MEDIA_MULTI_DEC=y
+endif
+endif
+
+ifeq ($(O),)
+out_dir := .
+else
+out_dir := $(O)
+endif
+include $(out_dir)/include/config/auto.conf
+
modules:
$(MAKE) -C $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE) $(KBUILD_CFLAGS_MODULE) ${VERSION_CONTROL_CFLAGS}" $(CONFIGS)
@@ -42,10 +68,17 @@
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 M=$(M)/drivers -C $(KERNEL_SRC) modules_install
- mkdir -p ${OUT_DIR}/../vendor_lib/modules
- cd ${OUT_DIR}/$(M)/; find -name "*.ko" -exec cp {} ${OUT_DIR}/../vendor_lib/modules/ \;
- mkdir -p ${OUT_DIR}/../vendor_lib/firmware/video
- cp $(KERNEL_SRC)/$(M)/firmware/* ${OUT_DIR}/../vendor_lib/firmware/video/
+ $(Q)mkdir -p ${out_dir}/../vendor_lib/modules
+ $(Q)mkdir -p ${out_dir}/../vendor_lib/firmware/video
+ $(Q)cp $(KERNEL_SRC)/$(M)/firmware/* ${out_dir}/../vendor_lib/firmware/video/ -rf
+ $(Q)if [ -z "$(CONFIG_AMLOGIC_KERNEL_VERSION)" ]; then \
+ cd ${out_dir}/$(M)/; find -name "*.ko" -exec cp {} ${out_dir}/../vendor_lib/modules/ \; ; \
+ else \
+ find $(INSTALL_MOD_PATH)/lib/modules/*/$(INSTALL_MOD_DIR) -name "*.ko" -exec cp {} ${out_dir}/../vendor_lib/modules \; ; \
+ fi;
+ if [ -e ${out_dir}/$(M)/drivers/Module.symvers ]; then \
+ ln -sf ${out_dir}/$(M)/drivers/Module.symvers ${out_dir}/$(M)/Module.symvers;\
+ fi;
clean:
- $(MAKE) -C $(KERNEL_SRC) M=$(M) clean
+ $(MAKE) -C $(KERNEL_SRC) M=$(M) clean
diff --git a/Media.mk b/Media.mk
index 58db63b..5f9c57f 100644
--- a/Media.mk
+++ b/Media.mk
@@ -21,10 +21,17 @@
CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS3=m \
CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
CONFIG_AMLOGIC_MEDIA_GE2D=y \
CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
- CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+ CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_VP9_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H265_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1_FB=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1_T5D=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB=m
define copy-media-modules
$(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\
diff --git a/VERSION b/VERSION
index 4b1504d..5ab40d7 100644
--- a/VERSION
+++ b/VERSION
@@ -1,58 +1,57 @@
-Major_V=5
-Minor_V=3
-BaseChangeId=Ifc17e92ef9c9e211b8f01ebae1e97c5855fea084
+#Developing Version
+Major_V=6
+Minor_V=8
+DevelopingChangeId=Ia7339b3a1afe89afc9eecae3e7a55c39799768ff
#history version
-#V5.2.104-g795aee00.003025 Release Notes
-#Release_ChangeId_V5_2=I34801cba60d54bfd9f459f7445d0362989c23496
-#V5.1.77-g0cdebf27.003009 Release Notes
-#Release_ChangeId_V5_1=Id7e315bbf379d166ca4b335cef13c983a8ca5078
-#Feature develop total count: 6
-# critical feature develop count: 0
-# important feature develop count: 4
-# normal feature develop count: 2
-#Feature develop detail information:
-# improve pip channel play
-# support decoder fence
-# fixed can't get hdr information correctly.
-# add multi-vdec info for new format av1 after revert
-# change ptsadjust and threshold from s64 to s32.
-# support dw 0x100
-#Fixed BUG total count: 30
-# fixed critical BUG count: 3
-# fixed important feature develop count: 15
-# fixed normal feature develop count: 12
-#Fixed BUG detail information:
-# add VIDTYPE_COMPRESS in vf for dw mode with afbc buffer
-# fix some the crash caused by null pointer
-# fixed vpp wrapper memory leak.
-# metadata lose the last byte every frame in frame mode
-# fix avs color abnormal.
-# fix gst secure v4l2 decoder not work
-# fix the playback stuck when resolution changed
-# h265 ucode send 2 interrupts cause playback stuck
-# fix av1 freeze when burn-in test.
-# fixed playback stuck after seek.
-# fix 8k display abnormal.
-# fixed irq-vdec-0 takes more cpu slice.
-# fixed AV1 seek freezing.
-# fixed failed to allocate tvp memory
-# fixed issue of reports resolution change.
+#V6.7 Release Notes
+#Release_ChangeId_V6_7=Iabfa01c63da558d842d3252c7612559fa830ec7d
+#New feature detail information:
+#H265 dual-core mosaic mode development
+#H264\H265 save one output buffer optimization
+#Add T5D AV1 fg support
+#Encoder bringup of C1
+#Optimization H264 software decoding time
+#V4ldec supports p010 decoding output
+#Optimized for redundant decoding memory usage
+#Decoder bringup of txhd2
+#V6.6 Release Notes
+#Release_ChangeId_V6_6=I7906e7fb1fc9cd2ae2f5e3b35a85146077f647ed
+#V6.5 Release Notes
+#Release_ChangeId_V6_5=I1fb4d74a26b20c810af5fabe70d11b30038f52cd
+#V6.4 Release Notes
+#Release_ChangeId_V6_4=I3e3ba6e50ff95c9bdee77ecf9b6a14054c7db016
+#V6.3 Release Notes
+#Release_ChangeId_V6_3=Id88c63edf8568ce8f5c52203db4020db6ad12d54
+#V6.2 Release Notes
+#Release_ChangeId_V6_2=I38197e6c418dee6183605006ca63b85337be2b19
+#V6.1 Release Notes
+#Release_ChangeId_V6_1=I3343779b4ad29ab1be55a002fbc43ecdbc440993
+#Support T7C, T3
+#Support new DOS Reg management
+#V6.0 Release Notes
+#Release_ChangeId_V6_0=Ie5dd8015a9663f3be43a0867348b70812bdfb25e
+#Support DMABUF heap Feature
+#Support Decoder new Buffer management for V4Ldec
+#Support Kernel 5.15
+#Support non-V4ldec feature of the all V5 version and so on
+#Kernel 5.15 Support Chip SC2
+#Support Codec2 for Android T, all CTS test clean
#V5.0 Release Notes
#Release_ChangeId_V5_0=I6053e02900215d9006469c38ca375ace498b849f
#upgrade Kernel version to 5.4
#Android R + v4l2dec (no vpp) xts clean
-#v4ldec driver seperate from amports drivers
+#v4ldec driver separate from amports drivers
#
#V4.0.0 Release Notes
#upgrade Kernel version to 4.19
-#v4l2 support for h264/h265/vp9
+#v4l2 support for h264/h265/vp9
#add fra support in decoder driver
#
#V3.0.0 Release Notes
#upgrade Kernel version to 4.9
-#media_module remove from kernel
+#media_module remove from kernel
#new firmware management
#mjpeg/mpeg12/mpeg2 multi-instance decoder support
#h264 4k afbc support
@@ -63,8 +62,8 @@
#upgrade TA ucode to 0.2 version
#
#V2.0.0 Release Notes
-#upgrade Kernel version to 3.14
-#Introduce codec_mm memory managment
+#upgrade Kernel version to 3.14
+#Introduce codec_mm memory management
#add afbc scatter memory support
#add vp9 decoder support
#add 264/265/vp9 multi-instance decoder support
diff --git a/drivers/Makefile b/drivers/Makefile
index e96ba44..0eed9e0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -2,7 +2,6 @@
obj-y += frame_provider/
obj-y += frame_sink/
obj-y += stream_input/
-obj-y += amvdec_ports/
obj-y += framerate_adapter/
obj-y += media_sync/
obj-$(CONFIG_AMLOGIC_MEDIA_V4L_DEC) += amvdec_ports/
diff --git a/drivers/amvdec_ports/Makefile b/drivers/amvdec_ports/Makefile
index 2e7cff4..1bee4e0 100644
--- a/drivers/amvdec_ports/Makefile
+++ b/drivers/amvdec_ports/Makefile
@@ -1,26 +1,39 @@
-obj-m += amvdec_ports.o
-amvdec_ports-objs += aml_vcodec_dec_drv.o
-amvdec_ports-objs += aml_vcodec_dec.o
-amvdec_ports-objs += aml_vcodec_util.o
-amvdec_ports-objs += aml_vcodec_adapt.o
-amvdec_ports-objs += aml_vcodec_vpp.o
-amvdec_ports-objs += aml_vcodec_ge2d.o
-amvdec_ports-objs += vdec_drv_if.o
-amvdec_ports-objs += aml_task_chain.o
-amvdec_ports-objs += decoder/vdec_h264_if.o
-amvdec_ports-objs += decoder/vdec_hevc_if.o
-amvdec_ports-objs += decoder/vdec_vp9_if.o
-amvdec_ports-objs += decoder/vdec_mpeg12_if.o
-amvdec_ports-objs += decoder/vdec_mpeg4_if.o
-amvdec_ports-objs += decoder/vdec_mjpeg_if.o
-amvdec_ports-objs += decoder/vdec_av1_if.o
+MODULE_NAME = amvdec_ports
+obj-m += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += aml_vcodec_dec_drv.o
+${MODULE_NAME}-objs += aml_vcodec_dec.o
+${MODULE_NAME}-objs += aml_vcodec_util.o
+${MODULE_NAME}-objs += aml_vcodec_adapt.o
+${MODULE_NAME}-objs += aml_vcodec_vpp.o
+${MODULE_NAME}-objs += aml_vcodec_ge2d.o
+${MODULE_NAME}-objs += aml_vcodec_ts.o
+${MODULE_NAME}-objs += vdec_drv_if.o
+${MODULE_NAME}-objs += aml_task_chain.o
+${MODULE_NAME}-objs += aml_buf_mgr.o
+${MODULE_NAME}-objs += aml_buf_core.o
+${MODULE_NAME}-objs += decoder/vdec_h264_if.o
+${MODULE_NAME}-objs += decoder/vdec_hevc_if.o
+${MODULE_NAME}-objs += decoder/vdec_vp9_if.o
+${MODULE_NAME}-objs += decoder/vdec_mpeg12_if.o
+${MODULE_NAME}-objs += decoder/vdec_mpeg4_if.o
+${MODULE_NAME}-objs += decoder/vdec_mjpeg_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs_if.o
+${MODULE_NAME}-objs += decoder/vdec_av1_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs2_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs3_if.o
+${MODULE_NAME}-objs += decoder/vdec_vc1_if.o
ifdef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
-amvdec_ports-objs += decoder/aml_h264_parser.o
-amvdec_ports-objs += decoder/aml_hevc_parser.o
-amvdec_ports-objs += decoder/aml_vp9_parser.o
-amvdec_ports-objs += decoder/aml_mpeg12_parser.o
-amvdec_ports-objs += decoder/aml_mpeg4_parser.o
-amvdec_ports-objs += decoder/aml_mjpeg_parser.o
-amvdec_ports-objs += utils/golomb.o
+${MODULE_NAME}-objs += decoder/aml_h264_parser.o
+${MODULE_NAME}-objs += decoder/aml_hevc_parser.o
+${MODULE_NAME}-objs += decoder/aml_vp9_parser.o
+${MODULE_NAME}-objs += decoder/aml_mpeg12_parser.o
+${MODULE_NAME}-objs += decoder/aml_mpeg4_parser.o
+${MODULE_NAME}-objs += decoder/aml_mjpeg_parser.o
+${MODULE_NAME}-objs += utils/golomb.o
endif
-amvdec_ports-objs += utils/common.o
+${MODULE_NAME}-objs += utils/common.o
+${MODULE_NAME}-objs += utils/aml_dec_trace.o
+
+PR_FMT = "amlv4l"
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/amvdec_ports/aml_buf_core.c b/drivers/amvdec_ports/aml_buf_core.c
new file mode 100644
index 0000000..b98a0ea
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_core.c
@@ -0,0 +1,872 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+
+#include <linux/atomic.h>
+#include <linux/dma-buf.h>
+
+#include "aml_buf_core.h"
+#include "aml_vcodec_util.h"
+
+static bool bc_sanity_check(struct buf_core_mgr_s *bc)
+{
+ return (bc->state == BM_STATE_ACTIVE) ? true : false;
+}
+
+/* In mmap mode, key is phy_addr; And in dma mode, key is dma buf handle */
+static bool is_dma_mode(ulong key, ulong phy_addr)
+{
+ return (key != phy_addr) ? true : false;
+}
+
+static void buf_core_destroy(struct kref *kref);
+
+static void direction_buf_get(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ int type;
+ switch (user) {
+ case BUF_USER_DEC:
+ entry->holder = BUF_HOLDER_DEC;
+ entry->ref_bit_map += DEC_BIT;
+
+ break;
+ case BUF_USER_VPP:
+ entry->holder = BUF_HOLDER_VPP;
+ entry->ref_bit_map += VPP_BIT;
+
+ type = bc->get_pre_user(bc, entry, user);
+ if (type == BUF_USER_DEC)
+ entry->ref_bit_map -= DEC_BIT;
+ if (type == BUF_USER_GE2D)
+ entry->ref_bit_map -= GE2D_BIT;
+
+ break;
+ case BUF_USER_GE2D:
+ entry->holder = BUF_HOLDER_GE2D;
+ entry->ref_bit_map += GE2D_BIT;
+ entry->ref_bit_map -= DEC_BIT;
+
+ break;
+ case BUF_USER_VSINK:
+ entry->holder = BUF_HOLDER_VSINK;
+ entry->ref_bit_map += VSINK_BIT;
+
+ type = bc->get_pre_user(bc, entry, user);
+ if (type == BUF_USER_VPP)
+ entry->ref_bit_map -= VPP_BIT;
+ if (type == BUF_USER_DEC)
+ entry->ref_bit_map -= DEC_BIT;
+ if (type == BUF_USER_GE2D)
+ entry->ref_bit_map -= GE2D_BIT;
+
+ break;
+ case BUF_USER_DI:
+ entry->ref_bit_map += DI_BIT;
+
+ break;
+ default:
+ break;
+ }
+}
+
+static void direction_buf_put(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ switch (user) {
+ case BUF_USER_DEC:
+ if (entry->ref_bit_map & DEC_MASK)
+ entry->ref_bit_map -= DEC_BIT;
+ if (entry->ref_bit_map & GE2D_MASK)
+ entry->holder = BUF_HOLDER_GE2D;
+ if (entry->ref_bit_map & VPP_MASK)
+ entry->holder = BUF_HOLDER_VPP;
+ if (entry->ref_bit_map & VSINK_MASK)
+ entry->holder = BUF_HOLDER_VSINK;
+
+ break;
+ case BUF_USER_VPP:
+ entry->ref_bit_map -= VPP_BIT;
+ if (entry->ref_bit_map & VPP_MASK)
+ entry->holder = BUF_HOLDER_VPP;
+ else {
+ if (entry->ref_bit_map & GE2D_MASK)
+ entry->holder = BUF_HOLDER_GE2D;
+ if (entry->ref_bit_map & DEC_MASK)
+ entry->holder = BUF_HOLDER_DEC;
+ }
+
+ break;
+ case BUF_USER_GE2D:
+ entry->ref_bit_map -= GE2D_BIT;
+ if (entry->ref_bit_map & GE2D_MASK)
+ entry->holder = BUF_HOLDER_GE2D;
+ else
+ entry->holder = BUF_HOLDER_DEC;
+
+ break;
+ case BUF_USER_VSINK:
+ entry->ref_bit_map -= VSINK_BIT;
+ if (entry->ref_bit_map & DEC_MASK)
+ entry->holder = BUF_HOLDER_DEC;
+ if (entry->ref_bit_map & VSINK_MASK)
+ entry->holder = BUF_HOLDER_VSINK;
+ else if (entry->ref_bit_map & DI_MASK)
+ entry->holder = BUF_HOLDER_DI;
+
+ break;
+ case BUF_USER_DI:
+ entry->ref_bit_map -= DI_BIT;
+
+ break;
+ default:
+ break;
+ }
+}
+
+static void buf_core_update_holder(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user,
+ enum buf_direction direction)
+{
+ struct buf_core_entry *master = entry->pair != BUF_MASTER ? entry->master_entry : entry;
+
+ if (direction == BUF_GET)
+ direction_buf_get(bc, master, user);
+ else
+ direction_buf_put(bc, master, user);
+
+ if (master->ref_bit_map & 0x8888)
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "error! ref_bit_map(0x%x)\n", master->ref_bit_map);
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, holder:%d, key:%lx, ref_bit_map(0x%x)\n",
+ __func__, user, master->holder, master->key, master->ref_bit_map);
+
+ return;
+}
+
+static void buf_core_free_que(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ entry->state = BUF_STATE_FREE;
+ entry->holder = BUF_HOLDER_FREE;
+ entry->ref_bit_map = 0;
+ list_add_tail(&entry->node, &bc->free_que);
+ bc->free_num++;
+ entry->inited = true;
+ entry->queued_mask = 0;
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+}
+
+static void buf_core_get(struct buf_core_mgr_s *bc,
+ enum buf_core_user user,
+ struct buf_core_entry **out_entry,
+ bool more_ref)
+{
+ struct buf_core_entry *entry = NULL, *sub_entry;
+ bool user_change = false;
+
+ mutex_lock(&bc->mutex);
+
+ if (!bc_sanity_check(bc)) {
+ goto out;
+ }
+
+ if (list_empty(&bc->free_que)) {
+ goto out;
+ }
+
+ entry = list_first_entry(&bc->free_que, struct buf_core_entry, node);
+ list_del(&entry->node);
+ bc->free_num--;
+
+ user_change = entry->user != user ? 1 : 0;
+ entry->user = user;
+ entry->state = BUF_STATE_USE;
+ atomic_inc(&entry->ref);
+
+ if (entry->sub_entry[0]) {
+ sub_entry = (struct buf_core_entry *)entry->sub_entry[0];
+ sub_entry->user = user;
+ sub_entry->state = BUF_STATE_USE;
+ }
+
+ if (entry->sub_entry[1]) {
+ sub_entry = (struct buf_core_entry *)entry->sub_entry[1];
+ sub_entry->user = user;
+ sub_entry->state = BUF_STATE_USE;
+ }
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__, user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ if (bc->prepare /*&&
+ user_change*/) {
+ bc->prepare(bc, entry);
+ }
+ buf_core_update_holder(bc, entry, user, BUF_GET);
+out:
+ *out_entry = entry;
+
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ mutex_lock(&bc->mutex);
+
+ if (!bc_sanity_check(bc)) {
+ mutex_unlock(&bc->mutex);
+ return;
+ }
+
+ atomic_dec_return(&entry->ref);
+
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_get_ref(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ mutex_lock(&bc->mutex);
+
+ if (!bc_sanity_check(bc)) {
+ mutex_unlock(&bc->mutex);
+ return;
+ }
+
+ entry->state = BUF_STATE_REF;
+ atomic_inc(&entry->ref);
+ //kref_get(&bc->core_ref);
+ buf_core_update_holder(bc, entry, BUF_USER_DEC, BUF_GET);
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put_ref(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ mutex_lock(&bc->mutex);
+
+ if (!atomic_read(&entry->ref) && !bc_sanity_check(bc)) {
+ v4l_dbg_ext(bc->id, 0,
+ "%s, user:%d, key:%lx, phy:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+ mutex_unlock(&bc->mutex);
+ return;
+ }
+
+ if (!atomic_dec_return(&entry->ref)) {
+ buf_core_free_que(bc, entry);
+ } else {
+ entry->state = BUF_STATE_REF;
+ buf_core_update_holder(bc, entry, BUF_USER_DEC, BUF_PUT);
+ }
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ //kref_put(&bc->core_ref, buf_core_destroy);
+
+ mutex_unlock(&bc->mutex);
+}
+
+static int buf_core_done(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ int ret = 0;
+ struct buf_core_entry *master;
+ mutex_lock(&bc->mutex);
+
+ master = entry;
+ if (entry->pair != BUF_MASTER)
+ master = entry->master_entry;
+
+ if (!bc_sanity_check(bc)) {
+ goto out;
+ }
+
+ if (WARN_ON((entry->state != BUF_STATE_USE) &&
+ (entry->state != BUF_STATE_REF) &&
+ (entry->state != BUF_STATE_DONE))) {
+ ret = -1;
+ goto out;
+ }
+
+ entry->state = BUF_STATE_DONE;
+
+ ret = bc->output(bc, entry, user);
+
+ if (bc->vpp_dque && /* Submit to GE2D doesn't call vpp_dque! */
+ bc->get_next_user(bc, entry, user) == BUF_USER_VSINK &&
+ !bc->vpp_dque(bc, entry)) {
+ atomic_inc(&master->ref);
+ buf_core_update_holder(bc, entry, BUF_USER_DI, BUF_GET);
+ }
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__, user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&master->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+out:
+ mutex_unlock(&bc->mutex);
+
+ return ret;
+}
+
+static void buf_core_fill(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ if (bc->vpp_que && user == BUF_USER_VSINK &&
+ !bc->vpp_que(bc, entry)) {
+ /*
+ * For DI post scenario, if seek or change resolution is doing,
+ * the reset callback will be executed in this process, and
+ * the state of all entries will be cleaned, but in fact
+ * the memory associated with entry may still be used
+ * as reference in DI mgr. If vpp_que returns 0, this entry
+ * is referenced by DI mgr, wait for DI mgr to be used, and
+ * then call callback to retrieve the buffer.
+ */
+ mutex_lock(&bc->mutex);
+ if (!entry->inited || entry->state == BUF_STATE_FREE)
+ goto out;
+ mutex_unlock(&bc->mutex);
+ }
+
+ mutex_lock(&bc->mutex);
+
+ if (!bc_sanity_check(bc)) {
+ goto out;
+ }
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__, user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ if (WARN_ON((entry->state != BUF_STATE_INIT) &&
+ (entry->state != BUF_STATE_DONE) &&
+ (entry->state != BUF_STATE_REF))) {
+ goto out;
+ }
+
+ if (bc->external_process)
+ bc->external_process(bc, entry);
+
+ if (!atomic_dec_return(&entry->ref)) {
+ buf_core_free_que(bc, entry);
+ } else {
+ entry->state = BUF_STATE_REF;
+ buf_core_update_holder(bc, entry, user, BUF_PUT);
+ }
+
+out:
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_vpp_cb(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+ mutex_lock(&bc->mutex);
+ if (entry->pair != BUF_MASTER)
+ entry = (struct buf_core_entry *)entry->master_entry;
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__, entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ if (!atomic_dec_return(&entry->ref)) {
+ buf_core_free_que(bc, entry);
+ } else {
+ entry->state = BUF_STATE_REF;
+ buf_core_update_holder(bc, entry, BUF_USER_DI, BUF_PUT);
+ }
+ mutex_unlock(&bc->mutex);
+}
+
+static int buf_core_ready_num(struct buf_core_mgr_s *bc)
+{
+ if (!bc_sanity_check(bc)) {
+ return 0;
+ }
+
+ return bc->free_num;
+}
+
+static bool buf_core_empty(struct buf_core_mgr_s *bc)
+{
+ if (!bc_sanity_check(bc)) {
+ return true;
+ }
+
+ return list_empty(&bc->free_que);
+}
+
+static void buf_core_reset(struct buf_core_mgr_s *bc)
+{
+ struct buf_core_entry *entry, *tmp;
+ struct hlist_node *h_tmp;
+ ulong bucket;
+
+ if (bc->vpp_reset)
+ bc->vpp_reset(bc);
+
+ mutex_lock(&bc->mutex);
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, core st:%d, core ref:%d, free:%d\n",
+ __func__,
+ bc->state,
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+ list_del(&entry->node);
+ }
+
+ hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+ entry->user = BUF_USER_MAX;
+ entry->state = BUF_STATE_INIT;
+ entry->queued_mask = 0;
+ entry->inited = false;
+
+ if (entry->pair == BUF_MASTER) {
+ atomic_set(&entry->ref, 1);
+ if (entry->sub_entry[0])
+ atomic_inc(&entry->ref);
+ if (entry->sub_entry[1])
+ atomic_inc(&entry->ref);
+ }
+ }
+
+ bc->free_num = 0;
+
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_destroy(struct kref *kref)
+{
+ struct buf_core_mgr_s *bc =
+ container_of(kref, struct buf_core_mgr_s, core_ref);
+ struct buf_core_entry *entry, *tmp;
+
+ list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+ list_del(&entry->node);
+ }
+
+ bc->free_num = 0;
+ bc->buf_num = 0;
+ bc->state = BM_STATE_EXIT;
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+}
+
+static int buf_core_attach(struct buf_core_mgr_s *bc, ulong key,
+ ulong phy_addr, void *priv)
+{
+ int ret = 0;
+ struct buf_core_entry *entry;
+ struct hlist_node *tmp;
+
+ mutex_lock(&bc->mutex);
+
+ hash_for_each_possible_safe(bc->buf_table, entry, tmp, h_node, key) {
+ if (key == entry->key) {
+ if (is_dma_mode(key, phy_addr) && !entry->dma_ref) {
+ get_dma_buf((struct dma_buf *)key);
+ entry->dma_ref++;
+ }
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "reuse buffer, user:%d, key:%lx, phy:%lx idx:%d, "
+ "st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ entry->dma_ref,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ entry->user = BUF_USER_MAX;
+ entry->state = BUF_STATE_INIT;
+ entry->vb2 = priv;
+
+ bc->prepare(bc, entry);
+
+ goto out;
+ }
+ }
+
+ ret = bc->mem_ops.alloc(bc, &entry, priv);
+ if (ret) {
+ goto out;
+ }
+
+ entry->key = key;
+ entry->phy_addr = phy_addr;
+ entry->priv = bc;
+ entry->vb2 = priv;
+ entry->user = BUF_USER_MAX;
+ entry->state = BUF_STATE_INIT;
+ atomic_set(&entry->ref, 1);
+
+ hash_add(bc->buf_table, &entry->h_node, key);
+
+ bc->state = BM_STATE_ACTIVE;
+ bc->buf_num++;
+ kref_get(&bc->core_ref);
+ if (is_dma_mode(key, phy_addr)) {
+ get_dma_buf((struct dma_buf *)key);
+ entry->dma_ref++;
+ }
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ entry->dma_ref,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+out:
+ mutex_unlock(&bc->mutex);
+
+ return ret;
+}
+
+static void buf_core_detach(struct buf_core_mgr_s *bc, ulong key)
+{
+ struct buf_core_entry *entry;
+ struct hlist_node *h_tmp;
+
+ mutex_lock(&bc->mutex);
+
+ hash_for_each_possible_safe(bc->buf_table, entry, h_tmp, h_node, key) {
+ if (key == entry->key) {
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ entry->state = BUF_STATE_ERR;
+ hash_del(&entry->h_node);
+ bc->mem_ops.free(bc, entry);
+
+ kref_put(&bc->core_ref, buf_core_destroy);
+ break;
+ }
+ }
+
+ mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put_dma(struct buf_core_mgr_s *bc)
+{
+ struct buf_core_entry *entry;
+ struct hlist_node *h_tmp;
+ ulong bucket;
+
+ mutex_lock(&bc->mutex);
+
+ hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+ if (is_dma_mode(entry->key, entry->phy_addr) &&
+ entry->dma_ref) {
+ entry->dma_ref--;
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->state,
+ bc->state,
+ entry->dma_ref,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+ dma_buf_put((struct dma_buf *)entry->key);
+ }
+ }
+
+ mutex_unlock(&bc->mutex);
+}
+
+
+static void buf_core_update(struct buf_core_mgr_s *bc, struct buf_core_entry *entry,
+ ulong phy_addr, enum buf_pair pair)
+{
+ mutex_lock(&bc->mutex);
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, phy:(%lx->%lx), "
+ "idx:%d, pair:%d st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->phy_addr,
+ phy_addr,
+ entry->index,
+ pair,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ entry->phy_addr = phy_addr;
+ entry->pair = pair;
+
+ bc->prepare(bc, entry);
+
+ mutex_unlock(&bc->mutex);
+}
+
+void buf_core_replace(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry, void *priv)
+{
+ mutex_lock(&bc->mutex);
+
+ entry->vb2 = priv;
+ entry->user = BUF_USER_MAX;
+ entry->state = BUF_STATE_INIT;
+
+ bc->prepare(bc, entry);
+
+ mutex_unlock(&bc->mutex);
+}
+
+ssize_t buf_core_walk(struct buf_core_mgr_s *bc, char *buf)
+{
+ struct buf_core_entry *entry, *tmp;
+ struct hlist_node *h_tmp;
+ ulong bucket;
+ int dec_holders = 0;
+ int ge2d_holders = 0;
+ int vpp_holders = 0;
+ int vsink_holders = 0;
+ int di_holders = 0;
+ char *pbuf = buf;
+
+ mutex_lock(&bc->mutex);
+
+ pbuf += sprintf(pbuf, "\nFree queue elements:\n");
+ list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+ pbuf += sprintf(pbuf,
+ "--> key:%lx, phy:%lx, idx:%d, user:%d, holder:%d, "
+ "st:(%d, %d), ref:(%d, %d), free:%d\n",
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->user,
+ entry->holder,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+ }
+
+ pbuf += sprintf(pbuf, "\nHash table elements:\n");
+ hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+ if (entry->pair == BUF_MASTER) {
+ if (entry->holder == BUF_HOLDER_DEC)
+ dec_holders++;
+ if (entry->holder == BUF_HOLDER_GE2D)
+ ge2d_holders++;
+ if (entry->holder == BUF_HOLDER_VPP)
+ vpp_holders++;
+ if (entry->holder == BUF_HOLDER_VSINK)
+ vsink_holders++;
+ if (entry->ref_bit_map & DI_MASK)
+ di_holders++;
+
+ pbuf += sprintf(pbuf,
+ "--> key:%lx, phy:%lx, idx:%d, user:%d, holder:%d, st:(%d, %d), ref:(%d, %d), free:%d, ref_map:0x%x\n",
+ entry->key,
+ entry->phy_addr,
+ entry->index,
+ entry->user,
+ entry->holder,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num,
+ entry->ref_bit_map);
+ }
+ }
+ pbuf += sprintf(pbuf, "holders: dec(%d), ge2d(%d), vpp(%d), vsink(%d) di(%d)\n",
+ dec_holders, ge2d_holders, vpp_holders, vsink_holders, di_holders);
+
+ mutex_unlock(&bc->mutex);
+
+ return pbuf - buf;
+}
+EXPORT_SYMBOL(buf_core_walk);
+
+int buf_core_mgr_init(struct buf_core_mgr_s *bc)
+{
+ /* Sanity check of mandatory interfaces. */
+ if (WARN_ON(!bc->config) ||
+ WARN_ON(!bc->input) ||
+ WARN_ON(!bc->output) ||
+ WARN_ON(!bc->mem_ops.alloc) ||
+ WARN_ON(!bc->mem_ops.free)) {
+ return -1;
+ }
+
+ hash_init(bc->buf_table);
+ INIT_LIST_HEAD(&bc->free_que);
+ mutex_init(&bc->mutex);
+ kref_init(&bc->core_ref);
+
+ bc->free_num = 0;
+ bc->buf_num = 0;
+ bc->state = BM_STATE_INIT;
+
+ /* The external interfaces of BC context. */
+ bc->attach = buf_core_attach;
+ bc->detach = buf_core_detach;
+ bc->reset = buf_core_reset;
+ bc->update = buf_core_update;
+ bc->replace = buf_core_replace;
+ bc->put_dma = buf_core_put_dma;
+
+ /* The interface set of the buffer core operation. */
+ bc->buf_ops.get = buf_core_get;
+ bc->buf_ops.put = buf_core_put;
+ bc->buf_ops.get_ref = buf_core_get_ref;
+ bc->buf_ops.put_ref = buf_core_put_ref;
+ bc->buf_ops.done = buf_core_done;
+ bc->buf_ops.fill = buf_core_fill;
+ bc->buf_ops.ready_num = buf_core_ready_num;
+ bc->buf_ops.empty = buf_core_empty;
+ bc->buf_ops.vpp_cb = buf_core_vpp_cb;
+ bc->buf_ops.update_holder = buf_core_update_holder;
+
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+ return 0;
+}
+EXPORT_SYMBOL(buf_core_mgr_init);
+
+void buf_core_mgr_release(struct buf_core_mgr_s *bc)
+{
+ v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+ kref_put(&bc->core_ref, buf_core_destroy);
+}
+EXPORT_SYMBOL(buf_core_mgr_release);
+
diff --git a/drivers/amvdec_ports/aml_buf_core.h b/drivers/amvdec_ports/aml_buf_core.h
new file mode 100644
index 0000000..ad5d600
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_core.h
@@ -0,0 +1,315 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef _AML_BUF_CORE_H_
+#define _AML_BUF_CORE_H_
+
+#include <linux/kref.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/hashtable.h>
+
+#define NEW_FB_CODE
+
+#define BUF_HASH_BITS (10)
+
+#define DEC_BIT (UL(1) << (0))
+#define GE2D_BIT (UL(1) << (4))
+#define VPP_BIT (UL(1) << (8))
+#define VSINK_BIT (UL(1) << (12))
+#define DI_BIT (UL(1) << (16))
+
+#define DEC_MASK (0xf)
+#define GE2D_MASK (0xf0)
+#define VPP_MASK (0xf00)
+#define VSINK_MASK (0xf000)
+#define DI_MASK (0xf0000)
+
+#define MASTER_DONE (1)
+#define SUB0_DONE (2)
+#define SUB1_DONE (3)
+#define PAIR_DONE (3)
+
+struct buf_core_mgr_s;
+
+/*
+ * enum buf_core_state - The state of the buffer to be used.
+ *
+ * @BUF_STATE_INIT : The initialization state of the buffer.
+ * @BUF_STATE_FREE : The idle state of the buffer that can be used.
+ * @BUF_STATE_USE : The status of the buffer being allocated by the user.
+ * @BUF_STATE_REF : The state of the buffer referenced by the user.
+ * @BUF_STATE_DONE : The state of the buffer is filled done by user.
+ * @BUF_STATE_ERR : The buffer has an error or is about to be released.
+ */
+enum buf_core_state {
+ BUF_STATE_INIT,
+ BUF_STATE_FREE,
+ BUF_STATE_USE,
+ BUF_STATE_REF,
+ BUF_STATE_DONE,
+ BUF_STATE_ERR
+};
+
+/*
+ * enum buf_core_state - The state of the buffer core manager context.
+ *
+ * @BM_STATE_INIT : The initialization state of context.
+ * @BM_STATE_ACTIVE : Status indicates that there are available buffers to manage.
+ * @BM_STATE_EXIT : The buffer core manager context release.
+ */
+enum buf_core_mgr_state {
+ BM_STATE_INIT,
+ BM_STATE_ACTIVE,
+ BM_STATE_EXIT
+};
+
+/*
+ * enum buf_core_user - Buffer users.
+ *
+ * @BUF_USER_DEC : Indicates that the current buffer user is decoder.
+ * @BUF_USER_VPP : Indicates that the current buffer user is vpp wrapper.
+ * @BUF_USER_GE2D : Indicates that the current buffer user is ge2d wrapper.
+ * @BUF_USER_VSINK : Indicates that the current buffer user is vsink.
+ * @BUF_USER_MAX : Invalid user.
+ */
+enum buf_core_user {
+ BUF_USER_DEC,
+ BUF_USER_VPP,
+ BUF_USER_GE2D,
+ BUF_USER_VSINK,
+ BUF_USER_DI,
+ BUF_USER_MAX
+};
+
+/*
+ * enum buf_core_holder - Buffer holders.
+ *
+ * @BUF_HOLDER_DEC : Indicates that the current buffer holder is decoder.
+ * @BUF_HOLDER_VPP : Indicates that the current buffer holder is vpp wrapper.
+ * @BUF_HOLDER_GE2D : Indicates that the current buffer holder is ge2d wrapper.
+ * @BUF_HOLDER_VSINK : Indicates that the current buffer holder is vsink.
+ * @BUF_HOLDER_MAX : Invalid holder.
+ */
+enum buf_core_holder {
+ BUF_HOLDER_DEC,
+ BUF_HOLDER_VPP,
+ BUF_HOLDER_GE2D,
+ BUF_HOLDER_VSINK,
+ BUF_HOLDER_DI,
+ BUF_HOLDER_FREE,
+};
+
+enum buf_direction {
+ BUF_GET,
+ BUF_PUT
+};
+
+/*
+ * enum buf_pair - For di post.
+ *
+ * @BUF_MASTER : Indicates that the first field.
+ * @BUF_SUB0 : Indicates that the second field.
+ * @BUF_SUB1 : Indicates that the third field.
+ */
+enum buf_pair {
+ BUF_MASTER,
+ BUF_SUB0,
+ BUF_SUB1
+};
+
+/*
+ * struct buf_core_entry - The entry of buffer.
+ *
+ * @key : Record the actual physical address associated with vb.
+ * @ref : Decode buffer's reference count status.
+ * @master_ref : Point to master buf ref.
+ * @node : The position of the decoded buffer entry.
+ * @h_node : The node of hash list used for query buffer.
+ * @state : The state of the buffer to be used.
+ * @user : Indicates the user that holds the current entry.
+ * @vb2 : The handle of v4l2 video buffer2.
+ * @priv : Record associated private data.
+ * @ref_bit_map : [0, 3]: dec ref, [4, 7]: ge2d ref,
+ * [8, 11]: vpp ref, [12, 15]: vsink ref.
+ * @sub_entry[2]: sub_entry[0]: The second filed buf entry;
+ * sub_entry[1]: The third filed buf entry;
+ * @master_entry: The first filed buf entry.
+ * @pair : Buf attributes: master, sub0, sub1.
+ * @pair_state : Buffer pairing status.
+ * @index : Aml buf index.
+ * @inited : The pairing is completed and enters the free queue.
+ * @queued_mask : Field buffer return times.
+ */
+struct buf_core_entry {
+ ulong key;
+ ulong phy_addr;
+ atomic_t ref;
+ atomic_t *master_ref;
+ u32 dma_ref;
+ struct list_head node;
+ struct hlist_node h_node;
+ enum buf_core_state state;
+ enum buf_core_user user;
+ enum buf_core_holder holder;
+ void *vb2;
+ void *priv;
+ u32 ref_bit_map;
+ void *sub_entry[2];
+ void *master_entry;
+ enum buf_pair pair;
+ u32 pair_state;
+ u32 index;
+ u32 inited;
+ u32 queued_mask; /* bit0: master; bit1: sub0; bit1: sub1*/
+};
+
+/*
+ * struct buf_core_ops - The interface set of the buffer core operation.
+ *
+ * @get : Get a free buffer from free queue.
+ * @put : Put an unused buffer to the free queue.
+ * @get_ref : Increase a reference count to the buffer and switch state to REF.
+ * @put_ref : Decrease a reference count to the buffer.
+ * @done : The done interface is called if the user finishes fill the data.
+ * @fill : The fill interface is called if the user consumes the data.
+ * @ready_num : Query the number of buffers in the free queue.
+ * @empty : Check whether the free queue is empty.
+ */
+struct buf_core_ops {
+ void (*get)(struct buf_core_mgr_s *, enum buf_core_user, struct buf_core_entry **, bool);
+ void (*put)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ void (*get_ref)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ void (*put_ref)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ int (*done)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ void (*fill)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ int (*ready_num)(struct buf_core_mgr_s *);
+ bool (*empty)(struct buf_core_mgr_s *);
+ void (*vpp_cb)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ void (*update_holder)(struct buf_core_mgr_s *, struct buf_core_entry *,
+ enum buf_core_user, enum buf_direction direction);
+};
+
+/*
+ * struct buf_core_mem_ops - The memory operation of entry.
+ *
+ * @alloc : Allocates an instance of an entry.
+ * @free : Releases an instance of an entry.
+ */
+struct buf_core_mem_ops {
+ int (*alloc)(struct buf_core_mgr_s *, struct buf_core_entry **, void *);
+ void (*free)(struct buf_core_mgr_s *, struct buf_core_entry *);
+};
+
+/*
+ * struct buf_core_mgr_s - Decoder buffer management structure.
+ *
+ * @id : Instance ID of the buffer core manager context.
+ * @name : Name of the buffer core manager context.
+ * @state : State of the buffer core manager context.
+ * @mutex : Lock is used to ensure interface serialization.
+ * @core_ref : Reference count of the buffer core manager context.
+ * @free_num : The number of free buffers available.
+ * @free_que : Queue for storing free buffers.
+ * @buf_num : Record the serial number of buffer attached to the buffer manager.
+ * @buf_table : Used to store the attached buffer.
+ * @config : Interface Settings parameters to buffer manager.
+ * @attach : The interface is used to attach buffer to buffer manager.
+ * @detach : Interface for detach buffer to buffer manager.
+ * @reset : Interface used to reset the state of the buffer manager.
+ * @prepare : The interface is used for the preprocessing of buffer data.
+ * @input : The interface uses data input and is triggered after calling the interface fill.
+ * @output : The interface uses data output and is triggered after the interface is called done.
+ * vpp_que : Interact with DI mgr to notify the buffer that has been displayed back to the driver.
+ * vpp_dque : The decoded buffer is submitted to DI mgr for post-processing.
+ * vpp_reset : Used to reset the buffer information managed by DI mgr.
+ * @mem_ops : Set of interfaces for memory-related operations.
+ * @buf_ops : Set of interfaces for buffer operations.
+ */
+struct buf_core_mgr_s {
+ int id;
+ char *name;
+ enum buf_core_mgr_state state;
+ struct mutex mutex;
+ struct kref core_ref;
+
+ int free_num;
+ struct list_head free_que;
+
+ int buf_num;
+ DECLARE_HASHTABLE(buf_table, BUF_HASH_BITS);
+
+ void (*config)(struct buf_core_mgr_s *, void *);
+ int (*attach)(struct buf_core_mgr_s *, ulong, ulong, void *);
+ void (*detach)(struct buf_core_mgr_s *, ulong);
+ void (*reset)(struct buf_core_mgr_s *);
+ void (*prepare)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ void (*input)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ int (*output)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ int (*vpp_que)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ int (*vpp_dque)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ int (*vpp_reset)(struct buf_core_mgr_s *);
+ void (*external_process)(struct buf_core_mgr_s *, struct buf_core_entry *);
+ int (*get_pre_user) (struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ int (*get_next_user) (struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+ void (*update)(struct buf_core_mgr_s *, struct buf_core_entry *, ulong, enum buf_pair);
+ void (*replace)(struct buf_core_mgr_s *, struct buf_core_entry *, void *);
+ void (*put_dma)(struct buf_core_mgr_s *);
+
+ struct buf_core_mem_ops mem_ops;
+ struct buf_core_ops buf_ops;
+};
+
+/*
+ * buf_core_walk() - Iterate over the buffer entities used for debugging.
+ *
+ * @bc : pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Iterate over information about the used buffer entities
+ * for debugging, including available buffers recorded in
+ * the Free queue and managed buffers attached to the hash table,
+ * and their states are iterated and printed out.
+ */
+ssize_t buf_core_walk(struct buf_core_mgr_s *bc, char *buf);
+
+/*
+ * buf_core_mgr_init() - buffer core management initialization.
+ *
+ * @bc : pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Used to initialize the buffer core manager context.
+ *
+ * Return : returns zero on success; an error code otherwise
+ */
+int buf_core_mgr_init(struct buf_core_mgr_s *bc);
+
+/*
+ * buf_core_mgr_release() - buffer core management release.
+ *
+ * @bc : pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Used to release buffer core manager context
+ */
+void buf_core_mgr_release(struct buf_core_mgr_s *bc);
+
+#endif //_AML_BUF_CORE_H_
+
diff --git a/drivers/amvdec_ports/aml_buf_mgr.c b/drivers/amvdec_ports/aml_buf_mgr.c
new file mode 100644
index 0000000..0a455a8
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_mgr.c
@@ -0,0 +1,1010 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+
+#include <linux/device.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/meson_uvm_core.h>
+
+#include "../frame_provider/decoder/utils/decoder_bmmu_box.h"
+#include "../frame_provider/decoder/utils/decoder_mmu_box.h"
+#include "aml_vcodec_drv.h"
+#include "aml_vcodec_dec.h"
+#include "aml_task_chain.h"
+#include "aml_buf_mgr.h"
+#include "aml_vcodec_util.h"
+#include "vdec_drv_if.h"
+#include "utils/common.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/amlogic/media/video_processor/di_proc_buf_mgr.h>
+#endif
+
+#define IS_VPP_POST(bm) (bm->vpp_work_mode == VPP_WORK_MODE_DI_POST)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+static void aml_buf_vpp_callback(void *caller_data, struct file *file, int id)
+{
+ struct buf_core_mgr_s *bc = caller_data;
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct buf_core_entry *entry = NULL;
+ struct dma_buf *dbuf = file->private_data;
+ ulong key = (ulong)dbuf;
+
+ hash_for_each_possible(bc->buf_table, entry, h_node, key) {
+ if (key == entry->key) {
+ break;
+ }
+ }
+
+ if (entry && bc->buf_ops.vpp_cb)
+ bc->buf_ops.vpp_cb(bc, entry);
+ else
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR, "entry is NULL\n");
+}
+
+static int aml_buf_vpp_que(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ int ret = -1;
+
+ if (buf->queued_mask & (1 << BUF_SUB0))
+ buf = entry_to_aml_buf(entry->sub_entry[0]);
+
+ if (buf->queued_mask & (1 << BUF_SUB1))
+ buf = entry_to_aml_buf(entry->sub_entry[1]);
+
+ ret = buf_mgr_q_checkin(bm->vpp_handle, buf->planes[0].dbuf->file);
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, idx: %d, ret:%d\n",
+ __func__, buf->index, ret);
+
+ return ret;
+}
+
+static int aml_buf_vpp_dque(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ struct vframe_s *vf = &buf->vframe;
+ int ret = -1;
+
+ vf->index_disp = bm->frm_cnt;
+ vf->omx_index = bm->frm_cnt;
+
+ if (!(vf->type & VIDTYPE_V4L_EOS))
+ bm->frm_cnt++;
+
+ dmabuf_set_vframe(buf->planes[0].dbuf, &buf->vframe, VF_SRC_DECODER);
+
+ ret = buf_mgr_dq_checkin(bm->vpp_handle, buf->planes[0].dbuf->file);
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, idx: %d, ret:%d\n",
+ __func__, buf->index, ret);
+
+ return ret;
+}
+
+static int aml_buf_vpp_reset(struct buf_core_mgr_s *bc)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ int ret = -1;
+
+ ret = buf_mgr_reset(bm->vpp_handle);
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, ret:%d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static int aml_buf_vpp_mgr_init(struct aml_buf_mgr_s *bm)
+{
+ if (!IS_VPP_POST(bm))
+ return 0;
+
+ if (!bm->vpp_handle) {
+ bm->vpp_handle = buf_mgr_creat(DEC_TYPE_V4L_DEC,
+ bm->bc.id,
+ &bm->bc,
+ aml_buf_vpp_callback);
+ if (!bm->vpp_handle) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "%s, The vpp buf mgr creat fail.\n",
+ __func__);
+ return -1;
+ }
+
+ bm->bc.vpp_que = aml_buf_vpp_que;
+ bm->bc.vpp_dque = aml_buf_vpp_dque;
+ bm->bc.vpp_reset = aml_buf_vpp_reset;
+ }
+
+ return 0;
+}
+
+static void aml_buf_vpp_mgr_release(struct aml_buf_mgr_s *bm)
+{
+ if (bm->vpp_handle)
+ buf_mgr_release(bm->vpp_handle);
+}
+#endif
+
+static int aml_buf_box_alloc(struct aml_buf_mgr_s *bm, void **mmu, void **mmu_1, void **bmmu) {
+ struct aml_buf_fbc_info fbc_info;
+ int mmu_flag = bm->config.enable_secure ? CODEC_MM_FLAGS_TVP : 0;
+ int bmmu_flag = mmu_flag;
+ struct aml_vcodec_ctx *ctx = container_of(bm,
+ struct aml_vcodec_ctx, bm);
+
+ bm->get_fbc_info(bm, &fbc_info);
+
+ /* init mmu box */
+ *mmu = decoder_mmu_box_alloc_box(bm->bc.name,
+ bm->bc.id,
+ BUF_FBC_NUM_MAX,
+ fbc_info.max_size * SZ_1M,
+ mmu_flag);
+ if (!(*mmu)) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to create mmu box\n");
+ return -EINVAL;
+ }
+
+#ifdef NEW_FB_CODE
+ if (ctx->front_back_mode) {
+ *mmu_1 = decoder_mmu_box_alloc_box(bm->bc.name,
+ bm->bc.id,
+ BUF_FBC_NUM_MAX,
+ fbc_info.max_size * SZ_1M,
+ mmu_flag);
+ if (!(*mmu_1)) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to create mmu_1 box\n");
+ goto free_mmubox;
+ }
+ }
+#endif
+
+ /* init bmmu box */
+ bmmu_flag |= (CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER);
+ *bmmu = decoder_bmmu_box_alloc_box(bm->bc.name,
+ bm->bc.id,
+ BUF_FBC_NUM_MAX,
+ 4 + PAGE_SHIFT,
+ bmmu_flag, BMMU_ALLOC_FLAGS_WAIT);
+ if (!(*bmmu)) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to create bmmu box\n");
+ goto free_mmubox1;
+ }
+
+ return 0;
+
+free_mmubox1:
+ decoder_mmu_box_free(*mmu_1);
+ *mmu_1 = NULL;
+
+free_mmubox:
+ decoder_mmu_box_free(*mmu);
+ *mmu = NULL;
+
+ return -1;
+}
+
+static int aml_buf_box_init(struct aml_buf_mgr_s *bm)
+{
+ u32 dw_mode = DM_YUV_ONLY;
+ struct aml_vcodec_ctx *ctx = container_of(bm,
+ struct aml_vcodec_ctx, bm);
+ bool buff_alloc_done = false;
+
+ if (!bm->mmu || !bm->bmmu) {
+ bm->fbc_array = vzalloc(sizeof(*bm->fbc_array) * BUF_FBC_NUM_MAX);
+ if (!bm->fbc_array)
+ return -ENOMEM;
+ if (aml_buf_box_alloc(bm, &bm->mmu, &bm->mmu_1, &bm->bmmu)) {
+ vfree(bm->fbc_array);
+ bm->fbc_array = NULL;
+ return -EINVAL;
+ }
+ buff_alloc_done = true;
+ }
+
+ if (!bm->mmu_dw || !bm->bmmu_dw) {
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+ return -EINVAL;
+ }
+ if (dw_mode & VDEC_MODE_MMU_DW_MASK) {
+ if (aml_buf_box_alloc(bm, &bm->mmu_dw, &bm->mmu_dw_1, &bm->bmmu_dw)) {
+ return -EINVAL;
+ }
+ buff_alloc_done = true;
+ }
+ }
+
+ if (buff_alloc_done)
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "box init, bmmu: %px, mmu: %px, bmmu_dw: %px mmu_dw: %px mmu_1: %px, mmu_dw_1: %px\n",
+ bm->bmmu, bm->mmu, bm->bmmu_dw, bm->mmu_dw, bm->mmu_1, bm->mmu_dw_1);
+
+ return 0;
+}
+
+static int aml_buf_fbc_init(struct aml_buf_mgr_s *bm, struct aml_buf *buf)
+{
+ struct aml_buf_fbc_info fbc_info;
+ struct aml_buf_fbc *fbc;
+ int ret, i;
+
+ if (aml_buf_box_init(bm))
+ return -EINVAL;
+
+
+ for (i = 0; i < BUF_FBC_NUM_MAX; i++) {
+ if (!bm->fbc_array[i].ref)
+ break;
+ }
+
+ if (i == BUF_FBC_NUM_MAX) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "out of fbc buf\n");
+ return -EINVAL;
+ }
+
+ bm->get_fbc_info(bm, &fbc_info);
+
+ fbc = &bm->fbc_array[i];
+ fbc->index = i;
+ fbc->hsize = fbc_info.header_size;
+ fbc->hsize_dw = fbc_info.header_size;
+ fbc->frame_size = fbc_info.frame_size;
+ fbc->bmmu = bm->bmmu;
+ fbc->mmu = bm->mmu;
+ fbc->bmmu_dw = bm->bmmu_dw;
+ fbc->mmu_dw = bm->mmu_dw;
+#ifdef NEW_FB_CODE
+ fbc->mmu_1 = bm->mmu_1;
+ fbc->mmu_dw_1 = bm->mmu_dw_1;
+#endif
+ fbc->used[i] = 0;
+ fbc->ref = 1;
+
+ /* allocate header */
+ ret = decoder_bmmu_box_alloc_buf_phy(bm->bmmu,
+ fbc->index,
+ fbc->hsize,
+ bm->bc.name,
+ &fbc->haddr);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to alloc %dth bmmu\n", i);
+ return -ENOMEM;
+ }
+ if (!bm->config.enable_secure) {
+ codec_mm_memset(fbc->haddr, 0, fbc->hsize);
+ }
+
+ if (bm->bmmu_dw) {
+ ret = decoder_bmmu_box_alloc_buf_phy(bm->bmmu_dw,
+ fbc->index,
+ fbc->hsize_dw,
+ "v4ldec-m2m-dw",
+ &fbc->haddr_dw);
+ if (ret < 0) {
+ decoder_bmmu_box_free_idx(bm->bmmu, fbc->index);
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to alloc %dth bmmu dw\n", i);
+ return -ENOMEM;
+ }
+ if (!bm->config.enable_secure) {
+ codec_mm_memset(fbc->haddr_dw, 0, fbc->hsize_dw);
+ }
+ }
+
+ buf->fbc = fbc;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, fbc:%d, haddr:%lx, hsize:%d, frm size:%d "
+ "haddr_dw:%lx, hsize_dw:%d\n",
+ __func__,
+ fbc->index,
+ fbc->haddr,
+ fbc->hsize,
+ fbc->frame_size,
+ fbc->haddr_dw,
+ fbc->hsize_dw);
+
+ return 0;
+}
+
+static int aml_buf_fbc_release(struct aml_buf_mgr_s *bm, struct aml_buf *buf)
+{
+ struct aml_buf_fbc *fbc = buf->fbc;
+ int ret;
+ struct aml_vcodec_ctx *ctx = container_of(bm,
+ struct aml_vcodec_ctx, bm);
+
+ ret = decoder_bmmu_box_free_idx(bm->bmmu, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth bmmu\n", fbc->index);
+ return -ENOMEM;
+ }
+
+ ret = decoder_mmu_box_free_idx(bm->mmu, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth mmu\n", fbc->index);
+ return -ENOMEM;
+ }
+
+#ifdef NEW_FB_CODE
+ if (ctx->front_back_mode) {
+ ret = decoder_mmu_box_free_idx(bm->mmu_1, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth mmu 1\n", fbc->index);
+ return -ENOMEM;
+ }
+ }
+#endif
+
+ if (bm->mmu_dw) {
+ ret = decoder_mmu_box_free_idx(bm->mmu_dw, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth mmu dw\n", fbc->index);
+ return -ENOMEM;
+ }
+ }
+
+#ifdef NEW_FB_CODE
+ if (ctx->front_back_mode && bm->mmu_dw_1) {
+ ret = decoder_mmu_box_free_idx(bm->mmu_dw_1, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth mmu dw 1\n", fbc->index);
+ return -ENOMEM;
+ }
+ }
+#endif
+
+ if (bm->bmmu_dw) {
+ decoder_bmmu_box_free_idx(bm->bmmu_dw, fbc->index);
+ if (ret < 0) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to free %dth bmmu dw\n", fbc->index);
+ return -ENOMEM;
+ }
+ }
+
+ fbc->used[fbc->index] = 0;
+ fbc->ref = 0;
+ buf->fbc = NULL;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, fbc:%d, haddr:%lx, hsize:%d, frm size:%d "
+ "haddr_dw:%lx, hsize_dw:%d\n",
+ __func__,
+ fbc->index,
+ fbc->haddr,
+ fbc->hsize,
+ fbc->frame_size,
+ fbc->haddr_dw,
+ fbc->hsize_dw);
+
+ return 0;
+}
+
+static void aml_buf_get_fbc_info(struct aml_buf_mgr_s *bm,
+ struct aml_buf_fbc_info *info)
+{
+ struct vdec_comp_buf_info comp_info;
+
+ if (vdec_if_get_param(bm->priv, GET_PARAM_COMP_BUF_INFO, &comp_info)) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "fail to get comp info\n");
+ return;
+ }
+
+ info->max_size = comp_info.max_size;
+ info->header_size = comp_info.header_size;
+ info->frame_size = comp_info.frame_buffer_size;
+}
+
+static void aml_buf_fbc_destroy(struct aml_buf_mgr_s *bm)
+{
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR, "%s %d\n", __func__, __LINE__);
+ if (bm->bmmu)
+ decoder_bmmu_box_free(bm->bmmu);
+ if (bm->mmu)
+ decoder_mmu_box_free(bm->mmu);
+
+ if (bm->mmu_dw)
+ decoder_mmu_box_free(bm->mmu_dw);
+ if (bm->bmmu_dw)
+ decoder_bmmu_box_free(bm->bmmu_dw);
+
+#ifdef NEW_FB_CODE
+ if (bm->mmu_1)
+ decoder_mmu_box_free(bm->mmu_1);
+ if (bm->mmu_dw_1)
+ decoder_mmu_box_free(bm->mmu_dw_1);
+#endif
+ if (bm->fbc_array)
+ vfree(bm->fbc_array);
+ bm->fbc_array = NULL;
+}
+
+static void aml_buf_mgr_destroy(struct kref *kref)
+{
+ struct aml_buf_mgr_s *bm =
+ container_of(kref, struct aml_buf_mgr_s, ref);
+
+ if (bm->fbc_array) {
+ aml_buf_fbc_destroy(bm);
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+ aml_buf_vpp_mgr_release(bm);
+#endif
+}
+
+static void aml_buf_flush(struct aml_buf_mgr_s *bm,
+ struct aml_buf *aml_buf)
+{
+ struct aml_buf_config *cfg = &bm->config;
+ void *buf = NULL;
+ int i;
+
+ if (aml_buf->flush_flag)
+ return;
+
+ if (cfg->enable_secure)
+ return;
+
+ for (i = 0 ; i < aml_buf->num_planes ; i++) {
+ buf = codec_mm_phys_to_virt(aml_buf->planes_tw[i].addr);
+ if (buf) {
+ codec_mm_dma_flush(buf,
+ aml_buf->planes_tw[i].length, DMA_FROM_DEVICE);
+ } else {
+ buf = codec_mm_vmap(aml_buf->planes_tw[i].addr,
+ aml_buf->planes_tw[i].length);
+ if (!buf) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "%s flush tw dma buffer fail!\n", __func__);
+ return;
+ }
+
+ codec_mm_dma_flush(buf,
+ aml_buf->planes_tw[i].length, DMA_FROM_DEVICE);
+ codec_mm_unmap_phyaddr(buf);
+ }
+ }
+
+ aml_buf->flush_flag = true;
+}
+
+void aml_buf_set_planes_v4l2(struct aml_buf_mgr_s *bm,
+ struct aml_buf *aml_buf,
+ void *priv)
+{
+ struct vb2_buffer *vb = (struct vb2_buffer *)priv;
+ struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+ struct aml_v4l2_buf *aml_vb = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+ struct aml_buf_config *cfg = &bm->config;
+ struct aml_buf *master_buf;
+ char plane_n[3] = {'Y','U','V'};
+ int i;
+
+ aml_buf->vb = vb;
+ aml_buf->num_planes = vb->num_planes;
+ aml_vb->aml_buf = aml_buf;
+ aml_buf->entry.index = aml_buf->index;
+ aml_buf->inited = aml_buf->entry.inited;
+ aml_buf->entry.pair_state = aml_buf->pair_state;
+
+ for (i = 0 ; i < vb->num_planes ; i++) {
+ if (i == 0) {
+ //Y
+ if (vb->num_planes == 1) {
+ aml_buf->planes[0].length = cfg->luma_length + cfg->chroma_length;
+ aml_buf->planes[0].offset = cfg->luma_length;
+ } else {
+ aml_buf->planes[0].length = cfg->luma_length;
+ aml_buf->planes[0].offset = 0;
+ }
+ } else {
+ if (vb->num_planes == 2) {
+ //UV
+ aml_buf->planes[1].length = cfg->chroma_length;
+ aml_buf->planes[1].offset = cfg->chroma_length >> 1;
+ } else {
+ aml_buf->planes[i].length = cfg->chroma_length >> 1;
+ aml_buf->planes[i].offset = 0;
+ }
+ }
+
+ aml_buf->planes[i].addr = get_addr(vb, i);
+ aml_buf->planes[i].dbuf = vb->planes[i].dbuf;
+
+ if (aml_buf->pair == BUF_SUB0) {
+ master_buf = (struct aml_buf *)aml_buf->master_buf;
+ master_buf->entry.master_ref = &master_buf->entry.ref;
+ master_buf->entry.sub_entry[0] = (void *)&aml_buf->entry;
+
+ aml_buf->entry.master_entry = (void *)&master_buf->entry;
+ aml_buf->entry.master_ref = &master_buf->entry.ref;
+ }
+
+ if (aml_buf->pair == BUF_SUB1) {
+ master_buf = (struct aml_buf *)aml_buf->master_buf;
+ master_buf->entry.sub_entry[1] = (void *)&aml_buf->entry;
+
+ aml_buf->entry.master_entry = (void *)&master_buf->entry;
+ aml_buf->entry.master_ref = &master_buf->entry.ref;
+ }
+
+ /* Make a fake used size for DW/TW:(0, 0). */
+ if (!cfg->dw_mode)
+ aml_buf->planes[i].bytes_used = 1;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "Buffer info, id:%x, %c:(0x%lx, %d), DW:%x\n",
+ vb->index,
+ plane_n[i],
+ aml_buf->planes[i].addr,
+ aml_buf->planes[i].length,
+ cfg->dw_mode);
+ }
+
+ if (cfg->tw_mode) {
+ for (i = 0 ; i < vb->num_planes ; i++) {
+ if (i == 0) {
+ //Y
+ if (vb->num_planes == 1) {
+ aml_buf->planes_tw[0].length = cfg->luma_length_tw + cfg->chroma_length_tw;
+ aml_buf->planes_tw[0].offset = cfg->luma_length_tw;
+ } else {
+ aml_buf->planes_tw[0].length = cfg->luma_length_tw;
+ aml_buf->planes_tw[0].offset = 0;
+ }
+ } else {
+ if (vb->num_planes == 2) {
+ //UV
+ aml_buf->planes_tw[1].length = cfg->chroma_length_tw;
+ aml_buf->planes_tw[1].offset = cfg->chroma_length_tw >> 1;
+ } else {
+ aml_buf->planes_tw[i].length = cfg->chroma_length_tw >> 1;
+ aml_buf->planes_tw[i].offset = 0;
+ }
+ }
+
+ aml_buf->planes_tw[i].addr = (cfg->dw_mode == DM_AVBC_ONLY) ?
+ vb2_dma_contig_plane_dma_addr(vb, i):
+ (aml_buf->planes_tw[i].addr ?
+ aml_buf->planes_tw[i].addr:
+ codec_mm_alloc_for_dma_ex("tw_buf",
+ (cfg->luma_length_tw +
+ cfg->chroma_length_tw) / PAGE_SIZE,
+ 4,
+ CODEC_MM_FLAGS_FOR_VDECODER,
+ bm->bc.id,
+ i));
+ aml_buf->planes_tw[i].dbuf = vb->planes[i].dbuf;
+ aml_buf_flush(bm, aml_buf);
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "Buffer info, id:%d, %c:(0x%lx, %d), TW:%x\n",
+ vb->index,
+ plane_n[i],
+ aml_buf->planes_tw[i].addr,
+ aml_buf->planes_tw[i].length,
+ cfg->tw_mode);
+ }
+ }
+}
+
+static void aml_buf_set_planes(struct aml_buf_mgr_s *bm,
+ struct aml_buf *buf)
+{
+ //todo
+}
+
+static int aml_buf_set_default_parms(struct aml_buf_mgr_s *bm,
+ struct aml_buf *buf,
+ void *priv)
+{
+ int ret;
+
+ buf->index = bm->bc.buf_num;
+
+ if (bm->config.enable_extbuf) {
+ aml_buf_set_planes_v4l2(bm, buf, priv);
+
+ ret = aml_uvm_buff_attach(buf->vb);
+ if (ret) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "uvm buffer attach failed.\n");
+ return ret;
+ }
+ } else {
+ // alloc buffer
+ aml_buf_set_planes(bm, buf);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+ ret = aml_buf_vpp_mgr_init(bm);
+ if (ret) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "VPP buf mgr init failed.\n");
+ return ret;
+ }
+#endif
+
+ ret = task_chain_init(&buf->task, bm->priv, buf, buf->index);
+ if (ret) {
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+ "task chain init failed.\n");
+ }
+
+ return ret;
+}
+
+static int aml_buf_alloc(struct buf_core_mgr_s *bc,
+ struct buf_core_entry **entry,
+ void *priv)
+{
+ int ret;
+ struct aml_buf *buf;
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+
+ buf = vzalloc(sizeof(struct aml_buf));
+ if (buf == NULL) {
+ return -ENOMEM;
+ }
+
+ /* afbc init. */
+ if (bm->config.enable_fbc) {
+ ret = aml_buf_fbc_init(bm, buf);
+ if (ret) {
+ goto err1;
+ }
+ }
+
+ ret = aml_buf_set_default_parms(bm, buf, priv);
+ if (ret) {
+ goto err2;
+ }
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, entry:%px, free:%d\n",
+ __func__,
+ &buf->entry,
+ bc->free_num);
+
+ kref_get(&bm->ref);
+
+ *entry = &buf->entry;
+
+ return 0;
+
+err2:
+ aml_buf_fbc_destroy(bm);
+err1:
+ vfree(buf);
+
+ return ret;
+}
+
+static void aml_buf_free(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ int i;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, entry:%px, user:%d, key:%lx, idx:%d, st:(%d, %d), ref:(%d, %d)\n",
+ __func__,
+ entry,
+ entry->user,
+ entry->key,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref));
+
+ /* afbc free */
+ if (buf->fbc) {
+ aml_buf_fbc_release(bm, buf);
+ }
+
+ /* task chain clean */
+ task_chain_clean(buf->task);
+ /* task chain release */
+ task_chain_release(buf->task);
+
+ /* free triple write buffer. */
+ if (bm->config.tw_mode &&
+ (bm->config.dw_mode != DM_AVBC_ONLY)) {
+ for (i = 0 ; i < buf->num_planes ; i++) {
+ if (buf->planes_tw[i].addr)
+ codec_mm_free_for_dma("tw_buf", buf->planes_tw[i].addr);
+ }
+ }
+
+ kref_put(&bm->ref, aml_buf_mgr_destroy);
+
+ if (buf->vpp_buf)
+ vfree(buf->vpp_buf);
+
+ if (buf->ge2d_buf)
+ vfree(buf->ge2d_buf);
+
+ vfree(buf);
+}
+
+static void aml_buf_configure(struct buf_core_mgr_s *bc, void *cfg)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+
+ bm->config = *(struct aml_buf_config *)cfg;
+}
+
+static void aml_external_process(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ struct aml_buf *aml_buf = entry_to_aml_buf(entry);
+ struct aml_buf_mgr_s *bm =
+ container_of(bc, struct aml_buf_mgr_s, bc);
+
+ aml_vdec_recycle_dec_resource(bm->priv, aml_buf);
+}
+
+static void aml_buf_prepare(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ struct aml_buf_fbc_info fbc_info = { 0 };
+ struct aml_buf *sub_buf[2];
+ struct buf_core_entry *sub_entry;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->index,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ if (entry->sub_entry[0]) {
+ sub_entry = (struct buf_core_entry *)entry->sub_entry[0];
+ sub_buf[0] = (struct aml_buf *)buf->sub_buf[0];
+ }
+
+ if (entry->sub_entry[1]) {
+ sub_entry = (struct buf_core_entry *)entry->sub_entry[1];
+ sub_buf[1] = (struct aml_buf *)buf->sub_buf[1];
+ }
+
+ if (entry->user != BUF_USER_MAX && !task_chain_empty(buf->task)) {
+ task_chain_clean(buf->task);
+ if (entry->sub_entry[0])
+ task_chain_clean(sub_buf[0]->task);
+ if (entry->sub_entry[1])
+ task_chain_clean(sub_buf[1]->task);
+ }
+
+ if (bm->config.enable_fbc)
+ bm->get_fbc_info(bm, &fbc_info);
+
+ if (buf->fbc &&
+ ((fbc_info.frame_size != buf->fbc->frame_size) ||
+ (fbc_info.header_size != buf->fbc->hsize) ||
+ !bm->config.enable_fbc)) {
+ aml_buf_fbc_release(bm, buf);
+ }
+
+ if (bm->config.enable_fbc &&
+ !buf->fbc) {
+ aml_buf_fbc_init(bm, buf);
+ }
+
+ if (bm->config.enable_extbuf) {
+ aml_buf_set_planes_v4l2(bm, buf, entry->vb2);
+ } else {
+ aml_buf_set_planes(bm, buf);
+ }
+
+ if (entry->user != BUF_USER_MAX) {
+ aml_creat_pipeline(bm->priv, buf, entry->user);
+ if (entry->sub_entry[0])
+ aml_creat_pipeline(bm->priv, sub_buf[0], entry->user);
+ if (entry->sub_entry[1])
+ aml_creat_pipeline(bm->priv, sub_buf[1], entry->user);
+ }
+}
+
+static int aml_buf_output(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ struct aml_buf *master_buf;
+ struct buf_core_entry *master_entry;
+ int i;
+
+ if (task_chain_empty(buf->task))
+ return -1;
+
+ if (entry->pair != BUF_MASTER) {
+ master_entry = (struct buf_core_entry *)entry->master_entry;
+ master_buf = entry_to_aml_buf(master_entry);
+
+ for (i = 0; i < buf->num_planes; i++) {
+ buf->planes[i].bytes_used = master_buf->planes[i].bytes_used;
+ }
+ }
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ return buf->task->submit(buf->task, user_to_task(user));
+}
+
+static void aml_buf_input(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+
+ if (task_chain_empty(buf->task))
+ return;
+
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+
+ buf->task->recycle(buf->task, user_to_task(user));
+}
+
+static int aml_buf_get_pre_user(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ //struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ int type;
+
+ if (task_chain_empty(buf->task))
+ return BUF_USER_MAX;
+#if 0
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+#endif
+ type = buf->task->get_pre_user(buf->task, user_to_task(user));
+
+ return task_to_user(type);
+}
+
+static int aml_buf_get_next_user(struct buf_core_mgr_s *bc,
+ struct buf_core_entry *entry,
+ enum buf_core_user user)
+{
+ //struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+ struct aml_buf *buf = entry_to_aml_buf(entry);
+ int type;
+
+ if (task_chain_empty(buf->task))
+ return BUF_USER_MAX;
+#if 0
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+ __func__,
+ entry->user,
+ entry->key,
+ entry->state,
+ bc->state,
+ atomic_read(&entry->ref),
+ kref_read(&bc->core_ref),
+ bc->free_num);
+#endif
+ type = buf->task->get_next_user(buf->task, user_to_task(user));
+
+ return task_to_user(type);
+}
+
+int aml_buf_mgr_init(struct aml_buf_mgr_s *bm, char *name, int id, void *priv)
+{
+ int ret = -1;
+
+ bm->bc.id = id;
+ bm->bc.name = name;
+ bm->priv = priv;
+ bm->get_fbc_info = aml_buf_get_fbc_info;
+
+ bm->bc.config = aml_buf_configure;
+ bm->bc.prepare = aml_buf_prepare;
+ bm->bc.input = aml_buf_input;
+ bm->bc.output = aml_buf_output;
+ bm->bc.get_pre_user = aml_buf_get_pre_user;
+ bm->bc.get_next_user = aml_buf_get_next_user;
+ bm->bc.external_process = aml_external_process;
+ bm->bc.mem_ops.alloc = aml_buf_alloc;
+ bm->bc.mem_ops.free = aml_buf_free;
+
+ kref_init(&bm->ref);
+
+ ret = buf_core_mgr_init(&bm->bc);
+ if (ret) {
+ v4l_dbg(priv, V4L_DEBUG_CODEC_ERROR,
+ "%s, init fail.\n", __func__);
+ } else {
+ v4l_dbg(priv, V4L_DEBUG_CODEC_BUFMGR,
+ "%s\n", __func__);
+ }
+
+ return ret;
+}
+
+void aml_buf_mgr_release(struct aml_buf_mgr_s *bm)
+{
+ v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+ kref_put(&bm->ref, aml_buf_mgr_destroy);
+ buf_core_mgr_release(&bm->bc);
+}
+
diff --git a/drivers/amvdec_ports/aml_buf_mgr.h b/drivers/amvdec_ports/aml_buf_mgr.h
new file mode 100644
index 0000000..458c2b9
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_mgr.h
@@ -0,0 +1,297 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef _AML_DEC_BUFMGR_H_
+#define _AML_DEC_BUFMGR_H_
+
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "aml_buf_core.h"
+
+#define BUF_FBC_NUM_MAX (64)
+#define BUF_MAX_PLANES (3)
+
+/* VPP work mode. */
+#define VPP_WORK_MODE_DI_M2M (0)
+#define VPP_WORK_MODE_DI_POST (1)
+
+struct aml_buf_mgr_s;
+
+/*
+ * struct aml_buf_config - Parameter configuration structure.
+ *
+ * @enable_extbuf : Configure the external buffer mode.
+ * @buf_size : The size of buffer that should be allocated.
+ * @enable_fbc : Enables the AFBC feature.
+ * @enable_secure : Indicates the secure mode.
+ * @memory_mode : memory mode used by v4l2 vb queue.
+ * @vpp_work_mode : 0: used DI m2m interface, 1: DI post process mode.
+ * @planes : The number of planes used.
+ * @luma_length : The size of the image brightness data.
+ * @chroma_length : The size of the image chroma data.
+ */
+struct aml_buf_config {
+ bool enable_extbuf;
+ bool enable_fbc;
+ bool enable_secure;
+ int memory_mode;
+ int planes;
+ u32 luma_length;
+ u32 chroma_length;
+ u32 luma_length_tw;
+ u32 chroma_length_tw;
+ u32 dw_mode;
+ u32 tw_mode;
+};
+
+/*
+ * struct aml_buf_plane - Buffer plane information.
+ *
+ * @dbuf : The address of dmabuf.
+ * @addr : Indicates the associated physical address.
+ * @vaddr : Indicates the virtual address associated with plane.
+ * @length : The actual size of the buffer.
+ * @bytes_used : The size of the buffer to be used.
+ * @offset : The offset position used by buffer.
+ * @stride : The size of each line of image data.
+ * @uvm_fd : The file handle of UVM buffer.
+ */
+struct aml_buf_plane {
+ struct dma_buf *dbuf;
+ ulong addr;
+ void *vaddr;
+ u32 length;
+ u32 bytes_used;
+ u32 offset;
+ int stride;
+ int uvm_fd;
+};
+
+/*
+ * struct aml_buf_fbc_info - AFBC buffer size information.
+ *
+ * @max_size : Max size needed for mmu box.
+ * @header_size : Continuous size for the compressed header.
+ * @frame_size : SG page number to store the frame.
+ */
+struct aml_buf_fbc_info {
+ u32 max_size;
+ u32 header_size;
+ u32 frame_size;
+};
+
+typedef void (*get_fbc_info)(struct aml_buf_mgr_s *,
+ struct aml_buf_fbc_info *);
+
+/*
+ * struct aml_buf_fbc - AFBC buffer information.
+ *
+ * @index : The serial number of the buffer.
+ * @bmmu : The context of bmmu box.
+ * @mmu : The context of mmu box.
+ * @ref : Reference count of AFBC buffer.
+ * @haddr : The address of header data.
+ * @hsize : The size of header data.
+ * @frame_size : the size of AFBC data per frame.
+ * @used: bit[0]: 0, idle; 1, decoder alloc from mmu
+ * bit[1]: 0, idle; 1, decoder alloc from mmu_dw.
+ */
+struct aml_buf_fbc {
+ u32 index;
+ void *bmmu;
+ void *mmu;
+ void *bmmu_dw;
+ void *mmu_dw;
+ int ref;
+ ulong haddr;
+ u32 hsize;
+ ulong haddr_dw;
+ u32 hsize_dw;
+ u32 frame_size;
+#ifdef NEW_FB_CODE
+ void *mmu_1;
+ void *mmu_dw_1;
+#endif
+ int used[BUF_FBC_NUM_MAX];
+};
+
+/*
+ * struct aml_buf - aml_buf structure.
+ *
+ * @index : The serial number of the buffer.
+ * @state : Indicates the usage status of the aml_buf.
+ * @num_planes : The number of planes used.
+ * @planes : Buffer plane information.
+ * @planes_tw : Used for another buffer planes storage.
+ * @fbc : AFBC buffer information.
+ * @entry : Buffer entity embedded in aml_buf.
+ * @task : The context of task chain.
+ * @vframe : The video frame struct.
+ * @vb : The vb2 struct defined by v4l2.
+ * @meta_ptr : The handle of meta date.
+ * @flush_flag : Mark the buffer flush at the first time to alloc.
+ * @is_delay_allocated : Dma buffer allocated and replaced.
+ * @cap_sgt : Point to new capture buffer sg table.
+ * @idmabuf[2] : Delayed allocated dma buffer.
+ * @uvm_buf : Uvm buf.
+ * @master_buf : The first filed buf entry.
+ * @sub_buf[2] : sub_buf[0]: The second filed buf entry;
+ * sub_buf[1]: The third filed buf entry;
+ * @pair : Buf attributes: master, sub0, sub1.
+ * @pair_state : Buffer pairing status.
+ * @inited : The pairing is completed and enters the free queue.
+ * @queued_mask : Field buffer return times.
+ */
+struct aml_buf {
+ u32 index;
+ int state;
+ u32 num_planes;
+ u64 timestamp;
+ struct aml_buf_plane planes[BUF_MAX_PLANES];
+ struct aml_buf_plane planes_tw[BUF_MAX_PLANES];
+ struct aml_buf_fbc *fbc;
+ struct buf_core_entry entry;
+
+ struct task_chain_s *task;
+ struct vframe_s vframe;
+ struct vb2_buffer *vb;
+ ulong meta_ptr;
+ void *vpp_buf;
+ void *ge2d_buf;
+ bool flush_flag;
+ bool is_delay_allocated;
+ struct sg_table *cap_sgt;
+ struct dma_buf *idmabuf[2];
+ void *uvm_buf;
+ void *master_buf;
+ void *sub_buf[2];
+ enum buf_pair pair;
+ u32 pair_state;
+ u32 inited;
+ u32 queued_mask;
+};
+
+/*
+ * struct aml_buf_mgr_s - aml_buf manager context.
+ *
+ * @bc : The buffer core manager context.
+ * @ref : The reference count of buffer manager.
+ * @priv : Records the context of the caller.
+ * @config : Parameter configuration structure.
+ * @bmmu : The context of bmmu box.
+ * @mmu : The context of mmu box.
+ * @fbc_array : AFBC buffer array data.
+ * @get_fbc_info : Used to get AFBC data size information.
+ * @vpp_handle : The handle of DI post mode.
+ */
+struct aml_buf_mgr_s {
+ struct buf_core_mgr_s bc;
+ struct kref ref;
+ void *priv;
+
+ struct aml_buf_config config;
+
+ /* fbc information */
+ void *bmmu;
+ void *mmu;
+ void *bmmu_dw;
+ void *mmu_dw;
+#ifdef NEW_FB_CODE
+ void *mmu_1;
+ void *mmu_dw_1;
+#endif
+ struct aml_buf_fbc *fbc_array;
+ get_fbc_info get_fbc_info;
+
+ void *vpp_handle;
+ u32 frm_cnt;
+ int vpp_work_mode;
+};
+
+/*
+ * bc_to_bm() - Used for BC to BM.
+ *
+ * @bc : Pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * It is easy to convert BC to BM.
+ *
+ * Return : returns bm context.
+ */
+static inline struct aml_buf_mgr_s *bc_to_bm(struct buf_core_mgr_s *bc)
+{
+ return container_of(bc, struct aml_buf_mgr_s, bc);
+}
+
+/*
+ * entry_to_aml_buf() - Used for entry to aml_buf.
+ *
+ * @bc : Pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * It is easy to convert entry to aml_buf.
+ *
+ * Return : returns aml_buf
+ */
+static inline struct aml_buf *entry_to_aml_buf(void *entry)
+{
+ return container_of(entry, struct aml_buf, entry);
+}
+
+/*
+ * aml_buf_set_vframe() - Copy the contents of vf into ambuf.
+ *
+ * @ambuf : The struct of aml_buf.
+ * @vf : The struct of vframe.
+ *
+ * Used to associate vframe within aml_buf.
+ */
+static inline void aml_buf_set_vframe(struct aml_buf *ambuf, struct vframe_s *vf)
+{
+ ambuf->vframe = *vf;
+}
+
+/*
+ * aml_buf_mgr_init() - buffer core management initialization.
+ *
+ * @bm : Pointer to &struct aml_buf_mgr_s buffer manager context.
+ * @name : The name of buffer manager.
+ * @id : The instance ID of buffer manager.
+ * @priv : The private date from caller.
+ *
+ * Used to initialize the buffer manager context.
+ *
+ * Return : returns zero on success; an error code otherwise
+ */
+int aml_buf_mgr_init(struct aml_buf_mgr_s *bm, char *name, int id, void *priv);
+
+/*
+ * aml_buf_mgr_release() - buffer core management initialization.
+ *
+ * @bm : pointer to &struct buf_core_mgr_s buffer manager context.
+ *
+ * Used to initialize the buffer manager context.
+ */
+void aml_buf_mgr_release(struct aml_buf_mgr_s *bm);
+
+#endif //_AML_DEC_BUFMGR_H_
+
diff --git a/drivers/amvdec_ports/aml_task_chain.c b/drivers/amvdec_ports/aml_task_chain.c
index 8dfe014..7450d8e 100644
--- a/drivers/amvdec_ports/aml_task_chain.c
+++ b/drivers/amvdec_ports/aml_task_chain.c
@@ -1,23 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -53,6 +52,19 @@
return name;
}
+static enum task_type_e name_to_type(const u8 *name)
+{
+ enum task_type_e type;
+ int i, size = ARRAY_SIZE(iname);
+
+ for (i = 0; i < size; i++) {
+ if (name == iname[i].name)
+ type = iname[i].type;
+ }
+
+ return type;
+}
+
static struct task_item_s *find_task_item(struct task_chain_s *task,
enum task_type_e type)
{
@@ -87,8 +99,8 @@
int i = 0;
for (i = 0 ; i < 3; i++) {
- if (item->vframe[i] == NULL) {
- item->vframe[i] = vframe;
+ if (item->vframe[i].index == -1) {
+ memcpy(&item->vframe[i], vframe, sizeof(struct vframe_s));
break;
}
}
@@ -96,18 +108,32 @@
static struct vframe_s *task_item_vframe_pop(struct task_item_s *item)
{
- struct vframe_s *vframe = NULL;
int i = 0;
for (i = 0 ; i < 3; i++) {
- if (item->vframe[i] != NULL) {
- vframe = item->vframe[i];
- item->vframe[i] = NULL;
+ if (item->vframe[i].index != -1) {
break;
}
}
- return vframe;
+ if (i >= 3) {
+ pr_info("[ERR] vframe pop fail!\n");
+ }
+
+ return &item->vframe[i];
+}
+
+static void task_item_vframe_reset(struct task_item_s *item,
+ struct vframe_s * vf)
+{
+ int i = 0;
+
+ for (i = 0 ; i < 3; i++) {
+ if (vf == &item->vframe[i]) {
+ item->vframe[i].index = -1;
+ break;
+ }
+ }
}
static struct task_item_s *task_item_get(struct task_chain_s *task,
@@ -116,10 +142,6 @@
struct task_item_s *item = NULL;
item = find_task_item(task, type);
- if (!item) {
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
- "TSK(%px):%d get item:%d fail.\n", task, task->id, type);
- }
return item;
}
@@ -129,44 +151,61 @@
return kref_put(&item->ref, task_item_release);
}
-static void task_buffer_submit(struct task_chain_s *task,
+static int task_buffer_submit(struct task_chain_s *task,
enum task_type_e type)
{
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
+ struct aml_buf *aml_buf =
+ (struct aml_buf *)task->obj;
struct task_item_s *item = NULL;
struct task_item_s *item2 = NULL;
- struct vframe_s *vf = NULL;
+ int ret = 0;
+
+ memset(task->vf_tmp, 0, sizeof(struct vframe_s));
item = task_item_get(task, type);
if (item) {
- item->ops->get_vframe(item->caller, &vf);
- fb->vframe = (void *)vf;
- task_item_vframe_push(item, vf);
+ item->ops->get_vframe(item->caller, task->vf_tmp);
+ memcpy(&aml_buf->vframe, task->vf_tmp, sizeof(struct vframe_s));
+ task_item_vframe_push(item, &aml_buf->vframe);
item->is_active = false;
item2 = task_item_get(task, task->map[0][type]);
if (item2) {
item2->is_active = true;
- item2->ops->fill_buffer(task->ctx, fb);
+
+ item2->ops->fill_buffer(task->ctx, aml_buf);
v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d, vf:%px, phy:%lx, submit %d => %d.\n",
- task, task->id, vf, fb->m.mem[0].addr,
+ "TSK(%px):%d, vf idx:0x%x, phy:%lx, submit %d => %d.\n",
+ task, task->id, task->vf_tmp->index, aml_buf->planes[0].addr,
type, task->map[0][type]);
task->direction = TASK_DIR_SUBMIT;
+
task_item_put(item2);
+
+ ret = 0;
+ } else {
+ v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+ "TSK(%px):%d get item:%d fail.\n", task, task->id, type);
+ ret = -1;
}
task_item_put(item);
+
+ } else {
+ v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+ "TSK(%px):%d get item:%d fail.\n", task, task->id, type);
+ ret = -1;
}
+
+ return ret;
}
static void task_buffer_recycle(struct task_chain_s *task,
enum task_type_e type)
{
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
+ struct aml_buf *aml_buf =
+ (struct aml_buf *)task->obj;
struct task_item_s *item = NULL;
struct task_item_s *item2 = NULL;
@@ -181,13 +220,15 @@
item2->is_active = true;
vf = task_item_vframe_pop(item2);
+ memcpy(vf, &aml_buf->vframe, sizeof(struct vframe_s));
item2->ops->put_vframe(item2->caller, vf);
v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d, vf:%px, phy:%lx, recycle %d => %d.\n",
- task, task->id, vf, fb->m.mem[0].addr,
+ "TSK(%px):%d, vf idx:%d, phy:%lx, recycle %d => %d.\n",
+ task, task->id, vf->index, aml_buf->planes[0].addr,
type, task->map[1][type]);
+ task_item_vframe_reset(item2, vf);
task->direction = TASK_DIR_RECYCLE;
task_item_put(item2);
}
@@ -195,38 +236,82 @@
}
}
-void task_chain_show(struct task_chain_s *task)
+static enum task_type_e task_buffer_get_pre_user(struct task_chain_s *task,
+ enum task_type_e type)
{
struct task_item_s *item = NULL;
- char buf[128] = {0};
+ struct task_item_s *item2 = NULL;
+ enum task_type_e type2 = TASK_TYPE_MAX;
+
+ item = task_item_get(task, type);
+ if (item) {
+ item2 = task_item_get(task, task->map[1][type]);
+
+ if (item2) {
+ type2 = name_to_type(item2->name);
+ task_item_put(item2);
+ }
+ task_item_put(item);
+ }
+
+ return type2;
+}
+
+static enum task_type_e task_buffer_get_next_user(struct task_chain_s *task,
+ enum task_type_e type)
+{
+ struct task_item_s *item = NULL;
+ struct task_item_s *item2 = NULL;
+ enum task_type_e type2 = TASK_TYPE_MAX;
+
+ item = task_item_get(task, type);
+ if (item) {
+ item2 = task_item_get(task, task->map[0][type]);
+
+ if (item2) {
+ type2 = name_to_type(item2->name);
+ task_item_put(item2);
+ }
+ task_item_put(item);
+ }
+
+ return type2;
+}
+
+ssize_t task_chain_show(struct task_chain_s *task, char *buf)
+{
+ struct task_item_s *item = NULL;
+ char tempbuf[128] = {0};
+ char *ptbuf = tempbuf;
char *pbuf = buf;
ulong flags;
if (!task || !task->ctx)
- return;
+ return 0;
spin_lock_irqsave(&task->slock, flags);
if (!list_empty(&task->list_item)) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
+ struct aml_buf *aml_buf =
+ (struct aml_buf *)task->obj;
list_for_each_entry(item, &task->list_item, node) {
- pbuf += sprintf(pbuf, "%s(%d)",
+ ptbuf += sprintf(ptbuf, "%s(%d)",
item->name, item->is_active);
if (item->node.next != &task->list_item) {
if (task->direction == TASK_DIR_SUBMIT)
- pbuf += sprintf(pbuf, " ==> ");
+ ptbuf += sprintf(ptbuf, " ==> ");
else
- pbuf += sprintf(pbuf, " <== ");
+ ptbuf += sprintf(ptbuf, " <== ");
}
}
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_PRINFO,
- "vb:%2d, phy:%lx %s\n",
- task->id, fb->m.mem[0].addr, buf);
+ pbuf += sprintf(pbuf, "vb:%2d, phy:%lx %s\n",
+ task->id, aml_buf->planes[0].addr, tempbuf);
}
spin_unlock_irqrestore(&task->slock, flags);
+
+ return pbuf - buf;
}
EXPORT_SYMBOL(task_chain_show);
@@ -238,6 +323,7 @@
task->cur_type = TASK_TYPE_MAX;
memset(task->map, 0, sizeof(task->map));
+ kfree(task->vf_tmp);
v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
"TSK(%px):%d task chain destroyed.\n", task, task->id);
@@ -261,6 +347,12 @@
kfree(item);
}
+bool task_chain_empty(struct task_chain_s *task)
+{
+ return task->cur_type == TASK_TYPE_MAX ? true : false;
+}
+EXPORT_SYMBOL(task_chain_empty);
+
void task_chain_clean(struct task_chain_s *task)
{
struct task_item_s *item, *tmp;
@@ -289,8 +381,9 @@
void *caller)
{
struct task_item_s *item;
+ int i;
- item = kzalloc(sizeof(struct task_item_s), GFP_ATOMIC);
+ item = kzalloc(sizeof(struct task_item_s), GFP_KERNEL);
if (!item) {
v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
"TSK(%px):%d alloc item fail.\n", task, task->id);
@@ -302,6 +395,9 @@
item->caller = caller;
item->name = type_to_name(ops->type);
kref_init(&item->ref);
+ for (i = 0 ; i < 3; i++) {
+ item->vframe[i].index = -1;
+ }
task->map[0][ops->type] = task->cur_type;
task->map[1][task->cur_type] = ops->type;
@@ -337,16 +433,25 @@
{
struct task_chain_s *task;
- task = kzalloc(sizeof(struct task_chain_s), GFP_ATOMIC);
+ task = kzalloc(sizeof(struct task_chain_s), GFP_KERNEL);
if (!task) {
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
- "TSK(%px):%d alloc task fail.\n", task, task->id);
+ v4l_dbg(v4l_ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s alloc task %d fail.\n", __func__, vb_idx);
return -ENOMEM;
}
task->id = vb_idx;
task->obj = obj;
task->ctx = v4l_ctx;
+ task->cur_type = TASK_TYPE_MAX;
+
+ task->vf_tmp = kzalloc(sizeof(struct vframe_s), GFP_KERNEL);
+ if (!task->vf_tmp) {
+ v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s alloc failed!\n", __func__);
+ kfree(task);
+ return -ENOMEM;
+ }
kref_init(&task->ref);
spin_lock_init(&task->slock);
INIT_LIST_HEAD(&task->list_item);
@@ -354,6 +459,8 @@
task->attach = task_order_attach;
task->submit = task_buffer_submit;
task->recycle = task_buffer_recycle;
+ task->get_pre_user = task_buffer_get_pre_user;
+ task->get_next_user = task_buffer_get_next_user;
*task_out = task;
diff --git a/drivers/amvdec_ports/aml_task_chain.h b/drivers/amvdec_ports/aml_task_chain.h
index fdbe2fb..16e658a 100644
--- a/drivers/amvdec_ports/aml_task_chain.h
+++ b/drivers/amvdec_ports/aml_task_chain.h
@@ -1,23 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AML_TASK_CHAIN_H
#define AML_TASK_CHAIN_H
@@ -48,7 +47,7 @@
*/
struct task_ops_s {
enum task_type_e type;
- void (*get_vframe) (void *caller, struct vframe_s **vf);
+ void (*get_vframe) (void *caller, struct vframe_s *vf);
void (*put_vframe) (void *caller, struct vframe_s *vf);
void (*fill_buffer) (void *v4l_ctx, void *fb_ctx);
};
@@ -69,7 +68,7 @@
struct kref ref;
const u8 *name;
bool is_active;
- void *vframe[3];
+ struct vframe_s vframe[3];
struct task_chain_s *task;
void *caller;
struct task_ops_s *ops;
@@ -95,6 +94,7 @@
struct list_head list_item;
struct list_head node;
struct kref ref;
+ struct vframe_s *vf_tmp;
spinlock_t slock;
int id;
void *ctx;
@@ -104,8 +104,10 @@
u8 map[2][8];
void (*attach) (struct task_chain_s *, struct task_ops_s *, void *);
- void (*submit) (struct task_chain_s *, enum task_type_e);
+ int (*submit) (struct task_chain_s *, enum task_type_e);
void (*recycle) (struct task_chain_s *, enum task_type_e);
+ enum task_type_e (*get_pre_user) (struct task_chain_s *, enum task_type_e);
+ enum task_type_e (*get_next_user) (struct task_chain_s *, enum task_type_e);
};
@@ -118,8 +120,9 @@
void *caller);
void task_chain_clean(struct task_chain_s *task);
void task_chain_release(struct task_chain_s *task);
-void task_chain_show(struct task_chain_s *task);
+ssize_t task_chain_show(struct task_chain_s *task, char *buf);
void task_chain_update_object(struct task_chain_s *task, void *obj);
+bool task_chain_empty(struct task_chain_s *task);
#endif //AML_TASK_CHAIN_H
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index 7e08371..87ad57a 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -1,23 +1,24 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/types.h>
+#include <media/v4l2-mem2mem.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/media/utils/aformat.h>
@@ -34,14 +35,14 @@
#include "../stream_input/amports/adec.h"
#include "../stream_input/amports/streambuf.h"
#include "../stream_input/amports/streambuf_reg.h"
-#include "../stream_input/parser/tsdemux.h"
-#include "../stream_input/parser/psparser.h"
-#include "../stream_input/parser/esparser.h"
#include "../frame_provider/decoder/utils/vdec.h"
#include "../common/media_clock/switch/amports_gate.h"
+#include "../stream_input/parser/stream_parser.h"
#include <linux/delay.h>
#include "aml_vcodec_adapt.h"
+#include "aml_vcodec_ts.h"
#include <linux/crc32.h>
+#include "../common/media_utils/media_utils.h"
#define DEFAULT_VIDEO_BUFFER_SIZE (1024 * 1024 * 3)
#define DEFAULT_VIDEO_BUFFER_SIZE_4K (1024 * 1024 * 6)
@@ -54,8 +55,9 @@
#define SYNC_OUTSIDE (2)
//#define DATA_DEBUG
-
+extern int dump_es_output_frame;
extern int dump_output_frame;
+extern char dump_path[32];
extern u32 dump_output_start_position;
extern void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle);
@@ -200,14 +202,7 @@
return -EPERM;
}
- if ((vdec->sys_info->height * vdec->sys_info->width) > 1920 * 1088
- || port->vformat == VFORMAT_H264_4K2K) {
- port->is_4k = true;
- if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
- && (port->vformat == VFORMAT_H264))
- vdec_poweron(VDEC_HEVC);
- } else
- port->is_4k = false;
+ port->is_4k = false;
if (port->type & PORT_TYPE_FRAME ||
(port->type & PORT_TYPE_ES)) {
@@ -237,9 +232,6 @@
tsdemux_release();
}
- if (port->type & PORT_TYPE_MPPS)
- psparser_release();
-
if (port->type & PORT_TYPE_VIDEO)
video_component_release(port);
@@ -249,7 +241,7 @@
return 0;
}
-static void set_vdec_properity(struct vdec_s *vdec,
+static void set_vdec_property(struct vdec_s *vdec,
struct aml_vdec_adapt *ada_ctx)
{
vdec->sys_info = &ada_ctx->dec_prop;
@@ -273,18 +265,19 @@
vdec->port->type |= PORT_TYPE_FRAME;
vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD;
- if (aml_set_vdec_type_enable) {
- if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) {
- vdec->type = VDEC_TYPE_STREAM_PARSER;
- vdec->port->type &= ~PORT_TYPE_FRAME;
- vdec->port->type |= PORT_TYPE_ES;
- } else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
- vdec->type = VDEC_TYPE_FRAME_BLOCK;
- vdec->port->type &= ~PORT_TYPE_ES;
- vdec->port->type |= PORT_TYPE_FRAME;
- }
+ if (ada_ctx->ctx->stream_mode) {
+ vdec->type = VDEC_TYPE_STREAM_PARSER;
+ vdec->port->type &= ~PORT_TYPE_FRAME;
+ vdec->port->type |= PORT_TYPE_ES;
+ } else {
+ vdec->type = VDEC_TYPE_FRAME_BLOCK;
+ vdec->port->type &= ~PORT_TYPE_ES;
+ vdec->port->type |= PORT_TYPE_FRAME;
}
+ if (vdec->format == VFORMAT_VC1)
+ vdec->type = VDEC_TYPE_SINGLE;
+
if (aml_set_vfm_enable)
vdec->frame_base_video_path = aml_set_vfm_path;
@@ -309,7 +302,7 @@
return -1;
vdec->disable_vfm = true;
- set_vdec_properity(vdec, ada_ctx);
+ set_vdec_property(vdec, ada_ctx);
/* init hw and gate*/
ret = enable_hardware(vdec->port);
@@ -329,7 +322,17 @@
vdec->port->vformat == VFORMAT_VP9)
pvbuf = &bufs[BUF_TYPE_HEVC];
}
+ if (vdec_stream_based(vdec)) {
+ struct parser_args pars;
+ struct stream_buf_ops *ops = get_stbuf_ops();
+ ret = stream_buffer_base_init(&vdec->vbuf, ops, &pars);
+ if (ret) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "stream buffer base init failed\n");
+ return ret;
+ }
+ }
ret = video_component_init(vdec->port, pvbuf);
if (ret < 0) {
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "video_component_init failed\n");
@@ -337,7 +340,7 @@
}
/* connect vdec at the end after all HW initialization */
- vdec_connect(vdec);
+ aml_codec_connect(ada_ctx);
}
return 0;
@@ -385,11 +388,11 @@
{
struct file *fp;
- fp = filp_open(path,
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+ fp = media_open(path,
+ O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0666);
if (!IS_ERR(fp)) {
- kernel_write(fp, data, size, 0);
- filp_close(fp, NULL);
+ media_write(fp, data, size, 0);
+ media_close(fp, NULL);
} else {
pr_info("Dump ES fail, should check RW permission, size:%x\n", size);
}
@@ -444,12 +447,17 @@
bool vdec_input_full(struct aml_vdec_adapt *ada_ctx)
{
struct vdec_s *vdec = ada_ctx->vdec;
+ struct aml_vcodec_ctx *ctx = ada_ctx->ctx;
- return (vdec->input.have_frame_num > 60) ? true : false;
+ /* The driver ignores the stream ctrl if in stream mode. */
+ if (vdec_stream_based(vdec))
+ return false;
+
+ return (vdec->input.have_frame_num > ctx->cache_input_buffer_num) ? true : false;
}
-int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
- const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr)
+int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, const char *buf,
+ unsigned int count, u64 timestamp, ulong meta_ptr, chunk_free free)
{
int ret = -1;
struct vdec_s *vdec = ada_ctx->vdec;
@@ -460,7 +468,7 @@
/* set metadata */
vdec_set_metadata(vdec, meta_ptr);
- ret = vdec_write_vframe(vdec, buf, count);
+ ret = vdec_write_vframe(vdec, buf, count, free, ada_ctx->ctx);
if (slow_input) {
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
@@ -471,14 +479,20 @@
if (dump_output_frame > 0 &&
(!dump_output_start_position ||
(dump_output_start_position == crc32_le(0, buf, count)))) {
- dump("/data/es.data", buf, count);
+ char file_name[64] = {0};
+
+ snprintf(file_name, 64, "%s/es.data", dump_path);
+ dump(file_name, buf, count);
dump_output_frame--;
dump_output_start_position = 0;
}
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
- "write frames, vbuf: %p, size: %u, ret: %d, crc: %x, ts: %llu\n",
- buf, count, ret, crc32_le(0, buf, count), timestamp);
+ "write frames[%d], vbuf: %p, size: %u, ret: %d, crc: %x, ts: %llu\n",
+ ada_ctx->ctx->write_frames, buf, count, ret,
+ crc32_le(0, buf, count), timestamp);
+
+ ada_ctx->ctx->write_frames++;
return ret;
}
@@ -487,7 +501,11 @@
{
struct aml_vcodec_ctx *ctx = priv;
- aml_recycle_dma_buffers(ctx, handle);
+ if (ctx->output_dma_mode)
+ aml_recycle_dma_buffers(ctx, handle);
+
+ if (!vdec_input_full(ctx->ada_ctx))
+ v4l2_m2m_try_schedule(ctx->m2m_ctx);
}
int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx,
@@ -496,7 +514,6 @@
{
int ret = -1;
struct vdec_s *vdec = ada_ctx->vdec;
-
/* set timestamp */
vdec_set_timestamp(vdec, timestamp);
@@ -510,8 +527,10 @@
}
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
- "write frames, vbuf: %lx, size: %u, ret: %d, ts: %llu\n",
- addr, count, ret, timestamp);
+ "write frames[%d], vbuf: %lx, size: %u, ret: %d, ts: %llu\n",
+ ada_ctx->ctx->write_frames, addr, count, ret, timestamp);
+
+ ada_ctx->ctx->write_frames++;
return ret;
}
@@ -546,6 +565,26 @@
return ret;
}
+void aml_codec_disconnect(struct aml_vdec_adapt *ada_ctx)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+
+ if (vdec) {
+ vdec_disconnect(vdec);
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, "set vdec disconnect\n");
+ }
+}
+
+void aml_codec_connect(struct aml_vdec_adapt *ada_ctx)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+
+ if (vdec) {
+ vdec_connect(vdec);
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, "set vdec connect\n");
+ }
+}
+
bool is_input_ready(struct aml_vdec_adapt *ada_ctx)
{
struct vdec_s *vdec = ada_ctx->vdec;
@@ -572,11 +611,52 @@
return -1;
}
+void vdec_thread_wakeup(struct aml_vdec_adapt *ada_ctx)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+
+ if (vdec) {
+ vdec_up(vdec);
+ }
+}
+
+void vdec_set_dmabuf_type(struct aml_vdec_adapt *ada_ctx, bool dmabuf_type)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+
+ if (vdec) {
+ if (dmabuf_type)
+ vdec->port_flag |= PORT_FLAG_DMABUF;
+ else
+ vdec->port_flag &= ~PORT_FLAG_DMABUF;
+ }
+}
+
int vdec_get_instance_num(void)
{
return vdec_get_core_nr();
}
+bool vdec_check_is_available(u32 fmt)
+{
+ if ((fmt == V4L2_PIX_FMT_VC1_ANNEX_G) || (fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+ if (vdec_get_instance_num() != 0)
+ return false;
+ } else {
+ if (vdec_has_single_mode())
+ return false;
+ }
+
+ return true;
+}
+
+int vdec_get_vdec_id(struct aml_vdec_adapt *ada_ctx)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+
+ return vdec ? vdec->id : -1;
+}
+
void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
{
struct vdec_s *vdec = ada_ctx->vdec;
@@ -589,3 +669,132 @@
{
vdec_frame_rate_uevent(duration);
}
+
+void aml_vdec_recycle_dec_resource(struct aml_vcodec_ctx * ctx,
+ struct aml_buf *aml_buf)
+{
+ if (ctx->vdec_recycle_dec_resource)
+ ctx->vdec_recycle_dec_resource(ctx->ada_ctx->vdec->private, aml_buf);
+}
+
+void vdec_dump_strea_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size)
+{
+ char file_name[64] = {0};
+ ulong buf_start = ada_ctx->vdec->vbuf.buf_start;
+ ulong buf_end = ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size;
+ u32 first_size = size;
+ u32 second_size = 0;
+ void *stbuf_vaddr;
+
+ if ((addr +size) > buf_end) {
+ first_size = buf_end - addr;
+ second_size = size - first_size;
+ }
+
+ stbuf_vaddr = codec_mm_vmap(addr, first_size);
+ if (stbuf_vaddr) {
+ codec_mm_dma_flush(stbuf_vaddr, first_size, DMA_FROM_DEVICE);
+ snprintf(file_name, 64, "%s/es.data", dump_path);
+ dump(file_name, stbuf_vaddr, first_size);
+
+ codec_mm_unmap_phyaddr(stbuf_vaddr);
+ pr_info("dump es buffer (%x, %u)\n", addr, first_size);
+ } else {
+ pr_err("es buffer (%x, %u) vmap fail\n", addr, first_size);
+ }
+
+ if (second_size) {
+ stbuf_vaddr = codec_mm_vmap(buf_start, second_size);
+ if (stbuf_vaddr) {
+ codec_mm_dma_flush(stbuf_vaddr, second_size, DMA_FROM_DEVICE);
+ snprintf(file_name, 64, "%s/es.data", dump_path);
+ dump(file_name, stbuf_vaddr, second_size);
+
+ codec_mm_unmap_phyaddr(stbuf_vaddr);
+ pr_info("dump next part es buffer (%lx, %u)\n", buf_start, second_size);
+ } else {
+ pr_err("next part es buffer (%lx, %u) vmap fail\n", buf_start, second_size);
+ }
+ }
+}
+
+void vdec_write_stream_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size)
+{
+ struct stream_buffer_metainfo stbuf_data = { 0 };
+ stbuf_data.stbuf_pktaddr = addr;
+ stbuf_data.stbuf_pktsize = size;
+ stream_buffer_meta_write(&ada_ctx->vdec->vbuf, &stbuf_data);
+
+ if (dump_es_output_frame) {
+ vdec_dump_strea_data(ada_ctx, addr, size);
+ }
+}
+
+void vdec_write_stream_data_inner(struct aml_vdec_adapt *ada_ctx, char *addr,
+ u32 size, u64 timestamp)
+{
+ bool stbuf_around = false;
+ u32 around_size;
+
+ // calculate whether the remaining space is enougth
+ if ((ada_ctx->vdec->vbuf.buf_wp + size) >
+ (ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size)) {
+ stbuf_around = true;
+ around_size = (ada_ctx->vdec->vbuf.buf_wp + size) -
+ (ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size);
+ }
+
+ // if not enougth, write two times
+ if (!stbuf_around)
+ stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+ addr, size);
+ else {
+ stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+ addr, size - around_size);
+
+ stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+ addr + size - around_size, around_size);
+ }
+
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
+ "VC1 input: es(add data size %d) -> stbuf(addr 0x%lx wp 0x%x) timestamp: %llu\n",
+ size, ada_ctx->vdec->vbuf.buf_start, ada_ctx->vdec->vbuf.buf_wp, timestamp);
+}
+
+#if 0
+void v4l2_set_rp_addr(struct aml_vdec_adapt *ada_ctx, struct dma_buf *dbuf)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+ u32 rp_addr;
+ struct dmabuf_dmx_sec_es_data *es_data;
+
+ /* get rp addr from vdec */
+ rp_addr = STBUF_READ(&vdec->vbuf, get_rp);
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_OUTPUT, "stream rp_addr is %x\n",rp_addr);
+
+ if (dmabuf_manage_get_type(dbuf) != DMA_BUF_TYPE_DMX_ES) {
+ pr_err("current dmabuf type is not DMA_BUF_TYPE_DMX_ES\n");
+ return;
+ }
+
+ es_data = (struct dmabuf_dmx_sec_es_data *)dmabuf_manage_get_info(dbuf, DMA_BUF_TYPE_DMX_ES);
+
+ es_data->buf_rp = rp_addr;
+}
+#endif
+void v4l2_set_ext_buf_addr(struct aml_vdec_adapt *ada_ctx, struct dmabuf_dmx_sec_es_data *es_data, int offset)
+{
+ struct vdec_s *vdec = ada_ctx->vdec;
+ u32 buf_size = 0;
+
+ buf_size = es_data->buf_end - es_data->buf_start;
+ ada_ctx->ctx->es_mgr.buf_start = es_data->buf_start;
+ ada_ctx->ctx->es_mgr.buf_size = buf_size;
+
+ stream_buffer_set_ext_buf(&vdec->vbuf, es_data->buf_start, buf_size, ada_ctx->ctx->is_drm_mode);
+ vdec_init_stbuf_info(vdec);
+ ada_ctx->ctx->pts_serves_ops->first_checkin(ada_ctx->ctx->output_pix_fmt, ada_ctx->ctx->ptsserver_id,
+ es_data->data_start + offset, es_data->buf_start);
+
+ return;
+}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h
index c8641ce..66ed2a6 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.h
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -1,27 +1,28 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef VDEC_ADAPT_H
#define VDEC_ADAPT_H
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/codec_mm/dmabuf_manage.h>
#include "../stream_input/amports/streambuf.h"
#include "../frame_provider/decoder/utils/vdec_input.h"
#include "aml_vcodec_drv.h"
@@ -50,8 +51,8 @@
int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
const char *buf, unsigned int count);
-int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
- const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr);
+int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, const char *buf,
+ unsigned int count, u64 timestamp, ulong meta_ptr, chunk_free free);
void vdec_vframe_input_free(void *priv, u32 handle);
@@ -64,6 +65,8 @@
void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx);
int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *flag);
+void aml_codec_connect(struct aml_vdec_adapt *ada_ctx);
+void aml_codec_disconnect(struct aml_vdec_adapt *ada_ctx);
extern void dump_write(const char __user *buf, size_t count);
@@ -71,9 +74,23 @@
int vdec_frame_number(struct aml_vdec_adapt *ada_ctx);
+void vdec_set_dmabuf_type(struct aml_vdec_adapt *ada_ctx, bool dmabuf_type);
+
int vdec_get_instance_num(void);
+bool vdec_check_is_available(u32 fmt);
+
void vdec_set_duration(s32 duration);
+void vdec_write_stream_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size);
+
+void vdec_write_stream_data_inner(struct aml_vdec_adapt *ada_ctx, char *addr, u32 size, u64 timestamp);
+
+void v4l2_set_ext_buf_addr(struct aml_vdec_adapt *ada_ctx, struct dmabuf_dmx_sec_es_data *es_data, int offset);
+
+int vdec_get_vdec_id(struct aml_vdec_adapt *ada_ctx);
+
+void vdec_thread_wakeup(struct aml_vdec_adapt *ada_ctx);
+
#endif /* VDEC_ADAPT_H */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index f40d3fd..86c2fbe 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
@@ -31,7 +31,13 @@
#include <linux/scatterlist.h>
#include <linux/sched/clock.h>
#include <linux/highmem.h>
+#include <linux/version.h>
#include <uapi/linux/sched/types.h>
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/media/codec_mm/dmabuf_manage.h>
+#include <linux/dma-heap.h>
+#include <uapi/linux/dma-heap.h>
+#include <linux/amlogic/media/meson_uvm_allocator.h>
#include "aml_vcodec_drv.h"
#include "aml_vcodec_dec.h"
@@ -45,16 +51,27 @@
#include "../frame_provider/decoder/utils/decoder_mmu_box.h"
#include "../common/chips/decoder_cpu_ver_info.h"
#include "utils/common.h"
+#include "../media_sync/pts_server/pts_server_core.h"
#include "../frame_provider/decoder/utils/vdec_sync.h"
-
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
+#include "../common/media_utils/media_utils.h"
+#include "../frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h"
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
+#endif
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/amlogic/media/dmabuf_heaps/amlogic_dmabuf_heap.h>
+#include <linux/amlogic/ion.h>
+#else
+#include <linux/meson_ion.h>
+#endif
#define OUT_FMT_IDX (0) //default h264
-#define CAP_FMT_IDX (9) //capture nv21
-#define CAP_FMT_I420_IDX (12) //use for mjpeg
+#define CAP_FMT_IDX (14) //capture nv21m
+#define CAP_FMT_I420_IDX (18) //use for mjpeg
#define AML_VDEC_MIN_W 64U
#define AML_VDEC_MIN_H 64U
@@ -66,12 +83,29 @@
#define AML_V4L2_GET_INPUT_BUFFER_NUM (V4L2_CID_USER_AMLOGIC_BASE + 1)
#define AML_V4L2_SET_DURATION (V4L2_CID_USER_AMLOGIC_BASE + 2)
#define AML_V4L2_GET_FILMGRAIN_INFO (V4L2_CID_USER_AMLOGIC_BASE + 3)
+#define AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE (V4L2_CID_USER_AMLOGIC_BASE + 4)
+#define AML_V4L2_GET_DECODER_INFO (V4L2_CID_USER_AMLOGIC_BASE + 5)
+
+/*V4L2_CID_USER_AMLOGIC_BASE + 5 occupied*/
+#define AML_V4L2_GET_BITDEPTH (V4L2_CID_USER_AMLOGIC_BASE + 6)
+#define AML_V4L2_DEC_PARMS_CONFIG (V4L2_CID_USER_AMLOGIC_BASE + 7)
+#define AML_V4L2_GET_INST_ID (V4L2_CID_USER_AMLOGIC_BASE + 8)
+#define AML_V4L2_SET_STREAM_MODE (V4L2_CID_USER_AMLOGIC_BASE + 9)
+#define AML_V4L2_SET_ES_DMABUF_TYPE (V4L2_CID_USER_AMLOGIC_BASE + 10)
+
+#define V4L2_EVENT_PRIVATE_EXT_VSC_BASE (V4L2_EVENT_PRIVATE_START + 0x2000)
+#define V4L2_EVENT_PRIVATE_EXT_VSC_EVENT (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 1)
+#define V4L2_EVENT_PRIVATE_EXT_SEND_ERROR (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 2)
+#define V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 3)
#define WORK_ITEMS_MAX (32)
#define MAX_DI_INSTANCE (2)
+#define PAGE_NUM_ONE_MB (256)
//#define USEC_PER_SEC 1000000
+#define INVALID_IDX -1
+
#define call_void_memop(vb, op, args...) \
do { \
if ((vb)->vb2_queue->mem_ops->op) \
@@ -122,12 +156,42 @@
.num_planes = 1,
},
{
+ .name = "AVS",
+ .fourcc = V4L2_PIX_FMT_AVS,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
.name = "AV1",
.fourcc = V4L2_PIX_FMT_AV1,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
+ .name = "AVS2",
+ .fourcc = V4L2_PIX_FMT_AVS2,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .name = "AVS3",
+ .fourcc = V4L2_PIX_FMT_AVS3,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .name = "VC1L",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .name = "VC1G",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
.name = "NV21",
.fourcc = V4L2_PIX_FMT_NV21,
.type = AML_FMT_FRAME,
@@ -202,11 +266,36 @@
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
},
{
+ .fourcc = V4L2_PIX_FMT_AVS,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+ },
+ {
.fourcc = V4L2_PIX_FMT_AV1,
.stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
},
{
+ .fourcc = V4L2_PIX_FMT_AVS2,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_AVS3,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+ },
+ {
.fourcc = V4L2_PIX_FMT_NV21,
.stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
@@ -243,6 +332,7 @@
extern bool multiplanar;
extern int dump_capture_frame;
+extern char dump_path[32];
extern int bypass_vpp;
extern int bypass_ge2d;
extern bool support_format_I420;
@@ -252,18 +342,21 @@
extern int force_enable_di_local_buffer;
extern int max_di_instance;
extern int bypass_nr_flag;
+extern int es_node_expand;
+extern int force_di_permission;
+extern int enable_di_post;
-extern int dmabuf_fd_install_data(int fd, void* data, u32 size);
-extern bool is_v4l2_buf_file(struct file *file);
-extern int get_double_write_ratio(int dw_mode);
-static void box_release(struct kref *kref);
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb);
+extern int vdec_get_size_ratio(int dw_mode);
static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type);
-static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
+static void copy_v4l2_format_dimension(struct aml_vcodec_ctx *ctx,
+ struct v4l2_pix_format_mplane *pix_mp,
struct v4l2_pix_format *pix,
struct aml_q_data *q_data,
u32 type);
+static void vidioc_vdec_s_parm_ext(struct v4l2_ctrl *, struct aml_vcodec_ctx *);
+static void vidioc_vdec_g_parm_ext(struct v4l2_ctrl *, struct aml_vcodec_ctx *);
+static int is_vdec_core_fmt(struct aml_vcodec_ctx *ctx);
+
static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
{
@@ -334,6 +427,15 @@
case V4L2_EVENT_SEND_EOS:
event.type = V4L2_EVENT_EOS;
break;
+ case V4L2_EVENT_SEND_ERROR:
+ event.type = V4L2_EVENT_PRIVATE_EXT_SEND_ERROR;
+ break;
+ case V4L2_EVENT_REPORT_ERROR_FRAME:
+ event.type = V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME;
+ memcpy(event.u.data, &ctx->current_timestamp, sizeof(u64));
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "report error frame timestamp: %llu\n",
+ ctx->current_timestamp);
+ break;
default:
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"unsupport dispatch event %x\n", changes);
@@ -354,6 +456,22 @@
aml_decoder_flush(ctx->ada_ctx);
}
+static bool is_di_support(int width, int height)
+{
+ int di_max_width = 1920;
+ int di_max_height = 1088;
+ int di_min_width = 128;
+ int di_min_height = 16;
+
+ if (width > di_max_width || height > di_max_height) {
+ return false;
+ } else if (width < di_min_width || height < di_min_height) {
+ return false;
+ }
+
+ return true;
+}
+
/* Conditions:
* Always connect VPP for mpeg2 and h264 when the stream size is under 2K.
* Always connect VPP for hevc/av1/vp9 when color space is not SDR and
@@ -366,26 +484,31 @@
{
int width = ctx->picinfo.coded_width;
int height = ctx->picinfo.coded_height;
- int size = 1920 * 1088;
- if (bypass_vpp)
+ if (bypass_vpp || ctx->enable_di_post)
+ return false;
+
+ if (ctx->vpp_cfg.bypass)
return false;
if (!ctx->vpp_cfg.enable_nr &&
- (ctx->picinfo.field == V4L2_FIELD_NONE)) {
+ (ctx->picinfo.field == V4L2_FIELD_NONE) &&
+ !((ctx->config.parm.dec.cfg.double_write_mode & VDEC_MODE_MMU_DW_MASK) &&
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4 ||
+ get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4D))) {
return false;
}
if (!ctx->vpp_cfg.enable_nr &&
(ctx->output_pix_fmt == V4L2_PIX_FMT_HEVC)) {
- if (is_over_size(width, height, size)) {
+ if (!is_di_support(width, height)) {
return false;
}
}
if ((ctx->output_pix_fmt == V4L2_PIX_FMT_H264) &&
(ctx->picinfo.field != V4L2_FIELD_NONE)) {
- if (is_over_size(width, height, size)) {
+ if (!is_di_support(width, height)) {
return false;
}
}
@@ -402,6 +525,12 @@
*mode = VPP_MODE_DI;
}
+ if (!disable_vpp_dw_mmu &&
+ (ctx->config.parm.dec.cfg.double_write_mode & VDEC_MODE_MMU_DW_MASK) &&
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4 ||
+ get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4D)) {
+ *mode = VPP_MODE_S4_DW_MMU;
+ }
#if 0//enable later
if (ctx->colorspace != V4L2_COLORSPACE_DEFAULT &&
!is_over_size(width, height, size)) {
@@ -426,12 +555,16 @@
if (bypass_ge2d)
return false;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
+ if (ctx->ge2d_cfg.bypass)
+ return false;
+
+ if (is_cpu_t7()) {
if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_AVS)) {
return false;
}
} else if (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) {
@@ -442,16 +575,7 @@
return false;
}
- if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- *mode = GE2D_MODE_CONVERT_NV12;
- else if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
- (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
- *mode = GE2D_MODE_CONVERT_NV21;
- else
- *mode = GE2D_MODE_CONVERT_NV21;
-
- *mode |= GE2D_MODE_CONVERT_LE;
+ *mode = GE2D_MODE_CONVERT_LE;
return true;
}
@@ -504,9 +628,25 @@
ctx->vpp_size = vpp->buf_size;
ctx->ge2d_size = ge2d->buf_size;
+ if (ctx->enable_di_post &&
+ ctx->picinfo.field != V4L2_FIELD_NONE &&
+ is_vdec_core_fmt(ctx))
+ ctx->dpb_size *= PAIR_DONE;
+
+ if (ctx->enable_di_post && (is_vdec_core_fmt(ctx)) &&
+ ctx->dpb_size > 2 * V4L_CAP_BUFF_MAX) {
+ ctx->dpb_size = ctx->dpb_size / PAIR_DONE * 2;
+ }
+
total_size = ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size;
- if (total_size > V4L_CAP_BUFF_MAX) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "dpb_size: %d dpb_frames: %d dpb_margin: %d vpp_size: %d ge2d_size: %d\n",
+ ctx->dpb_size, picinfo->dpb_frames, picinfo->dpb_margin,
+ ctx->vpp_size, ctx->ge2d_size);
+
+ if ((total_size > V4L_CAP_BUFF_MAX) &&
+ !(ctx->enable_di_post && ctx->picinfo.field != V4L2_FIELD_NONE)) {
if (ctx->ge2d_size) {
ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->ge2d_size - ctx->vpp_size;
} else if (ctx->vpp_size) {
@@ -522,18 +662,68 @@
return total_size;
}
+static void aml_buf_configure_update(struct aml_vcodec_ctx *ctx)
+{
+ struct aml_buf_config config = {0};
+ struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
+ u32 dw = DM_YUV_ONLY;
+ u32 tw = DM_INVALID;
+
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+ return;
+
+ }
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+ return;
+
+ }
+
+ config.enable_extbuf = true;
+ config.enable_fbc = ((dw != DM_YUV_ONLY) || tw) ? true : false;
+ config.enable_secure = ctx->is_drm_mode;
+ config.memory_mode = que->memory;
+ config.planes = V4L2_TYPE_IS_MULTIPLANAR(que->type) ? 2 : 1;
+ config.luma_length = ctx->picinfo.y_len_sz;
+ config.chroma_length = ctx->picinfo.c_len_sz;
+ config.luma_length_tw = ctx->picinfo.y_len_sz_tw;
+ config.chroma_length_tw = ctx->picinfo.c_len_sz_tw;
+ config.dw_mode = dw;
+ config.tw_mode = tw;
+
+ aml_buf_configure(&ctx->bm, &config);
+}
+
void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
{
- if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
+ struct aml_buf_config config;
+ struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
+ u32 dw = DM_YUV_ONLY;
+ u32 tw = DM_INVALID;
+
+ if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Cannot get param : GET_PARAM_PICTURE_INFO ERR\n");
return;
}
- if (ctx->last_decoded_picinfo.visible_width == 0 ||
- ctx->last_decoded_picinfo.visible_height == 0 ||
- ctx->last_decoded_picinfo.coded_width == 0 ||
- ctx->last_decoded_picinfo.coded_height == 0) {
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+ return;
+
+ }
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+ return;
+
+ }
+
+ if (ctx->picinfo.visible_width == 0 ||
+ ctx->picinfo.visible_height == 0 ||
+ ctx->picinfo.coded_width == 0 ||
+ ctx->picinfo.coded_height == 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Cannot get correct pic info\n");
return;
@@ -545,19 +735,34 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"new(%d,%d), old(%d,%d), real(%d,%d)\n",
+ ctx->picinfo.visible_width,
+ ctx->picinfo.visible_height,
ctx->last_decoded_picinfo.visible_width,
ctx->last_decoded_picinfo.visible_height,
- ctx->picinfo.visible_width, ctx->picinfo.visible_height,
- ctx->last_decoded_picinfo.coded_width,
- ctx->last_decoded_picinfo.coded_width);
-
- ctx->picinfo = ctx->last_decoded_picinfo;
+ ctx->picinfo.coded_width,
+ ctx->picinfo.coded_width);
if (ctx->vpp_is_need)
ctx->vpp_cfg.is_vpp_reset = true;
v4l_buf_size_decision(ctx);
+ config.enable_extbuf = true;
+ config.enable_fbc = ((dw != DM_YUV_ONLY) || tw) ? true : false;
+ config.enable_secure = ctx->is_drm_mode;
+ config.memory_mode = que->memory;
+ config.planes = V4L2_TYPE_IS_MULTIPLANAR(que->type) ? 2 : 1;
+ config.luma_length = ctx->picinfo.y_len_sz;
+ config.chroma_length = ctx->picinfo.c_len_sz;
+ config.luma_length_tw = ctx->picinfo.y_len_sz_tw;
+ config.chroma_length_tw = ctx->picinfo.c_len_sz_tw;
+ config.dw_mode = dw;
+ config.tw_mode = tw;
+
+ aml_buf_configure(&ctx->bm, &config);
+
+ aml_buf_put_dma(&ctx->bm);
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
"Update picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
@@ -571,7 +776,7 @@
(struct file_private_data *) data;
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)
priv_data->v4l_dec_ctx;
- struct aml_video_dec_buf *vb = (struct aml_video_dec_buf *)
+ struct aml_v4l2_buf *vb = (struct aml_v4l2_buf *)
priv_data->vb_handle;
struct uvm_hook_mod_info *uvm = NULL;
@@ -584,6 +789,20 @@
kfree(data);
}
+void aml_clean_proxy_uvm(struct aml_vcodec_ctx *ctx)
+{
+ struct uvm_hook_mod_info *uvm = NULL;
+ int i;
+
+ for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+ if (ctx && ctx->uvm_proxy) {
+ uvm = &ctx->uvm_proxy[i];
+ if (uvm->free)
+ uvm->free(uvm->arg);
+ }
+ }
+}
+
static void v4l2_buff_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
{
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(buf->vb2_buf.vb2_queue);
@@ -606,209 +825,209 @@
dmabuf_set_vframe(vb->planes[0].dbuf, vf, VF_SRC_DECODER);
}
-static void fb_map_table_clean(struct aml_vcodec_ctx *ctx)
+void fbc_transcode_and_set_vf(struct aml_vcodec_ctx *ctx,
+ struct aml_buf *aml_buf,
+ struct vframe_s *vf)
{
- int i;
- ulong flags;
+ struct vb2_buffer *vb2_buf = aml_buf->vb;
+ struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
+ struct aml_v4l2_buf *dstbuf =
+ container_of(vb, struct aml_v4l2_buf, vb);
- flags = aml_vcodec_ctx_lock(ctx);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- ctx->fb_map[i].addr = 0;
- ctx->fb_map[i].vframe = NULL;
- ctx->fb_map[i].task = NULL;
- ctx->fb_map[i].icomp = 0;
+ if (is_cpu_t7()) {
+ if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
+ if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
+ (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ }
+ else {
+ if (aml_buf->state == FB_ST_GE2D)
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ }
+ }
+ } else {
+ if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
}
+ if (!ctx->enable_di_post) {
+ vf->index_disp = ctx->index_disp;
+ vf->omx_index = vf->index_disp;
- aml_vcodec_ctx_unlock(ctx, flags);
+ if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
+ struct dma_buf * dma;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static void fb_map_table_hold(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb,
- struct vframe_s *vf,
- struct task_chain_s *task,
- u32 icomp)
-{
- int i;
- ulong addr, flags;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (!ctx->fb_map[i].addr ||
- (addr == ctx->fb_map[i].addr)) {
- ctx->fb_map[i].task = task;
- ctx->fb_map[i].addr = addr;
- ctx->fb_map[i].vframe = vf;
- ctx->fb_map[i].icomp = icomp;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
- __func__, task, vf, addr, icomp);
- break;
+ dma = dstbuf->vb.vb2_buf.planes[0].dbuf;
+ if (dmabuf_is_uvm(dma)) {
+ /* only Y will contain vframe */
+ comp_buf_set_vframe(ctx, vb2_buf, vf);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "set vf(%px) into %dth buf\n",
+ vf, vb2_buf->index);
+ }
}
}
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, table is full. addr:%lx, vf:%px\n",
- __func__, addr, vf);
- }
}
-static void fb_map_table_fetch(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb,
- struct vframe_s **vf,
- struct task_chain_s **task,
- u32 *icomp)
+ssize_t dump_cma_and_sys_memsize(struct aml_vcodec_ctx *ctx, char *buf)
{
- int i;
- ulong addr, flags;
+ struct cma_sys_size_info *info = &ctx->mem_size_info;
+ int cma_size = codec_mm_alloc_cma_size();
+ int sys_size = codec_mm_alloc_sys_size();
+ int total_size = cma_size + sys_size;
+ char *pbuf = buf;
- flags = aml_vcodec_ctx_lock(ctx);
-
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (addr == ctx->fb_map[i].addr) {
- *task = ctx->fb_map[i].task;
- *vf = ctx->fb_map[i].vframe;
- *icomp = ctx->fb_map[i].icomp;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
- __func__, task, vf, addr, *icomp);
-
- ctx->fb_map[i].task = NULL;
- ctx->fb_map[i].vframe = NULL;
- ctx->fb_map[i].addr = 0;
- ctx->fb_map[i].icomp = 0;
- break;
- }
+ if (total_size > info->max_total_size) {
+ info->max_total_size = total_size;
+ info->cma_part = cma_size;
+ info->sys_part = sys_size;
}
- aml_vcodec_ctx_unlock(ctx, flags);
+ info->max_cma_size = cma_size > info->max_cma_size ?
+ cma_size : info->max_cma_size;
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, there is new addr:%lx.\n",
- __func__, addr);
- }
-}
+ info->max_sys_size = sys_size > info->max_sys_size ?
+ sys_size : info->max_sys_size;
-static bool is_fb_mapped(struct aml_vcodec_ctx *ctx, ulong addr)
-{
- int i;
- ulong flags;
+ info->cur_cma_size = cma_size;
+ info->cur_sys_size = sys_size;
- flags = aml_vcodec_ctx_lock(ctx);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (addr == ctx->fb_map[i].addr)
- break;
+ if (pbuf) {
+ pbuf += sprintf(pbuf, "TOTAL[Max:%dM(CMA:%dM, SYS:%dM), CUR:%dM], "
+ "CMA[%dM, Max:%dM], SYS[%dM, Max:%dM]\n",
+ info->max_total_size, info->cma_part,
+ info->sys_part, total_size,
+ info->cur_cma_size, info->max_cma_size,
+ info->cur_sys_size, info->max_sys_size);
+ } else {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_COUNT,
+ "TOTAL[Max:%dM(CMA:%dM, SYS:%dM), CUR:%dM], "
+ "CMA[%dM, Max:%dM], SYS[%dM, Max:%dM]\n",
+ info->max_total_size, info->cma_part,
+ info->sys_part, total_size,
+ info->cur_cma_size, info->max_cma_size,
+ info->cur_sys_size, info->max_sys_size);
}
- aml_vcodec_ctx_unlock(ctx, flags);
-
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, addr:%lx isn't output.\n",
- __func__, addr);
- return false;
- }
-
- return true;
+ return pbuf - buf;
}
static void post_frame_to_upper(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb)
+ struct aml_buf *aml_buf)
{
- struct aml_video_dec_buf *dstbuf =
- container_of(fb, struct aml_video_dec_buf, frame_buffer);
- struct vb2_buffer *vb2_buf = &dstbuf->vb.vb2_buf;
- struct vframe_s *vf = fb->vframe;
- struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+ struct vb2_buffer *vb2_buf = aml_buf->vb;
+ struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
+ struct aml_v4l2_buf *dstbuf =
+ container_of(vb, struct aml_v4l2_buf, vb);
+ struct vframe_s *vf = &aml_buf->vframe;
+ struct aml_vdec_cfg_infos *cfg = &ctx->config.parm.dec.cfg;
+ struct aml_buf_plane *planes = aml_buf->planes; // DW def.
- vf->index_disp = ctx->index_disp;
- ctx->index_disp++;
+ dump_cma_and_sys_memsize(ctx, NULL);
+
+ if (!ctx->enable_di_post) {
+ vf->index_disp = ctx->index_disp;
+ if ((vf->type & VIDTYPE_V4L_EOS) == 0)
+ ctx->index_disp++;
+ }
+
ctx->post_to_upper_done = false;
+ if ((cfg->double_write_mode == DM_AVBC_ONLY) ||
+ (ctx->force_tw_output && cfg->triple_write_mode)) {
+ if (aml_buf->planes_tw[0].bytes_used)
+ planes = aml_buf->planes_tw;
+ }
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
- "OUT_BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+ "OUT_BUFF (%s, st:%d, seq:%d, idx:%d) vb:(%d, %px), vf:(%d, %px), ts:%llu, flag: 0x%x "
"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
- ctx->ada_ctx->frm_name, fb->status, vf->index_disp,
+ ctx->ada_ctx->frm_name, aml_buf->state, ctx->out_buff_cnt, aml_buf->index,
vb2_buf->index, vb2_buf,
vf->index & 0xff, vf,
vf->timestamp,
- fb->m.mem[0].addr, fb->m.mem[0].size,
- fb->m.mem[1].addr, fb->m.mem[1].size,
- fb->m.mem[2].addr, fb->m.mem[2].size);
+ vf->flag,
+ planes[0].addr, planes[0].length,
+ planes[1].addr, planes[1].length,
+ planes[2].addr, planes[2].length);
+ ctx->out_buff_cnt++;
- vb2_v4l2 = container_of(vb2_buf, struct vb2_v4l2_buffer, vb2_buf);
-
- if (dstbuf->frame_buffer.num_planes == 1) {
- vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
- } else if (dstbuf->frame_buffer.num_planes == 2) {
- vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
- vb2_set_plane_payload(vb2_buf, 1, fb->m.mem[1].bytes_used);
+ if (dstbuf->aml_buf->num_planes == 1) {
+ vb2_set_plane_payload(vb2_buf, 0, planes[0].bytes_used);
+ } else if (dstbuf->aml_buf->num_planes == 2) {
+ vb2_set_plane_payload(vb2_buf, 0, planes[0].bytes_used);
+ vb2_set_plane_payload(vb2_buf, 1, planes[1].bytes_used);
}
+
vb2_buf->timestamp = vf->timestamp;
dstbuf->vb.flags |= vf->frame_type;
if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) {
- vb2_v4l2->field = V4L2_FIELD_INTERLACED;
+ vb->field = V4L2_FIELD_INTERLACED;
}
do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ u32 dw_mode = DM_YUV_ONLY;
+ u32 tw_mode = DM_INVALID;
struct file *fp;
- char file_name[32] = {0};
+ char file_name[64] = {0};
if (!dump_capture_frame || ctx->is_drm_mode)
break;
+
if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
break;
- if (dw_mode == VDEC_DW_AFBC_ONLY)
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
break;
- snprintf(file_name, 32, "/data/dec_dump_%ux%u.raw", vf->width, vf->height);
+ if ((dw_mode == DM_AVBC_ONLY) && (tw_mode == DM_INVALID))
+ break;
- fp = filp_open(file_name,
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+ snprintf(file_name, 64, "%s/dec_dump_%ux%u.raw", dump_path, vf->width, vf->height);
+
+ fp = media_open(file_name,
+ O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0666);
if (!IS_ERR(fp)) {
struct vb2_buffer *vb = vb2_buf;
+ // dump y data
+ u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+ vf->width, vf->height, 64);
+ // dump uv data
+ if (vb->num_planes == 1) {
+ aml_yuv_dump(fp, yuv_data_addr, vf->width,
+ vf->height / 2, 64);
+ } else {
+ aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+ vf->width, vf->height / 2, 64);
+ }
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
- if (dstbuf->frame_buffer.num_planes == 2)
- kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
pr_info("dump idx: %d %dx%d\n", dump_capture_frame, vf->width, vf->height);
dump_capture_frame--;
- filp_close(fp, NULL);
+ media_close(fp, NULL);
}
} while(0);
- ATRACE_COUNTER("VC_OUT_VSINK-1.submit", vb2_buf->index);
- ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
+
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_6, vb2_buf->index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_1, vdec_frame_number(ctx->ada_ctx));
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_10,
+ CTX_BUF_TOTAL(ctx) + ctx->out_buff_cnt - ctx->in_buff_cnt);
if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
- if (dstbuf->frame_buffer.num_planes == 1) {
+ if (dstbuf->aml_buf->num_planes == 1) {
vb2_set_plane_payload(vb2_buf, 0, 0);
- } else if (dstbuf->frame_buffer.num_planes == 2) {
+ } else if (dstbuf->aml_buf->num_planes == 2) {
vb2_set_plane_payload(vb2_buf, 0, 0);
vb2_set_plane_payload(vb2_buf, 1, 0);
}
ctx->has_receive_eos = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "recevie a empty frame. idx: %d, state: %d\n",
+ "receive a empty frame. idx: %d, state: %d\n",
vb2_buf->index, vb2_buf->state);
}
@@ -818,11 +1037,10 @@
if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
if (ctx->v4l_resolution_change) {
- /* make the run to stanby until new buffs to enque. */
- ctx->v4l_codec_dpb_ready = false;
+ /* make the run to stanby until new buffs to enqueue. */
ctx->reset_flag = V4L_RESET_MODE_LIGHT;
ctx->vpp_cfg.res_chg = true;
-
+ ctx->last_decoded_picinfo = ctx->picinfo;
/*
* After all buffers containing decoded frames from
* before the resolution change point ready to be
@@ -837,54 +1055,26 @@
}
if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) {
- /* binding vframe handle. */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
- if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- else {
- if (fb->status == FB_ST_GE2D)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- }
- } else {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ if (!ctx->no_fbc_output &&
+ !(vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L)) {
+ ctx->fbc_transcode_and_set_vf(ctx, aml_buf, vf);
}
- vf->omx_index = vf->index_disp;
dstbuf->privdata.vf = *vf;
- if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
- struct dma_buf * dma;
+ if (vf->frame_type & V4L2_BUF_FLAG_ERROR)
+ v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_ERROR);
+ else
+ v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
- dma = dstbuf->vb.vb2_buf.planes[0].dbuf;
- if (dmabuf_is_uvm(dma)) {
- /* only Y will contain vframe */
- comp_buf_set_vframe(ctx, vb2_buf, vf);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "set vf(%px) into %dth buf\n",
- vf, vb2_buf->index);
- }
- }
-
- fb_map_table_hold(ctx, vb2_buf, vf, fb->task, dstbuf->internal_index);
-
- v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
-
- fb->status = FB_ST_DISPLAY;
+ aml_buf->state = FB_ST_DISPLAY;
}
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_FLUSHING &&
ctx->has_receive_eos) {
ctx->state = AML_STATE_FLUSHED;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_FLUSHED)\n");
}
@@ -902,174 +1092,31 @@
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
- struct aml_video_dec_buf *aml_buff =
- container_of(fb, struct aml_video_dec_buf, frame_buffer);
- struct vb2_v4l2_buffer *vb = &aml_buff->vb;
-
+ struct aml_buf *aml_buf = (struct aml_buf *)fb_ctx;
+ struct vb2_buffer *vb2_buf = aml_buf->vb;
+ struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
if (ctx->is_stream_off) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
- "ignore buff idx: %d streamoff\n", fb->buf_idx);
+ "ignore buff idx: %d streamoff\n", aml_buf->index);
return;
}
- ATRACE_COUNTER("VC_OUT_VSINK-0.receive", vb->vb2_buf.index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_5, vb->vb2_buf.index);
mutex_lock(&ctx->capture_buffer_lock);
kfifo_put(&ctx->capture_buffer, vb);
mutex_unlock(&ctx->capture_buffer_lock);
-
aml_thread_post_task(ctx, AML_THREAD_CAPTURE);
-}
-
-static void update_vdec_buf_plane(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb,
- struct vb2_buffer *vb)
-{
- int i;
- char plane_n[3] = {'Y','U','V'};
-
- fb->num_planes = vb->num_planes;
- fb->buf_idx = vb->index;
-
- for (i = 0 ; i < vb->num_planes ; i++) {
- fb->m.mem[i].addr = vb2_dma_contig_plane_dma_addr(vb, i);
- fb->m.mem[i].dbuf = vb->planes[i].dbuf;
- if (i == 0) {
- //Y
- if (vb->num_planes == 1) {
- fb->m.mem[0].size = ctx->picinfo.y_len_sz +
- ctx->picinfo.c_len_sz;
- fb->m.mem[0].offset = ctx->picinfo.y_len_sz;
- } else {
- fb->m.mem[0].size = ctx->picinfo.y_len_sz;
- fb->m.mem[0].offset = 0;
- }
- } else {
- if (vb->num_planes == 2) {
- //UV
- fb->m.mem[1].size = ctx->picinfo.c_len_sz;
- fb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
- } else {
- fb->m.mem[i].size = ctx->picinfo.c_len_sz >> 1;
- fb->m.mem[i].offset = 0;
- }
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "idx: %u, %c:(0x%lx, %d)\n", vb->index,
- plane_n[i], fb->m.mem[i].addr, fb->m.mem[i].size);
- }
-}
-
-static bool fb_token_insert(struct aml_vcodec_ctx *ctx,
- ulong *token)
-{
- ulong vb_handle;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (ctx->token_table[i] &&
- (ctx->token_table[i] == *token)) {
- return true;
- }
- }
-
- if (!v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx))
- return false;
-
- vb_handle = (ulong)v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (!ctx->token_table[i]) {
- ctx->token_table[i] = vb_handle;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(ctx->token_table)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, table is full. token:%lx\n",
- __func__, vb_handle);
- return false;
- }
-
- *token = vb_handle;
-
- return true;
-}
-
-static void fb_token_remove(struct aml_vcodec_ctx *ctx,
- ulong token)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (token == ctx->token_table[i]) {
- ctx->token_table[i] = 0;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(ctx->token_table)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, remove token err, token:%lx.\n",
- __func__, token);
- }
-}
-
-static void fb_token_clean(struct aml_vcodec_ctx *ctx)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- ctx->token_table[i] = 0;
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static bool fb_buff_query(struct aml_fb_ops *fb, ulong *token)
-{
- struct aml_vcodec_ctx *ctx =
- container_of(fb, struct aml_vcodec_ctx, fb_ops);
- struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
- bool ret = false;
- ulong flags;
-
- if (!que->streaming)
- return false;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- ret = fb_token_insert(ctx, token);
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- return ret;
-}
-
-static void aml_task_chain_remove(struct aml_vcodec_ctx *ctx)
-{
- struct task_chain_s *task, *tmp;
-
- list_for_each_entry_safe(task, tmp, &ctx->task_chain_pool, node) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "remove task chain:%d, %px\n", task->id, task);
- list_del(&task->node);
- task_chain_clean(task);
- task_chain_release(task);
- }
+ aml_buf_update_holder(&ctx->bm, aml_buf, BUF_USER_VSINK, BUF_GET);
}
static struct task_ops_s *get_v4l_sink_ops(void);
-static void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb,
- u32 requester)
+void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
+ struct aml_buf *aml_buf,
+ u32 requester)
{
- struct task_chain_s *task = fb->task;
+ struct task_chain_s *task = aml_buf->task;
/*
* line 1: dec <==> vpp <==> v4l-sink, for P / P + DI.NR.
* line 2: dec <==> vpp, vpp <==> v4l-sink, for I / I + DI.NR.
@@ -1129,71 +1176,33 @@
"unsupport requester %x\n", requester);
}
}
-
-static int fb_buff_from_queue(struct aml_fb_ops *fb_ops,
- ulong token, struct vdec_v4l2_buffer **out_fb,
- u32 requester)
+void cal_compress_buff_info(ulong used_page_num, struct aml_vcodec_ctx *ctx)
{
- struct aml_vcodec_ctx *ctx =
- container_of(fb_ops, struct aml_vcodec_ctx, fb_ops);
- struct aml_video_dec_buf *aml_buf = NULL;
- struct vb2_v4l2_buffer *v4l_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- u32 buf_status = 0;
- ulong flags;
+ struct v4l_compressed_buffer_info *buf_info = &ctx->compressed_buf_info;
+ u32 total_buffer_num = ctx->dpb_size;
+ u32 cur_index = buf_info->recycle_num % total_buffer_num;
+ u32 cur_avg_val_by_group;
- flags = aml_vcodec_ctx_lock(ctx);
+ if (!(debug_mode & V4L_DEBUG_CODEC_COUNT))
+ return;
- if (ctx->is_stream_off) {
- aml_vcodec_ctx_unlock(ctx, flags);
- return -1;
- }
+ mutex_lock(&ctx->compressed_buf_info_lock);
+ buf_info->used_page_sum += used_page_num;
+ buf_info->used_page_distributed_array[(u32)used_page_num / PAGE_NUM_ONE_MB]++;
- v4l_buf = (struct vb2_v4l2_buffer *) token;
- if (!v4l_buf) {
- aml_vcodec_ctx_unlock(ctx, flags);
- return -1;
- }
+ buf_info->used_page_by_group = buf_info->used_page_by_group -
+ buf_info->used_page_in_group[cur_index] + used_page_num;
+ buf_info->used_page_in_group[cur_index] = used_page_num;
+ cur_avg_val_by_group = buf_info->used_page_by_group / total_buffer_num;
+ if (cur_avg_val_by_group > buf_info->max_avg_val_by_group)
+ buf_info->max_avg_val_by_group = cur_avg_val_by_group;
- aml_buf = container_of(v4l_buf, struct aml_video_dec_buf, vb);
-
- fb = &aml_buf->frame_buffer;
- fb->buf_idx = v4l_buf->vb2_buf.index;
- aml_buf->used = true;
- ctx->buf_used_count++;
-
- if (requester == AML_FB_REQ_VPP) {
- buf_status = V4L_CAP_BUFF_IN_VPP;
- ctx->cap_pool.vpp++;
- } else if (requester == AML_FB_REQ_DEC) {
- buf_status = V4L_CAP_BUFF_IN_DEC;
- ctx->cap_pool.dec++;
- } else if (requester == AML_FB_REQ_GE2D) {
- buf_status = V4L_CAP_BUFF_IN_GE2D;
- ctx->cap_pool.ge2d++;
- }
-
- ctx->cap_pool.seq[ctx->cap_pool.out++] =
- (buf_status << 16 | fb->buf_idx);
-
- update_vdec_buf_plane(ctx, fb, &v4l_buf->vb2_buf);
-
- aml_creat_pipeline(ctx, fb, requester);
-
- fb_token_remove(ctx, token);
-
+ buf_info->recycle_num++;
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "vid:%d, task:%px, phy:%lx, state:%d, ready:%d, requester:%d\n",
- fb->buf_idx, fb->task, fb->m.mem[0].addr, v4l_buf->vb2_buf.state,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), requester);
-
- ATRACE_COUNTER("VC_IN_VSINK-3.require", v4l_buf->vb2_buf.index);
-
- *out_fb = fb;
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- return 0;
+ "4k_used_num %ld used_page_sum %llu used_page_by_group %u max_avg_val %u cur_avg_val %u buffer_num %d recycle_num %u\n",
+ used_page_num, buf_info->used_page_sum, buf_info->used_page_by_group,
+ buf_info->max_avg_val_by_group, cur_avg_val_by_group, total_buffer_num, buf_info->recycle_num);
+ mutex_unlock(&ctx->compressed_buf_info_lock);
}
static struct task_ops_s v4l_sink_ops = {
@@ -1206,59 +1215,62 @@
return &v4l_sink_ops;
}
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx)
+ssize_t aml_vdec_basic_information(struct aml_vcodec_ctx *ctx, char *buf)
{
struct aml_q_data *outq = NULL;
struct aml_q_data *capq = NULL;
struct vdec_pic_info pic;
+ u32 dw_mode = -1;
+ u32 tw_mode = -1;
+ char *pbuf = buf;
if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &pic)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"get pic info err\n");
- return;
+ return 0;
}
+ vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode);
+ vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode);
+
outq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
capq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- pr_info("\n==== Show Basic Information ==== \n");
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Format : %s\n",
- outq->fmt->name);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Color space: %s\n",
- capq->fmt->name);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Scan type : %s\n",
- (pic.field == V4L2_FIELD_NONE) ?
- "Progressive" : "Interlaced");
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Resolution : visible(%dx%d), coded(%dx%d)\n",
+ pbuf += sprintf(pbuf, "\n==== Show Basic Information ==== \n");
+ pbuf += sprintf(pbuf, "Format : %s\n", outq->fmt->name);
+ pbuf += sprintf(pbuf, "Color space: %s\n", capq->fmt->name);
+ pbuf += sprintf(pbuf, "Scan type : %s\n",
+ (pic.field == V4L2_FIELD_NONE) ? "Progressive" : "Interlaced");
+ pbuf += sprintf(pbuf, "Resolution : visible(%dx%d), coded(%dx%d)\n",
pic.visible_width, pic.visible_height,
pic.coded_width, pic.coded_height);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Buffer num : dec:%d, vpp:%d, ge2d:%d, margin:%d, total:%d\n",
+ pbuf += sprintf(pbuf, "Buffer num : dec:%d, vpp:%d, ge2d:%d, margin:%d, total:%d\n",
ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
ctx->picinfo.dpb_margin, CTX_BUF_TOTAL(ctx));
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Config : dw:%d, drm:%d, byp:%d, lc:%d, nr:%d, ge2d:%x\n",
- ctx->config.parm.dec.cfg.double_write_mode,
+
+ pbuf += sprintf(pbuf, "Config : DW/TW:(0x%x, 0x%x), drm:%d, byp:%d, lc:%d, nr:%d, ge2d:%x\n",
+ dw_mode,
+ tw_mode,
ctx->is_drm_mode,
ctx->vpp_cfg.is_bypass_p,
ctx->vpp_cfg.enable_local_buf,
ctx->vpp_cfg.enable_nr,
ctx->ge2d_cfg.mode);
+ pbuf += sprintf(pbuf, "write frames : %d, out_buff : %d in_buff : %d\n",
+ ctx->write_frames, ctx->out_buff_cnt, ctx->in_buff_cnt);
+
+ return pbuf - buf;
}
-void aml_buffer_status(struct aml_vcodec_ctx *ctx)
+ssize_t aml_buffer_status(struct aml_vcodec_ctx *ctx, char *buf)
{
struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *aml_buff = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_v4l2_buf *aml_buff = NULL;
+ struct aml_buf *aml_buf = NULL;
struct vb2_queue *q = NULL;
ulong flags;
int i;
+ char *pbuf = buf;
flags = aml_vcodec_ctx_lock(ctx);
@@ -1267,35 +1279,86 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"can't achieve buffers status before start streaming.\n");
}
+ if (!ctx->enable_di_post) {
+ pbuf += sprintf(pbuf, "\n==== Show Buffer Status ======== \n");
+ for (i = 0; i < q->num_buffers; ++i) {
+ vb = to_vb2_v4l2_buffer(q->bufs[i]);
+ aml_buff = container_of(vb, struct aml_v4l2_buf, vb);
+ aml_buf = aml_buff->aml_buf;
- pr_info("\n==== Show Buffer Status ======== \n");
- for (i = 0; i < q->num_buffers; ++i) {
- vb = to_vb2_v4l2_buffer(q->bufs[i]);
- aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
- fb = &aml_buff->frame_buffer;
-
- /* print out task chain status. */
- task_chain_show(fb->task);
+ /* print out task chain status. */
+ if (aml_buf)
+ pbuf += task_chain_show(aml_buf->task, pbuf);
+ }
}
aml_vcodec_ctx_unlock(ctx, flags);
+
+ pbuf += sprintf(pbuf, "\n==== Show Buffer Status ======== \n");
+ pbuf += buf_core_walk(&ctx->bm.bc, pbuf);
+
+ return pbuf - buf;
}
-static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
+void aml_compressed_info_show(struct aml_vcodec_ctx *ctx)
{
- if (!ctx->v4l_codec_dpb_ready) {
- /*
- * make sure enough dst bufs for decoding.
- */
- if ((ctx->dpb_size) && (ctx->cap_pool.in >= ctx->dpb_size))
- ctx->v4l_codec_dpb_ready = true;
+ struct aml_q_data *outq = NULL;
+ struct vdec_pic_info pic;
+ int i;
+ u32 aerage_mem_size;
+ u32 max_avg_val_by_proup;
+ struct v4l_compressed_buffer_info *buffer = &ctx->compressed_buf_info;
+ u64 used_page_sum = buffer->used_page_sum;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "dpb: %d, vpp: %d, ready: %d, used: %d, dpb is ready: %s\n",
- ctx->dpb_size, ctx->vpp_size,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
- ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no");
+ if (!(debug_mode & V4L_DEBUG_CODEC_COUNT))
+ return;
+
+ if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &pic)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "get pic info err\n");
+ return;
}
+
+ outq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+
+ pr_info("==== Show mmu buffer info ======== \n");
+ if (buffer->recycle_num == 0) {
+ pr_info("No valid info \n");
+ return;
+ }
+ mutex_lock(&ctx->compressed_buf_info_lock);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ "Fmt:%s, DW/TW:(%x, %x), Res:%dx%d, DPB:%d\n",
+ outq->fmt->name,
+ ctx->config.parm.dec.cfg.double_write_mode,
+ ctx->config.parm.dec.cfg.triple_write_mode,
+ pic.visible_width,
+ pic.visible_height,
+ ctx->dpb_size);
+
+ do_div(used_page_sum, buffer->recycle_num);
+ aerage_mem_size = ((u32)used_page_sum * 100) / PAGE_NUM_ONE_MB;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ "mmu mem recycle num: %u, average used mmu mem %u.%u%u(MB)\n",
+ buffer->recycle_num, aerage_mem_size / 100, (aerage_mem_size % 100) / 10, aerage_mem_size % 10);
+
+ max_avg_val_by_proup = buffer->max_avg_val_by_group * 100 / PAGE_NUM_ONE_MB;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ "%d buffer in group, max avg used mem by group %u.%u%u(MB)\n", ctx->dpb_size,
+ max_avg_val_by_proup / 100, (max_avg_val_by_proup % 100) / 10, max_avg_val_by_proup % 10);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,"mmu mem used distribution ratio\n");
+
+ for (i = 0; i < MAX_AVBC_BUFFER_SIZE; i++) {
+ u32 count = buffer->used_page_distributed_array[i];
+ //if (count)
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ "range %d [%dMB ~ %dMB] distribution num %d ratio %u%%\n",
+ i, i, i+1, count, (count * 100) / buffer->recycle_num);
+ }
+
+ mutex_unlock(&ctx->compressed_buf_info_lock);
+ pr_info("==== End Show mmu buffer info ========");
}
static void reconfig_vpp_status(struct aml_vcodec_ctx *ctx)
@@ -1313,12 +1376,9 @@
static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
{
- struct aml_vcodec_dev *dev = ctx->dev;
-
if (!is_input_ready(ctx->ada_ctx)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"the decoder input has not ready.\n");
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
return 0;
}
@@ -1326,7 +1386,7 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_PROBE) {
ctx->state = AML_STATE_READY;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_READY)\n");
}
@@ -1338,89 +1398,38 @@
if (ctx->m2m_ctx->out_q_ctx.q.streaming &&
ctx->m2m_ctx->cap_q_ctx.q.streaming) {
ctx->state = AML_STATE_ACTIVE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ACTIVE)\n");
}
}
mutex_unlock(&ctx->state_lock);
- /* check dpb ready */
- //aml_check_dpb_ready(ctx);
-
return 1;
}
-static bool is_enough_work_items(struct aml_vcodec_ctx *ctx)
-{
- struct aml_vcodec_dev *dev = ctx->dev;
-
- if (vdec_frame_number(ctx->ada_ctx) >= WORK_ITEMS_MAX) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- return false;
- }
-
- return true;
-}
-
-static void aml_wait_buf_ready(struct aml_vcodec_ctx *ctx)
-{
- ulong expires;
-
- expires = jiffies + msecs_to_jiffies(1000);
- while (!ctx->v4l_codec_dpb_ready) {
- u32 ready_num = 0;
-
- if (time_after(jiffies, expires)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "the DPB state has not ready.\n");
- break;
- }
-
- ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if ((ready_num + ctx->buf_used_count) >= CTX_BUF_TOTAL(ctx))
- ctx->v4l_codec_dpb_ready = true;
- }
-}
-
void dmabuff_recycle_worker(struct work_struct *work)
{
struct aml_vcodec_ctx *ctx =
- container_of(work, struct aml_vcodec_ctx, dmabuff_recycle_work);
+ container_of(work, struct aml_vcodec_ctx, es_wkr_out);
struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *buf = NULL;
- unsigned long flags;
+ struct aml_v4l2_buf *buf = NULL;
- for (;;) {
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
- if (!kfifo_get(&ctx->dmabuff_recycle, &vb)) {
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
- break;
- }
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
+ if (ctx->es_wkr_stop ||
+ !kfifo_get(&ctx->dmabuff_recycle, &vb))
+ return;
- buf = container_of(vb, struct aml_video_dec_buf, vb);
+ buf = container_of(vb, struct aml_v4l2_buf, vb);
- if (ctx->is_out_stream_off)
- continue;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
+ "recycle buff idx: %d, vbuf: %lx\n", vb->vb2_buf.index,
+ buf->addr ? buf->addr: (ulong)sg_dma_address(buf->out_sgt->sgl));
- if (wait_event_interruptible_timeout
- (ctx->wq, buf->used == false,
- msecs_to_jiffies(200)) == 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "wait recycle dma buff timeout.\n");
- }
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_9, vb->vb2_buf.index);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
- "recycle buff idx: %d, vbuf: %lx\n", vb->vb2_buf.index,
- (ulong)sg_dma_address(buf->out_sgt->sgl));
-
- ATRACE_COUNTER("VO_OUT_VSINK-2.write_secure_end", vb->vb2_buf.index);
-
- if (vb->vb2_buf.state != VB2_BUF_STATE_ERROR)
- v4l2_buff_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
- VB2_BUF_STATE_DONE);
- }
+ if (vb->vb2_buf.state != VB2_BUF_STATE_ERROR)
+ v4l2_buff_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
+ VB2_BUF_STATE_DONE);
}
void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle)
@@ -1429,44 +1438,51 @@
struct vb2_v4l2_buffer *vb = NULL;
struct vb2_queue *q = NULL;
int index = handle & 0xf;
- unsigned long flags;
+ ulong flags;
- if (ctx->is_out_stream_off) {
+retry:
+ spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+
+ if (ctx->es_wkr_stop) {
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
"ignore buff idx: %d streamoff\n", index);
return;
}
+ if (work_pending(&ctx->es_wkr_out)) {
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
+ flush_work(&ctx->es_wkr_out);
+
+ goto retry;
+ }
+
q = v4l2_m2m_get_vq(ctx->m2m_ctx,
V4L2_BUF_TYPE_VIDEO_OUTPUT);
vb = to_vb2_v4l2_buffer(q->bufs[index]);
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
kfifo_put(&ctx->dmabuff_recycle, vb);
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
- queue_work(dev->decode_workqueue, &ctx->dmabuff_recycle_work);
+ queue_work(dev->decode_workqueue, &ctx->es_wkr_out);
+
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
}
static void aml_vdec_worker(struct work_struct *work)
{
struct aml_vcodec_ctx *ctx =
- container_of(work, struct aml_vcodec_ctx, decode_work);
+ container_of(work, struct aml_vcodec_ctx, es_wkr_in);
struct aml_vcodec_dev *dev = ctx->dev;
- struct aml_video_dec_buf *aml_buf;
+ struct aml_v4l2_buf *aml_vb;
struct vb2_v4l2_buffer *vb2_v4l2;
struct vb2_buffer *vb;
struct aml_vcodec_mem buf;
bool res_chg = false;
int ret;
- if (ctx->state < AML_STATE_INIT ||
- ctx->state > AML_STATE_FLUSHED) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- goto out;
- }
-
if (!is_vdec_ready(ctx)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"the decoder has not ready.\n");
@@ -1482,50 +1498,21 @@
vb = (struct vb2_buffer *)vb2_v4l2;
- /*this case for google, but some frames are droped on ffmpeg, so disabled temp.*/
- if (0 && !is_enough_work_items(ctx))
- goto out;
-
- aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- if (aml_buf->lastframe) {
- ulong expires;
-
- /*the empty data use to flushed the decoder.*/
+ aml_vb = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+ if (aml_vb->lastframe) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"Got empty flush input buffer.\n");
- /*
- * when inputs a small amount of src buff, then soon to
- * switch state FLUSHING, must to wait the DBP to be ready.
- * (!ctx->v4l_codec_dpb_ready) change to only need one buf
- * for run ready in new version.
- */
- expires = jiffies + msecs_to_jiffies(5000);
- while ((vdec_frame_number(ctx->ada_ctx) > 0) &&
- (ctx->cap_pool.in < 1)) {
- if (time_after(jiffies, expires)) {
- aml_vdec_flush_decoder(ctx);
- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "capture buffer waiting timeout.\n");
- goto out;
- }
- usleep_range(5000, 5500);
- }
-
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_ACTIVE) {
ctx->state = AML_STATE_FLUSHING;// prepare flushing
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_FLUSHING-LASTFRM)\n");
}
mutex_unlock(&ctx->state_lock);
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
/* sets eos data for vdec input. */
aml_vdec_flush_decoder(ctx);
@@ -1533,23 +1520,35 @@
goto out;
}
+ if (ctx->stream_mode &&
+ !(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+ struct dmabuf_dmx_sec_es_data *es_data = (struct dmabuf_dmx_sec_es_data *)aml_vb->dma_buf;
+ int offset = vb->planes[0].data_offset;
+ buf.addr = es_data->data_start + offset;
+ buf.size = vb->planes[0].bytesused - offset;
+ buf.dbuf = vb->planes[0].dbuf;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, "stream update wp 0x%lx + sz 0x%x offset 0x%x ori start 0x%x ts %llu\n",
+ buf.addr, buf.size, offset, es_data->data_start, vb->timestamp);
+ } else {
+ buf.addr = aml_vb->addr ? aml_vb->addr : sg_dma_address(aml_vb->out_sgt->sgl);
+ buf.size = vb->planes[0].bytesused;
+ }
buf.index = vb->index;
- buf.vaddr = vb2_plane_vaddr(vb, 0);
- buf.addr = sg_dma_address(aml_buf->out_sgt->sgl);
- buf.size = vb->planes[0].bytesused;
+ if (!ctx->is_drm_mode)
+ buf.vaddr = vb2_plane_vaddr(vb, 0);
+
buf.model = vb->memory;
- buf.timestamp = vb->timestamp;
- buf.meta_ptr = (ulong)aml_buf->meta_data;
+ buf.timestamp = vb->timestamp;
+ buf.meta_ptr = (ulong)aml_vb->meta_data;
if (!buf.vaddr && !buf.addr) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"id=%d src_addr is NULL.\n", vb->index);
goto out;
}
- aml_buf->used = true;
-
/* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"size: 0x%zx, crc: 0x%x\n",
buf.size, crc32(0, buf.va, buf.size));*/
@@ -1558,86 +1557,42 @@
/*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"timestamp: 0x%llx\n", src_buf->timestamp);*/
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- ATRACE_COUNTER("VO_IN_VSINK-2.write_secure", buf.size);
+ if ((!ctx->stream_mode) && ctx->output_dma_mode) {
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_3, buf.size);
} else {
- ATRACE_COUNTER("VO_IN_VSINK-2.write", buf.size);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_2, buf.size);
}
- ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_1, vdec_frame_number(ctx->ada_ctx));
ret = vdec_if_decode(ctx, &buf, &res_chg);
if (ret > 0) {
- /*
- * we only return src buffer with VB2_BUF_STATE_DONE
- * when decode success without resolution change.
- */
- aml_buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
- ATRACE_COUNTER("VO_OUT_VSINK-0.wrtie_end", buf.size);
- v4l2_buff_done(&aml_buf->vb,
+ /* frame mode and non-dbuf mode. */
+ if (ctx->stream_mode || !ctx->output_dma_mode) {
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_8, buf.size);
+ v4l2_buff_done(&aml_vb->vb,
VB2_BUF_STATE_DONE);
}
} else if (ret && ret != -EAGAIN) {
- aml_buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
- ATRACE_COUNTER("VO_OUT_VSINK-3.write_error", buf.size);
- v4l2_buff_done(&aml_buf->vb,
+ /* frame mode and non-dbuf mode. */
+ if (ctx->stream_mode || !ctx->output_dma_mode) {
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_10, buf.size);
+ v4l2_buff_done(&aml_vb->vb,
VB2_BUF_STATE_ERROR);
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"error processing src data. %d.\n", ret);
- } else if (res_chg) {
- /* wait the DPB state to be ready. */
- aml_wait_buf_ready(ctx);
-
- aml_buf->used = false;
- aml_vdec_pic_info_update(ctx);
- /*
- * On encountering a resolution change in the stream.
- * The driver must first process and decode all
- * remaining buffers from before the resolution change
- * point, so call flush decode here
- */
- mutex_lock(&ctx->state_lock);
- if (ctx->state == AML_STATE_ACTIVE) {
- ctx->state = AML_STATE_FLUSHING;// prepare flushing
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
- "vcodec state (AML_STATE_FLUSHING-RESCHG)\n");
- }
- mutex_unlock(&ctx->state_lock);
-
- ctx->v4l_resolution_change = true;
- while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
- v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
- }
-
- aml_vdec_flush_decoder(ctx);
-
- goto out;
} else {
- ATRACE_COUNTER("VO_OUT_VSINK-1.write_again", buf.size);
- /* decoder is lack of resource, retry after short delay */
- if (vdec_get_instance_num() < 2)
- usleep_range(2000, 4000);
+ /* ES frame write again. */
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_11, buf.size);
}
-
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
out:
- return;
+ v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
}
static void aml_vdec_reset(struct aml_vcodec_ctx *ctx)
@@ -1648,15 +1603,29 @@
goto out;
}
+ aml_codec_disconnect(ctx->ada_ctx);
+
if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) {
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT).\n");
}
out:
complete(&ctx->comp);
- return;
+}
+
+void stop_pipeline(struct aml_vcodec_ctx *ctx)
+{
+ if (ctx->ge2d) {
+ aml_v4l2_ge2d_thread_stop(ctx->ge2d);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "ge2d stop.\n");
+ }
+
+ if (ctx->vpp) {
+ aml_v4l2_vpp_thread_stop(ctx->vpp);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "vpp stop\n");
+ }
}
void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
@@ -1666,26 +1635,21 @@
ctx->is_stream_off = true;
/* flush output buffer worker. */
- cancel_work_sync(&ctx->decode_work);
- cancel_work_sync(&ctx->dmabuff_recycle_work);
+ cancel_work_sync(&ctx->es_wkr_in);
+ cancel_work_sync(&ctx->es_wkr_out);
/* clean output cache and decoder status . */
if (ctx->state > AML_STATE_INIT)
aml_vdec_reset(ctx);
- /* pause the job and clean trans status. */
- while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
- v4l2_m2m_job_pause(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
- }
-
- ctx->v4l_codec_dpb_ready = false;
+ stop_pipeline(ctx);
}
void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx)
{
struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *aml_buff = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_v4l2_buf *aml_buff = NULL;
+ struct aml_buf *aml_buf = NULL;
for (;;) {
mutex_lock(&ctx->capture_buffer_lock);
@@ -1695,13 +1659,13 @@
}
mutex_unlock(&ctx->capture_buffer_lock);
- aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
- fb = &aml_buff->frame_buffer;
+ aml_buff = container_of(vb, struct aml_v4l2_buf, vb);
+ aml_buf = aml_buff->aml_buf;
if (ctx->is_stream_off)
continue;
- post_frame_to_upper(ctx, fb);
+ post_frame_to_upper(ctx, aml_buf);
}
}
EXPORT_SYMBOL_GPL(aml_thread_capture_worker);
@@ -1870,13 +1834,15 @@
return 0;
}
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
- V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!vb2_is_streaming(dst_vq)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "Capture stream is off. No need to flush.\n");
- return 0;
+ if ((vdec_frame_number(ctx->ada_ctx) <= 0) && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) == 0)) {
+ dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+ multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ if (!vb2_is_streaming(dst_vq)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "Capture stream is off. No need to flush.\n");
+ return 0;
+ }
}
/* flush pipeline */
@@ -1884,7 +1850,7 @@
v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
ctx->receive_cmd_stop = true;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"%s, receive cmd stop and prepare flush pipeline.\n", __func__);
break;
@@ -1894,7 +1860,7 @@
V4L2_BUF_TYPE_VIDEO_CAPTURE);
vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"%s, receive cmd start.\n", __func__);
break;
@@ -1905,6 +1871,272 @@
return 0;
}
+ulong get_addr(struct vb2_buffer *vb, int i)
+{
+ struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
+ struct vb2_v4l2_buffer, vb2_buf);
+ struct aml_v4l2_buf *buf = container_of(vb2_v4l2,
+ struct aml_v4l2_buf, vb);
+ struct aml_buf *am_buf = buf->aml_buf;
+
+ return am_buf->is_delay_allocated ?
+ sg_dma_address(am_buf->cap_sgt->sgl) :
+ vb2_dma_contig_plane_dma_addr(vb, i);
+}
+
+static void aml_uvm_buf_delay_free(struct uvm_buf_obj *obj)
+{
+ struct mua_buffer *mbuf;
+ struct aml_vcodec_ctx *ctx = obj->arg;
+
+ mbuf = container_of(obj, struct mua_buffer, base);
+ if (!mbuf)
+ return;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s ion buffer:%px/%px, dbuf:%px/%px\n",
+ __func__, mbuf->ibuffer[0], mbuf->ibuffer[1],
+ mbuf->idmabuf[0], mbuf->idmabuf[1]);
+
+ if (mbuf->idmabuf[0]) {
+ dma_buf_put(mbuf->idmabuf[0]);
+ }
+ if (mbuf->idmabuf[1]) {
+ dma_buf_put(mbuf->idmabuf[1]);
+ }
+
+ kfree(mbuf);
+}
+
+static void aml_uvm_copy_sgt(struct sg_table *dst_table,
+ struct sg_table *src_table)
+{
+ struct scatterlist *dst_sgl = NULL;
+ struct scatterlist *src_sgl = NULL;
+ int i;
+
+ dst_table->nents = src_table->nents;
+ dst_table->orig_nents = src_table->orig_nents;
+
+ dst_sgl = dst_table->sgl;
+ src_sgl = src_table->sgl;
+
+ for (i = 0; i < src_table->nents; i++) {
+ sg_set_page(dst_sgl, sg_page(src_sgl), src_sgl->length, 0);
+ sg_dma_address(dst_sgl) = sg_phys(src_sgl);
+ sg_dma_len(dst_sgl) = sg_dma_len(src_sgl);
+ dst_sgl = sg_next(dst_sgl);
+ src_sgl = sg_next(src_sgl);
+ }
+}
+
+static int aml_uvm_buf_delay_alloc(struct aml_vcodec_ctx *ctx,
+ struct vb2_v4l2_buffer *vb)
+{
+ struct aml_v4l2_buf *buf =
+ container_of(vb, struct aml_v4l2_buf, vb);
+ struct aml_buf *am_buf = buf->aml_buf;
+ struct dma_buf *dbuf = vb->vb2_buf.planes[0].dbuf;
+ struct device *dev = vb->vb2_buf.vb2_queue->alloc_devs[0];
+ struct uvm_handle *handle;
+ struct mua_buffer *mbuf = NULL;
+ struct dma_buf *idbuf = NULL;
+ struct uvm_alloc *ua = NULL;
+ struct uvm_buf_obj *obj = NULL;
+ /* ion heap*/
+ struct ion_buffer *ibuf = NULL;
+ struct page *page = NULL;
+
+ u64 time = local_clock();
+ struct sg_table *cap_sgt;
+ struct aml_uvm_buff_ref *ubuf = (struct aml_uvm_buff_ref *)am_buf->uvm_buf;
+ struct sg_table *sgt;
+ struct dma_buf_attachment *dba = NULL;
+
+ if (!ctx->enable_di_post || ctx->picinfo.field == V4L2_FIELD_NONE ||
+ !is_vdec_core_fmt(ctx))
+ return 0;
+
+ if ((vb->vb2_buf.memory != VB2_MEMORY_DMABUF) ||
+ !dbuf ||
+ !dmabuf_is_uvm(dbuf) ||
+ am_buf->is_delay_allocated)
+ return 0;
+
+ obj = dmabuf_get_uvm_buf_obj(dbuf);
+ mbuf = container_of(obj, struct mua_buffer, base);
+
+ /* free fake dma buffer. */
+ if (mbuf->idmabuf[0])
+ dma_buf_put(mbuf->idmabuf[0]);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "dma buffer size(fake: %zu, real: %d)\n",
+ mbuf->size,
+ ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz);
+
+ mbuf->size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
+
+ handle = dbuf->priv;
+
+ if (ctx->master_buf) {
+ struct aml_buf *master_buf = ctx->master_buf;
+
+ if (master_buf->pair_state == MASTER_DONE) {
+ master_buf->sub_buf[0] = (void *)am_buf;
+ am_buf->master_buf = (void *)master_buf;
+ am_buf->pair = BUF_SUB0;
+ aml_buf_put(&ctx->bm, am_buf);
+ }
+
+ if (master_buf->pair_state == SUB0_DONE) {
+ master_buf->sub_buf[1] = (void *)am_buf;
+ am_buf->master_buf = (void *)master_buf;
+ am_buf->pair = BUF_SUB1;
+ aml_buf_put(&ctx->bm, am_buf);
+ }
+
+ am_buf->is_delay_allocated = true;
+ master_buf->pair_state++;
+ if (master_buf->pair_state == PAIR_DONE)
+ ctx->master_buf = NULL;
+ else
+ aml_buf_get_ref(&ctx->bm, master_buf);
+ idbuf = master_buf->idmabuf[0];
+ sgt = master_buf->cap_sgt;
+ get_dma_buf(idbuf);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "[Paired]index(%d, %d), pair(%d), uvm dbuf: %px\n",
+ master_buf->index, am_buf->index, am_buf->pair,dbuf);
+ } else {
+ if (ctx->alloc_type) { /* ion */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
+ u32 flags = 0;
+
+ /* alloc real ion buffer relace older one. */
+ if (mbuf->ion_flags & MUA_USAGE_PROTECTED)
+ flags |= ION_FLAG_PROTECTED;
+
+ flags |= ION_FLAG_EXTEND_MESON_HEAP;
+
+ idbuf = ion_alloc(mbuf->size, (1 << ION_HEAP_TYPE_CUSTOM), flags);
+ if (IS_ERR(idbuf) || !idbuf->priv) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s: ion alloc fail.\n", __func__);
+ return -ENOMEM;
+ }
+#endif
+ } else { /* dma heap */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+ char *name = CODECMM_HEAP_NAME;
+ struct dma_heap *heap;
+
+ /* alloc real dma buffer relace older one. */
+ if (mbuf->ion_flags & MUA_USAGE_PROTECTED)
+ name = CODECMM_SECURE_HEAP_NAME;
+ else if (mbuf->ion_flags & MUA_BUFFER_CACHED)
+ name = CODECMM_CACHED_HEAP_NAME;
+
+ heap = dma_heap_find(name);
+ if (!heap) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s: dma_heap_find fail. heap name is %s\n", __func__, name);
+ return -ENOMEM;
+ }
+ idbuf = dma_heap_buffer_alloc(heap, mbuf->size, O_RDWR,
+ DMA_HEAP_VALID_HEAP_FLAGS);
+
+ /* create attachment for the dmabuf with the user device */
+ dba = dma_buf_attach(idbuf, dev);
+ if (IS_ERR(dba)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "failed to attach dmabuf\n");
+ return 0;
+ }
+
+ /* get the associated scatterlist for this buffer */
+ sgt = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sgt)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Error getting dmabuf scatterlist\n");
+ return 0;
+ }
+#endif
+ }
+
+ ctx->master_buf = am_buf;
+ am_buf->pair_state++;
+ am_buf->pair = BUF_MASTER;
+ aml_buf_get_ref(&ctx->bm, am_buf);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "[Pairing]index(%d), pair(%d), uvm dbuf: %px\n",
+ am_buf->index, am_buf->pair, dbuf);
+ }
+
+ /* replace free cb. */
+ ua = handle->ua;
+ ua->obj->arg = ctx;
+ ua->obj->dev = dev;
+ ua->free = aml_uvm_buf_delay_free;
+
+ if (ctx->alloc_type) {
+ ibuf = idbuf->priv;
+ page = sg_page(ibuf->sg_table->sgl);
+ mbuf->paddr = PFN_PHYS(page_to_pfn(page));
+ mbuf->sg_table = ibuf->sg_table;
+ mbuf->ibuffer[0] = ibuf;
+ mbuf->idmabuf[0] = idbuf;
+ sgt = ibuf->sg_table;
+ } else {
+ mbuf->paddr = sg_dma_address(sgt->sgl);
+ mbuf->sg_table = ua->sgt;
+ mbuf->ibuffer[0] = (void *)idbuf->priv;
+ mbuf->idmabuf[0] = idbuf;
+ }
+ am_buf->idmabuf[0] = idbuf;
+ /* update sg table. */
+ aml_uvm_copy_sgt(ua->sgt, sgt);
+
+ /* fill aml buffer information. */
+ am_buf->cap_sgt = ua->sgt;
+ cap_sgt = vb2_dma_sg_plane_desc(&vb->vb2_buf, 0);
+ memcpy(cap_sgt, am_buf->cap_sgt, sizeof(struct sg_table));
+ am_buf->is_delay_allocated = true;
+ ubuf->addr = get_addr(&vb->vb2_buf, 0);
+
+ if (am_buf->pair == BUF_MASTER) {
+ /* no need clear cache. If dev is ion, the cache has been flushed in ion_alloc;
+ * if dev is dma heap, dma_buf_map_attachment includes flush cache operation */
+ #if 0
+ /* clear cache. */
+ if (dma_map_sg(dev, mbuf->sg_table->sgl,
+ mbuf->sg_table->nents, DMA_FROM_DEVICE) <= 0) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "dma map sg %u bytes error\n", (u32)mbuf->size);
+ return -ENOMEM;
+ }
+ dma_sync_sg_for_device(dev, mbuf->sg_table->sgl,
+ mbuf->sg_table->nents, DMA_FROM_DEVICE);
+
+ dma_unmap_sg(ua->obj->dev, mbuf->sg_table->sgl,
+ mbuf->sg_table->nents, DMA_FROM_DEVICE);
+ #endif
+ /* unmap attachment and detach dbuf */
+ if (dba) {
+ dma_buf_unmap_attachment(dba, sgt, DMA_BIDIRECTIONAL);
+ dma_buf_detach(mbuf->idmabuf[0], dba);
+ }
+ }
+
+ aml_buf_update(&ctx->bm, get_addr(&vb->vb2_buf, 0), am_buf);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, Res:%ux%u, stride:%d, addr:%lx, size:%u, flags:%x, cost:%llu ms\n",
+ __func__, mbuf->width, mbuf->height, mbuf->byte_stride,
+ (ulong)mbuf->paddr, (u32)mbuf->size, mbuf->ion_flags,
+ div64_u64(local_clock() - time, 1000000));
+
+ return 0;
+}
+
static void aml_wait_resource(struct aml_vcodec_ctx *ctx)
{
ulong expires = jiffies + msecs_to_jiffies(1000);
@@ -1929,6 +2161,22 @@
q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
ctx->is_stream_off) {
+ if (ctx->ge2d_is_need) {
+ int ret;
+
+ if (ctx->ge2d) {
+ aml_v4l2_ge2d_destroy(ctx->ge2d);
+ ctx->ge2d = NULL;
+ }
+
+ ret = aml_v4l2_ge2d_init(ctx, &ctx->ge2d_cfg, &ctx->ge2d);
+ if (ret) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "ge2d_wrapper init err:%d\n", ret);
+ return ret;
+ }
+ }
+
if (ctx->vpp_is_need) {
int ret;
@@ -1948,22 +2196,21 @@
aml_v4l2_vpp_reset(ctx->vpp);
} else {
if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
aml_v4l2_vpp_destroy(ctx->vpp);
+ atomic_dec(&ctx->dev->vpp_count);
ctx->vpp = NULL;
}
-
+ atomic_inc(&ctx->dev->vpp_count);
ret = aml_v4l2_vpp_init(ctx, &ctx->vpp_cfg, &ctx->vpp);
if (ret) {
+ atomic_dec(&ctx->dev->vpp_count);
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"vpp_wrapper init err:%d vpp_cfg.fmt: %d\n",
ret, ctx->vpp_cfg.fmt);
return ret;
}
- atomic_inc(&ctx->dev->vpp_count);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"vpp_wrapper instance count: %d\n",
atomic_read(&ctx->dev->vpp_count));
}
@@ -1979,32 +2226,30 @@
ctx->vpp_cfg.is_vpp_reset = false;
} else {
if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
aml_v4l2_vpp_destroy(ctx->vpp);
+ atomic_dec(&ctx->dev->vpp_count);
ctx->vpp = NULL;
}
}
- if (ctx->ge2d_is_need) {
- int ret;
-
- if (ctx->ge2d) {
- aml_v4l2_ge2d_destroy(ctx->ge2d);
- ctx->ge2d = NULL;
- }
-
- ret = aml_v4l2_ge2d_init(ctx, &ctx->ge2d_cfg, &ctx->ge2d);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d_wrapper init err:%d\n", ret);
- return ret;
- }
- }
-
ctx->is_stream_off = false;
- } else
+ } else {
ctx->is_out_stream_off = false;
+ ctx->es_wkr_stop = false;
+ aml_codec_connect(ctx->ada_ctx); /* for seek */
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ if (ctx->dv_id < 0) {
+ dv_inst_map(&ctx->dv_id);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s: dv_inst_map ctx %p, dv_id %d\n",__func__, ctx, ctx->dv_id);
+ }
+#endif
+ }
+ if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+ memset(&ctx->decoder_status_info, 0,
+ sizeof(ctx->decoder_status_info));
+ }
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d\n", __func__, q->type);
@@ -2087,9 +2332,14 @@
ctx->vpp_size);
//rb->count = ctx->dpb_size;
}
+ ctx->v4l_reqbuff_flag = true;
+ ctx->capture_memory_mode = rb->memory;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
+ "capture buffer memory mode is %d\n", rb->memory);
} else {
ctx->output_dma_mode =
(rb->memory == VB2_MEMORY_DMABUF) ? 1 : 0;
+ vdec_set_dmabuf_type(ctx->ada_ctx, ctx->output_dma_mode);
v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
"output buffer memory mode is %d\n", rb->memory);
@@ -2120,16 +2370,252 @@
return v4l2_m2m_ioctl_expbuf(file, priv, eb);
}
+static bool is_turn_around(struct aml_es_ref_elem *elem)
+{
+ return (elem->au_addr + elem->au_size) >=
+ (elem->buf_start + elem->buf_size);
+}
+
+static ulong get_remain_pos(struct aml_es_ref_elem *elem)
+{
+ return is_turn_around(elem) ?
+ elem->buf_start + (elem->au_size -
+ (elem->buf_start + elem->buf_size - elem->au_addr)) :
+ elem->au_addr + elem->au_size;
+}
+
+static int aml_es_ref_que(struct aml_es_mgr *stmgr, struct dma_buf *dbuf,
+ ulong addr, u32 size, u64 timestamp)
+{
+ struct aml_es_ref_elem *elem;
+
+ /* 1.Get stbuf from free pool. */
+ if (!kfifo_get(&stmgr->free_q, &elem)) {
+ v4l_dbg(stmgr->ctx, 0, "Get elem from free queue fail.\n");
+ return -EBADSLT;
+ }
+
+ /* 2.Fill stbuf info from dbuf. */
+ elem->dbuf = dbuf;
+ elem->buf_start = stmgr->buf_start;
+ elem->buf_size = stmgr->buf_size;
+ elem->au_addr = addr;
+ elem->au_size = size;
+ elem->timestamp = timestamp;
+
+ if (stmgr->cursor_Wp == -1)
+ stmgr->cursor_Wp = elem->au_addr;
+
+ /* 3.Get dmabuf ref in driver. */
+ get_dma_buf(elem->dbuf);
+
+ atomic_inc(&stmgr->buf_cache);
+
+ /* 4.Add stbuf into the management queue. */
+ kfifo_put(&stmgr->ref_q, elem);
+ v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+ "Get-ref, CPB(%lx, %d), AU(%lx, %d, %d), "
+ "cursor_Wp:%lx, ts:%llu, buf_cache:%d\n",
+ elem->buf_start,
+ elem->buf_size,
+ elem->au_addr,
+ elem->au_size,
+ is_turn_around(elem),
+ stmgr->cursor_Wp,
+ elem->timestamp,
+ atomic_read(&stmgr->buf_cache));
+
+ return 0;
+}
+
+static void aml_es_put_ref(struct aml_es_mgr *stmgr,
+ struct aml_es_ref_elem *elem)
+{
+ /* Update cursor Wp. */
+ stmgr->cursor_Wp = get_remain_pos(elem);
+ atomic_dec(&stmgr->buf_cache);
+ v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+ "Put-ref, CPB(%lx, %d), AU(%lx, %d, %d), "
+ "cursor_Wp:%lx, ts:%llu, buf_cache:%d\n",
+ elem->buf_start,
+ elem->buf_size,
+ elem->au_addr,
+ elem->au_size,
+ is_turn_around(elem),
+ stmgr->cursor_Wp,
+ elem->timestamp,
+ atomic_read(&stmgr->buf_cache));
+
+ dma_buf_put(elem->dbuf);
+
+ kfifo_put(&stmgr->free_q, elem);
+}
+
+static int aml_es_ref_dque(struct aml_es_mgr *stmgr, ulong Rp)
+{
+ struct aml_es_ref_elem *elem;
+ ulong cursor_Wp = stmgr->cursor_Wp;
+
+ v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+ "Put-ref-start, cursor_Wp:%lx, Rp:%lx\n", cursor_Wp, Rp);
+
+ /* Get stbuf from management queue. */
+ if (kfifo_is_empty(&stmgr->ref_q)) {
+ v4l_dbg(stmgr->ctx, 0, "There is no ref elem to process.\n");
+ return 0;
+ }
+retry:
+ if (!kfifo_peek(&stmgr->ref_q, &elem)) {
+ v4l_dbg(stmgr->ctx, 0, "Peek elem from ref queue fail.\n");
+ return -EINVAL;
+ }
+
+ /* Checks the stbuf whether was consumed. */
+ if (Rp >= cursor_Wp) {
+ /*
+ * If Rp is to the right of the cursor_Wp, except the AU_end
+ * with around, the others just should be checked Rp >= AU_end,
+ * means that the AU-data has been consumed.
+ */
+ if (!is_turn_around(elem) &&
+ (Rp >= get_remain_pos(elem))) {
+ if (!kfifo_get(&stmgr->ref_q, &elem)) {
+ v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+ return -EINVAL;
+ }
+
+ aml_es_put_ref(stmgr, elem);
+
+ if (!kfifo_is_empty(&stmgr->ref_q))
+ goto retry;
+ }
+ } else {
+ /*
+ * Otherwise, there are 2 cases:
+ * 1. As long as the AU-data is on the right side of the cursor_Wp
+ * and the AU_end is not around, then the AU-data is consumed
+ * 2. If Rp > AU_end then indicates that the AU-data is consumed.
+ */
+ if ((!is_turn_around(elem) &&
+ (elem->au_addr >= cursor_Wp)) ||
+ (Rp >= get_remain_pos(elem))) {
+ if (!kfifo_get(&stmgr->ref_q, &elem)) {
+ v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+ return -EINVAL;
+ }
+
+ aml_es_put_ref(stmgr, elem);
+
+ if (!kfifo_is_empty(&stmgr->ref_q))
+ goto retry;
+ }
+ }
+
+ return 0;
+}
+
+int aml_es_write(struct aml_vcodec_ctx *ctx, struct dma_buf *dbuf,
+ ulong addr, u32 size, u64 timestamp)
+{
+ int ret = -1;
+
+ /* 1.Increase dmabuf reference. */
+ ret = aml_es_ref_que(&ctx->es_mgr, dbuf, addr, size, timestamp);
+ if (ret)
+ return ret;
+
+ /* 2.PTS checkin. */
+ ctx->pts_serves_ops->checkin(ctx->ptsserver_id, size, timestamp);
+
+ return ret;
+}
+
+void aml_es_input_free(struct aml_vcodec_ctx *ctx, ulong addr)
+{
+ aml_es_ref_dque(&ctx->es_mgr, addr);
+}
+
+int aml_es_mgr_init(struct aml_vcodec_ctx *ctx)
+{
+ struct aml_es_ref_elem *elems = NULL;
+ struct aml_es_mgr *stmgr = &ctx->es_mgr;
+ int ret = -1, i;
+
+ INIT_KFIFO(stmgr->free_q);
+ INIT_KFIFO(stmgr->ref_q);
+
+ ret = kfifo_alloc(&stmgr->free_q, AML_ES_REF_MAX, GFP_KERNEL);
+ if (ret) {
+ v4l_dbg(stmgr->ctx, 0, "Alloc free_q fifo fail.\n");
+ return -ENOMEM;
+ }
+
+ ret = kfifo_alloc(&stmgr->ref_q, AML_ES_REF_MAX, GFP_KERNEL);
+ if (ret) {
+ kfifo_free(&stmgr->free_q);
+ v4l_dbg(stmgr->ctx, 0, "Alloc ref_q fifo fail.\n");
+ return -ENOMEM;
+ }
+
+ elems = vzalloc(sizeof(*elems) * AML_ES_REF_MAX);
+ if (!elems) {
+ kfifo_free(&stmgr->free_q);
+ kfifo_free(&stmgr->ref_q);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < AML_ES_REF_MAX; i++) {
+ kfifo_put(&stmgr->free_q, &elems[i]);
+ }
+
+ atomic_set(&stmgr->buf_cache, 0);
+
+ stmgr->cursor_Wp = -1;
+ stmgr->elems = elems;
+ stmgr->ctx = ctx;
+
+ return 0;
+}
+
+void aml_es_mgr_release(struct aml_vcodec_ctx *ctx)
+{
+ struct aml_es_ref_elem *elem;
+ struct aml_es_mgr *stmgr = &ctx->es_mgr;
+
+ if (!stmgr->elems)
+ return;
+
+retry:
+ if (!kfifo_is_empty(&stmgr->ref_q)) {
+ if (!kfifo_get(&stmgr->ref_q, &elem)) {
+ v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+ goto out;
+ }
+
+ aml_es_put_ref(stmgr, elem);
+
+ goto retry;
+ }
+out:
+ kfifo_free(&stmgr->free_q);
+
+ kfifo_free(&stmgr->ref_q);
+
+ vfree(stmgr->elems);
+}
+
void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx)
{
ulong flags;
-
- if (kref_read(&ctx->box_ref))
- kref_put(&ctx->box_ref, box_release);
+ if (ctx->capture_memory_mode == VB2_MEMORY_MMAP) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,"clean proxy uvm\n");
+ aml_clean_proxy_uvm(ctx);
+ } else
+ aml_buf_put_dma(&ctx->bm);
flags = aml_vcodec_ctx_lock(ctx);
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT)\n");
aml_vcodec_ctx_unlock(ctx, flags);
@@ -2141,15 +2627,21 @@
{
struct aml_q_data *q_data;
- ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+ ctx->m2m_ctx->q_lock = &ctx->v4l_intf_lock;
ctx->fh.m2m_ctx = ctx->m2m_ctx;
ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
- INIT_WORK(&ctx->decode_work, aml_vdec_worker);
+ INIT_WORK(&ctx->es_wkr_in, aml_vdec_worker);
ctx->colorspace = V4L2_COLORSPACE_REC709;
ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
ctx->dev->dec_capability = 0;//VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+ ctx->dev->dec_capability = VCODEC_CAPABILITY_4K_DISABLED;
+ }
+
+ if (t3x_tw_output && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X))
+ ctx->force_tw_output = 1;
q_data = &ctx->q_data[AML_Q_DATA_SRC];
memset(q_data, 0, sizeof(struct aml_q_data));
@@ -2186,13 +2678,18 @@
q_data->bytesperline[0] = q_data->coded_width;
q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
q_data->bytesperline[1] = q_data->coded_width;
+
+ q_data->sizeimage_tw[0] = q_data->sizeimage[0];
+ q_data->bytesperline_tw[0] = q_data->bytesperline[0];
+ q_data->sizeimage_tw[1] = q_data->sizeimage[1];
+ q_data->bytesperline_tw[1] = q_data->bytesperline[1];
+
ctx->reset_flag = V4L_RESET_MODE_NORMAL;
- ctx->fb_ops.query = fb_buff_query;
- ctx->fb_ops.alloc = fb_buff_from_queue;
+ vdec_trace_init(&ctx->vtr, ctx->id, -1);
ctx->state = AML_STATE_IDLE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_IDLE)\n");
}
@@ -2218,20 +2715,22 @@
if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->m.planes[0].bytesused);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_1, buf->m.planes[0].bytesused);
else
- ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->m.planes[0].bytesused);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_0, buf->m.planes[0].bytesused);
} else {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->length);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_1, buf->length);
else
- ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->length);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_0, buf->length);
}
+
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_12, timeval_to_ns(&buf->timestamp));
} else {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VC_IN_VSINK-1.que_again", buf->index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_1, buf->index);
else
- ATRACE_COUNTER("VC_IN_VSINK-0.que", buf->index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_0, buf->index);
}
return ret;
@@ -2255,47 +2754,26 @@
}
ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
- if (!ret && !V4L2_TYPE_IS_OUTPUT(buf->type)) {
- struct vb2_queue *vq;
- struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- struct file *file = NULL;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
- vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]);
- aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- aml_buf->privdata.vb_handle = (ulong) aml_buf;
- aml_buf->privdata.v4l_dec_ctx = (ulong) ctx;
-
- file = fget(vb2_v4l2->private);
- if (file && is_v4l2_buf_file(file)) {
- dmabuf_fd_install_data(vb2_v4l2->private,
- (void*)&aml_buf->privdata,
- sizeof(struct file_private_data));
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "disp: %d, vf: %lx\n",
- aml_buf->privdata.vf.index_disp,
- (ulong) v4l_get_vf_handle(vb2_v4l2->private));
- fput(file);
- }
- }
if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->m.planes[0].bytesused);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_7, buf->m.planes[0].bytesused);
else
- ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->m.planes[0].bytesused);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_6, buf->m.planes[0].bytesused);
} else {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->length);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_7, buf->length);
else
- ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->length);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_6, buf->length);
}
} else {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VC_OUT_VSINK-3.deque_again", buf->index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_8, buf->index);
else
- ATRACE_COUNTER("VC_OUT_VSINK-2.deque", buf->index);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_7, buf->index);
+
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_9, timeval_to_ns(&buf->timestamp));
}
return ret;
@@ -2330,6 +2808,10 @@
return v4l2_event_subscribe(fh, sub, 2, NULL);
case V4L2_EVENT_SOURCE_CHANGE:
return v4l2_src_change_event_subscribe(fh, sub);
+ case V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME:
+ return v4l2_event_subscribe(fh, sub, 10, NULL);
+ case V4L2_EVENT_PRIVATE_EXT_SEND_ERROR:
+ return v4l2_event_subscribe(fh, sub, 5, NULL);
default:
return v4l2_ctrl_subscribe_event(fh, sub);
}
@@ -2346,7 +2828,8 @@
return v4l2_event_unsubscribe(fh, sub);
}
-static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
+static int vidioc_try_fmt(struct aml_vcodec_ctx *ctx, struct v4l2_format *f,
+ struct aml_video_fmt *fmt)
{
int i;
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
@@ -2365,7 +2848,7 @@
if (pix_mp->field == V4L2_FIELD_ANY)
pix_mp->field = V4L2_FIELD_NONE;
- pr_info("%s, field: %u, fmt: %x\n",
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, field: %u, fmt: %x\n",
__func__, pix_mp->field,
pix_mp->pixelformat);
}
@@ -2408,7 +2891,7 @@
if (pix->field == V4L2_FIELD_ANY)
pix->field = V4L2_FIELD_NONE;
- pr_info("%s, field: %u, fmt: %x\n",
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, field: %u, fmt: %x\n",
__func__, pix->field,
pix->pixelformat);
}
@@ -2468,7 +2951,7 @@
fmt = aml_vdec_find_format(f);
}
- vidioc_try_fmt(f, fmt);
+ vidioc_try_fmt(ctx, f, fmt);
q_data = aml_vdec_get_q_data(ctx, f->type);
if (!q_data)
@@ -2476,7 +2959,7 @@
if (ctx->state >= AML_STATE_PROBE)
update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
if (!V4L2_TYPE_IS_OUTPUT(f->type))
return 0;
@@ -2511,10 +2994,19 @@
if (ctx->internal_dw_scale) {
if (ctx->state >= AML_STATE_PROBE) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ u32 dw_mode = DM_YUV_ONLY;
+ u32 tw_mode = DM_INVALID;
+
if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
return -EBUSY;
- ratio = get_double_write_ratio(dw_mode);
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+ return -EBUSY;
+
+ if ((dw_mode == DM_AVBC_ONLY) && tw_mode)
+ ratio = vdec_get_size_ratio(tw_mode);
+ else
+ ratio = vdec_get_size_ratio(dw_mode);
}
}
@@ -2534,6 +3026,18 @@
s->r.width = ctx->picinfo.coded_width / ratio;
s->r.height = ctx->picinfo.coded_height / ratio;
break;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = ctx->picinfo.visible_width;
+ s->r.height = ctx->picinfo.visible_height;
+ break;
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = ctx->picinfo.coded_width;
+ s->r.height = ctx->picinfo.coded_height;
+ break;
default:
return -EINVAL;
}
@@ -2566,10 +3070,19 @@
if (ctx->internal_dw_scale) {
if (ctx->state >= AML_STATE_PROBE) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ u32 dw_mode = DM_YUV_ONLY;
+ u32 tw_mode = DM_INVALID;
+
if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
return -EBUSY;
- ratio = get_double_write_ratio(dw_mode);
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+ return -EBUSY;
+
+ if ((dw_mode == DM_AVBC_ONLY) && tw_mode)
+ ratio = vdec_get_size_ratio(tw_mode);
+ else
+ ratio = vdec_get_size_ratio(dw_mode);
}
}
@@ -2587,20 +3100,37 @@
return 0;
}
+static int is_vdec_core_fmt(struct aml_vcodec_ctx *ctx)
+{
+ if (ctx->output_pix_fmt == V4L2_PIX_FMT_H264 ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_MPEG ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_MPEG1 ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_MPEG2 ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_MPEG4 ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_AVS ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_MJPEG ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)
+ return true;
+
+ return false;
+}
+
/* called when it is beyong AML_STATE_PROBE */
static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type)
{
struct aml_q_data *q_data;
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ unsigned int dw_mode = DM_YUV_ONLY;
+ unsigned int tw_mode = DM_INVALID;
int ratio = 1;
q_data = aml_vdec_get_q_data(ctx, type);
- if (ctx->internal_dw_scale) {
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
- return;
- ratio = get_double_write_ratio(dw_mode);
- }
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+ return;
+
+ if (ctx->internal_dw_scale)
+ ratio = vdec_get_size_ratio(dw_mode);
if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
@@ -2611,25 +3141,69 @@
q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
q_data->bytesperline[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+
+ q_data->bytesperline[0] = q_data->bytesperline[0] << is_output_p010(dw_mode);
+ q_data->bytesperline[1] = q_data->bytesperline[1] << is_output_p010(dw_mode);
} else {
q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
q_data->sizeimage[0] += ctx->picinfo.c_len_sz;
q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+ q_data->bytesperline[0] = q_data->bytesperline[0] << is_output_p010(dw_mode);
+ }
+
+ /* For triple write. */
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+ return;
+
+ if (tw_mode == DM_INVALID)
+ return;
+
+ if (ctx->internal_dw_scale)
+ ratio = vdec_get_size_ratio(tw_mode);
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ q_data->sizeimage_tw[0] = ctx->picinfo.y_len_sz_tw;
+ q_data->sizeimage_tw[1] = ctx->picinfo.c_len_sz_tw;
+
+ q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+ q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
+
+ q_data->bytesperline_tw[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+ q_data->bytesperline_tw[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+
+ q_data->bytesperline_tw[0] = q_data->bytesperline_tw[0] << is_output_p010(tw_mode);
+ q_data->bytesperline_tw[1] = q_data->bytesperline_tw[1] << is_output_p010(tw_mode);
+ } else {
+ q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+ q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
+ q_data->sizeimage_tw[0] = ctx->picinfo.y_len_sz_tw;
+ q_data->sizeimage_tw[0] += ctx->picinfo.c_len_sz_tw;
+ q_data->bytesperline_tw[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+ q_data->bytesperline_tw[0] = q_data->bytesperline_tw[0] << is_output_p010(tw_mode);
}
}
-static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
+static void copy_v4l2_format_dimension(struct aml_vcodec_ctx *ctx,
+ struct v4l2_pix_format_mplane *pix_mp,
struct v4l2_pix_format *pix,
struct aml_q_data *q_data,
u32 type)
{
+ u32 dw_mode = DM_YUV_ONLY;
+ u32 tw_mode = DM_INVALID;
int i;
if (!pix || !pix_mp || !q_data)
return;
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+ return;
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+ return;
+
if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
pix_mp->width = q_data->coded_width;
pix_mp->height = q_data->coded_height;
@@ -2639,6 +3213,11 @@
for (i = 0; i < q_data->fmt->num_planes; i++) {
pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
+
+ if ((dw_mode == DM_AVBC_ONLY) && tw_mode) {
+ pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline_tw[i];
+ pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage_tw[i];
+ }
}
} else {
pix->width = q_data->coded_width;
@@ -2646,6 +3225,11 @@
pix->pixelformat = q_data->fmt->fourcc;
pix->bytesperline = q_data->bytesperline[0];
pix->sizeimage = q_data->sizeimage[0];
+
+ if ((dw_mode == DM_AVBC_ONLY) && tw_mode) {
+ pix->bytesperline = q_data->bytesperline_tw[0];
+ pix->sizeimage = q_data->sizeimage_tw[0];
+ }
}
}
@@ -2685,14 +3269,14 @@
vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"out_q_ctx buffers already requested\n");
- ret = -EBUSY;
+ return -EBUSY;
}
if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"cap_q_ctx buffers already requested\n");
- ret = -EBUSY;
+ return -EBUSY;
}
fmt = aml_vdec_find_format(f);
@@ -2705,7 +3289,16 @@
}
q_data->fmt = fmt;
- vidioc_try_fmt(f, q_data->fmt);
+ vidioc_try_fmt(ctx, f, q_data->fmt);
+
+ if (V4L2_TYPE_IS_OUTPUT(f->type) && ctx->drv_handle && ctx->receive_cmd_stop) {
+ ctx->state = AML_STATE_IDLE;
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+ "vcodec state (AML_STATE_IDLE)\n");
+ vdec_if_deinit(ctx);
+ ctx->receive_cmd_stop = 0;
+ }
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
@@ -2732,8 +3325,11 @@
mutex_unlock(&ctx->state_lock);
return -EINVAL;
}
+
+ vdec_trace_init(&ctx->vtr, ctx->id, vdec_get_vdec_id(ctx->ada_ctx));
+
ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_INIT)\n");
}
@@ -2743,6 +3339,12 @@
q_data->coded_width = pix->width;
q_data->coded_height = pix->height;
+ if (!vdec_check_is_available(pix->pixelformat)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "VC-1 only support single mode. \n");
+ return -EINVAL;
+ }
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"w: %d, h: %d, size: %d\n",
pix->width, pix->height,
@@ -2763,8 +3365,11 @@
mutex_unlock(&ctx->state_lock);
return -EINVAL;
}
+
+ vdec_trace_init(&ctx->vtr, ctx->id, vdec_get_vdec_id(ctx->ada_ctx));
+
ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_INIT)\n");
}
@@ -2776,8 +3381,7 @@
pix_mp->pixelformat : pix->pixelformat;
if (ctx->state >= AML_STATE_PROBE) {
update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
- v4l_buf_size_decision(ctx);
+ copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
}
}
@@ -2854,6 +3458,7 @@
if (j == f->index) {
f->pixelformat = fmt->fourcc;
+ strncpy(f->description, fmt->name, sizeof(f->description));
return 0;
}
++j;
@@ -2926,13 +3531,15 @@
}
if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
- pix_mp->field = ret ? V4L2_FIELD_NONE : ctx->picinfo.field;
+ pix_mp->field = ctx->force_report_interlace ? V4L2_FIELD_INTERLACED :
+ (ret ? V4L2_FIELD_NONE : ctx->picinfo.field);
pix_mp->colorspace = ctx->colorspace;
pix_mp->ycbcr_enc = ctx->ycbcr_enc;
pix_mp->quantization = ctx->quantization;
pix_mp->xfer_func = ctx->xfer_func;
} else {
- pix->field = ret ? V4L2_FIELD_NONE : ctx->picinfo.field;
+ pix->field = ctx->force_report_interlace ? V4L2_FIELD_INTERLACED :
+ (ret ? V4L2_FIELD_NONE : ctx->picinfo.field);
pix->colorspace = ctx->colorspace;
pix->ycbcr_enc = ctx->ycbcr_enc;
pix->quantization = ctx->quantization;
@@ -2942,7 +3549,7 @@
if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
(ctx->state >= AML_STATE_PROBE)) {
update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
/*
* This is run on OUTPUT
@@ -2950,9 +3557,9 @@
* so width and height have no meaning.
* Assign value here to pass v4l2-compliance test
*/
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
} else {
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"type=%d state=%d Format information could not be read, not ready yet!\n",
@@ -3022,29 +3629,49 @@
return -EINVAL;
alloc_devs[i] = &ctx->dev->plat_dev->dev;
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+ if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
+ (vq->memory == VB2_MEMORY_MMAP))
alloc_devs[i] = v4l_get_dev_from_codec_mm();
+ else if (vq->memory == VB2_MEMORY_MMAP)
+ dma_coerce_mask_and_coherent(alloc_devs[i], DMA_BIT_MASK(64));
}
} else {
- int dw_mode = VDEC_DW_NO_AFBC;
+ int dw_mode = DM_YUV_ONLY;
+ int tw_mode = DM_INVALID;
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
*nplanes = 2;
else
*nplanes = 1;
- if (!vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- if (dw_mode == VDEC_DW_AFBC_ONLY)
- *nplanes = 1;
- }
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+ return -EINVAL;
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+ return -EINVAL;
+
+ if ((dw_mode == DM_AVBC_ONLY) && (tw_mode == DM_INVALID))
+ *nplanes = 1;
for (i = 0; i < *nplanes; i++) {
- sizes[i] = q_data->sizeimage[i];
- if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->output_dma_mode)
- sizes[i] = 1;
alloc_devs[i] = &ctx->dev->plat_dev->dev;
+ sizes[i] = (dw_mode != DM_AVBC_ONLY) ? q_data->sizeimage[i] :
+ (tw_mode != DM_INVALID) ? q_data->sizeimage_tw[i] :
+ PAGE_SIZE;
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+ if (ctx->enable_di_post && is_vdec_core_fmt(ctx) &&
+ ctx->picinfo.field != V4L2_FIELD_NONE)
+ sizes[i] = PAGE_SIZE;
+
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ if (ctx->output_dma_mode)
+ sizes[i] = 1;
+ else
+ sizes[i] = q_data->sizeimage[i];
+
+ if (vq->memory == VB2_MEMORY_MMAP)
+ dma_coerce_mask_and_coherent(alloc_devs[i], DMA_BIT_MASK(64));
+ } else
alloc_devs[i] = v4l_get_dev_from_codec_mm();
}
}
@@ -3061,21 +3688,48 @@
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct aml_q_data *q_data;
struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
- struct aml_video_dec_buf *buf = NULL;
+ struct aml_v4l2_buf *buf = NULL;
int i;
-
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
- if (vb->memory == VB2_MEMORY_DMABUF
- && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
+ vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+ buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+
+ if (vb->memory == VB2_MEMORY_DMABUF && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+ if (!ctx->is_drm_mode) {
+ struct dmabuf_videodec_es_data *videodec_es_data;
+ if (dmabuf_manage_get_type(vb->planes[0].dbuf) != DMA_BUF_TYPE_VIDEODEC_ES) {
+ return 0;
+ }
+ videodec_es_data = (struct dmabuf_videodec_es_data *)dmabuf_manage_get_info(vb->planes[0].dbuf,
+ DMA_BUF_TYPE_VIDEODEC_ES);
+
+ if (videodec_es_data && videodec_es_data->data_type == DMA_BUF_VIDEODEC_HDR10PLUS) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "buf_prepare hdr10+ info type %d, len: %d\n",
+ videodec_es_data->data_type, videodec_es_data->data_len);
+ memcpy(buf->meta_data, (void *)videodec_es_data->data, videodec_es_data->data_len);
+ }
+ }
+#endif
return 0;
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
+ if (vb2_v4l2->meta_ptr && (copy_from_user(buf->meta_data,
+ (void *)vb2_v4l2->meta_ptr, VDEC_META_DATA_SIZE + 4))) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s:copy meta data error. ptr: %lx\n", __func__, vb2_v4l2->meta_ptr);
+ }
+#endif
q_data = aml_vdec_get_q_data(ctx, vb->vb2_queue->type);
for (i = 0; i < q_data->fmt->num_planes; i++) {
- if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
+ if (vb2_plane_size(vb, i) < q_data->sizeimage[i] &&
+ vb2_plane_size(vb, i) != PAGE_SIZE) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"data will not fit into plane %d (%lu < %d)\n",
i, vb2_plane_size(vb, i),
@@ -3083,116 +3737,9 @@
}
}
- vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-
- if (vb2_v4l2->meta_ptr && (copy_from_user(buf->meta_data,
- (void *)vb2_v4l2->meta_ptr, META_DATA_SIZE + 4))) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s:copy meta data error. ptr: %lx\n", __func__, vb2_v4l2->meta_ptr);
- }
-
return 0;
}
-static int init_mmu_bmmu_box(struct aml_vcodec_ctx *ctx)
-{
- int i;
- int mmu_flag = ctx->is_drm_mode? CODEC_MM_FLAGS_TVP:0;
- int bmmu_flag = mmu_flag;
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- ctx->comp_bufs = vzalloc(sizeof(*ctx->comp_bufs) * V4L_CAP_BUFF_MAX);
- if (!ctx->comp_bufs)
- return -ENOMEM;
-
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- goto free_comp_bufs;
- }
-
- /* init mmu box */
- ctx->mmu_box = decoder_mmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- ctx->comp_info.max_size * SZ_1M, mmu_flag);
- if (!ctx->mmu_box) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box\n");
- goto free_comp_bufs;
- }
-
- /* init bmmu box */
- bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
- ctx->bmmu_box = decoder_bmmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- 4 + PAGE_SHIFT, bmmu_flag);
- if (!ctx->bmmu_box) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box\n");
- goto free_mmubox;
- }
-
- if (dw_mode & 0x20) {
- /* init mmu box dw*/
- ctx->mmu_box_dw = decoder_mmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- ctx->comp_info.max_size * SZ_1M, mmu_flag);
- if (!ctx->mmu_box_dw) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box dw\n");
- goto free_bmmubox;
- }
-
- /* init bmmu box dw*/
- bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
- ctx->bmmu_box_dw = decoder_bmmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- 4 + PAGE_SHIFT, bmmu_flag);
- if (!ctx->bmmu_box_dw) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box dw\n");
- goto free_mmubox_dw;
- }
- }
-
- kref_init(&ctx->box_ref);
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- struct internal_comp_buf *buf;
- buf = &ctx->comp_bufs[i];
- buf->index = i;
- buf->ref = 0;
- buf->box_ref = &ctx->box_ref;
- buf->mmu_box = ctx->mmu_box;
- buf->bmmu_box = ctx->bmmu_box;
- buf->mmu_box_dw = ctx->mmu_box_dw;
- buf->bmmu_box_dw = ctx->bmmu_box_dw;
- }
- kref_get(&ctx->ctx_ref);
-
- ctx->uvm_proxy = vzalloc(sizeof(*ctx->uvm_proxy) * V4L_CAP_BUFF_MAX);
- if (!ctx->uvm_proxy)
- goto free_mmubox;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "box init, bmmu: %px, mmu: %px, mmu_dw: %px bmmu_dw: %px\n",
- ctx->bmmu_box, ctx->mmu_box, ctx->mmu_box_dw, ctx->bmmu_box_dw);
-
- return 0;
-free_mmubox_dw:
- decoder_mmu_box_free(ctx->mmu_box_dw);
- ctx->mmu_box_dw = NULL;
-
-free_bmmubox:
- decoder_bmmu_box_free(ctx->bmmu_box);
- ctx->bmmu_box = NULL;
-
-free_mmubox:
- decoder_mmu_box_free(ctx->mmu_box);
- ctx->mmu_box = NULL;
-
-free_comp_bufs:
- vfree(ctx->comp_bufs);
- ctx->comp_bufs = NULL;
-
- return -1;
-}
-
void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag)
{
int i = 0;
@@ -3232,6 +3779,21 @@
}
}
}
+
+ if (flag & HDR10P_TYPE) {
+ for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+ ctx->aux_infos.bufs[i].hdr10p_buf = vzalloc(HDR10P_BUF_SIZE);
+ if (ctx->aux_infos.bufs[i].hdr10p_buf) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "v4l2 alloc %dth hdr10p buffer:%px\n",
+ i, ctx->aux_infos.bufs[i].hdr10p_buf);
+ } else {
+ ctx->aux_infos.bufs[i].hdr10p_buf = NULL;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "v4l2 alloc %dth hdr10p buffer fail\n", i);
+ }
+ }
+ }
}
void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag)
@@ -3265,6 +3827,18 @@
}
}
}
+
+ if (flag & HDR10P_TYPE) {
+ for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+ if (ctx->aux_infos.bufs[i].hdr10p_buf != NULL) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "v4l2 free %dth hdr10p buffer:%px\n",
+ i, ctx->aux_infos.bufs[i].hdr10p_buf);
+ vfree(ctx->aux_infos.bufs[i].hdr10p_buf);
+ ctx->aux_infos.bufs[i].hdr10p_buf = NULL;
+ }
+ }
+ }
}
void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx)
@@ -3337,15 +3911,119 @@
}
}
+void aml_bind_hdr10p_buffer(struct aml_vcodec_ctx *ctx, char **addr)
+{
+ int index = ctx->aux_infos.hdr10p_index;
+
+ if (ctx->aux_infos.bufs[index].hdr10p_buf != NULL) {
+ *addr = ctx->aux_infos.bufs[index].hdr10p_buf;
+ ctx->aux_infos.hdr10p_index = (index + 1) % V4L_CAP_BUFF_MAX;
+ }
+}
+
+static void aml_canvas_cache_free(struct canvas_cache *cache)
+{
+ int i = -1;
+
+ for (i = 0; i < ARRAY_SIZE(cache->res); i++) {
+ if (cache->res[i].cid > 0) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "canvas-free, name:%s, canvas id:%d\n",
+ cache->res[i].name,
+ cache->res[i].cid);
+
+ canvas_pool_map_free_canvas(cache->res[i].cid);
+
+ cache->res[i].cid = 0;
+ }
+ }
+}
+
+void aml_canvas_cache_put(struct aml_vcodec_dev *dev)
+{
+ struct canvas_cache *cache = &dev->cache;
+
+ mutex_lock(&cache->lock);
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "canvas-put, ref:%d\n", cache->ref);
+
+ cache->ref--;
+
+ if (cache->ref == 0) {
+ aml_canvas_cache_free(cache);
+ }
+
+ mutex_unlock(&cache->lock);
+}
+
+int aml_canvas_cache_get(struct aml_vcodec_dev *dev, char *usr)
+{
+ struct canvas_cache *cache = &dev->cache;
+ int i;
+
+ mutex_lock(&cache->lock);
+
+ cache->ref++;
+
+ for (i = 0; i < ARRAY_SIZE(cache->res); i++) {
+ if (cache->res[i].cid <= 0) {
+ snprintf(cache->res[i].name, 32, "%s-%d", usr, i);
+ cache->res[i].cid =
+ canvas_pool_map_alloc_canvas(cache->res[i].name);
+ }
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "canvas-alloc, name:%s, canvas id:%d\n",
+ cache->res[i].name,
+ cache->res[i].cid);
+
+ if (cache->res[i].cid <= 0) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "canvas-fail, name:%s, canvas id:%d.\n",
+ cache->res[i].name,
+ cache->res[i].cid);
+
+ mutex_unlock(&cache->lock);
+ goto err;
+ }
+ }
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "canvas-get, ref:%d\n", cache->ref);
+
+ mutex_unlock(&cache->lock);
+ return 0;
+err:
+ aml_canvas_cache_put(dev);
+ return -1;
+}
+
+int aml_canvas_cache_init(struct aml_vcodec_dev *dev)
+{
+ dev->cache.ref = 0;
+ mutex_init(&dev->cache.lock);
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "canvas-init, ref:%d\n", dev->cache.ref);
+
+ return 0;
+}
+
void aml_v4l_vpp_release_early(struct aml_vcodec_ctx * ctx)
{
- if (ctx->vpp && !(ctx->vpp_cfg.enable_nr &&
- atomic_read(&ctx->vpp->local_buf_out))) {
+ struct aml_vpp_cfg_infos *vpp_cfg = &ctx->vpp_cfg;
+
+ if (ctx->vpp == NULL)
+ return;
+
+ if (vpp_cfg->early_release_flag ||
+ !(vpp_cfg->enable_nr && atomic_read(&ctx->vpp->local_buf_out))) {
aml_v4l2_vpp_destroy(ctx->vpp);
atomic_dec(&ctx->dev->vpp_count);
ctx->vpp = NULL;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"vpp destroy inst count:%d.\n",
atomic_read(&ctx->dev->vpp_count));
}
@@ -3358,116 +4036,54 @@
ctx = container_of(kref, struct aml_vcodec_ctx, ctx_ref);
if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
aml_v4l2_vpp_destroy(ctx->vpp);
+ atomic_dec(&ctx->dev->vpp_count);
ctx->vpp = NULL;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "vpp destory inst count:%d.\n",
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+ "vpp destroy inst count:%d.\n",
atomic_read(&ctx->dev->vpp_count));
}
if (ctx->ge2d) {
aml_v4l2_ge2d_destroy(ctx->ge2d);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "ge2d destory.\n");
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+ "ge2d destroy.\n");
}
v4l2_m2m_ctx_release(ctx->m2m_ctx);
- aml_task_chain_remove(ctx);
vfree(ctx->meta_infos.meta_bufs);
- ctx->aux_infos.free_buffer(ctx, SEI_TYPE | DV_TYPE);
- ctx->aux_infos.free_buffer(ctx, 1);
+ ctx->aux_infos.free_buffer(ctx, SEI_TYPE | DV_TYPE | HDR10P_TYPE);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"v4ldec has been destroyed.\n");
if (ctx->sync) {
vdec_clean_all_fence(ctx->sync);
}
+ vdec_trace_clean(&ctx->vtr);
+
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+ if (ctx->dv_id >= 0) {
+ dv_inst_unmap(ctx->dv_id);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s: dv_inst_unmap ctx %p, dv_id %d\n", __func__, ctx, ctx->dv_id);
+ }
+#endif
+
+ if (ctx->stream_mode) {
+ ctx->set_ext_buf_flg = false;
+ ptsserver_ins_release(ctx->ptsserver_id);
+ }
+
+ aml_es_mgr_release(ctx);
+
kfree(ctx);
}
-static void box_release(struct kref *kref)
-{
- struct aml_vcodec_ctx * ctx
- = container_of(kref, struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, bmmu: %px, mmu: %px mmu_dw: %pu\n",
- __func__, ctx->bmmu_box, ctx->mmu_box,ctx->mmu_box_dw);
-
- decoder_bmmu_box_free(ctx->bmmu_box);
- decoder_mmu_box_free(ctx->mmu_box);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free(ctx->mmu_box_dw);
- decoder_bmmu_box_free(ctx->bmmu_box_dw);
- }
- vfree(ctx->comp_bufs);
- vfree(ctx->uvm_proxy);
- kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
-}
-
-static void internal_buf_free(void *arg)
-{
- struct internal_comp_buf* ibuf =
- (struct internal_comp_buf*)arg;
- struct aml_vcodec_ctx * ctx
- = container_of(ibuf->box_ref,struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, idx:%d\n", __func__, ibuf->index);
-
- mutex_lock(&ctx->comp_lock);
-
- if (!(ibuf->ref & 0xff00)) {
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- }
- ibuf->ref = 0;
-
- mutex_unlock(&ctx->comp_lock);
-
- kref_put(ibuf->box_ref, box_release);
-}
-
-static void internal_buf_free2(void *arg)
-{
- struct internal_comp_buf *ibuf =
- container_of(arg, struct internal_comp_buf, priv_data);
- struct aml_vcodec_ctx * ctx
- = container_of(ibuf->box_ref, struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, idx: %d\n", __func__, ibuf->index);
-
- mutex_lock(&ctx->comp_lock);
-
- if (!(ibuf->ref & 0xff00)) {
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- }
- ibuf->ref = 0;
-
- mutex_unlock(&ctx->comp_lock);
-
- kref_put(ibuf->box_ref, box_release);
-}
-
static void aml_uvm_buf_free(void *arg)
{
struct aml_uvm_buff_ref * ubuf =
@@ -3480,177 +4096,13 @@
__func__, ubuf->index, ubuf->dbuf,
file_inode(ubuf->dbuf->file)->i_ino);
+ aml_buf_detach(&ctx->bm, (ulong)ubuf->dbuf);
+
kref_put(ubuf->ref, aml_v4l_ctx_release);
vfree(ubuf);
}
-static int uvm_attach_hook_mod_local(struct aml_vcodec_ctx *ctx,
- struct uvm_hook_mod_info *uvm)
-{
- struct internal_comp_buf* ibuf = uvm->arg;
-
- ctx->uvm_proxy[ibuf->index] = *uvm;
-
- return 0;
-}
-
-static int update_comp_buffer_to_reuse(struct aml_vcodec_ctx *ctx,
- struct aml_video_dec_buf *buf)
-{
- struct internal_comp_buf* ibuf = NULL;
-
- mutex_lock(&ctx->comp_lock);
-
- ibuf = vb_to_comp(ctx, &buf->vb.vb2_buf);
- if (!ibuf) {
- mutex_unlock(&ctx->comp_lock);
- return 0;
- }
-
- if (ibuf->ref & 0xff) {
- buf->internal_index = ibuf->index;
- ibuf->frame_buffer_size = ctx->comp_info.frame_buffer_size;
-
- if (ctx->comp_info.header_size != ibuf->header_size) {
- decoder_bmmu_box_free_idx(ctx->bmmu_box, ibuf->index);
- if (decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_addr) < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "fail to alloc %dth bmmu\n",
- ibuf->index);
- mutex_unlock(&ctx->comp_lock);
- return -ENOMEM;
- }
- ibuf->header_size = ctx->comp_info.header_size;
- }
-
- ibuf->ref |= (1 << 8);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, reuse comp buffer vb2:%d <--> internal: %d, header_addr 0x%lx, size: %u\n",
- __func__, buf->vb.vb2_buf.index,
- buf->internal_index,
- ibuf->header_addr,
- ibuf->header_size);
- }
-
- mutex_unlock(&ctx->comp_lock);
-
- return (ibuf->ref & 0xff00) ? 1 : 0;
-}
-
-static int bind_comp_buffer_to_uvm(struct aml_vcodec_ctx *ctx,
- struct aml_video_dec_buf *buf)
-{
- int ret, i;
- struct dma_buf * dma = buf->vb.vb2_buf.planes[0].dbuf;
- struct aml_dec_params *parms = &ctx->config.parm.dec;
- struct uvm_hook_mod_info u_info;
- struct internal_comp_buf* ibuf;
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- /* get header and page size */
- if (vdec_if_get_param(ctx, GET_PARAM_COMP_BUF_INFO, &ctx->comp_info)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to get comp info\n");
- return -EINVAL;
- }
-
- if (!ctx->bmmu_box || !ctx->mmu_box)
- if (init_mmu_bmmu_box(ctx))
- return -EINVAL;
-
- ret = update_comp_buffer_to_reuse(ctx, buf);
- if (ret < 0)
- return ret;
-
- if (ret == 1 /*reused*/)
- return 0;
-
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- if (!ctx->comp_bufs[i].ref)
- break;
- }
-
- if (i == V4L_CAP_BUFF_MAX) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "out of internal buf\n");
- return -EINVAL;
- }
-
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- return -EINVAL;
- }
-
- buf->internal_index = i;
- ibuf = &ctx->comp_bufs[i];
- ibuf->frame_buffer_size = ctx->comp_info.frame_buffer_size;
- ibuf->header_size = ctx->comp_info.header_size;
-
- /* allocate header */
- ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_addr);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu\n", i);
- return -ENOMEM;
- }
-
- if (dw_mode & 0x20) {
- ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box_dw,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_dw_addr);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu dw\n", i);
- return -ENOMEM;
- }
- }
-
- kref_get(&ctx->box_ref);
- ibuf->ref = 1;
-
- /* frame SG buffer need to be realloc inside decoder,
- * just before slice decoding to save memory
- */
- u_info.type = VF_SRC_DECODER;
- u_info.arg = ibuf;
- u_info.free = internal_buf_free;
-
- if (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO) {
- /* adapted video composer to use for hwc. */
- ibuf->priv_data.v4l_inst_id = ctx->id;
- u_info.type = VF_PROCESS_V4LVIDEO;
- u_info.arg = &ibuf->priv_data;
- u_info.free = internal_buf_free2;
- }
-
- ret = dmabuf_is_uvm(dma) ?
- uvm_attach_hook_mod(dma, &u_info) :
- uvm_attach_hook_mod_local(ctx, &u_info);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to set dmabuf priv buf\n");
- goto bmmu_box_free;
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, bind vb2:(%d, %px) <--> internal: (%d, %px) header_addr 0x%lx, size: %u\n",
- __func__, buf->vb.vb2_buf.index,
- dma, i, ibuf, ibuf->header_addr,
- ctx->comp_info.header_size);
-
- return 0;
-
-bmmu_box_free:
- if (dw_mode & 0x20) {
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
- kref_put(&ctx->box_ref, box_release);
- ibuf->ref = 0;
- return -EINVAL;
-}
-
-static int aml_uvm_buff_attach(struct vb2_buffer * vb)
+int aml_uvm_buff_attach(struct vb2_buffer * vb)
{
int ret = 0;
struct dma_buf *dbuf = vb->planes[0].dbuf;
@@ -3658,6 +4110,10 @@
struct aml_vcodec_ctx *ctx =
vb2_get_drv_priv(vb->vb2_queue);
struct aml_uvm_buff_ref *ubuf = NULL;
+ struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+ struct aml_v4l2_buf *buf =
+ container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+ struct aml_buf *am_buf = buf->aml_buf;
if (vb->memory != VB2_MEMORY_DMABUF || !dmabuf_is_uvm(dbuf))
return 0;
@@ -3667,9 +4123,10 @@
return -ENOMEM;
ubuf->index = vb->index;
- ubuf->addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ ubuf->addr = get_addr(vb, 0);
ubuf->dbuf = dbuf;
ubuf->ref = &ctx->ctx_ref;
+ am_buf->uvm_buf = (void *)ubuf;
u_info.type = VF_PROCESS_DECODER;
u_info.arg = (void *)ubuf;
@@ -3692,156 +4149,203 @@
return ret;
}
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb)
+static ulong prepare_get_addr(struct dma_buf *dbuf, struct device *dev)
{
- struct aml_dec_params *parms = &ctx->config.parm.dec;
- bool is_v4lvideo = (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO);
- enum uvm_hook_mod_type u_type =
- is_v4lvideo ? VF_PROCESS_V4LVIDEO : VF_SRC_DECODER;
- struct dma_buf *dbuf = vb->planes[0].dbuf;
- struct internal_comp_buf *ibuf = NULL;
- struct uvm_hook_mod *uhmod = NULL;
+ struct dma_buf_attachment *dba;
+ struct sg_table *sgt;
+ ulong addr;
- uhmod = uvm_get_hook_mod(dbuf, u_type);
- if (IS_ERR_OR_NULL(uhmod))
- return NULL;
+ /* create attachment for the dmabuf with the user device */
+ dba = dma_buf_attach(dbuf, dev);
+ if (IS_ERR(dba)) {
+ pr_err("failed to attach dmabuf\n");
+ return 0;
+ }
- ibuf = !is_v4lvideo ? (struct internal_comp_buf *) uhmod->arg :
- container_of(uhmod->arg, struct internal_comp_buf, priv_data);
+ /* get the associated scatterlist for this buffer */
+ sgt = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sgt)) {
+ pr_err("Error getting dmabuf scatterlist\n");
+ return 0;
+ }
- uvm_put_hook_mod(dbuf, u_type);
+ addr = sg_dma_address(sgt->sgl);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, vb2: (%d, %px) --> comp: (%d, %px)\n",
- __func__, vb->index, dbuf, ibuf->index, ibuf);
+ /* unmap attachment and detach dbuf */
+ dma_buf_unmap_attachment(dba, sgt, DMA_BIDIRECTIONAL);
+ dma_buf_detach(dbuf, dba);
- return ibuf;
+ return addr;
}
static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
{
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- struct aml_video_dec_buf *buf =
- container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
+ struct aml_v4l2_buf *buf =
+ container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
struct aml_vcodec_mem src_mem;
+ struct aml_buf_config config;
+ u32 dw = DM_YUV_ONLY;
+ u32 tw = DM_INVALID;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
- "%s, vb: %lx, type: %d, idx: %d, state: %d, used: %d, ts: %llu\n",
- __func__, (ulong) vb, vb->vb2_queue->type,
- vb->index, vb->state, buf->used, vb->timestamp);
+ "%s, type: %d, vb: %lx, idx: %d, state: %d, used: %d, ts: %llu, uvm dbuf: %px\n",
+ __func__, vb->vb2_queue->type, (ulong) vb,
+ vb->index, vb->state, buf->used, vb->timestamp, vb->planes[0].dbuf);
/*
* check if this buffer is ready to be used after decode
*/
if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- u32 dw_mode = VDEC_DW_NO_AFBC;
+ struct aml_buf *aml_buf = buf->aml_buf;
+ struct vframe_s *vf;
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- return;
+ if (aml_buf->vb != vb) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "vb2 (old idx: %d new idx: %d) update\n",
+ aml_buf->vb->index, vb->index);
+ aml_buf_replace(&ctx->bm, aml_buf, vb);
}
- if (!buf->que_in_m2m) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "enque capture buf idx %d, vf: %lx\n",
- vb->index, (ulong) v4l_get_vf_handle(vb2_v4l2->private));
+ if (aml_buf->pair == BUF_MASTER)
+ aml_buf->queued_mask = 1 << BUF_MASTER;
- /* bind compressed buffer to uvm */
- if ((dw_mode != VDEC_DW_NO_AFBC) &&
- vb->memory == VB2_MEMORY_DMABUF &&
- bind_comp_buffer_to_uvm(ctx, buf)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to bind comp buffer\n");
- return;
- }
+ if (aml_buf->pair == BUF_SUB0) {
+ aml_buf = aml_buf->master_buf;
+ aml_buf->queued_mask = 1 << BUF_SUB0;
+ }
+ if (aml_buf->pair == BUF_SUB1) {
+ aml_buf = aml_buf->master_buf;
+ aml_buf->queued_mask = 1 << BUF_SUB1;
+ }
- /* DI hook must be detached if the dmabuff be reused. */
- if (ctx->vpp_cfg.enable_local_buf) {
+ vf = &aml_buf->vframe;
+
+ /* DI hook must be detached if the dmabuff be reused. */
+ if (ctx->vpp_cfg.enable_local_buf) {
+ if (!buf->attached) {
struct dma_buf *dma = vb->planes[0].dbuf;
- if (dmabuf_is_uvm(dma) &&
- uvm_detach_hook_mod(dma, VF_PROCESS_DI) < 0) {
+ if (uvm_detach_hook_mod(dma, VF_PROCESS_DI) < 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"dmabuf without attach DI hook.\n");
}
- }
-
- task_chain_clean(fb->task);
-
- ctx->cap_pool.seq[ctx->cap_pool.in++] =
- (V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
- buf->que_in_m2m = true;
-
- fb->status = FB_ST_INIT;
- ATRACE_COUNTER("VC_IN_VSINK-2.storage", vb->index);
-
- /* check dpb ready */
- aml_check_dpb_ready(ctx);
- } else {
- struct vframe_s *vf = fb->vframe;
- struct task_chain_s *task = fb->task;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
- "IN__BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
- "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
- ctx->ada_ctx->frm_name, fb->status, vf ? vf->index_disp : -1,
- vb->index, vb,
- vf ? vf->index & 0xff : -1, vf,
- vf ? vf->timestamp : 0,
- fb->m.mem[0].addr, fb->m.mem[0].size,
- fb->m.mem[1].addr, fb->m.mem[1].size,
- fb->m.mem[2].addr, fb->m.mem[2].size);
-
- ATRACE_COUNTER("VC_IN_VSINK-4.recycle", vb->index);
-
- task->recycle(task, TASK_TYPE_V4L_SINK);
+ buf->attached = true;
+ } else
+ aml_v4l2_vpp_recycle(ctx->vpp, buf);
}
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
+ "IN__BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+ "dma addr: %llx Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
+ ctx->ada_ctx->frm_name,
+ aml_buf->state,
+ ctx->in_buff_cnt,
+ vb->index, vb,
+ vf ? vf->index & 0xff : -1, vf,
+ vf ? vf->timestamp : 0,
+ (u64)get_addr(vb, 0),
+ aml_buf->planes[0].addr, aml_buf->planes[0].length,
+ aml_buf->planes[1].addr, aml_buf->planes[1].length,
+ aml_buf->planes[2].addr, aml_buf->planes[2].length);
+
+ ctx->in_buff_cnt++;
+
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_10,
+ CTX_BUF_TOTAL(ctx) + ctx->out_buff_cnt - ctx->in_buff_cnt);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_4, vb->index);
+
+ aml_buf_fill(&ctx->bm, aml_buf, BUF_USER_VSINK);
+
+ vdec_thread_wakeup(ctx->ada_ctx);
+
wake_up_interruptible(&ctx->cap_wq);
return;
+ } else if (ctx->output_dma_mode) {
+ struct dma_buf *dbuf = vb->planes[0].dbuf;
+ struct device *dev = vb->vb2_queue->alloc_devs[0] ? :
+ vb->vb2_queue->dev;
+
+ if (dbuf && dev) {
+ buf->addr = prepare_get_addr(dbuf, dev);
+ if (buf->addr &&
+ buf->addr != sg_dma_address(buf->out_sgt->sgl)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "vb2 dma addr update(0x%llx --> 0x%lx)\n",
+ (u64)sg_dma_address(buf->out_sgt->sgl), buf->addr);
+ }
+ } else
+ v4l_dbg(ctx, 0,
+ "dbuf %px dev %px\n", dbuf, dev);
}
+ if (ctx->stream_mode &&
+ !(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+ struct dmabuf_dmx_sec_es_data *es_data;
+
+ if (dmabuf_manage_get_type(vb->planes[0].dbuf) != DMA_BUF_TYPE_DMX_ES) {
+ pr_err("not DMA_BUF_TYPE_DMX_ES\n");
+ return;
+ }
+ es_data = (struct dmabuf_dmx_sec_es_data *)dmabuf_manage_get_info(vb->planes[0].dbuf, DMA_BUF_TYPE_DMX_ES);
+ buf->dma_buf = (void *)es_data;
+ }
v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
if (ctx->state != AML_STATE_INIT) {
return;
}
- buf->used = true;
vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+ buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
if (buf->lastframe) {
/* This shouldn't happen. Just in case. */
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Invalid flush buffer.\n");
- buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode && (vb->memory == VB2_MEMORY_DMABUF))
- wake_up_interruptible(&ctx->wq);
return;
}
+ if (ctx->stream_mode &&
+ !(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+ ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+ struct dmabuf_dmx_sec_es_data *es_data = (struct dmabuf_dmx_sec_es_data *)buf->dma_buf;
+ int offset = vb->planes[0].data_offset;
+ if (ctx->set_ext_buf_flg == false) {
+ v4l2_set_ext_buf_addr(ctx->ada_ctx, es_data, offset);
+ ctx->es_free = aml_es_input_free;
+ ctx->set_ext_buf_flg = true;
+ }
+
+ src_mem.addr = es_data->data_start + offset;
+ src_mem.size = vb->planes[0].bytesused - offset;
+ src_mem.dbuf = vb->planes[0].dbuf;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, "update wp 0x%lx + sz 0x%x offset 0x%x ori start 0x%x pts %llu\n",
+ src_mem.addr, src_mem.size, offset, es_data->data_start, vb->timestamp);
+
+ } else {
+ src_mem.addr = buf->addr ? buf->addr :
+ sg_dma_address(buf->out_sgt->sgl);
+ src_mem.size = vb->planes[0].bytesused;
+ }
src_mem.index = vb->index;
- src_mem.vaddr = vb2_plane_vaddr(vb, 0);
- src_mem.addr = sg_dma_address(buf->out_sgt->sgl);
- src_mem.size = vb->planes[0].bytesused;
+ if (!ctx->is_drm_mode)
+ src_mem.vaddr = vb2_plane_vaddr(vb, 0);
+
src_mem.model = vb->memory;
src_mem.timestamp = vb->timestamp;
src_mem.meta_ptr = (ulong)buf->meta_data;
if (vdec_if_probe(ctx, &src_mem, NULL)) {
- buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (src_mem.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
+ /* frame mode and non-dbuf mode. */
+ if (ctx->stream_mode || !ctx->output_dma_mode) {
v4l2_buff_done(to_vb2_v4l2_buffer(vb),
VB2_BUF_STATE_DONE);
}
@@ -3853,13 +4357,10 @@
* If on model dmabuf must remove the buffer
* because this data has been consumed by hw.
*/
- buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (src_mem.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else if (ctx->param_sets_from_ucode) {
+ /* frame mode and non-dbuf mode. */
+ if (ctx->stream_mode || !ctx->output_dma_mode) {
v4l2_buff_done(to_vb2_v4l2_buffer(vb),
VB2_BUF_STATE_DONE);
}
@@ -3870,12 +4371,40 @@
return;
}
+ if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+ return;
+
+ }
+
+ if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+ return;
+
+ }
+
if (!ctx->picinfo.dpb_frames)
return;
v4l_buf_size_decision(ctx);
ctx->last_decoded_picinfo = ctx->picinfo;
+ config.enable_extbuf = true;
+ config.enable_fbc = ((dw != DM_YUV_ONLY) || tw) ? true : false;
+ config.enable_secure = ctx->is_drm_mode;
+ config.memory_mode = vb->vb2_queue->memory;
+ config.planes = V4L2_TYPE_IS_MULTIPLANAR(vb->vb2_queue->type) ? 2 : 1;
+ config.luma_length = ctx->picinfo.y_len_sz;
+ config.chroma_length = ctx->picinfo.c_len_sz;
+ config.luma_length_tw = ctx->picinfo.y_len_sz_tw;
+ config.chroma_length_tw = ctx->picinfo.c_len_sz_tw;
+ config.dw_mode = dw;
+ config.tw_mode = tw;
+
+ if (ctx->enable_di_post)
+ ctx->bm.vpp_work_mode = VPP_WORK_MODE_DI_POST;
+ aml_buf_configure(&ctx->bm, &config);
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
"Picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
@@ -3887,7 +4416,7 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_INIT) {
ctx->state = AML_STATE_PROBE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_PROBE)\n");
}
@@ -3898,20 +4427,20 @@
{
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
- struct aml_video_dec_buf *buf = NULL;
+ struct aml_v4l2_buf *buf = NULL;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+ buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
if (buf->error) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Unrecoverable error on buffer.\n");
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT)\n");
}
@@ -3922,17 +4451,19 @@
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
struct vb2_v4l2_buffer, vb2_buf);
- struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
- struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
+ struct aml_v4l2_buf *buf = container_of(vb2_v4l2,
+ struct aml_v4l2_buf, vb);
u32 size, phy_addr = 0;
int i;
+ int ret;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
buf->lastframe = false;
+ } else {
+ buf->attached = false;
}
/* codec_mm buffers count */
@@ -3941,21 +4472,21 @@
char *owner = __getname();
snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
- strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
- buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
+ strncpy(buf->mem_owner, owner, sizeof(buf->mem_owner));
+ buf->mem_owner[sizeof(buf->mem_owner) - 1] = '\0';
__putname(owner);
for (i = 0; i < vb->num_planes; i++) {
size = vb->planes[i].length;
phy_addr = vb2_dma_contig_plane_dma_addr(vb, i);
- buf->mem[i] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ buf->mem[i] = v4l_reqbufs_from_codec_mm(buf->mem_owner,
phy_addr, size, vb->index);
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"OUT %c alloc, addr: %x, size: %u, idx: %u\n",
(i == 0? 'Y':'C'), phy_addr, size, vb->index);
}
} else if (vb->memory == VB2_MEMORY_DMABUF) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ unsigned int dw_mode = DM_YUV_ONLY;
for (i = 0; i < vb->num_planes; i++) {
struct dma_buf * dma;
@@ -3965,7 +4496,7 @@
return -EINVAL;
}
/* None-DW mode means single layer */
- if (dw_mode == VDEC_DW_AFBC_ONLY && i > 0) {
+ if (dw_mode == DM_AVBC_ONLY && i > 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"only support single plane in dw mode 0\n");
return -EINVAL;
@@ -3974,45 +4505,26 @@
dma = vb->planes[i].dbuf;
if (!dmabuf_is_uvm(dma))
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "non-uvm dmabuf\n");
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "non-uvm dmabuf\n");
}
}
}
if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
- struct vframe_s *vf = NULL;
- struct task_chain_s *task = NULL;
- struct task_chain_s *task_pre = fb->task;
- u32 icomp = -1;
+ ulong key;
+ if (vb->memory == VB2_MEMORY_DMABUF)
+ key = (ulong)vb->planes[0].dbuf;
+ if (vb->memory == VB2_MEMORY_MMAP)
+ key = vb2_dma_contig_plane_dma_addr(vb, 0);
- fb_map_table_fetch(ctx, vb, &vf, &task, &icomp);
- if (vf) {
- fb->task = task;
- fb->vframe = vf;
- vf->v4l_mem_handle = (ulong)fb;
- buf->internal_index = icomp;
- task_chain_update_object(task, fb);
- } else {
- buf->que_in_m2m = false;
-
- if (aml_uvm_buff_attach(vb))
- return -EFAULT;
-
- if (task_chain_init(&fb->task, ctx, fb, vb->index))
- return -EFAULT;
-
- list_add(&fb->task->node, &ctx->task_chain_pool);
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "init buffer(%s), vb idx:%d, task:(%px -> %px), addr:(%lx -> %lx), icomp:%d\n",
- vf ? "update" : "idel",
- vb->index, task_pre, fb->task,
- fb->m.mem[0].addr,
- (ulong) vb2_dma_contig_plane_dma_addr(vb, 0),
- (int)icomp);
-
- update_vdec_buf_plane(ctx, fb, vb);
+ ret = aml_buf_attach(&ctx->bm, key,
+ vb2_dma_contig_plane_dma_addr(vb, 0), vb);
+ if (ret) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "aml_buf_attach fail!\n");
+ return ret;
+ }
+ aml_uvm_buf_delay_alloc(ctx, vb2_v4l2);
}
if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
@@ -4037,9 +4549,8 @@
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
struct vb2_v4l2_buffer, vb2_buf);
- struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
- struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;;
+ struct aml_v4l2_buf *buf = container_of(vb2_v4l2,
+ struct aml_v4l2_buf, vb);
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
@@ -4053,16 +4564,10 @@
"OUT %c clean, addr: %lx, size: %u, idx: %u\n",
(i == 0)? 'Y':'C',
buf->mem[i]->phy_addr, buf->mem[i]->buffer_size, vb->index);
- v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[i]);
+ v4l_freebufs_back_to_codec_mm(buf->mem_owner, buf->mem[i]);
buf->mem[i] = NULL;
}
- }
- if (ctx->output_thread_ready) {
- if (!is_fb_mapped(ctx, fb->m.mem[0].addr)) {
- list_del(&fb->task->node);
- task_chain_clean(fb->task);
- task_chain_release(fb->task);
- }
+ aml_buf_detach(&ctx->bm, vb2_dma_contig_plane_dma_addr(vb, 0));
}
}
}
@@ -4075,10 +4580,14 @@
ctx->v4l_resolution_change = false;
/* vdec has ready to decode subsequence data of new resolution. */
- v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
+ //v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
+ ctx->dst_queue_streaming = true;
+
+ vdec_thread_wakeup(ctx->ada_ctx);
+
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d\n", __func__, q->type);
@@ -4087,7 +4596,7 @@
static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
{
- struct aml_video_dec_buf *buf = NULL;
+ struct aml_v4l2_buf *buf = NULL;
struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
int i;
@@ -4096,19 +4605,27 @@
"%s, type: %d, state: %x, frame_cnt: %d\n",
__func__, q->type, ctx->state, ctx->decoded_frame_cnt);
- if (V4L2_TYPE_IS_OUTPUT(q->type))
+ if (V4L2_TYPE_IS_OUTPUT(q->type)) {
ctx->is_out_stream_off = true;
- else
+ } else {
ctx->is_stream_off = true;
+ ctx->dst_queue_streaming = false;
+ ctx->out_buff_cnt = 0;
+ ctx->in_buff_cnt = 0;
+ ctx->write_frames = 0;
+ }
if (V4L2_TYPE_IS_OUTPUT(q->type)) {
struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
- unsigned long flags;
+ ulong flags;
- cancel_work_sync(&ctx->dmabuff_recycle_work);
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
+ spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+ ctx->es_wkr_stop = true;
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
+ cancel_work_sync(&ctx->es_wkr_in);
+ cancel_work_sync(&ctx->es_wkr_out);
INIT_KFIFO(ctx->dmabuff_recycle);
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
@@ -4126,11 +4643,10 @@
if (!que->streaming &&
(vdec_frame_number(ctx->ada_ctx) > 0) &&
(ctx->state < AML_STATE_ACTIVE)) {
- ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
ctx->v4l_resolution_change = false;
ctx->reset_flag = V4L_RESET_MODE_NORMAL;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"force reset to drop es frames.\n");
wake_up_interruptible(&ctx->cap_wq);
aml_vdec_reset(ctx);
@@ -4142,23 +4658,21 @@
aml_vdec_reset(ctx);
}
- cancel_work_sync(&ctx->decode_work);
mutex_lock(&ctx->capture_buffer_lock);
INIT_KFIFO(ctx->capture_buffer);
mutex_unlock(&ctx->capture_buffer_lock);
- while ((vb2_v4l2 = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)))
- v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
-
for (i = 0; i < q->num_buffers; ++i) {
vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
- buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- buf->frame_buffer.status = FB_ST_FREE;
- buf->frame_buffer.vframe = NULL;
- buf->que_in_m2m = false;
- buf->used = false;
- buf->vb.flags = 0;
- ctx->cap_pool.seq[i] = 0;
+ buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+ if (buf->aml_buf) {
+ buf->aml_buf->state = FB_ST_FREE;
+ memset(&buf->aml_buf->vframe,
+ 0, sizeof(struct vframe_s));
+ }
+ buf->attached = false;
+ buf->used = false;
+ buf->vb.flags = 0;
if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
@@ -4167,15 +4681,23 @@
q->bufs[i]->index, q->bufs[i]->state);*/
}
- fb_map_table_clean(ctx);
-
- fb_token_clean(ctx);
-
+ aml_buf_reset(&ctx->bm);
+ aml_codec_connect(ctx->ada_ctx); /* for resolution change */
+ aml_compressed_info_show(ctx);
+ memset(&ctx->compressed_buf_info, 0, sizeof(ctx->compressed_buf_info));
ctx->buf_used_count = 0;
- ctx->cap_pool.in = 0;
- ctx->cap_pool.out = 0;
- ctx->cap_pool.dec = 0;
- ctx->cap_pool.vpp = 0;
+ }
+ if (ctx->is_out_stream_off && ctx->is_stream_off) {
+ ctx->v4l_resolution_change = false;
+ ctx->reset_flag = V4L_RESET_MODE_NORMAL;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+ "seek force reset to drop es frames.\n");
+ aml_vdec_reset(ctx);
+ }
+
+ if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+ atomic_set(&ctx->vpp_cache_num, 0);
+ atomic_set(&ctx->ge2d_cache_num, 0);
}
}
@@ -4183,26 +4705,33 @@
{
struct aml_vcodec_ctx *ctx = priv;
struct aml_vcodec_dev *dev = ctx->dev;
+ ulong flags;
- if (ctx->output_thread_ready)
- queue_work(dev->decode_workqueue, &ctx->decode_work);
+ spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+ if (ctx->es_wkr_stop) {
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+ return;
+ }
+
+ queue_work(dev->decode_workqueue, &ctx->es_wkr_in);
+
+ spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
}
static int m2mops_vdec_job_ready(void *m2m_priv)
{
struct aml_vcodec_ctx *ctx = m2m_priv;
- if (ctx->state < AML_STATE_PROBE ||
- ctx->state > AML_STATE_FLUSHED)
- return 0;
-
- return 1;
+ return (ctx->es_wkr_stop ||
+ !is_input_ready(ctx->ada_ctx) ||
+ vdec_input_full(ctx->ada_ctx)) ? 0 : 1;
}
static void m2mops_vdec_job_abort(void *priv)
{
struct aml_vcodec_ctx *ctx = priv;
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
}
@@ -4234,6 +4763,22 @@
case AML_V4L2_GET_FILMGRAIN_INFO:
ctrl->val = ctx->film_grain_present;
break;
+ case AML_V4L2_GET_DECODER_INFO:
+ memcpy(ctrl->p_new.p, &ctx->decoder_status_info,
+ sizeof(struct aml_decoder_status_info));
+ ctx->decoder_status_info.error_type = 0;
+ break;
+ case AML_V4L2_GET_BITDEPTH:
+ ctrl->val = ctx->picinfo.bitdepth;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "bitdepth: %d\n", ctrl->val);
+ break;
+ case AML_V4L2_DEC_PARMS_CONFIG:
+ vidioc_vdec_g_parm_ext(ctrl, ctx);
+ break;
+ case AML_V4L2_GET_INST_ID:
+ ctrl->val = ctx->id;
+ break;
default:
ret = -EINVAL;
}
@@ -4244,19 +4789,45 @@
{
struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s id %d val %d\n", __func__, ctrl->id, ctrl->val);
if (ctrl->id == AML_V4L2_SET_DRMMODE) {
ctx->is_drm_mode = ctrl->val;
ctx->param_sets_from_ucode = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "set stream mode: %x\n", ctrl->val);
+ "set DRM mode: %x\n", ctrl->val);
} else if (ctrl->id == AML_V4L2_SET_DURATION) {
vdec_set_duration(ctrl->val);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"set duration: %x\n", ctrl->val);
- }
+ } else if (ctrl->id == AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE) {
+ ctx->cache_input_buffer_num = ctrl->val;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "cache_input_buffer_num: %d\n", ctrl->val);
+ } else if (ctrl->id == AML_V4L2_DEC_PARMS_CONFIG) {
+ vidioc_vdec_s_parm_ext(ctrl, ctx);
+ } else if (ctrl->id == AML_V4L2_SET_STREAM_MODE) {
+ u32 ret;
+ ctx->stream_mode = ctrl->val;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "set streambase: %x\n", ctrl->val);
+ if (ctx->stream_mode == true) {
+ ptsserver_ins *pIns = NULL;
+ ret = ptsserver_ins_alloc(&ctx->ptsserver_id, &pIns, NULL);
+ if (ret < 0) {
+ v4l_dbg(ctx, 0, "%s Alloc pts server fail!\n", __func__);
+ }
+ ptsserver_set_mode(ctx->ptsserver_id, true);
+ ctx->pts_serves_ops = get_pts_server_ops();
+ if (ctx->pts_serves_ops == NULL) {
+ v4l_dbg(ctx, 0, "%s pts_serves_ops is NULL!\n", __func__);
+ }
+ }
+ } else if (ctrl->id == AML_V4L2_SET_ES_DMABUF_TYPE) {
+ ctx->output_dma_mode = ctrl->val;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+ "set dma buf mode: %x\n", ctrl->val);
+ }
return 0;
}
@@ -4277,6 +4848,18 @@
.def = 0,
};
+static const struct v4l2_ctrl_config ctrl_set_dma_buf_mode = {
+ .name = "dma buf mode",
+ .id = AML_V4L2_SET_ES_DMABUF_TYPE,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
+ .min = 0,
+ .max = 1,
+ .step = 1,
+ .def = 0,
+};
+
static const struct v4l2_ctrl_config ctrl_gt_input_buffer_number = {
.name = "input buffer number",
.id = AML_V4L2_GET_INPUT_BUFFER_NUM,
@@ -4289,6 +4872,17 @@
.def = 0,
};
+static const struct v4l2_ctrl_config ctrl_set_input_buffer_number_cache = {
+ .name = "input buffer number cache",
+ .id = AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 0,
+ .max = 128,
+ .step = 1,
+ .def = 0,
+};
+
static const struct v4l2_ctrl_config ctrl_st_duration = {
.name = "duration",
.id = AML_V4L2_SET_DURATION,
@@ -4301,6 +4895,18 @@
.def = 0,
};
+static const struct v4l2_ctrl_config ctrl_stream_mode = {
+ .name = "stream mode",
+ .id = AML_V4L2_SET_STREAM_MODE,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
+ .min = 0,
+ .max = 1,
+ .step = 1,
+ .def = 0,
+};
+
static const struct v4l2_ctrl_config ctrl_gt_filmgrain_info = {
.name = "filmgrain info",
.id = AML_V4L2_GET_FILMGRAIN_INFO,
@@ -4313,6 +4919,56 @@
.def = 0,
};
+static const struct v4l2_ctrl_config ctrl_gt_bit_depth = {
+ .name = "bitdepth",
+ .id = AML_V4L2_GET_BITDEPTH,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ .min = 0,
+ .max = 128,
+ .step = 1,
+ .def = 0,
+};
+
+static const struct v4l2_ctrl_config ctrl_sgt_streamparm = {
+ .name = "streamparm",
+ .id = AML_V4L2_DEC_PARMS_CONFIG,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_COMPOUND_TYPES,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ .dims = { sizeof(struct aml_dec_params) },
+ .min = 0,
+ .max = 0xff,
+ .step = 1,
+ .def = 0,
+};
+
+static const struct v4l2_ctrl_config ctrl_get_inst_id = {
+ .name = "Get instance id",
+ .id = AML_V4L2_GET_INST_ID,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE,
+ .min = 0,
+ .max = 0x7fffffff,
+ .step = 1,
+ .def = 0,
+};
+
+static const struct v4l2_ctrl_config ctrl_gt_decoder_info = {
+ .name = "decoder information",
+ .id = AML_V4L2_GET_DECODER_INFO,
+ .ops = &aml_vcodec_dec_ctrl_ops,
+ .type = V4L2_CTRL_COMPOUND_TYPES,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
+ .min = 0,
+ .max = sizeof(struct aml_decoder_status_info),
+ .step = 1,
+ .elem_size = 1,
+ .dims = { sizeof(struct aml_decoder_status_info) },
+};
+
int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
{
int ret;
@@ -4345,24 +5001,66 @@
goto err;
}
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_set_dma_buf_mode, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_input_buffer_number, NULL);
if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
ret = ctx->ctrl_hdl.error;
goto err;
}
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_set_input_buffer_number_cache, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_duration, NULL);
if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
ret = ctx->ctrl_hdl.error;
goto err;
}
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_stream_mode, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_filmgrain_info, NULL);
if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
ret = ctx->ctrl_hdl.error;
goto err;
}
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_decoder_info, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_bit_depth, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_sgt_streamparm, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
+ ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_get_inst_id, NULL);
+ if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ret = ctx->ctrl_hdl.error;
+ goto err;
+ }
+
v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
return 0;
@@ -4404,31 +5102,89 @@
return 0;
}
-static int check_dec_cfginfo(struct aml_vdec_cfg_infos *cfg)
+static void vidioc_vdec_g_parm_ext(struct v4l2_ctrl *ctrl,
+ struct aml_vcodec_ctx *ctx)
{
- if (cfg->double_write_mode != 0 &&
- cfg->double_write_mode != 1 &&
- cfg->double_write_mode != 2 &&
- cfg->double_write_mode != 3 &&
- cfg->double_write_mode != 4 &&
- cfg->double_write_mode != 16 &&
- cfg->double_write_mode != 0x21 &&
- cfg->double_write_mode != 0x100 &&
- cfg->double_write_mode != 0x200) {
- pr_err("invalid double write mode %d\n", cfg->double_write_mode);
+ struct v4l2_streamparm parm = {0};
+
+ parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ memcpy(&parm.parm.raw_data, ctrl->p_new.p, sizeof(parm.parm.raw_data));
+ vidioc_vdec_g_parm(NULL, &ctx->fh, &parm);
+ memcpy(ctrl->p_new.p, &parm.parm.raw_data, sizeof(parm.parm.raw_data));
+
+}
+
+static int vidioc_vdec_g_pixelaspect(struct file *file, void *fh,
+ int buf_type, struct v4l2_fract *aspect)
+{
+ struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
+ u32 height_aspect_ratio, width_aspect_ratio;
+
+ if ((aspect == NULL) || (ctx == NULL)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "GET_PARAM_PIXEL_ASPECT_INFO err\n");
+ return -EFAULT;
+ }
+
+ height_aspect_ratio = ctx->height_aspect_ratio;
+ width_aspect_ratio = ctx->width_aspect_ratio;
+
+ if ((height_aspect_ratio != 0) && (width_aspect_ratio != 0)) {
+ aspect->numerator = height_aspect_ratio;
+ aspect->denominator = width_aspect_ratio;
+ }
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s: numerator is %d, denominator is %d\n",
+ __func__, aspect->numerator, aspect->denominator);
+
+ return 0;
+}
+
+static int check_dec_cfginfo(struct aml_vcodec_ctx *ctx, struct aml_vdec_cfg_infos *cfg)
+{
+ if (cfg->double_write_mode != DM_AVBC_ONLY &&
+ cfg->double_write_mode != DM_YUV_1_1_AVBC &&
+ cfg->double_write_mode != DM_YUV_1_4_AVBC_A &&
+ cfg->double_write_mode != DM_YUV_1_4_AVBC_B &&
+ cfg->double_write_mode != DM_YUV_1_2_AVBC &&
+ cfg->double_write_mode != DM_YUV_ONLY &&
+ cfg->double_write_mode != DM_AVBC_1_1 &&
+ cfg->double_write_mode != DM_YUV_AUTO_1_2_AVBC &&
+ cfg->double_write_mode != DM_YUV_AUTO_1_4_AVBC &&
+ cfg->double_write_mode != DM_YUV_AUTO_14_12_AVBC &&
+ cfg->double_write_mode != DM_YUV_1_1_10BIT_AVBC &&
+ cfg->double_write_mode != DM_YUV_1_4_10BIT_AVBC &&
+ cfg->double_write_mode != DM_YUV_1_2_10BIT_AVBC &&
+ cfg->double_write_mode != DM_YUV_1_8_10BIT_AVBC &&
+ cfg->double_write_mode != DM_YUV_14_11_10BIT_AVBC) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid DW:0x%x\n", cfg->double_write_mode);
return -1;
}
+
+ if (cfg->triple_write_mode != DM_INVALID &&
+ cfg->triple_write_mode != DM_YUV_1_1_AVBC &&
+ cfg->triple_write_mode != DM_YUV_1_4_AVBC_A &&
+ cfg->triple_write_mode != DM_YUV_1_4_AVBC_B &&
+ cfg->triple_write_mode != DM_YUV_1_2_AVBC &&
+ cfg->triple_write_mode != DM_YUV_1_1_10BIT_AVBC &&
+ cfg->triple_write_mode != DM_YUV_1_4_10BIT_AVBC &&
+ cfg->triple_write_mode != DM_YUV_1_2_10BIT_AVBC &&
+ cfg->triple_write_mode != DM_YUV_1_8_10BIT_AVBC &&
+ cfg->triple_write_mode != DM_YUV_14_11_10BIT_AVBC) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid TW:0x%x\n", cfg->triple_write_mode);
+ return -1;
+ }
+
if (cfg->ref_buf_margin > 20) {
- pr_err("invalid margin %d\n", cfg->ref_buf_margin);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid margin %d\n", cfg->ref_buf_margin);
return -1;
}
- if (mandatory_dw_mmu) {
- cfg->double_write_mode = 0x21;
- }
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "DW:%x, TW:%x, Margin:%d\n",
+ cfg->double_write_mode,
+ cfg->triple_write_mode,
+ cfg->ref_buf_margin);
- pr_info("double write mode %d margin %d\n",
- cfg->double_write_mode, cfg->ref_buf_margin);
return 0;
}
@@ -4459,10 +5215,17 @@
ctx->config.type = V4L2_CONFIG_PARM_DECODE;
if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
- if (check_dec_cfginfo(&in->cfg))
+ if (check_dec_cfginfo(ctx, &in->cfg))
return -EINVAL;
dec->cfg = in->cfg;
}
+
+ if (!vdec_if_set_param(ctx, SET_PARAM_CFG_INFO, &dec->cfg) &&
+ !vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
+ update_ctx_dimension(ctx, dst_vq->type);
+ aml_buf_configure_update(ctx);
+ }
+
if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
dec->ps = in->ps;
if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -4475,16 +5238,46 @@
/* aml v4l driver parms config. */
ctx->vpp_cfg.enable_nr =
(dec->cfg.metadata_config_flag & (1 << 15));
- if (force_enable_nr)
- ctx->vpp_cfg.enable_nr = true;
+ if (force_enable_nr) {
+ if (force_enable_nr & 0x1)
+ ctx->vpp_cfg.enable_nr = true;
+ if (force_enable_nr & 0x2)
+ ctx->vpp_cfg.enable_nr = false;
+ }
ctx->vpp_cfg.enable_local_buf =
(dec->cfg.metadata_config_flag & (1 << 14));
- if (force_enable_di_local_buffer)
- ctx->vpp_cfg.enable_local_buf = true;
+ if (force_enable_di_local_buffer) {
+ if (force_enable_di_local_buffer & 0x1)
+ ctx->vpp_cfg.enable_local_buf = true;
+ if (force_enable_di_local_buffer & 0x2)
+ ctx->vpp_cfg.enable_local_buf = false;
+ }
+ ctx->vpp_cfg.dynamic_bypass_vpp =
+ dec->cfg.metadata_config_flag & (1 << 10);
+
+ ctx->vpp_cfg.early_release_flag = dec->cfg.metadata_config_flag & (1 << 18);
+
+ ctx->ge2d_cfg.bypass =
+ (dec->cfg.metadata_config_flag & (1 << 9));
+ ctx->vpp_cfg.bypass =
+ (dec->cfg.metadata_config_flag & (1 << 8));
+
+ if (ctx->ge2d_cfg.bypass || ctx->vpp_cfg.bypass)
+ v4l_buf_size_decision(ctx);
ctx->internal_dw_scale = dec->cfg.metadata_config_flag & (1 << 13);
ctx->second_field_pts_mode = dec->cfg.metadata_config_flag & (1 << 12);
+ ctx->force_di_permission = dec->cfg.metadata_config_flag & (1 << 17);
+ ctx->no_fbc_output = dec->cfg.metadata_config_flag & (1 << 19);
+ if (force_di_permission)
+ ctx->force_di_permission = true;
+
+ ctx->enable_di_post = dec->cfg.metadata_config_flag & (1 << 20);
+ if (enable_di_post) {
+ ctx->enable_di_post = true;
+ }
+ ctx->alloc_type = dec->cfg.metadata_config_flag & (1 << 21);
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s parms:%x metadata_config_flag: 0x%x\n",
__func__, in->parms_status, dec->cfg.metadata_config_flag);
@@ -4497,6 +5290,21 @@
return 0;
}
+static void vidioc_vdec_s_parm_ext(struct v4l2_ctrl *ctrl,
+ struct aml_vcodec_ctx *ctx)
+{
+ struct v4l2_streamparm parm = {0};
+ struct vb2_queue *dst_vq;
+ dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+ if (dst_vq->is_multiplanar == 1)
+ parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ else
+ parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+ memcpy(&parm.parm.raw_data, ctrl->p_new.p, sizeof(parm.parm.raw_data));
+ vidioc_vdec_s_parm(NULL, &ctx->fh, &parm);
+}
const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
.device_run = m2mops_vdec_device_run,
@@ -4562,6 +5370,8 @@
.vidioc_g_parm = vidioc_vdec_g_parm,
.vidioc_s_parm = vidioc_vdec_s_parm,
+
+ .vidioc_g_pixelaspect = vidioc_vdec_g_pixelaspect,
};
int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
@@ -4575,11 +5385,11 @@
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
+ src_vq->buf_struct_size = sizeof(struct aml_v4l2_buf);
src_vq->ops = &aml_vdec_vb2_ops;
src_vq->mem_ops = &vb2_dma_sg_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &ctx->dev->dev_mutex;
+ src_vq->lock = &ctx->v4l_intf_lock;
ret = vb2_queue_init(src_vq);
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -4591,11 +5401,11 @@
V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
+ dst_vq->buf_struct_size = sizeof(struct aml_v4l2_buf);
dst_vq->ops = &aml_vdec_vb2_ops;
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &ctx->dev->dev_mutex;
+ dst_vq->lock = &ctx->v4l_intf_lock;
dst_vq->min_buffers_needed = 1;
ret = vb2_queue_init(dst_vq);
if (ret) {
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index 649c977..318d404 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _AML_VCODEC_DEC_H_
#define _AML_VCODEC_DEC_H_
@@ -25,9 +25,39 @@
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+//#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
#include "aml_vcodec_util.h"
#include "aml_task_chain.h"
+#include "aml_buf_mgr.h"
+
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
+#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+#else
+struct metadata {
+ char *p_md;
+ char *p_comp;
+};
+
+struct file_private_data {
+ struct vframe_s vf;
+ struct vframe_s *vf_p;
+ bool is_keep;
+ int keep_id;
+ int keep_head_id;
+ struct file *file;
+ ulong vb_handle;
+ ulong v4l_dec_ctx;
+ u32 v4l_inst_id;
+ struct vframe_s vf_ext;
+ struct vframe_s *vf_ext_p;
+ u32 flag;
+ struct metadata md;
+ void *private;
+ struct file *cnt_file;
+};
+
+#endif
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
@@ -41,16 +71,20 @@
#define VDEC_GATHER_MEMORY_TYPE 0
#define VDEC_SCATTER_MEMORY_TYPE 1
-#define META_DATA_SIZE (256)
+#define VDEC_META_DATA_SIZE (256)
+#ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
#define MD_BUF_SIZE (1024)
#define COMP_BUF_SIZE (8196)
+#endif
#define SEI_BUF_SIZE (2 * 12 * 1024)
+#define HDR10P_BUF_SIZE (128)
+
#define SEI_TYPE (1)
#define DV_TYPE (2)
-
+#define HDR10P_TYPE (4)
/*
- * struct vdec_v4l2_buffer - decoder frame buffer
+ * struct aml_buf - decoder frame buffer
* @mem_type : gather or scatter memory.
* @num_planes : used number of the plane
* @mem[4] : array mem for used planes,
@@ -61,8 +95,8 @@
* @vframe : store the vframe that get from caller.
* @task : the context of task chain manager.
*/
-
-struct vdec_v4l2_buffer {
+/*
+struct aml_buf {
int mem_type;
int num_planes;
union {
@@ -74,46 +108,70 @@
void *vframe;
struct task_chain_s *task;
-};
+};*///todo
/**
- * struct aml_video_dec_buf - Private data related to each VB2 buffer.
+ * struct aml_v4l2_buf - Private data related to each VB2 buffer.
* @b: VB2 buffer
* @list: link list
* @used: Capture buffer contain decoded frame data and keep in
* codec data structure
* @lastframe: Intput buffer is last buffer - EOS
* @error: An unrecoverable error occurs on this buffer.
- * @frame_buffer: Decode status, and buffer information of Capture buffer
+ * @aml_buf: Decode status, and buffer information of Capture buffer
*
* Note : These status information help us track and debug buffer state
*/
-struct aml_video_dec_buf {
+struct aml_v4l2_buf {
struct vb2_v4l2_buffer vb;
struct list_head list;
- struct vdec_v4l2_buffer frame_buffer;
+ struct aml_buf *aml_buf;
struct file_private_data privdata;
struct codec_mm_s *mem[2];
- char mem_onwer[32];
+ char mem_owner[32];
bool used;
- bool que_in_m2m;
+ bool attached;
bool lastframe;
bool error;
/* internal compressed buffer */
unsigned int internal_index;
- ulong vpp_buf_handle;
- ulong ge2d_buf_handle;
-
/*4 bytes data for data len*/
- char meta_data[META_DATA_SIZE + 4];
-
+ char meta_data[VDEC_META_DATA_SIZE + 4];
+ void *dma_buf;
struct sg_table *out_sgt;
- struct sg_table *cap_sgt;
+ ulong addr;
};
+#define AML_ES_REF_MAX (1024)
+
+struct aml_es_mgr {
+ DECLARE_KFIFO_PTR(ref_q, typeof(struct aml_es_ref_elem*));
+ DECLARE_KFIFO_PTR(free_q, typeof(struct aml_es_ref_elem*));
+ void *elems;
+
+ /* The start position of unconsumed. */
+ ulong cursor_Wp;
+
+ ulong buf_start;
+ u32 buf_size;
+
+ struct aml_vcodec_ctx *ctx;
+ atomic_t buf_cache;
+};
+
+struct aml_es_ref_elem {
+ struct dma_buf *dbuf;
+ ulong buf_start;
+ u32 buf_size;
+ ulong au_addr;
+ u32 au_size;
+ u64 timestamp;
+};
+
+
extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops;
extern const struct v4l2_m2m_ops aml_vdec_m2m_ops;
@@ -137,13 +195,40 @@
void aml_v4l_vpp_release_early(struct aml_vcodec_ctx * ctx);
void aml_v4l_ctx_release(struct kref *kref);
void dmabuff_recycle_worker(struct work_struct *work);
-void aml_buffer_status(struct aml_vcodec_ctx *ctx);
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx);
+ssize_t aml_buffer_status(struct aml_vcodec_ctx *ctx, char *buf);
+void aml_compressed_info_show(struct aml_vcodec_ctx *ctx);
+void cal_compress_buff_info(ulong used_page_num, struct aml_vcodec_ctx *ctx);
+
+ssize_t aml_vdec_basic_information(struct aml_vcodec_ctx *ctx, char *buf);
+void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
+ struct aml_buf *aml_buf,
+ u32 requester);
void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag);
void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag);
void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
void aml_bind_sei_buffer(struct aml_vcodec_ctx *v4l, char **addr, int *size, int *idx);
void aml_bind_dv_buffer(struct aml_vcodec_ctx *v4l, char **comp_buf, char **md_buf);
+void aml_bind_hdr10p_buffer(struct aml_vcodec_ctx *v4l, char **addr);
+
+int aml_canvas_cache_init(struct aml_vcodec_dev *dev);
+void aml_canvas_cache_put(struct aml_vcodec_dev *dev);
+int aml_canvas_cache_get(struct aml_vcodec_dev *dev, char *usr);
+int aml_uvm_buff_attach(struct vb2_buffer * vb);
+
+int aml_es_mgr_init(struct aml_vcodec_ctx *ctx);
+void aml_es_mgr_release(struct aml_vcodec_ctx *ctx);
+
+int aml_es_write(struct aml_vcodec_ctx *ctx, struct dma_buf *dbuf,
+ ulong addr, u32 size, u64 timestamp);
+
+void fbc_transcode_and_set_vf(struct aml_vcodec_ctx *ctx,
+ struct aml_buf *aml_buf,
+ struct vframe_s *vf);
+ssize_t dump_cma_and_sys_memsize(struct aml_vcodec_ctx *ctx, char *buf);
+
+ulong get_addr(struct vb2_buffer *vb, int i);
+
+
#endif /* _AML_VCODEC_DEC_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
index f92f4a8..cb78b57 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -1,23 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#define DEBUG
#include <linux/slab.h>
#include <linux/interrupt.h>
@@ -30,10 +29,15 @@
#include <media/videobuf2-dma-contig.h>
#include <linux/kthread.h>
#include <linux/compat.h>
+#include <linux/version.h>
+#include <media/v4l2-dev.h>
+
#include "aml_vcodec_drv.h"
#include "aml_vcodec_dec.h"
#include "aml_vcodec_util.h"
#include "aml_vcodec_vpp.h"
+#include "../frame_provider/decoder/utils/decoder_report.h"
+
#include <linux/file.h>
#include <linux/anon_inodes.h>
@@ -51,35 +55,36 @@
bool param_sets_from_ucode = 1;
bool enable_drm_mode;
extern void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx);
+char dump_path[32] = "/data";
static int fops_vcodec_open(struct file *file)
{
struct aml_vcodec_dev *dev = video_drvdata(file);
struct aml_vcodec_ctx *ctx = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- int ret = 0;
+ struct aml_v4l2_buf *aml_vb = NULL;
struct vb2_queue *src_vq;
+ int ret = 0;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
kref_init(&ctx->ctx_ref);
- aml_buf = kzalloc(sizeof(*aml_buf), GFP_KERNEL);
- if (!aml_buf) {
+ aml_vb = kzalloc(sizeof(*aml_vb), GFP_KERNEL);
+ if (!aml_vb) {
kfree(ctx);
return -ENOMEM;
}
ctx->meta_infos.meta_bufs = vzalloc(sizeof(struct meta_data) * V4L_CAP_BUFF_MAX);
if (ctx->meta_infos.meta_bufs == NULL) {
- kfree(aml_buf);
+ kfree(aml_vb);
kfree(ctx);
return -ENOMEM;
}
mutex_lock(&dev->dev_mutex);
- ctx->empty_flush_buf = aml_buf;
+ ctx->empty_flush_buf = aml_vb;
ctx->id = dev->id_counter++;
v4l2_fh_init(&ctx->fh, video_devdata(file));
file->private_data = &ctx->fh;
@@ -94,19 +99,27 @@
mutex_init(&ctx->buff_done_lock);
mutex_init(&ctx->state_lock);
mutex_init(&ctx->comp_lock);
+ mutex_init(&ctx->compressed_buf_info_lock);
spin_lock_init(&ctx->slock);
spin_lock_init(&ctx->tsplock);
- spin_lock_init(&ctx->dmabuff_recycle_lock);
+ spin_lock_init(&ctx->es_wkr_slock);
init_completion(&ctx->comp);
init_waitqueue_head(&ctx->wq);
init_waitqueue_head(&ctx->cap_wq);
init_waitqueue_head(&ctx->post_done_wq);
- INIT_WORK(&ctx->dmabuff_recycle_work, dmabuff_recycle_worker);
+ INIT_WORK(&ctx->es_wkr_out, dmabuff_recycle_worker);
INIT_KFIFO(ctx->dmabuff_recycle);
INIT_KFIFO(ctx->capture_buffer);
+ atomic_set(&ctx->vpp_cache_num, 0);
+ atomic_set(&ctx->ge2d_cache_num, 0);
+ mutex_init(&ctx->v4l_intf_lock);
ctx->post_to_upper_done = true;
ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0;
+ ctx->cache_input_buffer_num = 60;
+ ctx->write_frames = 0;
+
+ aml_es_mgr_init(ctx);
if (enable_drm_mode) {
ctx->is_drm_mode = true;
@@ -134,9 +147,11 @@
ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
ctx->empty_flush_buf->lastframe = true;
ctx->vdec_pic_info_update = aml_vdec_pic_info_update;
+ ctx->cal_compress_buff_info = cal_compress_buff_info;
+ ctx->fbc_transcode_and_set_vf = fbc_transcode_and_set_vf;
aml_vcodec_dec_set_default_params(ctx);
ctx->is_stream_off = true;
-
+ ctx->set_ext_buf_flg = false;
ctx->aux_infos.dv_index = 0;
ctx->aux_infos.sei_index = 0;
ctx->aux_infos.alloc_buffer = aml_alloc_buffer;
@@ -144,6 +159,14 @@
ctx->aux_infos.bind_sei_buffer = aml_bind_sei_buffer;
ctx->aux_infos.bind_dv_buffer = aml_bind_dv_buffer;
ctx->aux_infos.free_one_sei_buffer = aml_free_one_sei_buffer;
+ ctx->aux_infos.bind_hdr10p_buffer = aml_bind_hdr10p_buffer;
+
+ ret = aml_buf_mgr_init(&ctx->bm, "v4ldec-m2m", ctx->id, ctx);
+ if (ret) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "Failed to init buffer manager.\n");
+ goto err_buffer_manager;
+ }
ret = aml_thread_start(ctx, aml_thread_capture_worker, AML_THREAD_CAPTURE, "cap");
if (ret) {
@@ -154,8 +177,10 @@
list_add(&ctx->list, &dev->ctx_list);
+ ctx->dv_id = -1;
+
mutex_unlock(&dev->dev_mutex);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n",
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "%s decoder %lx\n",
dev_name(&dev->plat_dev->dev), (ulong)ctx);
return 0;
@@ -163,6 +188,8 @@
/* Deinit when failure occurred */
err_creat_thread:
v4l2_m2m_ctx_release(ctx->m2m_ctx);
+err_buffer_manager:
+ aml_buf_mgr_release(&ctx->bm);
err_m2m_ctx_init:
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
err_ctrls_setup:
@@ -181,9 +208,8 @@
struct aml_vcodec_dev *dev = video_drvdata(file);
struct aml_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "release decoder %lx\n", (ulong) ctx);
mutex_lock(&dev->dev_mutex);
-
aml_thread_stop(ctx);
wait_vcodec_ending(ctx);
vb2_queue_release(&ctx->m2m_ctx->cap_q_ctx.q);
@@ -197,6 +223,7 @@
list_del_init(&ctx->list);
kfree(ctx->empty_flush_buf);
+ aml_buf_mgr_release(&ctx->bm);
aml_v4l_vpp_release_early(ctx);
kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
mutex_unlock(&dev->dev_mutex);
@@ -241,7 +268,7 @@
kzalloc(sizeof(struct file_private_data), GFP_KERNEL);
if (!file->private_data) {
v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "alloc priv data faild.\n");
+ "alloc priv data failed.\n");
return -ENOMEM;
}
@@ -464,10 +491,11 @@
list_for_each_entry(ctx, &dev->ctx_list, list) {
/* basic information. */
- aml_vdec_basic_information(ctx);
+ pbuf += aml_vdec_basic_information(ctx, pbuf);
/* buffers status. */
- aml_buffer_status(ctx);
+ pbuf += aml_buffer_status(ctx, pbuf);
+ pbuf += dump_cma_and_sys_memsize(ctx, pbuf);
}
out:
mutex_unlock(&dev->dev_mutex);
@@ -475,10 +503,64 @@
return pbuf - buf;
}
+ssize_t show_v4ldec_state(struct aml_vcodec_dev *dev, char *buf) {
+ return status_show(&dev->v4ldec_class, NULL, buf);
+}
+EXPORT_SYMBOL(show_v4ldec_state);
+
+static ssize_t mmu_mem_info_show(struct class *cls,
+ struct class_attribute *attr, char *buf)
+{
+ struct aml_vcodec_dev *dev = container_of(cls,
+ struct aml_vcodec_dev, v4ldec_class);
+ struct aml_vcodec_ctx *ctx = NULL;
+ char *pbuf = buf;
+
+ mutex_lock(&dev->dev_mutex);
+
+ if (list_empty(&dev->ctx_list)) {
+ pbuf += sprintf(pbuf, "No v4ldec context.\n");
+ goto out;
+ }
+
+ list_for_each_entry(ctx, &dev->ctx_list, list) {
+ aml_compressed_info_show(ctx);
+ }
+out:
+ mutex_unlock(&dev->dev_mutex);
+
+ return pbuf - buf;
+}
+
+static ssize_t dump_path_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return snprintf(buf, sizeof(dump_path), "%s\n", dump_path);
+}
+
+static ssize_t dump_path_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t size)
+{
+ ssize_t n;
+ if (size > sizeof(dump_path))
+ pr_err("path too long\n");
+ n = snprintf(dump_path, sizeof(dump_path), "%s", buf);
+ if (n > 0 && dump_path[n-1] == '\n') {
+ dump_path[n-1] = 0;
+ pr_info("dump path changed to %s\n", dump_path);
+ }
+ return size;
+}
+
static CLASS_ATTR_RO(status);
+static CLASS_ATTR_RO(mmu_mem_info);
+static CLASS_ATTR_RW(dump_path);
static struct attribute *v4ldec_class_attrs[] = {
&class_attr_status.attr,
+ &class_attr_dump_path.attr,
+ &class_attr_mmu_mem_info.attr,
NULL
};
@@ -543,7 +625,7 @@
}
dev->decode_workqueue =
- alloc_ordered_workqueue("output-worker",
+ alloc_ordered_workqueue("dec-worker",
__WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
if (!dev->decode_workqueue) {
dev_err(&pdev->dev, "Failed to create decode workqueue\n");
@@ -553,7 +635,11 @@
//dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26);
+#else
+ ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 26);
+#endif
if (ret) {
dev_err(&pdev->dev, "Failed to register video device\n");
goto err_dec_reg;
@@ -569,18 +655,26 @@
goto err_reg_class;
}
+ ret = aml_canvas_cache_init(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "v4l dec alloc canvas fail.\n");
+ goto err_alloc_canvas;
+ }
+ register_dump_v4ldec_state_func(dev, show_v4ldec_state);
dev_info(&pdev->dev, "v4ldec registered as /dev/video%d\n", vfd_dec->num);
return 0;
-err_reg_class:
+err_alloc_canvas:
class_unregister(&dev->v4ldec_class);
+err_reg_class:
+ video_unregister_device(vfd_dec);
err_dec_reg:
destroy_workqueue(dev->decode_workqueue);
err_event_workq:
v4l2_m2m_release(dev->m2m_dev_dec);
err_dec_mem_init:
- video_unregister_device(vfd_dec);
+ video_device_release(vfd_dec);
err_dec_alloc:
v4l2_device_unregister(&dev->v4l2_dev);
err_res:
@@ -605,6 +699,8 @@
v4l2_device_unregister(&dev->v4l2_dev);
+ aml_canvas_cache_put(dev);
+
dev_info(&pdev->dev, "v4ldec removed.\n");
return 0;
@@ -628,7 +724,8 @@
static int __init amvdec_ports_init(void)
{
- pr_info("v4l dec module init\n");
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "v4l dec module init\n");
if (platform_driver_register(&aml_vcodec_dec_driver)) {
pr_err("failed to register v4l dec driver\n");
@@ -652,9 +749,13 @@
EXPORT_SYMBOL(debug_mode);
module_param(debug_mode, uint, 0644);
-u32 mandatory_dw_mmu;
-EXPORT_SYMBOL(mandatory_dw_mmu);
-module_param(mandatory_dw_mmu, uint, 0644);
+int t3x_tw_output;
+EXPORT_SYMBOL(t3x_tw_output);
+module_param(t3x_tw_output, int, 0644);
+
+u32 disable_vpp_dw_mmu;
+EXPORT_SYMBOL(disable_vpp_dw_mmu);
+module_param(disable_vpp_dw_mmu, uint, 0644);
bool aml_set_vfm_enable;
EXPORT_SYMBOL(aml_set_vfm_enable);
@@ -726,6 +827,10 @@
EXPORT_SYMBOL(bypass_progressive);
module_param(bypass_progressive, int, 0644);
+int force_di_permission;
+EXPORT_SYMBOL(force_di_permission);
+module_param(force_di_permission, int, 0644);
+
bool support_mjpeg;
EXPORT_SYMBOL(support_mjpeg);
module_param(support_mjpeg, bool, 0644);
@@ -742,6 +847,14 @@
EXPORT_SYMBOL(force_enable_di_local_buffer);
module_param(force_enable_di_local_buffer, int, 0644);
+int es_node_expand = 1;
+EXPORT_SYMBOL(es_node_expand);
+module_param(es_node_expand, int, 0644);
+
+int dump_es_output_frame;
+EXPORT_SYMBOL(dump_es_output_frame);
+module_param(dump_es_output_frame, int, 0644);
+
int vpp_bypass_frames;
EXPORT_SYMBOL(vpp_bypass_frames);
module_param(vpp_bypass_frames, int, 0644);
@@ -750,6 +863,14 @@
EXPORT_SYMBOL(bypass_nr_flag);
module_param(bypass_nr_flag, int, 0644);
+u32 trace_config = 0xffffffff;
+EXPORT_SYMBOL(trace_config);
+module_param(trace_config, uint, 0644);
+
+int enable_di_post;
+EXPORT_SYMBOL(enable_di_post);
+module_param(enable_di_post, int, 0644);
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("AML video codec V4L2 decoder driver");
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 522fe67..32a3c2b 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _AML_VCODEC_DRV_H_
#define _AML_VCODEC_DRV_H_
@@ -30,9 +30,13 @@
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+#include <media/v4l2-mem2mem.h>
+//#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+
+#include "utils/aml_dec_trace.h"
#include "aml_vcodec_util.h"
#include "aml_vcodec_dec.h"
+#include "aml_vcodec_ts.h"
#define AML_VCODEC_DRV_NAME "aml_vcodec_drv"
#define AML_VCODEC_DEC_NAME "aml-vcodec-dec"
@@ -62,6 +66,9 @@
/* exception handing */
#define V4L2_EVENT_REQUEST_RESET (1 << 8)
#define V4L2_EVENT_REQUEST_EXIT (1 << 9)
+#define V4L2_EVENT_SEND_ERROR (1 << 10)
+#define V4L2_EVENT_REPORT_ERROR_FRAME (1 << 11)
+
/* eos event */
#define V4L2_EVENT_SEND_EOS (1 << 16)
@@ -87,6 +94,10 @@
#define TRANS_ABORT (1 << 2)
#define CTX_BUF_TOTAL(ctx) (ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size)
+
+#define MAX_AVBC_BUFFER_SIZE 16
+
+#define MAX_VPP_BUFFER_CACHE_NUM 16
/**
* enum aml_hw_reg_idx - AML hw register base index
*/
@@ -197,6 +208,10 @@
enum v4l2_field field;
u32 bytesperline[AML_VCODEC_MAX_PLANES];
u32 sizeimage[AML_VCODEC_MAX_PLANES];
+
+ u32 bytesperline_tw[AML_VCODEC_MAX_PLANES];
+ u32 sizeimage_tw[AML_VCODEC_MAX_PLANES];
+
struct aml_video_fmt *fmt;
bool resolution_changed;
};
@@ -241,7 +256,7 @@
* @visible_width: picture width
* @visible_height: picture height
* @coded_width: picture buffer width (64 aligned up from pic_w)
- * @coded_height: picture buffer heiht (64 aligned up from pic_h)
+ * @coded_height: picture buffer height (64 aligned up from pic_h)
* @y_bs_sz: Y bitstream size
* @c_bs_sz: CbCr bitstream size
* @y_len_sz: additional size required to store decompress information for y
@@ -265,17 +280,20 @@
u32 c_bs_sz;
u32 y_len_sz;
u32 c_len_sz;
+ u32 y_len_sz_tw;
+ u32 c_len_sz_tw;
int profile_idc;
enum v4l2_field field;
u32 dpb_frames;
u32 dpb_margin;
u32 vpp_margin;
+ u32 bitdepth;
};
/**
* struct vdec_comp_buf_info - compressed buffer info
* @max_size: max size needed for MMU Box in MB
- * @header_size: contineous size for the compressed header
+ * @header_size: continuous size for the compressed header
* @frame_buffer_size: SG page number to store the frame
*/
struct vdec_comp_buf_info {
@@ -294,18 +312,28 @@
u32 low_latency_mode;
u32 uvm_hook_type;
/*
+ * bit 21 : buffer alloc flag. 0: dma heap, 1: ion heap.
+ * bit 20 : di post flag.
+ * bit 19 : no-surface flag.
+ * bit 18 : release vpp early. 0:false, 1:true
+ * bit 17 : force di permission.
* bit 16 : force progressive output flag.
* bit 15 : enable nr.
* bit 14 : enable di local buff.
* bit 13 : report downscale yuv buffer size flag.
* bit 12 : for second field pts mode.
- * bit 11 : disable error policy
+ * bit 11 : disable error policy.
+ * bit 10 : dynamic bypass vpp.
+ * bit 9 : disable ge2d wrapper.
+ * bit 8 : disable vpp wrapper.
* bit 1 : Non-standard dv flag.
* bit 0 : dv two layer flag.
*/
u32 metadata_config_flag; // for metadata config flag
u32 duration;
- u32 data[4];
+ u32 triple_write_mode;
+ u32 dv_profile;
+ u32 data[2];
};
struct aml_vdec_hdr_infos {
@@ -342,7 +370,8 @@
u32 dpb_frames;
u32 dpb_margin;
u32 field;
- u32 data[3];
+ u32 bitdepth;
+ u32 data[2];
};
struct aml_vdec_cnt_infos {
@@ -382,6 +411,15 @@
u32 dec, vpp, ge2d;
};
+struct v4l_compressed_buffer_info {
+ u64 used_page_sum;
+ u32 recycle_num;
+ u32 used_page_distributed_array[MAX_AVBC_BUFFER_SIZE];
+ u32 used_page_in_group[V4L_CAP_BUFF_MAX];
+ u32 max_avg_val_by_group;
+ u32 used_page_by_group;
+};
+
enum aml_thread_type {
AML_THREAD_OUTPUT,
AML_THREAD_CAPTURE,
@@ -427,10 +465,14 @@
ulong header_dw_addr;
void *mmu_box_dw;
void *bmmu_box_dw;
+#ifdef NEW_FB_CODE
+ void *mmu_box_1;
+ void *mmu_box_dw_1;
+#endif
};
/*
- * struct aml_uvm_buff_ref - uvm buff is used reseve ctx ref count.
+ * struct aml_uvm_buff_ref - uvm buff is used reserve ctx ref count.
* @index : index of video buffer.
* @addr : physic address of video buffer.
* @ref : reference of v4ldec context.
@@ -444,7 +486,7 @@
};
/*
- * enum aml_fb_requester - indicate which module request fb buffers.
+ * enum aml_fb_requester - indicate which module request aml_buf buffers.
*/
enum aml_fb_requester {
AML_FB_REQ_DEC,
@@ -454,12 +496,12 @@
};
/*
- * @query: try to achieved fb token.
- * @alloc: used for allocte fb buffer.
+ * @query: try to achieved aml_buf token.
+ * @alloc: used for allocte aml_buf buffer.
*/
struct aml_fb_ops {
bool (*query)(struct aml_fb_ops *, ulong *);
- int (*alloc)(struct aml_fb_ops *, ulong, struct vdec_v4l2_buffer **, u32);
+ int (*alloc)(struct aml_fb_ops *, ulong, struct aml_buf **, u32);
};
/*
@@ -492,12 +534,14 @@
int sei_state;
char* comp_buf;
char* md_buf;
+ char* hdr10p_buf;
};
/*
* struct aux_info - record aux data infos
* @sei_index: sei data index.
* @dv_index: dv data index.
+ * @hdr10p_index: hdr10p data index.
* @sei_need_free: sei buffer need to free.
* @bufs: stores aux data.
* @alloc_buffer: alloc aux buffer functions.
@@ -505,10 +549,12 @@
* @free_one_sei_buffer:free sei buffer with index functions.
* @bind_sei_buffer: bind sei buffer functions.
* @bind_dv_buffer: bind dv buffer functions.
+ * @bind_hdr10p_buffer: bind hdr10p buffer functions.
*/
struct aux_info {
int sei_index;
- int dv_index;
+ int dv_index;
+ int hdr10p_index;
bool sei_need_free;
struct aux_data bufs[V4L_CAP_BUFF_MAX];
void (*alloc_buffer)(struct aml_vcodec_ctx *ctx, int flag);
@@ -516,14 +562,15 @@
void (*free_one_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
void (*bind_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx);
void (*bind_dv_buffer)(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf);
+ void (*bind_hdr10p_buffer)(struct aml_vcodec_ctx *ctx, char **addr);
};
/*
* struct meta_data - record meta data.
- * @buf[META_DATA_SIZE]: meta data information.
+ * @buf[VDEC_META_DATA_SIZE]: meta data information.
*/
struct meta_data {
- char buf[META_DATA_SIZE];
+ char buf[VDEC_META_DATA_SIZE];
};
/*
@@ -560,12 +607,45 @@
bool enable_local_buf;
bool res_chg;
bool is_vpp_reset;
+ bool dynamic_bypass_vpp;
+ bool early_release_flag;
+ bool bypass;
};
struct aml_ge2d_cfg_infos {
u32 mode;
u32 buf_size;
bool is_drm;
+ bool bypass;
+};
+
+struct canvas_res {
+ int cid;
+ u8 name[32];
+};
+
+struct canvas_cache {
+ int ref;
+ struct canvas_res res[8];
+ struct mutex lock;
+};
+
+struct aml_decoder_status_info {
+ u32 error_type;
+ u32 frame_width;
+ u32 frame_height;
+ u32 decoder_count;
+ u32 decoder_error_count;
+};
+
+struct cma_sys_size_info {
+ int max_total_size;
+ int cma_part;
+ int sys_part;
+ int max_cma_size;
+ int max_sys_size;
+ int cur_cma_size;
+ int cur_sys_size;
};
/*
@@ -589,7 +669,7 @@
* @queue: waitqueue that can be used to wait for this context to finish.
* @state_lock: protect the codec status.
* @state: state of the context.
- * @decode_work: decoder work be used to output buffer.
+
* @output_thread_ready: indicate the output thread ready.
* @cap_pool: capture buffers are remark in the pool.
* @vdec_thread_list: vdec thread be used to capture.
@@ -598,7 +678,8 @@
* @param_change: indicate encode parameter type
* @param_sets_from_ucode: if true indicate ps from ucode.
* @v4l_codec_dpb_ready: queue buffer number greater than dpb.
- # @v4l_resolution_change: indicate resolution change happend.
+ * @dst_queue_streaming: the state of the destination queue.
+ * @v4l_resolution_change: indicate resolution change happened.
* @comp: comp be used for sync picture information with decoder.
* @config: used to set or get parms for application.
* @picinfo: store picture info after header parsing.
@@ -619,8 +700,10 @@
* @buf_used_count: means that decode allocate how many buffs from v4l.
* @wq: wait recycle dma buffer finish.
* @cap_wq: the wq used for wait capture buffer.
- * @dmabuff_recycle_lock: protect the lock dmabuff free.
- * @dmabuff_recycle_work: used for recycle dmabuff.
+ * @es_wkr_in: Used to write es buffer from v4l2 core to decoder.
+ * @es_wkr_out: Used to recover the es buffer consumed by the decoder.
+ * @es_wkr_slock: Ensure the data access security of the es buffer work queue.
+ * @es_wkr_stop: Indicates that the es work queue stops working.
* @dmabuff_recycle: kfifo used for store vb buff.
* @capture_buffer: kfifo used for store capture vb buff.
* @mmu_box: mmu_box of context.
@@ -636,6 +719,9 @@
* @vpp_is_need: the instance is need vpp.
* @task_chain_pool: used to store task chain inst.
* @index_disp: the number of frames output.
+ * @buffer manager context.
+ * @force_report_interlace: the flag for conversion field.
+ * @force_tw_output: The flag for T3X output TW YUV.
*/
struct aml_vcodec_ctx {
int id;
@@ -651,14 +737,13 @@
struct v4l2_ctrl_handler ctrl_hdl;
spinlock_t slock;
spinlock_t tsplock;
- struct aml_video_dec_buf *empty_flush_buf;
+ struct aml_v4l2_buf *empty_flush_buf;
struct list_head list;
struct aml_q_data q_data[2];
wait_queue_head_t queue;
struct mutex state_lock;
enum aml_instance_state state;
- struct work_struct decode_work;
bool output_thread_ready;
struct v4l_buff_pool cap_pool;
struct list_head vdec_thread_list;
@@ -668,6 +753,7 @@
int ge2d_size;
bool param_sets_from_ucode;
bool v4l_codec_dpb_ready;
+ bool dst_queue_streaming;
bool v4l_resolution_change;
struct completion comp;
struct v4l2_config_parm config;
@@ -691,9 +777,13 @@
int buf_used_count;
wait_queue_head_t wq, cap_wq, post_done_wq;
struct mutex capture_buffer_lock;
- spinlock_t dmabuff_recycle_lock;
struct mutex buff_done_lock;
- struct work_struct dmabuff_recycle_work;
+
+ struct work_struct es_wkr_in;
+ struct work_struct es_wkr_out;
+ spinlock_t es_wkr_slock;
+ bool es_wkr_stop;
+
DECLARE_KFIFO(dmabuff_recycle, struct vb2_v4l2_buffer *, 32);
DECLARE_KFIFO(capture_buffer, struct vb2_v4l2_buffer *, 32);
@@ -724,12 +814,59 @@
bool ge2d_is_need;
bool second_field_pts_mode;
+ bool force_di_permission;
struct aux_info aux_infos;
+ u32 capture_memory_mode;
+ u32 height_aspect_ratio;
+ u32 width_aspect_ratio;
u32 index_disp;
bool post_to_upper_done;
bool film_grain_present;
void *bmmu_box_dw;
void *mmu_box_dw;
+
+ void (*cal_compress_buff_info)(ulong, struct aml_vcodec_ctx *ctx);
+ struct mutex compressed_buf_info_lock;
+ struct v4l_compressed_buffer_info compressed_buf_info;
+
+ u32 stream_mode;
+ bool set_ext_buf_flg;
+ s32 ptsserver_id;
+ struct pts_server_ops *pts_serves_ops;
+
+ struct aml_buf_mgr_s bm;
+ void (*vdec_recycle_dec_resource)(void *, struct aml_buf *);
+
+ atomic_t vpp_cache_num;
+ atomic_t ge2d_cache_num;
+ int cache_input_buffer_num;
+ int in_buff_cnt;
+ int out_buff_cnt;
+ int write_frames;
+ u64 current_timestamp;
+ bool force_recycle;
+
+ struct vdec_trace vtr;
+ int dv_id;
+ struct aml_es_mgr es_mgr;
+ void (*es_free)(struct aml_vcodec_ctx *, ulong);
+ bool v4l_reqbuff_flag;
+#ifdef NEW_FB_CODE
+ int front_back_mode;
+ void *mmu_box_1;
+ void *mmu_box_dw_1;
+#endif
+ struct mutex v4l_intf_lock;
+ void (*fbc_transcode_and_set_vf)(struct aml_vcodec_ctx *, struct aml_buf *,
+ struct vframe_s *);
+ bool no_fbc_output;
+ bool force_report_interlace;
+ struct cma_sys_size_info mem_size_info;
+ struct aml_decoder_status_info decoder_status_info;
+ struct aml_buf *master_buf;
+ bool enable_di_post;
+ u32 alloc_type;
+ bool force_tw_output;
};
/**
@@ -748,7 +885,8 @@
* @dec_mutex : decoder hardware lock.
* @queue : waitqueue for waiting for completion of device commands.
* @vpp_count : count the number of open vpp.
- * @v4ldec_class : creat class sysfs uesd to show some information.
+ * @v4ldec_class : creat class sysfs used to show some information.
+ * @cache : canvas pool specific used for v4ldec context.
*/
struct aml_vcodec_dev {
struct v4l2_device v4l2_dev;
@@ -767,6 +905,7 @@
wait_queue_head_t queue;
atomic_t vpp_count;
struct class v4ldec_class;
+ struct canvas_cache cache;
};
static inline struct aml_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
@@ -784,5 +923,31 @@
int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
enum aml_thread_type type, const char *thread_name);
void aml_thread_stop(struct aml_vcodec_ctx *ctx);
+void aml_vdec_recycle_dec_resource(struct aml_vcodec_ctx * ctx,
+ struct aml_buf *aml_buf);
+typedef ssize_t (*dump_v4ldec_state_func)(struct aml_vcodec_dev *dev, char *);
+
+/*
+ * v4l2_m2m_job_pause() - paused the schedule of data which from the job queue.
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+void v4l2_m2m_job_pause(struct v4l2_m2m_dev *m2m_dev,
+ struct v4l2_m2m_ctx *m2m_ctx);
+
+ /*
+ * v4l2_m2m_job_resume() - resumed the schedule of data which from the job que.
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+void v4l2_m2m_job_resume(struct v4l2_m2m_dev *m2m_dev,
+ struct v4l2_m2m_ctx *m2m_ctx);
+
+#define V4L2_PIX_FMT_AV1 v4l2_fourcc('A', 'V', '1', '0') /* av1 */
+#define V4L2_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0') /* avs */
+#define V4L2_PIX_FMT_AVS2 v4l2_fourcc('A', 'V', 'S', '2') /* avs2 */
+#define V4L2_PIX_FMT_AVS3 v4l2_fourcc('A', 'V', 'S', '3') /* avs3 */
#endif /* _AML_VCODEC_DRV_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.c b/drivers/amvdec_ports/aml_vcodec_ge2d.c
index 2d331ed..8a5a6d3 100644
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.c
+++ b/drivers/amvdec_ports/aml_vcodec_ge2d.c
@@ -1,23 +1,22 @@
/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
@@ -27,20 +26,22 @@
#include <linux/amlogic/media/ge2d/ge2d.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
#include "../common/chips/decoder_cpu_ver_info.h"
#include "aml_vcodec_ge2d.h"
#include "aml_vcodec_adapt.h"
#include "vdec_drv_if.h"
+#include "utils/common.h"
+#include "../common/media_utils/media_utils.h"
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
+#define GE2D_BUF_GET_IDX(ge2d_buf) (ge2d_buf->aml_vb->vb.vb2_buf.index)
-#define GE2D_BUF_GET_IDX(ge2d_buf) (ge2d_buf->aml_buf->vb.vb2_buf.index)
#define INPUT_PORT 0
#define OUTPUT_PORT 1
extern int dump_ge2d_input;
extern int ge2d_bypass_frames;
+extern char dump_path[32];
enum GE2D_FLAG {
GE2D_FLAG_P = 0x1,
@@ -100,11 +101,11 @@
static int get_input_format(struct vframe_s *vf)
{
int format = GE2D_FORMAT_M24_YUV420;
- enum videocom_source_type soure_type;
+ enum videocom_source_type source_type;
- soure_type = get_source_type(vf);
+ source_type = get_source_type(vf);
- switch (soure_type) {
+ switch (source_type) {
case DECODER_8BIT_NORMAL:
if (vf->type & VIDTYPE_VIU_422)
format = GE2D_FORMAT_S16_YUV422;
@@ -189,10 +190,16 @@
return format;
}
+static void update_ge2d_num_cache(struct aml_v4l2_ge2d *ge2d)
+{
+ atomic_set(&ge2d->ctx->ge2d_cache_num,
+ GE2D_FRAME_SIZE - kfifo_len(&ge2d->input));
+}
+
static int v4l_ge2d_empty_input_done(struct aml_v4l2_ge2d_buf *buf)
{
struct aml_v4l2_ge2d *ge2d = buf->caller_data;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
bool eos = false;
if (!ge2d || !ge2d->ctx) {
@@ -202,12 +209,19 @@
return -1;
}
- fb = &buf->aml_buf->frame_buffer;
+ if (ge2d->ctx->is_stream_off) {
+ v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "ge2d discard recycle frame %s %d ge2d:%p\n",
+ __func__, __LINE__, ge2d);
+ return -1;
+ }
+
+ aml_buf = buf->aml_vb->aml_buf;
eos = (buf->flag & GE2D_FLAG_EOS);
v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
"ge2d_input done: vf:%px, idx: %d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
+ "in:%d, out:%d, vf:%d, in done:%d, out done:%d, ge2d_cache_num:%d\n",
buf->vf,
buf->vf->index,
buf->vf->flag,
@@ -218,13 +232,16 @@
kfifo_len(&ge2d->output),
kfifo_len(&ge2d->frame),
kfifo_len(&ge2d->in_done_q),
- kfifo_len(&ge2d->out_done_q));
+ kfifo_len(&ge2d->out_done_q),
+ atomic_read(&ge2d->ctx->ge2d_cache_num));
- fb->task->recycle(fb->task, TASK_TYPE_GE2D);
+ aml_buf_fill(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D);
kfifo_put(&ge2d->input, buf);
+ update_ge2d_num_cache(ge2d);
- ATRACE_COUNTER("VC_IN_GE2D-1.recycle", fb->buf_idx);
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_6, atomic_read(&ge2d->ctx->ge2d_cache_num));
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_1, aml_buf->index);
return 0;
}
@@ -232,7 +249,7 @@
static int v4l_ge2d_fill_output_done(struct aml_v4l2_ge2d_buf *buf)
{
struct aml_v4l2_ge2d *ge2d = buf->caller_data;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
bool bypass = false;
bool eos = false;
@@ -243,15 +260,30 @@
return -1;
}
- fb = &buf->aml_buf->frame_buffer;
+ if (ge2d->ctx->is_stream_off) {
+ v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "ge2d discard submit frame %s %d ge2d:%p\n",
+ __func__, __LINE__, ge2d);
+ return -1;
+ }
+
+ aml_buf = buf->aml_vb->aml_buf;
eos = (buf->flag & GE2D_FLAG_EOS);
bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
- /* recovery fb handle. */
- buf->vf->v4l_mem_handle = (ulong)fb;
+ /* recovery aml_buf handle. */
+ buf->vf->v4l_mem_handle = (ulong)aml_buf;
kfifo_put(&ge2d->out_done_q, buf);
+ if (aml_buf->ge2d_buf == NULL) {
+ aml_buf->ge2d_buf = vzalloc(sizeof(struct aml_v4l2_ge2d_buf));
+ }
+
+ if (aml_buf->ge2d_buf)
+ memcpy((struct aml_v4l2_ge2d_buf *)(aml_buf->ge2d_buf), buf,
+ sizeof(struct aml_v4l2_ge2d_buf));
+
v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
"ge2d_output done: vf:%px, idx:%d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
"in:%d, out:%d, vf:%d, in done:%d, out done:%d, wxh:%ux%u\n",
@@ -268,20 +300,20 @@
kfifo_len(&ge2d->out_done_q),
buf->vf->width, buf->vf->height);
- ATRACE_COUNTER("VC_OUT_GE2D-2.submit", fb->buf_idx);
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_4, aml_buf->index);
- fb->task->submit(fb->task, TASK_TYPE_GE2D);
+ aml_buf_done(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D);
ge2d->out_num[OUTPUT_PORT]++;
return 0;
}
-static void ge2d_vf_get(void *caller, struct vframe_s **vf_out)
+static void ge2d_vf_get(void *caller, struct vframe_s *vf_out)
{
struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
struct aml_v4l2_ge2d_buf *buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
struct vframe_s *vf = NULL;
bool bypass = false;
bool eos = false;
@@ -294,7 +326,7 @@
}
if (kfifo_get(&ge2d->out_done_q, &buf)) {
- fb = &buf->aml_buf->frame_buffer;
+ aml_buf = buf->aml_vb->aml_buf;
eos = (buf->flag & GE2D_FLAG_EOS);
bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
vf = buf->vf;
@@ -307,9 +339,36 @@
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
}
- *vf_out = vf;
+ if (ge2d->ctx->enable_di_post) {
+ if (is_cpu_t7()) {
+ if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
+ if ((ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
+ (ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
+ (ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
+ (ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
+ (ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ }
+ else {
+ if (aml_buf->state == FB_ST_GE2D)
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ }
+ }
+ } else {
+ if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ }
+ }
- ATRACE_COUNTER("VC_OUT_GE2D-3.vf_get", fb->buf_idx);
+ memcpy(vf_out, vf, sizeof(struct vframe_s));
+
+ mutex_lock(&ge2d->output_lock);
+ kfifo_put(&ge2d->frame, vf);
+ kfifo_put(&ge2d->output, buf);
+ mutex_unlock(&ge2d->output_lock);
+ up(&ge2d->sem_out);
+
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_5, aml_buf->index);
v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
"%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld, type:%x, wxh:%ux%u\n",
@@ -323,34 +382,7 @@
static void ge2d_vf_put(void *caller, struct vframe_s *vf)
{
- struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- struct aml_v4l2_ge2d_buf *buf = NULL;
- bool bypass = false;
- bool eos = false;
- fb = (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
- aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- buf = (struct aml_v4l2_ge2d_buf *) aml_buf->ge2d_buf_handle;
- eos = (buf->flag & GE2D_FLAG_EOS);
- bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld\n",
- __func__, vf,
- vf->index,
- vf->flag,
- buf->flag,
- vf->timestamp);
-
- ATRACE_COUNTER("VC_IN_GE2D-0.vf_put", fb->buf_idx);
-
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->frame, vf);
- kfifo_put(&ge2d->output, buf);
- mutex_unlock(&ge2d->output_lock);
- up(&ge2d->sem_out);
}
static int aml_v4l2_ge2d_thread(void* param)
@@ -367,7 +399,7 @@
struct aml_v4l2_ge2d_buf *in_buf;
struct aml_v4l2_ge2d_buf *out_buf = NULL;
struct vframe_s *vf_out = NULL;
- struct vdec_v4l2_buffer *fb;
+ struct aml_buf *aml_buf;
if (down_interruptible(&ge2d->sem_in))
goto exit;
@@ -389,37 +421,28 @@
}
mutex_unlock(&ge2d->output_lock);
- /* bind v4l2 buffers */
- if (!out_buf->aml_buf) {
- struct vdec_v4l2_buffer *out;
-
- if (!ctx->fb_ops.query(&ctx->fb_ops, &ge2d->fb_token)) {
- usleep_range(500, 550);
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->output, out_buf);
- mutex_unlock(&ge2d->output_lock);
- goto retry;
- }
-
- if (ctx->fb_ops.alloc(&ctx->fb_ops, ge2d->fb_token, &out, AML_FB_REQ_GE2D)) {
- usleep_range(5000, 5500);
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->output, out_buf);
- mutex_unlock(&ge2d->output_lock);
- goto retry;
- }
-
- out_buf->aml_buf = container_of(out,
- struct aml_video_dec_buf, frame_buffer);
- out_buf->aml_buf->ge2d_buf_handle = (ulong) out_buf;
- v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d bind buf:%d to ge2d_buf:%px\n",
- GE2D_BUF_GET_IDX(out_buf), out_buf);
-
- out->m.mem[0].bytes_used = out->m.mem[0].size;
- out->m.mem[1].bytes_used = out->m.mem[1].size;
+ aml_buf = aml_buf_get(&ctx->bm, BUF_USER_GE2D, false);
+ if (!aml_buf) {
+ usleep_range(5000, 5500);
+ mutex_lock(&ge2d->output_lock);
+ kfifo_put(&ge2d->output, out_buf);
+ mutex_unlock(&ge2d->output_lock);
+ goto retry;
}
+ out_buf->aml_vb =
+ container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
+ #if 0
+ memcpy(&out_buf->aml_vb->ge2d_buf, out_buf,
+ sizeof(struct aml_v4l2_ge2d_buf));
+ #endif
+ v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
+ "ge2d bind buf:%d to ge2d_buf:%px\n",
+ GE2D_BUF_GET_IDX(out_buf), out_buf);
+
+ aml_buf->planes[0].bytes_used = aml_buf->planes[0].length;
+ aml_buf->planes[1].bytes_used = aml_buf->planes[1].length;
+
/* safe to pop in_buf */
if (!kfifo_get(&ge2d->in_done_q, &in_buf)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -436,8 +459,8 @@
}
mutex_unlock(&ge2d->output_lock);
- fb = &out_buf->aml_buf->frame_buffer;
- fb->status = FB_ST_GE2D;
+ aml_buf->state = FB_ST_GE2D;
+
/* fill output vframe information. */
memcpy(vf_out, in_buf->vf, sizeof(*vf_out));
@@ -445,18 +468,18 @@
in_buf->vf->canvas0_config,
2 * sizeof(struct canvas_config_s));
- vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1) {
+ vf_out->canvas0_config[0].phy_addr = aml_buf->planes[0].addr;
+ if (aml_buf->num_planes == 1) {
vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset;
+ aml_buf->planes[0].addr + aml_buf->planes[0].offset;
vf_out->canvas0_config[2].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset
- + (fb->m.mem[0].offset >> 2);
+ aml_buf->planes[0].addr + aml_buf->planes[0].offset
+ + (aml_buf->planes[0].offset >> 2);
} else {
vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[1].addr;
+ aml_buf->planes[1].addr;
vf_out->canvas0_config[2].phy_addr =
- fb->m.mem[2].addr;
+ aml_buf->planes[2].addr;
}
/* fill outbuf parms. */
@@ -470,10 +493,19 @@
memset(&ge2d_config, 0, sizeof(ge2d_config));
src_fmt = get_input_format(in_buf->vf);
+
if (in_buf->vf->canvas0_config[0].endian == 7)
- src_fmt |= GE2D_BIG_ENDIAN;
+ src_fmt |= (is_cpu_t7c() ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X)) ?
+ GE2D_LITTLE_ENDIAN : GE2D_BIG_ENDIAN;
else
- src_fmt |= GE2D_LITTLE_ENDIAN;
+ src_fmt |= (is_cpu_t7c() ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X)) ?
+ GE2D_BIG_ENDIAN : GE2D_LITTLE_ENDIAN;
/* negotiate format of destination */
dst_fmt = get_input_format(in_buf->vf);
@@ -504,17 +536,20 @@
vf_out->canvas0_config[2].endian = 7;
}
+ vf_out->mem_sec = ctx->is_drm_mode ? 1 : 0;
start_time = local_clock();
+
+ mutex_lock(&ctx->dev->cache.lock);
/* src canvas configure. */
if ((in_buf->vf->canvas0Addr == 0) ||
(in_buf->vf->canvas0Addr == (u32)-1)) {
- canvas_config_config(ge2d->src_canvas_id[0], &in_buf->vf->canvas0_config[0]);
- canvas_config_config(ge2d->src_canvas_id[1], &in_buf->vf->canvas0_config[1]);
- canvas_config_config(ge2d->src_canvas_id[2], &in_buf->vf->canvas0_config[2]);
+ canvas_config_config(ctx->dev->cache.res[0].cid, &in_buf->vf->canvas0_config[0]);
+ canvas_config_config(ctx->dev->cache.res[1].cid, &in_buf->vf->canvas0_config[1]);
+ canvas_config_config(ctx->dev->cache.res[2].cid, &in_buf->vf->canvas0_config[2]);
ge2d_config.src_para.canvas_index =
- ge2d->src_canvas_id[0] |
- ge2d->src_canvas_id[1] << 8 |
- ge2d->src_canvas_id[2] << 16;
+ ctx->dev->cache.res[0].cid |
+ ctx->dev->cache.res[1].cid << 8 |
+ ctx->dev->cache.res[2].cid << 16;
ge2d_config.src_planes[0].addr =
in_buf->vf->canvas0_config[0].phy_addr;
@@ -553,20 +588,20 @@
ge2d_config.src_para.height = in_buf->vf->height;
/* dst canvas configure. */
- canvas_config_config(ge2d->dst_canvas_id[0], &vf_out->canvas0_config[0]);
+ canvas_config_config(ctx->dev->cache.res[3].cid, &vf_out->canvas0_config[0]);
if ((ge2d_config.src_para.format & 0xfffff) == GE2D_FORMAT_M24_YUV420) {
vf_out->canvas0_config[1].width <<= 1;
}
- canvas_config_config(ge2d->dst_canvas_id[1], &vf_out->canvas0_config[1]);
- canvas_config_config(ge2d->dst_canvas_id[2], &vf_out->canvas0_config[2]);
+ canvas_config_config(ctx->dev->cache.res[4].cid, &vf_out->canvas0_config[1]);
+ canvas_config_config(ctx->dev->cache.res[5].cid, &vf_out->canvas0_config[2]);
ge2d_config.dst_para.canvas_index =
- ge2d->dst_canvas_id[0] |
- ge2d->dst_canvas_id[1] << 8;
- canvas_read(ge2d->dst_canvas_id[0], &cd);
+ ctx->dev->cache.res[3].cid |
+ ctx->dev->cache.res[4].cid << 8;
+ canvas_read(ctx->dev->cache.res[3].cid, &cd);
ge2d_config.dst_planes[0].addr = cd.addr;
ge2d_config.dst_planes[0].w = cd.width;
ge2d_config.dst_planes[0].h = cd.height;
- canvas_read(ge2d->dst_canvas_id[1], &cd);
+ canvas_read(ctx->dev->cache.res[4].cid, &cd);
ge2d_config.dst_planes[1].addr = cd.addr;
ge2d_config.dst_planes[1].w = cd.width;
ge2d_config.dst_planes[1].h = cd.height;
@@ -592,9 +627,10 @@
ge2d_config.src1_gb_alpha = 0;
ge2d_config.dst_xy_swap = 0;
ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
+ ge2d_config.mem_sec = ctx->is_drm_mode ? 1 : 0;
- ATRACE_COUNTER("VC_OUT_GE2D-1.handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_3,
+ in_buf->aml_vb->aml_buf->index);
v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
"ge2d_handle start: dec vf:%px/%d, ge2d vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, vf:%ux%u, fmt(src:%x, dst:%x), "
@@ -620,6 +656,7 @@
if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"ge2d_context_config_ex error.\n");
+ mutex_unlock(&ctx->dev->cache.lock);
goto exit;
}
@@ -634,6 +671,7 @@
0, 0, in_buf->vf->width, in_buf->vf->height);
}
}
+ mutex_unlock(&ctx->dev->cache.lock);
//pr_info("consume time %d us\n", div64_u64(local_clock() - start_time, 1000));
@@ -658,6 +696,19 @@
return 4;
}
+void static inline aml_v4l2_ge2d_set_workmode(struct aml_vcodec_ctx *ctx,
+ struct aml_ge2d_cfg_infos *cfg)
+{
+ if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
+ (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
+ cfg->mode |= GE2D_MODE_CONVERT_NV12;
+ else if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
+ (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
+ cfg->mode |= GE2D_MODE_CONVERT_NV21;
+ else
+ cfg->mode |= GE2D_MODE_CONVERT_NV21;
+}
+
int aml_v4l2_ge2d_init(
struct aml_vcodec_ctx *ctx,
struct aml_ge2d_cfg_infos *cfg,
@@ -665,7 +716,6 @@
{
struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
struct aml_v4l2_ge2d *ge2d;
- u32 work_mode = cfg->mode;
u32 buf_size;
int i, ret;
@@ -676,7 +726,8 @@
if (!ge2d)
return -ENOMEM;
- ge2d->work_mode = work_mode;
+ aml_v4l2_ge2d_set_workmode(ctx, cfg);
+ ge2d->work_mode = cfg->mode;
/* default convert little endian. */
if (!ge2d->work_mode) {
@@ -760,26 +811,15 @@
kfifo_put(&ge2d->frame, &ge2d->vfpool[i]);
}
- ge2d->src_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->src_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->src_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- if ((ge2d->src_canvas_id[0] <= 0) ||
- (ge2d->src_canvas_id[1] <= 0) ||
- (ge2d->src_canvas_id[2] <= 0) ||
- (ge2d->dst_canvas_id[0] <= 0) ||
- (ge2d->dst_canvas_id[1] <= 0) ||
- (ge2d->dst_canvas_id[2] <= 0)) {
+ if (aml_canvas_cache_get(ctx->dev, "v4ldec-ge2d") < 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"canvas pool alloc fail. src(%d, %d, %d) dst(%d, %d, %d).\n",
- ge2d->src_canvas_id[0],
- ge2d->src_canvas_id[1],
- ge2d->src_canvas_id[2],
- ge2d->dst_canvas_id[0],
- ge2d->dst_canvas_id[1],
- ge2d->dst_canvas_id[2]);
+ ctx->dev->cache.res[0].cid,
+ ctx->dev->cache.res[1].cid,
+ ctx->dev->cache.res[2].cid,
+ ctx->dev->cache.res[3].cid,
+ ctx->dev->cache.res[4].cid,
+ ctx->dev->cache.res[5].cid);
goto error8;
}
@@ -798,7 +838,7 @@
*ge2d_handle = ge2d;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"GE2D_CFG bsize:%d, wkm:%x, bm:%x, drm:%d\n",
ge2d->buf_size,
ge2d->work_mode,
@@ -808,18 +848,7 @@
return 0;
error9:
- if (ge2d->src_canvas_id[0] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
- if (ge2d->src_canvas_id[1] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
- if (ge2d->src_canvas_id[2] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
- if (ge2d->dst_canvas_id[0] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
- if (ge2d->dst_canvas_id[1] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
- if (ge2d->dst_canvas_id[2] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
+ aml_canvas_cache_put(ctx->dev);
error8:
vfree(ge2d->ivbpool);
error7:
@@ -846,11 +875,12 @@
v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
"ge2d destroy begin\n");
- ge2d->running = false;
- up(&ge2d->sem_in);
- up(&ge2d->sem_out);
- kthread_stop(ge2d->task);
-
+ if (ge2d->running) {
+ ge2d->running = false;
+ up(&ge2d->sem_in);
+ up(&ge2d->sem_out);
+ kthread_stop(ge2d->task);
+ }
destroy_ge2d_work_queue(ge2d->ge2d_context);
/* no more ge2d callback below this line */
@@ -862,12 +892,7 @@
vfree(ge2d->ivbpool);
mutex_destroy(&ge2d->output_lock);
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
+ aml_canvas_cache_put(ge2d->ctx->dev);
v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
"ge2d destroy done\n");
@@ -878,10 +903,28 @@
}
EXPORT_SYMBOL(aml_v4l2_ge2d_destroy);
+int aml_v4l2_ge2d_thread_stop(struct aml_v4l2_ge2d* ge2d)
+{
+ v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
+ "ge2d thread stop begin\n");
+
+ if (ge2d->running) {
+ ge2d->running = false;
+ up(&ge2d->sem_in);
+ up(&ge2d->sem_out);
+ kthread_stop(ge2d->task);
+ }
+ v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
+ "ge2d thread stop done\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(aml_v4l2_ge2d_thread_stop);
+
static int aml_v4l2_ge2d_push_vframe(struct aml_v4l2_ge2d* ge2d, struct vframe_s *vf)
{
struct aml_v4l2_ge2d_buf* in_buf;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
if (!ge2d)
return -EINVAL;
@@ -899,13 +942,14 @@
"ge2d_push_vframe: vf:%px, idx:%d, type:%x, ts:%lld\n",
vf, vf->index, vf->type, vf->timestamp);
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+ aml_buf = (struct aml_buf *)vf->v4l_mem_handle;
+ in_buf->aml_vb = container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
in_buf->vf = vf;
do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ unsigned int dw_mode = DM_YUV_ONLY;
struct file *fp;
+ char file_name[64] = {0};
if (!dump_ge2d_input || ge2d->ctx->is_drm_mode)
break;
@@ -913,26 +957,44 @@
if (vdec_if_get_param(ge2d->ctx, GET_PARAM_DW_MODE, &dw_mode))
break;
- if (dw_mode == VDEC_DW_AFBC_ONLY)
+ if (dw_mode == DM_AVBC_ONLY)
break;
- fp = filp_open("/data/dec_dump_before.raw",
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+ snprintf(file_name, 64, "%s/dec_dump_ge2d_input_%ux%u.raw", dump_path, vf->width, vf->height);
+ fp = media_open(file_name, O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
if (!IS_ERR(fp)) {
- struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
+ struct vb2_buffer *vb = &in_buf->aml_vb->vb.vb2_buf;
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
- if (in_buf->aml_buf->frame_buffer.num_planes == 2)
- kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
+ // dump y data
+ u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+ vf->width, vf->height, 64);
+
+ // dump uv data
+ if (vb->num_planes == 1) {
+ aml_yuv_dump(fp, yuv_data_addr, vf->width,
+ vf->height / 2, 64);
+ } else {
+ aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+ vf->width, vf->height / 2, 64);
+ }
+
+ pr_info("dump idx: %d %dx%d num_planes %d\n",
+ dump_ge2d_input,
+ vf->width,
+ vf->height,
+ vb->num_planes);
+
dump_ge2d_input--;
- filp_close(fp, NULL);
+ media_close(fp, NULL);
}
} while(0);
- ATRACE_COUNTER("VC_OUT_GE2D-0.receive", fb->buf_idx);
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_2, aml_buf->index);
kfifo_put(&ge2d->in_done_q, in_buf);
+ update_ge2d_num_cache(ge2d);
+ vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_6, atomic_read(&ge2d->ctx->ge2d_cache_num));
+ aml_buf_update_holder(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D, BUF_GET);
up(&ge2d->sem_in);
return 0;
@@ -942,11 +1004,11 @@
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
+ struct aml_buf *aml_buf =
+ (struct aml_buf *)fb_ctx;
int ret = -1;
- ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, fb->vframe);
+ ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, &aml_buf->vframe);
if (ret < 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"ge2d push vframe err, ret: %d\n", ret);
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.h b/drivers/amvdec_ports/aml_vcodec_ge2d.h
index a12931d..e495945 100644
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.h
+++ b/drivers/amvdec_ports/aml_vcodec_ge2d.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _AML_VCODEC_GE2D_H_
#define _AML_VCODEC_GE2D_H_
@@ -38,7 +38,7 @@
u32 flag;
struct vframe_s *vf;
void *caller_data;
- struct aml_video_dec_buf *aml_buf;
+ struct aml_v4l2_buf *aml_vb;
};
struct aml_v4l2_ge2d {
@@ -72,9 +72,6 @@
int in_num[2];
int out_num[2];
ulong fb_token;
-
- int src_canvas_id[3];
- int dst_canvas_id[3];
};
struct task_ops_s *get_ge2d_ops(void);
@@ -85,5 +82,7 @@
struct aml_v4l2_ge2d** ge2d_handle);
int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d);
+int aml_v4l2_ge2d_thread_stop(struct aml_v4l2_ge2d* ge2d);
+
#endif
diff --git a/drivers/amvdec_ports/aml_vcodec_ts.c b/drivers/amvdec_ports/aml_vcodec_ts.c
new file mode 100644
index 0000000..3a9abe0
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_ts.c
@@ -0,0 +1,123 @@
+/*
+* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+
+#include "aml_vcodec_drv.h"
+
+#include <linux/sched/clock.h>
+#include "aml_vcodec_ts.h"
+
+int aml_vcodec_pts_checkout(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts)
+{
+ checkout_pts_offset mCheckOutPtsOffset = {0};
+ int ret;
+
+ mCheckOutPtsOffset.offset = offset;
+ ret = ptsserver_checkout_pts_offset(ptsserver_id,&mCheckOutPtsOffset);
+ if (ret) {
+ pr_err("aml_vcodec_pts_checkout ret = %d\n", ret);
+ return ret;
+ }
+
+ *pts = mCheckOutPtsOffset;
+
+ pr_debug("%s duration: %lld offset: 0x%llx pts: 0x%x pts64: %llu\n",
+ __func__, (offset >> 32) & 0xffffffff,
+ offset & 0xffffffff, pts->pts, pts->pts_64);
+
+ return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_pts_checkout);
+
+int aml_vcodec_pts_offset(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts)
+{
+ checkout_pts_offset mCheckOutPtsOffset = {0};
+ int ret;
+ mCheckOutPtsOffset.offset = offset;
+
+ ret = ptsserver_peek_pts_offset(ptsserver_id, &mCheckOutPtsOffset);
+ if (ret) {
+ pr_err("aml_vcodec_pts_offset ret = %d\n", ret);
+ return ret;
+ }
+
+ *pts = mCheckOutPtsOffset;
+
+ pr_debug("%s duration: %lld offset: 0x%llx pts: 0x%x pts64: %llu\n",
+ __func__, (offset >> 32) & 0xffffffff,
+ offset & 0xffffffff, pts->pts, pts->pts_64);
+
+ return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_pts_offset);
+
+int aml_vcodec_pts_checkin(s32 ptsserver_id, u32 pkt_size, u64 pts_val)
+{
+ checkin_pts_size mCheckinPtsSize;
+
+ mCheckinPtsSize.size =pkt_size;
+ mCheckinPtsSize.pts = (u32)div64_u64(pts_val * 9, 100);
+ mCheckinPtsSize.pts_64 = pts_val;
+ ptsserver_checkin_pts_size(ptsserver_id,&mCheckinPtsSize);
+
+ pr_debug("%s pkt_size:%d chekin pts: %d, pts64: %llu\n",
+ __func__, pkt_size, mCheckinPtsSize.pts, pts_val);
+
+ return 0;
+}
+
+int aml_vcodec_pts_first_checkin(u32 format, s32 ptsserver_id, u32 wp, u32 buf_start)
+{
+ uint32_t mBaseffset = 0;
+ uint32_t mAlignmentOffset = 0;
+ start_offset mSartOffset;
+
+ if ((format == V4L2_PIX_FMT_HEVC) || (format == V4L2_PIX_FMT_VP9) || (format == V4L2_PIX_FMT_AV1)) {
+ mAlignmentOffset = wp % 0x80;
+ mBaseffset = 0;
+ } else {
+ mBaseffset = wp - buf_start;
+ }
+
+ mSartOffset.mBaseOffset = mBaseffset;
+ mSartOffset.mAlignmentOffset = mAlignmentOffset;
+ ptsserver_set_first_checkin_offset(ptsserver_id,&mSartOffset);
+
+ pr_debug("%s format:%d mBaseffset: 0x%d mAlignmentOffset: %d\n",
+ __func__, format, mBaseffset, mAlignmentOffset);
+
+ return 0;
+}
+
+static struct pts_server_ops pts_server_ops = {
+ .checkout = aml_vcodec_pts_checkout,
+ .cal_offset = aml_vcodec_pts_offset,
+ .checkin = aml_vcodec_pts_checkin,
+ .first_checkin = aml_vcodec_pts_first_checkin,
+};
+
+struct pts_server_ops *get_pts_server_ops(void)
+{
+ return &pts_server_ops;
+}
+EXPORT_SYMBOL(get_pts_server_ops);
diff --git a/drivers/amvdec_ports/aml_vcodec_ts.h b/drivers/amvdec_ports/aml_vcodec_ts.h
new file mode 100644
index 0000000..26924b3
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_ts.h
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef _AML_VCODEC_TS_H_
+#define _AML_VCODEC_TS_H_
+
+#include "../media_sync/pts_server/pts_server_core.h"
+
+int aml_vcodec_pts_checkout(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+int aml_vcodec_pts_offset(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+int aml_vcodec_pts_checkin(s32 ptsserver_id, u32 pkt_size, u64 pts_val);
+int aml_vcodec_pts_first_checkin(u32 format, s32 ptsserver_id, u32 wp, u32 buf_start);
+
+struct pts_server_ops {
+ int (*checkout) (s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+ int (*cal_offset) (s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+ int (*checkin) (s32 ptsserver_id, u32 pkt_size, u64 pts_val);
+ int (*first_checkin) (u32 format, s32 ptsserver_id, u32 wp, u32 buf_start);
+};
+struct pts_server_ops *get_pts_server_ops(void);
+
+#endif
+
diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c
index 54b0d06..ad90fd1 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.c
+++ b/drivers/amvdec_ports/aml_vcodec_util.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include "aml_vcodec_drv.h"
@@ -44,3 +44,54 @@
return ctx;
}
EXPORT_SYMBOL(aml_vcodec_get_curr_ctx);
+
+int user_to_task(enum buf_core_user user)
+{
+ enum task_type_e t;
+
+ switch (user) {
+ case BUF_USER_DEC:
+ t = TASK_TYPE_DEC;
+ break;
+ case BUF_USER_VPP:
+ t = TASK_TYPE_VPP;
+ break;
+ case BUF_USER_GE2D:
+ t = TASK_TYPE_GE2D;
+ break;
+ case BUF_USER_VSINK:
+ t = TASK_TYPE_V4L_SINK;
+ break;
+ default:
+ t = TASK_TYPE_MAX;
+ }
+
+ return t;
+}
+EXPORT_SYMBOL(user_to_task);
+
+int task_to_user(enum task_type_e task)
+{
+ enum buf_core_user t;
+
+ switch (task) {
+ case TASK_TYPE_DEC:
+ t = BUF_USER_DEC;
+ break;
+ case TASK_TYPE_VPP:
+ t = BUF_USER_VPP;
+ break;
+ case TASK_TYPE_GE2D:
+ t = BUF_USER_GE2D;
+ break;
+ case TASK_TYPE_V4L_SINK:
+ t = BUF_USER_VSINK;
+ break;
+ default:
+ t = BUF_USER_MAX;
+ }
+
+ return t;
+}
+EXPORT_SYMBOL(task_to_user);
+
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h
index 96c5453..cc4286f 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.h
+++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -1,28 +1,37 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _AML_VCODEC_UTIL_H_
#define _AML_VCODEC_UTIL_H_
#include <linux/types.h>
-#include <linux/dma-direction.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
+#ifdef __KERNEL__
+#include <uapi/linux/videodev2.h>
+#else
+#include <uapi/linux/time.h>
+#endif
+#include <linux/version.h>
+
+#include "aml_buf_core.h"
+#include "aml_task_chain.h"
+
/*
typedef unsigned long long u64;
typedef signed long long s64;
@@ -54,7 +63,8 @@
struct aml_vcodec_dev;
extern u32 debug_mode;
-extern u32 mandatory_dw_mmu;
+extern u32 disable_vpp_dw_mmu;
+extern int t3x_tw_output;
#ifdef v4l_dbg
#undef v4l_dbg
@@ -99,8 +109,42 @@
} \
} while (0)
+#define v4l_dbg_ext(id, flags, fmt, args...) \
+ do { \
+ if ((flags == V4L_DEBUG_CODEC_ERROR) || \
+ (flags == V4L_DEBUG_CODEC_PRINFO) || \
+ (debug_mode & flags)) { \
+ if (flags == V4L_DEBUG_CODEC_ERROR) { \
+ __v4l_dbg(1, id, "[ERR]: " fmt, ##args); \
+ } else { \
+ __v4l_dbg(1, id, fmt, ##args); \
+ } \
+ } \
+ } while (0)
+
void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev,
struct aml_vcodec_ctx *ctx);
struct aml_vcodec_ctx *aml_vcodec_get_curr_ctx(struct aml_vcodec_dev *dev);
+/*
+ * todo
+ */
+int user_to_task(enum buf_core_user user);
+
+/*
+ * todo
+ */
+int task_to_user(enum task_type_e task);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 0)
+#ifdef __KERNEL__
+static inline __u64 timeval_to_ns(const struct __kernel_v4l2_timeval *tv)
+#else
+static inline __u64 timeval_to_ns(const struct timeval *tv)
+#endif
+{
+ return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
+}
+#endif
+
#endif /* _AML_VCODEC_UTIL_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.c b/drivers/amvdec_ports/aml_vcodec_vpp.c
index 5a86c1f..716928d 100644
--- a/drivers/amvdec_ports/aml_vcodec_vpp.c
+++ b/drivers/amvdec_ports/aml_vcodec_vpp.c
@@ -1,23 +1,22 @@
/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
@@ -28,18 +27,27 @@
#include "aml_vcodec_adapt.h"
#include "vdec_drv_if.h"
#include "../common/chips/decoder_cpu_ver_info.h"
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
+#include "utils/common.h"
+#include "../common/media_utils/media_utils.h"
#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
#include <trace/events/meson_atrace.h>
-#define VPP_BUF_GET_IDX(vpp_buf) (vpp_buf->aml_buf->vb.vb2_buf.index)
+#define VPP_BUF_GET_IDX(vpp_buf) (vpp_buf->aml_vb->vb.vb2_buf.index)
#define INPUT_PORT 0
#define OUTPUT_PORT 1
extern int dump_vpp_input;
extern int vpp_bypass_frames;
+extern char dump_path[32];
-static void di_release_keep_buf_wrap(void *arg)
+struct di_buffer_wrap {
+ struct vframe_s vf_cp;
+ struct di_buffer *buf;
+};
+
+static void di_release_keep_buf_wrap1(void *arg)
{
struct di_buffer *buf = (struct di_buffer *)arg;
@@ -50,6 +58,40 @@
di_release_keep_buf(buf);
+ ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_release", buf->mng.index);
+}
+
+static void di_release_keep_buf_wrap2(void *arg)
+{
+ struct di_buffer_wrap *buf_wrap = (struct di_buffer_wrap *)arg;
+ struct di_buffer *buf = NULL;
+ struct vframe_s *vf_cp = NULL;
+ s32 cur_di_ins_id = -1, last_di_ins_id = -1;
+
+ if (buf_wrap) {
+ buf = buf_wrap->buf;
+ vf_cp = &buf_wrap->vf_cp;
+ if (buf && buf->vf)
+ cur_di_ins_id = buf->vf->di_instance_id;
+ last_di_ins_id = vf_cp->di_instance_id;
+ }
+
+ v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,
+ "%s release di local buffer %px, vf:%px, cur_id: %d vf_cp:%px, vf-ext:%px, vf_cp-ext:%px, last_id: %d comm:%s, pid:%d,buf->flag=%d\n",
+ __func__ , buf, buf->vf, cur_di_ins_id, vf_cp, buf->vf ? buf->vf->vf_ext : NULL, vf_cp->vf_ext, last_di_ins_id,
+ current->comm, current->pid, buf->flag);
+
+ /* just release di bufffer when same id or interlace video or post write mode */
+ if ((cur_di_ins_id == last_di_ins_id && cur_di_ins_id > 0) ||
+ (buf->flag & DI_FLAG_I) ||
+ !(vf_cp->di_flag & DI_FLAG_DI_PVPPLINK))
+ di_release_keep_buf(buf);
+ else
+ v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,"%s release warning\n",__func__);
+
+ if (buf_wrap)
+ vfree(buf_wrap);
+
ATRACE_COUNTER("VC_OUT_VPP_LC-2.lc_release", buf->mng.index);
}
@@ -57,15 +99,16 @@
{
struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
struct dma_buf *dma = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
+ struct aml_v4l2_buf *aml_vb = NULL;
struct uvm_hook_mod_info u_info;
+ struct di_buffer_wrap *buf_wrap = NULL;
int ret;
- aml_buf = vpp_buf->aml_buf;
- if (!aml_buf)
+ aml_vb = vpp_buf->aml_vb;
+ if (!aml_vb)
return -EINVAL;
- dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
+ dma = aml_vb->vb.vb2_buf.planes[0].dbuf;
if (!dma || !dmabuf_is_uvm(dma)) {
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
"attach_DI_buffer err\n");
@@ -81,20 +124,33 @@
if (uvm_get_hook_mod(dma, VF_PROCESS_DI)) {
uvm_put_hook_mod(dma, VF_PROCESS_DI);
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "attach_DI_buffer exist hook\n");
+ "attach_DI_buffer exist hook, dbuf:%px\n", dma);
return -EINVAL;
}
- u_info.type = VF_PROCESS_DI;
- u_info.arg = (void *)vpp_buf->di_local_buf;
- u_info.free = di_release_keep_buf_wrap;
+ buf_wrap = vzalloc(sizeof(struct di_buffer_wrap));
+ if (buf_wrap) {
+ buf_wrap->buf = vpp_buf->di_local_buf;
+ u_info.type = VF_PROCESS_DI;
+ u_info.arg = (void *)buf_wrap;
+ u_info.free = di_release_keep_buf_wrap2;
- ret = uvm_attach_hook_mod(dma, &u_info);
- if (ret < 0) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "fail to set dmabuf DI hook\n");
+ ret = uvm_attach_hook_mod(dma, &u_info);
+ if (ret < 0) {
+ v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
+ "fail to set dmabuf DI hook\n");
+ vfree(buf_wrap);
+ } else if (vpp_buf->di_buf.vf->vf_ext) {
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+ "%s swap di_buf %px.vf->vf_ext:%px to buf_wrap->vf_cp:%px\n",
+ __func__, vpp_buf->di_buf.vf, vpp_buf->di_buf.vf->vf_ext, &buf_wrap->vf_cp);
+ memcpy(&buf_wrap->vf_cp,
+ vpp_buf->di_buf.vf->vf_ext,
+ sizeof(struct vframe_s));
+ vpp_buf->di_buf.vf->vf_ext = &buf_wrap->vf_cp;
+ }
}
- ATRACE_COUNTER("VC_OUT_VPP_LC-0.lc_attach", vpp_buf->di_local_buf->mng.index);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_12, vpp_buf->di_local_buf->mng.index);
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
"%s attach di local buffer %px, dbuf:%px\n",
@@ -107,15 +163,14 @@
{
struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
struct dma_buf *dma = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
+ struct aml_v4l2_buf *aml_vb = NULL;
int ret;
- aml_buf = vpp_buf->aml_buf;
- if (!aml_buf)
+ aml_vb = vpp_buf->aml_vb;
+ if (!aml_vb)
return -EINVAL;
-
- dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
- if (!dma || !dmabuf_is_uvm(dma)) {
+ dma = aml_vb->vb.vb2_buf.planes[0].dbuf;
+ if (IS_ERR_OR_NULL(dma) || !dmabuf_is_uvm(dma)) {
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
"detach_DI_buffer err\n");
return -EINVAL;
@@ -127,7 +182,7 @@
return 0;
}
- ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_detach", vpp_buf->di_local_buf->mng.index);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_13, vpp_buf->di_local_buf->mng.index);
ret = uvm_detach_hook_mod(dma, VF_PROCESS_DI);
if (ret < 0) {
@@ -156,6 +211,12 @@
}
}
+static void update_vpp_num_cache(struct aml_v4l2_vpp *vpp)
+{
+ if (!vpp->ctx->is_stream_off)
+ atomic_set(&vpp->ctx->vpp_cache_num, VPP_FRAME_SIZE - kfifo_len(&vpp->input));
+}
+
static int is_di_input_buff_full(struct aml_v4l2_vpp *vpp)
{
return ((vpp->in_num[INPUT_PORT] - vpp->in_num[OUTPUT_PORT])
@@ -173,14 +234,15 @@
{
struct aml_v4l2_vpp *vpp = buf->caller_data;
struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
bool bypass = false;
bool eos = false;
+ struct vframe_s *tmp;
if (!vpp || !vpp->ctx) {
pr_err("fatal %s %d vpp:%p\n",
__func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
+ di_release_keep_buf_wrap1(buf);
return DI_ERR_UNDEFINED;
}
@@ -188,7 +250,7 @@
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
"vpp discard submit frame %s %d vpp:%p\n",
__func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
+ di_release_keep_buf_wrap1(buf);
return DI_ERR_UNDEFINED;
}
@@ -196,11 +258,11 @@
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
"vpp doesn't get output %s %d vpp:%p\n",
__func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
+ di_release_keep_buf_wrap1(buf);
return DI_ERR_UNDEFINED;
}
- fb = &vpp_buf->aml_buf->frame_buffer;
+ aml_buf = vpp_buf->aml_vb->aml_buf;
eos = (buf->flag & DI_FLAG_EOS);
bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
@@ -208,7 +270,7 @@
vpp_buf->di_buf.private_data = buf->private_data;
vpp_buf->di_buf.vf->vf_ext = buf->vf;
vpp_buf->di_buf.flag = buf->flag;
- vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)fb;
+ vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)aml_buf;
if (!eos && !bypass) {
vpp_buf->di_local_buf = buf;
@@ -219,18 +281,34 @@
kfifo_put(&vpp->out_done_q, vpp_buf);
- if (vpp->is_prog)
+ if (vpp->is_prog) {
kfifo_put(&vpp->input, vpp_buf->inbuf);
+ update_vpp_num_cache(vpp);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+ }
+ if (aml_buf->vpp_buf == NULL) {
+ aml_buf->vpp_buf = vzalloc(sizeof(struct aml_v4l2_vpp_buf));
+ }
+
+ if (aml_buf->vpp_buf)
+ memcpy((struct aml_v4l2_vpp_buf *)(aml_buf->vpp_buf), vpp_buf,
+ sizeof(struct aml_v4l2_vpp_buf));
+
+ tmp = (struct vframe_s *)(buf->vf ? buf->vf->vf_ext : NULL);
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_output local done: idx:%d, vf:%px, ext vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
+ "vpp_output local done: idx:%d, vf:%px, afbc:0x%lx ext vf:%px, idx:%d, flag(vf:%x di:%x) (buf->vf:%px vf_ext:%px, afbc:0x%lx) %s %s, ts:%lld, "
"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
+ aml_buf->index,
vpp_buf->di_buf.vf,
+ vpp_buf->di_buf.vf->compHeadAddr,
vpp_buf->di_buf.vf->vf_ext,
vpp_buf->di_buf.vf->index,
vpp_buf->di_buf.vf->flag,
buf->flag,
+ buf->vf,
+ buf->vf ? buf->vf->vf_ext : NULL,
+ tmp ? tmp->compHeadAddr : 0,
vpp->is_prog ? "P" : "I",
eos ? "eos" : "",
vpp_buf->di_buf.vf->timestamp,
@@ -240,9 +318,9 @@
kfifo_len(&vpp->in_done_q),
kfifo_len(&vpp->out_done_q));
- ATRACE_COUNTER("VC_OUT_VPP-2.lc_submit", fb->buf_idx);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_10, aml_buf->index);
- fb->task->submit(fb->task, TASK_TYPE_VPP);
+ aml_buf_done(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
vpp->out_num[OUTPUT_PORT]++;
vpp->in_num[OUTPUT_PORT]++;
@@ -255,7 +333,7 @@
{
struct aml_v4l2_vpp *vpp = buf->caller_data;
struct aml_v4l2_vpp_buf *vpp_buf;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
bool eos = false;
if (!vpp || !vpp->ctx) {
@@ -273,13 +351,13 @@
}
vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
- fb = &vpp_buf->aml_buf->frame_buffer;
+ aml_buf = vpp_buf->aml_vb->aml_buf;
eos = (buf->flag & DI_FLAG_EOS);
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
"vpp_input done: idx:%d, vf:%px, idx: %d, flag(vf:%x di:%x) %s %s, ts:%lld, "
"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
+ aml_buf->index,
buf->vf,
buf->vf->index,
buf->vf->flag,
@@ -295,15 +373,23 @@
if (!vpp->is_prog) {
/* recycle vf only in non-bypass mode */
- fb->task->recycle(fb->task, TASK_TYPE_VPP);
+ aml_buf_fill(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
kfifo_put(&vpp->input, vpp_buf);
+ update_vpp_num_cache(vpp);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+ }
+
+ if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+ kfifo_put(&vpp->input, vpp_buf);
+ update_vpp_num_cache(vpp);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
}
if (vpp->buffer_mode != BUFFER_MODE_ALLOC_BUF)
vpp->in_num[OUTPUT_PORT]++;
- ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_1, aml_buf->index);
return DI_ERR_NONE;
}
@@ -313,7 +399,7 @@
{
struct aml_v4l2_vpp *vpp = buf->caller_data;
struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
bool bypass = false;
bool eos = false;
@@ -332,19 +418,27 @@
}
vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
- fb = &vpp_buf->aml_buf->frame_buffer;
+ aml_buf = vpp_buf->aml_vb->aml_buf;
eos = (buf->flag & DI_FLAG_EOS);
bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
- /* recovery fb handle. */
- buf->vf->v4l_mem_handle = (ulong)fb;
+ /* recovery aml_buf handle. */
+ buf->vf->v4l_mem_handle = (ulong)aml_buf;
kfifo_put(&vpp->out_done_q, vpp_buf);
+ if (aml_buf->vpp_buf == NULL) {
+ aml_buf->vpp_buf = vzalloc(sizeof(struct aml_v4l2_vpp_buf));
+ }
+
+ if (aml_buf->vpp_buf)
+ memcpy((struct aml_v4l2_vpp_buf *)(aml_buf->vpp_buf), vpp_buf,
+ sizeof(struct aml_v4l2_vpp_buf));
+
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
"vpp_output done: idx:%d, vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
+ aml_buf->index,
buf->vf,
buf->vf->index,
buf->vf->flag,
@@ -358,9 +452,9 @@
kfifo_len(&vpp->in_done_q),
kfifo_len(&vpp->out_done_q));
- ATRACE_COUNTER("VC_OUT_VPP-2.submit", fb->buf_idx);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_9, aml_buf->index);
- fb->task->submit(fb->task, TASK_TYPE_VPP);
+ aml_buf_done(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
vpp->out_num[OUTPUT_PORT]++;
@@ -371,11 +465,109 @@
return DI_ERR_NONE;
}
-static void vpp_vf_get(void *caller, struct vframe_s **vf_out)
+static enum DI_ERRORTYPE
+ v4l_vpp_fill_output_done_dw_mmu(struct di_buffer *buf)
+{
+ struct aml_v4l2_vpp *vpp = buf->caller_data;
+ struct aml_v4l2_vpp_buf *vpp_buf = NULL;
+ struct aml_buf *fb = NULL;
+ bool bypass = false;
+ bool eos = false;
+
+ if (!vpp || !vpp->ctx) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "fatal %s %d vpp:%px\n",
+ __func__, __LINE__, vpp);
+ return DI_ERR_UNDEFINED;
+ }
+
+ if (vpp->ctx->is_stream_off) {
+ v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "vpp discard submit frame %s %d vpp:%p\n",
+ __func__, __LINE__, vpp);
+ return DI_ERR_UNDEFINED;
+ }
+
+ if (!kfifo_get(&vpp->processing, &vpp_buf)) {
+ v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "vpp doesn't get output %s %d vpp:%p\n",
+ __func__, __LINE__, vpp);
+ di_release_keep_buf_wrap1(buf);
+ return DI_ERR_UNDEFINED;
+ }
+
+ fb = vpp_buf->aml_vb->aml_buf;
+ eos = (buf->flag & DI_FLAG_EOS);
+ bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
+
+ vpp_buf->di_buf.flag |= buf->flag;
+ vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)fb;
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+ "%s dec_vf_type:0x%x di_out_vf_type:0x%x\n",
+ __func__, vpp_buf->di_buf.vf->type, buf->vf->type);
+
+ /*di pw*/
+ if (buf->vf->type & 0x40000000) {
+ vpp_buf->di_buf.vf->type |= (buf->vf->type & 0xfffffff);
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+ "di pw enable, vf_type:0x%x\n", vpp_buf->di_buf.vf->type);
+ }
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+ "%s dec_vf(w x h):(%d x %d) di_out_vf(w x h):(%d x %d)\n",
+ __func__, vpp_buf->di_buf.vf->width, vpp_buf->di_buf.vf->height,
+ buf->vf->width, buf->vf->height);
+
+ if (buf->vf->width != 0 &&
+ buf->vf->height != 0) {
+ vpp_buf->di_buf.vf->width = buf->vf->width;
+ vpp_buf->di_buf.vf->height = buf->vf->height;
+ }
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+ "vpp out buff canvas:phy:%lx/%lx %dx%d",
+ buf->vf->canvas0_config[0].phy_addr,
+ buf->vf->canvas0_config[1].phy_addr,
+ buf->vf->canvas0_config[0].width,
+ buf->vf->canvas0_config[0].height);
+
+ kfifo_put(&vpp->out_done_q, vpp_buf);
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+ "vpp_output_dw done: idx:%d, vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
+ "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
+ fb->index,
+ vpp_buf->di_buf.vf,
+ vpp_buf->di_buf.vf->index,
+ vpp_buf->di_buf.vf->flag,
+ vpp_buf->di_buf.flag,
+ vpp->is_prog ? "P" : "I",
+ eos ? "eos" : "",
+ vpp_buf->di_buf.vf->timestamp,
+ kfifo_len(&vpp->input),
+ kfifo_len(&vpp->output),
+ kfifo_len(&vpp->frame),
+ kfifo_len(&vpp->in_done_q),
+ kfifo_len(&vpp->out_done_q));
+
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_9, fb->index);
+
+ fb->task->submit(fb->task, TASK_TYPE_VPP);
+
+ vpp->out_num[OUTPUT_PORT]++;
+
+ vpp->in_num[OUTPUT_PORT]++;
+
+ return DI_ERR_NONE;
+}
+
+static void vpp_vf_get(void *caller, struct vframe_s *vf_out)
{
struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
struct di_buffer *buf = NULL;
struct vframe_s *vf = NULL;
bool bypass = false;
@@ -389,7 +581,7 @@
}
if (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
- fb = &vpp_buf->aml_buf->frame_buffer;
+ aml_buf = vpp_buf->aml_vb->aml_buf;
buf = &vpp_buf->di_buf;
eos = (buf->flag & DI_FLAG_EOS);
bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
@@ -409,9 +601,16 @@
}
}
- *vf_out = vf;
+ memcpy(vf_out, vf, sizeof(struct vframe_s));
- ATRACE_COUNTER("VC_OUT_VPP-3.vf_get", fb->buf_idx);
+ mutex_lock(&vpp->output_lock);
+ kfifo_put(&vpp->frame, vf);
+ kfifo_put(&vpp->output, vpp_buf);
+ mutex_unlock(&vpp->output_lock);
+
+ up(&vpp->sem_out);
+
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_11, aml_buf->index);
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
"%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
@@ -425,19 +624,19 @@
static void vpp_vf_put(void *caller, struct vframe_s *vf)
{
+ #if 0
struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
+ struct aml_buf *aml_buf = NULL;
+ struct aml_v4l2_buf *aml_vb = NULL;
struct aml_v4l2_vpp_buf *vpp_buf = NULL;
struct di_buffer *buf = NULL;
bool bypass = false;
bool eos = false;
- fb = (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
- aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+ aml_buf = (struct aml_buf *) vf->v4l_mem_handle;
+ aml_vb = container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
-
- vpp_buf = (struct aml_v4l2_vpp_buf *) aml_buf->vpp_buf_handle;
+ vpp_buf = (struct aml_v4l2_vpp_buf *) aml_vb->vpp_buf_handle;
buf = &vpp_buf->di_buf;
eos = (buf->flag & DI_FLAG_EOS);
bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
@@ -450,12 +649,7 @@
buf->flag,
vf->timestamp);
- ATRACE_COUNTER("VC_IN_VPP-0.vf_put", fb->buf_idx);
-
- if (vpp->is_prog) {
- ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
- fb->task->recycle(fb->task, TASK_TYPE_VPP);
- }
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_0, aml_buf->index);
if (!eos && !bypass) {
if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
@@ -463,24 +657,84 @@
}
}
- mutex_lock(&vpp->output_lock);
kfifo_put(&vpp->frame, vf);
- kfifo_put(&vpp->output, vpp_buf);
- mutex_unlock(&vpp->output_lock);
- up(&vpp->sem_out);
+ kfifo_put(&vpp->pre_output, vpp_buf);
+
+ queue_work(vpp->ctx->dev->decode_workqueue, &vpp->worker);
+ #endif
+}
+
+void vpp_wrapper_worker(struct work_struct *work)
+{
+ struct aml_v4l2_vpp *vpp =
+ container_of(work, struct aml_v4l2_vpp, worker);
+ struct aml_v4l2_vpp_buf *vpp_buf = NULL;
+
+ while (vpp->running &&
+ !kfifo_is_empty(&vpp->pre_output)) {
+ if (!kfifo_get(&vpp->pre_output, &vpp_buf)) {
+ v4l_dbg(vpp->ctx, 0, "vpp can not get pre output\n");
+ return;
+ }
+
+ if (vpp->is_prog) {
+ ATRACE_COUNTER("VC_IN_VPP-1.recycle", vpp_buf->aml_vb->aml_buf->index);
+ aml_buf_fill(&vpp->ctx->bm, vpp_buf->aml_vb->aml_buf, BUF_USER_VPP);
+ }
+
+ mutex_lock(&vpp->output_lock);
+ kfifo_put(&vpp->output, vpp_buf);
+ mutex_unlock(&vpp->output_lock);
+
+ up(&vpp->sem_out);
+ }
+}
+
+void aml_v4l2_vpp_recycle(struct aml_v4l2_vpp *vpp, struct aml_v4l2_buf *aml_vb)
+{
+ struct aml_v4l2_vpp_buf *vpp_buf;
+ struct di_buffer *buf = NULL;
+ struct vframe_s *vf = NULL;
+ bool bypass = false;
+ bool eos = false;
+
+ if (aml_vb->aml_buf->vpp_buf == NULL)
+ return;
+
+ vpp_buf = (struct aml_v4l2_vpp_buf *)aml_vb->aml_buf->vpp_buf;
+ buf = &vpp_buf->di_buf;
+ eos = (buf->flag & DI_FLAG_EOS);
+ bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
+ vf = vpp_buf->di_buf.vf;
+
+ ATRACE_COUNTER("VC_IN_VPP-0.vf_put", aml_vb->aml_buf->index);
+
+ if (!eos && !bypass) {
+ if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
+ /*vpp_buf->di_buf.caller_data might point to the vpp that had been destroyed*/
+ if (vpp != vpp_buf->di_buf.caller_data)
+ vpp_buf->di_buf.caller_data = vpp;
+ detach_DI_buffer(vpp_buf);
+ }
+ }
}
static int aml_v4l2_vpp_thread(void* param)
{
struct aml_v4l2_vpp* vpp = param;
struct aml_vcodec_ctx *ctx = vpp->ctx;
+ bool dynamic_bypass_vpp_flag = ctx->vpp_cfg.dynamic_bypass_vpp;
v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "enter vpp thread\n");
+
+ if (dynamic_bypass_vpp_flag) {
+ v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "dynamic bypass vpp\n");
+ }
while (vpp->running) {
struct aml_v4l2_vpp_buf *in_buf;
struct aml_v4l2_vpp_buf *out_buf = NULL;
struct vframe_s *vf_out = NULL;
- struct vdec_v4l2_buffer *fb;
+ struct aml_buf *aml_buf;
if (down_interruptible(&vpp->sem_in))
goto exit;
@@ -488,6 +742,12 @@
if (!vpp->running)
break;
+ if (dynamic_bypass_vpp_flag != ctx->vpp_cfg.dynamic_bypass_vpp) {
+ dynamic_bypass_vpp_flag = ctx->vpp_cfg.dynamic_bypass_vpp;
+ di_s_bypass_ch(vpp->di_handle, dynamic_bypass_vpp_flag);
+ v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "dynamic bypass vpp:%s\n",
+ dynamic_bypass_vpp_flag ? "enable" : "disable");
+ }
if (kfifo_is_empty(&vpp->output)) {
if (down_interruptible(&vpp->sem_out))
goto exit;
@@ -496,6 +756,7 @@
if ((vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) &&
(is_di_input_buff_full(vpp) || is_di_output_buff_full(vpp))) {
+ v4l_dbg(ctx, 0, "di input/output full!\n");
usleep_range(500, 550);
goto retry;
}
@@ -509,34 +770,28 @@
mutex_unlock(&vpp->output_lock);
/* bind v4l2 buffers */
- if (!vpp->is_prog && !out_buf->aml_buf) {
- struct vdec_v4l2_buffer *out;
+ if (!vpp->is_prog) {
+ struct aml_buf *out;
- if (!ctx->fb_ops.query(&ctx->fb_ops, &vpp->fb_token)) {
- usleep_range(500, 550);
- mutex_lock(&vpp->output_lock);
- kfifo_put(&vpp->output, out_buf);
- mutex_unlock(&vpp->output_lock);
- goto retry;
- }
-
- if (ctx->fb_ops.alloc(&ctx->fb_ops, vpp->fb_token, &out, AML_FB_REQ_VPP)) {
+ out = aml_buf_get(&ctx->bm, BUF_USER_VPP, false);
+ if (!out) {
usleep_range(5000, 5500);
mutex_lock(&vpp->output_lock);
kfifo_put(&vpp->output, out_buf);
mutex_unlock(&vpp->output_lock);
+ v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "vpp no frame buffers!\n");
goto retry;
}
- out_buf->aml_buf = container_of(out,
- struct aml_video_dec_buf, frame_buffer);
- out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
+ out_buf->aml_vb =
+ container_of(to_vb2_v4l2_buffer(out->vb), struct aml_v4l2_buf, vb);
+
v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
"vpp bind buf:%d to vpp_buf:%px\n",
VPP_BUF_GET_IDX(out_buf), out_buf);
- out->m.mem[0].bytes_used = out->m.mem[0].size;
- out->m.mem[1].bytes_used = out->m.mem[1].size;
+ out->planes[0].bytes_used = out->planes[0].length;
+ out->planes[1].bytes_used = out->planes[1].length;
}
/* safe to pop in_buf */
@@ -557,35 +812,32 @@
if (!vpp->is_prog) {
/* submit I to DI. */
- fb = &out_buf->aml_buf->frame_buffer;
- fb->status = FB_ST_VPP;
+ aml_buf = out_buf->aml_vb->aml_buf;
+ aml_buf->state = FB_ST_VPP;
memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
memcpy(vf_out->canvas0_config,
in_buf->di_buf.vf->canvas0_config,
2 * sizeof(struct canvas_config_s));
- vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1)
+ vf_out->canvas0_config[0].phy_addr = aml_buf->planes[0].addr;
+ if (aml_buf->num_planes == 1)
vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset;
+ aml_buf->planes[0].addr + aml_buf->planes[0].offset;
else
vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[1].addr;
-
- if (in_buf->di_buf.flag & DI_FLAG_EOS)
- memset(vf_out, 0, sizeof(*vf_out));
+ aml_buf->planes[1].addr;
vf_out->meta_data_size = in_buf->di_buf.vf->meta_data_size;
vf_out->meta_data_buf = in_buf->di_buf.vf->meta_data_buf;
} else {
/* submit P to DI. */
- out_buf->aml_buf = in_buf->aml_buf;
- out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
+ out_buf->aml_vb = in_buf->aml_vb;
memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
}
+ vf_out->mem_sec = ctx->is_drm_mode ? 1 : 0;
/* fill outbuf parms. */
out_buf->di_buf.vf = vf_out;
out_buf->di_buf.flag = 0;
@@ -612,11 +864,13 @@
}
v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_handle start: idx:(%d, %d), dec vf:%px/%d, vpp vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, %s %s "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d",
- in_buf->aml_buf->frame_buffer.buf_idx,
- out_buf->aml_buf->frame_buffer.buf_idx,
- in_buf->di_buf.vf, in_buf->di_buf.vf->index,
+ "vpp_handle start: idx:(%d, %d), dec vf:%px/%d afbc:0x%lx, vpp vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, %s %s "
+ "in:%d, out:%d, vf:%d, in done:%d, out done:%d, fgs_valid:%d",
+ in_buf->aml_vb->aml_buf->index,
+ out_buf->aml_vb->aml_buf->index,
+ in_buf->di_buf.vf,
+ in_buf->di_buf.vf->index,
+ in_buf->di_buf.vf->compHeadAddr,
out_buf->di_buf.vf, VPP_BUF_GET_IDX(out_buf),
in_buf->di_buf.vf->canvas0_config[0].phy_addr,
in_buf->di_buf.vf->canvas0_config[1].phy_addr,
@@ -632,36 +886,50 @@
kfifo_len(&vpp->output),
kfifo_len(&vpp->frame),
kfifo_len(&vpp->in_done_q),
- kfifo_len(&vpp->out_done_q));
+ kfifo_len(&vpp->out_done_q),
+ in_buf->di_buf.vf->fgs_valid);
- if (vpp->is_bypass_p) {
- ATRACE_COUNTER("V4L_OUT_VPP-1.direct_handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- out_buf->di_buf.flag = in_buf->di_buf.flag;
- out_buf->di_buf.vf->vf_ext = in_buf->di_buf.vf;
+ if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_7,
+ out_buf->aml_vb->aml_buf->index);
- v4l_vpp_fill_output_done(&out_buf->di_buf);
- v4l_vpp_empty_input_done(&in_buf->di_buf);
+ kfifo_put(&vpp->processing, in_buf);
+
+ di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_8,
+ in_buf->aml_vb->aml_buf->index);
+ di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
} else {
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
- /*
- * the flow of DI local buffer:
- * empty input -> output done cb -> fetch processing fifo.
- */
- ATRACE_COUNTER("VC_OUT_VPP-1.lc_handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- out_buf->inbuf = in_buf;
- kfifo_put(&vpp->processing, out_buf);
+ if (vpp->is_bypass_p) {
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_6,
+ in_buf->aml_vb->aml_buf->index);
+ out_buf->di_buf.flag = in_buf->di_buf.flag;
+ out_buf->di_buf.vf->vf_ext = in_buf->di_buf.vf;
- di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+ v4l_vpp_fill_output_done(&out_buf->di_buf);
+ v4l_vpp_empty_input_done(&in_buf->di_buf);
} else {
- ATRACE_COUNTER("VC_OUT_VPP-1.fill_output_start",
- out_buf->aml_buf->frame_buffer.buf_idx);
- di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
+ if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
+ /*
+ * the flow of DI local buffer:
+ * empty input -> output done cb -> fetch processing fifo.
+ */
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_5,
+ in_buf->aml_vb->aml_buf->index);
- ATRACE_COUNTER("VC_OUT_VPP-1.empty_input_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+ out_buf->inbuf = in_buf;
+ kfifo_put(&vpp->processing, out_buf);
+
+ di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+ } else {
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_3,
+ out_buf->aml_vb->aml_buf->index);
+ di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
+
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_4,
+ in_buf->aml_vb->aml_buf->index);
+ di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+ }
}
}
vpp->in_num[INPUT_PORT]++;
@@ -694,13 +962,17 @@
struct sched_param param =
{ .sched_priority = MAX_RT_PRIO - 1 };
- vpp->running = false;
- up(&vpp->sem_in);
- up(&vpp->sem_out);
- kthread_stop(vpp->task);
+ if (vpp->running) {
+ vpp->running = false;
+ cancel_work_sync(&vpp->worker);
+ up(&vpp->sem_in);
+ up(&vpp->sem_out);
+ kthread_stop(vpp->task);
+ }
kfifo_reset(&vpp->input);
kfifo_reset(&vpp->output);
+ kfifo_reset(&vpp->pre_output);
kfifo_reset(&vpp->frame);
kfifo_reset(&vpp->out_done_q);
kfifo_reset(&vpp->in_done_q);
@@ -737,7 +1009,7 @@
sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, ¶m);
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PRINFO, "vpp wrapper reset.\n");
+ v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PROT, "vpp wrapper reset.\n");
return 0;
@@ -773,17 +1045,28 @@
else
vpp->buffer_mode = BUFFER_MODE_USE_BUF;
- init.work_mode = WORK_MODE_PRE_POST;
+ if (vpp->work_mode == VPP_MODE_S4_DW_MMU)
+ init.work_mode = WORK_MODE_S4_DCOPY;
+ else
+ init.work_mode = WORK_MODE_PRE_POST;
init.buffer_mode = vpp->buffer_mode;
init.ops.fill_output_done = v4l_vpp_fill_output_done;
init.ops.empty_input_done = v4l_vpp_empty_input_done;
init.caller_data = (void *)vpp;
+ v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL,
+ "%s work_mode:0x%x buffer_mode:%d\n",__func__, vpp->work_mode, vpp->buffer_mode);
+
if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
init.ops.fill_output_done =
v4l_vpp_fill_output_done_alloc_buffer;
}
+ if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+ init.ops.fill_output_done =
+ v4l_vpp_fill_output_done_dw_mmu;
+ }
+
if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
init.output_format = DI_OUTPUT_BY_DI_DEFINE;
else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
@@ -792,7 +1075,7 @@
else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
((cfg->fmt == V4L2_PIX_FMT_NV12M) || (cfg->fmt == V4L2_PIX_FMT_NV12)))
init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
- else /* AFBC deocde case, NV12 as default */
+ else /* AFBC decoder case, NV12 as default */
init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
if (cfg->is_drm)
@@ -808,6 +1091,7 @@
INIT_KFIFO(vpp->input);
INIT_KFIFO(vpp->output);
+ INIT_KFIFO(vpp->pre_output);
INIT_KFIFO(vpp->frame);
INIT_KFIFO(vpp->out_done_q);
INIT_KFIFO(vpp->in_done_q);
@@ -816,11 +1100,20 @@
vpp->ctx = ctx;
vpp->is_prog = cfg->is_prog;
vpp->is_bypass_p = cfg->is_bypass_p;
+ INIT_WORK(&vpp->worker, vpp_wrapper_worker);
buf_size = vpp->is_prog ? 16 : cfg->buf_size;
vpp->buf_size = buf_size;
/* setup output fifo */
+ ret = kfifo_alloc(&vpp->pre_output, buf_size, GFP_KERNEL);
+ if (ret) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "alloc pre_output fifo fail.\n");
+ ret = -ENOMEM;
+ goto error1;
+ }
+
ret = kfifo_alloc(&vpp->output, buf_size, GFP_KERNEL);
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -907,7 +1200,7 @@
*vpp_handle = vpp;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"vpp_wrapper init bsize:%d, di(i:%d, o:%d), wkm:%x, bm:%x, fmt:%x, drm:%d, prog:%d, byp:%d, local:%d, NR:%d\n",
vpp->buf_size,
vpp->di_ibuf_num,
@@ -938,6 +1231,8 @@
error3:
kfifo_free(&vpp->output);
error2:
+ kfifo_free(&vpp->pre_output);
+error1:
di_destroy_instance(vpp->di_handle);
error:
kfree(vpp);
@@ -950,11 +1245,13 @@
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
"vpp destroy begin\n");
atomic_set(&vpp->local_buf_out, 0);
- vpp->running = false;
- up(&vpp->sem_in);
- up(&vpp->sem_out);
- kthread_stop(vpp->task);
-
+ if (vpp->running) {
+ vpp->running = false;
+ cancel_work_sync(&vpp->worker);
+ up(&vpp->sem_in);
+ up(&vpp->sem_out);
+ kthread_stop(vpp->task);
+ }
di_destroy_instance(vpp->di_handle);
/* no more vpp callback below this line */
@@ -964,6 +1261,7 @@
kfifo_free(&vpp->processing);
kfifo_free(&vpp->frame);
vfree(vpp->vfpool);
+ kfifo_free(&vpp->pre_output);
kfifo_free(&vpp->output);
vfree(vpp->ovbpool);
kfifo_free(&vpp->input);
@@ -977,17 +1275,36 @@
}
EXPORT_SYMBOL(aml_v4l2_vpp_destroy);
+int aml_v4l2_vpp_thread_stop(struct aml_v4l2_vpp* vpp)
+{
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+ "vpp thread stop begin\n");
+
+ if (vpp->running) {
+ vpp->running = false;
+ up(&vpp->sem_in);
+ up(&vpp->sem_out);
+ kthread_stop(vpp->task);
+ }
+
+ v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+ "vpp thread stop done\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(aml_v4l2_vpp_thread_stop);
+
static int aml_v4l2_vpp_push_vframe(struct aml_v4l2_vpp* vpp, struct vframe_s *vf)
{
struct aml_v4l2_vpp_buf *in_buf;
- struct vdec_v4l2_buffer *fb = NULL;
+ struct aml_buf *aml_buf = NULL;
if (!vpp)
return -EINVAL;
if (!kfifo_get(&vpp->input, &in_buf)) {
v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "cat not get free input buffer.\n");
+ "can not get free input buffer.\n");
return -1;
}
@@ -997,29 +1314,28 @@
if (vpp->in_num[INPUT_PORT] == 2)
vf->type |= VIDTYPE_V4L_EOS;
#endif
-
- in_buf->di_buf.vf = vf;
+ in_buf->di_buf.vf = &in_buf->vf;
in_buf->di_buf.flag = 0;
if (vf->type & VIDTYPE_V4L_EOS) {
- u32 dw_mode = VDEC_DW_NO_AFBC;
+ u32 dw_mode = DM_YUV_ONLY;
in_buf->di_buf.flag |= DI_FLAG_EOS;
if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
return -1;
- vf->type |= vpp->ctx->vpp_cfg.is_prog ?
- VIDTYPE_PROGRESSIVE :
- VIDTYPE_INTERLACE;
+ vf->type |= vpp->ctx->last_decoded_picinfo.field == V4L2_FIELD_INTERLACED ?
+ VIDTYPE_INTERLACE :
+ VIDTYPE_PROGRESSIVE;
- if (dw_mode != VDEC_DW_NO_AFBC)
+ if (dw_mode != DM_YUV_ONLY)
vf->type |= VIDTYPE_COMPRESS;
}
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+ aml_buf = (struct aml_buf *)vf->v4l_mem_handle;
+ in_buf->aml_vb = container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
+ if (is_cpu_t7()) {
if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
if ((vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
(vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
@@ -1029,7 +1345,7 @@
vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
}
else {
- if (fb->status == FB_ST_GE2D)
+ if (aml_buf->state == FB_ST_GE2D)
vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
}
}
@@ -1037,41 +1353,62 @@
if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
}
+ memcpy(&in_buf->vf, vf, sizeof(struct vframe_s));
v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_push_vframe: idx:%d, vf:%px, idx:%d, type:%x, ts:%lld\n",
- fb->buf_idx, vf, vf->index, vf->type, vf->timestamp);
+ "vpp_push_vframe: idx:%d, vf:%px, idx:%d, type:%x, ts:%lld flag:%x\n",
+ aml_buf->index, vf, vf->index, vf->type, vf->timestamp, vf->flag);
do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ unsigned int dw_mode = DM_YUV_ONLY;
struct file *fp;
-
+ char file_name[64] = {0};
if (!dump_vpp_input || vpp->ctx->is_drm_mode)
break;
if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
break;
- if (dw_mode == VDEC_DW_AFBC_ONLY)
+ if (dw_mode == DM_AVBC_ONLY)
break;
- fp = filp_open("/data/dec_dump_before.raw",
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+ snprintf(file_name, 64, "%s/dec_dump_vpp_input_%ux%u.raw", dump_path, vf->width, vf->height);
+ fp = media_open(file_name, O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
if (!IS_ERR(fp)) {
- struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
+ struct vb2_buffer *vb = &in_buf->aml_vb->vb.vb2_buf;
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
- if (in_buf->aml_buf->frame_buffer.num_planes == 2)
- kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
+ // dump y data
+ u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+ vf->width, vf->height, 64);
+
+ // dump uv data
+ if (vb->num_planes == 1) {
+ aml_yuv_dump(fp, yuv_data_addr, vf->width,
+ vf->height / 2, 64);
+ } else {
+ aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+ vf->width, vf->height / 2, 64);
+ }
+
+ pr_info("dump idx: %d %dx%d num_planes %d\n",
+ dump_vpp_input,
+ vf->width,
+ vf->height,
+ vb->num_planes);
+
dump_vpp_input--;
- filp_close(fp, NULL);
+ media_close(fp, NULL);
}
} while(0);
- ATRACE_COUNTER("VC_OUT_VPP-0.receive", fb->buf_idx);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_2, aml_buf->index);
kfifo_put(&vpp->in_done_q, in_buf);
up(&vpp->sem_in);
+ update_vpp_num_cache(vpp);
+ vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+
+ aml_buf_update_holder(&vpp->ctx->bm, aml_buf, BUF_USER_VPP, BUF_GET);
+
return 0;
}
@@ -1079,11 +1416,10 @@
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
+ struct aml_buf *aml_buf =
+ (struct aml_buf *)fb_ctx;
int ret = -1;
-
- ret = aml_v4l2_vpp_push_vframe(ctx->vpp, fb->vframe);
+ ret = aml_v4l2_vpp_push_vframe(ctx->vpp, &aml_buf->vframe);
if (ret < 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"vpp push vframe err, ret: %d\n", ret);
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.h b/drivers/amvdec_ports/aml_vcodec_vpp.h
index 27ffbe6..e53676f 100644
--- a/drivers/amvdec_ports/aml_vcodec_vpp.h
+++ b/drivers/amvdec_ports/aml_vcodec_vpp.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _AML_VCODEC_VPP_H_
#define _AML_VCODEC_VPP_H_
@@ -36,6 +36,7 @@
VPP_MODE_DI_LOCAL = 0x81,
VPP_MODE_COLOR_CONV_LOCAL = 0x82,
VPP_MODE_NOISE_REDUC_LOCAL = 0x83,
+ VPP_MODE_S4_DW_MMU = 0x91,
VPP_MODE_MAX = 0xff
};
@@ -46,8 +47,9 @@
struct di_buffer di_buf;
struct di_buffer *di_local_buf;
#endif
- struct aml_video_dec_buf *aml_buf;
+ struct aml_v4l2_buf *aml_vb;
struct aml_v4l2_vpp_buf *inbuf;
+ struct vframe_s vf;
};
struct aml_v4l2_vpp {
@@ -59,6 +61,7 @@
DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_vpp_buf*));
DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_vpp_buf*));
+ DECLARE_KFIFO_PTR(pre_output, typeof(struct aml_v4l2_vpp_buf*));
DECLARE_KFIFO_PTR(processing, typeof(struct aml_v4l2_vpp_buf*));
DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *));
DECLARE_KFIFO(out_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE);
@@ -70,6 +73,7 @@
struct task_struct *task;
bool running;
struct semaphore sem_in, sem_out;
+ struct work_struct worker;
/* In p to i transition, output/frame can be multi writer */
struct mutex output_lock;
@@ -101,6 +105,8 @@
struct aml_v4l2_vpp** vpp_handle);
int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp);
int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp);
+void aml_v4l2_vpp_recycle(struct aml_v4l2_vpp *vpp, struct aml_v4l2_buf *aml_vb);
+int aml_v4l2_vpp_thread_stop(struct aml_v4l2_vpp* vpp);
#else
static inline int aml_v4l2_vpp_get_buf_num(u32 mode) { return -1; }
static inline int aml_v4l2_vpp_init(
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
index d0d0198..085b84d 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.h b/drivers/amvdec_ports/decoder/aml_h264_parser.h
index def00dd..00cff32 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.h
@@ -1,7 +1,5 @@
/*
- * drivers/amvdec_ports/decoder/aml_h264_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef AML_H264_PARSER_H
#define AML_H264_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
index 24977a8..96154e6 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.h b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
index 9223639..5b8b9b6 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
@@ -1,7 +1,5 @@
/*
- * drivers/amvdec_ports/decoder/aml_hevc_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,9 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
-
#ifndef AML_HEVC_PARSER_H
#define AML_HEVC_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
index c582ab0..b86b6b1 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
index 4704ba0..c207b44 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AML_MJPEG_PARSER_H
#define AML_MJPEG_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
index 748a83f..23bfb93 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
index c06d632..e35947c 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AML_MPEG12_PARSER_H
#define AML_MPEG12_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
index 9c47c08..47075b2 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
@@ -1072,7 +1091,7 @@
// If we have not switched to studio profile than we also did not switch bps
// that means something else (like a previous instance) outside set bps which
- // would be inconsistant with the currect state, thus reset it
+ // would be inconsistent with the correct state, thus reset it
if (!s->studio_profile && bits_per_raw_sample != 8)
bits_per_raw_sample = 0;
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
index f9b71cf..16c78f5 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVCODEC_MPEG4VIDEO_H
#define AVCODEC_MPEG4VIDEO_H
diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.c b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
index 21d5283..c228abb 100644
--- a/drivers/amvdec_ports/decoder/aml_vp9_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.h b/drivers/amvdec_ports/decoder/aml_vp9_parser.h
index ddeddec..6b8cf92 100644
--- a/drivers/amvdec_ports/decoder/aml_vp9_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.h
@@ -1,7 +1,5 @@
/*
- * drivers/amvdec_ports/decoder/aml_vp9_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef AML_VP9_PARSER_H
#define AML_VP9_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/utils.h b/drivers/amvdec_ports/decoder/utils.h
index 26b1552..45268ee 100644
--- a/drivers/amvdec_ports/decoder/utils.h
+++ b/drivers/amvdec_ports/decoder/utils.h
@@ -1,6 +1,4 @@
/*
- * drivers/amlogic/media_modules/amvdec_ports/decoder/utils.h
- *
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef _UTILS_H
#define _UTILS_H
diff --git a/drivers/amvdec_ports/decoder/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c
index c28ca10..3a006b5 100644
--- a/drivers/amvdec_ports/decoder/vdec_av1_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -60,7 +60,7 @@
/**
* struct vdec_av1_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -205,8 +205,7 @@
};
static int vdec_write_nalu(struct vdec_av1_inst *inst,
- u8 *buf, u32 size, u64 ts);
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode);
+ u8 *buf, u32 size, u64 ts, chunk_free free);
static void get_pic_info(struct vdec_av1_inst *inst,
struct vdec_pic_info *pic)
@@ -277,6 +276,8 @@
ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "av1_double_write_mode:%d;",
ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "av1_triple_write_mode:%d;",
+ ctx->config.parm.dec.cfg.triple_write_mode);
pbuf += sprintf(pbuf, "av1_buf_width:1920;");
pbuf += sprintf(pbuf, "av1_buf_height:1088;");
pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -321,7 +322,7 @@
pbuf += sprintf(pbuf, "mW.y:%d;",
ctx->config.parm.dec.hdr.color_parms.white_point[1]);
pbuf += sprintf(pbuf, "mMaxDL:%d;",
- ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+ ctx->config.parm.dec.hdr.color_parms.luminance[0]);
pbuf += sprintf(pbuf, "mMinDL:%d;",
ctx->config.parm.dec.hdr.color_parms.luminance[1]);
pbuf += sprintf(pbuf, "mMaxCLL:%d;",
@@ -360,8 +361,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable av1 hw.*/
+ /* to enable av1 hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
/* probe info from the stream */
@@ -391,7 +394,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"av1 Instance >> %lx\n", (ulong) inst);
return 0;
@@ -412,7 +415,8 @@
{
int ret = 0;
- ret = vdec_write_nalu(inst, buf, size, timestamp);
+ ret = vdec_write_nalu(inst, buf, size, timestamp,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write data failed. size: %d, err: %d\n", size, ret);
@@ -450,7 +454,7 @@
static int parse_stream_cpu(struct vdec_av1_inst *inst, u8 *buf, u32 size)
{
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
- "can not suppport parse stream by cpu.\n");
+ "can not support parse stream by cpu.\n");
return -1;
}
@@ -464,7 +468,7 @@
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -915,7 +919,7 @@
&& ((p[1] == 0x00) && (p[2] == 0x3b)) /* terminal_provider_code */
&& ((p[3] == 0x00) && (p[4] == 0x00) && (p[5] == 0x08) && (p[6] == 0x00))) { /* terminal_provider_oriented_code */
v4l_dbg(0, V4L_DEBUG_CODEC_PARSER,
- "dolbyvison rpu\n");
+ "dolbyvision_std rpu\n");
meta_buf[0] = meta_buf[1] = meta_buf[2] = 0;
meta_buf[3] = 0x01;
meta_buf[4] = 0x19;
@@ -980,7 +984,7 @@
}
static int vdec_write_nalu(struct vdec_av1_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -1000,13 +1004,14 @@
parser_frame(0, src, src + size, data, &length, meta_buffer, &meta_size);
if (length)
- ret = vdec_vframe_write(vdec, data, length, ts, 0);
+ ret = vdec_vframe_write(vdec, data, length, ts,
+ 0, free);
else
ret = -1;
vfree(data);
} else {
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
}
return ret;
@@ -1051,7 +1056,7 @@
return -EAGAIN;
}
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -1070,7 +1075,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -1084,7 +1090,8 @@
(*res_chg = monitor_res_change(inst, buf, size)))
return 0;
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -1094,9 +1101,6 @@
struct aml_dec_params *parms)
{
if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
- /* dw use v4l cfg */
- inst->parms.cfg.double_write_mode =
- inst->ctx->config.parm.dec.cfg.double_write_mode;
parms->cfg = inst->parms.cfg;
}
if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
@@ -1112,6 +1116,11 @@
"parms status: %u\n", parms->parms_status);
}
+static void get_cfg_info(struct vdec_av1_inst *inst, struct aml_vdec_cfg_infos *cfg)
+{
+ memcpy(cfg, &inst->ctx->config.parm.dec.cfg, sizeof(struct aml_vdec_cfg_infos));
+}
+
static void get_param_comp_buf_info(struct vdec_av1_inst *inst,
struct vdec_comp_buf_info *params)
{
@@ -1147,16 +1156,24 @@
get_param_config_info(inst, out);
break;
+ case GET_PARAM_CFG_INFO:
+ get_cfg_info(inst, out);
+ break;
+
case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
{
u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ inst->parms.cfg.triple_write_mode;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
break;
}
+
case GET_PARAM_COMP_BUF_INFO:
get_param_comp_buf_info(inst, out);
break;
@@ -1175,62 +1192,6 @@
complete(&inst->comp);
}
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode)
-{
- u32 valid_dw_mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
- u32 dw = 0x1; /*1:1*/
-
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
-
- return dw;
-}
-
-static int vdec_pic_scale(struct vdec_av1_inst *inst, int length, int dw_mode)
-{
- int ret = 64;
-
- switch (vdec_get_dw_mode(inst, dw_mode)) {
- case 0x0: /* only afbc, output afbc */
- case 0x21: /* only afbc, output afbc */
- ret = 64;
- break;
- case 0x1: /* afbc and (w x h), output YUV420 */
- ret = length;
- break;
- case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
- case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
- ret = length >> 2;
- break;
- case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
- ret = length >> 1;
- break;
- case 0x10: /* (w x h), output YUV420-8bit) */
- default:
- ret = length;
- break;
- }
-
- return ret;
-}
-
static void set_param_ps_info(struct vdec_av1_inst *inst,
struct aml_vdec_ps_infos *ps)
{
@@ -1238,6 +1199,7 @@
struct vdec_av1_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
int dw = inst->parms.cfg.double_write_mode;
+ int tw = inst->parms.cfg.triple_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -1253,8 +1215,11 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ /* Only avbc, but DI will use YUV420 (w/4 x h/4) output. */
+ if (dw == DM_AVBC_1_1)
+ dw = DM_YUV_1_4_AVBC_B;
+
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
@@ -1263,6 +1228,12 @@
pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
+ pic->bitdepth = ps->bitdepth;
+
+ if (tw) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -1272,9 +1243,11 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
ps->visible_width, ps->visible_height,
- ps->coded_width, ps->coded_height);
+ ps->coded_width, ps->coded_height, ps->bitdepth,
+ inst->parms.cfg.double_write_mode,
+ inst->parms.cfg.triple_write_mode);
}
static void set_param_comp_buf_info(struct vdec_av1_inst *inst,
@@ -1300,7 +1273,7 @@
static void set_param_post_event(struct vdec_av1_inst *inst, u32 *event)
{
aml_vdec_dispatch_event(inst->ctx, *event);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"av1 post event: %d\n", *event);
}
@@ -1310,6 +1283,42 @@
inst->vsi->pic = *pic;
}
+static void set_cfg_info(struct vdec_av1_inst *inst,
+ struct aml_vdec_cfg_infos *new_cfg)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+ u32 tw_new = new_cfg->triple_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode,
+ old_cfg->triple_write_mode,
+ new_cfg->triple_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ /* Only avbc, but DI will use YUV420 (w/4 x h/4) output. */
+ if (dw_new == DM_AVBC_1_1)
+ dw_new = DM_YUV_1_4_AVBC_B;
+
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ if (old_cfg->triple_write_mode != tw_new) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ *old_cfg = *new_cfg;
+}
+
static int vdec_av1_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -1347,6 +1356,10 @@
set_pic_info(inst, in);
break;
+ case SET_PARAM_CFG_INFO:
+ set_cfg_info(inst, in);
+ break;
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_avs2_if.c b/drivers/amvdec_ports/decoder/vdec_avs2_if.c
new file mode 100644
index 0000000..1b8a27a
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs2_if.c
@@ -0,0 +1,795 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE (16)
+
+#define HEADER_BUFFER_SIZE (32 * 1024)
+#define SYNC_CODE (0x498342)
+
+/**
+ * struct avs2_fb - avs2 decode frame buffer information
+ * @vdec_fb_va : virtual address of struct vdec_fb
+ * @y_fb_dma : dma address of Y frame buffer (luma)
+ * @c_fb_dma : dma address of C frame buffer (chroma)
+ * @poc : picture order count of frame buffer
+ * @reserved : for 8 bytes alignment
+ */
+struct avs2_fb {
+ uint64_t vdec_fb_va;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ int32_t poc;
+ uint32_t reserved;
+};
+
+/**
+ * struct vdec_avs2_dec_info - decode information
+ * @dpb_sz : decoding picture buffer size
+ * @resolution_changed : resolution change happen
+ * @reserved : for 8 bytes alignment
+ * @bs_dma : Input bit-stream buffer dma address
+ * @y_fb_dma : Y frame buffer dma address
+ * @c_fb_dma : C frame buffer dma address
+ * @vdec_fb_va : VDEC frame buffer struct virtual address
+ */
+struct vdec_avs2_dec_info {
+ uint32_t dpb_sz;
+ uint32_t resolution_changed;
+ uint32_t reserved;
+ uint64_t bs_dma;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs2_vsi - shared memory for decode information exchange
+ * between VPU and Host.
+ * The memory is allocated by VPU then mapping to Host
+ * in vpu_dec_init() and freed in vpu_dec_deinit()
+ * by VPU.
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
+ * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp : display frame buffer ring list (AP-R, VPU-W)
+ * @dec : decode information (AP-R, VPU-W)
+ * @pic : picture information (AP-R, VPU-W)
+ * @crop : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs2_vsi {
+ char *header_buf;
+ int sps_size;
+ int pps_size;
+ int sei_size;
+ int head_offset;
+ struct vdec_avs2_dec_info dec;
+ struct vdec_pic_info pic;
+ struct vdec_pic_info cur_pic;
+ struct v4l2_rect crop;
+ bool is_combine;
+ int nalu_pos;
+};
+
+/**
+ * struct vdec_avs2_inst - avs2 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx : point to aml_vcodec_ctx
+ * @vsi : VPU shared information
+ */
+struct vdec_avs2_inst {
+ unsigned int num_nalu;
+ struct aml_vcodec_ctx *ctx;
+ struct aml_vdec_adapt vdec;
+ struct vdec_avs2_vsi *vsi;
+ struct aml_dec_params parms;
+ struct completion comp;
+ struct vdec_comp_buf_info comp_info;
+};
+
+
+static int vdec_write_nalu(struct vdec_avs2_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free);
+
+static void get_pic_info(struct vdec_avs2_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ *pic = inst->vsi->pic;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "pic(%d, %d), buf(%d, %d)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "Y(%d, %d), C(%d, %d)\n",
+ pic->y_bs_sz, pic->y_len_sz,
+ pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_crop_info(struct vdec_avs2_inst *inst, struct v4l2_rect *cr)
+{
+ cr->left = inst->vsi->crop.left;
+ cr->top = inst->vsi->crop.top;
+ cr->width = inst->vsi->crop.width;
+ cr->height = inst->vsi->crop.height;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "l=%d, t=%d, w=%d, h=%d\n",
+ cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_dpb_size(struct vdec_avs2_inst *inst, unsigned int *dpb_sz)
+{
+ *dpb_sz = inst->vsi->dec.dpb_sz;
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+ u8 *pbuf = parm;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
+ pbuf += sprintf(pbuf, "avs2_double_write_mode:3;");
+ pbuf += sprintf(pbuf, "avs2_buf_width:1920;");
+ pbuf += sprintf(pbuf, "avs2_buf_height:1088;");
+ pbuf += sprintf(pbuf, "avs2_max_pic_w:8192;");
+ pbuf += sprintf(pbuf, "avs2_max_pic_h:4608;");
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+ pbuf += sprintf(pbuf, "no_head:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
+
+ return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs2_inst *inst)
+{
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "%s:parms_status = 0x%x, present_flag = %d\n",
+ __func__, ctx->config.parm.dec.parms_status,
+ ctx->config.parm.dec.hdr.color_parms.present_flag);
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+ u8 *pbuf = ctx->config.buf;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+ ctx->config.parm.dec.cfg.ref_buf_margin);
+ pbuf += sprintf(pbuf, "avs2_double_write_mode:%d;",
+ ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "avs2_triple_write_mode:%d;",
+ ctx->config.parm.dec.cfg.triple_write_mode);
+ pbuf += sprintf(pbuf, "avs2_buf_width:1920;");
+ pbuf += sprintf(pbuf, "avs2_buf_height:1088;");
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+ pbuf += sprintf(pbuf, "no_head:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_endian);
+ pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
+ ctx->config.parm.dec.cfg.low_latency_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
+ ctx->config.parm.dec.cfg.duration);
+ ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.parm.dec.cfg.double_write_mode = 3;
+ ctx->config.parm.dec.cfg.ref_buf_margin = 7;
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
+ }
+
+ if ((ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
+ ctx->config.parm.dec.hdr.color_parms.present_flag) {
+ u8 *pbuf = ctx->config.buf + ctx->config.length;
+
+ pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
+ pbuf += sprintf(pbuf, "signal_type:%d;",
+ ctx->config.parm.dec.hdr.signal_type);
+ pbuf += sprintf(pbuf, "mG.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
+ pbuf += sprintf(pbuf, "mG.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+ pbuf += sprintf(pbuf, "mB.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+ pbuf += sprintf(pbuf, "mB.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+ pbuf += sprintf(pbuf, "mR.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+ pbuf += sprintf(pbuf, "mR.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+ pbuf += sprintf(pbuf, "mW.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+ pbuf += sprintf(pbuf, "mW.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+ pbuf += sprintf(pbuf, "mMaxDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+ pbuf += sprintf(pbuf, "mMinDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+ pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+ pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+ ctx->config.length = pbuf - ctx->config.buf;
+ inst->parms.hdr = ctx->config.parm.dec.hdr;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ }
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "config.buf = %s\n", ctx->config.buf);
+
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs2_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+ struct vdec_avs2_inst *inst = NULL;
+ int ret = -1;
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->vdec.frm_name = "AVS2";
+ inst->vdec.video_type = VFORMAT_AVS2;
+ inst->vdec.filp = ctx->dev->filp;
+ inst->vdec.ctx = ctx;
+ inst->ctx = ctx;
+
+ vdec_parser_parms(inst);
+
+ /* set play mode.*/
+ if (ctx->is_drm_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+ /* to enable avs2 hw.*/
+ inst->vdec.port.type = PORT_TYPE_HEVC;
+
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_avs2_vsi), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ init_completion(&inst->comp);
+
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ /* init decoder. */
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_avs2 init err=%d\n", ret);
+ goto err;
+ }
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs2 Instance >> %lx\n", (ulong) inst);
+
+ return 0;
+err:
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
+ *h_vdec = 0;
+
+ return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs2_inst *inst,
+ u8 *buf, u32 size, u64 timestamp)
+{
+ int ret = 0;
+
+ ret = vdec_write_nalu(inst, buf, size, timestamp,
+ vdec_vframe_input_free);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write data failed. size: %d, err: %d\n", size, ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_avs2_inst *inst,
+ ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+ vdec_vframe_input_free, inst->ctx);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs2_inst *inst, u8 *buf, u32 size)
+{
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "can not support parse stream by cpu.\n");
+
+ return -1;
+}
+
+static int vdec_avs2_probe(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, void *out)
+{
+ struct vdec_avs2_inst *inst =
+ (struct vdec_avs2_inst *)h_vdec;
+ u8 *buf = (u8 *)bs->vaddr;
+ u32 size = bs->size;
+ int ret = 0;
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if ((s->magic != AML_VIDEO_MAGIC) &&
+ (s->type != V4L_STREAM_TYPE_MATEDATA))
+ return -1;
+
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, s->data,
+ s->len, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, s->data, s->len);
+ }
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = parse_stream_ucode_dma(inst, bs->addr, size,
+ bs->timestamp, BUFF_IDX(bs, bs->index));
+ }
+ } else {
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, buf, size);
+ }
+ }
+
+ inst->vsi->cur_pic = inst->vsi->pic;
+
+ return ret;
+}
+
+static void vdec_avs2_deinit(unsigned long h_vdec)
+{
+ struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ video_decoder_release(&inst->vdec);
+
+ if (inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+
+ if (inst->vsi)
+ kfree(inst->vsi);
+
+ kfree(inst);
+
+ ctx->drv_handle = 0;
+}
+
+static int vdec_write_nalu(struct vdec_avs2_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+ return ret;
+}
+
+static bool monitor_res_change(struct vdec_avs2_inst *inst, u8 *buf, u32 size)
+{
+ int ret = -1;
+ u8 *p = buf;
+ int len = size;
+ u32 synccode =
+ ((p[17] << 16) | (p[18] << 8) | p[19]);
+
+ if (synccode == SYNC_CODE) {
+ ret = parse_stream_cpu(inst, p, len);
+ if (!ret && (inst->vsi->cur_pic.coded_width !=
+ inst->vsi->pic.coded_width ||
+ inst->vsi->cur_pic.coded_height !=
+ inst->vsi->pic.coded_height)) {
+ inst->vsi->cur_pic = inst->vsi->pic;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int vdec_avs2_decode(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, bool *res_chg)
+{
+ struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+ u8 *buf = (u8 *) bs->vaddr;
+ u32 size = bs->size;
+ int ret = -1;
+
+ if (bs == NULL)
+ return -1;
+
+ if (vdec_input_full(vdec)) {
+ return -EAGAIN;
+ }
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if (s->magic != AML_VIDEO_MAGIC)
+ return -1;
+
+ if (!inst->ctx->param_sets_from_ucode &&
+ (s->type == V4L_STREAM_TYPE_MATEDATA)) {
+ if ((*res_chg = monitor_res_change(inst,
+ s->data, s->len)))
+ return 0;
+ }
+
+ ret = vdec_vframe_write(vdec,
+ s->data,
+ s->len,
+ bs->timestamp,
+ 0,
+ vdec_vframe_input_free);
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = vdec_vframe_write_with_dma(vdec,
+ bs->addr, size, bs->timestamp,
+ BUFF_IDX(bs, bs->index),
+ vdec_vframe_input_free, inst->ctx);
+ }
+ } else {
+ /*checked whether the resolution changes.*/
+ if ((!inst->ctx->param_sets_from_ucode) &&
+ (*res_chg = monitor_res_change(inst, buf, size)))
+ return 0;
+
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
+ }
+
+ return ret;
+}
+
+ static void get_param_config_info(struct vdec_avs2_inst *inst,
+ struct aml_dec_params *parms)
+ {
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "parms status: %u\n", parms->parms_status);
+ }
+
+static void get_param_comp_buf_info(struct vdec_avs2_inst *inst,
+ struct vdec_comp_buf_info *params)
+{
+ memcpy(params, &inst->comp_info, sizeof(*params));
+}
+
+static int vdec_avs2_get_param(unsigned long h_vdec,
+ enum vdec_get_param_type type, void *out)
+{
+ int ret = 0;
+ struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs2 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case GET_PARAM_PIC_INFO:
+ get_pic_info(inst, out);
+ break;
+
+ case GET_PARAM_DPB_SIZE:
+ get_dpb_size(inst, out);
+ break;
+
+ case GET_PARAM_CROP_INFO:
+ get_crop_info(inst, out);
+ break;
+
+ case GET_PARAM_CONFIG_INFO:
+ get_param_config_info(inst, out);
+ break;
+
+ case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
+ {
+ u32 *mode = out;
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ inst->parms.cfg.triple_write_mode;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
+ break;
+ }
+
+ case GET_PARAM_COMP_BUF_INFO:
+ get_param_comp_buf_info(inst, out);
+ break;
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid get parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs2_inst *inst)
+{
+ complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs2_inst *inst,
+ struct aml_vdec_ps_infos *ps)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct vdec_avs2_dec_info *dec = &inst->vsi->dec;
+ struct v4l2_rect *rect = &inst->vsi->crop;
+ int dw = inst->parms.cfg.double_write_mode;
+ int tw = inst->parms.cfg.triple_write_mode;
+
+ /* fill visible area size that be used for EGL. */
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
+
+ /* calc visible ares. */
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = pic->visible_width;
+ rect->height = pic->visible_height;
+
+ /* config canvas size that be used for decoder. */
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
+
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+
+ /* calc DPB size */
+ pic->dpb_frames = ps->dpb_frames;
+ pic->dpb_margin = ps->dpb_margin;
+ pic->vpp_margin = ps->dpb_margin;
+ dec->dpb_sz = ps->dpb_size;
+ pic->field = ps->field;
+ pic->bitdepth = ps->bitdepth;
+
+ if (tw) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+ /*wake up*/
+ complete(&inst->comp);
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
+}
+
+static void set_param_comp_buf_info(struct vdec_avs2_inst *inst,
+ struct vdec_comp_buf_info *info)
+{
+ memcpy(&inst->comp_info, info, sizeof(*info));
+}
+
+static void set_param_hdr_info(struct vdec_avs2_inst *inst,
+ struct aml_vdec_hdr_infos *hdr)
+{
+ if ((inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+ inst->parms.hdr = *hdr;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ aml_vdec_dispatch_event(inst->ctx,
+ V4L2_EVENT_SRC_CH_HDRINFO);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "avs2 set HDR infos\n");
+ }
+}
+
+static void set_param_post_event(struct vdec_avs2_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs2 post event: %d\n", *event);
+}
+
+static void set_pic_info(struct vdec_avs2_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ inst->vsi->pic = *pic;
+}
+
+static void set_cfg_info(struct vdec_avs2_inst *inst,
+ struct aml_vdec_cfg_infos *new_cfg)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+ u32 tw_new = new_cfg->triple_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode,
+ old_cfg->triple_write_mode,
+ new_cfg->triple_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ if (old_cfg->triple_write_mode != tw_new) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ *old_cfg = *new_cfg;
+}
+
+static int vdec_avs2_set_param(unsigned long h_vdec,
+ enum vdec_set_param_type type, void *in)
+{
+ int ret = 0;
+ struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs2 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case SET_PARAM_WRITE_FRAME_SYNC:
+ set_param_write_sync(inst);
+ break;
+
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
+ break;
+
+ case SET_PARAM_COMP_BUF_INFO:
+ set_param_comp_buf_info(inst, in);
+ break;
+
+ case SET_PARAM_HDR_INFO:
+ set_param_hdr_info(inst, in);
+ break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
+ case SET_PARAM_PIC_INFO:
+ set_pic_info(inst, in);
+ break;
+
+ case SET_PARAM_CFG_INFO:
+ set_cfg_info(inst, in);
+ break;
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid set parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct vdec_common_if vdec_avs2_if = {
+ .init = vdec_avs2_init,
+ .probe = vdec_avs2_probe,
+ .decode = vdec_avs2_decode,
+ .get_param = vdec_avs2_get_param,
+ .set_param = vdec_avs2_set_param,
+ .deinit = vdec_avs2_deinit,
+};
+
+struct vdec_common_if *get_avs2_dec_comm_if(void)
+{
+ return &vdec_avs2_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_avs3_if.c b/drivers/amvdec_ports/decoder/vdec_avs3_if.c
new file mode 100644
index 0000000..e4de1a2
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs3_if.c
@@ -0,0 +1,795 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE (16)
+
+#define HEADER_BUFFER_SIZE (32 * 1024)
+#define SYNC_CODE (0x498342)
+
+/**
+ * struct avs3_fb - avs3 decode frame buffer information
+ * @vdec_fb_va : virtual address of struct vdec_fb
+ * @y_fb_dma : dma address of Y frame buffer (luma)
+ * @c_fb_dma : dma address of C frame buffer (chroma)
+ * @poc : picture order count of frame buffer
+ * @reserved : for 8 bytes alignment
+ */
+struct avs3_fb {
+ uint64_t vdec_fb_va;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ int32_t poc;
+ uint32_t reserved;
+};
+
+/**
+ * struct vdec_avs3_dec_info - decode information
+ * @dpb_sz : decoding picture buffer size
+ * @resolution_changed : resolution change happen
+ * @reserved : for 8 bytes alignment
+ * @bs_dma : Input bit-stream buffer dma address
+ * @y_fb_dma : Y frame buffer dma address
+ * @c_fb_dma : C frame buffer dma address
+ * @vdec_fb_va : VDEC frame buffer struct virtual address
+ */
+struct vdec_avs3_dec_info {
+ uint32_t dpb_sz;
+ uint32_t resolution_changed;
+ uint32_t reserved;
+ uint64_t bs_dma;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs3_vsi - shared memory for decode information exchange
+ * between VPU and Host.
+ * The memory is allocated by VPU then mapping to Host
+ * in vpu_dec_init() and freed in vpu_dec_deinit()
+ * by VPU.
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
+ * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp : display frame buffer ring list (AP-R, VPU-W)
+ * @dec : decode information (AP-R, VPU-W)
+ * @pic : picture information (AP-R, VPU-W)
+ * @crop : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs3_vsi {
+ char *header_buf;
+ int sps_size;
+ int pps_size;
+ int sei_size;
+ int head_offset;
+ struct vdec_avs3_dec_info dec;
+ struct vdec_pic_info pic;
+ struct vdec_pic_info cur_pic;
+ struct v4l2_rect crop;
+ bool is_combine;
+ int nalu_pos;
+};
+
+/**
+ * struct vdec_avs3_inst - avs3 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx : point to aml_vcodec_ctx
+ * @vsi : VPU shared information
+ */
+struct vdec_avs3_inst {
+ unsigned int num_nalu;
+ struct aml_vcodec_ctx *ctx;
+ struct aml_vdec_adapt vdec;
+ struct vdec_avs3_vsi *vsi;
+ struct aml_dec_params parms;
+ struct completion comp;
+ struct vdec_comp_buf_info comp_info;
+};
+
+
+static int vdec_write_nalu(struct vdec_avs3_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free);
+
+static void get_pic_info(struct vdec_avs3_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ *pic = inst->vsi->pic;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "pic(%d, %d), buf(%d, %d)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "Y(%d, %d), C(%d, %d)\n",
+ pic->y_bs_sz, pic->y_len_sz,
+ pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_crop_info(struct vdec_avs3_inst *inst, struct v4l2_rect *cr)
+{
+ cr->left = inst->vsi->crop.left;
+ cr->top = inst->vsi->crop.top;
+ cr->width = inst->vsi->crop.width;
+ cr->height = inst->vsi->crop.height;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "l=%d, t=%d, w=%d, h=%d\n",
+ cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_dpb_size(struct vdec_avs3_inst *inst, unsigned int *dpb_sz)
+{
+ *dpb_sz = inst->vsi->dec.dpb_sz;
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+ u8 *pbuf = parm;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
+ pbuf += sprintf(pbuf, "avs3_double_write_mode:3;");
+ pbuf += sprintf(pbuf, "avs3_buf_width:1920;");
+ pbuf += sprintf(pbuf, "avs3_buf_height:1088;");
+ pbuf += sprintf(pbuf, "avs3_max_pic_w:8192;");
+ pbuf += sprintf(pbuf, "avs3_max_pic_h:4608;");
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+ pbuf += sprintf(pbuf, "no_head:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
+
+ return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs3_inst *inst)
+{
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "%s:parms_status = 0x%x, present_flag = %d\n",
+ __func__, ctx->config.parm.dec.parms_status,
+ ctx->config.parm.dec.hdr.color_parms.present_flag);
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+ u8 *pbuf = ctx->config.buf;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+ ctx->config.parm.dec.cfg.ref_buf_margin);
+ pbuf += sprintf(pbuf, "avs3_double_write_mode:%d;",
+ ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "avs3_triple_write_mode:%d;",
+ ctx->config.parm.dec.cfg.triple_write_mode);
+ pbuf += sprintf(pbuf, "avs3_buf_width:1920;");
+ pbuf += sprintf(pbuf, "avs3_buf_height:1088;");
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+ pbuf += sprintf(pbuf, "no_head:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_endian);
+ pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
+ ctx->config.parm.dec.cfg.low_latency_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
+ ctx->config.parm.dec.cfg.duration);
+ ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.parm.dec.cfg.double_write_mode = 3;
+ ctx->config.parm.dec.cfg.ref_buf_margin = 7;
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
+ }
+
+ if ((ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
+ ctx->config.parm.dec.hdr.color_parms.present_flag) {
+ u8 *pbuf = ctx->config.buf + ctx->config.length;
+
+ pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
+ pbuf += sprintf(pbuf, "signal_type:%d;",
+ ctx->config.parm.dec.hdr.signal_type);
+ pbuf += sprintf(pbuf, "mG.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
+ pbuf += sprintf(pbuf, "mG.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+ pbuf += sprintf(pbuf, "mB.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+ pbuf += sprintf(pbuf, "mB.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+ pbuf += sprintf(pbuf, "mR.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+ pbuf += sprintf(pbuf, "mR.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+ pbuf += sprintf(pbuf, "mW.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+ pbuf += sprintf(pbuf, "mW.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+ pbuf += sprintf(pbuf, "mMaxDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+ pbuf += sprintf(pbuf, "mMinDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+ pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+ pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+ ctx->config.length = pbuf - ctx->config.buf;
+ inst->parms.hdr = ctx->config.parm.dec.hdr;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ }
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "config.buf = %s\n", ctx->config.buf);
+
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs3_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+ struct vdec_avs3_inst *inst = NULL;
+ int ret = -1;
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->vdec.frm_name = "AVS3";
+ inst->vdec.video_type = VFORMAT_AVS3;
+ inst->vdec.filp = ctx->dev->filp;
+ inst->vdec.ctx = ctx;
+ inst->ctx = ctx;
+
+ vdec_parser_parms(inst);
+
+ /* set play mode.*/
+ if (ctx->is_drm_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+ /* to enable avs3 hw.*/
+ inst->vdec.port.type = PORT_TYPE_HEVC;
+
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_avs3_vsi), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ init_completion(&inst->comp);
+
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ /* init decoder. */
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_avs3 init err=%d\n", ret);
+ goto err;
+ }
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs3 Instance >> %lx\n", (ulong) inst);
+
+ return 0;
+err:
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
+ *h_vdec = 0;
+
+ return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs3_inst *inst,
+ u8 *buf, u32 size, u64 timestamp)
+{
+ int ret = 0;
+
+ ret = vdec_write_nalu(inst, buf, size, timestamp,
+ vdec_vframe_input_free);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write data failed. size: %d, err: %d\n", size, ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_avs3_inst *inst,
+ ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+ vdec_vframe_input_free, inst->ctx);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs3_inst *inst, u8 *buf, u32 size)
+{
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "can not support parse stream by cpu.\n");
+
+ return -1;
+}
+
+static int vdec_avs3_probe(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, void *out)
+{
+ struct vdec_avs3_inst *inst =
+ (struct vdec_avs3_inst *)h_vdec;
+ u8 *buf = (u8 *)bs->vaddr;
+ u32 size = bs->size;
+ int ret = 0;
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if ((s->magic != AML_VIDEO_MAGIC) &&
+ (s->type != V4L_STREAM_TYPE_MATEDATA))
+ return -1;
+
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, s->data,
+ s->len, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, s->data, s->len);
+ }
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = parse_stream_ucode_dma(inst, bs->addr, size,
+ bs->timestamp, BUFF_IDX(bs, bs->index));
+ }
+ } else {
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, buf, size);
+ }
+ }
+
+ inst->vsi->cur_pic = inst->vsi->pic;
+
+ return ret;
+}
+
+static void vdec_avs3_deinit(unsigned long h_vdec)
+{
+ struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ video_decoder_release(&inst->vdec);
+
+ if (inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+
+ if (inst->vsi)
+ kfree(inst->vsi);
+
+ kfree(inst);
+
+ ctx->drv_handle = 0;
+}
+
+static int vdec_write_nalu(struct vdec_avs3_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+ return ret;
+}
+
+static bool monitor_res_change(struct vdec_avs3_inst *inst, u8 *buf, u32 size)
+{
+ int ret = -1;
+ u8 *p = buf;
+ int len = size;
+ u32 synccode =
+ ((p[17] << 16) | (p[18] << 8) | p[19]);
+
+ if (synccode == SYNC_CODE) {
+ ret = parse_stream_cpu(inst, p, len);
+ if (!ret && (inst->vsi->cur_pic.coded_width !=
+ inst->vsi->pic.coded_width ||
+ inst->vsi->cur_pic.coded_height !=
+ inst->vsi->pic.coded_height)) {
+ inst->vsi->cur_pic = inst->vsi->pic;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int vdec_avs3_decode(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, bool *res_chg)
+{
+ struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+ u8 *buf = (u8 *) bs->vaddr;
+ u32 size = bs->size;
+ int ret = -1;
+
+ if (bs == NULL)
+ return -1;
+
+ if (vdec_input_full(vdec)) {
+ return -EAGAIN;
+ }
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if (s->magic != AML_VIDEO_MAGIC)
+ return -1;
+
+ if (!inst->ctx->param_sets_from_ucode &&
+ (s->type == V4L_STREAM_TYPE_MATEDATA)) {
+ if ((*res_chg = monitor_res_change(inst,
+ s->data, s->len)))
+ return 0;
+ }
+
+ ret = vdec_vframe_write(vdec,
+ s->data,
+ s->len,
+ bs->timestamp,
+ 0,
+ vdec_vframe_input_free);
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = vdec_vframe_write_with_dma(vdec,
+ bs->addr, size, bs->timestamp,
+ BUFF_IDX(bs, bs->index),
+ vdec_vframe_input_free, inst->ctx);
+ }
+ } else {
+ /*checked whether the resolution changes.*/
+ if ((!inst->ctx->param_sets_from_ucode) &&
+ (*res_chg = monitor_res_change(inst, buf, size)))
+ return 0;
+
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
+ }
+
+ return ret;
+}
+
+ static void get_param_config_info(struct vdec_avs3_inst *inst,
+ struct aml_dec_params *parms)
+ {
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "parms status: %u\n", parms->parms_status);
+ }
+
+static void get_param_comp_buf_info(struct vdec_avs3_inst *inst,
+ struct vdec_comp_buf_info *params)
+{
+ memcpy(params, &inst->comp_info, sizeof(*params));
+}
+
+static int vdec_avs3_get_param(unsigned long h_vdec,
+ enum vdec_get_param_type type, void *out)
+{
+ int ret = 0;
+ struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs3 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case GET_PARAM_PIC_INFO:
+ get_pic_info(inst, out);
+ break;
+
+ case GET_PARAM_DPB_SIZE:
+ get_dpb_size(inst, out);
+ break;
+
+ case GET_PARAM_CROP_INFO:
+ get_crop_info(inst, out);
+ break;
+
+ case GET_PARAM_CONFIG_INFO:
+ get_param_config_info(inst, out);
+ break;
+
+ case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
+ {
+ u32 *mode = out;
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ inst->parms.cfg.triple_write_mode;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
+ break;
+ }
+
+ case GET_PARAM_COMP_BUF_INFO:
+ get_param_comp_buf_info(inst, out);
+ break;
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid get parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs3_inst *inst)
+{
+ complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs3_inst *inst,
+ struct aml_vdec_ps_infos *ps)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct vdec_avs3_dec_info *dec = &inst->vsi->dec;
+ struct v4l2_rect *rect = &inst->vsi->crop;
+ int dw = inst->parms.cfg.double_write_mode;
+ int tw = inst->parms.cfg.triple_write_mode;
+
+ /* fill visible area size that be used for EGL. */
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
+
+ /* calc visible ares. */
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = pic->visible_width;
+ rect->height = pic->visible_height;
+
+ /* config canvas size that be used for decoder. */
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
+
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+
+ /* calc DPB size */
+ pic->dpb_frames = ps->dpb_frames;
+ pic->dpb_margin = ps->dpb_margin;
+ pic->vpp_margin = ps->dpb_margin;
+ dec->dpb_sz = ps->dpb_size;
+ pic->field = ps->field;
+ pic->bitdepth = ps->bitdepth;
+
+ if (tw) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+ /*wake up*/
+ complete(&inst->comp);
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
+}
+
+static void set_param_comp_buf_info(struct vdec_avs3_inst *inst,
+ struct vdec_comp_buf_info *info)
+{
+ memcpy(&inst->comp_info, info, sizeof(*info));
+}
+
+static void set_param_hdr_info(struct vdec_avs3_inst *inst,
+ struct aml_vdec_hdr_infos *hdr)
+{
+ if ((inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+ inst->parms.hdr = *hdr;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ aml_vdec_dispatch_event(inst->ctx,
+ V4L2_EVENT_SRC_CH_HDRINFO);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "avs3 set HDR infos\n");
+ }
+}
+
+static void set_param_post_event(struct vdec_avs3_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs3 post event: %d\n", *event);
+}
+
+static void set_pic_info(struct vdec_avs3_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ inst->vsi->pic = *pic;
+}
+
+static void set_cfg_info(struct vdec_avs3_inst *inst,
+ struct aml_vdec_cfg_infos *new_cfg)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+ u32 tw_new = new_cfg->triple_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode,
+ old_cfg->triple_write_mode,
+ new_cfg->triple_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ if (old_cfg->triple_write_mode != tw_new) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ *old_cfg = *new_cfg;
+}
+
+static int vdec_avs3_set_param(unsigned long h_vdec,
+ enum vdec_set_param_type type, void *in)
+{
+ int ret = 0;
+ struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs3 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case SET_PARAM_WRITE_FRAME_SYNC:
+ set_param_write_sync(inst);
+ break;
+
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
+ break;
+
+ case SET_PARAM_COMP_BUF_INFO:
+ set_param_comp_buf_info(inst, in);
+ break;
+
+ case SET_PARAM_HDR_INFO:
+ set_param_hdr_info(inst, in);
+ break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
+ case SET_PARAM_PIC_INFO:
+ set_pic_info(inst, in);
+ break;
+
+ case SET_PARAM_CFG_INFO:
+ set_cfg_info(inst, in);
+ break;
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid set parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct vdec_common_if vdec_avs3_if = {
+ .init = vdec_avs3_init,
+ .probe = vdec_avs3_probe,
+ .decode = vdec_avs3_decode,
+ .get_param = vdec_avs3_get_param,
+ .set_param = vdec_avs3_set_param,
+ .deinit = vdec_avs3_deinit,
+};
+
+struct vdec_common_if *get_avs3_dec_comm_if(void)
+{
+ return &vdec_avs3_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_avs_if.c b/drivers/amvdec_ports/decoder/vdec_avs_if.c
new file mode 100644
index 0000000..dbc90b7
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs_if.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE (16)
+
+#define HEADER_BUFFER_SIZE (32 * 1024)
+#define SYNC_CODE (0x498342)
+
+/**
+ * struct vdec_avs_dec_info - decode information
+ * @dpb_sz : decoding picture buffer size
+ * @resolution_changed : resolution change happen
+ * @reserved : for 8 bytes alignment
+ * @bs_dma : Input bit-stream buffer dma address
+ * @y_fb_dma : Y frame buffer dma address
+ * @c_fb_dma : C frame buffer dma address
+ * @vdec_fb_va : VDEC frame buffer struct virtual address
+ */
+struct vdec_avs_dec_info {
+ uint32_t dpb_sz;
+ uint32_t resolution_changed;
+ uint32_t reserved;
+ uint64_t bs_dma;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs_vsi - shared memory for decode information exchange
+ * between VPU and Host.
+ * The memory is allocated by VPU then mapping to Host
+ * in vpu_dec_init() and freed in vpu_dec_deinit()
+ * by VPU.
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
+ * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp : display frame buffer ring list (AP-R, VPU-W)
+ * @dec : decode information (AP-R, VPU-W)
+ * @pic : picture information (AP-R, VPU-W)
+ * @crop : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs_vsi {
+ char *header_buf;
+ int sps_size;
+ int pps_size;
+ int sei_size;
+ int head_offset;
+ struct vdec_avs_dec_info dec;
+ struct vdec_pic_info pic;
+ struct vdec_pic_info cur_pic;
+ struct v4l2_rect crop;
+ bool is_combine;
+ int nalu_pos;
+};
+
+/**
+ * struct vdec_avs_inst - avs decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx : point to aml_vcodec_ctx
+ * @vsi : VPU shared information
+ */
+struct vdec_avs_inst {
+ unsigned int num_nalu;
+ struct aml_vcodec_ctx *ctx;
+ struct aml_vdec_adapt vdec;
+ struct vdec_avs_vsi *vsi;
+ struct aml_dec_params parms;
+ struct completion comp;
+ struct vdec_comp_buf_info comp_info;
+};
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+ u8 *pbuf = parm;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;");
+
+ return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs_inst *inst)
+{
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+ u8 *pbuf = ctx->config.buf;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+ ctx->config.parm.dec.cfg.ref_buf_margin);
+ ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
+ }
+
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+ struct vdec_avs_inst *inst = NULL;
+ int ret = -1;
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->vdec.frm_name = "AVS";
+ inst->vdec.video_type = VFORMAT_AVS;
+ inst->vdec.filp = ctx->dev->filp;
+ inst->vdec.ctx = ctx;
+ inst->ctx = ctx;
+
+ vdec_parser_parms(inst);
+
+ /* set play mode.*/
+ if (ctx->is_drm_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+ /* to enable avs hw.*/
+ inst->vdec.port.type = PORT_TYPE_VIDEO;
+
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_avs_vsi), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ init_completion(&inst->comp);
+
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ /* init decoder. */
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_avs init err=%d\n", ret);
+ goto err;
+ }
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs Instance >> %lx\n", (ulong) inst);
+
+ return 0;
+err:
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
+ *h_vdec = 0;
+
+ return ret;
+}
+
+static int vdec_write_nalu(struct vdec_avs_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+ return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs_inst *inst,
+ u8 *buf, u32 size, u64 timestamp)
+{
+ int ret = 0;
+
+ ret = vdec_write_nalu(inst, buf, size, timestamp,
+ vdec_vframe_input_free);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write data failed. size: %d, err: %d\n", size, ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+static int parse_stream_ucode_dma(struct vdec_avs_inst *inst,
+ ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+ vdec_vframe_input_free, inst->ctx);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs_inst *inst, u8 *buf, u32 size)
+{
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "can not support parse stream by cpu.\n");
+
+ return -1;
+}
+
+static int vdec_avs_probe(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, void *out)
+{
+ struct vdec_avs_inst *inst =
+ (struct vdec_avs_inst *)h_vdec;
+ u8 *buf = (u8 *)bs->vaddr;
+ u32 size = bs->size;
+ int ret = 0;
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if ((s->magic != AML_VIDEO_MAGIC) &&
+ (s->type != V4L_STREAM_TYPE_MATEDATA))
+ return -1;
+
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, s->data,
+ s->len, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, s->data, s->len);
+ }
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = parse_stream_ucode_dma(inst, bs->addr, size,
+ bs->timestamp, BUFF_IDX(bs, bs->index));
+ }
+ } else {
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, buf, size);
+ }
+ }
+
+ inst->vsi->cur_pic = inst->vsi->pic;
+
+ return ret;
+}
+
+static int vdec_avs_decode(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, bool *res_chg)
+{
+ struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+ u8 *buf = (u8 *) bs->vaddr;
+ u32 size = bs->size;
+ int ret = -1;
+
+ if (vdec_input_full(vdec))
+ return -EAGAIN;
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if (s->magic != AML_VIDEO_MAGIC)
+ return -1;
+
+ ret = vdec_vframe_write(vdec,
+ s->data,
+ s->len,
+ bs->timestamp,
+ 0,
+ vdec_vframe_input_free);
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = vdec_vframe_write_with_dma(vdec,
+ bs->addr, size, bs->timestamp,
+ BUFF_IDX(bs, bs->index),
+ vdec_vframe_input_free, inst->ctx);
+ }
+ } else {
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
+ }
+
+ return ret;
+}
+
+static void get_pic_info(struct vdec_avs_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ *pic = inst->vsi->pic;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "pic(%d, %d), buf(%d, %d)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "Y(%d, %d), C(%d, %d)\n",
+ pic->y_bs_sz, pic->y_len_sz,
+ pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_dpb_size(struct vdec_avs_inst *inst, unsigned int *dpb_sz)
+{
+ *dpb_sz = inst->vsi->dec.dpb_sz;
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static void get_crop_info(struct vdec_avs_inst *inst, struct v4l2_rect *cr)
+{
+ cr->left = inst->vsi->crop.left;
+ cr->top = inst->vsi->crop.top;
+ cr->width = inst->vsi->crop.width;
+ cr->height = inst->vsi->crop.height;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "l=%d, t=%d, w=%d, h=%d\n",
+ cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_param_config_info(struct vdec_avs_inst *inst,
+ struct aml_dec_params *parms)
+{
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "parms status: %u\n", parms->parms_status);
+}
+
+static int vdec_avs_get_param(unsigned long h_vdec,
+ enum vdec_get_param_type type, void *out)
+{
+ int ret = 0;
+ struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case GET_PARAM_PIC_INFO:
+ get_pic_info(inst, out);
+ break;
+
+ case GET_PARAM_DPB_SIZE:
+ get_dpb_size(inst, out);
+ break;
+
+ case GET_PARAM_CROP_INFO:
+ get_crop_info(inst, out);
+ break;
+
+ case GET_PARAM_CONFIG_INFO:
+ get_param_config_info(inst, out);
+ break;
+
+ case GET_PARAM_DW_MODE:
+ {
+ u32 *mode = out;
+ *mode = DM_YUV_ONLY;
+ break;
+ }
+
+ case GET_PARAM_TW_MODE:
+ {
+ unsigned int* mode = out;
+ *mode = DM_INVALID;
+ break;
+ }
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid get parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs_inst *inst)
+{
+ complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs_inst *inst,
+ struct aml_vdec_ps_infos *ps)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct vdec_avs_dec_info *dec = &inst->vsi->dec;
+ struct v4l2_rect *rect = &inst->vsi->crop;
+
+ /* fill visible area size that be used for EGL. */
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
+
+ /* calc visible ares. */
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = pic->visible_width;
+ rect->height = pic->visible_height;
+
+ /* config canvas size that be used for decoder. */
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
+
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
+ pic->c_len_sz = pic->y_len_sz >> 1;
+
+ /* calc DPB size */
+ pic->dpb_frames = ps->dpb_frames;
+ pic->dpb_margin = ps->dpb_margin;
+ pic->vpp_margin = ps->dpb_margin;
+ dec->dpb_sz = ps->dpb_size;
+ pic->field = ps->field;
+
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+ /*wake up*/
+ complete(&inst->comp);
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ ps->visible_width, ps->visible_height,
+ ps->coded_width, ps->coded_height,
+ pic->field == V4L2_FIELD_NONE ? "P" : "I");
+}
+
+static void set_pic_info(struct vdec_avs_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ inst->vsi->pic = *pic;
+}
+
+static void set_param_post_event(struct vdec_avs_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "avs post event: %d\n", *event);
+}
+
+static int vdec_avs_set_param(unsigned long h_vdec,
+ enum vdec_set_param_type type, void *in)
+{
+ int ret = 0;
+ struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the avs inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case SET_PARAM_WRITE_FRAME_SYNC:
+ set_param_write_sync(inst);
+ break;
+
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
+ break;
+
+ case SET_PARAM_PIC_INFO:
+ set_pic_info(inst, in);
+ break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid set parameter type=%d\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void vdec_avs_deinit(unsigned long h_vdec)
+{
+ struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ video_decoder_release(&inst->vdec);
+
+ if (inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+
+ if (inst->vsi)
+ kfree(inst->vsi);
+
+ kfree(inst);
+
+ ctx->drv_handle = 0;
+}
+
+static struct vdec_common_if vdec_avs_if = {
+ .init = vdec_avs_init,
+ .probe = vdec_avs_probe,
+ .decode = vdec_avs_decode,
+ .get_param = vdec_avs_get_param,
+ .set_param = vdec_avs_set_param,
+ .deinit = vdec_avs_deinit,
+};
+
+struct vdec_common_if *get_avs_dec_comm_if(void)
+{
+ return &vdec_avs_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 911c91d..d770115 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -32,6 +32,7 @@
#include "../vdec_drv_base.h"
#include "aml_h264_parser.h"
#include "../utils/common.h"
+#include "../aml_vcodec_ts.h"
/* h264 NALU type */
#define NAL_NON_IDR_SLICE 0x01
@@ -73,7 +74,7 @@
/**
* struct h264_ring_fb_list - ring frame buffer list
- * @fb_list : frame buffer arrary
+ * @fb_list : frame buffer array
* @read_idx : read index
* @write_idx : write index
* @count : buffer count in list
@@ -151,6 +152,7 @@
struct vdec_h264_vsi *vsi;
struct aml_dec_params parms;
struct completion comp;
+ struct vdec_comp_buf_info comp_info;
};
#if 0
@@ -176,7 +178,7 @@
void dump_init(void)
{
- filp = filp_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
+ filp = media_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
if (IS_ERR(filp)) {
pr_err("open dump file failed\n");
filp = NULL;
@@ -186,7 +188,7 @@
void dump_deinit(void)
{
if (filp) {
- filp_close(filp, current->files);
+ media_close(filp, current->files);
filp = NULL;
file_pos = 0;
}
@@ -218,6 +220,11 @@
pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
}
+static void get_cfg_info(struct vdec_h264_inst *inst, struct aml_vdec_cfg_infos *cfg)
+{
+ memcpy(cfg, &inst->ctx->config.parm.dec.cfg, sizeof(struct aml_vdec_cfg_infos));
+}
+
static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
{
cr->left = inst->vsi->crop.left;
@@ -315,6 +322,8 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
/* probe info from the stream */
inst->vsi = vzalloc(sizeof(struct vdec_h264_vsi));
@@ -342,7 +351,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"H264 Instance >> %lx", (ulong) inst);
return 0;
@@ -530,6 +539,33 @@
return combine;
}
+static bool cloud_game_check_frame_combine(u8 *buf, u32 size)
+{
+ bool combine = false;
+ int i = 0, j = 0, cnt = 0;
+ u32 nal_type = 0;
+ u8 *p = buf;
+
+ for (i = 4; i < size; i++) {
+ j = find_start_code(p, 7);
+ if (j > 0) {
+ if (++cnt > 1) {
+ combine = true;
+ break;
+ }
+
+ nal_type = AVC_NAL_TYPE(p[j]);
+ if (nal_type != NAL_H264_AUD &&
+ (nal_type > NAL_H264_PPS || nal_type < NAL_H264_SEI))
+ break;
+ p += j;
+ i += j;
+ }
+ p++;
+ }
+ return combine;
+}
+
static int vdec_search_startcode(u8 *buf, u32 range)
{
int pos = -1;
@@ -554,7 +590,8 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -628,13 +665,20 @@
static int vdec_h264_probe(unsigned long h_vdec,
struct aml_vcodec_mem *bs, void *out)
{
- struct vdec_h264_inst *inst =
- (struct vdec_h264_inst *)h_vdec;
+ struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
+ struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
u8 *buf = (u8 *) bs->vaddr;
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+ return 0;
+ }
+
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -688,7 +732,7 @@
}
static int vdec_write_nalu(struct vdec_h264_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = -1;
struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -703,7 +747,7 @@
goto err;
nal_type = AVC_NAL_TYPE(buf[nalu_pos]);
- //v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "NALU type: %d, size: %u\n", nal_type, size);
+ //v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "NALU type: %d, size: %u\n", nal_type, size);
if (nal_type == NAL_H264_SPS && !is_combine) {
if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
@@ -734,7 +778,7 @@
inst->vsi->head_offset += inst->vsi->sei_size;
ret = size;
} else if (inst->vsi->head_offset == 0) {
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
} else {
char *write_buf = vmalloc(inst->vsi->head_offset + size);
if (!write_buf) {
@@ -746,7 +790,7 @@
memcpy(write_buf + inst->vsi->head_offset, buf, size);
ret = vdec_vframe_write(vdec, write_buf,
- inst->vsi->head_offset + size, ts, 0);
+ inst->vsi->head_offset + size, ts, 0, free);
memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
inst->vsi->head_offset = 0;
@@ -795,7 +839,7 @@
inst->vsi->pic.coded_height) ||
(inst->vsi->pic.profile_idc !=
inst->vsi->cur_pic.profile_idc))) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n");
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "res change\n");
inst->vsi->cur_pic = inst->vsi->pic;
return true;
}
@@ -808,17 +852,27 @@
{
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
- u8 *buf = (u8 *) bs->vaddr;
- u32 size = bs->size;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+ u8 *buf;
+ u32 size;
int ret = -1;
if (bs == NULL)
return -1;
+ buf = (u8 *) bs->vaddr;
+ size = bs->size;
+
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(vdec, (u32)bs->addr, size);
+ return size;
+ }
+
if (vdec_input_full(vdec))
return -EAGAIN;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -837,7 +891,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -848,8 +903,12 @@
} else {
if (inst->ctx->param_sets_from_ucode) {
int nal_idx = 0;
+ bool enable_fence = (inst->parms.cfg.low_latency_mode & 2) ? 1 : 0;
/* if the st compose from csd + slice that is the combine data. */
- inst->vsi->is_combine = check_frame_combine(buf, size, &nal_idx);
+ if (enable_fence)
+ inst->vsi->is_combine = cloud_game_check_frame_combine(buf, size);
+ else
+ inst->vsi->is_combine = check_frame_combine(buf, size, &nal_idx);
/*if (nal_idx < 0)
return -1;*/
} else {
@@ -858,7 +917,8 @@
return 0;
}
}
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -878,8 +938,14 @@
parms->parms_status |= inst->parms.parms_status;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "parms status: %u\n", parms->parms_status);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "v4l config parms status: %u\n", parms->parms_status);
+}
+
+static void get_param_comp_buf_info(struct vdec_h264_inst *inst,
+ struct vdec_comp_buf_info *params)
+{
+ memcpy(params, &inst->comp_info, sizeof(*params));
}
static int vdec_h264_get_param(unsigned long h_vdec,
@@ -911,10 +977,25 @@
get_param_config_info(inst, out);
break;
+ case GET_PARAM_COMP_BUF_INFO:
+ get_param_comp_buf_info(inst, out);
+ break;
+
+ case GET_PARAM_CFG_INFO:
+ get_cfg_info(inst, out);
+ break;
+
case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
{
unsigned int* mode = out;
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ DM_INVALID;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
break;
}
@@ -932,6 +1013,30 @@
complete(&inst->comp);
}
+static void set_cfg_info(struct vdec_h264_inst *inst,
+ struct aml_vdec_cfg_infos *new_cfg)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ *old_cfg = *new_cfg;
+}
+
static void set_param_ps_info(struct vdec_h264_inst *inst,
struct aml_vdec_ps_infos *ps)
{
@@ -951,9 +1056,10 @@
rect->height = pic->visible_height;
/* config canvas size that be used for decoder. */
- pic->coded_width = ps->coded_width;
- pic->coded_height = ps->coded_height;
- pic->y_len_sz = pic->coded_width * pic->coded_height;
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
+
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
pic->c_len_sz = pic->y_len_sz >> 1;
pic->profile_idc = ps->profile;
pic->field = ps->field;
@@ -961,21 +1067,22 @@
pic->dpb_margin = ps->dpb_margin;
pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
+ pic->bitdepth = ps->bitdepth;
inst->parms.ps = *ps;
inst->parms.parms_status |=
V4L2_CONFIG_PARM_DECODE_PSINFO;
- vdec_config_dw_mode(pic, dw);
-
/*wake up*/
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), "
+ "scan:%s, bitdepth(%d), dw(%x)\n",
ps->visible_width, ps->visible_height,
ps->coded_width, ps->coded_height,
- ps->field == V4L2_FIELD_NONE ? "P" : "I");
+ ps->field == V4L2_FIELD_NONE ? "P" : "I",
+ ps->bitdepth, dw);
}
static void set_param_hdr_info(struct vdec_h264_inst *inst,
@@ -989,7 +1096,7 @@
V4L2_CONFIG_PARM_DECODE_HDRINFO;
aml_vdec_dispatch_event(inst->ctx,
V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
"H264 set HDR infos\n");
}
}
@@ -1003,9 +1110,14 @@
static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
{
aml_vdec_dispatch_event(inst->ctx, *event);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"H264 post event: %d\n", *event);
}
+static void set_param_comp_buf_info(struct vdec_h264_inst *inst,
+ struct vdec_comp_buf_info *info)
+{
+ memcpy(&inst->comp_info, info, sizeof(*info));
+}
static int vdec_h264_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
@@ -1039,7 +1151,12 @@
case SET_PARAM_PIC_INFO:
set_pic_info(inst, in);
break;
-
+ case SET_PARAM_COMP_BUF_INFO:
+ set_param_comp_buf_info(inst, in);
+ break;
+ case SET_PARAM_CFG_INFO:
+ set_cfg_info(inst, in);
+ break;
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index 56d492a..85242da 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -30,8 +30,9 @@
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
#include "aml_hevc_parser.h"
+#include "../aml_vcodec_ts.h"
-#define HEVC_NAL_TYPE(value) ((value >> 1) & 0x3F)
+#define HEVC_NAL_TYPE(value) ((value >> 1) & 0x3F)
#define HEADER_BUFFER_SIZE (32 * 1024)
/**
@@ -53,7 +54,7 @@
/**
* struct vdec_hevc_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -177,6 +178,8 @@
ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "hevc_double_write_mode:%d;",
ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "hevc_triple_write_mode:%d;",
+ ctx->config.parm.dec.cfg.triple_write_mode);
pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -190,6 +193,8 @@
ctx->config.parm.dec.cfg.metadata_config_flag);
pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
ctx->config.parm.dec.cfg.duration);
+ pbuf += sprintf(pbuf, "dv_profile:%d;",
+ ctx->config.parm.dec.cfg.dv_profile);
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.parm.dec.cfg.double_write_mode = 1;
@@ -222,8 +227,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable hevc hw.*/
+ /* to enable hevc hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
/* probe info from the stream */
@@ -252,7 +259,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"hevc Instance >> %lx\n", (ulong) inst);
return 0;
@@ -268,145 +275,14 @@
return ret;
}
-
-static int refer_buffer_num(struct h265_SPS_t *sps)
-{
- int used_buf_num = 0;
- int sps_pic_buf_diff = 0;
-
- if ((!sps->temporal_layer[0].num_reorder_pics) &&
- (sps->temporal_layer[0].max_dec_pic_buffering)) {
- /* the range of sps_num_reorder_pics_0 is in
- [0, sps_max_dec_pic_buffering_minus1_0] */
- used_buf_num = sps->temporal_layer[0].max_dec_pic_buffering;
- } else
- used_buf_num = sps->temporal_layer[0].num_reorder_pics;
-
- sps_pic_buf_diff = sps->temporal_layer[0].max_dec_pic_buffering -
- sps->temporal_layer[0].num_reorder_pics - 1;
-
- if (sps_pic_buf_diff >= 4)
- used_buf_num += 1;
-
- /*need one more for multi instance, as
- apply_ref_pic_set() has no chanch to run to
- to clear referenced flag in some case */
- used_buf_num++;
-
- /* for eos add more buffer to flush.*/
- used_buf_num++;
-
- return used_buf_num;
-}
-
-static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
-{
- u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
- u32 dw = 0x1; /*1:1*/
-
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
-
- return dw;
-}
-
-static int vdec_pic_scale(struct vdec_hevc_inst *inst, int length, int dw_mode)
-{
- int ret = 64;
-
- switch (vdec_get_dw_mode(inst, dw_mode)) {
- case 0x0: /* only afbc, output afbc */
- ret = 64;
- break;
- case 0x1: /* afbc and (w x h), output YUV420 */
- ret = length;
- break;
- case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
- case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
- ret = length >> 2;
- break;
- case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
- ret = length >> 1;
- break;
- case 0x10: /* (w x h), output YUV420-8bit)*/
- default:
- ret = length;
- break;
- }
-
- return ret;
-}
-
-static void fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps)
-{
- struct vdec_pic_info *pic = &inst->vsi->pic;
- struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
- struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.cfg.double_write_mode;
- int margin = inst->parms.cfg.ref_buf_margin;
-
- /* fill visible area size that be used for EGL. */
- pic->visible_width = sps->width - (sps->output_window.left_offset +
- sps->output_window.right_offset);
- pic->visible_height = sps->height - (sps->output_window.top_offset +
- sps->output_window.bottom_offset);
- pic->visible_width = vdec_pic_scale(inst, pic->visible_width, dw);
- pic->visible_height = vdec_pic_scale(inst, pic->visible_height, dw);
-
- /* calc visible ares. */
- rect->left = 0;
- rect->top = 0;
- rect->width = pic->visible_width;
- rect->height = pic->visible_height;
-
- /* config canvas size that be used for decoder. */
- pic->coded_width = vdec_pic_scale(inst, ALIGN(sps->width, 32), dw);
- pic->coded_height = vdec_pic_scale(inst, ALIGN(sps->height, 32), dw);
-
- pic->y_len_sz = pic->coded_width * pic->coded_height;
- pic->c_len_sz = pic->y_len_sz >> 1;
-
- /* calc DPB size */
- dec->dpb_sz = refer_buffer_num(sps) + margin;
-
- inst->parms.ps.visible_width = pic->visible_width;
- inst->parms.ps.visible_height = pic->visible_height;
- inst->parms.ps.coded_width = pic->coded_width;
- inst->parms.ps.coded_height = pic->coded_height;
- inst->parms.ps.dpb_size = dec->dpb_sz;
- inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
-
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
- "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
- dw, pic->coded_width, pic->coded_height,
- pic->visible_width, pic->visible_height,
- dec->dpb_sz - margin, margin);
-}
-
static int parse_stream_ucode(struct vdec_hevc_inst *inst,
u8 *buf, u32 size, u64 timestamp)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -458,7 +334,7 @@
}
if (ps->sps_parsed)
- fill_vdec_params(inst, &ps->sps);
+ //fill_vdec_params(inst, &ps->sps);
ret = ps->sps_parsed ? 0 : -1;
out:
@@ -475,8 +351,16 @@
u8 *buf = (u8 *)bs->vaddr;
u32 size = bs->size;
int ret = 0;
+ struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
- if (inst->ctx->is_drm_mode) {
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+ return 0;
+ }
+
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -528,12 +412,12 @@
}
static int vdec_write_nalu(struct vdec_hevc_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
return ret;
}
@@ -580,6 +464,7 @@
{
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
u8 *buf = (u8 *) bs->vaddr;
u32 size = bs->size;
int ret = -1;
@@ -587,10 +472,16 @@
if (bs == NULL)
return -1;
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(vdec, (u32)bs->addr, size);
+ return size;
+ }
+
if (vdec_input_full(vdec))
return -EAGAIN;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -609,7 +500,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -623,7 +515,8 @@
if ((*res_chg = monitor_res_change(inst, buf, size)))
return 0;
}
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -643,7 +536,7 @@
parms->parms_status |= inst->parms.parms_status;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"parms status: %u\n", parms->parms_status);
}
@@ -683,15 +576,19 @@
break;
case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
{
u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ inst->parms.cfg.triple_write_mode;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
break;
}
+
case GET_PARAM_COMP_BUF_INFO:
get_param_comp_buf_info(inst, out);
break;
@@ -717,6 +614,7 @@
struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
int dw = inst->parms.cfg.double_write_mode;
+ int tw = inst->parms.cfg.triple_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -733,8 +631,7 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
pic->c_len_sz = pic->y_len_sz >> 1;
pic->dpb_frames = ps->dpb_frames;
@@ -742,6 +639,12 @@
pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
+ pic->bitdepth = ps->bitdepth;
+
+ if (tw) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -751,19 +654,44 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), "
+ "scan:%s, bitdepth(%d), DW/TW(%x, %x)\n",
pic->visible_width, pic->visible_height,
pic->coded_width, pic->coded_height,
- pic->field == V4L2_FIELD_NONE ? "P" : "I");
+ pic->field == V4L2_FIELD_NONE ? "P" : "I",
+ ps->bitdepth, dw, tw);
}
static void set_cfg_info(struct vdec_hevc_inst *inst,
- struct aml_vdec_cfg_infos *cfg)
+ struct aml_vdec_cfg_infos *new_cfg)
{
- memcpy(&inst->ctx->config.parm.dec.cfg,
- cfg, sizeof(struct aml_vdec_cfg_infos));
- memcpy(&inst->parms.cfg,
- cfg, sizeof(struct aml_vdec_cfg_infos));
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+ u32 tw_new = new_cfg->triple_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode,
+ old_cfg->triple_write_mode,
+ new_cfg->triple_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ if (old_cfg->triple_write_mode != tw_new) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ *old_cfg = *new_cfg;
}
static void set_param_comp_buf_info(struct vdec_hevc_inst *inst,
@@ -782,7 +710,7 @@
V4L2_CONFIG_PARM_DECODE_HDRINFO;
aml_vdec_dispatch_event(inst->ctx,
V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"H265 set HDR infos\n");
}
}
@@ -790,7 +718,7 @@
static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event)
{
aml_vdec_dispatch_event(inst->ctx, *event);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"H265 post event: %d\n", *event);
}
@@ -858,8 +786,6 @@
.deinit = vdec_hevc_deinit,
};
-struct vdec_common_if *get_hevc_dec_comm_if(void);
-
struct vdec_common_if *get_hevc_dec_comm_if(void)
{
return &vdec_hevc_if;
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 8332956..98d04b5 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -53,7 +53,7 @@
/**
* struct vdec_mjpeg_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -209,8 +209,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable mjpeg hw.*/
+ /* to enable mjpeg hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
/* probe info from the stream */
@@ -238,7 +240,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"mjpeg Instance >> %lx\n", (ulong) inst);
return 0;
@@ -302,7 +304,8 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -372,7 +375,7 @@
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -424,12 +427,12 @@
}
static int vdec_write_nalu(struct vdec_mjpeg_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
return ret;
}
@@ -446,7 +449,7 @@
if (vdec_input_full(vdec))
return -EAGAIN;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -458,7 +461,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -467,7 +471,8 @@
vdec_vframe_input_free, inst->ctx);
}
} else {
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -501,7 +506,14 @@
case GET_PARAM_DW_MODE:
{
unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
+ *mode = DM_YUV_ONLY;
+ break;
+ }
+
+ case GET_PARAM_TW_MODE:
+ {
+ unsigned int* mode = out;
+ *mode = DM_INVALID;
break;
}
@@ -521,7 +533,7 @@
struct vdec_mjpeg_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "%s in\n", __func__);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "%s in\n", __func__);
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
pic->visible_height = ps->visible_height;
@@ -569,6 +581,13 @@
inst->vsi->pic = *pic;
}
+static void set_param_post_event(struct vdec_mjpeg_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "mjpeg post event: %d\n", *event);
+}
+
static int vdec_mjpeg_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -594,6 +613,10 @@
set_pic_info(inst, in);
break;
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
@@ -612,8 +635,6 @@
.deinit = vdec_mjpeg_deinit,
};
-struct vdec_common_if *get_mjpeg_dec_comm_if(void);
-
struct vdec_common_if *get_mjpeg_dec_comm_if(void)
{
return &vdec_mjpeg_if;
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
index 2472ac1..7697dbd 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -29,6 +29,7 @@
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
#include "aml_mpeg12_parser.h"
+#include "../aml_vcodec_ts.h"
#define NAL_TYPE(value) ((value) & 0x1F)
#define HEADER_BUFFER_SIZE (32 * 1024)
@@ -52,7 +53,7 @@
/**
* struct vdec_mpeg12_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -206,8 +207,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable mpeg12 hw.*/
+ /* to enable mpeg12 hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
/* probe info from the stream */
@@ -235,7 +238,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"mpeg12 Instance >> %lx\n", (ulong) inst);
return 0;
@@ -291,7 +294,8 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -361,7 +365,16 @@
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+ return 0;
+ }
+
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -413,12 +426,12 @@
}
static int vdec_write_nalu(struct vdec_mpeg12_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
return ret;
}
@@ -428,14 +441,21 @@
{
struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
u8 *buf = (u8 *) bs->vaddr;
u32 size = bs->size;
int ret = -1;
+ if (ctx->stream_mode) {
+ aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+ vdec_write_stream_data(vdec, (u32)bs->addr, size);
+ return size;
+ }
+
if (vdec_input_full(vdec))
return -EAGAIN;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -447,7 +467,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -456,7 +477,8 @@
vdec_vframe_input_free, inst->ctx);
}
} else {
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -471,7 +493,7 @@
parms->parms_status |= inst->parms.parms_status;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"parms status: %u\n", parms->parms_status);
}
@@ -507,7 +529,14 @@
case GET_PARAM_DW_MODE:
{
unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
+ *mode = DM_YUV_ONLY;
+ break;
+ }
+
+ case GET_PARAM_TW_MODE:
+ {
+ unsigned int* mode = out;
+ *mode = DM_INVALID;
break;
}
@@ -585,11 +614,18 @@
V4L2_CONFIG_PARM_DECODE_HDRINFO;
aml_vdec_dispatch_event(inst->ctx,
V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"mpeg12 set HDR infos\n");
}
}
+static void set_param_post_event(struct vdec_mpeg12_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "mpeg2 post event: %d\n", *event);
+}
+
static int vdec_mpeg12_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -619,6 +655,10 @@
set_pic_info(inst, in);
break;
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
index bc0af24..6f2abbf 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -52,7 +52,7 @@
/**
* struct vdec_mpeg4_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -205,8 +205,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable mpeg4 hw.*/
+ /* to enable mpeg4 hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
/* probe info from the stream */
@@ -234,7 +236,7 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"mpeg4 Instance >> %lx\n", (ulong) inst);
return 0;
@@ -298,7 +300,8 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -368,7 +371,7 @@
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -420,12 +423,12 @@
}
static int vdec_write_nalu(struct vdec_mpeg4_inst *inst,
- u8 *buf, u32 size, u64 ts)
+ u8 *buf, u32 size, u64 ts, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
return ret;
}
@@ -442,7 +445,7 @@
if (vdec_input_full(vdec))
return -EAGAIN;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -454,7 +457,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -463,7 +467,8 @@
vdec_vframe_input_free, inst->ctx);
}
} else {
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
}
return ret;
@@ -496,12 +501,19 @@
case GET_PARAM_DW_MODE:
{
unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
+ *mode = DM_YUV_ONLY;
+ break;
+ }
+
+ case GET_PARAM_TW_MODE:
+ {
+ unsigned int* mode = out;
+ *mode = DM_INVALID;
break;
}
default:
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
ret = -EINVAL;
}
@@ -516,7 +528,7 @@
struct vdec_mpeg4_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "%s in\n", __func__);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "%s in\n", __func__);
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
pic->visible_height = ps->visible_height;
@@ -564,6 +576,14 @@
inst->vsi->pic = *pic;
}
+static void set_param_post_event(struct vdec_mpeg4_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "mpeg4 post event: %d\n", *event);
+}
+
+
static int vdec_mpeg4_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -589,6 +609,10 @@
set_pic_info(inst, in);
break;
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_vc1_if.c b/drivers/amvdec_ports/decoder/vdec_vc1_if.c
new file mode 100644
index 0000000..44e05be
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_vc1_if.c
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+#include "../../frame_provider/decoder/utils/decoder_dma_alloc.h"
+#include "../../frame_provider/decoder/utils/vdec.h"
+
+#define NAL_TYPE(value) ((value) & 0x1F)
+#define HEADER_BUFFER_SIZE (32 * 1024)
+#define VC1_TS_POOL_SIZE 64
+
+/**
+ * struct vdec_vc1_dec_info - decode information
+ * @dpb_sz : decoding picture buffer size
+ * @resolution_changed : resolution change happen
+ * @reserved : for 8 bytes alignment
+ * @bs_dma : Input bit-stream buffer dma address
+ * @y_fb_dma : Y frame buffer dma address
+ * @c_fb_dma : C frame buffer dma address
+ * @vdec_fb_va : VDEC frame buffer struct virtual address
+ */
+struct vdec_vc1_dec_info {
+ uint32_t dpb_sz;
+ uint32_t resolution_changed;
+ uint32_t reserved;
+ uint64_t bs_dma;
+ uint64_t y_fb_dma;
+ uint64_t c_fb_dma;
+ uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_vc1_vsi - shared memory for decode information exchange
+ * between VPU and Host.
+ * The memory is allocated by VPU then mapping to Host
+ * in vpu_dec_init() and freed in vpu_dec_deinit()
+ * by VPU.
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
+ * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp : display frame buffer ring list (AP-R, VPU-W)
+ * @dec : decode information (AP-R, VPU-W)
+ * @pic : picture information (AP-R, VPU-W)
+ * @crop : crop information (AP-R, VPU-W)
+ */
+struct vdec_vc1_vsi {
+ char *header_buf;
+ int sps_size;
+ int pps_size;
+ int sei_size;
+ int head_offset;
+ struct vdec_vc1_dec_info dec;
+ struct vdec_pic_info pic;
+ struct vdec_pic_info cur_pic;
+ struct v4l2_rect crop;
+ bool is_combine;
+ int nalu_pos;
+};
+
+/**
+ * struct vdec_vc1_inst - vc1 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx : point to aml_vcodec_ctx
+ * @vsi : VPU shared information
+ */
+struct vdec_vc1_inst {
+ DECLARE_KFIFO_PTR(vc1_ts_q, u64);
+ unsigned int num_nalu;
+ struct aml_vcodec_ctx *ctx;
+ struct aml_vdec_adapt vdec;
+ struct vdec_vc1_vsi *vsi;
+ struct aml_dec_params parms;
+ struct completion comp;
+};
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+ u8 *pbuf = parm;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;");
+
+ return pbuf - parm;
+}
+
+static void vdec_parser_parms(struct vdec_vc1_inst *inst)
+{
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+ u8 *pbuf = ctx->config.buf;
+
+ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+ ctx->config.parm.dec.cfg.canvas_mem_mode);
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+ ctx->config.parm.dec.cfg.ref_buf_margin);
+ pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
+ ctx->config.parm.dec.cfg.metadata_config_flag);
+ pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
+ ctx->config.parm.dec.cfg.duration);
+ ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
+ }
+
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_vc1_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+ struct vdec_vc1_inst *inst = NULL;
+ int ret = -1;
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ /* init ts fifo */
+ INIT_KFIFO(inst->vc1_ts_q);
+
+ ret = kfifo_alloc(&inst->vc1_ts_q, VC1_TS_POOL_SIZE, GFP_KERNEL);
+ if (ret) {
+ v4l_dbg(inst->ctx, 0, "Alloc vc1_ts_q fifo fail.\n");
+ return -ENOMEM;
+ }
+
+ inst->vdec.frm_name = "VC1";
+ inst->vdec.video_type = VFORMAT_VC1;
+ inst->vdec.filp = ctx->dev->filp;
+ inst->vdec.ctx = ctx;
+ inst->ctx = ctx;
+
+ if (ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G)
+ inst->vdec.format = VIDEO_DEC_FORMAT_WVC1;
+ else if (ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)
+ inst->vdec.format = VIDEO_DEC_FORMAT_WMV3;
+
+ vdec_parser_parms(inst);
+
+ /* set play mode.*/
+ if (ctx->is_drm_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_vc1_inst), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ init_completion(&inst->comp);
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_vc1 init err=%d\n", ret);
+ goto err;
+ }
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "vc1 Instance >> %lx\n", (ulong) inst);
+
+ return 0;
+
+err:
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
+ *h_vdec = 0;
+
+ return ret;
+}
+
+static int parse_stream_ucode(struct vdec_vc1_inst *inst,
+ u8 *buf, u32 size, u64 timestamp)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+ vdec_vframe_input_free);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_vc1_inst *inst,
+ ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+ vdec_vframe_input_free, inst->ctx);
+ if (ret < 0) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_vc1_inst *inst, u8 *buf, u32 size)
+{
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "can not support parse stream by cpu.\n");
+
+ return -1;
+}
+
+static int vdec_vc1_probe(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, void *out)
+{
+ struct vdec_vc1_inst *inst =
+ (struct vdec_vc1_inst *)h_vdec;
+ u8 *buf = (u8 *)bs->vaddr;
+ u32 size = bs->size;
+ int ret = 0;
+
+ struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+
+ if (ctx->stream_mode) {
+ kfifo_put(&inst->vc1_ts_q, bs->timestamp);
+ vdec_write_stream_data_inner(adapt_vdec, (char *)bs->addr, size, bs->timestamp);
+
+ return 0;
+ }
+
+ /*
+ * Keep it for the frame mode later
+ */
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if ((s->magic != AML_VIDEO_MAGIC) &&
+ (s->type != V4L_STREAM_TYPE_MATEDATA))
+ return -1;
+
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, s->data,
+ s->len, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, s->data, s->len);
+ }
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = parse_stream_ucode_dma(inst, bs->addr, size,
+ bs->timestamp, BUFF_IDX(bs, bs->index));
+ }
+ } else {
+ if (inst->ctx->param_sets_from_ucode) {
+ ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+ } else {
+ ret = parse_stream_cpu(inst, buf, size);
+ }
+ }
+
+ inst->vsi->cur_pic = inst->vsi->pic;
+
+ return ret;
+}
+
+static void vdec_vc1_deinit(unsigned long h_vdec)
+{
+ struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+ if (!inst)
+ return;
+
+ video_decoder_release(&inst->vdec);
+
+ if (inst->vsi && inst->vsi->header_buf)
+ vfree(inst->vsi->header_buf);
+
+ if (inst->vsi)
+ kfree(inst->vsi);
+
+ kfifo_free(&inst->vc1_ts_q);
+
+ kfree(inst);
+}
+
+static int vdec_write_nalu(struct vdec_vc1_inst *inst,
+ u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+ return ret;
+}
+
+static int vdec_vc1_decode(unsigned long h_vdec,
+ struct aml_vcodec_mem *bs, bool *res_chg)
+{
+ struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
+ struct stream_buf_s *stbuf;
+ u8 *buf = (u8 *) bs->vaddr;
+ u32 size = bs->size;
+ int ret = -1;
+ u32 free_space = 0;
+
+ if (ctx->stream_mode) {
+ if (kfifo_is_full(&inst->vc1_ts_q))
+ return -EAGAIN;
+
+ stbuf = &vdec->vdec->vbuf;
+ /* calculate the free size of stbuf */
+ free_space = (stbuf->buf_wp >= stbuf->buf_rp) ?
+ (stbuf->buf_size - (stbuf->buf_wp - stbuf->buf_rp)) :
+ (stbuf->buf_rp - stbuf->buf_wp);
+ if (free_space < size) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_INPUT,
+ "%s require %d but stbuf free space(%d) is not enough. \n",
+ __func__, size, free_space);
+ return -EAGAIN;
+ } else {
+ kfifo_put(&inst->vc1_ts_q, bs->timestamp);
+ vdec_write_stream_data_inner(vdec, (char *)bs->addr, size, bs->timestamp);
+ return size;
+ }
+ }
+
+ /*
+ * Keep it for the frame mode later
+ */
+ if (vdec_input_full(vdec))
+ return -EAGAIN;
+
+ if (inst->ctx->output_dma_mode) {
+ if (bs->model == VB2_MEMORY_MMAP) {
+ struct aml_video_stream *s =
+ (struct aml_video_stream *) buf;
+
+ if (s->magic != AML_VIDEO_MAGIC)
+ return -1;
+
+ ret = vdec_vframe_write(vdec,
+ s->data,
+ s->len,
+ bs->timestamp,
+ 0,
+ vdec_vframe_input_free);
+ } else if (bs->model == VB2_MEMORY_DMABUF ||
+ bs->model == VB2_MEMORY_USERPTR) {
+ ret = vdec_vframe_write_with_dma(vdec,
+ bs->addr, size, bs->timestamp,
+ BUFF_IDX(bs, bs->index),
+ vdec_vframe_input_free, inst->ctx);
+ }
+ } else {
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ vdec_vframe_input_free);
+ }
+
+ return ret;
+}
+
+static void get_pic_info(struct vdec_vc1_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ *pic = inst->vsi->pic;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "pic(%d, %d), buf(%d, %d)\n",
+ pic->visible_width, pic->visible_height,
+ pic->coded_width, pic->coded_height);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "Y(%d, %d), C(%d, %d)\n",
+ pic->y_bs_sz, pic->y_len_sz,
+ pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void vdec_vc1_get_pts(struct vdec_vc1_inst *inst,
+ u64 *pts)
+{
+ u64 timestamp = 0;
+
+ if (kfifo_get(&inst->vc1_ts_q, ×tamp)) {
+ *pts = timestamp;
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "%s get pts: timestamp %lld\n", __func__,
+ timestamp);
+ }
+}
+
+static int vdec_vc1_get_param(unsigned long h_vdec,
+ enum vdec_get_param_type type, void *out)
+{
+ int ret = 0;
+ struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vc1 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case GET_PARAM_PIC_INFO:
+ get_pic_info(inst, out);
+ break;
+
+ case GET_PARAM_DW_MODE:
+ {
+ u32 *mode = out;
+ *mode = DM_YUV_ONLY;
+ break;
+ }
+
+ case GET_PARAM_TW_MODE:
+ {
+ unsigned int* mode = out;
+ *mode = DM_INVALID;
+ break;
+ }
+
+ case GET_PARAM_TIME_STAMP:
+ {
+ u64 *pts = out;
+ vdec_vc1_get_pts(inst, pts);
+ break;
+ }
+
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid get parameter type=%d\n", type);
+ ret = -EINVAL; // for test
+ }
+
+ return ret;
+}
+
+static void set_param_write_sync(struct vdec_vc1_inst *inst)
+{
+ complete(&inst->comp);
+}
+
+static void set_pic_info(struct vdec_vc1_inst *inst,
+ struct vdec_pic_info *pic)
+{
+ inst->vsi->pic = *pic;
+}
+
+static void set_param_post_event(struct vdec_vc1_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "vc1 post event: %d\n", *event);
+}
+
+static void set_param_ps_info(struct vdec_vc1_inst *inst,
+ struct aml_vdec_ps_infos *ps)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct vdec_vc1_dec_info *dec = &inst->vsi->dec;
+ struct v4l2_rect *rect = &inst->vsi->crop;
+
+ /* fill visible area size that be used for EGL. */
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
+
+ /* calc visible ares. */
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = pic->visible_width;
+ rect->height = pic->visible_height;
+
+ /* config canvas size that be used for decoder. */
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
+ pic->c_len_sz = pic->y_len_sz >> 1;
+
+ pic->dpb_frames = ps->dpb_frames;
+ pic->dpb_margin = ps->dpb_margin;
+ pic->vpp_margin = ps->dpb_margin;
+ dec->dpb_sz = ps->dpb_size;
+ pic->field = ps->field;
+
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+ /*wake up*/
+ complete(&inst->comp);
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ ps->visible_width, ps->visible_height,
+ ps->coded_width, ps->coded_height,
+ pic->field == V4L2_FIELD_NONE ? "P" : "I");
+}
+
+static void set_param_reset_event(struct vdec_vc1_inst *inst)
+{
+ /* reset fifo */
+ kfifo_reset(&inst->vc1_ts_q);
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+ "vc1 instance reset. \n");
+}
+
+static int vdec_vc1_set_param(unsigned long h_vdec,
+ enum vdec_set_param_type type, void *in)
+{
+ int ret = 0;
+ struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+ if (!inst) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vc1 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case SET_PARAM_WRITE_FRAME_SYNC:
+ set_param_write_sync(inst);
+ break;
+
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
+ break;
+
+ case SET_PARAM_PIC_INFO:
+ set_pic_info(inst, in);
+ break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
+
+ case SET_PARAM_INST_RESET:
+ set_param_reset_event(inst);
+ break;
+ default:
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "invalid set parameter type=%d\n", type);
+ ret = type;
+ }
+
+ return ret;
+}
+
+static struct vdec_common_if vdec_vc1_if = {
+ .init = vdec_vc1_init,
+ .probe = vdec_vc1_probe,
+ .decode = vdec_vc1_decode,
+ .get_param = vdec_vc1_get_param,
+ .set_param = vdec_vc1_set_param,
+ .deinit = vdec_vc1_deinit,
+};
+
+struct vdec_common_if *get_vc1_dec_comm_if(void);
+
+struct vdec_common_if *get_vc1_dec_comm_if(void)
+{
+ return &vdec_vc1_if;
+}
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index fe81ddd..1db31de 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/timer.h>
@@ -31,6 +31,7 @@
#include "../vdec_drv_base.h"
#include "aml_vp9_parser.h"
#include "vdec_vp9_trigger.h"
+#include "../utils/common.h"
#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
#include <trace/events/meson_atrace.h>
@@ -64,7 +65,7 @@
/**
* struct vdec_vp9_dec_info - decode information
* @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
+ * @resolution_changed : resolution change happen
* @reserved : for 8 bytes alignment
* @bs_dma : Input bit-stream buffer dma address
* @y_fb_dma : Y frame buffer dma address
@@ -128,7 +129,7 @@
};
static int vdec_write_nalu(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 ts, ulong meta_ptr);
+ u8 *buf, u32 size, u64 ts, ulong meta_ptr, chunk_free free);
static void get_pic_info(struct vdec_vp9_inst *inst,
struct vdec_pic_info *pic)
@@ -139,10 +140,6 @@
"pic(%d, %d), buf(%d, %d)\n",
pic->visible_width, pic->visible_height,
pic->coded_width, pic->coded_height);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
- "Y(%d, %d), C(%d, %d)\n",
- pic->y_bs_sz, pic->y_len_sz,
- pic->c_bs_sz, pic->c_len_sz);
}
static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
@@ -187,9 +184,9 @@
struct aml_vcodec_ctx *ctx = inst->ctx;
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s:parms_status = 0x%x, present_flag = %d\n",
+ "%s:parms_status = 0x%x, present_flag = %d, hdr.signal_type 0x%x\n",
__func__, ctx->config.parm.dec.parms_status,
- ctx->config.parm.dec.hdr.color_parms.present_flag);
+ ctx->config.parm.dec.hdr.color_parms.present_flag, ctx->config.parm.dec.hdr.signal_type);
if (ctx->config.parm.dec.parms_status &
V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
@@ -199,6 +196,8 @@
ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "vp9_triple_write_mode:%d;",
+ ctx->config.parm.dec.cfg.triple_write_mode);
pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
ctx->config.parm.dec.cfg.init_width);
pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
@@ -220,47 +219,51 @@
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
- if ((ctx->config.parm.dec.parms_status &
- V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
- ctx->config.parm.dec.hdr.color_parms.present_flag) {
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO) {
u8 *pbuf = ctx->config.buf + ctx->config.length;
-
- pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
- pbuf += sprintf(pbuf, "signal_type:%d;",
- ctx->config.parm.dec.hdr.signal_type);
- pbuf += sprintf(pbuf, "mG.x:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
- pbuf += sprintf(pbuf, "mG.y:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
- pbuf += sprintf(pbuf, "mB.x:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
- pbuf += sprintf(pbuf, "mB.y:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
- pbuf += sprintf(pbuf, "mR.x:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
- pbuf += sprintf(pbuf, "mR.y:%d;",
- ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
- pbuf += sprintf(pbuf, "mW.x:%d;",
- ctx->config.parm.dec.hdr.color_parms.white_point[0]);
- pbuf += sprintf(pbuf, "mW.y:%d;",
- ctx->config.parm.dec.hdr.color_parms.white_point[1]);
- pbuf += sprintf(pbuf, "mMaxDL:%d;",
- ctx->config.parm.dec.hdr.color_parms.luminance[0] * 10000);
- pbuf += sprintf(pbuf, "mMinDL:%d;",
- ctx->config.parm.dec.hdr.color_parms.luminance[1]);
- pbuf += sprintf(pbuf, "mMaxCLL:%d;",
- ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
- pbuf += sprintf(pbuf, "mMaxFALL:%d;",
- ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
- ctx->config.length = pbuf - ctx->config.buf;
- inst->parms.hdr = ctx->config.parm.dec.hdr;
- inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ if (ctx->config.parm.dec.hdr.color_parms.present_flag) {
+ pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
+ pbuf += sprintf(pbuf, "signal_type:%d;",
+ ctx->config.parm.dec.hdr.signal_type);
+ pbuf += sprintf(pbuf, "mG.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
+ pbuf += sprintf(pbuf, "mG.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+ pbuf += sprintf(pbuf, "mB.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+ pbuf += sprintf(pbuf, "mB.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+ pbuf += sprintf(pbuf, "mR.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+ pbuf += sprintf(pbuf, "mR.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+ pbuf += sprintf(pbuf, "mW.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+ pbuf += sprintf(pbuf, "mW.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+ pbuf += sprintf(pbuf, "mMaxDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[0] * 10000);
+ pbuf += sprintf(pbuf, "mMinDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+ pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+ pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+ }else {
+ pbuf += sprintf(pbuf, "signal_type:%d;",
+ ctx->config.parm.dec.hdr.signal_type);
+ }
+ ctx->config.length = pbuf - ctx->config.buf;
+ inst->parms.hdr = ctx->config.parm.dec.hdr;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "config.buf = %s\n", ctx->config.buf);
+ "config.buf = %s, ctx->config.length %d\n", ctx->config.buf, ctx->config.length);
inst->vdec.config = ctx->config;
inst->parms.cfg = ctx->config.parm.dec.cfg;
+
inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
}
@@ -284,8 +287,10 @@
/* set play mode.*/
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
+ if (ctx->output_dma_mode)
+ inst->vdec.port.flag |= PORT_FLAG_DMABUF;
- /* to eable vp9 hw.*/
+ /* to enable vp9 hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
/* probe info from the stream */
@@ -304,7 +309,7 @@
init_completion(&inst->comp);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"vp9 Instance >> %lx\n", (ulong) inst);
ctx->ada_ctx = &inst->vdec;
@@ -339,110 +344,13 @@
}
#endif
-static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
-{
- u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
- u32 dw = 0x1; /*1:1*/
-
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
-
- return dw;
-}
-
-static int vdec_pic_scale(struct vdec_vp9_inst *inst, int length, int dw_mode)
-{
- int ret = 64;
-
- switch (vdec_get_dw_mode(inst, dw_mode)) {
- case 0x0: /* only afbc, output afbc */
- ret = 64;
- break;
- case 0x1: /* afbc and (w x h), output YUV420 */
- ret = length;
- break;
- case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
- case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
- ret = length >> 2;
- break;
- case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
- ret = length >> 1;
- break;
- case 0x10: /* (w x h), output YUV420-8bit) */
- default:
- ret = length;
- break;
- }
-
- return ret;
-}
-
-static void fill_vdec_params(struct vdec_vp9_inst *inst,
- struct VP9Context *vp9_ctx)
-{
- struct vdec_pic_info *pic = &inst->vsi->pic;
- struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
- struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.cfg.double_write_mode;
- int margin = inst->parms.cfg.ref_buf_margin;
-
- /* fill visible area size that be used for EGL. */
- pic->visible_width = vdec_pic_scale(inst, vp9_ctx->render_width, dw);
- pic->visible_height = vdec_pic_scale(inst, vp9_ctx->render_height, dw);
-
- /* calc visible ares. */
- rect->left = 0;
- rect->top = 0;
- rect->width = pic->visible_width;
- rect->height = pic->visible_height;
-
- /* config canvas size that be used for decoder. */
- pic->coded_width = vdec_pic_scale(inst, ALIGN(vp9_ctx->width, 32), dw);
- pic->coded_height = vdec_pic_scale(inst, ALIGN(vp9_ctx->height, 32), dw);
-
- pic->y_len_sz = pic->coded_width * pic->coded_height;
- pic->c_len_sz = pic->y_len_sz >> 1;
-
- /* calc DPB size */
- dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
-
- inst->parms.ps.visible_width = pic->visible_width;
- inst->parms.ps.visible_height = pic->visible_height;
- inst->parms.ps.coded_width = pic->coded_width;
- inst->parms.ps.coded_height = pic->coded_height;
- inst->parms.ps.dpb_size = dec->dpb_sz;
- inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
-
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
- "The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
- dw, pic->coded_width, pic->coded_height,
- pic->visible_width, pic->visible_height,
- dec->dpb_sz - margin, margin);
-}
-
-static int parse_stream_ucode(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 timestamp, ulong meta_ptr)
+static int parse_stream_ucode(struct vdec_vp9_inst *inst, u8 *buf,
+ u32 size, u64 timestamp, ulong meta_ptr)
{
int ret = 0;
- ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr);
+ ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr,
+ vdec_vframe_input_free);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -494,7 +402,7 @@
}
if (ps->head_parsed)
- fill_vdec_params(inst, &ps->ctx);
+ //fill_vdec_params(inst, &ps->ctx);
ret = ps->head_parsed ? 0 : -1;
out:
@@ -512,7 +420,7 @@
u32 size = bs->size;
int ret = 0;
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -707,7 +615,7 @@
}
#endif
-static void trigger_decoder(struct aml_vdec_adapt *vdec)
+static void trigger_decoder(struct aml_vdec_adapt *vdec, chunk_free free)
{
int i, ret;
u32 frame_size = 0;
@@ -716,7 +624,7 @@
for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
frame_size = vp9_trigger_framesize[i];
ret = vdec_vframe_write(vdec, p,
- frame_size, 0, 0);
+ frame_size, 0, 0, free);
v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR,
"write trigger frame %d\n", ret);
p += frame_size;
@@ -724,7 +632,7 @@
}
static int vdec_write_nalu(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 ts, ulong meta_ptr)
+ u8 *buf, u32 size, u64 ts, ulong meta_ptr, chunk_free free)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -737,7 +645,7 @@
/*trigger.*/
if (0 && !need_trigger) {
- trigger_decoder(vdec);
+ trigger_decoder(vdec, free);
need_trigger = true;
}
@@ -754,10 +662,10 @@
/*add headers.*/
add_prefix_data(&s, &data, &length);
- ret = vdec_vframe_write(vdec, data, length, ts, 0);
+ ret = vdec_vframe_write(vdec, data, length, ts, 0, free);
vfree(data);
} else {
- ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr);
+ ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr, free);
}
return ret;
@@ -802,7 +710,7 @@
return -EAGAIN;
}
- if (inst->ctx->is_drm_mode) {
+ if (inst->ctx->output_dma_mode) {
if (bs->model == VB2_MEMORY_MMAP) {
struct aml_video_stream *s =
(struct aml_video_stream *) buf;
@@ -821,7 +729,8 @@
s->data,
s->len,
bs->timestamp,
- 0);
+ 0,
+ vdec_vframe_input_free);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -834,7 +743,8 @@
if ((!inst->ctx->param_sets_from_ucode) &&
(*res_chg = monitor_res_change(inst, buf, size)))
return 0;
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp, bs->meta_ptr);
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+ bs->meta_ptr, vdec_vframe_input_free);
}
return ret;
@@ -894,15 +804,19 @@
break;
case GET_PARAM_DW_MODE:
+ case GET_PARAM_TW_MODE:
{
u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
+ u32 m = (type == GET_PARAM_DW_MODE) ?
+ inst->parms.cfg.double_write_mode :
+ inst->parms.cfg.triple_write_mode;
+ int w = inst->vsi->pic.coded_width;
+ int h = inst->vsi->pic.coded_height;
+
+ *mode = vdec_get_dec_mode(w, h, m);
break;
}
+
case GET_PARAM_COMP_BUF_INFO:
get_param_comp_buf_info(inst, out);
break;
@@ -928,6 +842,7 @@
struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
int dw = inst->parms.cfg.double_write_mode;
+ int tw = inst->parms.cfg.triple_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -943,8 +858,7 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
@@ -953,6 +867,12 @@
pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
+ pic->bitdepth = ps->bitdepth;
+
+ if (tw) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -962,9 +882,9 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
+ "Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
pic->visible_width, pic->visible_height,
- pic->coded_width, pic->coded_height);
+ pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
}
static void set_param_comp_buf_info(struct vdec_vp9_inst *inst,
@@ -983,7 +903,7 @@
V4L2_CONFIG_PARM_DECODE_HDRINFO;
aml_vdec_dispatch_event(inst->ctx,
V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"VP9 set HDR infos\n");
}
}
@@ -991,7 +911,7 @@
static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event)
{
aml_vdec_dispatch_event(inst->ctx, *event);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
"VP9 post event: %d\n", *event);
}
@@ -1001,6 +921,38 @@
inst->vsi->pic = *pic;
}
+static void set_cfg_info(struct vdec_vp9_inst *inst,
+ struct aml_vdec_cfg_infos *new_cfg)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+ u32 dw_new = new_cfg->double_write_mode;
+ u32 tw_new = new_cfg->triple_write_mode;
+
+ if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+ return;
+
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+ __func__,
+ old_cfg->double_write_mode,
+ new_cfg->double_write_mode,
+ old_cfg->triple_write_mode,
+ new_cfg->triple_write_mode);
+
+ if (old_cfg->double_write_mode != dw_new) {
+ pic->y_len_sz = vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+ pic->c_len_sz = pic->y_len_sz >> 1;
+ }
+
+ if (old_cfg->triple_write_mode != tw_new) {
+ pic->y_len_sz_tw = vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+ pic->c_len_sz_tw = pic->y_len_sz_tw >> 1;
+ }
+
+ *old_cfg = *new_cfg;
+}
+
static int vdec_vp9_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -1038,6 +990,10 @@
set_pic_info(inst, in);
break;
+ case SET_PARAM_CFG_INFO:
+ set_cfg_info(inst, in);
+ break;
+
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h b/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
index 0097690..82fb3f4 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
@@ -1,7 +1,5 @@
/*
- * drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef _VDEC_VP9_TRIG_
#define _VDEC_VP9_TRIG_
diff --git a/drivers/amvdec_ports/test/Android.mk b/drivers/amvdec_ports/test/Android.mk
deleted file mode 100644
index d9652fb..0000000
--- a/drivers/amvdec_ports/test/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vcode_m2m
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := vcodec_m2m_test.c
-LOCAL_ARM_MODE := arm
-
-LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
- $(BOARD_AML_VENDOR_PATH)/vendor/amlogic/external/ffmpeg
-
-LOCAL_SHARED_LIBRARIES := \
- libamffmpeg
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_LIBS:= \
-# libavcodec:ffmpeg/lib/libavcodec.so \
-
-include $(BUILD_MULTI_PREBUILT)
diff --git a/drivers/amvdec_ports/test/vcodec_m2m_test.c b/drivers/amvdec_ports/test/vcodec_m2m_test.c
deleted file mode 100644
index bec040b..0000000
--- a/drivers/amvdec_ports/test/vcodec_m2m_test.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <pthread.h>
-
-#define INBUF_SIZE (4096)
-#define DUMP_DIR "/data/video_frames"
-static int dump;
-
-typedef struct VcodecCtx {
- AVFormatContext *fmt_ctx;
- AVStream *stream;
- int nb_streams;
- int vst_idx;
- char *filename;
- pthread_t tid;
- pthread_mutex_t pthread_mutex;
- pthread_cond_t pthread_cond;
-} VcodecCtx;
-
-static void dump_yuv(AVFrame *frame, char *filename)
-{
- FILE *f;
-
- printf("name: %s, resolution: %dx%d, size: %d\n",
- filename, frame->width, frame->height,
- frame->buf[0]->size + frame->buf[1]->size);
-
- f = fopen(filename,"w+");
-
- fwrite(frame->buf[0]->data, 1, frame->buf[0]->size, f);
- fwrite(frame->buf[1]->data, 1, frame->buf[1]->size, f);
-
- fclose(f);
-}
-
-static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
- const char *filename)
-{
- char buf[1024];
- int ret;
-
- ret = avcodec_send_packet(dec_ctx, pkt);
- if (ret < 0) {
- fprintf(stderr, "Error sending a packet for decoding\n");
- return;
- }
-
- while (ret >= 0) {
- ret = avcodec_receive_frame(dec_ctx, frame);
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
- return;
- else if (ret < 0) {
- fprintf(stderr, "Error during decoding, ret: %s\n", av_err2str(ret));
- break;
- }
-
- //fprintf(stderr, "saving frame %3d\n", dec_ctx->frame_number);
- fflush(stdout);
-
- /* the picture is allocated by the decoder. no need to free it */
- snprintf(buf, sizeof(buf), "%s/frame-%d", filename, dec_ctx->frame_number);
-
- if (dump)
- dump_yuv(frame, buf);
- }
-}
-
-static void* read_thread(void *arg)
-{
- int ret, err;
- AVFormatContext *ic = NULL;
- AVCodecContext *dec_ctx = NULL;
- AVStream *stream = NULL;
- AVCodec *codec = NULL;
- AVPacket pkt1, *pkt = &pkt1;
- AVFrame *frame = NULL;
- int vst_idx = 0;
- int has_video = 0;
- unsigned int st_idx = 0;
- VcodecCtx *vctx = arg;
- const char *forced_codec_name = NULL;
-
- printf("entry read thread, tid: %ld.\n", vctx->tid);
-
- ic = avformat_alloc_context();
- if (!ic) {
- fprintf(stderr, "Could not allocate avformat context.\n");
- goto out;
- }
-
- err = avformat_open_input(&ic, vctx->filename, NULL, NULL);
- if (err < 0) {
- fprintf(stderr, "Could not open avformat input.\n");
- goto out;
- }
-
- err = avformat_find_stream_info(ic, NULL);
- if (err < 0) {
- fprintf(stderr, "find stream info err.\n");
- goto out;
- }
-
- for (st_idx = 0; st_idx < ic->nb_streams; st_idx++) {
- AVStream *st = ic->streams[st_idx];
-
- enum AVMediaType type = st->codecpar->codec_type;
- st->discard = AVDISCARD_ALL;
-
- if (type == AVMEDIA_TYPE_VIDEO) {
- st->discard = AVDISCARD_NONE;
- vctx->vst_idx = st_idx;
- has_video = 1;
- break;
- }
- }
-
- if (!has_video) {
- fprintf(stderr, "no video stream.\n");
- goto out;
- }
-
- stream = ic->streams[vctx->vst_idx];
-
- //codec = avcodec_find_decoder(stream->codecpar->codec_id);
- switch (stream->codecpar->codec_id) {
- case AV_CODEC_ID_H264:
- forced_codec_name = "h264_v4l2m2m";
- break;
- case AV_CODEC_ID_HEVC:
- forced_codec_name = "hevc_v4l2m2m";
- break;
- case AV_CODEC_ID_VP9:
- forced_codec_name = "vp9_v4l2m2m";
- break;
- case AV_CODEC_ID_MPEG1VIDEO:
- forced_codec_name = "mpeg1_v4l2m2m";
- break;
- case AV_CODEC_ID_MPEG2VIDEO:
- forced_codec_name = "mpeg2_v4l2m2m";
- break;
- case AV_CODEC_ID_VC1:
- forced_codec_name = "vc1_v4l2m2m";
- break;
- case AV_CODEC_ID_H263:
- forced_codec_name = "h263_v4l2m2m";
- break;
- case AV_CODEC_ID_MPEG4:
- forced_codec_name = "mpeg4_v4l2m2m";
- break;
- case AV_CODEC_ID_MJPEG:
- forced_codec_name = "mjpeg_v4l2m2m";
- break;
- }
-
- codec = avcodec_find_decoder_by_name(forced_codec_name);
- if (!codec) {
- fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
- stream->codecpar->codec_id, stream->index);
- goto out;
- }
-
- dec_ctx = avcodec_alloc_context3(codec);
- if (!dec_ctx) {
- fprintf(stderr, "Could not allocate video codec context\n");
- goto out;
- }
-
- err = avcodec_parameters_to_context(dec_ctx, stream->codecpar);
- if (err < 0) {
- fprintf(stderr, "Could not set paras to context\n");
- goto out;
- }
-
- av_codec_set_pkt_timebase(dec_ctx, stream->time_base);
- dec_ctx->framerate = stream->avg_frame_rate;
-
- if (avcodec_open2(dec_ctx, codec, NULL) < 0) {
- fprintf(stderr, "Could not open codec for input stream %d\n",
- stream->index);
- goto out;
- }
-
- printf("fmt ctx: %p, stream: %p, video st idx: %d, num: %d\n",
- ic, stream, vst_idx, ic->nb_streams);
- printf("format: %s\n",ic->iformat->name);
-
- ic->flags |= AVFMT_FLAG_GENPTS;
- ic->debug = 0xff;
-
- //if (ic->pb)
- // ic->pb->eof_reached = 0;
-
- frame = av_frame_alloc();
- if (!frame) {
- fprintf(stderr, "Could not allocate video frame\n");
- goto out;
- }
-
- for (;;) {
- ret = av_read_frame(ic, pkt);
- if (ret < 0) {
- if (ret == AVERROR_EOF || avio_feof(ic->pb)) {
- printf("read data end, ret: %d.\n", ret);
- break;
- }
-
- if (ic->pb && ic->pb->error)
- break;
-
- printf("read data fail, ret: %d.\n", ret);
- continue;
- }
-
- if (pkt->stream_index == vctx->vst_idx) {
- //packet_queue_put(&is->audioq, pkt);
- //printf("read video data size: %d.\n", pkt->size);
- if (pkt->size)
- decode(dec_ctx, frame, pkt, DUMP_DIR);
- }
-
- av_packet_unref(pkt);
-
- usleep(8 * 1000);
- }
-
- /* flush the decoder */
- decode(dec_ctx, frame, NULL, DUMP_DIR);
-out:
- if (dec_ctx)
- avcodec_free_context(&dec_ctx);
-
- if (frame)
- av_frame_free(&frame);
-
- if (ic) {
- avformat_close_input(&ic);
- avformat_free_context(ic);
- }
-
- printf("read thread exit.\n");
-
- pthread_mutex_lock(&vctx->pthread_mutex);
- pthread_cond_signal(&vctx->pthread_cond);
- pthread_mutex_unlock(&vctx->pthread_mutex);
-
- return NULL;
-}
-
-static int open_input_file(const char *filename)
-{
- int ret;
- VcodecCtx *vctx;
- pthread_t pid = pthread_self();
-
- vctx = av_mallocz(sizeof(VcodecCtx));
- if (!vctx)
- return -1;
-
- vctx->filename = av_strdup(filename);
- if (!vctx->filename) {
- av_free(vctx);
- return -1;
- }
-
- pthread_mutex_init(&vctx->pthread_mutex, NULL);
- pthread_cond_init(&vctx->pthread_cond, NULL);
-
- ret = pthread_create(&vctx->tid, NULL, read_thread, (void *)vctx);
- if (ret == 0) {
- pthread_setname_np(pid, "read_thread");
-
- pthread_mutex_lock(&vctx->pthread_mutex);
- pthread_cond_wait(&vctx->pthread_cond, &vctx->pthread_mutex);
- pthread_join(vctx->tid, NULL);
- pthread_mutex_unlock(&vctx->pthread_mutex);
- }
-
- av_free(vctx->filename);
- av_free(vctx);
-
- printf("creat the read thread, ret: %d.\n", ret);
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int ret;
- const char *filename;
- int log_level = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <input file>\n ==> %s/frame-123\n", argv[0], DUMP_DIR);
- exit(0);
- }
-
- filename = argv[1];
- if (argv[2]) {
- if (!strcmp(argv[2], "dump"))
- dump = 1;
- else
- log_level = atoi(argv[2]);
- }
-
- mkdir(DUMP_DIR, 0664);
-
- /*set debug level*/
- av_log_set_level(log_level); //AV_LOG_DEBUG
-
- /* register all the codecs */
- avcodec_register_all();
-
- ret = open_input_file(filename);
- if (ret < 0)
- fprintf(stderr, "open input file fail.\n");
-
- return 0;
-}
diff --git a/drivers/amvdec_ports/utils/aml_dec_trace.c b/drivers/amvdec_ports/utils/aml_dec_trace.c
new file mode 100644
index 0000000..0d85b3f
--- /dev/null
+++ b/drivers/amvdec_ports/utils/aml_dec_trace.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+
+#include "aml_dec_trace.h"
+
+extern u32 trace_config;
+
+static const struct vdec_trace_map trace_map[] = {
+ /* trace mapping for v4ldec context. */
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_0, "V4L", "ES-que" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_1, "V4L", "ES-que_again" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_2, "V4L", "ES-write" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_3, "V4L", "ES-write_secure" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_4, "V4L", "ES-receive" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_5, "V4L", "ES-submit" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_6, "V4L", "ES-deque" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_7, "V4L", "ES-deque_again" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_8, "V4L", "ES-write_end" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_9, "V4L", "ES-write_secure_end" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_10, "V4L", "ES-write_error" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_11, "V4L", "ES-write_again" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ES_12, "V4L", "ES-in_pts" },
+
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_0, "V4L", "PIC-que" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_1, "V4L", "PIC-que_again" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_2, "V4L", "PIC-storage" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_3, "V4L", "PIC-require" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_4, "V4L", "PIC-recycle" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_5, "V4L", "PIC-receive" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_6, "V4L", "PIC-submit" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_7, "V4L", "PIC-deque" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_8, "V4L", "PIC-deque_again" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_9, "V4L", "PIC-out_pts" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_PIC_10, "V4L", "PIC-cache" },
+
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ST_0, "V4L", "ST-state" },
+ { VTRACE_GROUP_V4L_DEC, VTRACE_V4L_ST_1, "V4L", "ST-input_buffering" },
+
+ /* trace mapping for ge2d wrapper. */
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_0, "GE2D", "PIC-vf_put" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_1, "GE2D", "PIC-recycle" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_2, "GE2D", "PIC-receive" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_3, "GE2D", "PIC-handle_start" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_4, "GE2D", "PIC-submit" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_5, "GE2D", "PIC-vf_get" },
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_6, "GE2D", "PIC-cache" },
+
+ { VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_ST_0, "GE2D", "reserver" },
+
+ /* trace mapping for vpp wrapper. */
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_0, "VPP", "PIC-vf_put" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_1, "VPP", "PIC-recycle" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_2, "VPP", "PIC-receive" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_3, "VPP", "PIC-fill_output_start" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_4, "VPP", "PIC-empty_input_start" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_5, "VPP", "PIC-lc_handle_start" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_6, "VPP", "PIC-direct_handle_start" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_7, "VPP", "PIC-fill_output_start_dw" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_8, "VPP", "PIC-empty_input_start_dw" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_9, "VPP", "PIC-submit" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_10, "VPP", "PIC-lc_submit" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_11, "VPP", "PIC-vf_get" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_12, "VPP", "PIC-lc_attach" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_13, "VPP", "PIC-lc_detach" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_14, "VPP", "PIC-lc_release" },
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_PIC_15, "VPP", "PIC-cache" },
+
+ { VTRACE_GROUP_V4L_VPP, VTRACE_VPP_ST_0, "VPP", "reserver" },
+
+ /* trace mapping for decode core. */
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_PIC_0, "DEC", "PIC-submit" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_PIC_1, "DEC", "PIC-reserver" },
+
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_0, "DEC", "ST-chunk_size" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_1, "DEC", "ST-free_buffer_count" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_2, "DEC", "ST-dec_state" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_3, "DEC", "ST-work_state" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_4, "DEC", "ST-eos" },
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_5, "DEC", "ST-wait_more_buf" },
+
+ { VTRACE_GROUP_DEC_CORE, VTRACE_DEC_ST_6, "DEC", "ST-reserver" },
+
+ { 0, VTRACE_MAX, "unknown", "unknown" },
+};
+
+void vdec_trace_init(struct vdec_trace *vtr, int ch, int vdec_id)
+{
+ int i, size = ARRAY_SIZE(trace_map);
+
+ for (i = 0; i < size; i++) {
+ if (!(trace_config & trace_map[i].group)) {
+ vtr->item[i].enable = false;
+ continue;
+ }
+
+ vtr->item[i].channel = ch;
+ vtr->item[i].enable = true;
+ vtr->item[i].group = trace_map[i].group;
+ vtr->item[i].type = trace_map[i].type;
+
+ snprintf(vtr->item[i].name, 64,
+ "[%d,%d] %s_%s",
+ ch, vdec_id,
+ trace_map[i].gname,
+ trace_map[i].description);
+ }
+}
+
+void vdec_trace_clean(struct vdec_trace *vtr)
+{
+ int i, size = ARRAY_SIZE(trace_map);
+
+ for (i = 0; i < size; i++) {
+ if (vtr->item[i].value)
+ vdec_tracing(vtr, vtr->item[i].type, 0);
+ }
+}
+
diff --git a/drivers/amvdec_ports/utils/aml_dec_trace.h b/drivers/amvdec_ports/utils/aml_dec_trace.h
new file mode 100644
index 0000000..4c0fcb0
--- /dev/null
+++ b/drivers/amvdec_ports/utils/aml_dec_trace.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef _AML_DEC_TRACE_H_
+#define _AML_DEC_TRACE_H_
+
+#include <trace/events/meson_atrace.h>
+
+#define VTRACE_GROUP_V4L_DEC (1)
+#define VTRACE_GROUP_V4L_GE2D (2)
+#define VTRACE_GROUP_V4L_VPP (4)
+#define VTRACE_GROUP_DVB_DEC (8)
+#define VTRACE_GROUP_DVB_VTP (0x10)
+#define VTRACE_GROUP_DVB_VDO (0x20)
+#define VTRACE_GROUP_DVB_VOUT (0x40)
+#define VTRACE_GROUP_WRP (0x80)
+#define VTRACE_GROUP_WRP_GE2D (0x100)
+#define VTRACE_GROUP_WRP_VPP (0x200)
+#define VTRACE_GROUP_WRP_SINK (0x200)
+#define VTRACE_GROUP_DEC_CORE (0x400)
+
+enum vdec_trace_type_list {
+ /* v4l wrapper. */
+ VTRACE_V4L_ES_0, /* que. */
+ VTRACE_V4L_ES_1, /* que_again. */
+ VTRACE_V4L_ES_2, /* write. */
+ VTRACE_V4L_ES_3, /* write_secure. */
+ VTRACE_V4L_ES_4, /* receive. */
+ VTRACE_V4L_ES_5, /* submit. */
+ VTRACE_V4L_ES_6, /* deque. */
+ VTRACE_V4L_ES_7, /* deque_again. */
+ VTRACE_V4L_ES_8, /* write_end. */
+ VTRACE_V4L_ES_9, /* write_secure_end. */
+ VTRACE_V4L_ES_10, /* write_error. */
+ VTRACE_V4L_ES_11, /* write_again. */
+ VTRACE_V4L_ES_12, /* in PTS. */
+
+ VTRACE_V4L_PIC_0, /* que. */
+ VTRACE_V4L_PIC_1, /* que_again. */
+ VTRACE_V4L_PIC_2, /* storage. */
+ VTRACE_V4L_PIC_3, /* require. */
+ VTRACE_V4L_PIC_4, /* recycle. */
+ VTRACE_V4L_PIC_5, /* receive. */
+ VTRACE_V4L_PIC_6, /* submit. */
+ VTRACE_V4L_PIC_7, /* deque. */
+ VTRACE_V4L_PIC_8, /* deque_again. */
+ VTRACE_V4L_PIC_9, /* out PTS. */
+ VTRACE_V4L_PIC_10, /* vsink_cache_num. */
+
+ VTRACE_V4L_ST_0, /* state. */
+ VTRACE_V4L_ST_1, /* input_buffering. */
+
+ /* ge2d wrapper. */
+ VTRACE_GE2D_PIC_0, /* vf_put. */
+ VTRACE_GE2D_PIC_1, /* recycle. */
+ VTRACE_GE2D_PIC_2, /* receive. */
+ VTRACE_GE2D_PIC_3, /* handle_start. */
+ VTRACE_GE2D_PIC_4, /* submit. */
+ VTRACE_GE2D_PIC_5, /* vf_get. */
+ VTRACE_GE2D_PIC_6, /* ge2d_cache_num. */
+
+ VTRACE_GE2D_ST_0, /* reserver. */
+
+ /* vpp wrapper. */
+ VTRACE_VPP_PIC_0, /* vf_put. */
+ VTRACE_VPP_PIC_1, /* recycle. */
+ VTRACE_VPP_PIC_2, /* receive. */
+ VTRACE_VPP_PIC_3, /* fill_output_start. */
+ VTRACE_VPP_PIC_4, /* empty_input_start. */
+ VTRACE_VPP_PIC_5, /* lc_handle_start. */
+ VTRACE_VPP_PIC_6, /* direct_handle_start. */
+ VTRACE_VPP_PIC_7, /* fill_output_start_dw. */
+ VTRACE_VPP_PIC_8, /* empty_input_start_dw. */
+ VTRACE_VPP_PIC_9, /* submit. */
+ VTRACE_VPP_PIC_10, /* lc_submit. */
+ VTRACE_VPP_PIC_11, /* vf_get. */
+ VTRACE_VPP_PIC_12, /* lc_attach. */
+ VTRACE_VPP_PIC_13, /* lc_detach. */
+ VTRACE_VPP_PIC_14, /* lc_release. */
+ VTRACE_VPP_PIC_15, /* vpp_cache_num. */
+
+ VTRACE_VPP_ST_0, /* reserver. */
+
+ /* dec core */
+ VTRACE_DEC_PIC_0, /* submit. */
+ VTRACE_DEC_PIC_1, /* reserver. */
+
+ VTRACE_DEC_ST_0, /* chunk_size. */
+ VTRACE_DEC_ST_1, /* free_buffer_count. */
+ VTRACE_DEC_ST_2, /* dec_state. */
+ VTRACE_DEC_ST_3, /* work_state. */
+ VTRACE_DEC_ST_4, /* eos. */
+ VTRACE_DEC_ST_5, /* wait_more_buf. */
+ VTRACE_DEC_ST_6, /* reserver. */
+
+ VTRACE_MAX
+};
+
+struct vdec_trace_map {
+ u32 group;
+ int type;
+ u8 *gname;
+ u8 *description;
+};
+
+struct vdec_trace_item {
+ int channel;
+ bool enable;
+ u32 group;
+ int type;
+ ulong value;
+ u8 name[64];
+};
+
+struct vdec_trace {
+ struct vdec_trace_item item[VTRACE_MAX + 1];
+};
+
+void vdec_trace_init(struct vdec_trace *vtr, int ch, int vdec_id);
+
+void vdec_trace_clean(struct vdec_trace *vtr);
+
+static inline void vdec_tracing(struct vdec_trace *vtr, int type, ulong val)
+{
+ if (vtr->item[type].enable) {
+ meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+ vtr->item[type].name,
+ (1 << KERNEL_ATRACE_COUNTER), val);
+ vtr->item[type].value = val;
+ }
+}
+
+static inline void vdec_tracing_begin(struct vdec_trace *vtr, int type)
+{
+ if (vtr->item[type].enable) {
+ meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+ vtr->item[type].name,
+ (1 << KERNEL_ATRACE_BEGIN), 0);
+ }
+}
+
+static inline void vdec_tracing_end(struct vdec_trace *vtr, int type)
+{
+ if (vtr->item[type].enable) {
+ meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+ vtr->item[type].name,
+ (1 << KERNEL_ATRACE_END), 1);
+ }
+}
+
+#endif //_AML_DEC_TRACE_H_
+
diff --git a/drivers/amvdec_ports/utils/common.c b/drivers/amvdec_ports/utils/common.c
index 67cf93b..34efa3e 100644
--- a/drivers/amvdec_ports/utils/common.c
+++ b/drivers/amvdec_ports/utils/common.c
@@ -1,8 +1,28 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/string.h>
+#include "../../common/media_utils/media_utils.h"
#include "common.h"
#ifdef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
@@ -229,4 +249,121 @@
return false;
}
+u8 *aml_yuv_dump(struct file *fp, u8 *start_addr, u32 real_width, u32 real_height, u32 align)
+{
+ u32 index;
+ u32 coded_width = ALIGN(real_width, align);
+ u32 coded_height = ALIGN(real_height, align);
+ u8 *yuv_data_addr = start_addr;
+
+ if (real_width != coded_width) {
+ for (index = 0; index < real_height; index++) {
+ media_write(fp, yuv_data_addr, real_width, 0);
+ yuv_data_addr += coded_width;
+ }
+ } else {
+ media_write(fp, yuv_data_addr, real_width * real_height, 0);
+ }
+
+ return (start_addr + coded_width * coded_height);
+}
+
+bool is_output_p010(u32 dec_mode)
+{
+ return !!(dec_mode & VDEC_MODE_10BIT_MASK);
+}
+
+int vdec_get_size_ratio(int dec_mode)
+{
+ int ratio = 1;
+
+ u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+ switch (dm) {
+ case DM_YUV_1_4_AVBC_A:
+ case DM_YUV_1_4_AVBC_B:
+ ratio = 4;
+ break;
+ case DM_YUV_1_2_AVBC:
+ ratio = 2;
+ break;
+ case DM_YUV_1_8_AVBC:
+ ratio = 8;
+ break;
+ default:
+ break;
+ }
+
+ return ratio;
+}
+
+int vdec_get_dec_mode(u32 w, u32 h, int dec_mode)
+{
+ u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+ switch (dm) {
+ case DM_YUV_AUTO_1_2_AVBC:
+ if (is_over_size(w, h, 1920 * 1088))
+ dm = 0x4; /*1:2*/
+ break;
+ case DM_YUV_AUTO_1_4_AVBC:
+ if (is_over_size(w, h, 1920 * 1088))
+ dm = 0x2; /*1:4*/
+ break;
+ case DM_YUV_AUTO_1_2_AVBC_B:
+ if (is_over_size(w, h, 1280 * 768))
+ dm = 0x4; /*1:2*/
+ break;
+ case DM_YUV_AUTO_14_12_AVBC:
+ if (is_over_size(w, h, 1920 * 1088))
+ dm = 0x3; /*1:4*/
+ else if (is_over_size(w, h, 960 * 576))
+ dm = 0x4; /*1:2*/
+ break;
+ default:
+ break;
+ }
+
+ return (dec_mode & VDEC_MODE_10BIT_MASK) | dm;
+}
+
+static int vdec_size_scale(int length, int dec_mode)
+{
+ int ret = 64;
+ u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+ switch (dm) {
+ case DM_AVBC_ONLY: /* only afbc, output afbc */
+ ret = 64;
+ break;
+ case DM_YUV_1_1_AVBC: /* afbc and (w x h), output YUV420 */
+ ret = length;
+ break;
+ case DM_YUV_1_4_AVBC_A: /* afbc and (w/4 x h/4), output YUV420 */
+ case DM_YUV_1_4_AVBC_B: /* afbc and (w/4 x h/4), output afbc and YUV420 */
+ ret = length >> 2;
+ break;
+ case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
+ ret = length >> 1;
+ break;
+ case 0x8: /* afbc and (w/8 x h/8), output YUV420 */
+ ret = length >> 3;
+ break;
+ case 0x10: /* (w x h), output YUV420-8bit) */
+ default:
+ ret = length;
+ break;
+ }
+
+ return ret;
+}
+
+u32 vdec_get_plane_size(u32 w, u32 h, int dec_mode, int align)
+{
+ u32 dm = vdec_get_dec_mode(w, h, dec_mode);
+ u32 len = ALIGN(vdec_size_scale(w, dm), align) *
+ ALIGN(vdec_size_scale(h, dm), align);
+
+ return len << is_output_p010(dec_mode);
+}
diff --git a/drivers/amvdec_ports/utils/common.h b/drivers/amvdec_ports/utils/common.h
index 89ae50b..bbb2df4 100644
--- a/drivers/amvdec_ports/utils/common.h
+++ b/drivers/amvdec_ports/utils/common.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef UTILS_COMMON_H
#define UTILS_COMMON_H
@@ -58,7 +77,7 @@
#ifndef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
/**
* YUV colorspace type.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.3.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.3.
*/
enum AVColorSpace {
AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
@@ -82,7 +101,7 @@
/**
* Chromaticity coordinates of the source primaries.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.1.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.1.
*/
enum AVColorPrimaries {
AVCOL_PRI_RESERVED0 = 0,
@@ -106,7 +125,7 @@
/**
* Color Transfer Characteristic.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.2.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.2.
*/
enum AVColorTransferCharacteristic {
AVCOL_TRC_RESERVED0 = 0,
@@ -134,6 +153,35 @@
};
#endif
+#define VDEC_MODE_MMU_DW_MASK (0x20)
+#define VDEC_MODE_10BIT_MASK (0x10000)
+#define VDEC_MODE_DW_MASK (0xffff)
+
+enum vdec_dec_mode {
+ DM_INVALID = 0,
+ DM_AVBC_ONLY = 0,
+ DM_YUV_1_1_AVBC = 1,
+ DM_YUV_1_4_AVBC_A = 2,
+ DM_YUV_1_4_AVBC_B = 3,
+ DM_YUV_1_2_AVBC = 4,
+ DM_YUV_1_8_AVBC = 8,
+ DM_YUV_ONLY = 0x10,
+ DM_AVBC_1_1 = 0x21,
+ DM_AVBC_1_4 = 0x22,
+ DM_AVBC_1_2 = 0x24,
+ DM_YUV_AUTO_1_2_AVBC = 0x100,
+ DM_YUV_AUTO_1_4_AVBC = 0x200,
+ DM_YUV_AUTO_1_2_AVBC_B = 0x300,
+ /* (0~540] 1/1, (540~1080] 1/4, (1080~4K] 1/16 */
+ DM_YUV_AUTO_14_12_AVBC = 0x400,
+ DM_YUV_1_1_10BIT_AVBC = 0x10001,
+ DM_YUV_1_4_10BIT_AVBC = 0x10003,
+ DM_YUV_1_2_10BIT_AVBC = 0x10004,
+ DM_YUV_1_8_10BIT_AVBC = 0x10008,
+ /* (0~1080] 1/1, (1080~4K] 1/16 */
+ DM_YUV_14_11_10BIT_AVBC = 0x10200,
+};
+
//fmt
const char *av_color_space_name(enum AVColorSpace space);
const char *av_color_primaries_name(enum AVColorPrimaries primaries);
@@ -152,4 +200,13 @@
bool is_over_size(int w, int h, int size);
+u8 *aml_yuv_dump(struct file *fp, u8 *start_addr, u32 real_width, u32 real_height, u32 align);
+
+bool is_output_p010(u32 dec_mode);
+
+int vdec_get_size_ratio(int dec_mode);
+
+int vdec_get_dec_mode(u32 w, u32 h, int dec_mode);
+
+u32 vdec_get_plane_size(u32 w, u32 h, int dec_mode, int align);
#endif
\ No newline at end of file
diff --git a/drivers/amvdec_ports/utils/get_bits.h b/drivers/amvdec_ports/utils/get_bits.h
index bb98ebd..5d9f168 100644
--- a/drivers/amvdec_ports/utils/get_bits.h
+++ b/drivers/amvdec_ports/utils/get_bits.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVCODEC_GET_BITS_H
#define AVCODEC_GET_BITS_H
diff --git a/drivers/amvdec_ports/utils/golomb.c b/drivers/amvdec_ports/utils/golomb.c
index 21fcb6a..2033962 100644
--- a/drivers/amvdec_ports/utils/golomb.c
+++ b/drivers/amvdec_ports/utils/golomb.c
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/types.h>
diff --git a/drivers/amvdec_ports/utils/golomb.h b/drivers/amvdec_ports/utils/golomb.h
index d66c182..631dab7 100644
--- a/drivers/amvdec_ports/utils/golomb.h
+++ b/drivers/amvdec_ports/utils/golomb.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVCODEC_GOLOMB_H
#define AVCODEC_GOLOMB_H
diff --git a/drivers/amvdec_ports/utils/pixfmt.h b/drivers/amvdec_ports/utils/pixfmt.h
index f13411e..1a0e833 100644
--- a/drivers/amvdec_ports/utils/pixfmt.h
+++ b/drivers/amvdec_ports/utils/pixfmt.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVUTIL_PIXFMT_H
#define AVUTIL_PIXFMT_H
@@ -16,7 +35,7 @@
* then the chroma plane resolution must be rounded up.
*
* @par
- * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized
+ * When the pixel format is palette RGB32 (AV_PIX_FMT_PAL8), the palette
* image data is stored in AVFrame.data[0]. The palette is transported in
* AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
* formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is
diff --git a/drivers/amvdec_ports/utils/put_bits.h b/drivers/amvdec_ports/utils/put_bits.h
index 8b2aa15..11a6c94 100644
--- a/drivers/amvdec_ports/utils/put_bits.h
+++ b/drivers/amvdec_ports/utils/put_bits.h
@@ -1,3 +1,22 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVCODEC_PUT_BITS_H
#define AVCODEC_PUT_BITS_H
diff --git a/drivers/amvdec_ports/vdec_drv_base.h b/drivers/amvdec_ports/vdec_drv_base.h
index 990d406..ef0667e 100644
--- a/drivers/amvdec_ports/vdec_drv_base.h
+++ b/drivers/amvdec_ports/vdec_drv_base.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _VDEC_DRV_BASE_
#define _VDEC_DRV_BASE_
diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c
index 01510c5..ac48e41 100644
--- a/drivers/amvdec_ports/vdec_drv_if.c
+++ b/drivers/amvdec_ports/vdec_drv_if.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -24,6 +24,7 @@
#include "vdec_drv_if.h"
#include "aml_vcodec_dec.h"
#include "vdec_drv_base.h"
+#include "../frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h"
const struct vdec_common_if *get_h264_dec_comm_if(void);
const struct vdec_common_if *get_hevc_dec_comm_if(void);
@@ -32,6 +33,10 @@
const struct vdec_common_if *get_mpeg4_dec_comm_if(void);
const struct vdec_common_if *get_mjpeg_dec_comm_if(void);
const struct vdec_common_if *get_av1_dec_comm_if(void);
+const struct vdec_common_if *get_avs_dec_comm_if(void);
+const struct vdec_common_if *get_avs2_dec_comm_if(void);
+const struct vdec_common_if *get_avs3_dec_comm_if(void);
+const struct vdec_common_if *get_vc1_dec_comm_if(void);
int vdec_if_init(struct aml_vcodec_ctx *ctx, unsigned int fourcc)
{
@@ -61,6 +66,19 @@
case V4L2_PIX_FMT_AV1:
ctx->dec_if = get_av1_dec_comm_if();
break;
+ case V4L2_PIX_FMT_AVS:
+ ctx->dec_if = get_avs_dec_comm_if();
+ break;
+ case V4L2_PIX_FMT_AVS2:
+ ctx->dec_if = get_avs2_dec_comm_if();
+ break;
+ case V4L2_PIX_FMT_AVS3:
+ ctx->dec_if = get_avs3_dec_comm_if();
+ break;
+ case V4L2_PIX_FMT_VC1_ANNEX_L:
+ case V4L2_PIX_FMT_VC1_ANNEX_G:
+ ctx->dec_if = get_vc1_dec_comm_if();
+ break;
default:
return -EINVAL;
}
@@ -85,7 +103,7 @@
{
int ret = 0;
- if (bs) {
+ if (bs && (!ctx->stream_mode)) {
if ((bs->addr & 63) != 0) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"bs dma_addr should 64 byte align\n");
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index 29911f8..e837902 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef _VDEC_DRV_IF_H_
#define _VDEC_DRV_IF_H_
@@ -65,17 +65,6 @@
FB_ST_FREE
};
-enum vdec_dw_mode {
- VDEC_DW_AFBC_ONLY = 0,
- VDEC_DW_AFBC_1_1_DW = 1,
- VDEC_DW_AFBC_1_4_DW = 2,
- VDEC_DW_AFBC_x2_1_4_DW = 3,
- VDEC_DW_AFBC_1_2_DW = 4,
- VDEC_DW_NO_AFBC = 16,
- VDEC_DW_AFBC_AUTO_1_2 = 0x100,
- VDEC_DW_AFBC_AUTO_1_4 = 0x200,
-};
-
/*
* the caller does not own the returned buffer. The buffer will not be
* released before vdec_if_deinit.
@@ -91,7 +80,10 @@
GET_PARAM_DPB_SIZE,
GET_PARAM_CONFIG_INFO,
GET_PARAM_DW_MODE,
- GET_PARAM_COMP_BUF_INFO
+ GET_PARAM_COMP_BUF_INFO,
+ GET_PARAM_CFG_INFO,
+ GET_PARAM_TW_MODE,
+ GET_PARAM_TIME_STAMP
};
/*
@@ -104,7 +96,8 @@
SET_PARAM_HDR_INFO,
SET_PARAM_POST_EVENT,
SET_PARAM_PIC_INFO,
- SET_PARAM_CFG_INFO
+ SET_PARAM_CFG_INFO,
+ SET_PARAM_INST_RESET
};
/**
diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c
index 158e32c..fa1cba0 100644
--- a/drivers/common/chips/chips.c
+++ b/drivers/common/chips/chips.c
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/chips/chips.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -30,7 +32,6 @@
#include "../../frame_provider/decoder/utils/vdec.h"
#include "chips.h"
#include <linux/amlogic/media/utils/log.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
#include "decoder_cpu_ver_info.h"
#define VIDEO_FIRMWARE_FATHER_NAME "video"
@@ -86,6 +87,12 @@
{AM_MESON_CPU_MAJOR_ID_P1, "p1"},
{AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
{AM_MESON_CPU_MAJOR_ID_T5W, "t5w"},
+ {AM_MESON_CPU_MAJOR_ID_S5, "s5"},
+ {AM_MESON_CPU_MAJOR_ID_GXLX3, "gxlx3"},
+ {AM_MESON_CPU_MAJOR_ID_T5M, "t5m"},
+ {AM_MESON_CPU_MAJOR_ID_T3X, "t3x"},
+ {AM_MESON_CPU_MAJOR_ID_TXHD2, "txhd2"},
+ {AM_MESON_CPU_MAJOR_ID_S1A, "s1a"},
{0, NULL},
};
@@ -134,7 +141,9 @@
* VFORMAT_H264_ENC,
* VFORMAT_JPEG_ENC,
* VFORMAT_VP9,
-* VFORMAT_AVS2,
+ * VFORMAT_AVS2,
+ * VFORMAT_AV1,
+ * VFORMAT_AVS3,
* VFORMAT_MAX
*};
*/
@@ -156,6 +165,7 @@
{VFORMAT_VP9, "vp9"},
{VFORMAT_AVS2, "avs2"},
{VFORMAT_AV1, "av1"},
+ {VFORMAT_AVS3, "avs3"},
{VFORMAT_YUV, "yuv"},
{0, NULL},
};
diff --git a/drivers/common/chips/chips.h b/drivers/common/chips/chips.h
index 003e9d2..dd6b3a2 100644
--- a/drivers/common/chips/chips.h
+++ b/drivers/common/chips/chips.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/chips/chips.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef UCODE_MANAGER_HEADER
#define UCODE_MANAGER_HEADER
#include "../media_clock/clk/clk_priv.h"
diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c
index af162b8..13acb1e 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.c
+++ b/drivers/common/chips/decoder_cpu_ver_info.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -26,215 +26,683 @@
#include <linux/of_device.h>
#include <linux/amlogic/media/registers/cpu_version.h>
#include "decoder_cpu_ver_info.h"
+#include "../register/register.h"
-#define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
-#define AM_SUCESS 0
+#define AM_SUCCESS 0
#define MAJOR_ID_START AM_MESON_CPU_MAJOR_ID_M6
static enum AM_MESON_CPU_MAJOR_ID cpu_ver_id = AM_MESON_CPU_MAJOR_ID_MAX;
+
static int cpu_sub_id = 0;
-static enum AM_MESON_CPU_MAJOR_ID cpu_ver_info[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START]=
-{
- AM_MESON_CPU_MAJOR_ID_M6,
- AM_MESON_CPU_MAJOR_ID_M6TV,
- AM_MESON_CPU_MAJOR_ID_M6TVL,
- AM_MESON_CPU_MAJOR_ID_M8,
- AM_MESON_CPU_MAJOR_ID_MTVD,
- AM_MESON_CPU_MAJOR_ID_M8B,
- AM_MESON_CPU_MAJOR_ID_MG9TV,
- AM_MESON_CPU_MAJOR_ID_M8M2,
- AM_MESON_CPU_MAJOR_ID_UNUSE,
- AM_MESON_CPU_MAJOR_ID_GXBB,
- AM_MESON_CPU_MAJOR_ID_GXTVBB,
- AM_MESON_CPU_MAJOR_ID_GXL,
- AM_MESON_CPU_MAJOR_ID_GXM,
- AM_MESON_CPU_MAJOR_ID_TXL,
- AM_MESON_CPU_MAJOR_ID_TXLX,
- AM_MESON_CPU_MAJOR_ID_AXG,
- AM_MESON_CPU_MAJOR_ID_GXLX,
- AM_MESON_CPU_MAJOR_ID_TXHD,
- AM_MESON_CPU_MAJOR_ID_G12A,
- AM_MESON_CPU_MAJOR_ID_G12B,
- AM_MESON_CPU_MAJOR_ID_GXLX2,
- AM_MESON_CPU_MAJOR_ID_SM1,
- AM_MESON_CPU_MAJOR_ID_A1,
- AM_MESON_CPU_MAJOR_ID_RES_0x2d,
- AM_MESON_CPU_MAJOR_ID_TL1,
- AM_MESON_CPU_MAJOR_ID_TM2,
- AM_MESON_CPU_MAJOR_ID_C1,
- AM_MESON_CPU_MAJOR_ID_RES_0x31,
- AM_MESON_CPU_MAJOR_ID_SC2,
- AM_MESON_CPU_MAJOR_ID_C2,
- AM_MESON_CPU_MAJOR_ID_T5,
- AM_MESON_CPU_MAJOR_ID_T5D,
- AM_MESON_CPU_MAJOR_ID_T7,
- AM_MESON_CPU_MAJOR_ID_S4,
- AM_MESON_CPU_MAJOR_ID_T3,
- AM_MESON_CPU_MAJOR_ID_P1,
- AM_MESON_CPU_MAJOR_ID_S4D,
- AM_MESON_CPU_MAJOR_ID_T5W,
+static bool codec_dos_dev = 0; //to compat old dts
+
+static struct dos_of_dev_s *platform_dos_dev = NULL;
+
+static struct dos_of_dev_s dos_dev_data[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START] = {
+ [AM_MESON_CPU_MAJOR_ID_M8B - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_M8B,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = false,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_1080P,
+ .hevc_max_resolution = RESOLUTION_1080P,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_GXL,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_G12A,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667, //hevcb clk must be same with hevcf in g12a
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_G12B - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_G12B,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_GXLX2 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_GXLX2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_SM1,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K, //support 8kp24
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_TL1,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K, //support 8kp24
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_TM2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_C1,
+ .reg_compat = NULL,
+ .is_vdec_canvas_support = true,
+ .fmt_support_flags = FMT_JPEG_ENC,
+ },
+
+
+ [AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_SC2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T5,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K, //unsupport vp9 & av1
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_AVS2,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T5D,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 667,
+ .max_hevcb_clock = 667,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_1080P,
+ .hevc_max_resolution = RESOLUTION_1080P, //unsupport 4k and avs2
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T7,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .is_support_axi_ctrl = true,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_S4,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T3,
+ .reg_compat = t3_mm_registers_compat,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .is_support_rdma = true,
+ .is_support_mmu_copy = true,
+ .is_support_axi_ctrl = true,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K, //8kp30, rdma, mmu copy
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_S4D,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T5W,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_S5,
+ .reg_compat = s5_mm_registers_compat, //register compact
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = true,
+ .is_support_axi_ctrl = true,
+ .hevc_stream_extra_shift = 8,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T5M,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .is_support_axi_ctrl = true,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_4K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_T3X,
+ .reg_compat = s5_mm_registers_compat, //register compact
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .is_support_rdma = true,
+ .is_support_axi_ctrl = true,
+ .hevc_stream_extra_shift = 8,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_TXHD2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 500,
+ .max_hevcb_clock = 500,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_1080P,
+ .hevc_max_resolution = RESOLUTION_4K, //unsupport avs2,av1
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
+ },
+
+ [AM_MESON_CPU_MAJOR_ID_S1A - MAJOR_ID_START] = {
+ .chip_id = AM_MESON_CPU_MAJOR_ID_S1A,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 500,
+ .max_hevcb_clock = 500,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = false,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_1080P,
+ .hevc_max_resolution = RESOLUTION_1080P,
+ .fmt_support_flags = FMT_HEVC | FMT_H264 | FMT_MPEG2 | FMT_MPEG4 | FMT_VC1,
+ },
};
+/* sub id features */
+static struct dos_of_dev_s dos_dev_sub_table[] = {
+ { /* g12b revb */
+ .chip_id = AM_MESON_CPU_MINOR_ID_REVB_G12B,
+ .reg_compat = NULL,
+ .max_vdec_clock = 667,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800, //g12b revb hevc clk support 800mhz
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+ },
+
+ { /* tm2 revb */
+ .chip_id = AM_MESON_CPU_MINOR_ID_REVB_TM2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = true,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ {
+ .chip_id = AM_MESON_CPU_MINOR_ID_S4_S805X2,
+ .reg_compat = NULL,
+ .max_vdec_clock = 500,
+ .max_hevcf_clock = 500,
+ .max_hevcb_clock = 500,
+ .hevc_clk_combine_flag = true,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = false,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .vdec_max_resolution = RESOLUTION_1080P,
+ .hevc_max_resolution = RESOLUTION_1080P,
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ },
+
+ {
+ .chip_id = AM_MESON_CPU_MINOR_ID_T7C,
+ .reg_compat = NULL,
+ .max_vdec_clock = 800,
+ .max_hevcf_clock = 800,
+ .max_hevcb_clock = 800,
+ .hevc_clk_combine_flag = false,
+ .is_hw_parser_support = false,
+ .is_vdec_canvas_support = true,
+ .is_support_h264_mmu = true,
+ .is_support_dual_core = false,
+ .is_support_axi_ctrl = true,
+ .vdec_max_resolution = RESOLUTION_4K,
+ .hevc_max_resolution = RESOLUTION_8K, //fixed endian issue
+ .fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+ }
+};
+
+/* dos device match table */
static const struct of_device_id cpu_ver_of_match[] = {
{
.compatible = "amlogic, cpu-major-id-axg",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_AXG - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_AXG - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-g12a",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-gxl",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-gxm",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_GXM - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXM - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-txl",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TXL - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXL - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-txlx",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TXLX - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXLX - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-sm1",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-tl1",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-tm2",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-c1",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-sc2",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5d",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t7",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s4",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t3",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-p1",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_P1 - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_P1 - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-s4d",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START],
},
{
.compatible = "amlogic, cpu-major-id-t5w",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-s5",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-t5m",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-t3x",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-txhd2",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START],
+ },
+ {
+ .compatible = "amlogic, cpu-major-id-s1a",
+ .data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S1A - MAJOR_ID_START],
},
{},
};
-static const int cpu_sub_info[] = {
- AM_MESON_CPU_MINOR_ID_REVB_G12B,
- AM_MESON_CPU_MINOR_ID_REVB_TM2,
- AM_MESON_CPU_MINOR_ID_S4_S805X2,
-};
-
static const struct of_device_id cpu_sub_id_of_match[] = {
{
.compatible = "amlogic, cpu-major-id-g12b-b",
- .data = &cpu_sub_info[0],
+ .data = &dos_dev_sub_table[0],
},
{
.compatible = "amlogic, cpu-major-id-tm2-b",
- .data = &cpu_sub_info[1],
+ .data = &dos_dev_sub_table[1],
},
{
.compatible = "amlogic, cpu-major-id-s4-805x2",
- .data = &cpu_sub_info[2],
+ .data = &dos_dev_sub_table[2],
},
+ {
+ .compatible = "amlogic, cpu-major-id-t7c",
+ .data = &dos_dev_sub_table[3],
+ },
+ {}
};
-static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pid_type, int *sub_id)
+static struct platform_device *get_dos_dev_from_dtb(void)
{
struct device_node *pnode = NULL;
- struct platform_device *pdev = NULL;
- const struct of_device_id *pmatch = NULL;
- pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
- if (NULL == pnode) {
- pr_err("No find node.\n");
- return -EINVAL;
+ pnode = of_find_node_by_name(NULL, CODEC_DOS_DEV_ID_NODE_NAME);
+ if (pnode == NULL) {
+ codec_dos_dev = false;
+ pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+ if (pnode == NULL) {
+ pr_err("No find node.\n");
+ return NULL;
+ }
+ } else {
+ codec_dos_dev = true;
}
- pdev = of_find_device_by_node(pnode);
- if (NULL == pdev)
- return -EINVAL;
+ return of_find_device_by_node(pnode);
+}
+
+static struct dos_of_dev_s * get_dos_of_dev_data(struct platform_device *pdev)
+{
+ const struct of_device_id *pmatch = NULL;
+
+ if (pdev == NULL)
+ return NULL;
pmatch = of_match_device(cpu_ver_of_match, &pdev->dev);
if (NULL == pmatch) {
pmatch = of_match_device(cpu_sub_id_of_match, &pdev->dev);
if (NULL == pmatch) {
pr_err("No find of_match_device\n");
- return -EINVAL;
+ return NULL;
}
}
- *pid_type = (enum AM_MESON_CPU_MAJOR_ID)(*(int *)pmatch->data) & (MAJOY_ID_MASK);
-
- *sub_id = ((*(int *)pmatch->data) & (SUB_ID_MASK)) >> 8;
-
- return AM_SUCESS;
+ return (struct dos_of_dev_s *)pmatch->data;
}
-static void initial_cpu_id(void)
+/* dos to get platform data */
+static int dos_device_search_data(int id, int sub_id)
{
- enum AM_MESON_CPU_MAJOR_ID id_type = AM_MESON_CPU_MAJOR_ID_MAX;
- int sub_id = 0;
+ int i, j;
+ int sub_dev_id;
- if (AM_SUCESS == get_cpu_id_from_dtb(&id_type, &sub_id)) {
- cpu_ver_id = id_type;
- cpu_sub_id = sub_id;
+ for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
+ if (id == dos_dev_data[i].chip_id) {
+ platform_dos_dev = &dos_dev_data[i];
+ pr_info("%s, get major %d dos dev data success\n", __func__, i);
+
+ if (sub_id) {
+ for (j = 0; j < ARRAY_SIZE(dos_dev_sub_table); j++) {
+ if (id == (dos_dev_sub_table[j].chip_id & MAJOR_ID_MASK)) {
+ sub_dev_id = (dos_dev_sub_table[j].chip_id & SUB_ID_MASK) >> 8;
+ if (sub_id == sub_dev_id) {
+ platform_dos_dev = &dos_dev_sub_table[j];
+ pr_info("%s, get sub %d dos dev data success\n", __func__, j);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (platform_dos_dev)
+ return 0;
+ else
+ return -ENODEV;
+}
+
+struct platform_device *initial_dos_device(void)
+{
+ struct platform_device *pdev = NULL;
+ struct dos_of_dev_s *of_dev_data;
+
+ pdev = get_dos_dev_from_dtb();
+
+ of_dev_data = get_dos_of_dev_data(pdev);
+
+ if (of_dev_data) {
+ cpu_ver_id = of_dev_data->chip_id & MAJOY_ID_MASK;
+ cpu_sub_id = (of_dev_data->chip_id & SUB_ID_MASK) >> 8;
+ platform_dos_dev = of_dev_data;
} else {
cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type();
- cpu_sub_id = (is_meson_rev_b()) ? CHIP_REVB : CHIP_REVA;
- }
+ cpu_sub_id = is_meson_rev_b() ? CHIP_REVB :
+ (is_meson_rev_c() ? CHIP_REVC : CHIP_REVA);
- if ((AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) && (CHIP_REVB == cpu_sub_id))
+ pr_info("get dos dev failed, id %d(%d), try to search\n",
+ cpu_ver_id, cpu_sub_id);
+
+ if (dos_device_search_data(cpu_ver_id, cpu_sub_id) < 0) {
+ pr_err("get dos device failed, dos maybe out of work\n");
+ //return NULL;
+ }
+ }
+ if ((cpu_ver_id == AM_MESON_CPU_MAJOR_ID_G12B) &&
+ (cpu_sub_id == CHIP_REVB))
cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
- pr_info("vdec init cpu id: 0x%x(%d)", cpu_ver_id, cpu_sub_id);
+ if (pdev && of_dev_data)
+ dos_register_probe(pdev, of_dev_data->reg_compat);
+
+ pr_info("initial_dos_device end, chip %d(%d)\n",
+ cpu_ver_id, cpu_sub_id);
+
+ return pdev;
}
+EXPORT_SYMBOL(initial_dos_device);
enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void)
{
if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
- initial_cpu_id();
+ initial_dos_device();
return cpu_ver_id;
}
@@ -249,7 +717,7 @@
bool is_cpu_meson_revb(void)
{
if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
- initial_cpu_id();
+ initial_dos_device();
return (cpu_sub_id == CHIP_REVB);
}
@@ -269,3 +737,260 @@
}
EXPORT_SYMBOL(is_cpu_s4_s805x2);
+bool is_cpu_t7(void)
+{
+ return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
+ && (get_cpu_sub_id() != CHIP_REVC));
+}
+EXPORT_SYMBOL(is_cpu_t7);
+
+bool is_cpu_t7c(void)
+{
+ return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
+ && (get_cpu_sub_id() == CHIP_REVC));
+}
+EXPORT_SYMBOL(is_cpu_t7c);
+
+/*
+ feature from dos dev functions
+*/
+/*
+bit0: force support no_parser;
+bit1: force support all video format;
+*/
+#define FORCE_VDEC_NO_PARSER BIT(0)
+#define FORCE_VDEC_SUPPORT_FMT BIT(1)
+static u32 force_dos_support;
+
+inline bool is_hevc_align32(int blkmod)
+{
+ if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S1A) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(is_hevc_align32);
+
+inline bool is_support_new_dos_dev(void)
+{
+ return codec_dos_dev;
+}
+EXPORT_SYMBOL(is_support_new_dos_dev);
+
+inline struct dos_of_dev_s *dos_dev_get(void)
+{
+ return platform_dos_dev;
+}
+EXPORT_SYMBOL(dos_dev_get);
+
+
+/* vdec & hevc clock */
+inline u32 vdec_max_clk_get(void)
+{
+ return platform_dos_dev->max_vdec_clock;
+}
+EXPORT_SYMBOL(vdec_max_clk_get);
+
+inline u32 hevcf_max_clk_get(void)
+{
+ return platform_dos_dev->max_hevcf_clock;
+}
+EXPORT_SYMBOL(hevcf_max_clk_get);
+
+inline u32 hevcb_max_clk_get(void)
+{
+ return platform_dos_dev->max_hevcb_clock;
+}
+EXPORT_SYMBOL(hevcb_max_clk_get);
+
+inline bool is_hevc_clk_combined(void)
+{
+ return (platform_dos_dev->hevc_clk_combine_flag);
+}
+EXPORT_SYMBOL(is_hevc_clk_combined);
+
+/* ressolution */
+inline int vdec_is_support_4k(void)
+{
+ if (platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P)
+ return true;
+ else
+ return false;
+}
+EXPORT_SYMBOL(vdec_is_support_4k);
+
+inline int hevc_is_support_4k(void)
+{
+ if (platform_dos_dev->hevc_max_resolution > RESOLUTION_1080P)
+ return true;
+ else
+ return false;
+}
+EXPORT_SYMBOL(hevc_is_support_4k);
+
+inline int hevc_is_support_8k(void)
+{
+ if (platform_dos_dev->hevc_max_resolution > RESOLUTION_4K)
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(hevc_is_support_8k);
+
+inline bool is_oversize_vdec(int w, int h)
+{
+ if (w < 0 || h < 0)
+ return true;
+
+ if (h != 0 && (w > platform_dos_dev->vdec_max_resolution / h))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(is_oversize_vdec);
+
+inline bool is_oversize_hevc(int w, int h)
+{
+ if (w < 0 || h < 0)
+ return true;
+
+ if (h != 0 && (w > platform_dos_dev->hevc_max_resolution / h))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(is_oversize_hevc);
+
+inline bool is_support_no_parser(void)
+{
+ return ((force_dos_support & FORCE_VDEC_NO_PARSER) ||
+ (!platform_dos_dev->is_hw_parser_support));
+}
+EXPORT_SYMBOL(is_support_no_parser);
+
+/* vdec intra canvas feature */
+inline bool is_support_vdec_canvas(void)
+{
+ return (platform_dos_dev->is_vdec_canvas_support);
+}
+EXPORT_SYMBOL(is_support_vdec_canvas);
+
+inline bool is_support_dual_core(void)
+{
+ return (platform_dos_dev->is_support_dual_core);
+}
+EXPORT_SYMBOL(is_support_dual_core);
+
+inline bool is_support_p010_mode(void)
+{
+ return (platform_dos_dev->is_support_p010);
+}
+EXPORT_SYMBOL(is_support_p010_mode);
+
+inline bool is_support_triple_write(void)
+{
+ return (platform_dos_dev->is_support_triple_write);
+}
+EXPORT_SYMBOL(is_support_triple_write);
+
+inline bool is_support_rdma(void)
+{
+ return (platform_dos_dev->is_support_rdma);
+}
+EXPORT_SYMBOL(is_support_rdma);
+
+inline bool is_support_mmu_copy(void)
+{
+ return (platform_dos_dev->is_support_mmu_copy);
+}
+EXPORT_SYMBOL(is_support_mmu_copy);
+
+inline bool is_support_axi_ctrl(void)
+{
+ return platform_dos_dev->is_support_axi_ctrl;
+}
+EXPORT_SYMBOL(is_support_axi_ctrl);
+
+inline bool is_support_format(int format)
+{
+ if ((platform_dos_dev->fmt_support_flags == 0) ||
+ (force_dos_support & FORCE_VDEC_SUPPORT_FMT))
+ return true;
+
+ return ((1 << format) &
+ platform_dos_dev->fmt_support_flags);
+}
+EXPORT_SYMBOL(is_support_format);
+
+inline int get_hevc_stream_extra_shift_bytes(void)
+{
+ return platform_dos_dev->hevc_stream_extra_shift;
+}
+EXPORT_SYMBOL(get_hevc_stream_extra_shift_bytes);
+
+void pr_dos_infos(void)
+{
+ pr_info("dos device info:\n");
+ pr_info("chip id: 0x%x(0x%x)\n", cpu_ver_id, cpu_sub_id);
+
+ pr_info("max vdec clock: %03d MHz\n", vdec_max_clk_get());
+ pr_info("max hevcf clock: %03d MHz\n", hevcf_max_clk_get());
+ if (!is_hevc_clk_combined()) {
+ pr_info("max hevcb clock: %03d MHz\n", hevcb_max_clk_get());
+ }
+
+ pr_info("max vdec resolution : %s\n",
+ platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P ? "4K":"1080P");
+ pr_info("max hevc resolution : %s\n",
+ platform_dos_dev->hevc_max_resolution < RESOLUTION_4K ? "1080P" :
+ (platform_dos_dev->hevc_max_resolution > RESOLUTION_4K ? "8K":"4K"));
+
+ pr_info("support no parser : %d\n", is_support_no_parser());
+ pr_info("support vdec canvas : %d\n", is_support_vdec_canvas());
+ pr_info("support dual core : %d\n", is_support_dual_core());
+ pr_info("support p010 mode : %d\n", is_support_p010_mode());
+ pr_info("support triple write: %d\n", is_support_triple_write());
+ pr_info("support rdma : %d\n", is_support_rdma());
+ pr_info("support mmu copy : %d\n", is_support_mmu_copy());
+ pr_info("support dos axi ctrl: %d\n", is_support_axi_ctrl());
+ pr_info("support format : 0x%x\n", platform_dos_dev->fmt_support_flags);
+ pr_info("hevc_stream_extra_shift_bytes: %d\n", get_hevc_stream_extra_shift_bytes());
+}
+EXPORT_SYMBOL(pr_dos_infos);
+
+void dos_info_debug(void)
+{
+ int i;
+ struct dos_of_dev_s *save = platform_dos_dev;
+ int save_major_id = cpu_ver_id;
+ int save_sub_id = cpu_sub_id;
+
+ for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
+ platform_dos_dev = &dos_dev_data[i];
+ if (platform_dos_dev->chip_id) {
+ cpu_ver_id = platform_dos_dev->chip_id;
+ pr_dos_infos();
+ pr_info("\n");
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(dos_dev_sub_table); i++) {
+ platform_dos_dev = &dos_dev_sub_table[i];
+ if (platform_dos_dev->chip_id) {
+ cpu_ver_id = platform_dos_dev->chip_id & MAJOR_ID_MASK;
+ cpu_sub_id = (platform_dos_dev->chip_id & SUB_ID_MASK) >> 8;
+ pr_dos_infos();
+ pr_info("\n");
+ }
+ }
+
+ platform_dos_dev = save;
+ cpu_ver_id = save_major_id;
+ cpu_sub_id = save_sub_id;
+}
+EXPORT_SYMBOL(dos_info_debug);
+
+
+module_param(force_dos_support, uint, 0664);
+
diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h
index 6129244..eaf58c9 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.h
+++ b/drivers/common/chips/decoder_cpu_ver_info.h
@@ -1,28 +1,35 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef DECODER_CPU_VER_INFO_H
#define DECODER_CPU_VER_INFO_H
+#include <linux/platform_device.h>
#include <linux/amlogic/media/registers/cpu_version.h>
+#include "../register/register.h"
+#include <linux/amlogic/media/utils/vformat.h>
+
/* majoy chip id define */
#define MAJOY_ID_MASK (0x000000ff)
+#define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
+#define CODEC_DOS_DEV_ID_NODE_NAME "vcodec_dos_dev"
+
enum AM_MESON_CPU_MAJOR_ID {
AM_MESON_CPU_MAJOR_ID_M6 = 0x16,
AM_MESON_CPU_MAJOR_ID_M6TV = 0x17,
@@ -62,6 +69,14 @@
AM_MESON_CPU_MAJOR_ID_P1 = 0x39,
AM_MESON_CPU_MAJOR_ID_S4D = 0x3a,
AM_MESON_CPU_MAJOR_ID_T5W = 0x3b,
+ AM_MESON_CPU_MAJOR_ID_C3 = 0x3c,
+ AM_MESON_CPU_MAJOR_ID_S5 = 0x3e,
+ AM_MESON_CPU_MAJOR_ID_GXLX3 = 0x3f,
+ AM_MESON_CPU_MAJOR_ID_T5M = 0x41,
+ AM_MESON_CPU_MAJOR_ID_T3X = 0x42,
+ AM_MESON_CPU_MAJOR_ID_RES_0x43,
+ AM_MESON_CPU_MAJOR_ID_TXHD2 = 0x44,
+ AM_MESON_CPU_MAJOR_ID_S1A = 0x45,
AM_MESON_CPU_MAJOR_ID_MAX,
};
@@ -75,13 +90,88 @@
#define REVC_MASK (CHIP_REVC << 8)
#define REVX_MASK (CHIP_REVX << 8)
+#define MAJOR_ID_MASK 0xFF
#define SUB_ID_MASK (REVB_MASK | REVC_MASK | REVX_MASK)
-#define AM_MESON_CPU_MINOR_ID_REVB_G12B (REVB_MASK | AM_MESON_CPU_MAJOR_ID_G12B)
+#define AM_MESON_CPU_MINOR_ID_REVB_G12B (REVB_MASK | AM_MESON_CPU_MAJOR_ID_G12B)
#define AM_MESON_CPU_MINOR_ID_REVB_TM2 (REVB_MASK | AM_MESON_CPU_MAJOR_ID_TM2)
#define AM_MESON_CPU_MINOR_ID_S4_S805X2 (REVX_MASK | AM_MESON_CPU_MAJOR_ID_S4)
+#define AM_MESON_CPU_MINOR_ID_T7C (REVC_MASK | AM_MESON_CPU_MAJOR_ID_T7)
+
+/* for dos_of_dev_s max resolution define */
+#define RESOLUTION_1080P (1920 * 1088)
+#define RESOLUTION_4K (4302 * 2176) //4k
+#define RESOLUTION_8K (8192 * 4352) //8k
+
+/* fmt_support */
+//vdec
+#define FMT_MPEG2 BIT(VFORMAT_MPEG12)
+#define FMT_MPEG4 BIT(VFORMAT_MPEG4)
+#define FMT_H264 BIT(VFORMAT_H264)
+#define FMT_MJPEG BIT(VFORMAT_MJPEG)
+#define FMT_VC1 BIT(VFORMAT_VC1)
+#define FMT_AVS BIT(VFORMAT_AVS)
+#define FMT_MVC BIT(VFORMAT_H264MVC)
+//hevc
+#define FMT_HEVC BIT(VFORMAT_HEVC)
+#define FMT_VP9 BIT(VFORMAT_VP9)
+#define FMT_AVS2 BIT(VFORMAT_AVS2)
+#define FMT_AV1 BIT(VFORMAT_AV1)
+#define FMT_AVS3 BIT(VFORMAT_AVS3)
+//hcodec
+#define FMT_H264_ENC BIT(VFORMAT_H264_ENC)
+#define FMT_JPEG_ENC BIT(VFORMAT_JPEG_ENC)
+
+//frequently-used combination
+#define FMT_VDEC_ALL (FMT_MPEG2 | FMT_MPEG4 | FMT_H264 | FMT_MJPEG | FMT_VC1 | FMT_MVC | FMT_AVS)
+#define FMT_VDEC_NO_AVS (FMT_MPEG2 | FMT_MPEG4 | FMT_H264 | FMT_MJPEG | FMT_VC1 | FMT_MVC)
+
+#define FMT_HEVC_VP9_AV1 (FMT_HEVC | FMT_VP9 | FMT_AV1)
+#define FMT_HEVC_VP9_AVS2 (FMT_HEVC | FMT_VP9 | FMT_AVS2)
+#define FMT_HEVC_VP9_AVS2_AV1 (FMT_AV1 | FMT_HEVC_VP9_AVS2)
+#define FMT_HEVC_VP9_AVS2_AV1_AVS3 (FMT_AVS3 | FMT_HEVC_VP9_AVS2_AV1)
+
+/* dos hardware feature define. */
+struct dos_of_dev_s {
+ enum AM_MESON_CPU_MAJOR_ID chip_id;
+
+ /* register*/
+ reg_compat_func reg_compat;
+
+ /* clock, Mhz. necessary!! */
+ u32 max_vdec_clock;
+ u32 max_hevcf_clock;
+ u32 max_hevcb_clock;
+ bool hevc_clk_combine_flag;
+
+ /* resolution. necessary!! */
+ u32 vdec_max_resolution; //just for h264
+ u32 hevc_max_resolution;
+
+ /* esparser */
+ bool is_hw_parser_support;
+
+ /* vdec */
+ bool is_vdec_canvas_support;
+ bool is_support_h264_mmu;
+
+ /* hevc */
+ bool is_support_dual_core;
+ bool is_support_p010;
+ bool is_support_triple_write;
+ bool is_support_rdma;
+ bool is_support_mmu_copy;
+ int hevc_stream_extra_shift;
+
+ bool is_support_axi_ctrl; /*dos pipeline ctrl by dos or dmc */
+
+ u32 fmt_support_flags;
+};
+
/* export functions */
+struct platform_device *initial_dos_device(void);
+
enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void);
bool is_cpu_meson_revb(void);
@@ -92,4 +182,58 @@
bool is_cpu_s4_s805x2(void);
+bool is_cpu_t7(void);
+bool is_cpu_t7c(void);
+
+inline bool is_support_new_dos_dev(void);
+
+struct dos_of_dev_s *dos_dev_get(void);
+
+inline bool is_hevc_align32(int blkmod);
+
+/* clk get */
+inline u32 vdec_max_clk_get(void);
+
+inline u32 hevcf_max_clk_get(void);
+
+inline u32 hevcb_max_clk_get(void);
+
+inline bool is_hevc_clk_combined(void);
+
+/* resolution check */
+inline int vdec_is_support_4k(void);
+
+inline int hevc_is_support_4k(void);
+
+inline int hevc_is_support_8k(void);
+
+inline bool is_oversize_vdec(int w, int h);
+
+inline bool is_oversize_hevc(int w, int h);
+
+/* hardware features */
+inline bool is_support_no_parser(void);
+
+inline bool is_support_vdec_canvas(void);
+
+inline bool is_support_dual_core(void);
+
+inline bool is_support_p010_mode(void);
+
+inline bool is_support_triple_write(void);
+
+inline bool is_support_rdma(void);
+
+inline bool is_support_mmu_copy(void);
+
+inline bool is_support_axi_ctrl(void);
+
+inline bool is_support_format(int format);
+
+inline int get_hevc_stream_extra_shift_bytes(void);
+
+void pr_dos_infos(void);
+
+void dos_info_debug(void);
+
#endif
diff --git a/drivers/common/firmware/Makefile b/drivers/common/firmware/Makefile
index 748039c..8b7ef6b 100644
--- a/drivers/common/firmware/Makefile
+++ b/drivers/common/firmware/Makefile
@@ -1,3 +1,14 @@
-obj-m += firmware.o
-firmware-objs += firmware_drv.o
-firmware-objs += firmware_type.o
+MODULE_NAME = firmware
+obj-m = $(MODULE_NAME).o
+$(MODULE_NAME)-y += firmware_drv.o
+$(MODULE_NAME)-y += firmware_type.o
+ifeq (${VERSION},5)
+ifeq (${PATCHLEVEL},15)
+ $(MODULE_NAME)-y += ../media_utils/media_utils_dummy.o
+else
+ $(MODULE_NAME)-y += ../media_utils/media_utils.o
+endif
+endif
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)= \"[$(PR_FMT)]: \" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/common/firmware/firmware_cfg.h b/drivers/common/firmware/firmware_cfg.h
index e23ac2a..342a3a2 100644
--- a/drivers/common/firmware/firmware_cfg.h
+++ b/drivers/common/firmware/firmware_cfg.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/firmware/firmware_cfg.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
/*all firmwares in one bin.*/
{VIDEO_MISC, VIDEO_PACKAGE, "video_ucode.bin"},
diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c
index 9422198..4ec161c 100644
--- a/drivers/common/firmware/firmware_drv.c
+++ b/drivers/common/firmware/firmware_drv.c
@@ -1,7 +1,5 @@
-/*
- * drivers/amlogic/media/common/firmware/firmware.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ /*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,6 +11,11 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
#include <linux/kernel.h>
#include <linux/module.h>
@@ -23,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/media/registers/cpu_version.h>
@@ -33,20 +37,30 @@
#include <linux/string.h>
#include <linux/amlogic/media/utils/log.h>
#include <linux/firmware.h>
-#include <linux/amlogic/tee.h>
-//#include <linux/amlogic/major.h> //if kernel is 4.9 then use this one
+#include <linux/version.h>
+#if LINUX_VERSION_CODE == KERNEL_VERSION(5, 4, 0)
#include <uapi/linux/major.h>
+#else
+#include <linux/amlogic/major.h> //if kernel is 4.9 then use this one
+#endif
#include <linux/cdev.h>
#include <linux/crc32.h>
#include "../chips/decoder_cpu_ver_info.h"
+#if !IS_ENABLED(CONFIG_AMLOGIC_TEE) && \
+ !IS_ENABLED(CONFIG_AMLOGIC_TEE_MODULE)
+static inline bool tee_enabled(void) { return false; }
+#else
+#include <linux/amlogic/tee.h>
+#endif
+
/* major.minor */
-#define PACK_VERS "v0.3"
+#define PACK_VERS "v0.4"
#define CLASS_NAME "firmware_codec"
#define DEV_NAME "firmware_vdec"
#define DIR "video"
-#define FRIMWARE_SIZE (64 * 1024) /*64k*/
+#define FIRMWARE_SIZE (64 * 1024) /*64k*/
#define BUFF_SIZE (1024 * 1024 * 2)
#define FW_LOAD_FORCE (0x1)
@@ -59,6 +73,7 @@
#define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K')
#define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E')
+#define NEWP ('N' << 24 | 'E' << 16 | 'W' << 8 | 'P')
#ifndef FIRMWARE_MAJOR
#define FIRMWARE_MAJOR AMSTREAM_MAJOR
@@ -80,6 +95,39 @@
static u32 debug;
static u32 detail;
+static bool new_package = false;
+
+bool fw_tee_enabled(void)
+{
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S1A)
+ return false;
+
+ return tee_enabled();
+}
+EXPORT_SYMBOL(fw_tee_enabled);
+
+extern unsigned long long g_fw_mask;
+void fw_get_format_from_dtb(void)
+{
+ struct device_node *pnode = NULL;
+ u32 ret;
+
+ pnode = of_find_node_by_name(NULL, CODEC_DOS_DEV_ID_NODE_NAME);
+ if (!pnode) {
+ pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+ if (!pnode) {
+ pr_err("not find node\n");
+ return;
+ }
+ }
+ ret = of_property_read_u64(pnode, "ucode_format", &g_fw_mask);
+ if (ret) {
+ pr_info("read format in dts failed, ret = %d\n", ret);
+ return;
+ }
+
+ return;
+}
int get_firmware_data(unsigned int format, char *buf)
{
@@ -87,11 +135,12 @@
struct fw_mgr_s *mgr = g_mgr;
struct fw_info_s *info;
- pr_info("[%s], the fw (%s) will be loaded...\n",
- tee_enabled() ? "TEE" : "LOCAL",
- get_fw_format_name(format));
+ if (debug)
+ pr_info("[%s], the fw (%s) will be loaded...\n",
+ fw_tee_enabled() ? "TEE" : "LOCAL",
+ get_fw_format_name(format));
- if (tee_enabled())
+ if (fw_tee_enabled())
return 0;
mutex_lock(&mutex);
@@ -177,7 +226,7 @@
const struct firmware *fw;
int magic, offset = 0;
- pr_info("Try to load %s ...\n", file_name);
+ pr_debug("Try to load %s ...\n", file_name);
ret = request_firmware(&fw, file_name, g_dev->dev);
if (ret < 0) {
@@ -192,7 +241,7 @@
}
magic = fw_probe((char *)fw->data);
- if (magic != PACK && magic != CODE) {
+ if (magic != PACK && magic != CODE && magic != NEWP) {
if (fw->size < SEC_OFFSET) {
pr_info("This is an invalid firmware file.\n");
goto release;
@@ -209,7 +258,7 @@
memcpy(buf, (char *)fw->data + offset, fw->size - offset);
- pr_info("load firmware size : %zd, Name : %s.\n",
+ pr_debug("load firmware size : %zd, Name : %s.\n",
fw->size, file_name);
ret = fw->size;
release:
@@ -248,6 +297,22 @@
}
EXPORT_SYMBOL(get_decoder_firmware_data);
+int get_decoder_firmware_version(void)
+{
+ int version;
+
+ version = (package_head.version & 0xff);
+
+ return version;
+}
+EXPORT_SYMBOL(get_decoder_firmware_version);
+
+int get_decoder_firmware_submit_count(void)
+{
+ return package_head.submit_count;
+}
+EXPORT_SYMBOL(get_decoder_firmware_submit_count);
+
static unsigned long fw_mgr_lock(struct fw_mgr_s *mgr)
{
unsigned long flags;
@@ -368,7 +433,6 @@
memset(history_change_id, 0, sizeof(history_change_id));
strncpy(history_change_id, &(package_head.history_change_id[i * 6]), 6);
pr_info("\t%s\n", history_change_id);
-
}
list_for_each_entry(info, &mgr->fw_head, node) {
@@ -460,6 +524,8 @@
__putname(path);
+ fw_get_format_from_dtb();
+
if (debug)
fw_files_info_walk();
@@ -494,6 +560,12 @@
if (fw_info->format == FIRMWARE_MAX)
return 0;
+ if (!fw_check_need_load(fw->head.format)) {
+ kfree(fw_info);
+ kfree(fw);
+ return 1;
+ }
+
list_for_each_entry_safe(info, tmp, &mgr->fw_head, node) {
if (info->format != fw_info->format)
continue;
@@ -656,7 +728,7 @@
goto out;
}
- data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
+ data = kzalloc(FIRMWARE_SIZE, GFP_KERNEL);
if (data == NULL) {
kfree(info);
ret = -ENOMEM;
@@ -678,7 +750,7 @@
pack_data += (pack_info->head.length + info_len);
pack_info = (struct package_info_s *)pack_data;
- if (!data->head.duplicate &&
+ if (!data->head.duplicate && (new_package == false) &&
!fw_data_check_sum(data)) {
pr_info("check sum fail !\n");
kfree(data);
@@ -715,7 +787,7 @@
if (info == NULL)
return -ENOMEM;
- info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
+ info->data = kzalloc(FIRMWARE_SIZE, GFP_KERNEL);
if (info->data == NULL) {
kfree(info);
return -ENOMEM;
@@ -780,12 +852,16 @@
if (files->file_type == VIDEO_PACKAGE && magic == PACK) {
if (!fw_check_pack_version(buf))
ret = fw_package_parse(files, buf, size);
+ } else if (files->file_type == VIDEO_PACKAGE && magic == NEWP) {
+ new_package = true;
+ if (!fw_check_pack_version(buf))
+ ret = fw_package_parse(files, buf, size);
} else if (files->file_type == VIDEO_FW_FILE && magic == CODE) {
ret = fw_code_parse(files, buf, size);
} else {
list_del(&files->node);
kfree(files);
- pr_info("invaild file type.\n");
+ pr_info("invalid file type.\n");
}
memset(buf, 0, BUFF_SIZE);
@@ -858,7 +934,7 @@
int ret = 0;
struct fw_mgr_s *mgr = g_mgr;
- if (tee_enabled())
+ if (fw_tee_enabled())
return 0;
mutex_lock(&mutex);
@@ -1002,7 +1078,7 @@
goto err;
}
- pr_info("Registered firmware driver success.\n");
+ pr_debug("Registered firmware driver success.\n");
err:
return ret;
}
diff --git a/drivers/common/firmware/firmware_priv.h b/drivers/common/firmware/firmware_priv.h
index d901f9d..371949f 100644
--- a/drivers/common/firmware/firmware_priv.h
+++ b/drivers/common/firmware/firmware_priv.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/firmware/firmware.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
-*/
-
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef __VIDEO_FIRMWARE_PRIV_HEAD_
#define __VIDEO_FIRMWARE_PRIV_HEAD_
#include <linux/types.h>
diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c
index 8d95c12..0f506b9 100644
--- a/drivers/common/firmware/firmware_type.c
+++ b/drivers/common/firmware/firmware_type.c
@@ -1,66 +1,82 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/bits.h>
#include "firmware_type.h"
#include "../chips/decoder_cpu_ver_info.h"
static const struct format_name_s format_name[] = {
- {VIDEO_DEC_MPEG12, "mpeg12"},
- {VIDEO_DEC_MPEG12_MULTI, "mpeg12_multi"},
- {VIDEO_DEC_MPEG4_3, "mpeg4_3"},
- {VIDEO_DEC_MPEG4_4, "mpeg4_4"},
- {VIDEO_DEC_MPEG4_4_MULTI, "mpeg4_4_multi"},
- {VIDEO_DEC_MPEG4_5, "xvid"},
- {VIDEO_DEC_MPEG4_5_MULTI, "xvid_multi"},
- {VIDEO_DEC_H263, "h263"},
- {VIDEO_DEC_H263_MULTI, "h263_multi"},
- {VIDEO_DEC_MJPEG, "mjpeg"},
- {VIDEO_DEC_MJPEG_MULTI, "mjpeg_multi"},
- {VIDEO_DEC_REAL_V8, "real_v8"},
- {VIDEO_DEC_REAL_V9, "real_v9"},
- {VIDEO_DEC_VC1, "vc1"},
- {VIDEO_DEC_VC1_G12A, "vc1_g12a"},
- {VIDEO_DEC_AVS, "avs"},
- {VIDEO_DEC_AVS_GXM, "avs_gxm"},
- {VIDEO_DEC_AVS_NOCABAC, "avs_no_cabac"},
- {VIDEO_DEC_AVS_MULTI, "avs_multi"},
- {VIDEO_DEC_H264, "h264"},
- {VIDEO_DEC_H264_MVC, "h264_mvc"},
- {VIDEO_DEC_H264_MVC_GXM, "h264_mvc_gxm"},
- {VIDEO_DEC_H264_MULTI, "h264_multi"},
- {VIDEO_DEC_H264_MULTI_MMU, "h264_multi_mmu"},
- {VIDEO_DEC_H264_MULTI_GXM, "h264_multi_gxm"},
- {VIDEO_DEC_HEVC, "hevc"},
- {VIDEO_DEC_HEVC_MMU, "hevc_mmu"},
- {VIDEO_DEC_HEVC_MMU_SWAP, "hevc_mmu_swap"},
- {VIDEO_DEC_HEVC_G12A, "hevc_g12a"},
- {VIDEO_DEC_VP9, "vp9"},
- {VIDEO_DEC_VP9_MMU, "vp9_mmu"},
- {VIDEO_DEC_VP9_G12A, "vp9_g12a"},
- {VIDEO_DEC_AVS2, "avs2"},
- {VIDEO_DEC_AVS2_MMU, "avs2_mmu"},
- {VIDEO_DEC_AV1_MMU, "av1_mmu"},
- {VIDEO_ENC_H264, "h264_enc"},
- {VIDEO_ENC_JPEG, "jpeg_enc"},
+ {VIDEO_DEC_MPEG12, "mpeg12", BIT_ULL(0)},
+ {VIDEO_DEC_MPEG12_MULTI, "mpeg12_multi", BIT_ULL(1)},
+ {VIDEO_DEC_MPEG4_3, "mpeg4_3", BIT_ULL(2)},
+ {VIDEO_DEC_MPEG4_4, "mpeg4_4", BIT_ULL(3)},
+ {VIDEO_DEC_MPEG4_4_MULTI, "mpeg4_4_multi", BIT_ULL(4)},
+ {VIDEO_DEC_MPEG4_5, "xvid", BIT_ULL(5)},
+ {VIDEO_DEC_MPEG4_5_MULTI, "xvid_multi", BIT_ULL(6)},
+ {VIDEO_DEC_H263, "h263", BIT_ULL(7)},
+ {VIDEO_DEC_H263_MULTI, "h263_multi", BIT_ULL(8)},
+ {VIDEO_DEC_MJPEG, "mjpeg", BIT_ULL(9)},
+ {VIDEO_DEC_MJPEG_MULTI, "mjpeg_multi", BIT_ULL(10)},
+ {VIDEO_DEC_REAL_V8, "real_v8", BIT_ULL(11)},
+ {VIDEO_DEC_REAL_V9, "real_v9", BIT_ULL(12)},
+ {VIDEO_DEC_VC1, "vc1", BIT_ULL(13)},
+ {VIDEO_DEC_VC1_G12A, "vc1_g12a", BIT_ULL(14)},
+ {VIDEO_DEC_AVS, "avs", BIT_ULL(15)},
+ {VIDEO_DEC_AVS_GXM, "avs_gxm", BIT_ULL(16)},
+ {VIDEO_DEC_AVS_NOCABAC, "avs_no_cabac", BIT_ULL(17)},
+ {VIDEO_DEC_AVS_MULTI, "avs_multi", BIT_ULL(18)},
+ {VIDEO_DEC_H264, "h264", BIT_ULL(19)},
+ {VIDEO_DEC_H264_MVC, "h264_mvc", BIT_ULL(20)},
+ {VIDEO_DEC_H264_MVC_GXM, "h264_mvc_gxm", BIT_ULL(21)},
+ {VIDEO_DEC_H264_MULTI, "h264_multi", BIT_ULL(22)},
+ {VIDEO_DEC_H264_MULTI_MMU, "h264_multi_mmu", BIT_ULL(23)},
+ {VIDEO_DEC_H264_MULTI_GXM, "h264_multi_gxm", BIT_ULL(24)},
+ {VIDEO_DEC_HEVC, "hevc", BIT_ULL(25)},
+ {VIDEO_DEC_HEVC_MMU, "hevc_mmu", BIT_ULL(26)},
+ {VIDEO_DEC_HEVC_MMU_SWAP, "hevc_mmu_swap", BIT_ULL(27)},
+ {VIDEO_DEC_HEVC_G12A, "hevc_g12a", BIT_ULL(28)},
+ {VIDEO_DEC_VP9, "vp9", BIT_ULL(29)},
+ {VIDEO_DEC_VP9_MMU, "vp9_mmu", BIT_ULL(30)},
+ {VIDEO_DEC_VP9_G12A, "vp9_g12a", BIT_ULL(31)},
+ {VIDEO_DEC_AVS2, "avs2", BIT_ULL(32)},
+ {VIDEO_DEC_AVS2_MMU, "avs2_mmu", BIT_ULL(33)},
+ {VIDEO_DEC_AV1_MMU, "av1_mmu", BIT_ULL(34)},
+ {VIDEO_DEC_AVS3, "avs3_mmu", BIT_ULL(35)},
+ /* front/back ucode */
+ {VIDEO_DEC_HEVC_FRONT, "hevc_front", BIT_ULL(36)},
+ {VIDEO_DEC_HEVC_BACK, "hevc_back", BIT_ULL(37)},
+ {VIDEO_DEC_VP9_FRONT, "vp9_front", BIT_ULL(38)},
+ {VIDEO_DEC_VP9_BACK, "vp9_back", BIT_ULL(39)},
+ {VIDEO_DEC_AV1_FRONT, "av1_front", BIT_ULL(40)},
+ {VIDEO_DEC_AV1_BACK, "av1_back", BIT_ULL(41)},
+ {VIDEO_DEC_AVS2_FRONT, "avs2_front", BIT_ULL(42)},
+ {VIDEO_DEC_AVS2_BACK, "avs2_back", BIT_ULL(43)},
+ {VIDEO_DEC_AVS3_FRONT, "avs3_front", BIT_ULL(44)},
+ {VIDEO_DEC_AVS3_BACK, "avs3_back", BIT_ULL(45)},
+
+ {VIDEO_ENC_H264, "h264_enc", BIT_ULL(46)},
+ {VIDEO_ENC_JPEG, "jpeg_enc", BIT_ULL(47)},
{FIRMWARE_MAX, "unknown"},
};
+unsigned long long g_fw_mask = (~0ULL);
+
static const struct cpu_type_s cpu_type[] = {
{AM_MESON_CPU_MAJOR_ID_GXL, "gxl"},
{AM_MESON_CPU_MAJOR_ID_GXM, "gxm"},
@@ -75,7 +91,9 @@
{AM_MESON_CPU_MAJOR_ID_SM1, "sm1"},
{AM_MESON_CPU_MAJOR_ID_TL1, "tl1"},
{AM_MESON_CPU_MAJOR_ID_TM2, "tm2"},
+ {AM_MESON_CPU_MAJOR_ID_C1, "c1"},
{AM_MESON_CPU_MAJOR_ID_SC2, "sc2"},
+ {AM_MESON_CPU_MAJOR_ID_C2, "c2"},
{AM_MESON_CPU_MAJOR_ID_T5, "t5"},
{AM_MESON_CPU_MAJOR_ID_T5D, "t5d"},
{AM_MESON_CPU_MAJOR_ID_T7, "t7"},
@@ -83,6 +101,12 @@
{AM_MESON_CPU_MAJOR_ID_T3, "t3"},
{AM_MESON_CPU_MAJOR_ID_P1, "p1"},
{AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
+ {AM_MESON_CPU_MAJOR_ID_S5, "s5"},
+ {AM_MESON_CPU_MAJOR_ID_GXLX3, "gxlx3"},
+ {AM_MESON_CPU_MAJOR_ID_T5M, "t5m"},
+ {AM_MESON_CPU_MAJOR_ID_T3X, "t3x"},
+ {AM_MESON_CPU_MAJOR_ID_TXHD2, "txhd2"},
+ {AM_MESON_CPU_MAJOR_ID_S1A, "s1a"},
};
const char *get_fw_format_name(unsigned int format)
@@ -127,3 +151,21 @@
}
EXPORT_SYMBOL(fw_get_cpu);
+int fw_check_need_load(const char *name)
+{
+ int idx, size = ARRAY_SIZE(format_name);
+
+ for (idx = 0; idx < size; idx++) {
+ if (!strcmp(name, format_name[idx].name)) {
+ if (g_fw_mask & format_name[idx].format_mask)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ pr_info("no %s load info, load it\n", name);
+ return -1;
+}
+EXPORT_SYMBOL(fw_check_need_load);
+
diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h
index 4615baf..6907e4c 100644
--- a/drivers/common/firmware/firmware_type.h
+++ b/drivers/common/firmware/firmware_type.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef __VIDEO_FIRMWARE_FORMAT_
#define __VIDEO_FIRMWARE_FORMAT_
@@ -49,6 +49,7 @@
#define VIDEO_DEC_VP9_MMU (19)
#define VIDEO_ENC_H264 (20)
#define VIDEO_ENC_JPEG (21)
+#define VIDEO_ENC_H264_CABAC (22)
#define VIDEO_DEC_H264_MULTI_MMU (23)
#define VIDEO_DEC_HEVC_G12A (24)
#define VIDEO_DEC_VP9_G12A (25)
@@ -66,6 +67,17 @@
#define VIDEO_DEC_HEVC_MMU_SWAP TAG('2', '6', '5', 'S')
#define VIDEO_DEC_AVS_MULTI TAG('A', 'V', 'S', 'M')
#define VIDEO_DEC_AV1_MMU TAG('A', 'V', '1', 'M')
+#define VIDEO_DEC_HEVC_FRONT TAG('2', '6', '5', 'F')
+#define VIDEO_DEC_HEVC_BACK TAG('2', '6', '5', 'B')
+#define VIDEO_DEC_VP9_FRONT TAG('V', 'P', '9', 'F')
+#define VIDEO_DEC_VP9_BACK TAG('V', 'P', '9', 'B')
+#define VIDEO_DEC_AV1_FRONT TAG('A', 'V', '1', 'F')
+#define VIDEO_DEC_AV1_BACK TAG('A', 'V', '1', 'B')
+#define VIDEO_DEC_AVS2_FRONT TAG('A', 'S', '2', 'F')
+#define VIDEO_DEC_AVS2_BACK TAG('A', 'S', '2', 'B')
+#define VIDEO_DEC_AVS3 TAG('A', 'V', 'S', '3')
+#define VIDEO_DEC_AVS3_FRONT TAG('A', 'S', '3', 'F')
+#define VIDEO_DEC_AVS3_BACK TAG('A', 'S', '3', 'B')
/* ... */
#define FIRMWARE_MAX (UINT_MAX)
@@ -81,10 +93,12 @@
#define OPTEE_VDEC (1)
#define OPTEE_VDEC_HEVC (2)
#define OPTEE_VDEC_HCDEC (3)
+#define OPTEE_VDEC_HEVCB (4)
struct format_name_s {
unsigned int format;
const char *name;
+ unsigned long long format_mask;
};
struct cpu_type_s {
@@ -95,5 +109,8 @@
const char *get_fw_format_name(unsigned int format);
unsigned int get_fw_format(const char *name);
int fw_get_cpu(const char *name);
+int get_decoder_firmware_version(void);
+int get_decoder_firmware_submit_count(void);
+int fw_check_need_load(const char *name);
#endif
diff --git a/drivers/common/media_clock/Makefile b/drivers/common/media_clock/Makefile
index 975b5e5..cd6eb27 100644
--- a/drivers/common/media_clock/Makefile
+++ b/drivers/common/media_clock/Makefile
@@ -1,6 +1,12 @@
-obj-m += media_clock.o
-media_clock-objs += ../chips/chips.o
-media_clock-objs += clk/clkg12.o
-media_clock-objs += clk/clk.o
-media_clock-objs += switch/amports_gate.o
-media_clock-objs += ../chips/decoder_cpu_ver_info.o
+MODULE_NAME = media_clock
+obj-m = $(MODULE_NAME).o
+$(MODULE_NAME)-y += ../chips/chips.o
+$(MODULE_NAME)-y += clk/clkg12.o
+$(MODULE_NAME)-y += clk/clk.o
+$(MODULE_NAME)-y += switch/amports_gate.o
+$(MODULE_NAME)-y += ../chips/decoder_cpu_ver_info.o
+$(MODULE_NAME)-y += ../register/register.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)= \"[$(PR_FMT)]: \" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c
index 6340c1a..9304fd1 100644
--- a/drivers/common/media_clock/clk/clk.c
+++ b/drivers/common/media_clock/clk/clk.c
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/clk/clk.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,13 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ * drivers/amlogic/media/common/arch/clk/clk.c
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -311,21 +314,6 @@
}
EXPORT_SYMBOL(get_clk_with_source);
-bool is_hevc_front_back_clk_combined(void)
-{
- int cpu_id = get_cpu_major_id();
-
- if (cpu_id == AM_MESON_CPU_MAJOR_ID_T5 ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_T5D) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_S4) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_S4D) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_T5W))
- return true;
-
- return false;
-}
-EXPORT_SYMBOL(is_hevc_front_back_clk_combined);
-
int vdec_source_changed_for_clk_set(int format, int width, int height, int fps)
{
int clk = get_clk_with_source(format, width * height * fps);
@@ -350,11 +338,12 @@
if (format == VFORMAT_HEVC || format == VFORMAT_VP9
|| format == VFORMAT_AVS2
- || format == VFORMAT_AV1) {
+ || format == VFORMAT_AV1
+ || format == VFORMAT_AVS3) {
ret_clk = hevc_clock_set(clk);
clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps;
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A &&
- !is_hevc_front_back_clk_combined()) {
+ !is_hevc_clk_combined()) {
ret_clk = hevc_back_clock_set(clk);
clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps;
}
@@ -444,19 +433,19 @@
return -ENOMEM;
memcpy(p_setting, setting, size);
- pr_info("register clk_set_setting cpu[%d]\n", cputype);
+ pr_debug("register clk_set_setting cpu[%d]\n", cputype);
get_current_vdec_chip()->clk_setting_array = p_setting;
return 0;
}
int register_vdec_clk_setting(int cputype[],
- struct clk_set_setting *p_seting, int size)
+ struct clk_set_setting *p_setting, int size)
{
int i = 0;
while (cputype[i] > 0) {
- register_vdec_clk_setting_per_cpu(cputype[i], p_seting, size);
+ register_vdec_clk_setting_per_cpu(cputype[i], p_setting, size);
i++;
}
return 0;
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h
index bbc3bee..2d22e29 100644
--- a/drivers/common/media_clock/clk/clk.h
+++ b/drivers/common/media_clock/clk/clk.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/clk/clk.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,13 +11,19 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ * drivers/amlogic/media/common/arch/clk/clk.h
*/
-
#ifndef VDEC_CHIP_CLK_HEADER
#define VDEC_CHIP_CLK_HEADER
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/clk/clk-conf.h>
#include "clk_priv.h"
#include <linux/amlogic/media/clk/gp_pll.h>
@@ -52,8 +56,6 @@
int vdec_source_get(enum vdec_type_e core);
int vdec_clk_get(enum vdec_type_e core);
-bool is_hevc_front_back_clk_combined(void);
-
int vdec_source_changed_for_clk_set(int format, int width, int height, int fps);
int get_clk_with_source(int format, int w_x_h_fps);
@@ -74,7 +76,7 @@
int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type);
int register_vdec_clk_setting(int cputype[],
- struct clk_set_setting *p_seting, int size);
+ struct clk_set_setting *p_setting, int size);
int unregister_vdec_clk_setting(void);
@@ -124,8 +126,18 @@
static int __init vdec_init_clk(void)
{
+ struct platform_device *pdev;
int cpus[] = CLK_FOR_CPU;
+ pdev = initial_dos_device();
+
+ if (is_support_new_dos_dev()) {
+ /* set clock parent as dos dev node */
+ of_clk_set_defaults(pdev->dev.of_node, false);
+
+ amports_clock_gate_init(&pdev->dev);
+ }
+
register_vdec_clk_mgr(cpus, VDEC_1, &vdec_clk_mgr);
#ifdef VDEC_HAS_VDEC2
register_vdec_clk_mgr(cpus, VDEC_2, &vdec2_clk_mgr);
diff --git a/drivers/common/media_clock/clk/clk_priv.h b/drivers/common/media_clock/clk/clk_priv.h
index 60b7be0..3949e48 100644
--- a/drivers/common/media_clock/clk/clk_priv.h
+++ b/drivers/common/media_clock/clk/clk_priv.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/clk/clk_priv.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,10 +11,16 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ * drivers/amlogic/media/common/arch/clk/clk_priv.h
*/
-
#ifndef AMPORTS_CLK_PRIV_HEADER
#define AMPORTS_CLK_PRIV_HEADER
+#include "../../../frame_provider/decoder/utils/vdec.h"
struct clk_set {
u32 wh_X_fps; /* [x*y*fps */
diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c
index c49d150..94b77da 100644
--- a/drivers/common/media_clock/clk/clkg12.c
+++ b/drivers/common/media_clock/clk/clkg12.c
@@ -1,7 +1,5 @@
-/*
- * drivers/amlogic/media/common/arch/clk/clkgx.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ /*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,6 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ * drivers/amlogic/media/common/arch/clk/clkgx.c
*/
#define DEBUG
#include <linux/init.h>
@@ -21,7 +25,6 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/amlogic/media/clk/gp_pll.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/media/utils/amports_config.h>
#include "../../../frame_provider/decoder/utils/vdec.h"
#include <linux/amlogic/media/registers/register.h>
@@ -289,6 +292,9 @@
* VFORMAT_H264_ENC,
* VFORMAT_JPEG_ENC,
* VFORMAT_VP9,
+ * VFORMAT_AVS2,
+ * VFORMAT_AV1,
+ * VFORMAT_AVS3,
* VFORMAT_MAX
*};
*sample:
@@ -408,7 +414,11 @@
{1920*1080*60, 166}, {4096*2048*30, 333},
{4096*2048*60, 630}, {INT_MAX, 630},}
},
-
+ {/*VFORMAT_AVS3*/
+ {{1280*720*30, 100}, {1920*1080*30, 100},
+ {1920*1080*60, 166}, {4096*2048*30, 333},
+ {4096*2048*60, 630}, {INT_MAX, 630},}
+ },
};
void set_clock_gate(struct gate_switch_node *nodes, int num)
@@ -418,7 +428,11 @@
if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) ||
(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D))
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2))
hevc_mux_str = "clk_hevc_mux";
else
hevc_mux_str = "clk_hevcf_mux";
@@ -426,16 +440,23 @@
do {
node = &nodes[num - 1];
if (IS_ERR_OR_NULL(node) || (IS_ERR_OR_NULL(node->clk)))
- pr_info("get mux clk err.\n");
-
- if (!strcmp(node->name, "clk_vdec_mux"))
+ continue;
+ if (!strcmp(node->name, "clk_vdec_mux")) {
gclk.vdec_mux_node = node;
- else if (!strcmp(node->name, "clk_hcodec_mux"))
+ pr_debug("%s get vdec mux\n", __func__);
+ }
+ else if (!strcmp(node->name, "clk_hcodec_mux")) {
gclk.hcodec_mux_node = node;
- else if (!strcmp(node->name, hevc_mux_str))
- gclk.hevc_mux_node = node;
- else if (!strcmp(node->name, "clk_hevcb_mux"))
+ pr_debug("%s get hcodec mux\n", __func__);
+ }
+ else if (!strcmp(node->name, hevc_mux_str)) {
+ gclk.hevc_mux_node = node;
+ pr_debug("%s get hevc_mux_str\n", __func__);
+ }
+ else if (!strcmp(node->name, "clk_hevcb_mux")) {
gclk.hevc_back_mux_node = node;
+ pr_debug("%s get hevcb mux\n", __func__);
+ }
} while(--num);
}
EXPORT_SYMBOL(set_clock_gate);
@@ -489,7 +510,7 @@
break;
default:
- pr_info("invaild vdec type.\n");
+ pr_info("invalid vdec type.\n");
}
if (IS_ERR_OR_NULL(clk)) {
@@ -732,14 +753,7 @@
clk = 667;
}
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)
- clk = 800;
-
- if (is_cpu_s4_s805x2())
- clk = 500;
+ clk = vdec_max_clk_get();
if (set_frq_enable && vdec_frq) {
pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
@@ -787,10 +801,8 @@
if ((clk > 500 && clk != 667)) {
if (clock_real_clk[VDEC_HEVCB] == 648)
return 648;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- clk = TL1_HEVC_MAX_CLK;
- else
- clk = 667;
+
+ clk = hevcb_max_clk_get();
}
if (set_frq_enable && hevcb_frq) {
@@ -836,15 +848,8 @@
if ((clk > 500 && clk != 667)) {
if (clock_real_clk[VDEC_HEVC] == 648)
return 648;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- clk = TL1_HEVC_MAX_CLK;
- else
- clk = 667;
- if (is_cpu_s4_s805x2())
- clk = 500;
+ clk = hevcf_max_clk_get();
}
if (set_frq_enable && hevc_frq) {
@@ -1050,6 +1055,12 @@
AM_MESON_CPU_MAJOR_ID_P1,\
AM_MESON_CPU_MAJOR_ID_S4D,\
AM_MESON_CPU_MAJOR_ID_T5W,\
+ AM_MESON_CPU_MAJOR_ID_S5,\
+ AM_MESON_CPU_MAJOR_ID_GXLX3,\
+ AM_MESON_CPU_MAJOR_ID_T5M,\
+ AM_MESON_CPU_MAJOR_ID_T3X,\
+ AM_MESON_CPU_MAJOR_ID_TXHD2,\
+ AM_MESON_CPU_MAJOR_ID_S1A,\
0}
#include "clk.h"
diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c
index 58a0289..9009894 100644
--- a/drivers/common/media_clock/switch/amports_gate.c
+++ b/drivers/common/media_clock/switch/amports_gate.c
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/switch/amports_gate.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,13 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-#define DEBUG
+//#define DEBUG
#include <linux/compiler.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
@@ -22,7 +25,6 @@
#include <linux/spinlock.h>
#include <linux/clk.h>
#include "amports_gate.h"
-#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../stream_input/amports/amports_priv.h"
#include "../../../frame_provider/decoder/utils/vdec.h"
#include "../clk/clk.h"
@@ -99,11 +101,11 @@
gates[i].clk = devm_clk_get(dev, gates[i].name);
if (IS_ERR_OR_NULL(gates[i].clk)) {
gates[i].clk = NULL;
- pr_info("get gate %s control failed %px\n",
+ pr_debug("get gate %s control failed %px\n",
gates[i].name,
gates[i].clk);
} else {
- pr_info("get gate %s control ok %px\n",
+ pr_debug("get gate %s control ok %px\n",
gates[i].name,
gates[i].clk);
}
@@ -156,6 +158,8 @@
if (gates[i].clk)
amports_gate_clk(&gates[i], enable);
+ else
+ return -ENODEV;
}
}
return 0;
diff --git a/drivers/common/media_clock/switch/amports_gate.h b/drivers/common/media_clock/switch/amports_gate.h
index 58abc92..6dd8049 100644
--- a/drivers/common/media_clock/switch/amports_gate.h
+++ b/drivers/common/media_clock/switch/amports_gate.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/media/common/arch/switch/amports_gate.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef AMPORT_GATE_H
#define AMPORT_GATE_H
#include <linux/device.h>
diff --git a/drivers/common/media_utils/media_utils.c b/drivers/common/media_utils/media_utils.c
new file mode 100644
index 0000000..d2a6337
--- /dev/null
+++ b/drivers/common/media_utils/media_utils.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/fs.h>
+
+ssize_t media_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+{
+ return kernel_write(file, buf, count, pos);
+}
+EXPORT_SYMBOL(media_write);
+
+ssize_t media_read(struct file *file, void *bufs, size_t count, loff_t *pos)
+{
+ return kernel_read(file, bufs, count, pos);
+}
+EXPORT_SYMBOL(media_read);
+
+struct file *media_open(const char *filename, int flags, umode_t mode)
+{
+ return filp_open(filename, flags, mode);
+}
+EXPORT_SYMBOL(media_open);
+
+int media_close(struct file *filp, fl_owner_t id)
+{
+ return filp_close(filp, id);
+}
+EXPORT_SYMBOL(media_close);
+
diff --git a/drivers/common/media_utils/media_utils.h b/drivers/common/media_utils/media_utils.h
new file mode 100644
index 0000000..09e8638
--- /dev/null
+++ b/drivers/common/media_utils/media_utils.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef _MEDIA_FILE_H_
+#define _MEDIA_FILE_H_
+ssize_t media_write(struct file *, const void *, size_t, loff_t *);
+ssize_t media_read(struct file *, void *, size_t, loff_t *);
+struct file *media_open(const char *, int, umode_t);
+int media_close(struct file *, fl_owner_t);
+#endif
diff --git a/drivers/common/media_utils/media_utils_dummy.c b/drivers/common/media_utils/media_utils_dummy.c
new file mode 100644
index 0000000..4d75a55
--- /dev/null
+++ b/drivers/common/media_utils/media_utils_dummy.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/fs.h>
+
+ssize_t media_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+{
+ return 0;
+}
+EXPORT_SYMBOL(media_write);
+
+ssize_t media_read(struct file *file, void *bufs, size_t count, loff_t *pos)
+{
+ return 0;
+}
+EXPORT_SYMBOL(media_read);
+
+struct file *media_open(const char *filename, int flags, umode_t mode)
+{
+ return NULL;
+}
+EXPORT_SYMBOL(media_open);
+
+int media_close(struct file *filp, fl_owner_t id)
+{
+ return 0;
+}
+EXPORT_SYMBOL(media_close);
+
diff --git a/drivers/common/media_utils/media_utils_dummy.h b/drivers/common/media_utils/media_utils_dummy.h
new file mode 100644
index 0000000..09e8638
--- /dev/null
+++ b/drivers/common/media_utils/media_utils_dummy.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef _MEDIA_FILE_H_
+#define _MEDIA_FILE_H_
+ssize_t media_write(struct file *, const void *, size_t, loff_t *);
+ssize_t media_read(struct file *, void *, size_t, loff_t *);
+struct file *media_open(const char *, int, umode_t);
+int media_close(struct file *, fl_owner_t);
+#endif
diff --git a/drivers/common/register/register.c b/drivers/common/register/register.c
new file mode 100644
index 0000000..859ae92
--- /dev/null
+++ b/drivers/common/register/register.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include "../chips/decoder_cpu_ver_info.h"
+#include "register.h"
+
+static void __iomem *reg_base[MAX_REG_BUS];
+struct bus_reg_desc *reg_desc[MAX_REG_BUS];
+
+#define CODEC_REG_READ_DEBUG 0x01
+#define CODEC_REG_WRITE_DEBUG 0x02
+#define CODEC_REG_MAP_DEBUG 0x08
+
+static u32 register_debug;
+module_param(register_debug, uint, 0664);
+
+void registers_offset_config(struct bus_reg_desc *offset_from, s32 val, u32 size)
+{
+ u32 i;
+
+ for (i = 0; i < size; i++) {
+ offset_from[i].reg_compat_offset = val;
+ }
+}
+EXPORT_SYMBOL(registers_offset_config);
+
+
+void s5_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs)
+{
+ if (bs == DOS_BUS) {
+ printk("s5 dos register compat\n");
+ registers_offset_config(&desc[HEVC_ASSIST_AMR1_INT0],
+ -(0x0025 - 0x0015),
+ (HEVC_ASSIST_MBX_SSEL - HEVC_ASSIST_AMR1_INT0 + 1));
+
+ registers_offset_config(&desc[HEVC_ASSIST_TIMER0_LO],
+ -(0x0060 - 0x0036),
+ (HEVC_ASSIST_DMA_INT_MSK2 - HEVC_ASSIST_TIMER0_LO + 1));
+
+ registers_offset_config(&desc[HEVC_ASSIST_MBOX0_IRQ_REG],
+ -(0x0070 - 0x0040),
+ (HEVC_ASSIST_AXI_STATUS2_LO - HEVC_ASSIST_MBOX0_IRQ_REG + 1));
+
+ registers_offset_config(&desc[HEVC_ASSIST_SCRATCH_0],
+ -(0x00c0 - 0x00b0),
+ (HEVC_ASSIST_SCRATCH_N - HEVC_ASSIST_SCRATCH_0) + 1);
+
+ registers_offset_config(&desc[AV1D_IPP_DIR_CFG], -(0x0490 - 0x0419), 1);
+ }
+}
+
+void t3_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs)
+{
+ registers_offset_config(&desc[AV1D_IPP_DIR_CFG], -(0x0490 - 0x0419), 1);
+}
+
+
+//###############################################################################
+ulong dos_reg_compat_convert(ulong addr)
+{
+ s32 reg_compat_offset;
+ struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+
+ if (addr & NEW_REG_CHECK_MASK) {
+ addr &= (~NEW_REG_CHECK_MASK);
+ reg_compat_offset = 0;
+ } else {
+ reg_compat_offset = dos_desc[addr].reg_compat_offset;
+ }
+
+ return (addr + reg_compat_offset);
+ }
+EXPORT_SYMBOL(dos_reg_compat_convert);
+
+void write_dos_reg(ulong addr, int val)
+{
+ void __iomem * reg_adr;
+ s32 reg_compat_offset;
+ struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+
+ if (addr & NEW_REG_CHECK_MASK) {
+ addr &= (~NEW_REG_CHECK_MASK);
+ reg_compat_offset = 0;
+ } else {
+ reg_compat_offset = dos_desc[addr].reg_compat_offset;
+ }
+
+ if ((reg_compat_offset + addr) < 0) {
+ pr_err("write dos reg out of range, name %s, addr %lx, offset %d\n",
+ dos_desc[addr].reg_name, addr, reg_compat_offset);
+ return;
+ }
+
+ reg_adr = reg_base[DOS_BUS] + ((reg_compat_offset + addr) << 2);
+
+ if (register_debug) {
+ if (register_debug & CODEC_REG_WRITE_DEBUG) {
+ pr_info("write_reg(%lx, %x)\n", (reg_compat_offset + addr), val);
+ }
+ if (register_debug & CODEC_REG_MAP_DEBUG) {
+ pr_info("%s %px, name %s, addr %lx, offset %d\n",
+ __func__, reg_adr, dos_desc[addr].reg_name, addr, reg_compat_offset);
+ }
+ }
+
+ writel(val, reg_adr);
+}
+EXPORT_SYMBOL(write_dos_reg);
+
+int read_dos_reg(ulong addr)
+{
+ void __iomem * reg_adr;
+ int value;
+ struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+ s32 reg_compat_offset;
+
+ if (addr & NEW_REG_CHECK_MASK) {
+ addr &= (~NEW_REG_CHECK_MASK);
+ reg_compat_offset = 0;
+ } else {
+ reg_compat_offset = dos_desc[addr].reg_compat_offset;
+ }
+
+ if ((reg_compat_offset + addr) < 0) {
+ pr_err("read dos reg out of range, name %s, addr %lx, offset %d\n",
+ dos_desc[addr].reg_name, addr, reg_compat_offset);
+ return -ENXIO;
+ }
+
+ reg_adr = reg_base[DOS_BUS] + ((reg_compat_offset + addr) << 2);
+
+ value = readl(reg_adr);
+
+ if (register_debug) {
+ if (register_debug & CODEC_REG_READ_DEBUG) {
+ pr_info("read_reg(%lx) = %x\n", (reg_compat_offset + addr), value);
+ }
+ if (register_debug & CODEC_REG_MAP_DEBUG) {
+ pr_info("%s %px, name %s, addr %lx, offset %d\n",
+ __func__, reg_adr, dos_desc[addr].reg_name, addr, reg_compat_offset);
+ }
+ }
+ return value;
+}
+EXPORT_SYMBOL(read_dos_reg);
+
+int read_dos_reg_comp(ulong addr)
+{
+ if (is_support_new_dos_dev())
+ return read_dos_reg(addr);
+ else
+ return aml_read_dosbus((uint)addr);
+}
+EXPORT_SYMBOL(read_dos_reg_comp);
+
+void write_dos_reg_comp(ulong addr, int val)
+{
+ if (is_support_new_dos_dev())
+ write_dos_reg(addr, val);
+ else
+ aml_write_dosbus((uint)addr, (uint)val);
+}
+EXPORT_SYMBOL(write_dos_reg_comp);
+
+
+void dos_reg_write_bits(unsigned int reg, u32 val, int start, int len)
+{
+ u32 to_val = read_dos_reg_comp(reg);
+ u32 mask = (((1L << (len)) - 1) << (start));
+
+ to_val &= ~mask;
+ to_val |= (val << start) & mask;
+ write_dos_reg_comp(reg, to_val);
+}
+EXPORT_SYMBOL(dos_reg_write_bits);
+
+int dos_register_probe(struct platform_device *pdev, reg_compat_func reg_compat_fn)
+{
+ u32 i;
+ struct resource res;
+ u32 res_size;
+
+ if (pdev == NULL) {
+ pr_info("no dev found, dos_register can not map\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < MAX_REG_BUS; i++) {
+ if (of_address_to_resource(pdev->dev.of_node, i, &res)) {
+ pr_err("of_address_to_resource failed\n");
+ return -EINVAL;
+ }
+
+ res_size = resource_size(&res);
+ reg_base[i] = ioremap(res.start, res_size);
+
+ pr_info("%s, res start %llx, end %llx, iomap: %px\n",
+ __func__, (unsigned long long)res.start,
+ (unsigned long long)res.end, reg_base[i]);
+
+ reg_desc[i] = (struct bus_reg_desc *)kzalloc(res_size *
+ sizeof(struct bus_reg_desc), GFP_KERNEL);
+ if (!reg_desc[i])
+ pr_err("Warn: dos regs offset table alloc failed\n");
+
+ if (reg_compat_fn)
+ reg_compat_fn(reg_desc[i], i);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(dos_register_probe);
+
+
diff --git a/drivers/common/register/register.h b/drivers/common/register/register.h
new file mode 100644
index 0000000..8ed948b
--- /dev/null
+++ b/drivers/common/register/register.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef _DOS_REGISTER_H_
+#define _DOS_REGISTER_H_
+
+#include <linux/platform_device.h>
+#include "../../include/regs/dos_registers.h"
+#include <linux/amlogic/media/utils/vdec_reg.h>
+
+
+typedef enum {
+ DOS_BUS,
+ MAX_REG_BUS
+} MM_BUS_ENUM;
+
+struct bus_reg_desc {
+ char const *reg_name;
+ s32 reg_compat_offset;
+};
+
+
+#define WRITE_VREG(addr, val) write_dos_reg_comp(addr, val)
+
+#define READ_VREG(addr) read_dos_reg_comp(addr)
+
+
+int read_dos_reg(ulong addr);
+void write_dos_reg(ulong addr, int val);
+void dos_reg_write_bits(unsigned int reg, u32 val, int start, int len);
+
+int read_dos_reg_comp(ulong addr);
+void write_dos_reg_comp(ulong addr, int val);
+
+
+#define WRITE_VREG_BITS(r, val, start, len) dos_reg_write_bits(r, val, start, len)
+#define CLEAR_VREG_MASK(r, mask) write_dos_reg_comp(r, read_dos_reg_comp(r) & ~(mask))
+#define SET_VREG_MASK(r, mask) write_dos_reg_comp(r, read_dos_reg_comp(r) | (mask))
+
+
+#define READ_HREG(r) read_dos_reg_comp((r) | 0x1000)
+#define WRITE_HREG(r, val) write_dos_reg_comp((r) | 0x1000, val)
+#define WRITE_HREG_BITS(r, val, start, len) \
+ dos_reg_write_bits((r) | 0x1000, val, start, len)
+//#define SET_HREG_MASK(r, mask) codec_set_dosbus_mask((r) | 0x1000, mask)
+//#define CLEAR_HREG_MASK(r, mask) codec_clear_dosbus_mask((r) | 0x1000, mask)
+
+//##############################################################
+
+typedef void (*reg_compat_func)(struct bus_reg_desc *, MM_BUS_ENUM bus);
+
+void t3_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs);
+void s5_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs);
+
+
+ulong dos_reg_compat_convert(ulong addr);
+
+void write_dos_reg(ulong addr, int val);
+
+int read_dos_reg(ulong addr);
+
+
+int dos_register_probe(struct platform_device *pdev, reg_compat_func reg_compat_fn);
+
+
+#endif
diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile
index f30c4f1..3346cef 100644
--- a/drivers/frame_provider/Makefile
+++ b/drivers/frame_provider/Makefile
@@ -1,2 +1,2 @@
obj-y += decoder/
-obj-y += decoder_v4l/
+obj-${CONFIG_AMLOGIC_MEDIA_V4L_DEC} += decoder_v4l/
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile
index bb0079e..0268802 100644
--- a/drivers/frame_provider/decoder/Makefile
+++ b/drivers/frame_provider/decoder/Makefile
@@ -2,12 +2,16 @@
obj-y += mpeg12/
obj-y += mpeg4/
obj-y += vc1/
-obj-y += h264/
+obj-y += h264_mvc/
obj-y += h264_multi/
obj-y += h265/
obj-y += vp9/
obj-y += mjpeg/
-obj-y += avs/
obj-y += avs2/
obj-y += avs_multi/
obj-y += vav1/
+obj-y += avs3/
+obj-y += vp9_fb/
+obj-y += h265_fb/
+obj-y += vav1_fb/
+obj-y += avs2_fb/
diff --git a/drivers/frame_provider/decoder/avs/Makefile b/drivers/frame_provider/decoder/avs/Makefile
deleted file mode 100644
index 1d56236..0000000
--- a/drivers/frame_provider/decoder/avs/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS) += amvdec_avs.o
-amvdec_avs-objs += avs.o avsp_trans.o
diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c
deleted file mode 100644
index 5869eac..0000000
--- a/drivers/frame_provider/decoder/avs/avs.c
+++ /dev/null
@@ -1,1988 +0,0 @@
-/*
- * drivers/amlogic/amports/vavs.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../stream_input/amports/streambuf_reg.h"
-#include "../utils/amvdec.h"
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/dma-mapping.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/slab.h>
-#include "avs.h"
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../utils/decoder_mmu_box.h"
-#include "../utils/decoder_bmmu_box.h"
-#include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-
-#define DRIVER_NAME "amvdec_avs"
-#define MODULE_NAME "amvdec_avs"
-
-
-#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
-#define NV21
-#endif
-
-#define USE_AVS_SEQ_INFO
-#define HANDLE_AVS_IRQ
-#define DEBUG_PTS
-
-#define I_PICTURE 0
-#define P_PICTURE 1
-#define B_PICTURE 2
-
-/* #define ORI_BUFFER_START_ADDR 0x81000000 */
-#define ORI_BUFFER_START_ADDR 0x80000000
-
-#define INTERLACE_FLAG 0x80
-#define TOP_FIELD_FIRST_FLAG 0x40
-
-/* protocol registers */
-#define AVS_PIC_RATIO AV_SCRATCH_0
-#define AVS_PIC_WIDTH AV_SCRATCH_1
-#define AVS_PIC_HEIGHT AV_SCRATCH_2
-#define AVS_FRAME_RATE AV_SCRATCH_3
-
-#define AVS_ERROR_COUNT AV_SCRATCH_6
-#define AVS_SOS_COUNT AV_SCRATCH_7
-#define AVS_BUFFERIN AV_SCRATCH_8
-#define AVS_BUFFEROUT AV_SCRATCH_9
-#define AVS_REPEAT_COUNT AV_SCRATCH_A
-#define AVS_TIME_STAMP AV_SCRATCH_B
-#define AVS_OFFSET_REG AV_SCRATCH_C
-#define MEM_OFFSET_REG AV_SCRATCH_F
-#define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G
-
-#define VF_POOL_SIZE 32
-#define PUT_INTERVAL (HZ/100)
-
-#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
-#define INT_AMVENCODER INT_DOS_MAILBOX_1
-#else
-/* #define AMVENC_DEV_VERSION "AML-MT" */
-#define INT_AMVENCODER INT_MAILBOX_1A
-#endif
-
-
-#define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001
-static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE;
-
-
-#define VPP_VD1_POSTBLEND (1 << 10)
-
-static int debug_flag;
-
-/********************************
-firmware_sel
- 0: use avsp_trans long cabac ucode;
- 1: not use avsp_trans long cabac ucode
-********************************/
-static int firmware_sel;
-static int disable_longcabac_trans = 1;
-
-static int support_user_data = 1;
-
-int avs_get_debug_flag(void)
-{
- return debug_flag;
-}
-
-static struct vframe_s *vavs_vf_peek(void *);
-static struct vframe_s *vavs_vf_get(void *);
-static void vavs_vf_put(struct vframe_s *, void *);
-static int vavs_event_cb(int type, void *data, void *private_data);
-static int vavs_vf_states(struct vframe_states *states, void *);
-
-static const char vavs_dec_id[] = "vavs-dev";
-
-#define PROVIDER_NAME "decoder.avs"
-static DEFINE_SPINLOCK(lock);
-static DEFINE_MUTEX(vavs_mutex);
-
-static const struct vframe_operations_s vavs_vf_provider = {
- .peek = vavs_vf_peek,
- .get = vavs_vf_get,
- .put = vavs_vf_put,
- .event_cb = vavs_event_cb,
- .vf_states = vavs_vf_states,
-};
-static void *mm_blk_handle;
-static struct vframe_provider_s vavs_vf_prov;
-
-#define VF_BUF_NUM_MAX 16
-#define WORKSPACE_SIZE (4 * SZ_1M)
-
-#ifdef AVSP_LONG_CABAC
-#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2)
-#define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE)
-#else
-#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 1)
-#endif
-
-#define RV_AI_BUFF_START_ADDR 0x01a00000
-#define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000
-
-static u32 vf_buf_num = 8;
-static u32 vf_buf_num_used;
-static u32 canvas_base = 128;
-#ifdef NV21
- int canvas_num = 2; /*NV21*/
-#else
- int canvas_num = 3;
-#endif
-
-static struct vframe_s vfpool[VF_POOL_SIZE];
-/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
-static struct vframe_s *cur_vfpool;
-static unsigned char recover_flag;
-static s32 vfbuf_use[VF_BUF_NUM_MAX];
-static u32 saved_resolution;
-static u32 frame_width, frame_height, frame_dur, frame_prog;
-static struct timer_list recycle_timer;
-static u32 stat;
-static u32 buf_size = 32 * 1024 * 1024;
-static u32 buf_offset;
-static u32 avi_flag;
-static u32 vavs_ratio;
-static u32 pic_type;
-static u32 pts_by_offset = 1;
-static u32 total_frame;
-static u32 next_pts;
-static unsigned char throw_pb_flag;
-#ifdef DEBUG_PTS
-static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
-#endif
-
-static u32 radr, rval;
-static struct dec_sysinfo vavs_amstream_dec_info;
-static struct vdec_info *gvs;
-static u32 fr_hint_status;
-static struct work_struct notify_work;
-static struct work_struct set_clk_work;
-static bool is_reset;
-
-static struct vdec_s *vdec = NULL;
-
-#ifdef AVSP_LONG_CABAC
-static struct work_struct long_cabac_wd_work;
-void *es_write_addr_virt;
-dma_addr_t es_write_addr_phy;
-
-void *bitstream_read_tmp;
-dma_addr_t bitstream_read_tmp_phy;
-void *avsp_heap_adr;
-static uint long_cabac_busy;
-#endif
-
-
-static void *user_data_buffer;
-static dma_addr_t user_data_buffer_phys;
-
-static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
-
-static inline u32 index2canvas(u32 index)
-{
- const u32 canvas_tab[VF_BUF_NUM_MAX] = {
- 0x010100, 0x030302, 0x050504, 0x070706,
- 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e,
- 0x111110, 0x131312, 0x151514, 0x171716,
- 0x191918, 0x1b1b1a, 0x1d1d1c, 0x1f1f1e,
- };
- const u32 canvas_tab_3[4] = {
- 0x010100, 0x040403, 0x070706, 0x0a0a09
- };
-
- if (canvas_num == 2)
- return canvas_tab[index] + (canvas_base << 16)
- + (canvas_base << 8) + canvas_base;
-
- return canvas_tab_3[index] + (canvas_base << 16)
- + (canvas_base << 8) + canvas_base;
-}
-
-static const u32 frame_rate_tab[16] = {
- 96000 / 30, /* forbidden */
- 96000000 / 23976, /* 24000/1001 (23.967) */
- 96000 / 24,
- 96000 / 25,
- 9600000 / 2997, /* 30000/1001 (29.97) */
- 96000 / 30,
- 96000 / 50,
- 9600000 / 5994, /* 60000/1001 (59.94) */
- 96000 / 60,
- /* > 8 reserved, use 24 */
- 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24,
- 96000 / 24, 96000 / 24, 96000 / 24
-};
-
-static void set_frame_info(struct vframe_s *vf, unsigned int *duration)
-{
- int ar = 0;
-
- unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO);
-#ifndef USE_AVS_SEQ_INFO
- if (vavs_amstream_dec_info.width > 0
- && vavs_amstream_dec_info.height > 0) {
- vf->width = vavs_amstream_dec_info.width;
- vf->height = vavs_amstream_dec_info.height;
- } else
-#endif
- {
- vf->width = READ_VREG(AVS_PIC_WIDTH);
- vf->height = READ_VREG(AVS_PIC_HEIGHT);
- frame_width = vf->width;
- frame_height = vf->height;
- /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/
- }
-
-#ifndef USE_AVS_SEQ_INFO
- if (vavs_amstream_dec_info.rate > 0)
- *duration = vavs_amstream_dec_info.rate;
- else
-#endif
- {
- *duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf];
- /* pr_info("%s: duration = %d\n", __func__, *duration); */
- frame_dur = *duration;
- schedule_work(¬ify_work);
- }
-
- if (vavs_ratio == 0) {
- /* always stretch to 16:9 */
- vf->ratio_control |= (0x90 <<
- DISP_RATIO_ASPECT_RATIO_BIT);
- } else {
- switch (pixel_ratio) {
- case 1:
- ar = (vf->height * vavs_ratio) / vf->width;
- break;
- case 2:
- ar = (vf->height * 3 * vavs_ratio) / (vf->width * 4);
- break;
- case 3:
- ar = (vf->height * 9 * vavs_ratio) / (vf->width * 16);
- break;
- case 4:
- ar = (vf->height * 100 * vavs_ratio) / (vf->width *
- 221);
- break;
- default:
- ar = (vf->height * vavs_ratio) / vf->width;
- break;
- }
- }
-
- ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
-
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
- /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */
-
- vf->flag = 0;
-}
-
-
-static struct work_struct userdata_push_work;
-/*
-#define DUMP_LAST_REPORTED_USER_DATA
-*/
-static void userdata_push_do_work(struct work_struct *work)
-{
- unsigned int user_data_flags;
- unsigned int user_data_wp;
- unsigned int user_data_length;
- struct userdata_poc_info_t user_data_poc;
-#ifdef DUMP_LAST_REPORTED_USER_DATA
- int user_data_len;
- int wp_start;
- unsigned char *pdata;
- int nLeft;
-#endif
-
- user_data_flags = READ_VREG(AV_SCRATCH_N);
- user_data_wp = (user_data_flags >> 16) & 0xffff;
- user_data_length = user_data_flags & 0x7fff;
-
-#ifdef DUMP_LAST_REPORTED_USER_DATA
- dma_sync_single_for_cpu(amports_get_dma_device(),
- user_data_buffer_phys, USER_DATA_SIZE,
- DMA_FROM_DEVICE);
-
- if (user_data_length & 0x07)
- user_data_len = (user_data_length + 8) & 0xFFFFFFF8;
- else
- user_data_len = user_data_length;
-
- if (user_data_wp >= user_data_len) {
- wp_start = user_data_wp - user_data_len;
-
- pdata = (unsigned char *)user_data_buffer;
- pdata += wp_start;
- nLeft = user_data_len;
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
- } else {
- wp_start = user_data_wp +
- USER_DATA_SIZE - user_data_len;
-
- pdata = (unsigned char *)user_data_buffer;
- pdata += wp_start;
- nLeft = USER_DATA_SIZE - wp_start;
-
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
-
- pdata = (unsigned char *)user_data_buffer;
- nLeft = user_data_wp;
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
- }
-#endif
-
-/*
- pr_info("pocinfo 0x%x, poc %d, wp 0x%x, len %d\n",
- READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M),
- user_data_wp, user_data_length);
-*/
- user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L);
- user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M);
-
- WRITE_VREG(AV_SCRATCH_N, 0);
-/*
- wakeup_userdata_poll(user_data_poc, user_data_wp,
- (unsigned long)user_data_buffer,
- USER_DATA_SIZE, user_data_length);
-*/
-}
-
-static void UserDataHandler(void)
-{
- unsigned int user_data_flags;
-
- user_data_flags = READ_VREG(AV_SCRATCH_N);
- if (user_data_flags & (1 << 15)) { /* data ready */
- schedule_work(&userdata_push_work);
- }
-}
-
-
-#ifdef HANDLE_AVS_IRQ
-static irqreturn_t vavs_isr(int irq, void *dev_id)
-#else
-static void vavs_isr(void)
-#endif
-{
- u32 reg;
- struct vframe_s *vf;
- u32 dur;
- u32 repeat_count;
- u32 picture_type;
- u32 buffer_index;
- u32 frame_size;
- bool force_interlaced_frame = false;
- unsigned int pts, pts_valid = 0, offset = 0;
- u64 pts_us64;
- if (debug_flag & AVS_DEBUG_UCODE) {
- if (READ_VREG(AV_SCRATCH_E) != 0) {
- pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E),
- READ_VREG(AV_SCRATCH_D));
- WRITE_VREG(AV_SCRATCH_E, 0);
- }
- }
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) {
-#ifdef PERFORMANCE_DEBUG
- pr_info("%s:schedule long_cabac_wd_work\r\n", __func__);
-#endif
- pr_info("schedule long_cabac_wd_work and requested from %d\n",
- (READ_VREG(LONG_CABAC_REQ) >> 8)&0xFF);
- schedule_work(&long_cabac_wd_work);
- }
-#endif
-
-
- UserDataHandler();
-
- reg = READ_VREG(AVS_BUFFEROUT);
-
- if (reg) {
- if (debug_flag & AVS_DEBUG_PRINT)
- pr_info("AVS_BUFFEROUT=%x\n", reg);
- if (pts_by_offset) {
- offset = READ_VREG(AVS_OFFSET_REG);
- if (debug_flag & AVS_DEBUG_PRINT)
- pr_info("AVS OFFSET=%x\n", offset);
- if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
- &frame_size,
- 0, &pts_us64) == 0) {
- pts_valid = 1;
-#ifdef DEBUG_PTS
- pts_hit++;
-#endif
- } else {
-#ifdef DEBUG_PTS
- pts_missed++;
-#endif
- }
- }
-
- repeat_count = READ_VREG(AVS_REPEAT_COUNT);
- if (firmware_sel == 0)
- buffer_index =
- ((reg & 0x7) +
- (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
- else
- buffer_index =
- ((reg & 0x7) - 1) & 7;
-
- picture_type = (reg >> 3) & 7;
-#ifdef DEBUG_PTS
- if (picture_type == I_PICTURE) {
- /* pr_info("I offset 0x%x, pts_valid %d\n",
- * offset, pts_valid);
- */
- if (!pts_valid)
- pts_i_missed++;
- else
- pts_i_hit++;
- }
-#endif
-
- if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
- && frame_width == 1920 && frame_height == 1080) {
- force_interlaced_frame = true;
- }
-
- if (throw_pb_flag && picture_type != I_PICTURE) {
-
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("picture type %d throwed\n",
- picture_type);
- }
- WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index));
- } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */
- throw_pb_flag = 0;
-
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("interlace, picture type %d\n",
- picture_type);
- }
-
- if (kfifo_get(&newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(vf, &dur);
- vf->bufWidth = 1920;
- pic_type = 2;
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- vf->pts_us64 = pts_us64;
- if ((repeat_count > 1) && avi_flag) {
- /* next_pts = pts +
- * (vavs_amstream_dec_info.rate *
- * repeat_count >> 1)*15/16;
- */
- next_pts =
- pts +
- (dur * repeat_count >> 1) *
- 15 / 16;
- } else
- next_pts = 0;
- } else {
- vf->pts = next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && avi_flag) {
- /* vf->duration =
- * vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (next_pts != 0) {
- next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * vavs_amstream_dec_info.rate >> 1;
- */
- vf->duration = dur >> 1;
- next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_TOP;
- }else{
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG)
- ? VIDTYPE_INTERLACE_TOP
- : VIDTYPE_INTERLACE_BOTTOM;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
-
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr);
- }
-
- vf->pts = (pts_valid)?pts:0;
- /*
- *vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- */
- vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- mm_blk_handle,
- buffer_index);
- decoder_do_frame_check(NULL, vf);
- kfifo_put(&display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
-
- if (kfifo_get(&newframe_q, &vf) == 0) {
- pr_info("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(vf, &dur);
- vf->bufWidth = 1920;
- if (force_interlaced_frame)
- vf->pts = 0;
- else
- vf->pts = next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && avi_flag) {
- /* vf->duration = vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (next_pts != 0) {
- next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration = vavs_amstream_dec_info.rate
- * >> 1;
- */
- vf->duration = dur >> 1;
- next_pts = 0;
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_BOTTOM;
- } else {
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG) ?
- VIDTYPE_INTERLACE_BOTTOM :
- VIDTYPE_INTERLACE_TOP;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
- vf->pts_us64 = 0;
- vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- mm_blk_handle,
- buffer_index);
-
- kfifo_put(&display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- total_frame++;
- } else { /* progressive */
- throw_pb_flag = 0;
-
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("progressive picture type %d\n",
- picture_type);
- }
- if (kfifo_get(&newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(vf, &dur);
- vf->bufWidth = 1920;
- pic_type = 1;
-
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- if ((repeat_count > 1) && avi_flag) {
- /* next_pts = pts +
- * (vavs_amstream_dec_info.rate *
- * repeat_count)*15/16;
- */
- next_pts =
- pts +
- (dur * repeat_count) * 15 / 16;
- } else
- next_pts = 0;
- } else {
- vf->pts = next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && avi_flag) {
- /* vf->duration =
- * vavs_amstream_dec_info.rate *
- * repeat_count;
- */
- vf->duration = dur * repeat_count;
- if (next_pts != 0) {
- next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * vavs_amstream_dec_info.rate;
- */
- vf->duration = dur;
- next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
- vf->pts = (pts_valid)?pts:0;
- /*
- *vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- */
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr
- );
- pr_info("PicType = %d, PTS = 0x%x\n",
- picture_type, vf->pts);
- }
-
- vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- mm_blk_handle,
- buffer_index);
- decoder_do_frame_check(NULL, vf);
- kfifo_put(&display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- total_frame++;
- }
-
- /*count info*/
- gvs->frame_dur = frame_dur;
- vdec_count_info(gvs, 0, offset);
-
- /* pr_info("PicType = %d, PTS = 0x%x\n",
- * picture_type, vf->pts);
- */
- WRITE_VREG(AVS_BUFFEROUT, 0);
- }
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
-#ifdef HANDLE_AVS_IRQ
- return IRQ_HANDLED;
-#else
- return;
-#endif
-}
-/*
- *static int run_flag = 1;
- *static int step_flag;
- */
-static int error_recovery_mode; /*0: blocky 1: mosaic*/
-/*
- *static uint error_watchdog_threshold=10;
- *static uint error_watchdog_count;
- *static uint error_watchdog_buf_threshold = 0x4000000;
- */
-
-static struct vframe_s *vavs_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
-
- if (recover_flag)
- return NULL;
-
- if (kfifo_peek(&display_q, &vf))
- return vf;
-
- return NULL;
-
-}
-
-static struct vframe_s *vavs_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
-
- if (recover_flag)
- return NULL;
-
- if (kfifo_get(&display_q, &vf))
- return vf;
-
- return NULL;
-
-}
-
-static void vavs_vf_put(struct vframe_s *vf, void *op_arg)
-{
- int i;
-
- if (recover_flag)
- return;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &cur_vfpool[i])
- break;
- }
- if (i < VF_POOL_SIZE)
- kfifo_put(&recycle_q, (const struct vframe_s *)vf);
-
-}
-
-static int vavs_event_cb(int type, void *data, void *private_data)
-{
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE && vdec)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- if (!(stat & STAT_VDEC_RUN))
- return -1;
-
- vstatus->frame_width = frame_width;
- vstatus->frame_height = frame_height;
- if (frame_dur != 0)
- vstatus->frame_rate = 96000 / frame_dur;
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = READ_VREG(AV_SCRATCH_C);
- vstatus->status = stat;
- vstatus->bit_rate = gvs->bit_rate;
- vstatus->frame_dur = frame_dur;
- vstatus->frame_data = gvs->frame_data;
- vstatus->total_data = gvs->total_data;
- vstatus->frame_count = gvs->frame_count;
- vstatus->error_frame_count = gvs->error_frame_count;
- vstatus->drop_frame_count = gvs->drop_frame_count;
- vstatus->total_data = gvs->total_data;
- vstatus->samp_cnt = gvs->samp_cnt;
- vstatus->offset = gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
-
- return 0;
-}
-
-int vavs_set_isreset(struct vdec_s *vdec, int isreset)
-{
- is_reset = isreset;
- return 0;
-}
-
-static int vavs_vdec_info_init(void)
-{
- gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
- if (NULL == gvs) {
- pr_info("the struct of vdec status malloc failed.\n");
- return -ENOMEM;
- }
- return 0;
-}
-/****************************************/
-static int vavs_canvas_init(void)
-{
- int i, ret;
- u32 canvas_width, canvas_height;
- u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
- unsigned long buf_start;
- int need_alloc_buf_num;
- u32 endian;
-
- vf_buf_num_used = vf_buf_num;
- if (buf_size <= 0x00400000) {
- /* SD only */
- canvas_width = 768;
- canvas_height = 576;
- decbuf_y_size = 0x80000;
- decbuf_uv_size = 0x20000;
- decbuf_size = 0x100000;
- } else {
- /* HD & SD */
- canvas_width = 1920;
- canvas_height = 1088;
- decbuf_y_size = 0x200000;
- decbuf_uv_size = 0x80000;
- decbuf_size = 0x300000;
- }
-
-#ifdef AVSP_LONG_CABAC
- need_alloc_buf_num = vf_buf_num_used + 2;
-#else
- need_alloc_buf_num = vf_buf_num_used + 1;
-#endif
- for (i = 0; i < need_alloc_buf_num; i++) {
-
- if (i == (need_alloc_buf_num - 1))
- decbuf_size = WORKSPACE_SIZE;
-#ifdef AVSP_LONG_CABAC
- else if (i == (need_alloc_buf_num - 2))
- decbuf_size = WORKSPACE_SIZE_A;
-#endif
- ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, i,
- decbuf_size, DRIVER_NAME, &buf_start);
- if (ret < 0)
- return ret;
- if (i == (need_alloc_buf_num - 1)) {
- if (firmware_sel == 1)
- buf_offset = buf_start -
- RV_AI_BUFF_START_ADDR;
- else
- buf_offset = buf_start -
- LONG_CABAC_RV_AI_BUFF_START_ADDR;
- continue;
- }
-#ifdef AVSP_LONG_CABAC
- else if (i == (need_alloc_buf_num - 2)) {
- avsp_heap_adr = codec_mm_phys_to_virt(buf_start);
- continue;
- }
-#endif
- if (vdec->canvas_mode == CANVAS_BLKMODE_LINEAR)
- endian = 7;
- else
- endian = 0;
-#ifdef NV21
- config_cav_lut_ex(canvas_base + canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_base + canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
-#else
- config_cav_lut_ex(canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width / 2,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 2,
- buf_start +
- decbuf_y_size + decbuf_uv_size,
- canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
-#endif
- if (debug_flag & AVS_DEBUG_PRINT) {
- pr_info("canvas config %d, addr %p\n", i,
- (void *)buf_start);
- }
-
- }
- return 0;
-}
-
-void vavs_recover(void)
-{
- vavs_canvas_init();
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
- WRITE_VREG(DOS_SW_RESET0, 0);
- WRITE_VREG(AV_SCRATCH_H, 0);
- if (firmware_sel == 1) {
- WRITE_VREG(POWER_CTL_VLD, 0x10);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2,
- MEM_FIFO_CNT_BIT, 2);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8,
- MEM_LEVEL_CNT_BIT, 6);
- WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode
- }
-
-
- if (firmware_sel == 0) {
- /* fixed canvas index */
- WRITE_VREG(AV_SCRATCH_0, canvas_base);
- WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used);
- } else {
- int ii;
-
- for (ii = 0; ii < 4; ii++) {
- WRITE_VREG(AV_SCRATCH_0 + ii,
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 1)
- << 16)
- );
- }
- }
-
- /* notify ucode the buffer offset */
- WRITE_VREG(AV_SCRATCH_F, buf_offset);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
- WRITE_VREG(AVS_SOS_COUNT, 0);
- WRITE_VREG(AVS_BUFFERIN, 0);
- WRITE_VREG(AVS_BUFFEROUT, 0);
- if (error_recovery_mode)
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
- else
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-#if 1 /* def DEBUG_UCODE */
- WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
-
-#ifdef PIC_DC_NEED_CLEAR
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
- WRITE_VREG(LONG_CABAC_REQ, 0);
- WRITE_VREG(LONG_CABAC_PIC_SIZE, 0);
- WRITE_VREG(LONG_CABAC_SRC_ADDR, 0);
- }
-#endif
- WRITE_VREG(AV_SCRATCH_N, (u32)(user_data_buffer_phys - buf_offset));
- pr_info("support_user_data = %d\n", support_user_data);
- if (support_user_data)
- WRITE_VREG(AV_SCRATCH_M, 1);
- else
- WRITE_VREG(AV_SCRATCH_M, 0);
-
- WRITE_VREG(AV_SCRATCH_5, 0);
-
-}
-
-static int vavs_prot_init(void)
-{
- int r;
-#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
-#else
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
- READ_RESET_REG(RESET0_REGISTER);
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
-
- WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
-#endif
-
- /***************** reset vld **********************************/
- WRITE_VREG(POWER_CTL_VLD, 0x10);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
- /*************************************************************/
-
- r = vavs_canvas_init();
- WRITE_VREG(AV_SCRATCH_H, 0);
-#ifdef NV21
- if (firmware_sel == 0) {
- /* fixed canvas index */
- WRITE_VREG(AV_SCRATCH_0, canvas_base);
- WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used);
- } else {
- int ii;
-
- for (ii = 0; ii < 4; ii++) {
- WRITE_VREG(AV_SCRATCH_0 + ii,
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 1)
- << 16)
- );
- }
- WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode
- }
-#else
- /* index v << 16 | u << 8 | y */
- WRITE_VREG(AV_SCRATCH_0, 0x020100);
- WRITE_VREG(AV_SCRATCH_1, 0x050403);
- WRITE_VREG(AV_SCRATCH_2, 0x080706);
- WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
-#endif
- /* notify ucode the buffer offset */
- WRITE_VREG(AV_SCRATCH_F, buf_offset);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
- WRITE_VREG(AVS_SOS_COUNT, 0);
- WRITE_VREG(AVS_BUFFERIN, 0);
- WRITE_VREG(AVS_BUFFEROUT, 0);
- if (error_recovery_mode)
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
- else
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-#if 1 /* def DEBUG_UCODE */
- WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
-
-#ifdef PIC_DC_NEED_CLEAR
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
- WRITE_VREG(LONG_CABAC_REQ, 0);
- WRITE_VREG(LONG_CABAC_PIC_SIZE, 0);
- WRITE_VREG(LONG_CABAC_SRC_ADDR, 0);
- }
-#endif
-
- WRITE_VREG(AV_SCRATCH_N, (u32)(user_data_buffer_phys - buf_offset));
- pr_info("support_user_data = %d\n", support_user_data);
- if (support_user_data)
- WRITE_VREG(AV_SCRATCH_M, 1);
- else
- WRITE_VREG(AV_SCRATCH_M, 0);
-
- return r;
-}
-
-#ifdef AVSP_LONG_CABAC
-static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64);
-#endif
-static void vavs_local_init(bool is_reset)
-{
- int i;
-
- is_reset = 0;
- vavs_ratio = vavs_amstream_dec_info.ratio;
-
- avi_flag = (unsigned long) vavs_amstream_dec_info.param;
-
- frame_width = frame_height = frame_dur = frame_prog = 0;
-
- throw_pb_flag = 1;
-
- total_frame = 0;
- saved_resolution = 0;
- next_pts = 0;
-
-#ifdef DEBUG_PTS
- pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0;
-#endif
-
- if (!is_reset) {
- INIT_KFIFO(display_q);
- INIT_KFIFO(recycle_q);
- INIT_KFIFO(newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &vfpool[i];
-
- vfpool[i].index = vf_buf_num;
- vfpool[i].bufWidth = 1920;
- kfifo_put(&newframe_q, vf);
- }
-
- for (i = 0; i < vf_buf_num; i++)
- vfbuf_use[i] = 0;
- }
-
- cur_vfpool = vfpool;
-
- if (recover_flag == 1)
- return;
-
- if (mm_blk_handle) {
- decoder_bmmu_box_free(mm_blk_handle);
- mm_blk_handle = NULL;
- }
-
- mm_blk_handle = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- 0,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER);
-
-}
-
-static int vavs_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&lock, flags);
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&newframe_q);
- states->buf_avail_num = kfifo_len(&display_q);
- states->buf_recycle_num = kfifo_len(&recycle_q);
- spin_unlock_irqrestore(&lock, flags);
- return 0;
-}
-
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
-static void vavs_ppmgr_reset(void)
-{
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
-
- vavs_local_init(true);
-
- pr_info("vavs: vf_ppmgr_reset\n");
-}
-#endif
-
-static void vavs_local_reset(void)
-{
- mutex_lock(&vavs_mutex);
- //recover_flag = 1;
- pr_info("error, local reset\n");
- amvdec_stop();
- msleep(100);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
- vavs_local_init(true);
- vavs_recover();
-
-
- reset_userdata_fifo(1);
-
-
- amvdec_start();
- recover_flag = 0;
-#if 0
- error_watchdog_count = 0;
-
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
-#endif
-
-
-
- mutex_unlock(&vavs_mutex);
-}
-
-static struct work_struct fatal_error_wd_work;
-static struct work_struct notify_work;
-static atomic_t error_handler_run = ATOMIC_INIT(0);
-static void vavs_fatal_error_handler(struct work_struct *work)
-{
- if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) {
- mutex_lock(&vavs_mutex);
- pr_info("vavs fatal error reset !\n");
- amvdec_stop();
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vavs_ppmgr_reset();
-#else
- vf_light_unreg_provider(&vavs_vf_prov);
- vavs_local_init(true);
- vf_reg_provider(&vavs_vf_prov);
-#endif
- vavs_recover();
- amvdec_start();
- mutex_unlock(&vavs_mutex);
- } else {
- pr_info("avs fatal_error_handler\n");
- vavs_local_reset();
- }
- atomic_set(&error_handler_run, 0);
-}
-
-static void vavs_notify_work(struct work_struct *work)
-{
- if (fr_hint_status == VDEC_NEED_HINT) {
- vf_notify_receiver(PROVIDER_NAME ,
- VFRAME_EVENT_PROVIDER_FR_HINT ,
- (void *)((unsigned long)frame_dur));
- fr_hint_status = VDEC_HINTED;
- }
- return;
-}
-
-static void avs_set_clk(struct work_struct *work)
-{
- int fps = 96000 / frame_dur;
-
- saved_resolution = frame_width * frame_height * fps;
- if (firmware_sel == 0 &&
- (debug_flag & AVS_DEBUG_USE_FULL_SPEED)) {
- vdec_source_changed(VFORMAT_AVS,
- 4096, 2048, 60);
- } else {
- vdec_source_changed(VFORMAT_AVS,
- frame_width, frame_height, fps);
- }
-}
-
-static void vavs_put_timer_func(struct timer_list *timer)
-{
-#ifndef HANDLE_AVS_IRQ
- vavs_isr();
-#endif
-
- if (READ_VREG(AVS_SOS_COUNT)) {
- if (!error_recovery_mode) {
-#if 0
- if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) {
- mutex_lock(&vavs_mutex);
- pr_info("vavs fatal error reset !\n");
- amvdec_stop();
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vavs_ppmgr_reset();
-#else
- vf_light_unreg_provider(&vavs_vf_prov);
- vavs_local_init(true);
- vf_reg_provider(&vavs_vf_prov);
-#endif
- vavs_recover();
- amvdec_start();
- mutex_unlock(&vavs_mutex);
- } else {
- vavs_local_reset();
- }
-#else
- if (!atomic_read(&error_handler_run)) {
- atomic_set(&error_handler_run, 1);
- pr_info("AVS_SOS_COUNT = %d\n",
- READ_VREG(AVS_SOS_COUNT));
- pr_info("WP = 0x%x, RP = 0x%x, LEVEL = 0x%x, AVAIL = 0x%x, CUR_PTR = 0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL),
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
- schedule_work(&fatal_error_wd_work);
- }
-#endif
- }
- }
-#if 0
- if (long_cabac_busy == 0 &&
- error_watchdog_threshold > 0 &&
- kfifo_len(&display_q) == 0 &&
- READ_VREG(VLD_MEM_VIFIFO_LEVEL) >
- error_watchdog_buf_threshold) {
- pr_info("newq %d dispq %d recyq %d\r\n",
- kfifo_len(&newframe_q),
- kfifo_len(&display_q),
- kfifo_len(&recycle_q));
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- error_watchdog_count++;
- if (error_watchdog_count >= error_watchdog_threshold)
- vavs_local_reset();
- } else
- error_watchdog_count = 0;
-#endif
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (!kfifo_is_empty(&recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
- struct vframe_s *vf;
-
- if (kfifo_get(&recycle_q, &vf)) {
- if ((vf->index < vf_buf_num) &&
- (--vfbuf_use[vf->index] == 0)) {
- WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
- vf->index = vf_buf_num;
- }
- kfifo_put(&newframe_q,
- (const struct vframe_s *)vf);
- }
- }
-
- if (frame_dur > 0 && saved_resolution !=
- frame_width * frame_height * (96000 / frame_dur))
- schedule_work(&set_clk_work);
-
- timer->expires = jiffies + PUT_INTERVAL;
-
- add_timer(timer);
-}
-
-#ifdef AVSP_LONG_CABAC
-
-static void long_cabac_do_work(struct work_struct *work)
-{
- int status = 0;
-#ifdef PERFORMANCE_DEBUG
- pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&newframe_q),
- kfifo_len(&display_q),
- kfifo_len(&recycle_q)
- );
-#endif
- mutex_lock(&vavs_mutex);
- long_cabac_busy = 1;
- while (READ_VREG(LONG_CABAC_REQ)) {
- if (process_long_cabac() < 0) {
- status = -1;
- break;
- }
- }
- long_cabac_busy = 0;
- mutex_unlock(&vavs_mutex);
-#ifdef PERFORMANCE_DEBUG
- pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&newframe_q),
- kfifo_len(&display_q),
- kfifo_len(&recycle_q)
- );
-#endif
- if (status < 0) {
- pr_info("transcoding error, local reset\r\n");
- vavs_local_reset();
- }
-
-}
-#endif
-
-#ifdef AVSP_LONG_CABAC
-static void init_avsp_long_cabac_buf(void)
-{
-#if 0
- es_write_addr_phy = (unsigned long)codec_mm_alloc_for_dma(
- "vavs",
- PAGE_ALIGN(MAX_CODED_FRAME_SIZE)/PAGE_SIZE,
- 0, CODEC_MM_FLAGS_DMA_CPU);
- es_write_addr_virt = codec_mm_phys_to_virt(es_write_addr_phy);
-
-#elif 0
- es_write_addr_virt =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- MAX_CODED_FRAME_SIZE, &es_write_addr_phy,
- GFP_KERNEL);
-#else
- /*es_write_addr_virt = kmalloc(MAX_CODED_FRAME_SIZE, GFP_KERNEL);
- * es_write_addr_virt = (void *)__get_free_pages(GFP_KERNEL,
- * get_order(MAX_CODED_FRAME_SIZE));
- */
- es_write_addr_virt = &es_write_addr[0];
- if (es_write_addr_virt == NULL) {
- pr_err("%s: failed to alloc es_write_addr_virt buffer\n",
- __func__);
- return;
- }
-
- es_write_addr_phy = dma_map_single(amports_get_dma_device(),
- es_write_addr_virt,
- MAX_CODED_FRAME_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(amports_get_dma_device(),
- es_write_addr_phy)) {
- pr_err("%s: failed to map es_write_addr_virt buffer\n",
- __func__);
- /*kfree(es_write_addr_virt);*/
- es_write_addr_virt = NULL;
- return;
- }
-#endif
-
-
-#ifdef BITSTREAM_READ_TMP_NO_CACHE
- bitstream_read_tmp =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy,
- GFP_KERNEL);
-
-#else
-
- bitstream_read_tmp = kmalloc(SVA_STREAM_BUF_SIZE, GFP_KERNEL);
- /*bitstream_read_tmp = (void *)__get_free_pages(GFP_KERNEL,
- *get_order(MAX_CODED_FRAME_SIZE));
- */
- if (bitstream_read_tmp == NULL) {
- pr_err("%s: failed to alloc bitstream_read_tmp buffer\n",
- __func__);
- return;
- }
-
- bitstream_read_tmp_phy = dma_map_single(amports_get_dma_device(),
- bitstream_read_tmp,
- SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- bitstream_read_tmp_phy)) {
- pr_err("%s: failed to map rpm buffer\n", __func__);
- kfree(bitstream_read_tmp);
- bitstream_read_tmp = NULL;
- return;
- }
-#endif
-}
-#endif
-
-
-static s32 vavs_init(void)
-{
- int ret, size = -1;
- char *buf = vmalloc(0x1000 * 16);
-
- if (IS_ERR_OR_NULL(buf))
- return -ENOMEM;
-
- pr_info("vavs_init\n");
-
- stat |= STAT_TIMER_INIT;
-
- amvdec_enable();
- vavs_local_init(false);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- size = get_firmware_data(VIDEO_DEC_AVS, buf);
- else {
- if (firmware_sel == 1)
- size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, buf);
-#ifdef AVSP_LONG_CABAC
- else {
- init_avsp_long_cabac_buf();
- size = get_firmware_data(VIDEO_DEC_AVS, buf);
- }
-#endif
- }
-
- if (size < 0) {
- amvdec_disable();
- pr_err("get firmware fail.");
- vfree(buf);
- return -1;
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf);
- else if (firmware_sel == 1)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", buf);
- else
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf);
-
- if (ret < 0) {
- amvdec_disable();
- vfree(buf);
- pr_err("AVS: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- vfree(buf);
-
- stat |= STAT_MC_LOAD;
-
- /* enable AMRISC side protocol */
- ret = vavs_prot_init();
- if (ret < 0)
- return ret;
-
-#ifdef HANDLE_AVS_IRQ
- if (vdec_request_irq(VDEC_IRQ_1, vavs_isr,
- "vavs-irq", (void *)vavs_dec_id)) {
- amvdec_disable();
- pr_info("vavs irq register error.\n");
- return -ENOENT;
- }
-#endif
-
- stat |= STAT_ISR_REG;
-
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL);
- vf_reg_provider(&vavs_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
-#else
- vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL);
- vf_reg_provider(&vavs_vf_prov);
-#endif
-
- if (vavs_amstream_dec_info.rate != 0) {
- if (!is_reset) {
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)
- vavs_amstream_dec_info.rate));
- fr_hint_status = VDEC_HINTED;
- }
- } else
- fr_hint_status = VDEC_NEED_HINT;
-
- stat |= STAT_VF_HOOK;
-
- timer_setup(&recycle_timer, vavs_put_timer_func, 0);
- recycle_timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&recycle_timer);
-
- stat |= STAT_TIMER_ARM;
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0)
- INIT_WORK(&long_cabac_wd_work, long_cabac_do_work);
-#endif
- vdec_source_changed(VFORMAT_AVS,
- 1920, 1080, 30);
- amvdec_start();
-
- stat |= STAT_VDEC_RUN;
-
- return 0;
-}
-
-static int amvdec_avs_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
-
- if (pdata == NULL) {
- pr_info("amvdec_avs memory resource undefined.\n");
- return -EFAULT;
- }
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
- firmware_sel = 1;
-
- if (firmware_sel == 1) {
- vf_buf_num = 8;
- canvas_base = 0;
- canvas_num = 2;
- } else {
-
- canvas_base = 128;
- canvas_num = 2; /*NV21*/
- }
-
-
- if (pdata->sys_info)
- vavs_amstream_dec_info = *pdata->sys_info;
-
- pr_info("%s (%d,%d) %d\n", __func__, vavs_amstream_dec_info.width,
- vavs_amstream_dec_info.height, vavs_amstream_dec_info.rate);
-
- pdata->dec_status = vavs_dec_status;
- pdata->set_isreset = vavs_set_isreset;
- is_reset = 0;
-
- pdata->user_data_read = NULL;
- pdata->reset_userdata_fifo = NULL;
-
- vavs_vdec_info_init();
-
-
- if (NULL == user_data_buffer) {
- user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
- USER_DATA_SIZE,
- &user_data_buffer_phys, GFP_KERNEL);
- if (!user_data_buffer) {
- pr_info("%s: Can not allocate user_data_buffer\n",
- __func__);
- return -ENOMEM;
- }
- pr_debug("user_data_buffer = 0x%p, user_data_buffer_phys = 0x%x\n",
- user_data_buffer, (u32)user_data_buffer_phys);
- }
-
- INIT_WORK(&set_clk_work, avs_set_clk);
- vdec = pdata;
-
- INIT_WORK(&fatal_error_wd_work, vavs_fatal_error_handler);
- atomic_set(&error_handler_run, 0);
-
- INIT_WORK(&userdata_push_work, userdata_push_do_work);
- INIT_WORK(¬ify_work, vavs_notify_work);
-
- if (vavs_init() < 0) {
- pr_info("amvdec_avs init failed.\n");
- kfree(gvs);
- gvs = NULL;
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- return 0;
-}
-
-static int amvdec_avs_remove(struct platform_device *pdev)
-{
- if (stat & STAT_TIMER_ARM) {
- del_timer_sync(&recycle_timer);
- stat &= ~STAT_TIMER_ARM;
- }
- cancel_work_sync(&fatal_error_wd_work);
- atomic_set(&error_handler_run, 0);
-
- cancel_work_sync(&userdata_push_work);
-
- cancel_work_sync(¬ify_work);
- if (stat & STAT_VDEC_RUN) {
- amvdec_stop();
- stat &= ~STAT_VDEC_RUN;
- }
-
- if (stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id);
- stat &= ~STAT_ISR_REG;
- }
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- mutex_lock(&vavs_mutex);
- cancel_work_sync(&long_cabac_wd_work);
- mutex_unlock(&vavs_mutex);
-
- if (es_write_addr_virt) {
-#if 0
- codec_mm_free_for_dma("vavs", es_write_addr_phy);
-#else
- dma_unmap_single(amports_get_dma_device(),
- es_write_addr_phy,
- MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE);
- /*kfree(es_write_addr_virt);*/
- es_write_addr_virt = NULL;
-#endif
- }
-
-#ifdef BITSTREAM_READ_TMP_NO_CACHE
- if (bitstream_read_tmp) {
- dma_free_coherent(amports_get_dma_device(),
- SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
- bitstream_read_tmp_phy);
- bitstream_read_tmp = NULL;
- }
-#else
- if (bitstream_read_tmp) {
- dma_unmap_single(amports_get_dma_device(),
- bitstream_read_tmp_phy,
- SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
- kfree(bitstream_read_tmp);
- bitstream_read_tmp = NULL;
- }
-#endif
- }
-#endif
- if (stat & STAT_VF_HOOK) {
- if (fr_hint_status == VDEC_HINTED)
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
- fr_hint_status = VDEC_NO_NEED_HINT;
- vf_unreg_provider(&vavs_vf_prov);
- stat &= ~STAT_VF_HOOK;
- }
-
-
- if (user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
- USER_DATA_SIZE,
- user_data_buffer,
- user_data_buffer_phys);
- user_data_buffer = NULL;
- user_data_buffer_phys = 0;
- }
-
-
- amvdec_disable();
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TM2)
- vdec_reset_core(NULL);
- pic_type = 0;
- if (mm_blk_handle) {
- decoder_bmmu_box_free(mm_blk_handle);
- mm_blk_handle = NULL;
- }
-#ifdef DEBUG_PTS
- pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit,
- pts_missed, pts_i_hit, pts_i_missed);
- pr_debug("total frame %d, avi_flag %d, rate %d\n", total_frame, avi_flag,
- vavs_amstream_dec_info.rate);
-#endif
- kfree(gvs);
- gvs = NULL;
- vdec = NULL;
-
- cancel_work_sync(&set_clk_work);
- return 0;
-}
-
-/****************************************/
-#ifdef CONFIG_PM
-static int avs_suspend(struct device *dev)
-{
- amvdec_suspend(to_platform_device(dev), dev->power.power_state);
- return 0;
-}
-
-static int avs_resume(struct device *dev)
-{
- amvdec_resume(to_platform_device(dev));
- return 0;
-}
-
-static const struct dev_pm_ops avs_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(avs_suspend, avs_resume)
-};
-#endif
-
-static struct platform_driver amvdec_avs_driver = {
- .probe = amvdec_avs_probe,
- .remove = amvdec_avs_remove,
- .driver = {
- .name = DRIVER_NAME,
-#ifdef CONFIG_PM
- .pm = &avs_pm_ops,
-#endif
- }
-};
-
-static struct codec_profile_t amvdec_avs_profile = {
- .name = "avs",
- .profile = ""
-};
-
-static struct mconfig avs_configs[] = {
- MC_PU32("stat", &stat),
- MC_PU32("debug_flag", &debug_flag),
- MC_PU32("error_recovery_mode", &error_recovery_mode),
- MC_PU32("pic_type", &pic_type),
- MC_PU32("radr", &radr),
- MC_PU32("vf_buf_num", &vf_buf_num),
- MC_PU32("vf_buf_num_used", &vf_buf_num_used),
- MC_PU32("canvas_base", &canvas_base),
- MC_PU32("firmware_sel", &firmware_sel),
-};
-static struct mconfig_node avs_node;
-
-
-static int __init amvdec_avs_driver_init_module(void)
-{
- pr_debug("amvdec_avs module init\n");
-
- if (platform_driver_register(&amvdec_avs_driver)) {
- pr_info("failed to register amvdec_avs driver\n");
- return -ENODEV;
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- amvdec_avs_profile.profile = "avs+";
-
- vcodec_profile_register(&amvdec_avs_profile);
- INIT_REG_NODE_CONFIGS("media.decoder", &avs_node,
- "avs", avs_configs, CONFIG_FOR_RW);
- return 0;
-}
-
-static void __exit amvdec_avs_driver_remove_module(void)
-{
- pr_debug("amvdec_avs module remove.\n");
-
- platform_driver_unregister(&amvdec_avs_driver);
-}
-
-/****************************************/
-
-module_param(stat, uint, 0664);
-MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n");
-
-/******************************************
- *module_param(run_flag, uint, 0664);
- *MODULE_PARM_DESC(run_flag, "\n run_flag\n");
- *
- *module_param(step_flag, uint, 0664);
- *MODULE_PARM_DESC(step_flag, "\n step_flag\n");
- *******************************************
- */
-
-module_param(debug_flag, uint, 0664);
-MODULE_PARM_DESC(debug_flag, "\n debug_flag\n");
-
-module_param(error_recovery_mode, uint, 0664);
-MODULE_PARM_DESC(error_recovery_mode, "\n error_recovery_mode\n");
-
-/******************************************
- *module_param(error_watchdog_threshold, uint, 0664);
- *MODULE_PARM_DESC(error_watchdog_threshold, "\n error_watchdog_threshold\n");
- *
- *module_param(error_watchdog_buf_threshold, uint, 0664);
- *MODULE_PARM_DESC(error_watchdog_buf_threshold,
- * "\n error_watchdog_buf_threshold\n");
- *******************************************
- */
-
-module_param(pic_type, uint, 0444);
-MODULE_PARM_DESC(pic_type, "\n amdec_vas picture type\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(vf_buf_num, uint, 0664);
-MODULE_PARM_DESC(vf_buf_num, "\nvf_buf_num\n");
-
-module_param(vf_buf_num_used, uint, 0664);
-MODULE_PARM_DESC(vf_buf_num_used, "\nvf_buf_num_used\n");
-
-module_param(canvas_base, uint, 0664);
-MODULE_PARM_DESC(canvas_base, "\ncanvas_base\n");
-
-
-module_param(firmware_sel, uint, 0664);
-MODULE_PARM_DESC(firmware_sel, "\n firmware_sel\n");
-
-module_param(disable_longcabac_trans, uint, 0664);
-MODULE_PARM_DESC(disable_longcabac_trans, "\n disable_longcabac_trans\n");
-
-module_param(dec_control, uint, 0664);
-MODULE_PARM_DESC(dec_control, "\n amvdec_vavs decoder control\n");
-
-module_param(support_user_data, uint, 0664);
-MODULE_PARM_DESC(support_user_data, "\n support_user_data\n");
-
-module_init(amvdec_avs_driver_init_module);
-module_exit(amvdec_avs_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC AVS Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/avs/avs.h b/drivers/frame_provider/decoder/avs/avs.h
deleted file mode 100644
index 8277d20..0000000
--- a/drivers/frame_provider/decoder/avs/avs.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef AVS_H_
-#define AVS_H_
-
-#ifdef CONFIG_AMLOGIC_AVSP_LONG_CABAC
-#define AVSP_LONG_CABAC
-#endif
-/*#define BITSTREAM_READ_TMP_NO_CACHE*/
-
-#ifdef AVSP_LONG_CABAC
-#define MAX_CODED_FRAME_SIZE 1500000 /*!< bytes for one frame*/
-#define LOCAL_HEAP_SIZE (1024*1024*10)
-/*
- *#define MAX_CODED_FRAME_SIZE 240000
- *#define MAX_CODED_FRAME_SIZE 700000
- */
-#define SVA_STREAM_BUF_SIZE 1024
-
-extern void *es_write_addr_virt;
-extern dma_addr_t es_write_addr_phy;
-
-extern void *bitstream_read_tmp;
-extern dma_addr_t bitstream_read_tmp_phy;
-extern void *avsp_heap_adr;
-
-int avs_get_debug_flag(void);
-
-int process_long_cabac(void);
-
-/* bit [6] - skip_mode_flag
- * bit [5:4] - picture_type
- * bit [3] - picture_structure (0-Field, 1-Frame)
- * bit [2] - fixed_picture_qp
- * bit [1] - progressive_sequence
- * bit [0] - active
- */
-#define LONG_CABAC_REQ AV_SCRATCH_K
-#define LONG_CABAC_SRC_ADDR AV_SCRATCH_H
-#define LONG_CABAC_DES_ADDR AV_SCRATCH_I
-/* bit[31:16] - vertical_size
- * bit[15:0] - horizontal_size
- */
-#define LONG_CABAC_PIC_SIZE AV_SCRATCH_J
-
-#endif
-
-/*
- *#define PERFORMANCE_DEBUG
- *#define DUMP_DEBUG
- */
-#define AVS_DEBUG_PRINT 0x01
-#define AVS_DEBUG_UCODE 0x02
-#define AVS_DEBUG_OLD_ERROR_HANDLE 0x10
-#define AVS_DEBUG_USE_FULL_SPEED 0x80
-#define AEC_DUMP 0x100
-#define STREAM_INFO_DUMP 0x200
-#define SLICE_INFO_DUMP 0x400
-#define MB_INFO_DUMP 0x800
-#define MB_NUM_DUMP 0x1000
-#define BLOCK_NUM_DUMP 0x2000
-#define COEFF_DUMP 0x4000
-#define ES_DUMP 0x8000
-#define DQUANT_DUMP 0x10000
-#define STREAM_INFO_DUMP_MORE 0x20000
-#define STREAM_INFO_DUMP_MORE2 0x40000
-
-extern void *es_write_addr_virt;
-extern void *bitstream_read_tmp;
-extern dma_addr_t bitstream_read_tmp_phy;
-int read_bitstream(unsigned char *Buf, int size);
-int u_v(int LenInBits, char *tracestring);
-
-#endif
diff --git a/drivers/frame_provider/decoder/avs/avsp_trans.c b/drivers/frame_provider/decoder/avs/avsp_trans.c
deleted file mode 100644
index a92dbb9..0000000
--- a/drivers/frame_provider/decoder/avs/avsp_trans.c
+++ /dev/null
@@ -1,5065 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/dma-mapping.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/slab.h>
-/* #include <mach/am_regs.h> */
-#include <linux/module.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../stream_input/amports/streambuf_reg.h"
-#include "../utils/amvdec.h"
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-
-#include "avs.h"
-#ifdef AVSP_LONG_CABAC
-
-#define DECODING_SANITY_CHECK
-
-#define TRACE 0
-#define LIWR_FIX 0
-#define pow2(a, b) (1<<b)
-#define io_printf pr_info
-
-static unsigned char *local_heap_adr;
-static int local_heap_size;
-static int local_heap_pos;
-static int transcoding_error_flag;
-
-unsigned char *local_alloc(int num, int size)
-{
- unsigned char *ret_buf = NULL;
- int alloc_size = num * size;
-
- if ((local_heap_pos + alloc_size) <= local_heap_size) {
- ret_buf = local_heap_adr + local_heap_pos;
- local_heap_pos += alloc_size;
- } else {
- pr_info(
- "!!!local_alloc(%d) error, local_heap (size %d) is not enough\r\n",
- alloc_size, local_heap_size);
- }
- return ret_buf;
-}
-
-int local_heap_init(int size)
-{
- /*local_heap_adr = &local_heap[0];*/
- local_heap_adr = (unsigned char *)(avsp_heap_adr +
- MAX_CODED_FRAME_SIZE);
- memset(local_heap_adr, 0, LOCAL_HEAP_SIZE);
-
- local_heap_size = LOCAL_HEAP_SIZE;
- local_heap_pos = 0;
- return 0;
-}
-
-void local_heap_uninit(void)
-{
- local_heap_adr = NULL;
- local_heap_size = 0;
- local_heap_pos = 0;
-}
-
-#define CODE2D_ESCAPE_SYMBOL 59
-
-const int vlc_golomb_order[3][7][2] =
-
-{{{2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{3, 9}, {2, 9}, {
- 2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{2, 9}, {0, 9},
- {1, 9}, {1, 9}, {0, 9}, {-1, -1}, {-1, -1}, }, };
-
-const int MaxRun[3][7] = {{22, 14, 9, 6, 4, 2, 1}, {25, 18, 13, 9, 6, 4, 3}, {
- 24, 19, 10, 7, 4, -1, -1} };
-
-const int refabslevel[19][26] = {{4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1}, {7, 4, 4, 3, 3, 3, 3, 3, 2,
- 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, 3, 2, 2, -1, -1,
- -1 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, 7, 3, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4,
- 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2}, {5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 5, 4, 4, 3, 3, 3, 2, 2,
- 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4,
- 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {17, 8, 4,
- 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1}, {6, 4, 3,
- 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, -1, -1, -1, -1, -1, -1}, {10, 6, 4, 4, 3, 3,
- 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {14, 7, 4, 3, 3, 2,
- 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1}, {20, 7, 3, 2,
- 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} };
-
-static const int incvlc_intra[7] = {0, 1, 2, 4, 7, 10, 3000};
-static const int incvlc_chroma[5] = {0, 1, 2, 4, 3000};
-
-const int AVS_2DVLC_INTRA[7][26][27] = {{{0, 22, 38, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {2, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 44, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {6, 50, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {8, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {18, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {46, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {52, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {56, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 4, 15, 27, 41,
- 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, 2, 17, 35, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {-1, 6, 25, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 9, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 11, 39, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 13, 45, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 19, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 21, 51, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 31, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 37, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 47, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 2, 6,
- 13, 17, 27, 35, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 4, 11, 21, 33, 49, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, 9, 23, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 15,
- 29, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, 39, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, 25, 43, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, 31, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 41,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, 57, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, }, {{8, 0, 2, 4, 9, 11, 17, 21, 25, 33, 39, 45, 55, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 6, 13, 19,
- 29, 35, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 15, 27, 41, 57, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 23, 37, 53, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 31, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 43, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, }, {{6, 0, 2, 4, 7, 9, 11, 15, 17,
- 21, 23, 29, 33, 35, 43, 47, 49, 57, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, 13, 19, 27, 31, 37, 45, 55, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 25, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 39, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 53, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0,
- 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 27, 31, 33, 37, 41,
- 45, 49, 51, 55, -1, -1, -1, -1, -1}, {-1, 21, 29, 35, 43, 47,
- 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, 39, 57, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, }, {{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
- 21, 23, 25, 27, 29, 31, 35, 37, 39, 41, 43, 47, 49, 51, 53, 57},
- {-1, 33, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} } };
-
-const int AVS_2DVLC_CHROMA[5][26][27] = {{{0, 14, 32, 56, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {2, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1}, {6, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {38,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {46,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {50, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {52, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0, 1, 5, 15, 29,
- 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 3, 21, 45, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1}, {-1, 7, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 9, 41, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 11, 53, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 31, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 33, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, },
- {{2, 0, 3, 7, 11, 17, 27, 33, 47, 53, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
- -1, 5, 13, 21, 37, 55, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 9, 23, 41, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 15, 31, 57, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 19, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, 25, 45, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 29, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, 39, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, }, {{0, 1, 3, 5, 7, 11, 15, 19, 23, 29,
- 35, 43, 47, 53, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1}, {-1, 9, 13, 21, 31, 39, 51,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 17, 27,
- 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {-1, 25, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, 33, 55, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 45, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, 49, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, 57, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1}, {-1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1}, },
- {{0, 1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 27, 29, 33, 37, 41,
- 43, 51, 55, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 17, 25, 31, 39, 45, 53, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, 35, 49, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1}, } };
-
-const int UE[64][2] = {{1, 1}, {2, 3}, {3, 3}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {
- 8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15,
- 7}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9},
- {22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {
- 29, 9}, {30, 9}, {31, 9}, {32, 11}, {33, 11}, {
- 34, 11}, {35, 11}, {36, 11}, {37, 11}, {38, 11},
- {39, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45,
- 11}, {46, 11}, {47, 11}, {48, 11}, {49, 11}, {
- 50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11},
- {55, 11}, {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61,
- 11}, {62, 11}, {63, 11}, {64, 13} };
-
-unsigned int src_start;
-unsigned int des_start;
-
-#ifdef AVSP_LONG_CABAC
-
-unsigned char *es_buf;
-unsigned int es_buf_ptr;
-unsigned int es_buf_is_overflow;
-
-#else
-FILE *f_es;
-#endif
-unsigned int es_ptr;
-unsigned int es_res;
-unsigned int es_res_ptr;
-unsigned int previous_es;
-
-void init_es(void)
-{
-
-#ifdef AVSP_LONG_CABAC
- es_buf_is_overflow = 0;
-
- es_buf[0] = 0x00;
- es_buf[1] = 0x00;
- es_buf[2] = 0x01;
- es_buf_ptr = 3;
- es_ptr = 3;
-#else
- f_es = fopen("es.out", "wb");
- if (f_es == NULL)
- io_printf(" ERROR : Can not open es.out for write\n");
- putc(0x00, f_es);
- putc(0x00, f_es);
- putc(0x01, f_es);
-
- es_ptr = 3;
-#endif
- es_res = 0;
- es_res_ptr = 0;
- previous_es = 0xff;
-
-}
-
-void push_es(int value, int num)
-{
- unsigned char wr_es_data;
- int push_num;
- int push_value;
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & ES_DUMP)
- io_printf(" push_es : value : 0x%x, num : %d\n", value, num);
-#endif
- while (num > 0) {
- if (num >= 8)
- push_num = 8;
- else
- push_num = num;
-
- num = num - push_num;
- push_value = (value >> num);
-
- es_res = (es_res << push_num) | push_value;
- es_res_ptr = es_res_ptr + push_num;
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & ES_DUMP)
- io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n",
- es_res, es_res_ptr);
-#endif
-
- while (es_res_ptr >= 8) {
- es_res_ptr = es_res_ptr & 7;
- wr_es_data = (es_res >> es_res_ptr) & 0xff;
- if ((previous_es == 0) & (wr_es_data < 4)) {
- io_printf(
- " Insert 2'b10 for emu at position : %d\n",
- es_ptr);
-
- es_res_ptr = es_res_ptr + 2;
- wr_es_data = 2;
- }
-#ifdef AVSP_LONG_CABAC
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & ES_DUMP)
- pr_info("es_buf[%d] = 0x%02x\r\n",
- es_buf_ptr, wr_es_data);
-#endif
- if (!es_buf_is_overflow) {
- es_buf[es_buf_ptr++] = wr_es_data;
- if (es_buf_ptr >= MAX_CODED_FRAME_SIZE)
- es_buf_is_overflow = 1;
- }
-#else
- putc(wr_es_data, f_es);
-#endif
- es_ptr++;
- previous_es = ((previous_es << 8) | wr_es_data)
- & 0xffff;
- }
-
- }
-}
-
-#ifdef BLOCK_SIZE
-#undef BLOCK_SIZE
-#endif
-
-#define MIN_QP 0
-#define MAX_QP 63
-
-#define BLOCK_SIZE 4
-#define B8_SIZE 8
-#define MB_BLOCK_SIZE 16
-
-#define BLOCK_MULTIPLE (MB_BLOCK_SIZE/(BLOCK_SIZE*2))
-
-#define DECODE_COPY_MB 0
-#define DECODE_MB 1
-
-#define NO_INTRA_PMODE 5
-#define INTRA_PMODE_4x4 10
-#define NO_INTRA_PMODE_4x4 19
-/* 8x8 intra prediction modes */
-#define VERT_PRED 0
-#define HOR_PRED 1
-#define DC_PRED 2
-#define DOWN_LEFT_PRED 3
-#define DOWN_RIGHT_PRED 4
-
-#define VERT_PRED_4x4 0
-#define HOR_PRED_4x4 1
-#define DC_PRED_4x4 2
-#define DOWN_LEFT_PRED_4x4 3
-#define DOWN_RIGHT_PRED_4x4 4
-
-#define HOR_DOWN_PRED_4x4 5
-#define VERT_LEFT_PRED_4x4 6
-#define HOR_UP_PRED_4x4 7
-#define VERT_RIGHT_PRED_4x4 8
-
-#define DC_PRED_8 0
-#define HOR_PRED_8 1
-#define VERT_PRED_8 2
-#define PLANE_8 3
-
-#define LUMA_16DC 0
-#define LUMA_16AC 1
-#define LUMA_8x8 2
-#define LUMA_8x4 3
-#define LUMA_4x8 4
-#define LUMA_4x4 5
-#define CHROMA_DC 6
-#define CHROMA_AC 7
-#define NUM_BLOCK_TYPES 8
-
-#define I_PICTURE_START_CODE 0xB3
-#define PB_PICTURE_START_CODE 0xB6
-#define SLICE_START_CODE_MIN 0x00
-#define SLICE_START_CODE_MAX 0xAF
-#define USER_DATA_START_CODE 0xB2
-#define SEQUENCE_HEADER_CODE 0xB0
-#define EXTENSION_START_CODE 0xB5
-#define SEQUENCE_END_CODE 0xB1
-#define VIDEO_EDIT_CODE 0xB7
-
-#define EOS 1
-#define SOP 2
-#define SOS 3
-#define P8x8 8
-#define I8MB 9
-#define I4MB 10
-#define IBLOCK 11
-#define SI4MB 12
-#define MAXMODE 13
-
-#define IS_INTRA(MB) ((MB)->mb_type == I8MB || (MB)->mb_type == I4MB)
-#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB)
-#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB)
-#define IS_INTER(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB)
-#define IS_INTERMV(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB\
- && (MB)->mb_type != 0)
-
-#define IS_DIRECT(MB) ((MB)->mb_type == 0 && (img->type == B_IMG))
-#define IS_COPY(MB) ((MB)->mb_type == 0 && (img->type == P_IMG))
-#define IS_P8x8(MB) ((MB)->mb_type == P8x8)
-
-#define P_IMG 0
-#define B_IMG 1
-#define I_IMG 2
-
-#define FIELD 0
-#define FRAME 1
-
-#define SE_CABP 21
-struct decoding_environment_s {
- unsigned int dbuffer;
- int dbits_to_go;
- unsigned char *dcodestrm;
- int *dcodestrm_len;
-};
-
-struct bi_context_type_s {
- unsigned char MPS;
- unsigned int LG_PMPS;
- unsigned char cycno;
-};
-
-
-/**********************************************************************
- * C O N T E X T S F O R R M S Y N T A X E L E M E N T S
- **********************************************************************
- */
-
-#define NUM_MB_TYPE_CTX 11
-#define NUM_B8_TYPE_CTX 9
-#define NUM_MV_RES_CTX 10
-#define NUM_REF_NO_CTX 6
-#define NUM_DELTA_QP_CTX 4
-#define NUM_MB_AFF_CTX 4
-
-struct motion_info_contexts_s {
- struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX];
- struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX];
- struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX];
- struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX];
- struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX];
- struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX];
-#ifdef TEST_WEIGHTING_AEC
-struct bi_context_type_s mb_weighting_pred;
-#endif
-};
-
-#define NUM_IPR_CTX 2
-#define NUM_CIPR_CTX 4
-#define NUM_CBP_CTX 4
-#define NUM_BCBP_CTX 4
-#define NUM_MAP_CTX 16
-#define NUM_LAST_CTX 16
-
-#define NUM_ONE_CTX 5
-#define NUM_ABS_CTX 5
-
-struct texture_info_contexts {
- struct bi_context_type_s ipr_contexts[NUM_IPR_CTX];
- struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX];
- struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX];
- struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX];
- struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX];
- struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX];
- struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
- struct bi_context_type_s fld_last_contexts
- [NUM_BLOCK_TYPES][NUM_LAST_CTX];
- struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
- struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
-};
-struct img_par;
-
-struct syntaxelement {
- int type;
- int value1;
- int value2;
- int len;
- int inf;
- unsigned int bitpattern;
- int context;
- int k;
- int golomb_grad;
- int golomb_maxlevels;
-#if TRACE
-#define TRACESTRING_SIZE 100
- char tracestring[TRACESTRING_SIZE];
-#endif
-
- void (*mapping)(int len, int info, int *value1, int *value2);
-
- void (*reading)(struct syntaxelement *, struct img_par *,
- struct decoding_environment_s *);
-
-};
-
-struct bitstream_s {
-
- int read_len;
- int code_len;
-
- int frame_bitoffset;
- int bitstream_length;
-
- unsigned char *stream_buffer;
-};
-
-struct datapartition {
-
- struct bitstream_s *bitstream;
- struct decoding_environment_s de_aec;
-
- int (*read_syntax_element)(struct syntaxelement *, struct img_par *,
- struct datapartition *);
-/*!< virtual function;
- * actual method depends on chosen data partition and
- * entropy coding method
- */
-};
-
-struct slice_s {
- int picture_id;
- int qp;
- int picture_type;
- int start_mb_nr;
- int max_part_nr;
- int num_mb;
-
- struct datapartition *part_arr;
- struct motion_info_contexts_s *mot_ctx;
- struct texture_info_contexts *tex_ctx;
- int field_ctx[3][2];
-};
-
-struct img_par {
- int number;
- int current_mb_nr;
- int max_mb_nr;
- int current_slice_nr;
- int tr;
- int qp;
- int type;
-
- int typeb;
-
- int width;
- int height;
- int width_cr;
- int height_cr;
- int source_bitdepth;
- int mb_y;
- int mb_x;
- int block_y;
- int pix_y;
- int pix_x;
- int pix_c_y;
- int block_x;
- int pix_c_x;
-
- int ***mv;
- int mpr[16][16];
-
- int m7[16][16];
- int m8[/*2*/4][8][8];
- int cof[4][/*6*/8][4][4];
- int cofu[4];
- int **ipredmode;
- int quad[256];
- int cod_counter;
-
- int ***dfmv;
- int ***dbmv;
- int **fw_reffrarr;
- int **bw_reffrarr;
-
- int ***mv_frm;
- int **fw_reffrarr_frm;
- int **bw_reffrarr_frm;
- int imgtr_next_p;
- int imgtr_last_p;
- int tr_frm;
- int tr_fld;
- int imgtr_last_prev_p;
-
- int no_forward_reference;
- int seq_header_indicate;
- int b_discard_flag;
-
- int ***fw_mv;
- int ***bw_mv;
- int subblock_x;
- int subblock_y;
-
- int buf_cycle;
-
- int direct_type;
-
- int ***mv_top;
- int ***mv_bot;
- int **fw_reffrarr_top;
- int **bw_reffrarr_top;
- int **fw_reffrarr_bot;
- int **bw_reffrarr_bot;
-
- int **ipredmode_top;
- int **ipredmode_bot;
- int ***fw_mv_top;
- int ***fw_mv_bot;
- int ***bw_mv_top;
- int ***bw_mv_bot;
- int ***dfmv_top;
- int ***dbmv_top;
- int ***dfmv_bot;
- int ***dbm_bot;
-
- int toppoc;
- int bottompoc;
- int framepoc;
- unsigned int frame_num;
-
- unsigned int pic_distance;
- int delta_pic_order_cnt_bottom;
-
- signed int pic_distance_msb;
- unsigned int prev_pic_distance_lsb;
- signed int curr_pic_distance_msb;
- unsigned int this_poc;
-
- int pic_width_inmbs;
- int pic_height_inmbs;
- int pic_size_inmbs;
-
- int block8_x, block8_y;
- int structure;
- int pn;
- int buf_used;
- int buf_size;
- int picture_structure;
- int advanced_pred_mode_disable;
- int types;
- int current_mb_nr_fld;
-
- int p_field_enhanced;
- int b_field_enhanced;
-
- int slice_weighting_flag;
- int lum_scale[4];
- int lum_shift[4];
- int chroma_scale[4];
- int chroma_shift[4];
- int mb_weighting_flag;
- int weighting_prediction;
- int mpr_weight[16][16];
- int top_bot;
- int bframe_number;
-
- int auto_crop_right;
- int auto_crop_bottom;
-
- struct slice_s *current_slice;
- int is_v_block;
- int is_intra_block;
-
- int new_seq_header_flag;
- int new_sequence_flag;
- int last_pic_bbv_delay;
-
- int sequence_end_flag;
- int is_top_field;
-
- int abt_flag;
- int qp_shift;
-
-#ifdef EIGHTH
-int eighth_subpixel_flag;
-int subpixel_precision;
-int unit_length;
-int subpixel_mask;
-
-int max_mvd;
-int min_mvd;
-#endif
-
-};
-
-struct macroblock {
- int qp;
- int slice_nr;
- int delta_quant;
- struct macroblock *mb_available[3][3];
- /*!< pointer to neighboring MBs in a 3x3 window of current MB,
- *which is located at [1][1]
- * NULL pointer identifies neighboring MBs which are unavailable
- */
-
- int mb_type;
- int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];
- int cbp, cbp_blk, cbp01;
- unsigned long cbp_bits;
-
- int b8mode[4];
- int b8pdir[4];
- int mb_type_2;
- int c_ipred_mode_2;
- int dct_mode;
-
- int c_ipred_mode;
- int lf_disable;
- int lf_alpha_c0_offset;
- int lf_beta_offset;
-
- int CABT[4];
- int CABP[4];
- int cbp_4x4[4];
-
- int skip_flag;
-
- struct macroblock *mb_available_up;
- struct macroblock *mb_available_left;
- unsigned int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d;
- unsigned int mbavail_a, mbavail_b, mbavail_c, mbavail_d;
-
-};
-
-struct macroblock *mb_data;
-
-struct img_par *img;
-
-struct bitstream_s *curr_stream;
-
-struct datapartition *alloc_partition(int n);
-
-unsigned int vld_mem_start_addr;
-unsigned int vld_mem_end_addr;
-
-int marker_bit;
-
-int progressive_sequence;
-int horizontal_size;
-int vertical_size;
-
-int second_ifield;
-int pre_img_type;
-
-/* slice_header() */
-int slice_vertical_position;
-int slice_vertical_position_extension;
-int fixed_picture_qp;
-int fixed_slice_qp;
-int slice_qp;
-
-/*
- *************************************************************************
- * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in
- the global UsedBits variable
- * Input:
- tracestring
- the string for the trace file
- bitstream
- the stream to be read from
- * Output:
- * Return: the value of the coded syntax element
- * Attention:
- *************************************************************************
- */
-/*!
- * definition of AVS syntaxelements
- * order of elements follow dependencies for picture reconstruction
- */
-/*!
- * \brief Assignment of old TYPE partition elements to new
- * elements
- *
- * old element | new elements
- * TYPE_HEADER | SE_HEADER, SE_PTYPE
- * TYPE_MBHEADER | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE
- * TYPE_MVD | SE_MVD
- * TYPE_CBP | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER
- * SE_DELTA_QUANT_INTRA
- * TYPE_COEFF_Y | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA,
- SE_LUM_DC_INTER, SE_LUM_AC_INTER
- * TYPE_2x2DC | SE_CHR_DC_INTRA, SE_CHR_DC_INTER
- * TYPE_COEFF_C | SE_CHR_AC_INTRA, SE_CHR_AC_INTER
- * TYPE_EOS | SE_EOS
- */
-
-#define SE_HEADER 0
-#define SE_PTYPE 1
-#define SE_MBTYPE 2
-#define SE_REFFRAME 3
-#define SE_INTRAPREDMODE 4
-#define SE_MVD 5
-#define SE_CBP_INTRA 6
-#define SE_LUM_DC_INTRA 7
-#define SE_CHR_DC_INTRA 8
-#define SE_LUM_AC_INTRA 9
-#define SE_CHR_AC_INTRA 10
-#define SE_CBP_INTER 11
-#define SE_LUM_DC_INTER 12
-#define SE_CHR_DC_INTER 13
-#define SE_LUM_AC_INTER 14
-#define SE_CHR_AC_INTER 15
-#define SE_DELTA_QUANT_INTER 16
-#define SE_DELTA_QUANT_INTRA 17
-#define SE_BFRAME 18
-#define SE_EOS 19
-#define SE_MAX_ELEMENTS 20
-#define SE_CBP01 21
-int chroma_format;
-/*
- *************************************************************************
- * Function:Reads bits from the bitstream buffer
- * Input:
- byte buffer[]
- containing VLC-coded data bits
- int totbitoffset
- bit offset from start of partition
- int bytecount
- total bytes in bitstream
- int numbits
- number of bits to read
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int get_bits(unsigned char buffer[], int totbitoffset, int *info, int bytecount,
- int numbits)
-{
- register int inf;
- long byteoffset;
- int bitoffset;
-
- int bitcounter = numbits;
-
- byteoffset = totbitoffset / 8;
- bitoffset = 7 - (totbitoffset % 8);
-
- inf = 0;
- while (numbits) {
- inf <<= 1;
- inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset;
- numbits--;
- bitoffset--;
- if (bitoffset < 0) {
- byteoffset++;
- bitoffset += 8;
- if (byteoffset > bytecount)
- return -1;
- }
- }
-
- *info = inf;
-
-
- return bitcounter;
-}
-
-/*
- *************************************************************************
- * Function:read FLC codeword from UVLC-partition
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int read_syntaxelement_flc(struct syntaxelement *sym)
-{
- int frame_bitoffset = curr_stream->frame_bitoffset;
- unsigned char *buf = curr_stream->stream_buffer;
- int bitstreamlengthinbytes = curr_stream->bitstream_length;
-
- if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
- sym->len)) < 0)
- return -1;
-
- curr_stream->frame_bitoffset += sym->len;
- sym->value1 = sym->inf;
-
-#if TRACE
- tracebits2(sym->tracestring, sym->len, sym->inf);
-#endif
-
- return 1;
-}
-
-/*
- *************************************************************************
- * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in
- the global UsedBits variable
- * Input:
- tracestring
- the string for the trace file
- bitstream
- the stream to be read from
- * Output:
- * Return: the value of the coded syntax element
- * Attention:
- *************************************************************************
- */
-int u_1(char *tracestring)
-{
- return u_v(1, tracestring);
-}
-
-/*
- *************************************************************************
- * Function:mapping rule for ue(v) syntax elements
- * Input:length and info
- * Output:number in the code table
- * Return:
- * Attention:
- *************************************************************************
- */
-void linfo_ue(int len, int info, int *value1, int *dummy)
-{
- *value1 = (int)pow2(2, (len / 2)) + info - 1;
-}
-
-int u_v(int leninbits, char *tracestring)
-{
- struct syntaxelement symbol, *sym = &symbol;
-
-#ifdef AVSP_LONG_CABAC
-#else
- assert(curr_stream->stream_buffer != NULL);
-#endif
- sym->type = SE_HEADER;
- sym->mapping = linfo_ue;
- sym->len = leninbits;
- read_syntaxelement_flc(sym);
-
- return sym->inf;
-}
-
-/*
- *************************************************************************
- * Function:mapping rule for se(v) syntax elements
- * Input:length and info
- * Output:signed mvd
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void linfo_se(int len, int info, int *value1, int *dummy)
-{
- int n;
-
- n = (int)pow2(2, (len / 2)) + info - 1;
- *value1 = (n + 1) / 2;
- if ((n & 0x01) == 0)
- *value1 = -*value1;
-
-}
-
-/*
- *************************************************************************
- * Function:length and info
- * Input:
- * Output:cbp (intra)
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void linfo_cbp_intra(int len, int info, int *cbp, int *dummy)
-{
-}
-
-const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18},
- {9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12},
- {7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, {
- 48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59},
- {26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23,
- 24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56,
- 52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, {
- 27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47},
- {42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57,
- 56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, {
- 15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22},
- {34, 32}, {13, 20}, {20, 23}, {0, 2} };
-
-unsigned int s1, t1, value_s, value_t;
-unsigned char dec_bypass, dec_final;
-
-#define get_byte() { \
- dbuffer = dcodestrm[(*dcodestrm_len)++];\
- dbits_to_go = 7; \
-}
-
-#define dbuffer (dep->dbuffer)
-#define dbits_to_go (dep->dbits_to_go)
-#define dcodestrm (dep->dcodestrm)
-#define dcodestrm_len (dep->dcodestrm_len)
-
-#define B_BITS 10
-
-#define LG_PMPS_SHIFTNO 2
-
-#define HALF (1 << (B_BITS-1))
-#define QUARTER (1 << (B_BITS-2))
-
-unsigned int biari_decode_symbol(struct decoding_environment_s *dep,
- struct bi_context_type_s *bi_ct)
-{
- register unsigned char bit;
- register unsigned char s_flag;
- register unsigned char is_lps = 0;
- register unsigned char cwr;
- register unsigned char cycno = bi_ct->cycno;
- register unsigned int lg_pmps = bi_ct->LG_PMPS;
- register unsigned int t_rlps;
- register unsigned int s2, t2;
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n",
- bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct);
-#endif
-
- bit = bi_ct->MPS;
-
- cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5;
-
- if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
- s2 = s1;
- t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
- s_flag = 0;
- } else {
- s2 = s1 + 1;
- t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
- s_flag = 1;
- }
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf(" s2 : %d, t2 : %03X\n", s2, t2);
-#endif
-
- if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
- is_lps = 1;
- bit = !bit;
-
- t_rlps = (s_flag == 0) ?
- (lg_pmps >> LG_PMPS_SHIFTNO) :
- (t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
-
- if (s2 == value_s)
- value_t = (value_t - t2);
- else {
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1)
- | ((dbuffer >> dbits_to_go) & 0x01);
- value_t = 256 + value_t - t2;
-
- }
-
- while (t_rlps < QUARTER) {
- t_rlps = t_rlps << 1;
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1)
- | ((dbuffer >> dbits_to_go) & 0x01);
- }
-
- s1 = 0;
- t1 = t_rlps & 0xff;
-
- value_s = 0;
- while (value_t < QUARTER) {
- int j;
-
- if (--dbits_to_go < 0)
- get_byte();
- j = (dbuffer >> dbits_to_go) & 0x01;
-
- value_t = (value_t << 1) | j;
- value_s++;
- }
- value_t = value_t & 0xff;
- } else {
-
- s1 = s2;
- t1 = t2;
- }
-
- if (dec_bypass)
- return bit;
-
- if (is_lps)
- cycno = (cycno <= 2) ? (cycno + 1) : 3;
- else if (cycno == 0)
- cycno = 1;
- bi_ct->cycno = cycno;
-
- if (is_lps) {
- switch (cwr) {
- case 3:
- lg_pmps = lg_pmps + 197;
- break;
- case 4:
- lg_pmps = lg_pmps + 95;
- break;
- default:
- lg_pmps = lg_pmps + 46;
- }
-
- if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) {
- lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps;
- bi_ct->MPS = !(bi_ct->MPS);
- }
- } else {
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n",
- lg_pmps - (unsigned int)(lg_pmps>>cwr)
- - (unsigned int)(lg_pmps>>(cwr+2)),
- lg_pmps,
- (unsigned int)(lg_pmps>>cwr),
- (unsigned int)(lg_pmps>>(cwr+2))
- );
-#endif
- lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr)
- - (unsigned int)(lg_pmps >> (cwr + 2));
- }
-
- bi_ct->LG_PMPS = lg_pmps;
-
- return bit;
-}
-
-unsigned int biari_decode_symbolw(struct decoding_environment_s *dep,
- struct bi_context_type_s *bi_ct1,
- struct bi_context_type_s *bi_ct2)
-{
- register unsigned char bit1, bit2;
- register unsigned char pred_mps, bit;
- register unsigned int lg_pmps;
- register unsigned char cwr1, cycno1 = bi_ct1->cycno;
- register unsigned char cwr2, cycno2 = bi_ct2->cycno;
- register unsigned int lg_pmps1 = bi_ct1->LG_PMPS;
- register unsigned int lg_pmps2 =
- bi_ct2->LG_PMPS;
- register unsigned int t_rlps;
- register unsigned char s_flag, is_lps = 0;
- register unsigned int s2, t2;
-
-
- bit1 = bi_ct1->MPS;
- bit2 = bi_ct2->MPS;
-
- cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5;
- cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5;
-
- if (bit1 == bit2) {
- pred_mps = bit1;
- lg_pmps = (lg_pmps1 + lg_pmps2) / 2;
- } else {
- if (lg_pmps1 < lg_pmps2) {
- pred_mps = bit1;
- lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
- - ((lg_pmps2 - lg_pmps1) >> 1);
- } else {
- pred_mps = bit2;
- lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
- - ((lg_pmps1 - lg_pmps2) >> 1);
- }
- }
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n",
- lg_pmps, pred_mps);
-#endif
- if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
- s2 = s1;
- t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
- s_flag = 0;
- } else {
- s2 = s1 + 1;
- t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
- s_flag = 1;
- }
-
- bit = pred_mps;
- if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
- is_lps = 1;
- bit = !bit;
- t_rlps = (s_flag == 0) ?
- (lg_pmps >> LG_PMPS_SHIFTNO) :
- (t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
-
- if (s2 == value_s)
- value_t = (value_t - t2);
- else {
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1)
- | ((dbuffer >> dbits_to_go) & 0x01);
- value_t = 256 + value_t - t2;
- }
-
- while (t_rlps < QUARTER) {
- t_rlps = t_rlps << 1;
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1)
- | ((dbuffer >> dbits_to_go) & 0x01);
- }
- s1 = 0;
- t1 = t_rlps & 0xff;
-
- value_s = 0;
- while (value_t < QUARTER) {
- int j;
-
- if (--dbits_to_go < 0)
- get_byte();
- j = (dbuffer >> dbits_to_go) & 0x01;
-
- value_t = (value_t << 1) | j;
- value_s++;
- }
- value_t = value_t & 0xff;
- } else {
- s1 = s2;
- t1 = t2;
- }
-
- if (bit != bit1) {
- cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3;
- } else {
- if (cycno1 == 0)
- cycno1 = 1;
- }
-
- if (bit != bit2) {
- cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3;
- } else {
- if (cycno2 == 0)
- cycno2 = 1;
- }
- bi_ct1->cycno = cycno1;
- bi_ct2->cycno = cycno2;
-
- {
-
- if (bit == bit1) {
- lg_pmps1 =
- lg_pmps1
- - (unsigned int)(lg_pmps1
- >> cwr1)
- - (unsigned int)(lg_pmps1
- >> (cwr1
- + 2));
- } else {
- switch (cwr1) {
- case 3:
- lg_pmps1 = lg_pmps1 + 197;
- break;
- case 4:
- lg_pmps1 = lg_pmps1 + 95;
- break;
- default:
- lg_pmps1 = lg_pmps1 + 46;
- }
-
- if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) {
- lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1
- - lg_pmps1;
- bi_ct1->MPS = !(bi_ct1->MPS);
- }
- }
- bi_ct1->LG_PMPS = lg_pmps1;
-
- if (bit == bit2) {
- lg_pmps2 =
- lg_pmps2
- - (unsigned int)(lg_pmps2
- >> cwr2)
- - (unsigned int)(lg_pmps2
- >> (cwr2
- + 2));
- } else {
- switch (cwr2) {
- case 3:
- lg_pmps2 = lg_pmps2 + 197;
- break;
- case 4:
- lg_pmps2 = lg_pmps2 + 95;
- break;
- default:
- lg_pmps2 = lg_pmps2 + 46;
- }
-
- if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) {
- lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1
- - lg_pmps2;
- bi_ct2->MPS = !(bi_ct2->MPS);
- }
- }
- bi_ct2->LG_PMPS = lg_pmps2;
- }
-
-
- return bit;
-}
-
-/*!
- ************************************************************************
- * \brief
- * biari_decode_symbol_eq_prob():
- * \return
- * the decoded symbol
- ************************************************************************
- */
-unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep)
-{
- unsigned char bit;
- struct bi_context_type_s octx;
- struct bi_context_type_s *ctx = &octx;
-
- ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
- ctx->MPS = 0;
- ctx->cycno = 0xfe;
- dec_bypass = 1;
- bit = biari_decode_symbol(dep, ctx);
- dec_bypass = 0;
- return bit;
-}
-
-unsigned int biari_decode_final(struct decoding_environment_s *dep)
-{
- unsigned char bit;
- struct bi_context_type_s octx;
- struct bi_context_type_s *ctx = &octx;
-
- ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO;
- ctx->MPS = 0;
- ctx->cycno = 0xff;
- dec_final = 1;
- bit = biari_decode_symbol(dep, ctx);
- dec_final = 0;
- return bit;
-}
-
-int i_8(char *tracestring)
-{
- int frame_bitoffset = curr_stream->frame_bitoffset;
- unsigned char *buf = curr_stream->stream_buffer;
- int bitstreamlengthinbytes = curr_stream->bitstream_length;
- struct syntaxelement symbol, *sym = &symbol;
-#ifdef AVSP_LONG_CABAC
-#else
- assert(curr_stream->stream_buffer != NULL);
-#endif
-
- sym->len = 8;
- sym->type = SE_HEADER;
- sym->mapping = linfo_ue;
-
- if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
- sym->len)) < 0)
- return -1;
- curr_stream->frame_bitoffset += sym->len;
- sym->value1 = sym->inf;
- if (sym->inf & 0x80)
- sym->inf = -(~((int)0xffffff00 | sym->inf) + 1);
-#if TRACE
- tracebits2(sym->tracestring, sym->len, sym->inf);
-#endif
- return sym->inf;
-}
-
-/*!
- ************************************************************************
- * \brief
- * arideco_bits_read
- ************************************************************************
- */
-int arideco_bits_read(struct decoding_environment_s *dep)
-{
-
- return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go);
-}
-
-/*!
- ************************************************************************
- * \brief
- * arithmetic decoding
- ************************************************************************
- */
-int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img,
- struct datapartition *this_data_part)
-{
- int curr_len;
- struct decoding_environment_s *dep_dp = &(this_data_part->de_aec);
-
- curr_len = arideco_bits_read(dep_dp);
-
- se->reading(se, img, dep_dp);
-
- se->len = (arideco_bits_read(dep_dp) - curr_len);
- return se->len;
-}
-
-/*!
- ************************************************************************
- * \brief
- * This function is used to arithmetically decode the
- * run length info of the skip mb
- ************************************************************************
- */
-void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- struct bi_context_type_s *pctx;
- int ctx, symbol;
-
- pctx = img->current_slice->tex_ctx->one_contexts[0];
- symbol = 0;
- ctx = 0;
- while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
- symbol += 1;
- ctx++;
- if (ctx >= 3)
- ctx = 3;
- }
- se->value1 = symbol;
-#if TRACE
- fprintf(p_trace, "@%d%s\t\t\t%d\n",
- symbol_count++, se->tracestring, se->value1);
- fflush(p_trace);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- * This function is used to arithmetically decode a pair of
- * intra prediction modes of a given MB.
- ************************************************************************
- */
-int mapd_intrap[5] = {0, 2, 3, 4, 1};
-void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- struct bi_context_type_s *pctx;
- int ctx, symbol;
-
- pctx = img->current_slice->tex_ctx->one_contexts[1];
- symbol = 0;
- ctx = 0;
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
-#endif
- while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
- symbol += 1;
- ctx++;
- if (ctx >= 3)
- ctx = 3;
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & AEC_DUMP)
- io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
-#endif
- if (symbol == 4)
- break;
- }
- se->value1 = mapd_intrap[symbol] - 1;
-
-#if TRACE
- fprintf(p_trace, "@%d %s\t\t\t%d\n",
- symbol_count++, se->tracestring, se->value1);
- fflush(p_trace);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- * decoding of unary binarization using one or 2 distinct
- * models for the first and all remaining bins; no terminating
- * "0" for max_symbol
- ***********************************************************************
- */
-unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp,
- struct bi_context_type_s *ctx,
- int ctx_offset, unsigned int max_symbol)
-{
- unsigned int l;
- unsigned int symbol;
- struct bi_context_type_s *ictx;
-
- symbol = biari_decode_symbol(dep_dp, ctx);
-
- if (symbol == 0)
- return 0;
-
- if (max_symbol == 1)
- return symbol;
- symbol = 0;
- ictx = ctx + ctx_offset;
- do {
- l = biari_decode_symbol(dep_dp, ictx);
- symbol++;
- } while ((l != 0) && (symbol < max_symbol - 1));
- if ((l != 0) && (symbol == max_symbol - 1))
- symbol++;
- return symbol;
-}
-
-/*!
- ************************************************************************
- * \brief
- * decoding of unary binarization using one or 2 distinct
- * models for the first and all remaining bins
- ***********************************************************************
- */
-unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp,
- struct bi_context_type_s *ctx, int ctx_offset)
-{
- unsigned int l;
- unsigned int symbol;
- struct bi_context_type_s *ictx;
-
- symbol = 1 - biari_decode_symbol(dep_dp, ctx);
-
- if (symbol == 0)
- return 0;
- symbol = 0;
- ictx = ctx + ctx_offset;
- do {
- l = 1 - biari_decode_symbol(dep_dp, ictx);
- symbol++;
- } while (l != 0);
- return symbol;
-}
-
-/*!
- ************************************************************************
- * \brief
- * This function is used to arithmetically decode the chroma
- * intra prediction mode of a given MB.
- ************************************************************************
- */
-void read_cipredmode_aec(struct syntaxelement *se,
- struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
- struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
- int act_ctx, a, b;
- int act_sym = se->value1;
-
- if (curr_mb->mb_available_up == NULL)
- b = 0;
- else {
- /*if ( (curr_mb->mb_available_up)->mb_type==IPCM)
- * b=0;
- * else
- */
- b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
- }
-
- if (curr_mb->mb_available_left == NULL)
- a = 0;
- else {
- /* if ( (curr_mb->mb_available_left)->mb_type==IPCM)
- * a=0;
- * else
- */
- a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
- }
-
- act_ctx = a + b;
-
-
- act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx);
-
- if (act_sym != 0)
- act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3,
- 0, 2) + 1;
-
- se->value1 = act_sym;
-
-#if TRACE
- fprintf(p_trace, "@%d %s\t\t%d\n",
- symbol_count++, se->tracestring, se->value1);
- fflush(p_trace);
-#endif
-
-}
-
-int slice_header(char *buf, int startcodepos, int length)
-{
- int i;
-
- int weight_para_num = 0;
- int mb_row;
- int mb_column;
- int mb_index;
- int mb_width, mb_height;
-
- mb_column = 0;
-
- memcpy(curr_stream->stream_buffer, buf, length);
- curr_stream->code_len = curr_stream->bitstream_length = length;
-
- curr_stream->read_len =
- curr_stream->frame_bitoffset = (startcodepos) * 8;
- slice_vertical_position = u_v(8, "slice vertical position");
-
- push_es(slice_vertical_position, 8);
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & SLICE_INFO_DUMP)
- io_printf(" * 8-bits slice_vertical_position : %d\n",
- slice_vertical_position);
-#endif
-
- if (vertical_size > 2800) {
- slice_vertical_position_extension = u_v(3,
- "slice vertical position extension");
- push_es(slice_vertical_position_extension, 3);
-
- }
-
- if (vertical_size > 2800)
- mb_row = (slice_vertical_position_extension << 7)
- + slice_vertical_position;
- else
- mb_row = slice_vertical_position;
-
- mb_width = (horizontal_size + 15) / 16;
- if (!progressive_sequence)
- mb_height = 2 * ((vertical_size + 31) / 32);
- else
- mb_height = (vertical_size + 15) / 16;
-
-
- mb_index = mb_row * mb_width + mb_column;
-
- if (!img->picture_structure && img->type == I_IMG
- && (mb_index >= mb_width * mb_height / 2)) {
- second_ifield = 1;
- img->type = P_IMG;
- pre_img_type = P_IMG;
- }
-
- {
- if (!fixed_picture_qp) {
- fixed_slice_qp = u_v(1, "fixed_slice_qp");
- push_es(fixed_slice_qp, 1);
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & SLICE_INFO_DUMP)
- io_printf(" * 1-bit fixed_slice_qp : %d\n",
- fixed_slice_qp);
-#endif
- slice_qp = u_v(6, "slice_qp");
- push_es(slice_qp, 6);
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & SLICE_INFO_DUMP)
- io_printf(" * 6-bits slice_qp : %d\n",
- slice_qp);
-#endif
-
- img->qp = slice_qp;
- }
-
- if (img->type != I_IMG) {
- img->slice_weighting_flag = u_v(1,
- "slice weighting flag");
-
- if (img->slice_weighting_flag) {
-
- if (second_ifield && !img->picture_structure)
- weight_para_num = 1;
- else if (img->type == P_IMG
- && img->picture_structure)
- weight_para_num = 2;
- else if (img->type == P_IMG
- && !img->picture_structure)
- weight_para_num = 4;
- else if (img->type == B_IMG
- && img->picture_structure)
- weight_para_num = 2;
- else if (img->type == B_IMG
- && !img->picture_structure)
- weight_para_num = 4;
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & SLICE_INFO_DUMP)
- io_printf(" - weight_para_num : %d\n",
- weight_para_num);
-#endif
- for (i = 0; i < weight_para_num; i++) {
- img->lum_scale[i] = u_v(8,
- "luma scale");
-
- img->lum_shift[i] = i_8("luma shift");
-
- marker_bit = u_1("insert bit");
-
-
- {
- img->chroma_scale[i] = u_v(8,
- "chroma scale");
-
- img->chroma_shift[i] = i_8(
- "chroma shift");
-
- marker_bit = u_1("insert bit");
-
- }
- }
- img->mb_weighting_flag = u_v(1,
- "MB weighting flag");
-
- }
- }
- }
-
-
-#if 1
- return mb_index;
-#endif
-}
-
-void no_mem_exit(char *where)
-{
- io_printf("%s\r\n", where);
-}
-
-unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-
-struct inputstream_s {
- /*FILE *f;*/
- unsigned char buf[SVA_STREAM_BUF_SIZE];
- unsigned int uclear_bits;
- unsigned int upre_3bytes;
- int ibyte_position;
- int ibuf_bytesnum;
- int iclear_bitsnum;
- int istuff_bitsnum;
- int ibits_count;
-};
-
-struct inputstream_s IRABS;
-struct inputstream_s *p_irabs = &IRABS;
-
-struct stat_bits {
- int curr_frame_bits;
- int prev_frame_bits;
- int emulate_bits;
- int prev_emulate_bits;
- int last_unit_bits;
- int bitrate;
- int total_bitrate[1000];
- int coded_pic_num;
- int time_s;
-};
-
-struct stat_bits *stat_bits_ptr;
-
-unsigned char *temp_slice_buf;
-int start_codeposition;
-int first_slice_length;
-int first_slice_startpos;
-
-int bitstream_buf_used;
-int startcode_offset;
-
-int bitstream_read_ptr;
-
-int demulate_enable;
-
-int last_dquant;
-
-int total_mb_count;
-
-int current_mb_skip;
-
-int skip_mode_flag;
-
-int current_mb_intra;
-
-/*
- *************************************************************************
- * Function: Check start code's type
- * Input:
- * Output:
- * Return:
- * Author: XZHENG, 20080515
- *************************************************************************
- */
-void check_type(int startcode)
-{
- startcode = startcode & 0x000000ff;
- switch (startcode) {
- case 0xb0:
- case 0xb2:
- case 0xb5:
- demulate_enable = 0;
- break;
- default:
- demulate_enable = 1;
- break;
- }
-
-}
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return: 0 : OK
- -1 : arrive at stream end
- -2 : meet another start code
- * Attention:
- *************************************************************************
- */
-int clear_nextbyte(struct inputstream_s *p)
-{
- int i, k, j;
- unsigned char temp[3];
-
- i = p->ibyte_position;
- k = p->ibuf_bytesnum - i;
- if (k < 3) {
- for (j = 0; j < k; j++)
- temp[j] = p->buf[i + j];
-
- p->ibuf_bytesnum = read_bitstream(p->buf + k,
- SVA_STREAM_BUF_SIZE - k);
- bitstream_buf_used++;
- if (p->ibuf_bytesnum == 0) {
- if (k > 0) {
- while (k > 0) {
- p->upre_3bytes = ((p->upre_3bytes << 8)
- | p->buf[i])
- & 0x00ffffff;
- if (p->upre_3bytes < 4
- && demulate_enable) {
- p->uclear_bits =
- (p->uclear_bits
- << 6)
- | (p->buf[i]
- >> 2);
- p->iclear_bitsnum += 6;
- stat_bits_ptr->emulate_bits
- += 2;
- } else {
- p->uclear_bits = (p->uclear_bits
- << 8)
- | p->buf[i];
- p->iclear_bitsnum += 8;
- }
- p->ibyte_position++;
- k--;
- i++;
- }
- return 0;
- } else {
- return -1;
- }
- } else {
- for (j = 0; j < k; j++)
- p->buf[j] = temp[j];
- p->ibuf_bytesnum += k;
- i = p->ibyte_position = 0;
- }
- }
- if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1)
- return -2;
- p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff;
- if (p->upre_3bytes < 4 && demulate_enable) {
- p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2);
- p->iclear_bitsnum += 6;
- stat_bits_ptr->emulate_bits += 2;
- } else {
- p->uclear_bits = (p->uclear_bits << 8) | p->buf[i];
- p->iclear_bitsnum += 8;
- }
- p->ibyte_position++;
- return 0;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return: 0 : OK
- -1 : arrive at stream end
- -2 : meet another start code
- * Attention:
- *************************************************************************
- */
-int read_n_bit(struct inputstream_s *p, int n, int *v)
-{
- int r;
- unsigned int t;
-
- while (n > p->iclear_bitsnum) {
- r = clear_nextbyte(p);
- if (r) {
- if (r == -1) {
- if (p->ibuf_bytesnum - p->ibyte_position > 0)
- break;
- }
- return r;
- }
- }
- t = p->uclear_bits;
- r = 32 - p->iclear_bitsnum;
- *v = (t << r) >> (32 - n);
- p->iclear_bitsnum -= n;
- return 0;
-}
-
-#ifdef AVSP_LONG_CABAC
-unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE];
-int tmp_buf_wr_ptr;
-int tmp_buf_rd_ptr;
-int tmp_buf_count;
-#endif
-void open_irabs(struct inputstream_s *p)
-{
- p->uclear_bits = 0xffffffff;
- p->ibyte_position = 0;
- p->ibuf_bytesnum = 0;
- p->iclear_bitsnum = 0;
- p->istuff_bitsnum = 0;
- p->ibits_count = 0;
- p->upre_3bytes = 0;
-
- bitstream_buf_used = 0;
- bitstream_read_ptr = (src_start - 16) & 0xfffffff0;
-
-#ifdef AVSP_LONG_CABAC
- tmp_buf_count = 0;
- tmp_buf_wr_ptr = 0;
- tmp_buf_rd_ptr = 0;
-#endif
-
-}
-
-void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr,
- int move_size)
-{
- int move_bytes_left = move_size;
- unsigned int move_read_addr;
- unsigned int move_write_addr = move_to_addr;
-
- int move_byte;
- unsigned int data32;
-
- while (move_from_addr > vld_mem_end_addr) {
- move_from_addr = move_from_addr + vld_mem_start_addr
- - vld_mem_end_addr - 8;
- }
- move_read_addr = move_from_addr;
- while (move_bytes_left > 0) {
- move_byte = move_bytes_left;
- if (move_byte > 512)
- move_byte = 512;
- if ((move_read_addr + move_byte) > vld_mem_end_addr)
- move_byte = (vld_mem_end_addr + 8) - move_read_addr;
-
- WRITE_VREG(LMEM_DMA_ADR, move_read_addr);
- WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
- WRITE_VREG(LMEM_DMA_CTRL, 0xc200);
-
- data32 = 0x8000;
- while (data32 & 0x8000)
- data32 = READ_VREG(LMEM_DMA_CTRL);
-
- WRITE_VREG(LMEM_DMA_ADR, move_write_addr);
- WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
- WRITE_VREG(LMEM_DMA_CTRL, 0x8200);
-
- data32 = 0x8000;
- while (data32 & 0x8000)
- data32 = READ_VREG(LMEM_DMA_CTRL);
-
- data32 = 0x0fff;
- while (data32 & 0x0fff)
- data32 = READ_VREG(WRRSP_LMEM);
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & STREAM_INFO_DUMP)
- io_printf(" 2 MOVE %d Bytes from 0x%x to 0x%x\n",
- move_byte, move_read_addr, move_write_addr);
-#endif
-
- move_read_addr = move_read_addr + move_byte;
- if (move_read_addr > vld_mem_end_addr)
- move_read_addr = vld_mem_start_addr;
- move_write_addr = move_write_addr + move_byte;
- move_bytes_left = move_bytes_left - move_byte;
- }
-
-}
-
-int read_bitstream(unsigned char *buf, int size)
-{
- int i;
-
-#ifdef AVSP_LONG_CABAC
-
- unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp;
-
- if (tmp_buf_count < size) {
- dma_sync_single_for_cpu(amports_get_dma_device(),
- bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy,
- SVA_STREAM_BUF_SIZE);
-
- for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) {
- TMP_BUF[tmp_buf_wr_ptr++] =
- (TMP_BUF_32[2 * i + 1] >> 24) & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] =
- (TMP_BUF_32[2 * i + 1] >> 16) & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8)
- & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0)
- & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] =
- (TMP_BUF_32[2 * i + 0] >> 24) & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] =
- (TMP_BUF_32[2 * i + 0] >> 16) & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8)
- & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0)
- & 0xff;
- if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_wr_ptr = 0;
- }
- tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE;
- bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE;
- }
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & STREAM_INFO_DUMP)
- io_printf(" Read %d bytes from %d, size left : %d\n",
- size, tmp_buf_rd_ptr, tmp_buf_count);
-#endif
- for (i = 0; i < size; i++) {
- buf[i] = TMP_BUF[tmp_buf_rd_ptr++];
- if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE))
- tmp_buf_rd_ptr = 0;
- }
- tmp_buf_count = tmp_buf_count - size;
-
-#else
- for (i = 0; i < size; i++)
- buf[i] = tmp_stream[bitstream_read_ptr + i];
- bitstream_read_ptr = bitstream_read_ptr + size;
-#endif
-
- return size;
-}
-
-int next_startcode(struct inputstream_s *p)
-{
- int i, m;
- unsigned char a = 0, b = 0;
-
- m = 0;
-
- while (1) {
- if (p->ibyte_position >= p->ibuf_bytesnum - 2) {
- m = p->ibuf_bytesnum - p->ibyte_position;
- if (m < 0)
- return -2;
- if (m == 1)
- b = p->buf[p->ibyte_position + 1];
- if (m == 2) {
- b = p->buf[p->ibyte_position + 1];
- a = p->buf[p->ibyte_position];
- }
- p->ibuf_bytesnum = read_bitstream(p->buf,
- SVA_STREAM_BUF_SIZE);
- p->ibyte_position = 0;
- bitstream_buf_used++;
- }
-
- if (p->ibuf_bytesnum + m < 3)
- return -1;
-
- if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
- p->ibyte_position = 2;
- p->iclear_bitsnum = 0;
- p->istuff_bitsnum = 0;
- p->ibits_count += 24;
- p->upre_3bytes = 1;
- return 0;
- }
-
- if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) {
- p->ibyte_position = 1;
- p->iclear_bitsnum = 0;
- p->istuff_bitsnum = 0;
- p->ibits_count += 24;
- p->upre_3bytes = 1;
- return 0;
- }
-
- if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
- p->ibyte_position = 2;
- p->iclear_bitsnum = 0;
- p->istuff_bitsnum = 0;
- p->ibits_count += 24;
- p->upre_3bytes = 1;
- return 0;
- }
-
- for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) {
- if (p->buf[i] == 0 && p->buf[i + 1] == 0
- && p->buf[i + 2] == 1) {
- p->ibyte_position = i + 3;
- p->iclear_bitsnum = 0;
- p->istuff_bitsnum = 0;
- p->ibits_count += 24;
- p->upre_3bytes = 1;
- return 0;
- }
- p->ibits_count += 8;
- }
- p->ibyte_position = i;
- }
-}
-
-int get_oneunit(char *buf, int *startcodepos, int *length)
-{
- int i, j, k;
-
- i = next_startcode(p_irabs);
-
- if (i != 0) {
- if (i == -1)
- io_printf(
- "\narrive at stream end and start code is not found!");
- if (i == -2)
- io_printf("\np->ibyte_position error!");
-
- }
- startcode_offset =
- p_irabs->ibyte_position
- - 3 + (bitstream_buf_used-1)
- * SVA_STREAM_BUF_SIZE;
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = 1;
- *startcodepos = 3;
- i = read_n_bit(p_irabs, 8, &j);
- buf[3] = (char)j;
-
- check_type(buf[3]);
- if (buf[3] == SEQUENCE_END_CODE) {
- *length = 4;
- return -1;
- }
- k = 4;
- while (1) {
- i = read_n_bit(p_irabs, 8, &j);
- if (i < 0)
- break;
- buf[k++] = (char)j;
- if (k >= (MAX_CODED_FRAME_SIZE - 1))
- break;
- }
- if (p_irabs->iclear_bitsnum > 0) {
- int shift;
-
- shift = 8 - p_irabs->iclear_bitsnum;
- i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j);
-
- if (j != 0)
- buf[k++] = (char)(j << shift);
- stat_bits_ptr->last_unit_bits += shift;
- }
- *length = k;
- return k;
-}
-
-/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/
-/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/
-int header(void)
-{
- unsigned char *buf;
- int startcodepos, length;
-
- unsigned char *tmp_buf;
-
- tmp_buf = (unsigned char *)avsp_heap_adr;
-
- buf = &tmp_buf[0];
- while (1) {
- start_codeposition = get_oneunit(buf, &startcodepos, &length);
-
- switch (buf[startcodepos]) {
- case SEQUENCE_HEADER_CODE:
- io_printf(
- "# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case EXTENSION_START_CODE:
- io_printf(
- "# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case USER_DATA_START_CODE:
- io_printf(
- "# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case VIDEO_EDIT_CODE:
- io_printf(
- "# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case I_PICTURE_START_CODE:
- io_printf(
- "# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case PB_PICTURE_START_CODE:
- io_printf(
- "# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- case SEQUENCE_END_CODE:
- io_printf(
- "# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
- break;
- default:
- io_printf(
- "# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
- buf[startcodepos], startcode_offset,
- startcode_offset);
-#if 0
- io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_START_PTR));
- io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
- io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_END_PTR));
- io_printf("VLD_MEM_VIFIFO_WP %x\r\n"
- READ_VREG(VLD_MEM_VIFIFO_WP));
- io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n"
- READ_VREG(VLD_MEM_VBUF_RD_PTR));
- io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
- io_printf("PARSER_VIDEO_HOLE %x\r\n",
- READ_MPEG_REG(PARSER_VIDEO_HOLE));
-#endif
- if ((buf[startcodepos] >= SLICE_START_CODE_MIN
- && buf[startcodepos]
- <= SLICE_START_CODE_MAX)
- && ((!img->seq_header_indicate)
- || (img->type == B_IMG
- && img->b_discard_flag
- == 1
- && !img->no_forward_reference))) {
- break;
- } else if (buf[startcodepos] >= SLICE_START_CODE_MIN) {
-
- first_slice_length = length;
- first_slice_startpos = startcodepos;
-
- temp_slice_buf = &tmp_buf[0];
- return SOP;
- } else {
- io_printf("Can't find start code");
- return -EOS;
- }
- }
- }
-
-}
-
-/*
- *************************************************************************
- * Function:Allocates a Bitstream
- * Input:
- * Output:allocated Bitstream point
- * Return:
- * Attention:
- *************************************************************************
- */
-struct bitstream_s *alloc_bitstream(void)
-{
- struct bitstream_s *bitstream;
-
- bitstream = (struct bitstream_s *)local_alloc(1,
- sizeof(struct bitstream_s));
- if (bitstream == NULL) {
- io_printf(
- "AllocBitstream: Memory allocation for Bitstream failed");
- return NULL;
- }
- bitstream->stream_buffer = (unsigned char *)local_alloc(
- MAX_CODED_FRAME_SIZE,
- sizeof(unsigned char));
- if (bitstream->stream_buffer == NULL) {
- io_printf(
- "AllocBitstream: Memory allocation for streamBuffer failed");
- return NULL;
- }
-
- return bitstream;
-}
-
-void biari_init_context_logac(struct bi_context_type_s *ctx)
-{
- ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
- ctx->MPS = 0;
- ctx->cycno = 0;
-}
-
-#define BIARI_CTX_INIT1_LOG(jj, ctx)\
-{\
- for (j = 0; j < jj; j++)\
- biari_init_context_logac(&(ctx[j]));\
-}
-
-#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\
-{\
- for (i = 0; i < ii; i++)\
- for (j = 0; j < jj; j++)\
- biari_init_context_logac(&(ctx[i][j]));\
-}
-
-#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\
-{\
- for (i = 0; i < ii; i++)\
- for (j = 0; j < jj; j++)\
- for (k = 0; k < kk; k++)\
- biari_init_context_logac(&(ctx[i][j][k]));\
-}
-
-#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\
-{\
- for (i = 0; i < ii; i++)\
- for (j = 0; j < jj; j++)\
- for (k = 0; k < kk; k++)\
- for (l = 0; l < ll; l++)\
- biari_init_context_logac\
- (&(ctx[i][j][k][l]));\
-}
-
-void init_contexts(struct img_par *img)
-{
- struct motion_info_contexts_s *mc = img->current_slice->mot_ctx;
- struct texture_info_contexts *tc = img->current_slice->tex_ctx;
- int i, j;
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & SLICE_INFO_DUMP)
- io_printf(" ---- init_contexts ----\n");
-#endif
-
- BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts);
- BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts);
- BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts);
- BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts);
- BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts);
- BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts);
-
- BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts);
- BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts);
- BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX,
- tc->fld_last_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts);
- BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts);
-#ifdef TEST_WEIGHTING_AEC
- biari_init_context_logac(&mc->mb_weighting_pred);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- * Allocation of contexts models for the motion info
- * used for arithmetic decoding
- *
- ************************************************************************
- */
-struct motion_info_contexts_s *create_contexts_motioninfo(void)
-{
- struct motion_info_contexts_s *deco_ctx;
-
- deco_ctx = (struct motion_info_contexts_s *)local_alloc(1,
- sizeof(struct motion_info_contexts_s));
- if (deco_ctx == NULL)
- no_mem_exit("create_contexts_motioninfo: deco_ctx");
-
- return deco_ctx;
-}
-
-/*!
- ************************************************************************
- * \brief
- * Allocates of contexts models for the texture info
- * used for arithmetic decoding
- ************************************************************************
- */
-struct texture_info_contexts *create_contexts_textureinfo(void)
-{
- struct texture_info_contexts *deco_ctx;
-
- deco_ctx = (struct texture_info_contexts *)local_alloc(1,
- sizeof(struct texture_info_contexts));
- if (deco_ctx == NULL)
- no_mem_exit("create_contexts_textureinfo: deco_ctx");
-
- return deco_ctx;
-}
-
-struct datapartition *alloc_partition(int n)
-{
- struct datapartition *part_arr, *datapart;
- int i;
-
- part_arr =
- (struct datapartition *)local_alloc(n, sizeof(struct datapartition));
- if (part_arr == NULL) {
- no_mem_exit(
- "alloc_partition: Memory allocation for Data Partition failed");
- return NULL;
- }
-
-#if LIWR_FIX
- part_arr[0].bitstream = NULL;
-#else
- for (i = 0; i < n; i++) {
- datapart = &(part_arr[i]);
- datapart->bitstream = (struct bitstream_s *)local_alloc(1,
- sizeof(struct bitstream_s));
- if (datapart->bitstream == NULL) {
- no_mem_exit(
- "alloc_partition: Memory allocation for Bitstream failed");
- return NULL;
- }
- }
-#endif
- return part_arr;
-}
-
-int malloc_slice(struct img_par *img)
-{
- struct slice_s *currslice;
-
- img->current_slice =
- (struct slice_s *)local_alloc(1, sizeof(struct slice_s));
- currslice = img->current_slice;
- if (currslice == NULL) {
- no_mem_exit(
- "Memory allocation for struct slice_s datastruct Failed"
- );
- return 0;
- }
- if (1) {
-
- currslice->mot_ctx = create_contexts_motioninfo();
- if (currslice->mot_ctx == NULL)
- return 0;
-
- currslice->tex_ctx = create_contexts_textureinfo();
- if (currslice->tex_ctx == NULL)
- return 0;
- }
-#if LIWR_FIX
- currslice->max_part_nr = 1;
-#else
- currslice->max_part_nr = 3;
-#endif
- currslice->part_arr = alloc_partition(currslice->max_part_nr);
- if (currslice->part_arr == NULL)
- return 0;
- return 1;
-}
-
-void init(struct img_par *img)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- img->quad[i] = i * i;
-}
-
-/*
- *************************************************************************
- * Function:Allocate 2D memory array -> int array2D[rows][columns]
- * Input:
- * Output: memory size in bytes
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int get_mem2Dint(int ***array2D, int rows, int columns)
-{
- int i;
-
- *array2D = (int **)local_alloc(rows, sizeof(int *));
- if (*array2D == NULL) {
- no_mem_exit("get_mem2Dint: array2D");
- return -1;
- }
- (*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int));
- if ((*array2D)[0] == NULL) {
- no_mem_exit("get_mem2Dint: array2D");
- return -1;
- }
-
- for (i = 1; i < rows; i++)
- (*array2D)[i] = (*array2D)[i - 1] + columns;
-
- return rows * columns * sizeof(int);
-}
-
-int initial_decode(void)
-{
- int i, j;
- int ret;
- int img_height = (vertical_size + img->auto_crop_bottom);
- int memory_size = 0;
-
- ret = malloc_slice(img);
- if (ret == 0)
- return 0;
-
- mb_data = (struct macroblock *)local_alloc(
- (img->width / MB_BLOCK_SIZE)
- * (img_height /*vertical_size*/
- / MB_BLOCK_SIZE), sizeof(struct macroblock));
- if (mb_data == NULL) {
- no_mem_exit("init_global_buffers: mb_data");
- return 0;
- }
-
- if (progressive_sequence) {
- int size;
- size = get_mem2Dint(&(img->ipredmode),
- img->width / B8_SIZE * 2 + 4,
- vertical_size / B8_SIZE * 2 + 4);
- if (size == -1)
- return 0;
-
- memory_size += size;
- } else {
- int size;
- size = get_mem2Dint(&(img->ipredmode),
- img->width / B8_SIZE * 2 + 4,
- (vertical_size + 32) / (2 * B8_SIZE) * 4 + 4);
- if (size == -1)
- return 0;
-
- memory_size += size;
- }
-
- for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) {
- for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++)
- img->ipredmode[i][j] = -1;
- }
-
- init(img);
- img->number = 0;
- img->type = I_IMG;
- img->imgtr_last_p = 0;
- img->imgtr_next_p = 0;
-
- img->new_seq_header_flag = 1;
- img->new_sequence_flag = 1;
-
- return 1;
-}
-
-void aec_new_slice(void)
-{
- last_dquant = 0;
-}
-
-/*!
- ************************************************************************
- * \brief
- * Initializes the DecodingEnvironment for the arithmetic coder
- ************************************************************************
- */
-
-void arideco_start_decoding(struct decoding_environment_s *dep,
- unsigned char *cpixcode,
- int firstbyte, int *cpixcode_len, int slice_type)
-{
-
- dcodestrm = cpixcode;
- dcodestrm_len = cpixcode_len;
- *dcodestrm_len = firstbyte;
-
- s1 = 0;
- t1 = QUARTER - 1;
- value_s = 0;
-
- value_t = 0;
-
- {
- int i;
-
- dbits_to_go = 0;
- for (i = 0; i < B_BITS - 1; i++) {
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1)
- | ((dbuffer >> dbits_to_go) & 0x01);
- }
- }
-
- while (value_t < QUARTER) {
- if (--dbits_to_go < 0)
- get_byte();
-
- value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01);
- value_s++;
- }
- value_t = value_t & 0xff;
-
- dec_final = dec_bypass = 0;
-
-
-
-}
-
-/*
- *************************************************************************
- * Function:Checks the availability of neighboring macroblocks of
- the current macroblock for prediction and context determination;
- marks the unavailable MBs for intra prediction in the
- ipredmode-array by -1. Only neighboring MBs in the causal
- past of the current MB are checked.
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void checkavailabilityofneighbors(struct img_par *img)
-{
- int i, j;
- const int mb_width = img->width / MB_BLOCK_SIZE;
- const int mb_nr = img->current_mb_nr;
- struct macroblock *curr_mb = &mb_data[mb_nr];
- int check_value;
- int remove_prediction;
-
- curr_mb->mb_available_up = NULL;
- curr_mb->mb_available_left = NULL;
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- mb_data[mb_nr].mb_available[i][j] = NULL;
-
- mb_data[mb_nr].mb_available[1][1] = curr_mb;
-
- if (img->pix_x >= MB_BLOCK_SIZE) {
- remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - 1].slice_nr;
-
- if (remove_prediction)
-
- {
-
- img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
- + 1) * 2] = -1;
- img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
- + 1) * 2 + 1] = -1;
- img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
- + 2) * 2] = -1;
- img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
- + 2) * 2 + 1] = -1;
- }
- if (!remove_prediction)
- curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
-
- }
-
- check_value = (img->pix_y >= MB_BLOCK_SIZE);
- if (check_value) {
- remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - mb_width].slice_nr;
-
- if (remove_prediction) {
- img->ipredmode
- [(img->block_x + 1) * 2][(img->block_y + 1)
- * 2 - 1] = -1;
- img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y
- + 1) * 2 - 1] = -1;
- img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y
- + 1) * 2 - 1] = -1;
- img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y
- + 1) * 2 - 1] = -1;
- }
-
- if (!remove_prediction) {
- curr_mb->mb_available[0][1] =
- &(mb_data[mb_nr - mb_width]);
- }
- }
-
- if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
- remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - mb_width - 1].slice_nr;
-
- if (remove_prediction) {
- img->ipredmode[img->block_x * 2 + 1][img->block_y * 2
- + 1] = -1;
- }
- if (!remove_prediction) {
- curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
- - 1]);
- }
- }
-
- if (img->pix_y >= MB_BLOCK_SIZE
- && img->pix_x < (img->width - MB_BLOCK_SIZE)) {
- if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
- curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
- + 1]);
- }
-
- if (1) {
- curr_mb->mbaddr_a = mb_nr - 1;
- curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
- curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
- curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
-
- curr_mb->mbavail_a =
- (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
- curr_mb->mbavail_b =
- (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
- curr_mb->mbavail_c =
- (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
- curr_mb->mbavail_d =
- (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
-
- }
-
-}
-
-void checkavailabilityofneighborsaec(void)
-{
-
- int i, j;
- const int mb_width = img->width / MB_BLOCK_SIZE;
- const int mb_nr = img->current_mb_nr;
- struct macroblock *curr_mb = &(mb_data[mb_nr]);
- int check_value;
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- mb_data[mb_nr].mb_available[i][j] = NULL;
- mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]);
-
- if (img->pix_x >= MB_BLOCK_SIZE) {
- int remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - 1].slice_nr;
- if (!remove_prediction)
- curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
- }
-
- check_value = (img->pix_y >= MB_BLOCK_SIZE);
- if (check_value) {
- int remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - mb_width].slice_nr;
-
- if (!remove_prediction) {
- curr_mb->mb_available[0][1] =
- &(mb_data[mb_nr - mb_width]);
- }
- }
-
- if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
- int remove_prediction = curr_mb->slice_nr
- != mb_data[mb_nr - mb_width - 1].slice_nr;
- if (!remove_prediction) {
- curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
- - 1]);
- }
- }
-
- if (img->pix_y >= MB_BLOCK_SIZE
- && img->pix_x < (img->width - MB_BLOCK_SIZE)) {
- if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
- curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
- + 1]);
- }
- curr_mb->mb_available_left = curr_mb->mb_available[1][0];
- curr_mb->mb_available_up = curr_mb->mb_available[0][1];
- curr_mb->mbaddr_a = mb_nr - 1;
- curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
- curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
- curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
-
- curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
- curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
- curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
- curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
-}
-
-/*
- *************************************************************************
- * Function:initializes the current macroblock
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void start_macroblock(struct img_par *img)
-{
- int i, j, k, l;
- struct macroblock *curr_mb;
-
-#ifdef AVSP_LONG_CABAC
-#else
-
-#endif
-
- curr_mb = &mb_data[img->current_mb_nr];
-
- /* Update coordinates of the current macroblock */
- img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE);
- img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE);
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_NUM_DUMP)
- io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n",
- img->current_mb_nr, img->mb_x, img->mb_y, es_ptr);
-#endif
-
-
- total_mb_count = total_mb_count + 1;
-
- /* Define vertical positions */
- img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */
- img->block8_y = img->mb_y * BLOCK_SIZE / 2;
- img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
- if (chroma_format == 2)
- img->pix_c_y = img->mb_y *
- MB_BLOCK_SIZE; /* chroma macroblock position */
- else
- img->pix_c_y = img->mb_y *
- MB_BLOCK_SIZE / 2; /* chroma macroblock position */
-
- /* Define horizontal positions */
- img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */
- img->block8_x = img->mb_x * BLOCK_SIZE / 2;
- img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
- img->pix_c_x = img->mb_x *
- MB_BLOCK_SIZE / 2; /* chroma pixel position */
-
- checkavailabilityofneighbors(img);
-
- /*<!*******EDIT START BY lzhang ******************/
-
- if (1)
- checkavailabilityofneighborsaec();
- /*<!*******EDIT end BY lzhang ******************/
-
- curr_mb->qp = img->qp;
- curr_mb->mb_type = 0;
- curr_mb->delta_quant = 0;
- curr_mb->cbp = 0;
- curr_mb->cbp_blk = 0;
- curr_mb->c_ipred_mode = DC_PRED_8;
- curr_mb->c_ipred_mode_2 = DC_PRED_8;
-
- for (l = 0; l < 2; l++)
- for (j = 0; j < BLOCK_MULTIPLE; j++)
- for (i = 0; i < BLOCK_MULTIPLE; i++)
- for (k = 0; k < 2; k++)
- curr_mb->mvd[l][j][i][k] = 0;
-
- curr_mb->cbp_bits = 0;
-
- for (j = 0; j < MB_BLOCK_SIZE; j++)
- for (i = 0; i < MB_BLOCK_SIZE; i++)
- img->m7[i][j] = 0;
-
- for (j = 0; j < 2 * BLOCK_SIZE; j++)
- for (i = 0; i < 2 * BLOCK_SIZE; i++) {
- img->m8[0][i][j] = 0;
- img->m8[1][i][j] = 0;
- img->m8[2][i][j] = 0;
- img->m8[3][i][j] = 0;
- }
-
- curr_mb->lf_disable = 1;
-
- img->weighting_prediction = 0;
-}
-
-/*
- *************************************************************************
- * Function:init macroblock I and P frames
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void init_macroblock(struct img_par *img)
-{
- int i, j;
-
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- img->ipredmode[img->block_x * 2 + i + 2][img->block_y
- * 2 + j + 2] = -1;
- }
- }
-
-}
-
-/*
- *************************************************************************
- * Function:Interpret the mb mode for I-Frames
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void interpret_mb_mode_i(struct img_par *img)
-{
- int i;
-
- struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
- int num = 4;
-
- curr_mb->mb_type = I8MB;
-
-
- current_mb_intra = 1;
-
- for (i = 0; i < 4; i++) {
- curr_mb->b8mode[i] = IBLOCK;
- curr_mb->b8pdir[i] = -1;
- }
-
- for (i = num; i < 4; i++) {
- curr_mb->b8mode[i] =
- curr_mb->mb_type_2 == P8x8 ?
- 4 : curr_mb->mb_type_2;
- curr_mb->b8pdir[i] = 0;
- }
-}
-
-const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1,
- 1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3},
- {0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0,
- 0, 0, 0, 0, 6, 0, 0},
- {0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8}
-
-};
-
-const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0
-
-};
-
-const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4};
-
-void read_ipred_block_modes(struct img_par *img, int b8)
-{
- int bi, bj, dec;
- struct syntaxelement curr_se;
- struct macroblock *curr_mb;
- int j2;
- int mostprobableintrapredmode;
- int upintrapredmode;
- int uprightintrapredmode;
- int leftintrapredmode;
- int leftdownintrapredmode;
- int intrachromapredmodeflag;
-
- struct slice_s *currslice = img->current_slice;
- struct datapartition *dp;
-
- curr_mb = mb_data + img->current_mb_nr;
- intrachromapredmodeflag = IS_INTRA(curr_mb);
-
- curr_se.type = SE_INTRAPREDMODE;
-#if TRACE
- strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE);
-#endif
-
- if (b8 < 4) {
- if (curr_mb->b8mode[b8] == IBLOCK) {
- intrachromapredmodeflag = 1;
-
- if (1) {
- dp = &(currslice->part_arr[0]);
- curr_se.reading = read_intrapredmode_aec;
- dp->read_syntax_element(&curr_se, img, dp);
-
- if (curr_se.value1 == -1)
- push_es(1, 1);
- else
- push_es(curr_se.value1, 3);
-
-
- }
- bi = img->block_x + (b8 & 1);
- bj = img->block_y + (b8 / 2);
-
- upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2
- + 1];
- uprightintrapredmode =
- img->ipredmode[(bi + 1) * 2 + 1][(bj)
- * 2 + 1];
- leftintrapredmode =
- img->ipredmode[(bi) * 2 + 1][(bj + 1)
- * 2];
- leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj
- + 1) * 2 + 1];
-
- if ((upintrapredmode < 0) || (leftintrapredmode < 0)) {
- mostprobableintrapredmode = DC_PRED;
- } else if ((upintrapredmode < NO_INTRA_PMODE)
- && (leftintrapredmode <
- NO_INTRA_PMODE)) {
- mostprobableintrapredmode =
- upintrapredmode
- < leftintrapredmode ?
- upintrapredmode :
- leftintrapredmode;
- } else if (upintrapredmode < NO_INTRA_PMODE) {
- mostprobableintrapredmode = upintrapredmode;
- } else if (leftintrapredmode < NO_INTRA_PMODE) {
- mostprobableintrapredmode = leftintrapredmode;
- } else {
- mostprobableintrapredmode =
- pred_4x4[leftintrapredmode
- - INTRA_PMODE_4x4][upintrapredmode
- - INTRA_PMODE_4x4];
- mostprobableintrapredmode =
- pred_4x4to8x8[mostprobableintrapredmode];
- }
-
-
-
- dec =
- (curr_se.value1 == -1) ?
- mostprobableintrapredmode :
- curr_se.value1
- + (curr_se.value1
- >= mostprobableintrapredmode);
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_INFO_DUMP)
- io_printf(" - ipredmode[%d] : %d\n", b8, dec);
-#endif
-
- img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec;
- img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec;
- img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec;
- img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] =
- dec;
-
- j2 = bj;
- }
- } else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) {
-
- curr_se.type = SE_INTRAPREDMODE;
-#if TRACE
- strncpy(curr_se.tracestring,
- "Chroma intra pred mode", TRACESTRING_SIZE);
-#endif
-
- if (1) {
- dp = &(currslice->part_arr[0]);
- curr_se.reading = read_cipredmode_aec;
- dp->read_syntax_element(&curr_se, img, dp);
- } else
-
- {
- }
- curr_mb->c_ipred_mode = curr_se.value1;
-
- push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]);
-
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_INFO_DUMP)
- io_printf(" * UE c_ipred_mode read : %d\n",
- curr_mb->c_ipred_mode);
-#endif
-
- if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) {
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_INFO_DUMP)
- io_printf("%d\n", img->current_mb_nr);
-#endif
- pr_info("illegal chroma intra pred mode!\n");
- }
- }
-}
-
-/*!
- ************************************************************************
- * \brief
- * This function is used to arithmetically decode the coded
- * block pattern of a given MB.
- ************************************************************************
- */
-void readcp_aec(struct syntaxelement *se, struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
- struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-
- int mb_x, mb_y;
- int a, b;
- int curr_cbp_ctx, curr_cbp_idx;
- int cbp = 0;
- int cbp_bit;
- int mask;
-
- for (mb_y = 0; mb_y < 4; mb_y += 2) {
- for (mb_x = 0; mb_x < 4; mb_x += 2) {
- if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK)
- curr_cbp_idx = 0;
- else
- curr_cbp_idx = 1;
-
- if (mb_y == 0) {
- if (curr_mb->mb_available_up == NULL)
- b = 0;
- else {
- b = ((((curr_mb->mb_available_up)->cbp
- & (1 << (2 + mb_x / 2)))
- == 0) ? 1 : 0);
- }
-
- } else
- b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0);
-
- if (mb_x == 0) {
- if (curr_mb->mb_available_left == NULL)
- a = 0;
- else {
- a =
- ((((curr_mb->mb_available_left)->cbp
- & (1
- << (2
- * (mb_y
- / 2)
- + 1)))
- == 0) ?
- 1 : 0);
- }
- } else
- a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0);
- curr_cbp_ctx = a + 2 * b;
- mask = (1 << (mb_y + mb_x / 2));
- cbp_bit = biari_decode_symbol(dep_dp,
- ctx->cbp_contexts[0] + curr_cbp_ctx);
-
- if (cbp_bit)
- cbp += mask;
- }
- }
- curr_cbp_ctx = 0;
- cbp_bit = biari_decode_symbol(dep_dp,
- ctx->cbp_contexts[1] + curr_cbp_ctx);
-
- if (cbp_bit) {
- curr_cbp_ctx = 1;
- cbp_bit = biari_decode_symbol(dep_dp,
- ctx->cbp_contexts[1] + curr_cbp_ctx);
- if (cbp_bit) {
- cbp += 48;
-
- } else {
- curr_cbp_ctx = 1;
- cbp_bit = biari_decode_symbol(dep_dp,
- ctx->cbp_contexts[1] + curr_cbp_ctx);
- cbp += (cbp_bit == 1) ? 32 : 16;
-
- }
- }
-
- se->value1 = cbp;
- if (!cbp)
- last_dquant = 0;
-
-
-
-}
-
-/*!
- ************************************************************************
- * \brief
- * This function is used to arithmetically decode the delta qp
- * of a given MB.
- ************************************************************************
- */
-void readdquant_aec(struct syntaxelement *se, struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx;
-
- int act_ctx;
- int act_sym;
- int dquant;
-
-
- act_ctx = ((last_dquant != 0) ? 1 : 0);
-
- act_sym = 1
- - biari_decode_symbol(dep_dp,
- ctx->delta_qp_contexts + act_ctx);
- if (act_sym != 0) {
- act_ctx = 2;
- act_sym = unary_bin_decode(dep_dp,
- ctx->delta_qp_contexts + act_ctx, 1);
- act_sym++;
- }
- act_sym &= 0x3f;
- push_es(UE[act_sym][0], UE[act_sym][1]);
-
- dquant = (act_sym + 1) / 2;
- if ((act_sym & 0x01) == 0)
- dquant = -dquant;
- se->value1 = dquant;
-
- last_dquant = dquant;
-
-}
-
-int csyntax;
-
-#define CHECKDELTAQP {\
- if (img->qp+curr_mb->delta_quant > 63\
- || img->qp+curr_mb->delta_quant < 0) {\
- csyntax = 0;\
- transcoding_error_flag = 1;\
- io_printf("error(0) (%3d|%3d) @ MB%d\n",\
- curr_mb->delta_quant,\
- img->qp+curr_mb->delta_quant,\
- img->picture_structure == 0 \
- ? img->current_mb_nr_fld : img->current_mb_nr);\
- } }
-
-int dct_level[65];
-int dct_run[65];
-int pair_pos;
-int dct_pairs = -1;
-const int t_chr[5] = {0, 1, 2, 4, 3000};
-
-void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img,
- struct decoding_environment_s *dep_dp)
-{
- int pairs, rank, pos;
- int run, level, abslevel, symbol;
- int sign;
-
- if (dct_pairs < 0) {
- struct bi_context_type_s (*primary)[NUM_MAP_CTX];
- struct bi_context_type_s *pctx;
- struct bi_context_type_s *pCTX2;
- int ctx, ctx2, offset;
-
- if (se->context == LUMA_8x8) {
- if (img->picture_structure == 0) {
- primary =
- img->current_slice->tex_ctx->fld_map_contexts;
- } else {
- primary =
- img->current_slice->tex_ctx->map_contexts;
- }
- } else {
- if (img->picture_structure == 0) {
- primary =
- img->current_slice->tex_ctx->fld_last_contexts;
- } else {
- primary =
- img->current_slice->tex_ctx->last_contexts;
- }
- }
-
- rank = 0;
- pos = 0;
- for (pairs = 0; pairs < 65; pairs++) {
-#ifdef DECODING_SANITY_CHECK
- /*max index is NUM_BLOCK_TYPES - 1*/
- pctx = primary[rank & 0x7];
-#else
- pctx = primary[rank];
-#endif
- if (rank > 0) {
-#ifdef DECODING_SANITY_CHECK
- /*max index is NUM_BLOCK_TYPES - 1*/
- pCTX2 = primary[(5 + (pos >> 5)) & 0x7];
-#else
- pCTX2 = primary[5 + (pos >> 5)];
-#endif
- ctx2 = (pos >> 1) & 0x0f;
- ctx = 0;
-
-
- if (biari_decode_symbolw(dep_dp, pctx + ctx,
- pCTX2 + ctx2)) {
- break;
- }
- }
-
- ctx = 1;
- symbol = 0;
- while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
- symbol += 1;
- ctx++;
- if (ctx >= 2)
- ctx = 2;
- }
- abslevel = symbol + 1;
-
- if (biari_decode_symbol_eq_prob(dep_dp)) {
- level = -abslevel;
- sign = 1;
- } else {
- level = abslevel;
- sign = 0;
- }
-#if TRACE
- tracebits2("level", 1, level);
-#endif
-
- if (abslevel == 1)
- offset = 4;
- else
- offset = 6;
- symbol = 0;
- ctx = 0;
- while (biari_decode_symbol(dep_dp, pctx + ctx + offset)
- == 0) {
- symbol += 1;
- ctx++;
- if (ctx >= 1)
- ctx = 1;
- }
- run = symbol;
-
-#if TRACE
- tracebits2("run", 1, run);
-#endif
- dct_level[pairs] = level;
- dct_run[pairs] = run;
- if (abslevel > t_chr[rank]) {
- if (abslevel <= 2)
- rank = abslevel;
- else if (abslevel <= 4)
- rank = 3;
- else
- rank = 4;
- }
- pos += (run + 1);
- if (pos >= 64)
- pos = 63;
- }
- dct_pairs = pairs;
- pair_pos = dct_pairs;
- }
-
- if (dct_pairs > 0) {
- se->value1 = dct_level[pair_pos - 1];
- se->value2 = dct_run[pair_pos - 1];
- pair_pos--;
- } else {
-
- se->value1 = se->value2 = 0;
- }
-
- if ((dct_pairs--) == 0)
- pair_pos = 0;
-}
-
-int b8_ctr;
-#if 0
-int curr_residual_chroma[4][16][16];
-int curr_residual_luma[16][16];
-#endif
-
-const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1,
- 1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1,
- 4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4,
- 0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3,
- 4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6,
- 0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4,
- 6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6,
- 6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7,
- 6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {
- 3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, {
- 4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, {
- 1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, {
- 5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, {
- 3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, {
- 4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, {
- 7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, {
- 6, 7}, {7, 7} } };
-
-const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3,
- 0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2,
- 3}, {3, 3} };
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void encode_golomb_word(unsigned int symbol, unsigned int grad0,
- unsigned int max_levels, unsigned int *res_bits,
- unsigned int *res_len)
-{
- unsigned int level, res, numbits;
-
- res = 1UL << grad0;
- level = 1UL;
- numbits = 1UL + grad0;
-
- while (symbol >= res && level < max_levels) {
- symbol -= res;
- res = res << 1;
- level++;
- numbits += 2UL;
- }
-
- if (level >= max_levels) {
- if (symbol >= res)
- symbol = res - 1UL;
- }
-
- *res_bits = res | symbol;
- *res_len = numbits;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void encode_multilayer_golomb_word(unsigned int symbol,
- const unsigned int *grad, const unsigned int *max_levels,
- unsigned int *res_bits, unsigned int *res_len)
-{
- unsigned int accbits, acclen, bits, len, tmp;
-
- accbits = acclen = 0UL;
-
- while (1) {
- encode_golomb_word(symbol, *grad, *max_levels, &bits, &len);
- accbits = (accbits << len) | bits;
- acclen += len;
-#ifdef AVSP_LONG_CABAC
-#else
- assert(acclen <= 32UL);
-#endif
- tmp = *max_levels - 1UL;
-
- if (!((len == (tmp << 1) + (*grad))
- && (bits == (1UL << (tmp + *grad)) - 1UL)))
- break;
-
- tmp = *max_levels;
- symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL;
- grad++;
- max_levels++;
- }
- *res_bits = accbits;
- *res_len = acclen;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream)
-{
- unsigned int bits, len, i;
- unsigned int grad[4], max_lev[4];
-
- if (!(se->golomb_maxlevels & ~0xFF))
- encode_golomb_word(se->value1, se->golomb_grad,
- se->golomb_maxlevels, &bits, &len);
- else {
- for (i = 0UL; i < 4UL; i++) {
- grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL;
- max_lev[i] = (se->golomb_maxlevels >> (i << 3))
- & 0xFFUL;
- }
- encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits,
- &len);
- }
-
- se->len = len;
- se->bitpattern = bits;
-
- if (write_to_stream)
- push_es(bits, len);
- return se->len;
-}
-
-/*
- *************************************************************************
- * Function:Get coded block pattern and coefficients (run/level)
- from the bitstream
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void read_cbpandcoeffsfrom_nal(struct img_par *img)
-{
-
- int tablenum;
- int inumblk;
- int inumcoeff;
- int symbol2D;
- int escape_level_diff;
- const int (*AVS_2DVLC_table_intra)[26][27];
- const int (*AVS_2DVLC_table_chroma)[26][27];
- int write_to_stream;
- struct syntaxelement currse_enc;
- struct syntaxelement *e_currse = &currse_enc;
-
- int coeff_save[65][2];
- int coeff_ptr;
-
- int ii, jj;
- int mb_nr = img->current_mb_nr;
-
- int m2, jg2;
- struct macroblock *curr_mb = &mb_data[mb_nr];
-
- int block8x8;
-
- int block_x, block_y;
-
- struct slice_s *currslice = img->current_slice;
- int level, run, coef_ctr, len, k, i0, j0, uv, qp;
-
- int boff_x, boff_y, start_scan;
- struct syntaxelement curr_se;
- struct datapartition *dp;
-
- AVS_2DVLC_table_intra = AVS_2DVLC_INTRA;
- AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA;
- write_to_stream = 1;
-
- dct_pairs = -1;
-
- curr_mb->qp = img->qp;
- qp = curr_mb->qp;
-
-
- for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */
- for (block_x = 0; block_x < 4; block_x += 2) {
- block8x8 = 2 * (block_y / 2) + block_x / 2;
- if (curr_mb->cbp & (1 << block8x8)) {
- tablenum = 0;
- inumblk = 1;
- inumcoeff = 65;
- coeff_save[0][0] = 0;
- coeff_save[0][1] = 0;
- coeff_ptr = 1;
-
- b8_ctr = block8x8;
-
- boff_x = (block8x8 % 2) << 3;
- boff_y = (block8x8 / 2) << 3;
-
- img->subblock_x = boff_x >> 2;
- img->subblock_y = boff_y >> 2;
-
- start_scan = 0;
- coef_ctr = start_scan - 1;
- level = 1;
- img->is_v_block = 0;
- img->is_intra_block = IS_INTRA(curr_mb);
- for (k = start_scan;
- (k < 65) && (level != 0);
- k++) {
-
- curr_se.context = LUMA_8x8;
- curr_se.type =
- (IS_INTRA(curr_mb)) ?
- SE_LUM_AC_INTRA :
- SE_LUM_AC_INTER;
-
- dp = &(currslice->part_arr[0]);
- curr_se.reading =
- readrunlevel_aec_ref;
- dp->
- read_syntax_element(&curr_se,
- img, dp);
- level = curr_se.value1;
- run = curr_se.value2;
- len = curr_se.len;
-
- if (level != 0) {
- coeff_save[coeff_ptr][0] =
- run;
- coeff_save[coeff_ptr][1] =
- level;
- coeff_ptr++;
- }
-
-
-
- if (level != 0) {/* leave if len = 1 */
- coef_ctr += run + 1;
- if ((img->picture_structure
- == FRAME)) {
- ii =
- SCAN[img->picture_structure]
- [coef_ctr][0];
- jj =
- SCAN[img->picture_structure]
- [coef_ctr][1];
- } else {
- ii =
- SCAN[img->picture_structure]
- [coef_ctr][0];
- jj =
- SCAN[img->picture_structure]
- [coef_ctr][1];
- }
-
- }
- }
-
- while (coeff_ptr > 0) {
- run =
- coeff_save[coeff_ptr
- - 1][0];
- level =
- coeff_save[coeff_ptr
- - 1][1];
-
- coeff_ptr--;
-
- symbol2D = CODE2D_ESCAPE_SYMBOL;
- if (level > -27 && level < 27
- && run < 26) {
- if (tablenum == 0)
-
- symbol2D =
- AVS_2DVLC_table_intra
- [tablenum]
- [run][abs(
- level)
- - 1];
- else
-
- symbol2D =
- AVS_2DVLC_table_intra
- [tablenum]
- [run][abs(
- level)];
- if (symbol2D >= 0
- && level
- < 0)
- symbol2D++;
- if (symbol2D < 0)
-
- symbol2D =
- (CODE2D_ESCAPE_SYMBOL
- + (run
- << 1)
- + ((level
- > 0) ?
- 1 :
- 0));
- }
-
- else {
-
- symbol2D =
- (CODE2D_ESCAPE_SYMBOL
- + (run
- << 1)
- + ((level
- > 0) ?
- 1 :
- 0));
- }
-
-
-
- e_currse->type = SE_LUM_AC_INTER;
- e_currse->value1 = symbol2D;
- e_currse->value2 = 0;
-
- e_currse->golomb_grad =
- vlc_golomb_order
- [0][tablenum][0];
- e_currse->golomb_maxlevels =
- vlc_golomb_order
- [0][tablenum][1];
-
- writesyntaxelement_golomb(
- e_currse,
- write_to_stream);
-
- if (symbol2D
- >= CODE2D_ESCAPE_SYMBOL) {
-
- e_currse->type =
- SE_LUM_AC_INTER;
- e_currse->golomb_grad =
- 1;
- e_currse->golomb_maxlevels =
- 11;
- escape_level_diff =
- abs(
- level)
- - ((run
- > MaxRun[0][tablenum]) ?
- 1 :
- refabslevel[tablenum][run]);
- e_currse->value1 =
- escape_level_diff;
-
- writesyntaxelement_golomb(
- e_currse,
- write_to_stream);
-
- }
-
- if (abs(level)
- > incvlc_intra[tablenum]) {
- if (abs(level) <= 2)
- tablenum =
- abs(
- level);
- else if (abs(level) <= 4)
- tablenum = 3;
- else if (abs(level) <= 7)
- tablenum = 4;
- else if (abs(level)
- <= 10)
- tablenum = 5;
- else
- tablenum = 6;
- }
- }
-
-
- }
- }
- }
-
-
-
- m2 = img->mb_x * 2;
- jg2 = img->mb_y * 2;
-
-
- uv = -1;
- block_y = 4;
-#if 0
- qp = QP_SCALE_CR[curr_mb->qp];
-#endif
- for (block_x = 0; block_x < 4; block_x += 2) {
-
- uv++;
-
-
- b8_ctr = (uv + 4);
- if ((curr_mb->cbp >> (uv + 4)) & 0x1) {
-
- tablenum = 0;
- inumblk = 1;
- inumcoeff = 65;
- coeff_save[0][0] = 0;
- coeff_save[0][1] = 0;
- coeff_ptr = 1;
-
- coef_ctr = -1;
- level = 1;
- img->subblock_x = 0;
- img->subblock_y = 0;
- curr_se.context = CHROMA_AC;
- curr_se.type = (IS_INTRA(curr_mb) ?
- SE_CHR_AC_INTRA :
- SE_CHR_AC_INTER);
- dp = &(currslice->part_arr[0]);
- curr_se.reading = readrunlevel_aec_ref;
- img->is_v_block = uv;
- img->is_intra_block = IS_INTRA(curr_mb);
- for (k = 0; (k < 65) && (level != 0); k++) {
-
- dp->read_syntax_element
- (&curr_se, img, dp);
- level = curr_se.value1;
- run = curr_se.value2;
- len = curr_se.len;
-
- if (level != 0) {
- coeff_save[coeff_ptr][0] = run;
- coeff_save[coeff_ptr][1] =
- level;
- coeff_ptr++;
- }
-
-
- if (level != 0) {
- coef_ctr = coef_ctr + run + 1;
- if ((img->picture_structure
- == FRAME)
- /*&& (!curr_mb->mb_field)*/) {
- i0 =
- SCAN[img->picture_structure]
- [coef_ctr][0];
- j0 =
- SCAN[img->picture_structure]
- [coef_ctr][1];
- } else {
- i0 =
- SCAN[img->picture_structure]
- [coef_ctr][0];
- j0 =
- SCAN[img->picture_structure]
- [coef_ctr][1];
- }
-
- }
- }
-
- while (coeff_ptr > 0) {
-
- run = coeff_save[coeff_ptr - 1][0];
- level = coeff_save[coeff_ptr - 1][1];
-
- coeff_ptr--;
-
- symbol2D = CODE2D_ESCAPE_SYMBOL;
- if (level > -27 && level < 27
- && run < 26) {
- if (tablenum == 0)
-
- symbol2D =
- AVS_2DVLC_table_chroma
- [tablenum][run][abs(
- level)
- - 1];
- else
- symbol2D =
- AVS_2DVLC_table_chroma
- [tablenum][run][abs(
- level)];
- if (symbol2D >= 0
- && level < 0)
- symbol2D++;
- if (symbol2D < 0)
- symbol2D =
- (CODE2D_ESCAPE_SYMBOL
- + (run
- << 1)
- + ((level
- > 0) ?
- 1 :
- 0));
- }
-
- else {
- symbol2D =
- (CODE2D_ESCAPE_SYMBOL
- + (run
- << 1)
- + ((level
- > 0) ?
- 1 :
- 0));
- }
-
- e_currse->type = SE_LUM_AC_INTER;
- e_currse->value1 = symbol2D;
- e_currse->value2 = 0;
- e_currse->golomb_grad =
- vlc_golomb_order[2]
- [tablenum][0];
- e_currse->golomb_maxlevels =
- vlc_golomb_order[2]
- [tablenum][1];
-
- writesyntaxelement_golomb(e_currse,
- write_to_stream);
-
- /*
- * if (write_to_stream)
- * {
- * bitCount[BITS_COEFF_UV_MB]+=e_currse->len;
- * e_currse++;
- * curr_mb->currSEnr++;
- * }
- * no_bits+=e_currse->len;
-
-
- * if (icoef == 0) break;
- */
-
- if (symbol2D >= CODE2D_ESCAPE_SYMBOL) {
-
- e_currse->type = SE_LUM_AC_INTER;
- e_currse->golomb_grad = 0;
- e_currse->golomb_maxlevels = 11;
- escape_level_diff =
- abs(level)
- - ((run
- > MaxRun[2][tablenum]) ?
- 1 :
- refabslevel[tablenum
- + 14][run]);
- e_currse->value1 =
- escape_level_diff;
-
- writesyntaxelement_golomb(
- e_currse,
- write_to_stream);
-
- }
-
- if (abs(level)
- > incvlc_chroma[tablenum]) {
- if (abs(level) <= 2)
- tablenum = abs(level);
- else if (abs(level) <= 4)
- tablenum = 3;
- else
- tablenum = 4;
- }
- }
-
- }
- }
-}
-
-/*
- *************************************************************************
- * Function:Get the syntax elements from the NAL
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int read_one_macroblock(struct img_par *img)
-{
- int i, j;
-
- struct syntaxelement curr_se;
- struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-
- int cabp_flag;
-
- int tempcbp;
- int fixqp;
-
- struct slice_s *currslice = img->current_slice;
- struct datapartition *dp;
-
- fixqp = (fixed_picture_qp || fixed_slice_qp);
-
- for (i = 0; i < 8; i++)
- for (j = 0; j < 8; j++) {
- img->m8[0][i][j] = 0;
- img->m8[1][i][j] = 0;
- img->m8[2][i][j] = 0;
- img->m8[3][i][j] = 0;
- }
-
- current_mb_skip = 0;
-
- curr_mb->qp = img->qp;
- curr_se.type = SE_MBTYPE;
- curr_se.mapping = linfo_ue;
-
- curr_mb->mb_type_2 = 0;
-
- if (img->type == I_IMG)
- curr_mb->mb_type = 0;
-
- interpret_mb_mode_i(img);
-
- init_macroblock(img);
-
- if ((IS_INTRA(curr_mb)) && (img->abt_flag)) {
-
-#if TRACE
- strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE);
-#endif
-
- curr_se.len = 1;
- curr_se.type = SE_CABP;
- read_syntaxelement_flc(&curr_se);
- cabp_flag = curr_se.value1;
- if (cabp_flag == 0) {
- curr_mb->CABP[0] = 0;
- curr_mb->CABP[1] = 0;
- curr_mb->CABP[2] = 0;
- curr_mb->CABP[3] = 0;
- } else {
- for (i = 0; i < 4; i++) {
- curr_se.len = 1;
- curr_se.type = SE_CABP;
- read_syntaxelement_flc(&curr_se);
- curr_mb->CABP[i] = curr_se.value1;
- }
- }
-
- } else {
- curr_mb->CABP[0] = 0;
- curr_mb->CABP[1] = 0;
- curr_mb->CABP[2] = 0;
- curr_mb->CABP[3] = 0;
-
- }
-
- if (IS_INTRA(curr_mb)) {
- for (i = 0; i < /*5*/(chroma_format + 4); i++)
-
- read_ipred_block_modes(img, i);
- }
-
- curr_se.type = SE_CBP_INTRA;
- curr_se.mapping = linfo_cbp_intra;
-
-#if TRACE
- snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP");
-#endif
-
- if (img->type == I_IMG || IS_INTER(curr_mb)) {
- curr_se.golomb_maxlevels = 0;
-
- if (1) {
- dp = &(currslice->part_arr[0]);
- curr_se.reading = readcp_aec;
- dp->read_syntax_element(&curr_se, img, dp);
- }
-
-
- curr_mb->cbp = curr_se.value1;
- push_es(UE[NCBP[curr_se.value1][0]][0],
- UE[NCBP[curr_se.value1][0]][1]);
-
- }
-
-# if 1
- if (curr_mb->cbp != 0)
- tempcbp = 1;
- else
- tempcbp = 0;
-#else
-
- if (chroma_format == 2) {
-#if TRACE
- snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422");
-#endif
- curr_se.mapping = /*linfo_se*/linfo_ue;
- curr_se.type = SE_CBP_INTRA;
- readsyntaxelement_uvlc(&curr_se, inp);
- curr_mb->cbp01 = curr_se.value1;
- io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01);
- }
-
- if (chroma_format == 2) {
- if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0)
- tempcbp = 1;
- else
- tempcbp = 0;
-
- } else {
- if (curr_mb->cbp != 0)
- tempcbp = 1;
- else
- tempcbp = 0;
- }
-
-#endif
-
- if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) {
- curr_mb->CABT[0] = curr_mb->CABP[0];
- curr_mb->CABT[1] = curr_mb->CABP[1];
- curr_mb->CABT[2] = curr_mb->CABP[2];
- curr_mb->CABT[3] = curr_mb->CABP[3];
- } else {
-
- curr_mb->CABT[0] = 0;
- curr_mb->CABT[1] = 0;
- curr_mb->CABT[2] = 0;
- curr_mb->CABT[3] = 0;
-
- if (!fixqp && (tempcbp)) {
- if (IS_INTER(curr_mb))
- curr_se.type = SE_DELTA_QUANT_INTER;
- else
- curr_se.type = SE_DELTA_QUANT_INTRA;
-
-#if TRACE
- snprintf(curr_se.tracestring,
- TRACESTRING_SIZE, "Delta quant ");
-#endif
-
- if (1) {
- dp = &(currslice->part_arr[0]);
- curr_se.reading = readdquant_aec;
- dp->read_syntax_element(&curr_se, img, dp);
- }
-
- curr_mb->delta_quant = curr_se.value1;
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_INFO_DUMP) {
- io_printf(" * SE delta_quant read : %d\n",
- curr_mb->delta_quant);
- }
-#endif
- CHECKDELTAQP
-
- if (transcoding_error_flag)
- return -1;
-
- img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
- + (MAX_QP - MIN_QP + 1))
- % (MAX_QP - MIN_QP + 1) + MIN_QP;
- }
-
- if (fixqp) {
- curr_mb->delta_quant = 0;
- img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
- + (MAX_QP - MIN_QP + 1))
- % (MAX_QP - MIN_QP + 1) + MIN_QP;
-
- }
-#ifdef DUMP_DEBUG
- if (avs_get_debug_flag() & MB_INFO_DUMP)
- io_printf(" - img->qp : %d\n", img->qp);
-#endif
- }
-
- read_cbpandcoeffsfrom_nal(img);
- return DECODE_MB;
-}
-
-/*!
- ************************************************************************
- * \brief
- * finding end of a slice in case this is not the end of a frame
- *
- * Unsure whether the "correction" below actually solves an off-by-one
- * problem or whether it introduces one in some cases :-( Anyway,
- * with this change the bit stream format works with AEC again.
- * StW, 8.7.02
- ************************************************************************
- */
-int aec_startcode_follows(struct img_par *img, int eos_bit)
-{
- struct slice_s *currslice = img->current_slice;
- struct datapartition *dp;
- unsigned int bit;
- struct decoding_environment_s *dep_dp;
-
- dp = &(currslice->part_arr[0]);
- dep_dp = &(dp->de_aec);
-
- if (eos_bit)
- bit = biari_decode_final(dep_dp);
- else
- bit = 0;
-
- return bit == 1 ? 1 : 0;
-}
-
-#ifdef AVSP_LONG_CABAC
-int process_long_cabac(void)
-#else
-void main(void)
-#endif
-{
- int data32;
- int current_header;
- int i;
- int tmp;
- int ret;
-
- int byte_startposition;
- int aec_mb_stuffing_bit;
- struct slice_s *currslice;
-#ifdef PERFORMANCE_DEBUG
- pr_info("enter %s\r\n", __func__);
-#endif
- transcoding_error_flag = 0;
- ret = 0;
- es_buf = es_write_addr_virt;
-
- if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) {
- ret = -1;
- goto End;
- }
-
- img = (struct img_par *)local_alloc(1, sizeof(struct img_par));
- if (img == NULL) {
- no_mem_exit("main: img");
- ret = -1;
- goto End;
- }
- stat_bits_ptr = (struct stat_bits *)local_alloc(1,
- sizeof(struct stat_bits));
- if (stat_bits_ptr == NULL) {
- no_mem_exit("main: stat_bits");
- ret = -1;
- goto End;
- }
-
- curr_stream = alloc_bitstream();
- if (curr_stream == NULL) {
- io_printf("alloc bitstream failed\n");
- ret = -1;
- goto End;
- }
-
- chroma_format = 1;
- demulate_enable = 0;
- img->seq_header_indicate = 1;
-
-#ifdef AVSP_LONG_CABAC
- data32 = READ_VREG(LONG_CABAC_REQ);
- progressive_sequence = (data32 >> 1) & 1;
- fixed_picture_qp = (data32 >> 2) & 1;
- img->picture_structure = (data32 >> 3) & 1;
- img->type = (data32 >> 4) & 3;
- skip_mode_flag = (data32 >> 6) & 1;
-
- src_start = READ_VREG(LONG_CABAC_SRC_ADDR);
- des_start = READ_VREG(LONG_CABAC_DES_ADDR);
-
- data32 = READ_VREG(LONG_CABAC_PIC_SIZE);
- horizontal_size = (data32 >> 0) & 0xffff;
- vertical_size = (data32 >> 16) & 0xffff;
- if (horizontal_size * vertical_size > 1920 * 1080) {
- io_printf("pic size check failed: width = %d, height = %d\n",
- horizontal_size, vertical_size);
- ret = -1;
- goto End;
- }
-
- vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR);
- vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR);
-
-#else
- progressive_sequence = 0;
- fixed_picture_qp = 0;
- img->picture_structure = 0;
- img->type = I_IMG;
- skip_mode_flag = 1;
- horizontal_size = 1920;
- vertical_size = 1080;
-
- src_start = 0;
-#endif
-
- if (horizontal_size % 16 != 0)
- img->auto_crop_right = 16 - (horizontal_size % 16);
- else
- img->auto_crop_right = 0;
-
- if (!progressive_sequence) {
- if (vertical_size % 32 != 0)
- img->auto_crop_bottom = 32 - (vertical_size % 32);
- else
- img->auto_crop_bottom = 0;
- } else {
- if (vertical_size % 16 != 0)
- img->auto_crop_bottom = 16 - (vertical_size % 16);
- else
- img->auto_crop_bottom = 0;
- }
-
- img->width = (horizontal_size + img->auto_crop_right);
- if (img->picture_structure)
- img->height = (vertical_size + img->auto_crop_bottom);
- else
- img->height = (vertical_size + img->auto_crop_bottom) / 2;
- img->width_cr = (img->width >> 1);
-
- img->pic_width_inmbs = img->width / MB_BLOCK_SIZE;
- img->pic_height_inmbs = img->height / MB_BLOCK_SIZE;
- img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs;
-
- io_printf(
- "[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n",
- src_start, des_start, horizontal_size, vertical_size);
-#if 0
- io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_START_PTR));
- io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
- io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_END_PTR));
- io_printf("VLD_MEM_VIFIFO_WP %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n",
- READ_VREG(VLD_MEM_VBUF_RD_PTR));
- io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
-#endif
- io_printf(
- "[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n",
- progressive_sequence, fixed_picture_qp, skip_mode_flag);
- io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n",
- img->picture_structure, img->type);
-
- open_irabs(p_irabs);
-
-
- if (initial_decode() == 0) {
- io_printf("initial_decode failed\n");
- ret = -1;
- goto End;
- }
-
- init_es();
-
- current_header = header();
- io_printf("[LONG CABAC] header Return : %d\n", current_header);
-
- tmp = slice_header(temp_slice_buf, first_slice_startpos,
- first_slice_length);
-
- init_contexts(img);
- aec_new_slice();
- byte_startposition = (curr_stream->frame_bitoffset) / 8;
-
- currslice = img->current_slice;
-
- if (1) {
- for (i = 0; i < 1; i++) {
- img->current_slice->part_arr[i].read_syntax_element =
- read_syntaxelement_aec;
- img->current_slice->part_arr[i].bitstream = curr_stream;
- }
- curr_stream = currslice->part_arr[0].bitstream;
- }
- if ((curr_stream->frame_bitoffset) % 8 != 0)
- byte_startposition++;
-
- arideco_start_decoding(&img->current_slice->part_arr[0].de_aec,
- curr_stream->stream_buffer, (byte_startposition),
- &(curr_stream->read_len), img->type);
-
- img->current_mb_nr = 0;
- total_mb_count = 0;
- while (img->current_mb_nr < img->pic_size_inmbs)
-
- {
- start_macroblock(img);
- if (-1 == read_one_macroblock(img)) {
- ret = -1;
- pr_info("macroblock trans failed, exit\n");
- goto End;
- }
- if (img->cod_counter <= 0)
- aec_mb_stuffing_bit = aec_startcode_follows(img, 1);
- img->current_mb_nr++;
- }
-
- push_es(0xff, 8);
- io_printf(" Total ES_LENGTH : %d\n", es_ptr);
-
-#ifdef AVSP_LONG_CABAC
- push_es(0xff, 64);
- if (es_buf_is_overflow) {
- io_printf("fatal error: es_buf_is_overflow\n");
- ret = -1;
- goto End;
- }
-
- if (transcoding_error_flag == 0) {
-#if 1
- dma_sync_single_for_device(amports_get_dma_device(),
- es_write_addr_phy,
- es_ptr, DMA_TO_DEVICE);
-
- wmb(); /**/
-#endif
- }
-#else
- fclose(f_es);
-#endif
-
-End:
-#ifdef AVSP_LONG_CABAC
- WRITE_VREG(LONG_CABAC_REQ, 0);
-#endif
- local_heap_uninit();
-#ifdef PERFORMANCE_DEBUG
- pr_info("exit %s\r\n", __func__);
-#endif
- return ret;
-}
-#endif
diff --git a/drivers/frame_provider/decoder/avs2/Makefile b/drivers/frame_provider/decoder/avs2/Makefile
index 5fe8566..04c7767 100644
--- a/drivers/frame_provider/decoder/avs2/Makefile
+++ b/drivers/frame_provider/decoder/avs2/Makefile
@@ -1,2 +1,7 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += amvdec_avs2.o
-amvdec_avs2-objs += vavs2.o avs2_bufmgr.o
+MODULE_NAME = amvdec_avs2
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs2.o avs2_bufmgr.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
index de9a3d2..143acdc 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
+++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -36,24 +36,21 @@
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/sched/clock.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
-#include "avs2_global.h"
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../utils/vdec.h"
#include "../utils/amvdec.h"
+#include "avs2_global.h"
#undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
#define assert(chk_cond) {\
if (!(chk_cond))\
@@ -83,13 +80,11 @@
for (pos = 0; pos < numCoeff; pos++) {
if (Alfp->componentID == ALF_Cb)
Alfp->coeffmulti[0][pos] =
- get_param(
- rpm_param->alf.alf_cb_coeffmulti[pos],
+ get_param(rpm_param->alf.alf_cb_coeffmulti[pos],
"Chroma ALF coefficients");
else
Alfp->coeffmulti[0][pos] =
- get_param(
- rpm_param->alf.alf_cr_coeffmulti[pos],
+ get_param(rpm_param->alf.alf_cr_coeffmulti[pos],
"Chroma ALF coefficients");
#if Check_Bitstream
if (pos <= 7)
@@ -119,8 +114,7 @@
for (f = 0; f < Alfp->filters_per_group; f++) {
if (f > 0) {
if (Alfp->filters_per_group != 16) {
- symbol =
- get_param(rpm_param->alf.region_distance
+ symbol = get_param(rpm_param->alf.region_distance
[region_distance_idx++],
"Region distance");
} else {
@@ -132,30 +126,21 @@
for (pos = 0; pos < numCoeff; pos++) {
Alfp->coeffmulti[f][pos] =
- get_param(
- rpm_param->alf.alf_y_coeffmulti[f][pos],
+ get_param(rpm_param->alf.alf_y_coeffmulti[f][pos],
"Luma ALF coefficients");
#if Check_Bitstream
if (pos <= 7)
- assert(
- Alfp->coeffmulti[f][pos]
- >= -64 &&
- Alfp->coeffmulti[f][pos]
- <= 63);
+ assert(Alfp->coeffmulti[f][pos] >= -64 &&
+ Alfp->coeffmulti[f][pos] <= 63);
if (pos == 8)
- assert(
- Alfp->coeffmulti[f][pos]
- >= -1088 &&
- Alfp->coeffmulti[f][pos]
- <= 1071);
+ assert(Alfp->coeffmulti[f][pos] >= -1088 &&
+ Alfp->coeffmulti[f][pos] <= 1071);
#endif
-
}
}
#if Check_Bitstream
assert(pre_symbole >= 0 && pre_symbole <= 15);
-
#endif
}
break;
@@ -175,16 +160,13 @@
int32_t compIdx;
if (input->alf_enable) {
img->pic_alf_on[0] =
- get_param(
- rpm_param->alf.picture_alf_enable_Y,
+ get_param(rpm_param->alf.picture_alf_enable_Y,
"alf_pic_flag_Y");
img->pic_alf_on[1] =
- get_param(
- rpm_param->alf.picture_alf_enable_Cb,
+ get_param(rpm_param->alf.picture_alf_enable_Cb,
"alf_pic_flag_Cb");
img->pic_alf_on[2] =
- get_param(
- rpm_param->alf.picture_alf_enable_Cr,
+ get_param(rpm_param->alf.picture_alf_enable_Cr,
"alf_pic_flag_Cr");
avs2_dec->m_alfPictureParam[ALF_Y].alf_flag
@@ -219,24 +201,16 @@
union param_u *rpm_param = &avs2_dec->param;
/*int32_t i, j;*/
- /*fpr_info(stdout, "Sequence Header\n");*/
- /*memcpy(currStream->streamBuffer, buf, length);*/
- /*currStream->code_len = currStream->bitstream_length = length;*/
- /*currStream->read_len = currStream->frame_bitoffset = (startcodepos +
- 1) * 8;*/
-
input->profile_id =
get_param(rpm_param->p.profile_id, "profile_id");
input->level_id =
get_param(rpm_param->p.level_id, "level_id");
hd->progressive_sequence =
- get_param(
- rpm_param->p.progressive_sequence,
+ get_param(rpm_param->p.progressive_sequence,
"progressive_sequence");
#if INTERLACE_CODING
hd->is_field_sequence =
- get_param(
- rpm_param->p.is_field_sequence,
+ get_param(rpm_param->p.is_field_sequence,
"field_coded_sequence");
#endif
#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
@@ -255,102 +229,84 @@
input->output_bit_depth =
get_param(rpm_param->p.sample_precision,
"sample_precision");
- input->output_bit_depth =
- 6 + (input->output_bit_depth) * 2;
+ input->output_bit_depth = 6 + (input->output_bit_depth) * 2;
input->sample_bit_depth =
get_param(rpm_param->p.encoding_precision,
"encoding_precision");
- input->sample_bit_depth =
- 6 + (input->sample_bit_depth) * 2;
+ input->sample_bit_depth = 6 + (input->sample_bit_depth) * 2;
} else { /* other profile*/
hd->sample_precision =
get_param(rpm_param->p.sample_precision,
- "sample_precision");
+ "sample_precision");
}
hd->aspect_ratio_information =
get_param(rpm_param->p.aspect_ratio_information,
- "aspect_ratio_information");
+ "aspect_ratio_information");
hd->frame_rate_code =
get_param(rpm_param->p.frame_rate_code, "frame_rate_code");
hd->bit_rate_lower =
get_param(rpm_param->p.bit_rate_lower, "bit_rate_lower");
- /*hd->marker_bit = get_param(rpm_param->p.marker_bit,
- * "marker bit");*/
/*CHECKMARKERBIT*/
hd->bit_rate_upper =
get_param(rpm_param->p.bit_rate_upper, "bit_rate_upper");
hd->low_delay =
get_param(rpm_param->p.low_delay, "low_delay");
- /*hd->marker_bit =
- get_param(rpm_param->p.marker_bit2,
- "marker bit");*/
+
/*CHECKMARKERBIT*/
#if M3480_TEMPORAL_SCALABLE
hd->temporal_id_exist_flag =
get_param(rpm_param->p.temporal_id_exist_flag,
- "temporal_id exist flag"); /*get
- Extention Flag*/
+ "temporal_id exist flag"); /*get
+ Extension Flag*/
#endif
/*u_v(18, "bbv buffer size");*/
input->g_uiMaxSizeInBit =
get_param(rpm_param->p.g_uiMaxSizeInBit,
"Largest Coding Block Size");
-
- /*hd->background_picture_enable = 0x01 ^
- (get_param(rpm_param->p.avs2_seq_flags,
- "background_picture_disable")
- >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1;*/
- /*rain???*/
hd->background_picture_enable = 0x01 ^
((get_param(rpm_param->p.avs2_seq_flags,
- "background_picture_disable")
- >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1);
-
+ "background_picture_disable") >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1);
hd->b_dmh_enabled = 1;
hd->b_mhpskip_enabled =
get_param(rpm_param->p.avs2_seq_flags >> B_MHPSKIP_ENABLED_BIT,
- "mhpskip enabled") & 0x1;
+ "mhpskip enabled") & 0x1;
hd->dhp_enabled =
get_param(rpm_param->p.avs2_seq_flags >> DHP_ENABLED_BIT,
- "dhp enabled") & 0x1;
+ "dhp enabled") & 0x1;
hd->wsm_enabled =
get_param(rpm_param->p.avs2_seq_flags >> WSM_ENABLED_BIT,
- "wsm enabled") & 0x1;
+ "wsm enabled") & 0x1;
img->inter_amp_enable =
get_param(rpm_param->p.avs2_seq_flags >> INTER_AMP_ENABLE_BIT,
- "Asymmetric Motion Partitions") & 0x1;
+ "Asymmetric Motion Partitions") & 0x1;
input->useNSQT =
get_param(rpm_param->p.avs2_seq_flags >> USENSQT_BIT,
- "useNSQT") & 0x1;
+ "useNSQT") & 0x1;
input->useSDIP =
get_param(rpm_param->p.avs2_seq_flags >> USESDIP_BIT,
- "useNSIP") & 0x1;
+ "useNSIP") & 0x1;
hd->b_secT_enabled =
get_param(rpm_param->p.avs2_seq_flags >> B_SECT_ENABLED_BIT,
- "secT enabled") & 0x1;
+ "secT enabled") & 0x1;
input->sao_enable =
get_param(rpm_param->p.avs2_seq_flags >> SAO_ENABLE_BIT,
- "SAO Enable Flag") & 0x1;
+ "SAO Enable Flag") & 0x1;
input->alf_enable =
get_param(rpm_param->p.avs2_seq_flags >> ALF_ENABLE_BIT,
- "ALF Enable Flag") & 0x1;
+ "ALF Enable Flag") & 0x1;
hd->b_pmvr_enabled =
get_param(rpm_param->p.avs2_seq_flags >> B_PMVR_ENABLED_BIT,
- "pmvr enabled") & 0x1;
-
+ "pmvr enabled") & 0x1;
hd->gop_size = get_param(rpm_param->p.num_of_RPS,
"num_of_RPS");
-#if Check_Bitstream
- /*assert(hd->gop_size<=32);*/
-#endif
if (hd->low_delay == 0) {
hd->picture_reorder_delay =
@@ -359,23 +315,19 @@
}
input->crossSliceLoopFilter =
- get_param(rpm_param->p.avs2_seq_flags
- >> CROSSSLICELOOPFILTER_BIT,
- "Cross Loop Filter Flag") & 0x1;
+ get_param(rpm_param->p.avs2_seq_flags >> CROSSSLICELOOPFILTER_BIT,
+ "Cross Loop Filter Flag") & 0x1;
#if BCBR
if ((input->profile_id == SCENE_PROFILE ||
input->profile_id == SCENE10_PROFILE) &&
hd->background_picture_enable) {
- hd->bcbr_enable = u_v(1,
- "block_composed_background_picture_enable");
+ hd->bcbr_enable = u_v(1, "block_composed_background_picture_enable");
u_v(1, "reserved bits");
} else {
hd->bcbr_enable = 0;
u_v(2, "reserved bits");
}
-#else
- /*u_v(2, "reserved bits");*/
#endif
img->width = hd->horizontal_size;
@@ -383,26 +335,22 @@
img->width_cr = (img->width >> 1);
if (input->chroma_format == 1) {
- img->height_cr
- = (img->height >> 1);
+ img->height_cr = (img->height >> 1);
}
img->PicWidthInMbs = img->width / MIN_CU_SIZE;
img->PicHeightInMbs = img->height / MIN_CU_SIZE;
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
img->buf_cycle = input->buf_cycle + 1;
- img->max_mb_nr = (img->width * img->height)
- / (MIN_CU_SIZE * MIN_CU_SIZE);
+ img->max_mb_nr = (img->width * img->height) / (MIN_CU_SIZE * MIN_CU_SIZE);
#ifdef AML
-avs2_dec->lcu_size =
- get_param(rpm_param->p.lcu_size, "lcu_size");
+avs2_dec->lcu_size = get_param(rpm_param->p.lcu_size, "lcu_size");
avs2_dec->lcu_size = 1<<(avs2_dec->lcu_size);
#endif
hc->seq_header++;
}
-
void Get_I_Picture_Header(struct avs2_decoder *avs2_dec)
{
struct ImageParameters_s *img = &avs2_dec->img;
@@ -416,13 +364,11 @@
#endif
hd->time_code_flag =
- get_param(rpm_param->p.time_code_flag,
- "time_code_flag");
+ get_param(rpm_param->p.time_code_flag, "time_code_flag");
if (hd->time_code_flag) {
hd->time_code =
- get_param(rpm_param->p.time_code,
- "time_code");
+ get_param(rpm_param->p.time_code, "time_code");
}
if (hd->background_picture_enable) {
hd->background_picture_flag =
@@ -430,16 +376,14 @@
"background_picture_flag");
if (hd->background_picture_flag) {
- img->typeb =
- BACKGROUND_IMG;
+ img->typeb = BACKGROUND_IMG;
} else {
img->typeb = 0;
}
if (img->typeb == BACKGROUND_IMG) {
hd->background_picture_output_flag =
- get_param(
- rpm_param->p.background_picture_output_flag,
+ get_param(rpm_param->p.background_picture_output_flag,
"background_picture_output_flag");
}
}
@@ -447,10 +391,7 @@
{
img->coding_order =
- get_param(rpm_param->p.coding_order,
- "coding_order");
-
-
+ get_param(rpm_param->p.coding_order, "coding_order");
#if M3480_TEMPORAL_SCALABLE
if (hd->temporal_id_exist_flag == 1) {
@@ -478,19 +419,12 @@
int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
int32_t predict;
int32_t j;
- predict =
- get_param(rpm_param->p.predict,
- "use RCS in SPS");
- /*if (predict) {*/
- RPS_idx =
- get_param(rpm_param->p.RPS_idx,
+ predict = get_param(rpm_param->p.predict, "use RCS in SPS");
+ RPS_idx = get_param(rpm_param->p.RPS_idx,
"predict for RCS");
- /* hd->curr_RPS = hd->decod_RPS[RPS_idx];*/
- /*} else {*/
/*gop size16*/
- hd->curr_RPS.referd_by_others =
- get_param(rpm_param->p.referd_by_others_cur,
- "refered by others");
+ hd->curr_RPS.referred_by_others =
+ get_param(rpm_param->p.referred_by_others_cur, "referred by others");
hd->curr_RPS.num_of_ref =
get_param(rpm_param->p.num_of_ref_cur,
"num of reference picture");
@@ -516,51 +450,34 @@
rpm_param->p.remove_pic_cur[j],
"delta COI of removed pic");
}
- /*u_v(1, "marker bit");*/
-
- /*}*/
}
/*xyji 12.23*/
- if (hd->low_delay) {
- /*ue_v(
- "bbv check times");*/
- }
- hd->progressive_frame =
- get_param(rpm_param->p.progressive_frame,
+ hd->progressive_frame = get_param(rpm_param->p.progressive_frame,
"progressive_frame");
if (!hd->progressive_frame) {
- img->picture_structure =
- get_param(rpm_param->p.picture_structure,
+ img->picture_structure = get_param(rpm_param->p.picture_structure,
"picture_structure");
} else {
- img->picture_structure
- = 1;
+ img->picture_structure = 1;
}
- hd->top_field_first =
- get_param(rpm_param->p.top_field_first,
+ hd->top_field_first = get_param(rpm_param->p.top_field_first,
"top_field_first");
- hd->repeat_first_field =
- get_param(rpm_param->p.repeat_first_field,
+ hd->repeat_first_field = get_param(rpm_param->p.repeat_first_field,
"repeat_first_field");
#if INTERLACE_CODING
if (hd->is_field_sequence) {
- hd->is_top_field =
- get_param(rpm_param->p.is_top_field,
+ hd->is_top_field = get_param(rpm_param->p.is_top_field,
"is_top_field");
#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
img->is_top_field = hd->is_top_field;
#endif
}
#endif
-
-
img->qp = hd->picture_qp;
-
img->type = I_IMG;
-
}
/*
@@ -577,9 +494,6 @@
struct Video_Dec_data_s *hd = &avs2_dec->hd;
union param_u *rpm_param = &avs2_dec->param;
-
- /*u_v(32, "bbv delay");*/
-
hd->picture_coding_type =
get_param(rpm_param->p.picture_coding_type,
"picture_coding_type");
@@ -589,8 +503,7 @@
hd->picture_coding_type == 3)) {
if (hd->picture_coding_type == 1) {
hd->background_pred_flag =
- get_param(
- rpm_param->p.background_pred_flag,
+ get_param(rpm_param->p.background_pred_flag,
"background_pred_flag");
} else {
hd->background_pred_flag = 0;
@@ -598,11 +511,8 @@
if (hd->background_pred_flag == 0) {
hd->background_reference_enable =
- get_param(
- rpm_param->
- p.background_reference_enable,
+ get_param(rpm_param->p.background_reference_enable,
"background_reference_enable");
-
} else {
#if RD170_FIX_BG
hd->background_reference_enable = 1;
@@ -616,20 +526,14 @@
hd->background_reference_enable = 0;
}
-
-
if (hd->picture_coding_type == 1) {
- img->type =
- P_IMG;
+ img->type = P_IMG;
} else if (hd->picture_coding_type == 3) {
- img->type =
- F_IMG;
+ img->type = F_IMG;
} else {
- img->type =
- B_IMG;
+ img->type = B_IMG;
}
-
if (hd->picture_coding_type == 1 &&
hd->background_pred_flag) {
img->typeb = BP_IMG;
@@ -637,60 +541,45 @@
img->typeb = 0;
}
-
{
img->coding_order =
- get_param(
- rpm_param->p.coding_order,
- "coding_order");
-
+ get_param(rpm_param->p.coding_order, "coding_order");
#if M3480_TEMPORAL_SCALABLE
if (hd->temporal_id_exist_flag == 1) {
- hd->cur_layer =
- get_param(rpm_param->p.cur_layer,
- "temporal_id");
+ hd->cur_layer = get_param(rpm_param->p.cur_layer, "temporal_id");
}
#endif
if (hd->low_delay == 0) {
hd->displaydelay =
- get_param(rpm_param->p.displaydelay,
- "displaydelay");
+ get_param(rpm_param->p.displaydelay, "displaydelay");
}
}
{
int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
int32_t predict;
- predict =
- get_param(rpm_param->p.predict,
- "use RPS in SPS");
+ predict = get_param(rpm_param->p.predict, "use RPS in SPS");
if (predict) {
- RPS_idx =
- get_param(rpm_param->p.RPS_idx,
- "predict for RPS");
+ RPS_idx = get_param(rpm_param->p.RPS_idx, "predict for RPS");
hd->curr_RPS = hd->decod_RPS[RPS_idx];
} /*else*/
{
/*gop size16*/
int32_t j;
- hd->curr_RPS.referd_by_others =
- get_param(
- rpm_param->p.referd_by_others_cur,
- "refered by others");
+ hd->curr_RPS.referred_by_others =
+ get_param(rpm_param->p.referred_by_others_cur,
+ "referred by others");
hd->curr_RPS.num_of_ref =
- get_param(
- rpm_param->p.num_of_ref_cur,
+ get_param(rpm_param->p.num_of_ref_cur,
"num of reference picture");
for (j = 0; j < hd->curr_RPS.num_of_ref; j++) {
hd->curr_RPS.ref_pic[j] =
- get_param(
- rpm_param->p.ref_pic_cur[j],
+ get_param(rpm_param->p.ref_pic_cur[j],
"delta COI of ref pic");
}
hd->curr_RPS.num_to_remove =
- get_param(
- rpm_param->p.num_to_remove_cur,
+ get_param(rpm_param->p.num_to_remove_cur,
"num of removed picture");
#ifdef SANITY_CHECK
if (hd->curr_RPS.num_to_remove > MAXREF) {
@@ -706,75 +595,52 @@
rpm_param->p.remove_pic_cur[j],
"delta COI of removed pic");
}
- /*u_v(1, "marker bit");*/
-
}
}
- /*xyji 12.23*/
- if (hd->low_delay) {
- /*ue_v(
- "bbv check times");*/
- }
hd->progressive_frame =
- get_param(rpm_param->p.progressive_frame,
+ get_param(rpm_param->p.progressive_frame,
"progressive_frame");
if (!hd->progressive_frame) {
img->picture_structure =
- get_param(rpm_param->p.picture_structure,
+ get_param(rpm_param->p.picture_structure,
"picture_structure");
} else {
img->picture_structure = 1;
}
hd->top_field_first =
- get_param(rpm_param->p.top_field_first,
+ get_param(rpm_param->p.top_field_first,
"top_field_first");
hd->repeat_first_field =
- get_param(rpm_param->p.repeat_first_field,
+ get_param(rpm_param->p.repeat_first_field,
"repeat_first_field");
#if INTERLACE_CODING
if (hd->is_field_sequence) {
hd->is_top_field =
- get_param(rpm_param->p.is_top_field,
+ get_param(rpm_param->p.is_top_field,
"is_top_field");
#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
img->is_top_field = hd->is_top_field;
#endif
- /*u_v(1, "reserved bit for interlace coding");*/
}
#endif
-#if Check_Bitstream
- /*assert(hd->picture_qp>=0&&hd->picture_qp<=(63 + 8 *
- (input->sample_bit_depth - 8)));*/
-#endif
-
img->random_access_decodable_flag =
- get_param(rpm_param->p.random_access_decodable_flag,
+ get_param(rpm_param->p.random_access_decodable_flag,
"random_access_decodable_flag");
img->qp = hd->picture_qp;
}
-
-
-
void calc_picture_distance(struct avs2_decoder *avs2_dec)
{
struct ImageParameters_s *img = &avs2_dec->img;
struct Video_Com_data_s *hc = &avs2_dec->hc;
struct Video_Dec_data_s *hd = &avs2_dec->hd;
- /*
- union param_u *rpm_param = &avs2_dec->param;
- for POC mode 0:
- uint32_t MaxPicDistanceLsb = (1 << 8);
- */
- if (img->coding_order < img->PrevPicDistanceLsb)
-
- {
+ if (img->coding_order < img->PrevPicDistanceLsb) {
int32_t i, j;
hc->total_frames++;
@@ -810,8 +676,7 @@
img->tr = img->coding_order +
hd->displaydelay - hd->picture_reorder_delay;
} else {
- img->tr =
- img->coding_order;
+ img->tr = img->coding_order;
}
#if REMOVE_UNUSED
@@ -820,7 +685,6 @@
img->pic_distance = img->tr % 256;
#endif
hc->picture_distance = img->pic_distance;
-
}
int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec)
@@ -832,9 +696,7 @@
int32_t refnum;
int32_t memory_size = 0;
- /*
-int32_t img_height = (hd->vertical_size + img->auto_crop_bottom);
- */
+
img->buf_cycle = input->buf_cycle + 1;
img->buf_cycle *= 2;
@@ -844,15 +706,13 @@
for (refnum = 0; refnum < REF_MAXBUFFER; refnum++) {
avs2_dec->fref[refnum] = &avs2_dec->frm_pool[refnum];
- /*//avs2_dec->fref[i] memory allocation*/
if (is_avs2_print_bufmgr_detail())
pr_info("[t] avs2_dec->fref[%d]@0x%p\n",
refnum, avs2_dec->fref[refnum]);
avs2_dec->fref[refnum]->imgcoi_ref = -257;
avs2_dec->fref[refnum]->is_output = -1;
- avs2_dec->fref[refnum]->refered_by_others = -1;
- avs2_dec->fref[refnum]->
- imgtr_fwRefDistance = -256;
+ avs2_dec->fref[refnum]->referred_by_others = -1;
+ avs2_dec->fref[refnum]->imgtr_fwRefDistance = -256;
init_frame_t(avs2_dec->fref[refnum]);
#ifdef AML
avs2_dec->fref[refnum]->index = refnum;
@@ -862,13 +722,13 @@
avs2_dec->f_bg = NULL;
avs2_dec->m_bg = &avs2_dec->frm_pool[REF_MAXBUFFER];
- /*///avs2_dec->fref[i] memory allocation*/
+
if (is_avs2_print_bufmgr_detail())
pr_info("[t] avs2_dec->m_bg@0x%p\n",
avs2_dec->m_bg);
avs2_dec->m_bg->imgcoi_ref = -257;
avs2_dec->m_bg->is_output = -1;
- avs2_dec->m_bg->refered_by_others = -1;
+ avs2_dec->m_bg->referred_by_others = -1;
avs2_dec->m_bg->imgtr_fwRefDistance = -256;
init_frame_t(avs2_dec->m_bg);
avs2_dec->m_bg->index = refnum;
@@ -880,9 +740,6 @@
((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
* ((img->height + MAX_CU_SIZE - 1)
/ MAX_CU_SIZE);
- /*img->BLCUidx = (int32_t*) calloc(
- img->iNumCUsInFrame, sizeof(int32_t));*/
- /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/
#endif
return memory_size;
}
@@ -910,12 +767,11 @@
#endif
if (is_avs2_print_bufmgr_detail())
pr_info("%s[t] avs2_dec->fref[%d]@0x%p\n",
- __func__, refnum, avs2_dec->fref[refnum]);
+ __func__, refnum, avs2_dec->fref[refnum]);
avs2_dec->fref[refnum]->imgcoi_ref = -257;
avs2_dec->fref[refnum]->is_output = -1;
- avs2_dec->fref[refnum]->refered_by_others = -1;
- avs2_dec->fref[refnum]->
- imgtr_fwRefDistance = -256;
+ avs2_dec->fref[refnum]->referred_by_others = -1;
+ avs2_dec->fref[refnum]->imgtr_fwRefDistance = -256;
memset(avs2_dec->fref[refnum]->ref_poc, 0,
sizeof(avs2_dec->fref[refnum]->ref_poc));
}
@@ -923,10 +779,10 @@
if (is_avs2_print_bufmgr_detail())
pr_info("%s[t] avs2_dec->m_bg@0x%p\n",
- __func__, avs2_dec->m_bg);
+ __func__, avs2_dec->m_bg);
avs2_dec->m_bg->imgcoi_ref = -257;
avs2_dec->m_bg->is_output = -1;
- avs2_dec->m_bg->refered_by_others = -1;
+ avs2_dec->m_bg->referred_by_others = -1;
avs2_dec->m_bg->imgtr_fwRefDistance = -256;
memset(avs2_dec->m_bg->ref_poc, 0,
sizeof(avs2_dec->m_bg->ref_poc));
@@ -937,9 +793,6 @@
((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
* ((img->height + MAX_CU_SIZE - 1)
/ MAX_CU_SIZE);
- /*img->BLCUidx = (int32_t*) calloc(
- img->iNumCUsInFrame, sizeof(int32_t));*/
- /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/
#endif
}
#endif
@@ -949,7 +802,7 @@
memset(currfref, 0, sizeof(struct avs2_frame_s));
currfref->imgcoi_ref = -257;
currfref->is_output = -1;
- currfref->refered_by_others = -1;
+ currfref->referred_by_others = -1;
currfref->imgtr_fwRefDistance = -256;
memset(currfref->ref_poc, 0, sizeof(currfref->ref_poc));
}
@@ -961,8 +814,6 @@
int8_t str_tmp[16];
int32_t i;
- /* int32_t poc = hc->f_rec->imgtr_fwRefDistance;
- fred.chiu@mediatek.com*/
if (img->num_of_references > 0) {
strcpy(str, "[");
@@ -970,9 +821,7 @@
#if RD1510_FIX_BG
if (img->type == B_IMG) {
sprintf(str_tmp, "%4d ",
- hc->f_rec->
- ref_poc[
- img->num_of_references - 1 - i]);
+ hc->f_rec->ref_poc[img->num_of_references - 1 - i]);
} else {
sprintf(str_tmp, "%4d ",
hc->f_rec->ref_poc[i]);
@@ -981,7 +830,6 @@
sprintf(str_tmp, "%4d ",
avs2_dec->fref[i]->imgtr_fwRefDistance);
#endif
-
str_tmp[5] = '\0';
strcat(str, str_tmp);
}
@@ -991,7 +839,7 @@
}
}
-void prepare_RefInfo(struct avs2_decoder *avs2_dec)
+int prepare_RefInfo(struct avs2_decoder *avs2_dec)
{
struct ImageParameters_s *img = &avs2_dec->img;
struct Video_Com_data_s *hc = &avs2_dec->hc;
@@ -999,7 +847,9 @@
int32_t i, j;
int32_t ii;
+ int32_t tmp_ref;
struct avs2_frame_s *tmp_fref;
+ int32_t error_mark = 0;
/*update IDR frame*/
if (img->tr > hd->next_IDRtr && hd->curr_IDRtr != hd->next_IDRtr) {
@@ -1009,7 +859,6 @@
/* re-order the ref buffer according to RPS*/
img->num_of_references = hd->curr_RPS.num_of_ref;
-#if 1
/*rain*/
if (is_avs2_print_bufmgr_detail()) {
pr_info("%s: coding_order is %d, curr_IDRcoi is %d\n",
@@ -1026,7 +875,6 @@
avs2_dec->fref[ii]->imgtr_fwRefDistance);
}
}
-#endif
for (i = 0; i < hd->curr_RPS.num_of_ref; i++) {
/*int32_t accumulate = 0;*/
@@ -1036,8 +884,7 @@
#if REMOVE_UNUSED
for (j = i; j < avs2_dec->ref_maxbuffer; j++) {
/*/////////////to be modified IDR*/
- if (avs2_dec->fref[j]->imgcoi_ref ==
- img->coding_order -
+ if (avs2_dec->fref[j]->imgcoi_ref == img->coding_order -
hd->curr_RPS.ref_pic[i]) {
break;
}
@@ -1056,15 +903,12 @@
}
}
if (k == avs2_dec->ref_maxbuffer) {
- tmp_tr =
- -1-1;
+ tmp_tr = -1-1;
} else {
- tmp_tr =
- avs2_dec->fref[k]->imgtr_fwRefDistance;
+ tmp_tr = avs2_dec->fref[k]->imgtr_fwRefDistance;
}
if (tmp_tr < hd->curr_IDRtr) {
- hd->curr_RPS.ref_pic[i] =
- img->coding_order - hd->curr_IDRcoi;
+ hd->curr_RPS.ref_pic[i] = img->coding_order - hd->curr_IDRcoi;
for (k = 0; k < i; k++) {
if (hd->curr_RPS.ref_pic[k] ==
@@ -1089,28 +933,46 @@
avs2_dec->fref[j] = tmp_fref;
if (is_avs2_print_bufmgr_detail()) {
pr_info("%s, switch %d %d: ", __func__, i, j);
- for (ii = 0; ii < hd->curr_RPS.num_of_ref
- || ii <= j; ii++)
- pr_info("%d ",
- avs2_dec->fref[ii]->index);
+ for (ii = 0; ii < hd->curr_RPS.num_of_ref || ii <= j; ii++)
+ pr_info("%d ",avs2_dec->fref[ii]->index);
pr_info("\n");
}
}
}
- if (img->type == B_IMG &&
+ if ((img->type == B_IMG &&
(avs2_dec->fref[0]->imgtr_fwRefDistance <= img->tr
- || avs2_dec->fref[1]->imgtr_fwRefDistance >= img->tr)) {
-
- pr_info("wrong reference configuration for B frame\n");
- pr_info(
- "fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, img->tr %d\n",
+ || avs2_dec->fref[1]->imgtr_fwRefDistance >= img->tr
+ || avs2_dec->fref[1]->imgtr_fwRefDistance == -256))) {
+ if (get_error_policy(avs2_dec) & 0x2) {
+ pr_info("wrong reference configuration for B frame\n");
+ pr_info("fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, img->tr %d\n",
avs2_dec->fref[0]->imgtr_fwRefDistance,
avs2_dec->fref[1]->imgtr_fwRefDistance,
img->tr);
- hc->f_rec->error_mark = 1;
- avs2_dec->bufmgr_error_flag = 1;
- return; /* exit(-1);*/
- /*******************************************/
+ if (avs2_dec->fref[1]->imgtr_fwRefDistance != -256) {
+ avs2_dec->bufmgr_error_flag = 1;
+ }
+ return -1;
+ } else {
+ error_mark = 1;
+ }
+ }
+ if (img->type == P_IMG) {
+ for (ii = 0; ii < img->num_of_references;ii++) {
+ tmp_ref = img->coding_order - hd->curr_RPS.ref_pic[ii];
+ if ((avs2_dec->fref[ii]->imgcoi_ref != tmp_ref) &&
+ (avs2_dec->fref[ii]->imgcoi_ref != (tmp_ref - 256))) {
+ if (get_error_policy(avs2_dec) & 0x2) {
+ pr_info("wrong reference configuration for P frame\n");
+ pr_info("fref[%d] imgcoi_ref %d, ref_pic[%d] %d\n",
+ ii,avs2_dec->fref[ii]->imgcoi_ref,
+ ii,hd->curr_RPS.ref_pic[ii]);
+ return -1;
+ } else {
+ error_mark = 1;
+ }
+ }
+ }
}
#if !FIX_PROFILE_LEVEL_DPB_RPS_1
@@ -1131,8 +993,7 @@
avs2_dec->fref[j]->temporal_id = -1;
#endif
if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->
- imgtr_fwRefDistance = -256;
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
}
}
}
@@ -1143,23 +1004,19 @@
/* add current frame to ref buffer*/
for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
if ((avs2_dec->fref[i]->imgcoi_ref < -256
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128)
+ || abs(avs2_dec->fref[i]->imgtr_fwRefDistance - img->tr) >= 128)
&& avs2_dec->fref[i]->is_output == -1
&& avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
&& avs2_dec->fref[i]->vf_ref == 0
&& avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
) {
break;
}
}
+
if (i == avs2_dec->ref_maxbuffer) {
- pr_info(
- "%s, warning, no enough buf\n",
- __func__);
- i--;
+ pr_info("%s, warning, no enough buf\n", __func__);
+ return -2;
}
hc->f_rec = avs2_dec->fref[i];
@@ -1171,28 +1028,24 @@
#endif
hc->f_rec->is_output = 1;
#ifdef AML
- hc->f_rec->error_mark = 0;
+ hc->f_rec->error_mark = error_mark;
hc->f_rec->decoded_lcu = 0;
hc->f_rec->slice_type = img->type;
+ hc->f_rec->time = div64_u64(local_clock(), 1000) - avs2_dec->start_time;
#endif
- hc->f_rec->refered_by_others = hd->curr_RPS.referd_by_others;
+ hc->f_rec->referred_by_others = hd->curr_RPS.referred_by_others;
if (is_avs2_print_bufmgr_detail())
- pr_info(
- "%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d img_type %d\n",
- __func__, i, img->tr, img->coding_order,
- img->type);
+ pr_info("%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d img_type %d\n",
+ __func__, i, img->tr, img->coding_order, img->type);
if (img->type != B_IMG) {
for (j = 0;
j < img->num_of_references; j++) {
- hc->f_rec->ref_poc[j] =
- avs2_dec->fref[j]->imgtr_fwRefDistance;
+ hc->f_rec->ref_poc[j] = avs2_dec->fref[j]->imgtr_fwRefDistance;
}
} else {
- hc->f_rec->ref_poc[0] =
- avs2_dec->fref[1]->imgtr_fwRefDistance;
- hc->f_rec->ref_poc[1] =
- avs2_dec->fref[0]->imgtr_fwRefDistance;
+ hc->f_rec->ref_poc[0] = avs2_dec->fref[1]->imgtr_fwRefDistance;
+ hc->f_rec->ref_poc[1] = avs2_dec->fref[0]->imgtr_fwRefDistance;
}
#if M3480_TEMPORAL_SCALABLE
@@ -1206,8 +1059,7 @@
if (img->type == INTRA_IMG) {
int32_t l;
for (l = 0; l < 4; l++) {
- hc->f_rec->ref_poc[l]
- = img->tr;
+ hc->f_rec->ref_poc[l] = img->tr;
}
}
@@ -1223,19 +1075,19 @@
if (img->type == B_IMG) {
hd->trtmp = avs2_dec->fref[0]->imgtr_fwRefDistance;
avs2_dec->fref[0]->imgtr_fwRefDistance =
- avs2_dec->fref[1]->imgtr_fwRefDistance;
+ avs2_dec->fref[1]->imgtr_fwRefDistance;
}
}
-#if 1
+
/*rain*/
if (is_avs2_print_bufmgr_detail()) {
for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
pr_info(
- "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, is_out %d, bg %d, vf_ref %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
+ "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d referred %d, is_out %d, bg %d, vf_ref %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
ii, avs2_dec->fref[ii]->index,
avs2_dec->fref[ii]->imgcoi_ref,
avs2_dec->fref[ii]->imgtr_fwRefDistance,
- avs2_dec->fref[ii]->refered_by_others,
+ avs2_dec->fref[ii]->referred_by_others,
avs2_dec->fref[ii]->is_output,
avs2_dec->fref[ii]->bg_flag,
avs2_dec->fref[ii]->vf_ref,
@@ -1245,11 +1097,10 @@
avs2_dec->fref[ii]->ref_poc[3],
avs2_dec->fref[ii]->ref_poc[4],
avs2_dec->fref[ii]->ref_poc[5],
- avs2_dec->fref[ii]->ref_poc[6]
- );
+ avs2_dec->fref[ii]->ref_poc[6]);
+ }
}
- }
-#endif
+ return 0;
}
int32_t init_frame(struct avs2_decoder *avs2_dec)
@@ -1276,18 +1127,17 @@
hc->cur_pic = avs2_dec->m_bg;
#endif
} else {
- prepare_RefInfo(avs2_dec);
+ if (prepare_RefInfo(avs2_dec) < 0)
+ return -1;
#ifdef AML
hc->cur_pic = hc->f_rec;
#endif
}
-
#ifdef FIX_CHROMA_FIELD_MV_BK_DIST
if (img->typeb == BACKGROUND_IMG
&& img->is_field_sequence) {
- avs2_dec->bk_img_is_top_field
- = img->is_top_field;
+ avs2_dec->bk_img_is_top_field = img->is_top_field;
}
#endif
return 0;
@@ -1296,10 +1146,8 @@
void delete_trbuffer(struct outdata_s *data, int32_t pos)
{
int32_t i;
- for (i = pos;
- i < data->buffer_num - 1; i++) {
- data->stdoutdata[i] =
- data->stdoutdata[i + 1];
+ for (i = pos; i < data->buffer_num - 1; i++) {
+ data->stdoutdata[i] = data->stdoutdata[i + 1];
}
data->buffer_num--;
}
@@ -1331,9 +1179,8 @@
report_frame(avs2_dec, &avs2_dec->outprint, pos);
if (avs2_dec->outprint.stdoutdata[pos].typeb
== BACKGROUND_IMG &&
- avs2_dec->outprint.stdoutdata[pos].
- background_picture_output_flag
- == 0) {
+ avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag
+ == 0) {
/*write_GB_frame(hd->p_out_background);*/
} else {
write_frame(avs2_dec,
@@ -1349,36 +1196,11 @@
avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
avs2_dec->fref[j]->imgcoi_ref = -257;
avs2_dec->fref[j]->temporal_id = -1;
- avs2_dec->fref[j]->refered_by_others = 0;
+ avs2_dec->fref[j]->referred_by_others = 0;
}
}
#endif
-
-
-#if M3480_TEMPORAL_SCALABLE
-void cleanRefMVBufRef(int pos)
-{
-#if 0
- int k, x, y;
- /*re-init mvbuf*/
- for (k = 0; k < 2; k++) {
- for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) {
- for (x = 0; x < img->width / MIN_BLOCK_SIZE; x++)
- fref[pos]->mvbuf[y][x][k] = 0;
-
- }
- }
- /*re-init refbuf*/
- for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) {
- for (x = 0; x < img->width / MIN_BLOCK_SIZE ; x++)
- fref[pos]->refbuf[y][x] = -1;
-
- }
-#endif
-}
-#endif
-
static int frame_postprocessing(struct avs2_decoder *avs2_dec)
{
struct ImageParameters_s *img = &avs2_dec->img;
@@ -1402,22 +1224,14 @@
p_outdata->typeb = img->typeb;
p_outdata->framenum = img->tr;
p_outdata->tr = img->tr;
-#if 0 /*def ORI*/
- p_outdata->qp = img->qp;
-#else
+
p_outdata->qp = 0;
-#endif
- /*p_outdata->snr_y = snr->snr_y;*/
- /*p_outdata->snr_u = snr->snr_u;*/
- /*p_outdata->snr_v = snr->snr_v;*/
+
p_outdata->tmp_time = hd->tmp_time;
p_outdata->picture_structure = img->picture_structure;
- /*p_outdata->curr_frame_bits =
- StatBitsPtr->curr_frame_bits;*/
- /*p_outdata->emulate_bits = StatBitsPtr->emulate_bits;*/
+
#if RD1501_FIX_BG
- p_outdata->background_picture_output_flag
- = hd->background_picture_output_flag;
+ p_outdata->background_picture_output_flag = hd->background_picture_output_flag;
/*Longfei.Wang@mediatek.com*/
#endif
@@ -1441,10 +1255,6 @@
== (hd->last_output + 1)) {
hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
report_frame(avs2_dec, &avs2_dec->outprint, pos);
-#if 0 /*def ORI*/
- write_frame(hd->p_out,
- avs2_dec->outprint.stdoutdata[pos].tr);
-#endif
delete_trbuffer(&avs2_dec->outprint, pos);
i--;
} else {
@@ -1464,8 +1274,7 @@
for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
if ((avs2_dec->outprint.stdoutdata[i].tr < tmp_min) &&
((avs2_dec->outprint.stdoutdata[i].tr
- + avs2_dec->outprint.stdoutdata[i].
- picture_reorder_delay)
+ + avs2_dec->outprint.stdoutdata[i].picture_reorder_delay)
<= (int32_t)img->coding_order)) {
pos = i;
tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
@@ -1483,18 +1292,12 @@
if (pos != -1) {
hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
report_frame(avs2_dec, &avs2_dec->outprint, pos);
-#if 1 /*def ORI*/
if (avs2_dec->outprint.stdoutdata[pos].typeb
== BACKGROUND_IMG &&
- avs2_dec->outprint.stdoutdata[pos].
- background_picture_output_flag == 0) {
- /**/
- /**/
+ avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag == 0) {
} else {
- write_frame(avs2_dec,
- avs2_dec->outprint.stdoutdata[pos].tr);
+ write_frame(avs2_dec, avs2_dec->outprint.stdoutdata[pos].tr);
}
-#endif
delete_trbuffer(&avs2_dec->outprint, pos);
}
@@ -1508,16 +1311,14 @@
int32_t tmp_min, pos = -1;
tmp_min = 1 << 20;
- for (i = 0; i <
- avs2_dec->outprint.buffer_num; i++) {
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
if (avs2_dec->outprint.stdoutdata[i].tr
< tmp_min &&
avs2_dec->outprint.stdoutdata[i].tr
>= hd->last_output) {
/*GB has the same "tr" with "last_output"*/
pos = i;
- tmp_min =
- avs2_dec->outprint.stdoutdata[i].tr;
+ tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
}
}
@@ -1532,24 +1333,20 @@
#else
if (avs2_dec->outprint.stdoutdata[pos].typeb
== BACKGROUND_IMG &&
- hd->background_picture_output_flag
- == 0) {
+ hd->background_picture_output_flag == 0) {
#endif
- write_GB_frame(
- hd->p_out_background);
+ write_GB_frame(hd->p_out_background);
} else {
write_frame(avs2_dec,
avs2_dec->outprint.stdoutdata[pos].tr);
}
delete_trbuffer(&avs2_dec->outprint, pos);
-
}
}
#endif
#endif
return pos;
-
}
void write_frame(struct avs2_decoder *avs2_dec, int32_t pos)
@@ -1565,18 +1362,15 @@
avs2_dec->fref[j]->is_output = -1;
avs2_dec->fref[j]->to_prepare_disp =
avs2_dec->to_prepare_disp_count++;
- if (avs2_dec->fref[j]->refered_by_others == 0
- || avs2_dec->fref[j]->imgcoi_ref
- == -257) {
- avs2_dec->fref[j]->imgtr_fwRefDistance
- = -256;
+ if (avs2_dec->fref[j]->referred_by_others == 0
+ || avs2_dec->fref[j]->imgcoi_ref == -257) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
avs2_dec->fref[j]->imgcoi_ref = -257;
#if M3480_TEMPORAL_SCALABLE
avs2_dec->fref[j]->temporal_id = -1;
#endif
if (is_avs2_print_bufmgr_detail())
- pr_info("%s, fref index %d\n",
- __func__, j);
+ pr_info("%s, fref index %d\n", __func__, j);
}
break;
}
@@ -1594,25 +1388,10 @@
int8_t *Frmfld;
int8_t Frm[] = "FRM";
int8_t Fld[] = "FLD";
- struct STDOUT_DATA_s *p_stdoutdata
- = &data->stdoutdata[pos];
+ struct STDOUT_DATA_s *p_stdoutdata = &data->stdoutdata[pos];
const int8_t *typ;
-#if 0
- if (input->MD5Enable & 0x02) {
- sprintf(MD5str, "%08X%08X%08X%08X\0",
- p_stdoutdata->DecMD5Value[0],
- p_stdoutdata->DecMD5Value[1],
- p_stdoutdata->DecMD5Value[2],
- p_stdoutdata->DecMD5Value[3]);
- } else {
- memset(MD5val, 0, 16);
- memset(MD5str, 0, 33);
- }
-#endif
-
- if (p_stdoutdata->
- picture_structure) {
+ if (p_stdoutdata->picture_structure) {
Frmfld = Frm;
} else {
Frmfld = Fld;
@@ -1624,11 +1403,8 @@
#endif
if ((p_stdoutdata->tr + hc->total_frames * 256)
== hd->end_SeqTr) { /* I picture*/
- /*if ( img->new_sequence_flag == 1 )*/
{
img->sequence_end_flag = 0;
- /*fprintf(stdout, "Sequence
- End\n\n");*/
}
}
if ((p_stdoutdata->tr + hc->total_frames * 256)
@@ -1638,8 +1414,6 @@
#endif
{
hd->vec_flag = 0;
- /*fprintf(stdout, "Video Edit
- Code\n");*/
}
}
@@ -1659,22 +1433,9 @@
#endif
}
-#if 0
- /*rain???*/
- pr_info("%3d(%s) %3d %5d %7.4f %7.4f %7.4f %5d\t\t%s %8d %6d\t%s",
- p_stdoutdata->framenum + hc->total_frames * 256,
- typ, p_stdoutdata->tr + hc->total_frames * 256,
- p_stdoutdata->qp, p_stdoutdata->snr_y,
- p_stdoutdata->snr_u, p_stdoutdata->snr_v,
- p_stdoutdata->tmp_time, Frmfld,
- p_stdoutdata->curr_frame_bits,
- p_stdoutdata->emulate_bits,
- "");
-#endif
if (is_avs2_print_bufmgr_detail())
pr_info(" %s\n", p_stdoutdata->str_reference_list);
- /*fflush(stdout);*/
hd->FrameNum++;
}
@@ -1698,11 +1459,6 @@
if ((seq_checker_length != length) ||
(memcmp(seq_checker_buf, Buf, length) != 0)) {
free(seq_checker_buf);
- /*fprintf(stdout,
- "Non-conformance
- stream: sequence
- header cannot change
- !!\n");*/
#if RD170_FIX_BG
seq_checker_buf = NULL;
seq_checker_length = 0;
@@ -1711,13 +1467,10 @@
memcpy(seq_checker_buf, Buf, length);
#endif
}
-
-
}
#endif
#if RD170_FIX_BG
- if (input->alf_enable
- && alfParAllcoated == 1) {
+ if (input->alf_enable && alfParAllcoated == 1) {
ReleaseAlfGlobalBuffer();
alfParAllcoated = 0;
}
@@ -1726,13 +1479,10 @@
#endif
#if FIX_FLUSH_DPB_BY_LF
if (hd->vec_flag) {
- int32_t k;
if (is_avs2_print_bufmgr_detail())
pr_info("vec_flag is 1, flushDPB and reinit bugmgr\n");
flushDPB(avs2_dec);
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
hd->vec_flag = 0;
#ifdef AML
@@ -1749,13 +1499,9 @@
#if FIX_SEQ_END_FLUSH_DPB_BY_LF
if (img->new_sequence_flag
&& img->sequence_end_flag) {
- int32_t k;
if (is_avs2_print_bufmgr_detail())
- pr_info(
- "new_sequence_flag after sequence_end_flag, flushDPB and reinit bugmgr\n");
+ pr_info("new_sequence_flag after sequence_end_flag, flushDPB and reinit bugmgr\n");
flushDPB(avs2_dec);
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
#ifdef AML
free_unused_buffers(avs2_dec);
@@ -1778,9 +1524,6 @@
Read_ALF_param(avs2_dec);
if (!img->seq_header_indicate) {
img->B_discard_flag = 1;
- /*fprintf(stdout, " I
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
break;
}
break;
@@ -1794,22 +1537,6 @@
/* xiaozhen zheng, 20071009*/
if (!img->seq_header_indicate) {
img->B_discard_flag = 1;
-
- if (img->type == P_IMG) {
- /*fprintf(stdout, " P
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- }
- if (img->type == F_IMG) {
- /*fprintf(stdout, " F
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- } else {
- /*fprintf(stdout, " B
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- }
-
break;
}
@@ -1819,9 +1546,6 @@
}
if (img->type == B_IMG && img->B_discard_flag == 1
&& !img->random_access_decodable_flag) {
- /*fprintf(stdout, " B
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
break;
}
@@ -1844,7 +1568,6 @@
case VIDEO_EDIT_CODE:
if (is_avs2_print_bufmgr_detail())
pr_info("VIDEO_EDIT_CODE\n");
- /*video_edit_code_data(Buf, startcodepos, length);*/
hd->vec_flag = 1;
#ifdef TO_CHECK
#if SEQ_CHANGE_CHECKER
@@ -1881,7 +1604,6 @@
int32_t lcu_y_num_div;
int32_t N8_SizeScale;
- /*pr_info("%s\n", __func__);*/
{
N8_SizeScale = 1;
@@ -1922,20 +1644,10 @@
img->PicWidthInMbs = img->width / MIN_CU_SIZE;
img->PicHeightInMbs = img->height / MIN_CU_SIZE;
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
- img->max_mb_nr = (img->width * img->height) /
- (MIN_CU_SIZE * MIN_CU_SIZE);
+ img->max_mb_nr = (img->width * img->height) / (MIN_CU_SIZE * MIN_CU_SIZE);
}
if (img->new_sequence_flag && img->sequence_end_flag) {
-#if 0/*RD170_FIX_BG //*/
- int32_t k;
- flushDPB();
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
-
- free_global_buffers();
- img->number = 0;
-#endif
hd->end_SeqTr = img->tr;
img->sequence_end_flag = 0;
}
@@ -1944,27 +1656,13 @@
hd->next_IDRcoi = img->coding_order;
img->new_sequence_flag = 0;
}
-#if 0/*RD170_FIX_BG*/
- if (hd->vec_flag) {
- int32_t k;
- flushDPB();
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
- hd->vec_flag = 0;
- free_global_buffers();
- img->number = 0;
- }
-#endif
-/* allocate memory for frame buffers*/
-#if 0
-/* called in vavs2.c*/
- if (img->number == 0)
- avs2_init_global_buffers(avs2_dec);
-#endif
img->current_mb_nr = 0;
- init_frame(avs2_dec);
+ if (init_frame(avs2_dec) < 0) {
+ pr_info("%s, warning, init_frame error!\n", __func__);
+ return -1;
+ }
img->types = img->type; /* jlzheng 7.15*/
@@ -2031,7 +1729,6 @@
/* record the reference list information*/
get_reference_list_info(avs2_dec, avs2_dec->hc.str_list_reference);
- /*pr_info("%s\n", __func__);*/
ret = frame_postprocessing(avs2_dec);
#if FIX_PROFILE_LEVEL_DPB_RPS_1
@@ -2039,8 +1736,7 @@
{
int32_t i, j;
if (is_avs2_print_bufmgr_detail()) {
- pr_info(
- "%s, coding_order %d to remove %d buf: ",
+ pr_info("%s, coding_order %d to remove %d buf: ",
__func__,
img->coding_order,
hd->curr_RPS.num_to_remove);
@@ -2060,12 +1756,11 @@
if (j < avs2_dec->ref_maxbuffer) { /**/
#if FIX_RPS_PICTURE_REMOVE
/* Label new frames as "un-referenced" */
- avs2_dec->fref[j]->refered_by_others = 0;
+ avs2_dec->fref[j]->referred_by_others = 0;
/* remove frames which have been outputted */
if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->
- imgtr_fwRefDistance = -256;
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
avs2_dec->fref[j]->imgcoi_ref = -257;
avs2_dec->fref[j]->temporal_id = -1;
@@ -2076,8 +1771,7 @@
avs2_dec->fref[j]->temporal_id = -1;
#endif
if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->imgtr_fwRefDistance
- = -256;
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
}
#endif
}
@@ -2085,7 +1779,6 @@
}
#endif
-
/*! TO 19.11.2001 Known Problem: for init_frame
* we have to know the picture type of the
* actual frame*/
@@ -2143,8 +1836,7 @@
}
for (j = 0; j < 16; j++) {
for (k = 0; k < 9; k++) {
- avs2_dec->
- m_alfPictureParam[i].coeffmulti[j][k] = 0;
+ avs2_dec->m_alfPictureParam[i].coeffmulti[j][k] = 0;
/*16*9*/
}
}
@@ -2159,15 +1851,6 @@
hd->dec_ref_num = 0;
}
- /*
- memset(g_log2size, -1, MAX_CU_SIZE + 1);
- c = 2;
- for (k = 4; k <= MAX_CU_SIZE; k *= 2) {
- g_log2size[k] = c;
- c++;
- }
- */
-
avs2_dec->outprint.buffer_num = 0;
hd->last_output = -1;
@@ -2184,7 +1867,6 @@
img->imgcoi_next_ref = 0;
-
img->num_of_references = 0;
hc->seq_header = 0;
@@ -2200,6 +1882,5 @@
/* time for total decoding session*/
hc->tot_time = 0;
-
}
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h
index be35a5e..b3b0feb 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_global.h
+++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -1,47 +1,22 @@
-/* The copyright in this software is being made available under the BSD
- * License, included below. This software may be subject to other third party
- * and contributor rights, including patent rights, and no such rights are
- * granted under this license.
- *
- * Copyright (c) 2002-2016, Audio Video coding Standard Workgroup of China
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of Audio Video coding Standard Workgroup of China
- * nor the names of its contributors maybe
- * used to endorse or promote products
- * derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-
/*
- * File name: global.h
- * Function: global definitions for for AVS decoder.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
-
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
@@ -141,7 +116,7 @@
/* MV derivation method 1, weighted P_skip mode */
#define HALF_PIXEL_COMPENSATION_M1 1
/* M1 related with mv-scaling function */
-#define HALF_PIXEL_COMPENSATION_M1_FUCTION 1
+#define HALF_PIXEL_COMPENSATION_M1_FUNCTION 1
#define HALF_PIXEL_COMPENSATION_MVD 1 /* MV scaling from FW->BW */
/* Chroma components */
/* chroma MV is scaled with luma MV for 4:2:0 format */
@@ -172,7 +147,7 @@
#define AVS2_HDR_Tec 1
#if AVS2_HDR_Tec
#define HDR_CHROMA_DELTA_QP 1 /* M3905 */
-#define HDR_ADPTIVE_UV_DELTA 1
+#define HDR_ADAPTIVE_UV_DELTA 1
#endif
/*
*************************************
@@ -601,7 +576,7 @@
int32_t copyright_number;
};
-struct CameraParamters_s {
+struct CameraParameters_s {
int32_t reserved;
int32_t camera_id;
int32_t height_of_image_device;
@@ -746,7 +721,7 @@
byte ***ref;
int32_t imgtr_fwRefDistance;
- int32_t refered_by_others;
+ int32_t referred_by_others;
int32_t is_output;
int32_t to_prepare_disp;
#if M3480_TEMPORAL_SCALABLE
@@ -789,7 +764,7 @@
int BUF_index;
int pic_w;
int pic_h;
- int stream_offset;
+ u32 stream_offset;
u32 pts;
u64 pts64;
/**/
@@ -804,7 +779,7 @@
int mv_buf_index;
#endif
- /* picture qos infomation*/
+ /* picture qos information*/
int max_qp;
int avg_qp;
int min_qp;
@@ -820,6 +795,9 @@
char *cuva_data_buf;
int cuva_data_size;
+#ifdef AML
+ u64 time;
+#endif
};
@@ -858,7 +836,7 @@
int32_t **predBlock; /* !< current best prediction mode */
int32_t **predBlockTmp;
- /* !< the diff pixel values between orginal image and prediction */
+ /* !< the diff pixel values between original image and prediction */
int32_t **resiY;
/* !< Array containing square values,used for snr computation */
int32_t *quad;
@@ -1093,7 +1071,7 @@
/*#include "commonVariables.h"*/
/*
-extern struct CameraParamters_s *camera;
+extern struct CameraParameters_s *camera;
extern struct SNRParameters_s *snr;
extern struct ImageParameters_s *img;
*/
@@ -1181,7 +1159,7 @@
int32_t poc;
int32_t qp_offset;
int32_t num_of_ref;
- int32_t referd_by_others;
+ int32_t referred_by_others;
int32_t ref_pic[MAXREF];
int32_t predict;
int32_t deltaRPS;
@@ -1333,8 +1311,8 @@
int32_t slice_vertical_position_extension;
int32_t fixed_slice_qp;
int32_t slice_qp;
-int32_t slice_horizontal_positon; /* added by mz, 2008.04 */
-int32_t slice_horizontal_positon_extension;
+int32_t slice_horizontal_position; /* added by mz, 2008.04 */
+int32_t slice_horizontal_position_extension;
int32_t StartCodePosition;
int32_t background_pred_flag;
@@ -1588,7 +1566,7 @@
uint16_t displaydelay; /*???*/
uint16_t predict; /*???*/
uint16_t RPS_idx; /*???*/
- uint16_t referd_by_others_cur;
+ uint16_t referred_by_others_cur;
uint16_t num_of_ref_cur;
uint16_t ref_pic_cur[8];
uint16_t num_to_remove_cur;
@@ -1667,6 +1645,9 @@
int32_t to_prepare_disp_count;
int8_t bufmgr_error_flag;
#endif
+#ifdef AML
+ u64 start_time;
+#endif
};
@@ -1686,5 +1667,6 @@
extern bool is_avs2_print_param(void);
extern bool is_avs2_print_bufmgr_detail(void);
+extern int get_error_policy(struct avs2_decoder *avs2_dec);
#endif
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c
index e21dc55..ba0a363 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.c
+++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -1,7 +1,5 @@
- /*
- * drivers/amlogic/amports/avs2.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,7 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
-*/
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -34,30 +37,37 @@
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../utils/decoder_mmu_box.h"
-#include "../utils/decoder_bmmu_box.h"
-#include "avs2_global.h"
-
-#define MEM_NAME "codec_avs2"
-/* #include <mach/am_regs.h> */
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../utils/vdec.h"
-#include "../utils/amvdec.h"
-
#include <linux/amlogic/media/video_sink/video.h>
#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+
+#include <linux/slab.h>
+#include <linux/sched/clock.h>
+#include <uapi/linux/tee.h>
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../include/regs/dos_registers.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
#include "../utils/config_parser.h"
#include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../utils/vdec_feature.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "avs2_global.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+
+#define MEM_NAME "codec_avs2"
#define I_ONLY_SUPPORT
#define MIX_STREAM_SUPPORT
@@ -68,7 +78,6 @@
#include "vavs2.h"
#define HEVC_SHIFT_LENGTH_PROTECT 0x313a
#define HEVC_MPRED_CTRL4 0x324c
-#define HEVC_MPRED_CTRL9 0x325b
#define HEVC_DBLK_CFGD 0x350d
#define HEVC_CM_HEADER_START_ADDR 0x3628
#define HEVC_DBLK_CFGB 0x350b
@@ -96,8 +105,6 @@
#define HEVC_SAO_CTRL9 0x362d
-
-
/*
* AVS2_DEC_STATUS define
*/
@@ -141,11 +148,10 @@
#define AVS2_ACTION_DONE 0xff
/*AVS2_DEC_STATUS end*/
-
#define VF_POOL_SIZE 32
#undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
#define DECODE_MODE_SINGLE (0 | (0x80 << 24))
#define DECODE_MODE_MULTI_STREAMBASE (1 | (0x80 << 24))
@@ -155,7 +161,6 @@
#define VP9_TRIGGER_FRAME_DONE 0x100
#define VP9_TRIGGER_FRAME_ENABLE 0x200
-/*#define MV_MEM_UNIT 0x240*/
#define MV_MEM_UNIT 0x200
/*---------------------------------------------------
Include "parser_cmd.h"
@@ -170,43 +175,43 @@
#define PARSER_CMD_NUMBER 37
static unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
-0x0401,
-0x8401,
-0x0800,
-0x0402,
-0x9002,
-0x1423,
-0x8CC3,
-0x1423,
-0x8804,
-0x9825,
-0x0800,
-0x04FE,
-0x8406,
-0x8411,
-0x1800,
-0x8408,
-0x8409,
-0x8C2A,
-0x9C2B,
-0x1C00,
-0x840F,
-0x8407,
-0x8000,
-0x8408,
-0x2000,
-0xA800,
-0x8410,
-0x04DE,
-0x840C,
-0x840D,
-0xAC00,
-0xA000,
-0x08C0,
-0x08E0,
-0xA40E,
-0xFC00,
-0x7C00
+ 0x0401,
+ 0x8401,
+ 0x0800,
+ 0x0402,
+ 0x9002,
+ 0x1423,
+ 0x8CC3,
+ 0x1423,
+ 0x8804,
+ 0x9825,
+ 0x0800,
+ 0x04FE,
+ 0x8406,
+ 0x8411,
+ 0x1800,
+ 0x8408,
+ 0x8409,
+ 0x8C2A,
+ 0x9C2B,
+ 0x1C00,
+ 0x840F,
+ 0x8407,
+ 0x8000,
+ 0x8408,
+ 0x2000,
+ 0xA800,
+ 0x8410,
+ 0x04DE,
+ 0x840C,
+ 0x840D,
+ 0xAC00,
+ 0xA000,
+ 0x08C0,
+ 0x08E0,
+ 0xA40E,
+ 0xFC00,
+ 0x7C00
};
static int32_t g_WqMDefault4x4[16] = {
@@ -227,13 +232,9 @@
96, 100, 104, 116, 124, 140, 164, 188,
104, 108, 116, 128, 152, 172, 192, 216
};
-/*#define HEVC_PIC_STRUCT_SUPPORT*/
/* to remove, fix build error */
-/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/
-
#define MULTI_INSTANCE_SUPPORT
-/* #define ERROR_HANDLE_DEBUG */
#ifndef STAT_KTHREAD
#define STAT_KTHREAD 0x40
@@ -288,12 +289,17 @@
static u32 double_write_mode;
static u32 without_display_mode;
+/*
+bit0: if dpb abnormal, check dpb buffer status and flush dpb.
+bit1: 0:show error frame.
+*/
+static unsigned int error_proc_policy = 0x3;
+
static u32 mv_buf_dynamic_alloc;
#define DRIVER_NAME "amvdec_avs2"
#define DRIVER_HEADER_NAME "amvdec_avs2_header"
-
#define PUT_INTERVAL (HZ/100)
#define ERROR_SYSTEM_RESET_COUNT 200
@@ -301,7 +307,7 @@
#define PTS_NONE_REF_USE_DURATION 1
#define PTS_MODE_SWITCHING_THRESHOLD 3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
+#define PTS_MODE_SWITCHING_RECOVERY_THRESHOLD 3
#define DUR2PTS(x) ((x)*90/96)
@@ -360,9 +366,6 @@
static inline int div_r32(int64_t m, int n)
{
-/*
-return (int)(m/n)
-*/
#ifndef CONFIG_ARM64
int64_t qu = 0;
qu = div_s64(m, n);
@@ -397,22 +400,12 @@
int used_flag;
} /*MVBUF_t */;
- /* #undef BUFMGR_ONLY to enable hardware configuration */
-
-/*#define TEST_WR_PTR_INC*/
#define WR_PTR_INC_NUM 128
#define SIMULATION
#define DOS_PROJECT
#undef MEMORY_MAP_IN_REAL_CHIP
-/*#undef DOS_PROJECT*/
-/*#define MEMORY_MAP_IN_REAL_CHIP*/
-
-/*#define BUFFER_MGR_ONLY*/
-/*#define CONFIG_HEVC_CLK_FORCED_ON*/
-/*#define ENABLE_SWAP_TEST*/
-
#ifdef AVS2_10B_NV21
#define MEM_MAP_MODE 2 /* 0:linear 1:32x32 2:64x32*/
#else
@@ -442,7 +435,7 @@
#define AVS2_DBG_PIC_LEAK 0x1000
#define AVS2_DBG_PIC_LEAK_WAIT 0x2000
#define AVS2_DBG_HDR_INFO 0x4000
-#define AVS2_DBG_HDR_DATA 0x8000
+#define AVS2_DBG_QOS_INFO 0x8000
#define AVS2_DBG_DIS_LOC_ERROR_PROC 0x10000
#define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000
#define AVS2_DBG_DUMP_PIC_LIST 0x40000
@@ -558,19 +551,11 @@
#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1)
#define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n+1)
#define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
-//#define DW_HEADER_BUFFER_IDX(n) ((FRAME_BUFFERS * 3) + n+1)
#endif
#define CO_MV_BUF_SIZE_1080P 0x3fc00
#define CO_MV_BUF_SIZE_4K 0x120000
#define CO_MV_BUF_SIZE_8K 0x480000
-/*
-static void set_canvas(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic);
-int avs2_prepare_display_buf(struct AVS2Decoder_s *dec,
- int pos);
-*/
-
struct buff_s {
u32 buf_start;
@@ -625,6 +610,13 @@
#define DEC_RESULT_EOS 9
#define DEC_RESULT_FORCE_EXIT 10
+#define PROC_STATE_INIT 0
+#define PROC_STATE_HEAD_DONE 1
+#define PROC_STATE_DECODING 2
+#define PROC_STATE_HEAD_AGAIN 3
+#define PROC_STATE_DECODE_AGAIN 4
+#define PROC_STATE_TEST1 5
+
static void avs2_work(struct work_struct *work);
struct loop_filter_info_n;
struct loopfilter;
@@ -636,7 +628,7 @@
spinlock_t buffer_lock;
struct device *cma_dev;
struct platform_device *platform_dev;
- void (*vdec_cb)(struct vdec_s *, void *);
+ void (*vdec_cb)(struct vdec_s *, void *, int);
void *vdec_cb_arg;
struct vframe_chunk_s *chunk;
int dec_result;
@@ -668,12 +660,6 @@
uint8_t init_flag;
uint8_t first_sc_checked;
uint8_t process_busy;
-#define PROC_STATE_INIT 0
-#define PROC_STATE_HEAD_DONE 1
-#define PROC_STATE_DECODING 2
-#define PROC_STATE_HEAD_AGAIN 3
-#define PROC_STATE_DECODE_AGAIN 4
-#define PROC_STATE_TEST1 5
uint8_t process_state;
u32 ucode_pause_pos;
@@ -764,9 +750,7 @@
uint8_t skip_PB_before_I;
int PB_skip_mode;
int PB_skip_count_after_decoding;
- /*hw*/
- /**/
struct vdec_info *gvs;
@@ -815,6 +799,14 @@
dma_addr_t rdma_phy_adr;
unsigned *rdma_adr;
int hdr_flag;
+ bool high_bandwidth_flag;
+ ulong rpm_mem_handle;
+ ulong lmem_phy_handle;
+ ulong frame_mmu_map_handle;
+ ulong frame_dw_mmu_map_handle;
+ ulong rdma_mem_handle;
+ ulong cuva_handle;
+ u32 error_proc_policy;
};
static int compute_losless_comp_body_size(
@@ -861,7 +853,6 @@
#define PROB_SIZE (496 * 2 * 4)
#define PROB_BUF_SIZE (0x5000)
#define COUNT_BUF_SIZE (0x300 * 4 * 4)
-/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/
#define MAX_FRAME_4K_NUM 0x1200
#define MAX_FRAME_8K_NUM 0x4800
#define MAX_SIZE_4K (4096 * 2304)
@@ -878,10 +869,13 @@
static int get_compress_header_size(struct AVS2Decoder_s *dec)
{
+ int w = ALIGN(dec->init_pic_w, 64);
+ int h = ALIGN(dec->init_pic_h, 64);
+
if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h)))
+ (IS_8K_SIZE(w, h)))
return MMU_COMPRESS_HEADER_SIZE_8K;
- else if (IS_4K_SIZE(dec->init_pic_w, dec->init_pic_h))
+ else if (IS_4K_SIZE(w, h))
return MMU_COMPRESS_HEADER_SIZE_4K;
return MMU_COMPRESS_HEADER_SIZE_1080P;
}
@@ -909,15 +903,18 @@
static void timeout_process(struct AVS2Decoder_s *dec)
{
struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+ struct avs2_frame_s *pic = avs2_dec->hc.cur_pic;
dec->timeout_num++;
amhevc_stop();
- avs2_print(dec,
- 0, "%s decoder timeout\n", __func__);
- if (cur_pic)
- cur_pic->error_mark = 1;
+ avs2_print(dec, 0, "%s decoder timeout\n", __func__);
+
+ if (pic && (pic->error_mark == 0) &&
+ (pic->decoded_lcu == 0)) {
+ update_decoded_pic(dec);
+ pic->error_mark = 1;
+ }
+
dec->dec_result = DEC_RESULT_DONE;
- update_decoded_pic(dec);
reset_process_time(dec);
vdec_schedule_work(&dec->work);
}
@@ -926,10 +923,8 @@
{
u32 dw_mode;
- dw_mode = (dec->m_ins_flag &&
- ((double_write_mode & 0x80000000) == 0)) ?
- dec->double_write_mode :
- (double_write_mode & 0x7fffffff);
+ dw_mode = (dec->m_ins_flag && ((double_write_mode & 0x80000000) == 0)) ?
+ dec->double_write_mode : (double_write_mode & 0x7fffffff);
if (dw_mode & 0x20) {
if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
&& ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3))
@@ -947,15 +942,15 @@
u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
case 0x100:
- if (w > 1920 && h > 1088)
+ if (w * h > 1920 * 1088)
dw = 0x4; /*1:2*/
break;
case 0x200:
- if (w > 1920 && h > 1088)
+ if (w * h > 1920 * 1088)
dw = 0x2; /*1:4*/
break;
case 0x300:
- if (w > 1280 && h > 720)
+ if (w * h > 1280 * 768)
dw = 0x4; /*1:2*/
break;
default:
@@ -984,7 +979,7 @@
dw = 0x2; /*1:4*/
break;
case 0x300:
- if (w > 1280 && h > 720)
+ if (w > 1280 && h > 768)
dw = 0x4; /*1:2*/
break;
default:
@@ -994,7 +989,6 @@
return dw;
}
-//#define MAX_4K_NUM 0x1200
#ifdef AVS2_10B_MMU
int avs2_alloc_mmu(
struct AVS2Decoder_s *dec,
@@ -1009,8 +1003,7 @@
int cur_mmu_4k_number, max_frame_num;
picture_size = compute_losless_comp_body_size(
- dec, pic_width, pic_height,
- bit_depth_10);
+ dec, pic_width, pic_height, bit_depth_10);
cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
max_frame_num = MAX_FRAME_8K_NUM;
@@ -1043,8 +1036,7 @@
int cur_mmu_4k_number, max_frame_num;
picture_size = compute_losless_comp_body_size(
- dec, pic_width, pic_height,
- bit_depth_10);
+ dec, pic_width, pic_height, bit_depth_10);
cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
max_frame_num = MAX_FRAME_8K_NUM;
@@ -1069,18 +1061,11 @@
int i;
int count = 0;
for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref < -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) && avs2_dec->fref[i]->is_output == -1
- && avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
- && avs2_dec->fref[i]->vf_ref == 0
- && avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
- ) {
+ if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+ && avs2_dec->fref[i]->is_output == -1
+ && avs2_dec->fref[i]->bg_flag == 0
+ && avs2_dec->fref[i]->vf_ref == 0
+ && avs2_dec->fref[i]->to_prepare_disp == 0) {
count++;
}
}
@@ -1088,6 +1073,13 @@
return count;
}
+int get_error_policy(struct avs2_decoder *avs2_dec)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec, struct AVS2Decoder_s, avs2_dec);
+
+ return dec->error_proc_policy;
+}
+
#ifdef CONSTRAIN_MAX_BUF_NUM
static int get_vf_ref_only_buf_count(struct AVS2Decoder_s *dec)
{
@@ -1095,18 +1087,11 @@
int i;
int count = 0;
for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref < -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) && avs2_dec->fref[i]->is_output == -1
- && avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
- && avs2_dec->fref[i]->vf_ref > 0
- && avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
- ) {
+ if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+ && avs2_dec->fref[i]->is_output == -1
+ && avs2_dec->fref[i]->bg_flag == 0
+ && avs2_dec->fref[i]->vf_ref > 0
+ && avs2_dec->fref[i]->to_prepare_disp == 0) {
count++;
}
}
@@ -1120,18 +1105,11 @@
int i;
int count = 0;
for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref >= -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) || avs2_dec->fref[i]->is_output != -1
- || avs2_dec->fref[i]->bg_flag != 0
-#ifndef NO_DISPLAY
- || avs2_dec->fref[i]->vf_ref != 0
- || avs2_dec->fref[i]->to_prepare_disp != 0
-#endif
- ) {
+ if ((avs2_dec->fref[i]->imgcoi_ref >= -256)
+ || avs2_dec->fref[i]->is_output != -1
+ || avs2_dec->fref[i]->bg_flag != 0
+ || avs2_dec->fref[i]->vf_ref != 0
+ || avs2_dec->fref[i]->to_prepare_disp != 0) {
count++;
}
}
@@ -1149,7 +1127,6 @@
dec->cur_fb_idx_mmu = INVALID_IDX;
#endif
-
/* private init */
dec->work_space_buf = buf_spec_i;
#ifndef AVS2_10B_MMU
@@ -1161,8 +1138,7 @@
dec->use_cma_flag = 0;
dec->decode_idx = 0;
dec->slice_idx = 0;
- /*int m_uiMaxCUWidth = 1<<7;*/
- /*int m_uiMaxCUHeight = 1<<7;*/
+
dec->wait_buf = 0;
dec->error_flag = 0;
dec->skip_PB_before_I = 0;
@@ -1193,8 +1169,6 @@
#define LOSLESS_COMPRESS_MODE
-/*#define DECOMP_HEADR_SURGENT*/
-
static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
static u32 enable_mem_saving = 1;
static u32 force_w_h;
@@ -1265,7 +1239,6 @@
static u32 buffer_mode = 1;
/* buffer_mode_dbg: debug only*/
static u32 buffer_mode_dbg = 0xffff0000;
-/**/
/*
bit 0, 1: only display I picture;
@@ -1273,7 +1246,6 @@
*/
static u32 i_only_flag;
-
static u32 max_decoding_time;
/*
error handling
@@ -1293,7 +1265,6 @@
bit 15~8: frame count threshold
*/
static u32 re_search_seq_threshold = 0x800; /*0x8;*/
-/*static u32 parser_sei_enable = 1;*/
static u32 max_buf_num = (REF_BUFFER + 1);
@@ -1307,22 +1278,16 @@
#define HEVC_RCS_BUFFER HEVC_ASSIST_SCRATCH_3
#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
-//#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
#ifdef AVS2_10B_MMU
#define AVS2_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
#else
#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
#endif
#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
-/*
-#define VP9_PROB_SWAP_BUFFER HEVC_ASSIST_SCRATCH_9
-#define VP9_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
-#define VP9_SEG_MAP_BUFFER HEVC_ASSIST_SCRATCH_B
-*/
+
#define AVS2_CUVA_ADR HEVC_ASSIST_SCRATCH_A
#define AVS2_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_B
-//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_9
@@ -1454,14 +1419,6 @@
.mmu_vbh = {
.buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
},
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
#endif
.mpred_above = {
.buf_size = 0x8000, /* 2 * size of hevc*/
@@ -1549,14 +1506,6 @@
.mmu_vbh = {
.buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
},
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
#endif
.mpred_above = {
.buf_size = 0x10000, /* 2 * size of hevc*/
@@ -1639,12 +1588,6 @@
.mmu_vbh = {
.buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/
},
-#if 0
- .cm_header = {
- /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
- },
-#endif
#endif
.mpred_above = {
.buf_size = 0x8000 * 2,
@@ -1664,310 +1607,94 @@
},
{
/* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x1e00,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- 32Kbytes (0x8000) */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x3d00, //0x3c80,
- },
- .dblk_data = {
- .buf_size = 0x62800,
- },
- .dblk_data2 = {
- .buf_size = 0x62800,
- },
+ .max_width = 1920, //2048
+ .max_height = 1088, //1152
+ .ipp = {.buf_size = 0x1e00}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+ .short_term_rps = {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, // RCS STORE AREA - Max 32 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+ .sao_up = {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .swap_buf = {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+ .scalelut = {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .dblk_para = {.buf_size = 0x4100}, //(ctu_numb_x+1) * 128 = (2048/16+1)*128= 0x4080
+ .dblk_data = {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+ .dblk_data2 = {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_1080P, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_1080P}, /*2*16*(more than 2304)/4, 4K*/
#endif
#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_1080P, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_1080P}, //2*16*2304/4, 4K
#endif
-#endif
- .mpred_above = {
- .buf_size = 0x1e00, /* 2 * size of hevc*/
- },
+ .mpred_above = {.buf_size = 0x2000}, // 2 * size of hevc: (pic_width/64)*16*16 byte = 2048/64*16*16=0x2000
#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS,
- },
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS}, // 1080p, 0x40000 per buffer
#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+ .lmem = {.buf_size = 0x400 * 2},
},
{
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- (0x8000) */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x8100, //0x8080,
- },
- .dblk_data = {
- /*DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x88800,
- },
- .dblk_data2 = {
- .buf_size = 0x88800,
- },
+ .max_width = 4096,
+ .max_height = 2304,
+ .ipp = {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+ .short_term_rps = {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, // RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,total 0x2000 bytes
+ .sao_up = {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .swap_buf = {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+ .scalelut = {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .dblk_para = {.buf_size = 0x8100}, //(ctu_numb_x+1) * 128 = (4096/16+1)*128 = 0x8080
+ .dblk_data = {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+ .dblk_data2 = {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_4K,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_4K},/*2*16*(more than 2304)/4, 4K*/
#endif
#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_4K, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_4K}, //2*16*2304/4, 4K
#endif
-#endif
- .mpred_above = {
- .buf_size = 0x4000, /* 2 * size of hevc*/
- },
+ .mpred_above = {.buf_size = 0x4000}, //(pic_width/64)*16*16 byte = 4096/64*16*16=0x4000
#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS,
- },
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS}, //.buf_size = 0x100000*16, 4k2k => 0x100000 per buffer 4096x2304 => 0x120000 per buffer
#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+ .lmem = {.buf_size = 0x400 * 2},
},
{
- .max_width = 4096 * 2,
- .max_height = 2304 * 2,
- .ipp = {
- /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
- round to 16k*/
- .buf_size = 0x4000 * 2,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800)*/
- .buf_size = 0x800,
- },
- .rcs = {
- /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes*/
- .buf_size = 0x400,
- },
- .sps = {
- /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
- 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
- total 0x2800 bytes*/
- .buf_size = 0,
- },
- .swap_buf = {
- /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
- .buf_size = 0,
- },
- .dblk_para = {
- .buf_size = 0x10100, //0x10080,
- },
- .dblk_data = {
- .buf_size = 0x110800,
- },
- .dblk_data2 = {
- .buf_size = 0x110800,
- },
+ .max_width = 4096 * 2,
+ .max_height = 2304 * 2,
+ .ipp = {.buf_size = 0x4000 * 2}, //IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+ .short_term_rps = {.buf_size = 0x800}, //SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, //RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, //SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, //PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytess
+ .sao_up = {.buf_size = 0}, //SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .swap_buf = {.buf_size = 0x800}, //256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+ .scalelut = {.buf_size = 0}, //support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .dblk_para = {.buf_size = 0x10100}, //0x10080, //(ctu_numb_x+1) * 128 = (8192/16+1) * 128 = 0x10080
+ .dblk_data = {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+ .dblk_data2 = {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_8K, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
- },
-#endif
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_8K}, /*2*16*2304/4, 4K*/
#endif
#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_8K, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_8K}, //2*16*2304/4, 4K
#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
+ .mpred_above = {.buf_size = 0x8000}, //(pic_width/64)*16*16 byte = 8192/64*16*16=0x8000
#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /*4k2k , 0x100000 per buffer*/
- .buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS,
- },
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS}, //4k2k , 0x100000 per buffer
#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+ .lmem = {.buf_size = 0x400 * 2},
}
};
@@ -2316,15 +2043,14 @@
#endif
static int config_pic(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic, int32_t lcu_size_log2)
+ struct avs2_frame_s *pic)
{
int ret = -1;
int i;
int pic_width = dec->init_pic_w;
int pic_height = dec->init_pic_h;
- /*struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- int32_t lcu_size_log2 = avs2_dec->lcu_size_log2;*/
- int32_t lcu_size = 1 << lcu_size_log2;
+
+ int32_t lcu_size = dec->avs2_dec.lcu_size;
int pic_width_64 = (pic_width + 63) & (~0x3f);
int pic_height_32 = (pic_height + 31) & (~0x1f);
int pic_width_lcu = (pic_width_64 % lcu_size) ?
@@ -2374,7 +2100,6 @@
if (mc_buffer_size & 0xffff) /*64k alignment*/
mc_buffer_size_h += 1;
-
#ifdef AVS2_10B_MMU
if (dec->mmu_enable) {
pic->header_adr = decoder_bmmu_box_get_phy_addr(
@@ -2403,44 +2128,39 @@
dec->mc_buf_spec.buf_start + i * buf_size, buf_size);
}
for (i = 0; i < dec->buf_num; i++) {
- y_adr = ((dec->m_BUF[i].free_start_adr
- + 0xffff) >> 16) << 16;
+ y_adr = ((dec->m_BUF[i].free_start_adr + 0xffff) >> 16) << 16;
/*64k alignment*/
if ((y_adr+buf_size) <= (dec->m_BUF[i].start_adr+
dec->m_BUF[i].size)) {
- dec->m_BUF[i].free_start_adr =
- y_adr + buf_size;
+ dec->m_BUF[i].free_start_adr = y_adr + buf_size;
break;
}
}
if (i < dec->buf_num)
#else
- /*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
- dec->mc_buf->buf_end)
- y_adr = dec->mc_buf->buf_start + i * buf_size;
- else {*/
if (buf_size > 0 && pic->cma_alloc_addr == 0) {
ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
VF_BUFFER_IDX(i),
buf_size, DRIVER_NAME,
&pic->cma_alloc_addr);
+
if (ret < 0) {
avs2_print(dec, 0,
"decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
VF_BUFFER_IDX(i),
- buf_size
- );
+ buf_size);
return ret;
}
- if (pic->cma_alloc_addr)
+ if (pic->cma_alloc_addr) {
y_adr = pic->cma_alloc_addr;
- else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(y_adr, 0, buf_size);
+ } else {
avs2_print(dec, 0,
"decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
VF_BUFFER_IDX(i),
- buf_size
- );
+ buf_size);
return -1;
}
}
@@ -2484,31 +2204,29 @@
#endif
}
#ifdef MV_USE_FIXED_BUF
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start +
+ pic->mpred_mv_wr_start_addr = dec->work_space_buf->mpred_mv.buf_start +
pic->index * (dec->work_space_buf->mpred_mv.buf_size / FRAME_BUFFERS);
if (pic->mpred_mv_wr_start_addr >
(dec->work_space_buf->mpred_mv.buf_start
+ dec->work_space_buf->mpred_mv.buf_size)) {
avs2_print(dec, 0, "err: fixed mv buf out of size, 0x0%x\n",
pic->mpred_mv_wr_start_addr);
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start;
+ pic->mpred_mv_wr_start_addr = dec->work_space_buf->mpred_mv.buf_start;
}
#endif
if (debug) {
avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index %d BUF_index %d mc_y_adr %x ",
- __func__, pic->index,
- pic->BUF_index,
- pic->mc_y_adr);
+ "%s index %d BUF_index %d mc_y_adr %x ",
+ __func__, pic->index,
+ pic->BUF_index,
+ pic->mc_y_adr);
avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "comp_body_size %x comp_buf_size %x ",
- pic->comp_body_size,
- pic->buf_size);
+ "comp_body_size %x comp_buf_size %x ",
+ pic->comp_body_size,
+ pic->buf_size);
avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "mpred_mv_wr_start_adr %d\n",
- pic->mpred_mv_wr_start_addr);
+ "mpred_mv_wr_start_adr %d\n",
+ pic->mpred_mv_wr_start_addr);
avs2_print_cont(dec, AVS2_DBG_BUFMGR,
"dw_y_adr %d, pic->dw_u_v_adr =%d\n",
pic->dw_y_adr,
@@ -2520,8 +2238,7 @@
return ret;
}
-static void init_pic_list(struct AVS2Decoder_s *dec,
- int32_t lcu_size_log2)
+static void init_pic_list(struct AVS2Decoder_s *dec)
{
int i;
struct avs2_decoder *avs2_dec = &dec->avs2_dec;
@@ -2546,6 +2263,8 @@
dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
return;
}
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(buf_addr, 0, header_size);
}
}
#endif
@@ -2560,11 +2279,9 @@
pic->index = i;
pic->BUF_index = -1;
pic->mv_buf_index = -1;
- if (config_pic(dec, pic, lcu_size_log2) < 0) {
+ if (config_pic(dec, pic) < 0) {
if (debug)
- avs2_print(dec, 0,
- "Config_pic %d fail\n",
- pic->index);
+ avs2_print(dec, 0, "Config_pic %d fail\n", pic->index);
pic->index = -1;
break;
}
@@ -2592,16 +2309,7 @@
int i;
struct avs2_decoder *avs2_dec = &dec->avs2_dec;
struct avs2_frame_s *pic;
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
-#if 0
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-#ifdef DUAL_CORE_64
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-#endif
-#endif
for (i = 0; i < dec->used_buf_num; i++) {
if (i == (dec->used_buf_num - 1))
pic = avs2_dec->m_bg;
@@ -2610,9 +2318,6 @@
if (pic->index < 0)
break;
#ifdef AVS2_10B_MMU
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->header_adr
- | (pic->mc_canvas_y << 8)|0x1);*/
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
(0x1 << 1) | (pic->index << 8));
@@ -2626,36 +2331,26 @@
#endif
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
#else
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->mc_y_adr
- | (pic->mc_canvas_y << 8) | 0x1);*/
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
#endif
#ifndef LOSLESS_COMPRESS_MODE
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->mc_u_v_adr
- | (pic->mc_canvas_u_v << 8)| 0x1);*/
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
#endif
#ifdef DUAL_CORE_64
#ifdef AVS2_10B_MMU
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->header_adr >> 5);
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
#else
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->mc_y_adr >> 5);
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
#endif
#ifndef LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->mc_u_v_adr >> 5);
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
#endif
/*DUAL_CORE_64*/
#endif
}
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
#ifdef DUAL_CORE_64
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- 0x1);
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
#endif
/*Zero out canvas registers in IPP -- avoid simulation X*/
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
@@ -2675,13 +2370,13 @@
struct avs2_decoder *avs2_dec = &dec->avs2_dec;
for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
avs2_print(dec, 0,
- "fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
+ "fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d referred %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d), time %lld\n",
ii, avs2_dec->fref[ii]->index,
avs2_dec->fref[ii]->decode_idx,
avs2_dec->fref[ii]->mv_buf_index,
avs2_dec->fref[ii]->imgcoi_ref,
avs2_dec->fref[ii]->imgtr_fwRefDistance,
- avs2_dec->fref[ii]->refered_by_others,
+ avs2_dec->fref[ii]->referred_by_others,
avs2_dec->fref[ii]->to_prepare_disp,
avs2_dec->fref[ii]->is_output,
avs2_dec->fref[ii]->bg_flag,
@@ -2694,8 +2389,8 @@
avs2_dec->fref[ii]->ref_poc[3],
avs2_dec->fref[ii]->ref_poc[4],
avs2_dec->fref[ii]->ref_poc[5],
- avs2_dec->fref[ii]->ref_poc[6]
- );
+ avs2_dec->fref[ii]->ref_poc[6],
+ avs2_dec->fref[ii]->time);
}
return;
}
@@ -2707,25 +2402,20 @@
struct avs2_frame_s *pic;
struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
- /*if (avs2_dec->img.type == I_IMG)
- return 0;
- */
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"Entered config_mc_buffer....\n");
if (avs2_dec->f_bg != NULL) {
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
avs2_dec->f_bg->mc_canvas_y, avs2_dec->f_bg->mc_canvas_u_v);
- /*WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (7 << 8) | (0<<1) | 1); L0:BG */
+
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
(15 << 8) | (0<<1) | 1); /* L0:BG*/
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
(avs2_dec->f_bg->mc_canvas_u_v << 16) |
(avs2_dec->f_bg->mc_canvas_u_v << 8) |
avs2_dec->f_bg->mc_canvas_y);
- /*WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (23 << 8) | (0<<1) | 1); L1:BG*/
+
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
(31 << 8) | (0<<1) | 1); /* L1:BG*/
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
@@ -2738,6 +2428,9 @@
return 0;
if (avs2_dec->img.type == P_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"config_mc_buffer for P_IMG, img type %d\n",
avs2_dec->img.type);
@@ -2746,28 +2439,9 @@
(0 << 8) | (0<<1) | 1);
for (i = 0; i < avs2_dec->img.num_of_references; i++) {
pic = avs2_dec->fref[i];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16) |
- (pic->mc_canvas_u_v << 8) |
- pic->mc_canvas_y);
-
- if (pic->error_mark)
- cur_pic->error_mark = 1;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
- i, pic->mc_canvas_u_v, pic->mc_canvas_y,
- pic->error_mark);
- }
- } else if (avs2_dec->img.type == F_IMG) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "config_mc_buffer for F_IMG, img type %d\n",
- avs2_dec->img.type);
- /*refer to prepare_RefInfo()*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0<<1) | 1);
- for (i = 0; i < avs2_dec->img.num_of_references; i++) {
- pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
(pic->mc_canvas_u_v << 16) |
(pic->mc_canvas_u_v << 8) |
@@ -2781,6 +2455,39 @@
i, pic->mc_canvas_u_v, pic->mc_canvas_y,
pic->error_mark);
}
+
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
+ } else if (avs2_dec->img.type == F_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for F_IMG, img type %d\n",
+ avs2_dec->img.type);
+ /*refer to prepare_RefInfo()*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v << 16) |
+ (pic->mc_canvas_u_v << 8) |
+ pic->mc_canvas_y);
+
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
+ i, pic->mc_canvas_u_v, pic->mc_canvas_y,
+ pic->error_mark);
+ }
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
(16 << 8) | (0<<1) | 1);
for (i = 0; i < avs2_dec->img.num_of_references; i++) {
@@ -2831,145 +2538,6 @@
}
return 0;
}
-#if 0
-static void mcrcc_get_hitrate(void)
-{
- u32 tmp;
- u32 raw_mcr_cnt;
- u32 hit_mcr_cnt;
- u32 byp_mcr_cnt_nchoutwin;
- u32 byp_mcr_cnt_nchcanv;
- int hitrate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered mcrcc_get_hitrate...\n");
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
- byp_mcr_cnt_nchoutwin = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
- byp_mcr_cnt_nchcanv = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("raw_mcr_cnt_total: %d\n",raw_mcr_cnt);
- pr_info("hit_mcr_cnt_total: %d\n",hit_mcr_cnt);
- pr_info("byp_mcr_cnt_nchoutwin_total: %d\n",byp_mcr_cnt_nchoutwin);
- pr_info("byp_mcr_cnt_nchcanv_total: %d\n",byp_mcr_cnt_nchcanv);
- }
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("miss_mcr_0_cnt_total: %d\n", tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("miss_mcr_1_cnt_total: %d\n", tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("hit_mcr_0_cnt_total: %d\n",tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
- tmp= READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("hit_mcr_1_cnt_total: %d\n",tmp);
-
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("MCRCC_HIT_RATE : %d\n", hitrate);
- hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)
- /raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("MCRCC_BYP_RATE : %d\n", hitrate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("MCRCC_HIT_RATE : na\n");
- pr_info("MCRCC_BYP_RATE : na\n");
- }
- return;
-}
-
-
-static void decomp_get_hitrate(void)
-{
- u32 raw_mcr_cnt;
- u32 hit_mcr_cnt;
- int hitrate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_hitrate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
- pr_info("hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
- }
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
- } else {
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : na\n");
- }
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("dcache_raw_cnt_total: %d\n", raw_mcr_cnt);
- pr_info("dcache_hit_cnt_total: %d\n", hit_mcr_cnt);
- }
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("DECOMP_DCACHE_HIT_RATE : na\n");
- }
-return;
-}
-
-static void decomp_get_comprate(void)
-{
- u32 raw_ucomp_cnt;
- u32 fast_comp_cnt;
- u32 slow_comp_cnt;
- int comprate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_comprate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
- fast_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
- slow_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
- raw_ucomp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE) {
- pr_info("decomp_fast_comp_total: %d\n", fast_comp_cnt);
- pr_info("decomp_slow_comp_total: %d\n", slow_comp_cnt);
- pr_info("decomp_raw_uncomp_total: %d\n", raw_ucomp_cnt);
- }
-
- if (raw_ucomp_cnt != 0) {
- comprate = ((fast_comp_cnt + slow_comp_cnt)
- / raw_ucomp_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_COMP_RATIO : %d\n", comprate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("DECOMP_COMP_RATIO : na\n");
- }
- return;
-}
-#endif
static void config_mcrcc_axi_hw(struct AVS2Decoder_s *dec)
{
@@ -2984,13 +2552,7 @@
WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
return;
}
-/*
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- mcrcc_get_hitrate();
- decomp_get_hitrate();
- decomp_get_comprate();
- }
-*/
+
if ((avs2_dec->img.type == B_IMG) ||
(avs2_dec->img.type == F_IMG)) { /*B-PIC or F_PIC*/
/*Programme canvas0 */
@@ -3008,8 +2570,7 @@
rdata32_2 = rdata32_2 & 0xffff;
rdata32_2 = rdata32_2 | (rdata32_2 << 16);
if (rdata32 == rdata32_2) {
- rdata32_2 =
- READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
rdata32_2 = rdata32_2 & 0xffff;
rdata32_2 = rdata32_2 | (rdata32_2 << 16);
}
@@ -3061,26 +2622,22 @@
col_isIntra = 0;
}
- mpred_mv_rd_start_addr =
- col_pic->mpred_mv_wr_start_addr;
+ mpred_mv_rd_start_addr = col_pic->mpred_mv_wr_start_addr;
data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
mpred_curr_lcu_x = data32 & 0xffff;
mpred_curr_lcu_y = (data32 >> 16) & 0xffff;
mv_mem_unit = avs2_dec->lcu_size_log2 == 6 ?
0x200 : (avs2_dec->lcu_size_log2 == 5 ?
- 0x80 : 0x20);
+ 0x80 : 0x20);
- mpred_mv_rd_end_addr =
- mpred_mv_rd_start_addr +
- ((avs2_dec->lcu_x_num *
- avs2_dec->lcu_y_num) * mv_mem_unit);
+ mpred_mv_rd_end_addr = mpred_mv_rd_start_addr +
+ ((avs2_dec->lcu_x_num * avs2_dec->lcu_y_num) * mv_mem_unit);
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"cur pic index %d col pic index %d\n",
cur_pic->index, col_pic->index);
-
WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
cur_pic->mpred_mv_wr_start_addr);
WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
@@ -3120,8 +2677,7 @@
avs2_dec->fref[0]->ref_poc[3],
avs2_dec->fref[0]->ref_poc[4],
avs2_dec->fref[0]->ref_poc[5],
- avs2_dec->fref[0]->ref_poc[6]
- );
+ avs2_dec->fref[0]->ref_poc[6]);
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"pic_distance %d, imgtr_next_P %d\n",
avs2_dec->img.pic_distance, avs2_dec->img.imgtr_next_P);
@@ -3206,15 +2762,14 @@
[ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
[ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
*/
- data32 = ((avs2_dec->input.crossSliceLoopFilter
- & 0x1) << 27) |
- ((rpm_param->p.loop_filter_disable & 0x1) << 26) |
- ((avs2_dec->input.useNSQT & 0x1) << 25) |
- ((avs2_dec->img.type & 0x7) << 22) |
- ((rpm_param->p.alpha_c_offset & 0x1f) << 17) |
- ((rpm_param->p.beta_offset & 0x1f) << 12) |
- ((rpm_param->p.chroma_quant_param_delta_cb & 0x3f) << 6) |
- ((rpm_param->p.chroma_quant_param_delta_cr & 0x3f) << 0);
+ data32 = ((avs2_dec->input.crossSliceLoopFilter & 0x1) << 27) |
+ ((rpm_param->p.loop_filter_disable & 0x1) << 26) |
+ ((avs2_dec->input.useNSQT & 0x1) << 25) |
+ ((avs2_dec->img.type & 0x7) << 22) |
+ ((rpm_param->p.alpha_c_offset & 0x1f) << 17) |
+ ((rpm_param->p.beta_offset & 0x1f) << 12) |
+ ((rpm_param->p.chroma_quant_param_delta_cb & 0x3f) << 6) |
+ ((rpm_param->p.chroma_quant_param_delta_cr & 0x3f) << 0);
WRITE_VREG(HEVC_DBLK_CFG9, data32);
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
@@ -3230,8 +2785,7 @@
rpm_param->p.beta_offset,
rpm_param->p.chroma_quant_param_delta_cb,
rpm_param->p.chroma_quant_param_delta_cr);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgDBLK: .done.\n");
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgDBLK: .done.\n");
}
static void config_sao_hw(struct AVS2Decoder_s *dec)
@@ -3241,10 +2795,8 @@
struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
int lcu_size = 64;
- int mc_buffer_size_u_v =
- cur_pic->lcu_total * lcu_size*lcu_size/2;
- int mc_buffer_size_u_v_h =
- (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
+ int mc_buffer_size_u_v = cur_pic->lcu_total * lcu_size*lcu_size/2;
+ int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
data32 = READ_VREG(HEVC_SAO_CTRL0);
data32 &= (~0xf);
@@ -3280,10 +2832,8 @@
WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
}
#endif
-
data32 = (mc_buffer_size_u_v_h << 16) << 1;
- /*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
- data32, mc_buffer_size_u_v_h, cur_pic->lcu_total);*/
+
WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
data32 = (mc_buffer_size_u_v_h << 16);
@@ -3294,13 +2844,13 @@
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
/*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (MEM_MAP_MODE << 12);
+ data32 |= (mem_map_mode << 12);
data32 &= (~0x3);
data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
/*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
+ * [31:24] ar_fifo1_axi_thread
+ * [23:16] ar_fifo0_axi_thread
* [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
* [11:08] axi_lendian_C
@@ -3323,14 +2873,14 @@
ata32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (MEM_MAP_MODE << 4);
+ data32 |= (mem_map_mode << 4);
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#else
/*m8baby test1902*/
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
/*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (MEM_MAP_MODE << 12);
+ data32 |= (mem_map_mode << 12);
data32 &= (~0xff0);
/*data32 |= 0x670;*/ /*Big-Endian per 64-bit*/
data32 |= 0x880; /*.Big-Endian per 64-bit */
@@ -3357,7 +2907,7 @@
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (MEM_MAP_MODE << 4);
+ data32 |= (mem_map_mode << 4);
data32 &= (~0xF);
data32 |= 0x8; /*Big-Endian per 64-bit*/
@@ -3368,9 +2918,12 @@
#else
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~(3 << 14));
- data32 |= (2 << 14); /* line align with 64*/
+ if (is_hevc_align32(mem_map_mode))
+ data32 |= (1 << 14);
+ else
+ data32 |= (2 << 14); /* line align with 64*/
data32 &= (~0x3000);
- data32 |= (MEM_MAP_MODE << 12); /* [13:12] axi_aformat, 0-Linear,
+ data32 |= (mem_map_mode << 12); /* [13:12] axi_aformat, 0-Linear,
1-32x32, 2-64x32 */
data32 &= (~0xff0);
#ifdef AVS2_10B_MMU_DW
@@ -3380,25 +2933,15 @@
data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
#endif
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
-#if 0
- if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
- if (get_double_write_mode(dec) == 0)
- data32 |= 0x2; /*disable double write*/
-#ifndef AVS2_10B_MMU
- else
- if (get_double_write_mode(dec) & 0x10)
- data32 |= 0x1; /*disable cm*/
-#endif
- }
-#endif
+
if (get_double_write_mode(dec) == 0)
data32 |= 0x2; /*disable double write*/
else if (get_double_write_mode(dec) & 0x10)
data32 |= 0x1; /*disable cm*/
/*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
+ * [31:24] ar_fifo1_axi_thread
+ * [23:16] ar_fifo0_axi_thread
* [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
* [11:08] axi_lendian_C
@@ -3447,7 +2990,6 @@
* [12] CbCr_byte_swap
* [31:13] reserved
*/
-
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
@@ -3456,7 +2998,10 @@
data32 |= (dec->endian & 0xf); /* valid only when double write only */
/*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
data32 &= (~(3 << 8));
- data32 |= (2 << 8); /* line align with 64 for dw only */
+ if (is_hevc_align32(mem_map_mode))
+ data32 |= (1 << 8);
+ else
+ data32 |= (2 << 8); /* line align with 64 for dw only */
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#endif
#ifndef AVS2_10B_NV21
@@ -3469,7 +3014,6 @@
}
#endif
#endif
-
}
static void reconstructCoefficients(struct AVS2Decoder_s *dec,
@@ -3480,18 +3024,11 @@
sum = 0;
for (i = 0; i < alfParam->num_coeff - 1; i++) {
sum += (2 * alfParam->coeffmulti[g][i]);
- dec->m_filterCoeffSym[g][i] =
- alfParam->coeffmulti[g][i];
- /*pr_info("[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n",
- g, i, dec->m_filterCoeffSym[g][i]);*/
+ dec->m_filterCoeffSym[g][i] = alfParam->coeffmulti[g][i];
}
coeffPred = (1 << ALF_NUM_BIT_SHIFT) - sum;
- dec->m_filterCoeffSym[g][alfParam->num_coeff - 1]
- = coeffPred +
- alfParam->coeffmulti[g][alfParam->num_coeff - 1];
- /*pr_info("[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n",
- g, (alfParam->num_coeff - 1),
- dec->m_filterCoeffSym[g][alfParam->num_coeff - 1]);*/
+ dec->m_filterCoeffSym[g][alfParam->num_coeff - 1] = coeffPred +
+ alfParam->coeffmulti[g][alfParam->num_coeff - 1];
}
}
@@ -3687,8 +3224,7 @@
dec->m_filterCoeffSym[i][7],
dec->m_filterCoeffSym[i][8]);
}
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgALF .done.\n");
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgALF .done.\n");
}
static void config_other_hw(struct AVS2Decoder_s *dec)
@@ -3737,7 +3273,7 @@
}
static u32 init_cuva_size;
-static int cuva_data_is_avaible(struct AVS2Decoder_s *dec)
+static int cuva_data_is_available(struct AVS2Decoder_s *dec)
{
u32 reg_val;
@@ -3767,10 +3303,10 @@
unsigned int cuva_count = 0;
int cuva_size = 0;
struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
- if (pic == NULL || 0 == cuva_data_is_avaible(dec)) {
+ if (pic == NULL || 0 == cuva_data_is_available(dec)) {
avs2_print(dec, AVS2_DBG_HDR_INFO,
- "%s:pic 0x%p or data not avaible\n",
- __func__, pic);
+ "%s:pic 0x%p or data not available\n",
+ __func__, pic);
return;
}
@@ -3780,8 +3316,8 @@
dec->hdr_flag |= HDR_CUVA_MASK;
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
- __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
+ "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
+ __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
if (cuva_size > 0 && cuva_count > 0) {
int new_size;
char *new_buf;
@@ -3808,9 +3344,8 @@
}
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "cuva: (size %d)\n",
- pic->cuva_data_size);
- if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) {
+ "cuva: (size %d)\n", pic->cuva_data_size);
+ if (get_dbg_flag(dec) & AVS2_DBG_HDR_INFO) {
for (i = 0; i < pic->cuva_data_size; i++) {
pr_info("%02x ", pic->cuva_data_buf[i]);
if (((i + 1) & 0xf) == 0)
@@ -3880,7 +3415,6 @@
WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
- //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
#ifdef AVS2_10B_MMU
WRITE_VREG(AVS2_MMU_MAP_BUFFER, dec->frame_mmu_map_phy_addr);
#else
@@ -3888,12 +3422,10 @@
#endif
#ifdef AVS2_10B_MMU_DW
if (dec->dw_mmu_enable) {
- //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
}
#endif
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
- //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
@@ -3913,14 +3445,8 @@
#ifdef LOSLESS_COMPRESS_MODE
data32 = READ_VREG(HEVC_SAO_CTRL5);
-#if 1
data32 &= ~(1<<9);
-#else
- if (params->p.bit_depth != 0x00)
- data32 &= ~(1<<9);
- else
- data32 |= (1<<9);
-#endif
+
WRITE_VREG(HEVC_SAO_CTRL5, data32);
#ifdef AVS2_10B_MMU
/*bit[4] : paged_mem_mode*/
@@ -3932,8 +3458,6 @@
WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
#endif
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));*/
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
/*8-bit mode */
WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
@@ -3944,21 +3468,16 @@
#ifdef AVS2_10B_MMU
WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start
- + VBH_BUF_SIZE(buf_spec));
- /*data32 = READ_VREG(HEVC_SAO_CTRL9);*/
- /*data32 |= 0x1;*/
- /*WRITE_VREG(HEVC_SAO_CTRL9, data32);*/
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + VBH_BUF_SIZE(buf_spec));
/* use HEVC_CM_HEADER_START_ADDR */
data32 = READ_VREG(HEVC_SAO_CTRL5);
data32 |= (1<<10);
-#if 1
+
if (debug & AVS2_DBG_FORCE_UNCOMPRESS)
data32 |= 0x80;
-#endif
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
#endif
#ifdef AVS2_10B_MMU_DW
@@ -4019,30 +3538,29 @@
unsigned int data32;
unsigned int decode_mode;
int i;
- /*if (debug & AVS2_DBG_BUFMGR_MORE)
- pr_info("%s\n", __func__);*/
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
-#if 1
- /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
- data32 &= ~(7 << 29);
- data32 |= (3 << 29);
-#endif
- data32 = data32 |
+
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+ /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+ data32 &= ~(7 << 29);
+ data32 |= (3 << 29);
+
+ data32 = data32 |
(1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
(1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
(1 << 7) |/*dec_done_int_cpu_enable*/
(1 << 4) |/*startcode_found_int_cpu_enable*/
(0 << 3) |/*startcode_found_int_amrisc_enable*/
- (1 << 0) /*parser_int_enable*/
- ;
+ (1 << 0); /*parser_int_enable*/
+
WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
data32 = READ_VREG(HEVC_SHIFT_STATUS);
data32 = data32 |
- (0 << 1) |/*emulation_check_off VP9
+ (0 << 1) |/*emulation_check_off VP9
do not have emulation*/
- (1 << 0)/*startcode_check_on*/
- ;
+ (1 << 0);/*startcode_check_on*/
+
WRITE_VREG(HEVC_SHIFT_STATUS, data32);
WRITE_VREG(HEVC_SHIFT_CONTROL,
(6 << 20) | /* emu_push_bits (6-bits for AVS2)*/
@@ -4054,21 +3572,15 @@
(3 << 6) | /* sft_valid_wr_position*/
(2 << 4) | /* emulate_code_length_sub_1*/
(2 << 1) | /* start_code_length_sub_1*/
- (1 << 0) /* stream_shift_enable*/
- );
+ (1 << 0)); /* stream_shift_enable*/
WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
(0 << 30) | /*data_protect_fill_00_enable*/
- (1 << 29) /*data_protect_fill_ff_enable*/
- );
- WRITE_VREG(HEVC_CABAC_CONTROL,
- (1 << 0)/*cabac_enable*/
- );
+ (1 << 29)); /*data_protect_fill_ff_enable*/
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
- (1 << 0)/* hevc_parser_core_clk_en*/
- );
+ WRITE_VREG(HEVC_CABAC_CONTROL, (1 << 0));/*cabac_enable*/
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0));/* hevc_parser_core_clk_en*/
WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
@@ -4149,14 +3661,6 @@
WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
#endif
- /*End of Multi-instance*/
- /*Changed to Start MPRED in microcode*/
- /*
- pr_info("[test.c] Start MPRED\n");
- WRITE_VREG(HEVC_MPRED_INT_STATUS,
- (1<<31)
- );
- */
/*AVS2 default seq_wq_matrix config*/
@@ -4177,17 +3681,12 @@
WRITE_VREG(HEVCD_IPP_TOP_CNTL,
(0 << 1) | /*enable ipp*/
- (1 << 0) /*software reset ipp and mpp*/
- );
+ (1 << 0)); /*software reset ipp and mpp*/
+
WRITE_VREG(HEVCD_IPP_TOP_CNTL,
(1 << 1) | /*enable ipp*/
- (0 << 0) /*software reset ipp and mpp*/
- );
-#if 0
-/*AVS2_10B_NV21*/
- /*Enable NV21 reference read mode for MC*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
+ (0 << 0)); /*software reset ipp and mpp*/
+
/* Init dblk*/
data32 = READ_VREG(HEVC_DBLK_CFGB);
data32 |= (2 << 0);
@@ -4268,14 +3767,14 @@
dec->rpm_ptr = NULL;
dec->lmem_ptr = NULL;
if (dec->rpm_addr) {
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(dec->rpm_mem_handle,
RPM_BUF_SIZE, dec->rpm_addr,
dec->rpm_phy_addr);
dec->rpm_addr = NULL;
}
if (dec->cuva_addr) {
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(dec->cuva_handle,
dec->cuva_size, dec->cuva_addr,
dec->cuva_phy_addr);
dec->cuva_addr = NULL;
@@ -4283,7 +3782,7 @@
if (dec->lmem_addr) {
if (dec->lmem_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(dec->lmem_phy_handle,
LMEM_BUF_SIZE, dec->lmem_addr,
dec->lmem_phy_addr);
dec->lmem_addr = NULL;
@@ -4292,7 +3791,7 @@
#ifdef AVS2_10B_MMU
if (dec->frame_mmu_map_addr) {
if (dec->frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(dec->frame_mmu_map_handle,
get_frame_mmu_map_size(dec), dec->frame_mmu_map_addr,
dec->frame_mmu_map_phy_addr);
dec->frame_mmu_map_addr = NULL;
@@ -4302,7 +3801,7 @@
#ifdef AVS2_10B_MMU_DW
if (dec->dw_frame_mmu_map_addr) {
if (dec->dw_frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
get_frame_mmu_map_size(dec), dec->dw_frame_mmu_map_addr,
dec->dw_frame_mmu_map_phy_addr);
dec->dw_frame_mmu_map_addr = NULL;
@@ -4360,8 +3859,7 @@
#ifdef AVS2_10B_MMU
avs2_bufmgr_init(dec, cur_buf_info, NULL);
#else
- dec->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff)
- & (~0xffff);
+ dec->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff) & (~0xffff);
dec->mc_buf_spec.buf_size = (dec->mc_buf_spec.buf_end
- dec->mc_buf_spec.buf_start);
if (debug) {
@@ -4401,15 +3899,14 @@
dec->used_buf_num = FRAME_BUFFERS;
#endif
dec->avs2_dec.ref_maxbuffer = dec->used_buf_num - 1;
- /*init_pic_list(dec);*/
pts_unstable = ((unsigned long)(dec->vavs2_amstream_dec_info.param)
& 0x40) >> 6;
if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
- dec->rpm_addr = dma_alloc_coherent(amports_get_dma_device(),
+ dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
RPM_BUF_SIZE,
- &dec->rpm_phy_addr, GFP_KERNEL);
+ &dec->rpm_phy_addr, "AVS2_RPM_BUF");
if (dec->rpm_addr == NULL) {
pr_err("%s: failed to alloc rpm buffer\n", __func__);
return -1;
@@ -4422,8 +3919,8 @@
if (cuva_buf_size > 0) {
dec->cuva_size = AUX_BUF_ALIGN(cuva_buf_size);
- dec->cuva_addr = dma_alloc_coherent(amports_get_dma_device(),
- dec->cuva_size, &dec->cuva_phy_addr, GFP_KERNEL);
+ dec->cuva_addr = decoder_dma_alloc_coherent(&dec->cuva_handle,
+ dec->cuva_size, &dec->cuva_phy_addr, "AVS2_CUVA_BUF");
avs2_print(dec, AVS2_DBG_BUFMGR,
"%s, cuva_size = %d cuva_phy_addr %x dec->cuva_addr = %px\n",
__func__, dec->cuva_size, (u32)dec->cuva_phy_addr, dec->cuva_addr);
@@ -4433,9 +3930,9 @@
}
}
- dec->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
+ dec->lmem_addr = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
LMEM_BUF_SIZE,
- &dec->lmem_phy_addr, GFP_KERNEL);
+ &dec->lmem_phy_addr, "AVS2_LMEM_BUF");
if (dec->lmem_addr == NULL) {
pr_err("%s: failed to alloc lmem buffer\n", __func__);
return -1;
@@ -4447,9 +3944,9 @@
#ifdef AVS2_10B_MMU
if (dec->mmu_enable) {
- dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
+ dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
get_frame_mmu_map_size(dec),
- &dec->frame_mmu_map_phy_addr, GFP_KERNEL);
+ &dec->frame_mmu_map_phy_addr, "AVS2_MMU_BUF");
if (dec->frame_mmu_map_addr == NULL) {
pr_err("%s: failed to alloc count_buffer\n", __func__);
return -1;
@@ -4460,9 +3957,9 @@
#ifdef AVS2_10B_MMU_DW
if (dec->dw_mmu_enable) {
- dec->dw_frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
+ dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
get_frame_mmu_map_size(dec),
- &dec->dw_frame_mmu_map_phy_addr, GFP_KERNEL);
+ &dec->dw_frame_mmu_map_phy_addr, "AVS2_DWMMU_BUF");
if (dec->dw_frame_mmu_map_addr == NULL) {
pr_err("%s: failed to alloc count_buffer\n", __func__);
return -1;
@@ -4482,7 +3979,6 @@
#define CMD_FRAME_DISPLAY 3
#define CMD_DEBUG 10
-
#define DECODE_BUFFER_NUM_MAX 32
#define DISPLAY_BUFFER_NUM 6
@@ -4509,7 +4005,10 @@
canvas_h = pic->pic_h /
get_double_write_ratio(pic->double_write_mode);
/*sao_crtl1 aligned with 64*/
- canvas_w = ALIGN(canvas_w, 64);
+ if (is_hevc_align32(blkmode))
+ canvas_w = ALIGN(canvas_w, 32);
+ else
+ canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
if (vdec->parallel_dec == 1) {
@@ -4624,6 +4123,7 @@
vf->sidebind_type = dec->sidebind_type;
vf->sidebind_channel_id = dec->sidebind_channel_id;
+ vf->codec_vfmt = VFORMAT_AVS2;
return;
}
@@ -4656,7 +4156,7 @@
if (kfifo_len(&dec->display_q) > VF_POOL_SIZE) {
avs2_print(dec, AVS2_DBG_BUFMGR,
- "kfifo len:%d invaild, peek error\n",
+ "kfifo len:%d invalid, peek error\n",
kfifo_len(&dec->display_q));
return NULL;
}
@@ -4676,8 +4176,8 @@
pic = dec->avs2_dec.m_bg;
else if (index >= 0 && index < dec->used_buf_num) {
for (i = 0; i < dec->used_buf_num; i++) {
- if (dec->avs2_dec.fref[i]->index == index)
- pic = dec->avs2_dec.fref[i];
+ if (dec->avs2_dec.frm_pool[i].index == index)
+ pic = &dec->avs2_dec.frm_pool[i];
}
}
return pic;
@@ -4713,6 +4213,8 @@
if (kfifo_get(&dec->display_q, &vf)) {
uint8_t index = vf->index & 0xff;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
ATRACE_COUNTER(dec->disp_q_name, kfifo_len(&dec->display_q));
if (index < dec->used_buf_num) {
struct avs2_frame_s *pic = get_pic_by_index(dec, index);
@@ -4720,8 +4222,8 @@
(debug & AVS2_DBG_PIC_LEAK)) {
int i;
avs2_print(dec, 0,
- "%s error index 0x%x pic not exist\n",
- __func__, index);
+ "%s error index 0x%x pic not exist\n",
+ __func__, index);
dump_pic_list(dec);
for (i = 0; i < 10; i++) {
pic = get_pic_by_index(dec, index);
@@ -4732,17 +4234,30 @@
debug |= AVS2_DBG_PIC_LEAK_WAIT;
return NULL;
}
+
+ vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+ vf->vf_ud_param.ud_param.buf_len = 0;
+ vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+ vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+ vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+ vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS2 << 3);
+ vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+ if (vf->pts)
+ vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+ vf->omx_index = dec->vf_get_count;
dec->vf_get_count++;
if (pic)
avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n",
- __func__, index,
- pic->imgtr_fwRefDistance_bak,
- dec->vf_get_count,
- vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64);
+ "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n",
+ __func__, index,
+ pic->imgtr_fwRefDistance_bak,
+ dec->vf_get_count,
+ vf->type,
+ vf->width, vf->height,
+ vf->pts,
+ vf->pts_us64);
return vf;
}
}
@@ -4752,7 +4267,11 @@
static void vavs2_vf_put(struct vframe_s *vf, void *op_arg)
{
struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+ struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
uint8_t index;
+ unsigned long flags = 0;
if (vf == (&dec->vframe_dummy))
return;
@@ -4760,6 +4279,7 @@
if (!vf)
return;
+ lock_buffer(dec, flags);
index = vf->index & 0xff;
kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
@@ -4771,11 +4291,8 @@
dec->vf_put_count);
if (index < dec->used_buf_num) {
- unsigned long flags;
- struct avs2_frame_s *pic;
+ struct avs2_frame_s *pic = get_pic_by_index(dec, index);
- lock_buffer(dec, flags);
- pic = get_pic_by_index(dec, index);
if (pic && pic->vf_ref > 0)
pic->vf_ref--;
else {
@@ -4793,9 +4310,12 @@
0x1);
dec->last_put_idx = index;
dec->new_frame_displayed++;
- unlock_buffer(dec, flags);
}
+ unlock_buffer(dec, flags);
+#ifdef MULTI_INSTANCE_SUPPORT
+ vdec_up(vdec);
+#endif
}
static int vavs2_event_cb(int type, void *data, void *private_data)
@@ -4814,7 +4334,7 @@
(struct provider_aux_req_s *)data;
unsigned char index;
unsigned long flags;
- struct avs2_frame_s *pic;
+ struct avs2_frame_s *pic = NULL;
if (!req->vf) {
req->aux_size = dec->vf_put_count;
@@ -4833,8 +4353,8 @@
unlock_buffer(dec, flags);
avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s pic 0x%p index %d =>size %d\n",
- __func__, pic, index, req->aux_size);
+ "%s pic 0x%p index %d =>size %d\n",
+ __func__, pic, index, req->aux_size);
}
return 0;
@@ -4859,11 +4379,8 @@
pic->to_prepare_disp = 0;
return pic;
-
}
-
-
static void fill_frame_info(struct AVS2Decoder_s *dec,
struct avs2_frame_s *pic, unsigned int framesize, unsigned int pts)
{
@@ -4871,13 +4388,12 @@
if (pic->slice_type == I_IMG)
vframe_qos->type = 1;
- else if (pic->slice_type == P_IMG)
+ else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG))
vframe_qos->type = 2;
else if (pic->slice_type == B_IMG)
vframe_qos->type = 3;
-/*
-#define SHOW_QOS_INFO
-*/
+
if (input_frame_based(hw_to_vdec(dec)))
vframe_qos->size = pic->frame_size;
else
@@ -4887,15 +4403,14 @@
avs2_print(dec, 0, "slice:%d\n", pic->slice_type);
#endif
-
vframe_qos->max_mv = pic->max_mv;
vframe_qos->avg_mv = pic->avg_mv;
vframe_qos->min_mv = pic->min_mv;
#ifdef SHOW_QOS_INFO
avs2_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
+ vframe_qos->max_mv,
+ vframe_qos->avg_mv,
+ vframe_qos->min_mv);
#endif
vframe_qos->max_qp = pic->max_qp;
@@ -4903,9 +4418,9 @@
vframe_qos->min_qp = pic->min_qp;
#ifdef SHOW_QOS_INFO
avs2_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
+ vframe_qos->max_qp,
+ vframe_qos->avg_qp,
+ vframe_qos->min_qp);
#endif
vframe_qos->max_skip = pic->max_skip;
@@ -4913,9 +4428,9 @@
vframe_qos->min_skip = pic->min_skip;
#ifdef SHOW_QOS_INFO
avs2_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
+ vframe_qos->max_skip,
+ vframe_qos->avg_skip,
+ vframe_qos->min_skip);
#endif
vframe_qos->num++;
@@ -4926,11 +4441,11 @@
struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy)
{
unsigned long flags;
- int stream_offset;
+ u32 stream_offset = pic->stream_offset;
unsigned int frame_size = 0;
int pts_discontinue;
struct vdec_s *vdec = hw_to_vdec(dec);
- stream_offset = pic->stream_offset;
+
avs2_print(dec, AVS2_DBG_BUFMGR,
"%s index = %d pos = %d\r\n",
__func__, pic->index,
@@ -4948,9 +4463,7 @@
vf->pts_us64 = pic->pts64;
} else {
#endif
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
- stream_offset, &vf->pts, 0) != 0) { */
+ if (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
if (pts_lookup_offset_us64
(PTS_TYPE_VIDEO, stream_offset,
&vf->pts, &frame_size, 0,
@@ -4982,14 +4495,12 @@
if (dec->pts_mode_switching_count >=
PTS_MODE_SWITCHING_THRESHOLD) {
- dec->pts_mode =
- PTS_NONE_REF_USE_DURATION;
- pr_info
- ("HEVC: switch to n_d mode.\n");
+ dec->pts_mode = PTS_NONE_REF_USE_DURATION;
+ pr_info("HEVC: switch to n_d mode.\n");
}
} else {
- int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD;
+ int p = PTS_MODE_SWITCHING_RECOVERY_THRESHOLD;
dec->pts_mode_recovery_count++;
if (dec->pts_mode_recovery_count > p) {
dec->pts_mode_switching_count = 0;
@@ -4998,8 +4509,7 @@
}
}
- pts_discontinue =
- (abs(dec->last_pts - vf->pts) >=
+ pts_discontinue = (abs(dec->last_pts - vf->pts) >=
tsync_vpts_discontinuity_margin());
if (vf->pts != 0)
@@ -5017,15 +4527,11 @@
if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
&& ((pic->slice_type != I_IMG) || (!pts_discontinue &&
!first_pts_checkin_complete(PTS_TYPE_AUDIO)))) {
- vf->pts_us64 =
- dec->last_pts_us64 +
+ vf->pts_us64 = dec->last_pts_us64 +
(DUR2PTS(dec->frame_dur) * 100 / 9);
}
dec->last_pts_us64 = vf->pts_us64;
- avs2_print(dec, AVS2_DBG_OUT_PTS,
- "avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n",
- vf->pts, vf->pts_us64);
}
vf->index = 0xff00 | pic->index;
@@ -5052,7 +4558,6 @@
}
}
#endif
-
#else
vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
@@ -5060,8 +4565,7 @@
}
if (pic->double_write_mode &&
((pic->double_write_mode & 0x20) == 0)) {
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD;
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
vf->type |= VIDTYPE_VIU_NV21;
if (pic->double_write_mode == 3) {
vf->type |= VIDTYPE_COMPRESS;
@@ -5073,15 +4577,11 @@
if (dec->m_ins_flag) {
vf->canvas0Addr = vf->canvas1Addr = -1;
vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic->canvas_config[0];
- vf->canvas0_config[1] =
- pic->canvas_config[1];
+ vf->canvas0_config[0] = pic->canvas_config[0];
+ vf->canvas0_config[1] = pic->canvas_config[1];
- vf->canvas1_config[0] =
- pic->canvas_config[0];
- vf->canvas1_config[1] =
- pic->canvas_config[1];
+ vf->canvas1_config[0] = pic->canvas_config[0];
+ vf->canvas1_config[1] = pic->canvas_config[1];
} else
#endif
@@ -5111,17 +4611,17 @@
break;
}
if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
+ vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
if (pic->bit_depth == AVS2_BITS_8)
vf->bitdepth |= BITDEPTH_SAVING_MODE;
+ vf->type_original = vf->type;
set_frame_info(dec, vf);
- /* if((vf->width!=pic->width)|
- (vf->height!=pic->height)) */
- /* pr_info("aaa: %d/%d, %d/%d\n",
- vf->width,vf->height, pic->width,
- pic->height); */
+
+ if (dec->high_bandwidth_flag) {
+ vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH;
+ }
+
vf->width = pic->pic_w /
get_double_write_ratio(pic->double_write_mode);
vf->height = pic->pic_h /
@@ -5134,11 +4634,9 @@
((pic->double_write_mode & 0xf) == 2 ||
(pic->double_write_mode & 0xf) == 4)) {
vf->compWidth = pic->pic_w /
- get_double_write_ratio(
- pic->double_write_mode & 0xf);
+ get_double_write_ratio(pic->double_write_mode & 0xf);
vf->compHeight = pic->pic_h /
- get_double_write_ratio(
- pic->double_write_mode & 0xf);
+ get_double_write_ratio(pic->double_write_mode & 0xf);
} else {
vf->compWidth = pic->pic_w;
vf->compHeight = pic->pic_h;
@@ -5155,12 +4653,10 @@
#ifdef AVS2_10B_MMU_DW
if (pic->double_write_mode & 0x20) {
vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- dec->dw_mmu_box, pic->index);
+ decoder_mmu_box_get_mem_handle(dec->dw_mmu_box, pic->index);
vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
+ decoder_bmmu_box_get_mem_handle(dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->BUF_index));
vf->mem_dw_handle = NULL;
} else
#endif
@@ -5171,6 +4667,13 @@
vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
dec->bmmu_box,
HEADER_BUFFER_IDX(pic->index));
+ if (dec->double_write_mode == 3)
+ vf->mem_dw_handle =
+ decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->BUF_index));
+ else
+ vf->mem_dw_handle = NULL;
}
} else {
vf->mem_handle = decoder_bmmu_box_get_mem_handle(
@@ -5185,10 +4688,44 @@
dec->bmmu_box,
VF_BUFFER_IDX(pic->index));
#endif
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- vf->pts_us64 = stream_offset;
+
+ if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+ /* offset for tsplayer pts lookup */
+ u64 frame_type = 0;
+ if (pic->slice_type == I_IMG)
+ frame_type = KEYFRAME_FLAG;
+ else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG))
+ frame_type = PFRAME_FLAG;
+ else
+ frame_type = BFRAME_FLAG;
+ vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ /* lookup by decoder */
+ checkout_pts_offset pts_info;
+ u64 frame_type = 0;
+ if (pic->slice_type == I_IMG)
+ frame_type = KEYFRAME_FLAG;
+ else if (pic->slice_type == P_IMG)
+ frame_type = PFRAME_FLAG;
+ else
+ frame_type = BFRAME_FLAG;
+ pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
}
+ avs2_print(dec, AVS2_DBG_OUT_PTS,
+ "avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld(0x%llx) slice_type %d, duration %d\n",
+ vf->pts, vf->pts_us64, vf->pts_us64, pic->slice_type, vf->duration);
+
if (!dummy) {
lock_buffer(dec, flags);
pic->vf_ref = 1;
@@ -5232,9 +4769,7 @@
}
if (pic->error_mark) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "!!!error pic, skip\n",
- 0);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "!!!error pic, skip\n", 0);
continue;
}
@@ -5242,8 +4777,7 @@
if (dec->skip_PB_before_I &&
pic->slice_type != I_IMG) {
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "!!!slice type %d (not I) skip\n",
- 0, pic->slice_type);
+ "!!!slice type %d (not I) skip\n", 0, pic->slice_type);
continue;
}
dec->skip_PB_before_I = 0;
@@ -5256,7 +4790,7 @@
if (vf) {
struct vdec_info tmp4x;
- int stream_offset = pic->stream_offset;
+ u32 stream_offset = pic->stream_offset;
set_vframe(dec, vf, pic, 0);
decoder_do_frame_check(pvdec, vf);
vdec_vframe_ready(pvdec, vf);
@@ -5267,16 +4801,7 @@
dec_update_gvs(dec);
/*count info*/
- vdec_count_info(dec->gvs, 0, stream_offset);
- if (stream_offset) {
- if (pic->slice_type == I_IMG) {
- dec->gvs->i_decoded_frames++;
- } else if (pic->slice_type == P_IMG) {
- dec->gvs->p_decoded_frames++;
- } else if (pic->slice_type == B_IMG) {
- dec->gvs->b_decoded_frames++;
- }
- }
+ vdec_count_info(dec->gvs, 2, stream_offset);
memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info));
tmp4x.bit_depth_luma = bit_depth_luma;
tmp4x.bit_depth_chroma = bit_depth_chroma;
@@ -5304,10 +4829,8 @@
for (i = 0; i < (RPM_END - RPM_BEGIN); i++) {
do {
data32 = READ_VREG(RPM_CMD_REG);
- /*pr_info("%x\n", data32);*/
} while ((data32 & 0x10000) == 0);
params->l.data[i] = data32&0xffff;
- /*pr_info("%x\n", data32);*/
WRITE_VREG(RPM_CMD_REG, 0);
}
if (debug & AVS2_DBG_BUFMGR)
@@ -5362,35 +4885,23 @@
if (dec->process_state ==
PROC_STATE_DECODING) {
dec->process_state =
- PROC_STATE_DECODE_AGAIN;
+ PROC_STATE_DECODE_AGAIN;
} else if (dec->process_state ==
PROC_STATE_HEAD_DONE) {
dec->process_state =
- PROC_STATE_HEAD_AGAIN;
+ PROC_STATE_HEAD_AGAIN;
}
dec->next_again_flag = 1;
reset_process_time(dec);
vdec_schedule_work(&dec->work);
}
-static uint32_t log2i(uint32_t val)
-{
- uint32_t ret = -1;
- while (val != 0) {
- val >>= 1;
- ret++;
- }
- return ret;
-}
-
static void check_pic_error(struct AVS2Decoder_s *dec,
struct avs2_frame_s *pic)
{
- if (pic->decoded_lcu == 0) {
- pic->decoded_lcu =
- (READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff) + 1;
- }
+ if (pic == NULL)
+ return ;
+
if (pic->decoded_lcu != dec->avs2_dec.lcu_total) {
avs2_print(dec, AVS2_DBG_BUFMGR,
"%s error pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
@@ -5457,7 +4968,6 @@
tmp = tmp / 2;
dec->frame_dur = div_u64(96000ULL, tmp);
dec->get_frame_dur = true;
- /*avs2_print(dec, 0, "avs2 frame_dur:%d,progressive:%d\n", dec->frame_dur, params->p.progressive_sequence);*/
return 0;
}
@@ -5484,10 +4994,6 @@
local_clock() - vdec->mvfrm->hw_decode_start;
}
-/*
-#define DEBUG_QOS
-*/
-
if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
unsigned char a[3];
unsigned char i, j, t;
@@ -5546,7 +5052,6 @@
avs2_print(dec, 0, "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
#endif
-
data = READ_VREG(HEVC_SKIP_INFO);
a[0] = data & 0x1f;
a[1] = (data >> 8) & 0x3f;
@@ -5591,7 +5096,6 @@
#ifdef DEBUG_QOS
int pic_number = 0;
#endif
-
picture->max_mv = 0;
picture->avg_mv = 0;
picture->min_mv = 0;
@@ -5603,9 +5107,6 @@
picture->max_qp = 0;
picture->avg_qp = 0;
picture->min_qp = 0;
-
-
-
#ifdef DEBUG_QOS
avs2_print(dec, 0, "slice_type:%d, poc:%d\n",
picture->slice_type,
@@ -5709,21 +5210,21 @@
rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
#ifdef DEBUG_QOS
avs2_print(dec, 0, "[Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
+ pic_number, (rdata32>>0) & 0xff);
#endif
- picture->min_qp = (rdata32>>0)&0xff;
+ picture->min_qp = (rdata32>>0) & 0xff;
#ifdef DEBUG_QOS
avs2_print(dec, 0, "[Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
+ pic_number, (rdata32>>8) & 0xff);
#endif
- picture->max_qp = (rdata32>>8)&0xff;
+ picture->max_qp = (rdata32>>8) & 0xff;
#ifdef DEBUG_QOS
avs2_print(dec, 0, "[Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
+ pic_number, (rdata32>>16) & 0xff);
avs2_print(dec, 0, "[Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
+ pic_number, (rdata32>>24) & 0xff);
#endif
/* blk22_mv_count */
@@ -5845,7 +5346,6 @@
avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n",
pic_number, mv_hi);
-
mv_lo = (rdata32>>0)&0xffff;
if (mv_lo & 0x8000)
mv_lo = 0x8000 - mv_lo;
@@ -5853,7 +5353,6 @@
avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n",
pic_number, mv_lo);
-
/* {mvx_L1_max, mvx_L1_min} */
rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
mv_hi = (rdata32>>16)&0xffff;
@@ -5863,7 +5362,6 @@
avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n",
pic_number, mv_hi);
-
mv_lo = (rdata32>>0)&0xffff;
if (mv_lo & 0x8000)
mv_lo = 0x8000 - mv_lo;
@@ -5871,7 +5369,6 @@
avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n",
pic_number, mv_lo);
-
/* {mvy_L1_max, mvy_L1_min} */
rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
mv_hi = (rdata32>>16)&0xffff;
@@ -5907,10 +5404,6 @@
int i, ret;
int32_t start_code = 0;
- /*if (dec->wait_buf)
- pr_info("set wait_buf to 0\r\n");
- */
-
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
"%s decode_status 0x%x process_state %d lcu 0x%x\n",
__func__, dec_status, dec->process_state,
@@ -5943,54 +5436,16 @@
if (dec->m_ins_flag) {
set_cuva_data(dec);
update_decoded_pic(dec);
+ check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
get_picture_qos_info(dec);
reset_process_time(dec);
dec->dec_result = DEC_RESULT_DONE;
amhevc_stop();
-#if 0 /*def AVS2_10B_MMU*/
- if (dec->m_ins_flag) {
- /*avs2_recycle_mmu_buf_tail(dec);*/
- dec->used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- }
-#endif
-
-#if 0
- /*keep hardware state*/
- WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
- WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
- dec->mpred_abv_start_addr =
- READ_VREG(HEVC_MPRED_ABV_START_ADDR);
- /**/
-#endif
vdec_schedule_work(&dec->work);
}
goto irq_handled_exit;
}
PRINT_LINE();
-#if 0
- if (dec_status == AVS2_EOS) {
- if (dec->m_ins_flag)
- reset_process_time(dec);
-
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "AVS2_EOS, flush buffer\r\n");
-
- avs2_post_process(&dec->avs2_dec);
- avs2_prepare_display_buf(dec);
-
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "send AVS2_10B_DISCARD_NAL\r\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
- if (dec->m_ins_flag) {
- update_decoded_pic(dec);
- dec->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&dec->work);
- }
- goto irq_handled_exit;
- } else
-#endif
if (dec_status == AVS2_DECODE_OVER_SIZE) {
avs2_print(dec, 0,
"avs2 decode oversize !!\n");
@@ -6017,13 +5472,17 @@
start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
if (dec->process_state ==
- PROC_STATE_HEAD_AGAIN
- ) {
+ PROC_STATE_HEAD_AGAIN) {
if ((start_code == I_PICTURE_START_CODE)
|| (start_code == PB_PICTURE_START_CODE)) {
avs2_print(dec, 0,
"PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n",
start_code);
+ if (dec->m_ins_flag) {
+ dec->dec_result = DEC_RESULT_DONE;
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
goto irq_handled_exit;
} else {
avs2_print(dec, AVS2_DBG_BUFMGR,
@@ -6031,10 +5490,12 @@
start_code);
dec->process_state = PROC_STATE_HEAD_DONE;
WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
goto irq_handled_exit;
}
} else if (dec->process_state ==
- PROC_STATE_DECODE_AGAIN) {
+ PROC_STATE_DECODE_AGAIN) {
if ((start_code == I_PICTURE_START_CODE)
|| (start_code == PB_PICTURE_START_CODE)) {
avs2_print(dec, AVS2_DBG_BUFMGR,
@@ -6046,6 +5507,8 @@
"PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
start_code);
WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
goto irq_handled_exit;
}
}
@@ -6061,7 +5524,6 @@
#ifdef AVS2_10B_MMU
avs2_recycle_mmu_buf_tail(dec);
#endif
- check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
avs2_post_process(&dec->avs2_dec);
if (debug & AVS2_DBG_PRINT_PIC_LIST)
@@ -6077,11 +5539,10 @@
pic->is_output == -1 &&
pic->mmu_alloc_flag &&
pic->vf_ref == 0) {
- if (pic->refered_by_others == 0) {
+ if (pic->referred_by_others == 0) {
#ifdef AVS2_10B_MMU
pic->mmu_alloc_flag = 0;
- /*release_buffer_4k(
- dec->avs2_dec.fref[ii]->index);*/
+
decoder_mmu_box_free_idx(dec->mmu_box,
pic->index);
#endif
@@ -6128,36 +5589,29 @@
debug_buffer_mgr_more(dec);
get_frame_rate(&dec->avs2_dec.param, dec);
-#if 1 // The video_signal_type is type of uint16_t and result false, so comment it out.
- if (dec->avs2_dec.param.p.video_signal_type
- & (1<<30)) {
+ if (dec->avs2_dec.param.p.video_signal_type & (1<<14)) {
union param_u *pPara;
- avs2_print(dec, 0,
- "avs2 HDR meta data present\n");
+ avs2_print(dec, AVS2_DBG_HDR_INFO, "avs2 HDR meta data present\n");
pPara = &dec->avs2_dec.param;
/*clean this flag*/
- pPara->p.video_signal_type
- &= ~(1<<30);
+ pPara->p.video_signal_type &= ~(1<<14);
dec->vf_dp.present_flag = 1;
- dec->vf_dp.white_point[0]
- = pPara->p.white_point_x;
+ dec->vf_dp.white_point[0] = pPara->p.white_point_x;
avs2_print(dec, AVS2_DBG_HDR_INFO,
"white_point[0]:0x%x\n",
dec->vf_dp.white_point[0]);
- dec->vf_dp.white_point[1]
- = pPara->p.white_point_y;
+ dec->vf_dp.white_point[1] = pPara->p.white_point_y;
avs2_print(dec, AVS2_DBG_HDR_INFO,
"white_point[1]:0x%x\n",
dec->vf_dp.white_point[1]);
for (i = 0; i < 3; i++) {
- dec->vf_dp.primaries[i][0]
- = pPara->p.display_primaries_x[i];
+ dec->vf_dp.primaries[i][0] = pPara->p.display_primaries_x[i];
avs2_print(dec, AVS2_DBG_HDR_INFO,
"primaries[%d][0]:0x%x\n",
i,
@@ -6165,31 +5619,26 @@
}
for (i = 0; i < 3; i++) {
- dec->vf_dp.primaries[i][1]
- = pPara->p.display_primaries_y[i];
+ dec->vf_dp.primaries[i][1] = pPara->p.display_primaries_y[i];
avs2_print(dec, AVS2_DBG_HDR_INFO,
"primaries[%d][1]:0x%x\n",
i,
dec->vf_dp.primaries[i][1]);
}
- dec->vf_dp.luminance[0]
- = pPara->p.max_display_mastering_luminance;
+ dec->vf_dp.luminance[0] = pPara->p.max_display_mastering_luminance;
avs2_print(dec, AVS2_DBG_HDR_INFO,
"luminance[0]:0x%x\n",
dec->vf_dp.luminance[0]);
- dec->vf_dp.luminance[1]
- = pPara->p.min_display_mastering_luminance;
+ dec->vf_dp.luminance[1] = pPara->p.min_display_mastering_luminance;
avs2_print(dec, AVS2_DBG_HDR_INFO,
"luminance[1]:0x%x\n",
dec->vf_dp.luminance[1]);
- dec->vf_dp.content_light_level.present_flag
- = 1;
- dec->vf_dp.content_light_level.max_content
- = pPara->p.max_content_light_level;
+ dec->vf_dp.content_light_level.present_flag = 1;
+ dec->vf_dp.content_light_level.max_content = pPara->p.max_content_light_level;
avs2_print(dec, AVS2_DBG_HDR_INFO,
"max_content:0x%x\n",
dec->vf_dp.content_light_level.max_content);
@@ -6201,8 +5650,6 @@
"max_pic_average:0x%x\n",
dec->vf_dp.content_light_level.max_pic_average);
}
-#endif
-
if (dec->video_ori_signal_type !=
((dec->avs2_dec.param.p.video_signal_type << 16)
@@ -6218,7 +5665,7 @@
" %s %s\n",
video_format_names[(v >> 10) & 7],
((v >> 9) & 1) ?
- "full_range" : "limited");
+ "full_range" : "limited");
if (v & 0x100) {
u32 transfer;
u32 maxtrix;
@@ -6226,14 +5673,11 @@
avs2_print(dec, AVS2_DBG_HDR_INFO,
"color_description present:\n");
avs2_print(dec, AVS2_DBG_HDR_INFO,
- "color_primarie = %d\n",
- v & 0xff);
+ "color_primarie = %d\n", v & 0xff);
avs2_print(dec, AVS2_DBG_HDR_INFO,
- "transfer_characteristic = %d\n",
- (c >> 8) & 0xff);
+ "transfer_characteristic = %d\n", (c >> 8) & 0xff);
avs2_print(dec, AVS2_DBG_HDR_INFO,
- " matrix_coefficient = %d\n",
- c & 0xff);
+ " matrix_coefficient = %d\n", c & 0xff);
transfer = (c >> 8) & 0xFF;
if (transfer >= 15)
@@ -6266,30 +5710,15 @@
}
if (enable_force_video_signal_type)
- dec->video_signal_type
- = force_video_signal_type;
+ dec->video_signal_type = force_video_signal_type;
else {
- dec->video_signal_type
- = (v << 16) | convert_c;
-
- dec->video_ori_signal_type
- = (v << 16) | c;
+ dec->video_signal_type = (v << 16) | convert_c;
+ dec->video_ori_signal_type = (v << 16) | c;
}
video_signal_type = dec->video_signal_type;
}
}
-#if 0
- if ((debug_again & 0x4) &&
- dec->process_state ==
- PROC_STATE_INIT) {
- if (start_code == PB_PICTURE_START_CODE) {
- dec->process_state = PROC_STATE_TEST1;
- dec_again_process(dec);
- goto irq_handled_exit;
- }
- }
-#endif
PRINT_LINE();
avs2_prepare_header(&dec->avs2_dec, start_code);
@@ -6301,24 +5730,23 @@
dec->start_decoding_flag |= 0x1;
dec->process_state = PROC_STATE_HEAD_DONE;
WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
} else if (start_code == I_PICTURE_START_CODE ||
start_code == PB_PICTURE_START_CODE) {
ret = 0;
if (dec->pic_list_init_flag == 0) {
- int32_t lcu_size_log2 =
- log2i(dec->avs2_dec.param.p.lcu_size);
-
avs2_init_global_buffers(&dec->avs2_dec);
/*avs2_dec->m_bg->index is
set to dec->used_buf_num - 1*/
- init_pic_list(dec, lcu_size_log2);
+ init_pic_list(dec);
init_pic_list_hw(dec);
}
ret = avs2_process_header(&dec->avs2_dec);
if (!dec->m_ins_flag)
dec->slice_idx++;
- if (dec->m_ins_flag && ret
+ if (dec->m_ins_flag && ret > 0
&& dec->avs2_dec.hc.cur_pic->cuva_data_buf != NULL)
release_cuva_data(dec->avs2_dec.hc.cur_pic);
@@ -6377,63 +5805,93 @@
dec->avs2_dec.hc.cur_pic->pic_w,
dec->avs2_dec.hc.cur_pic->pic_h);
int i = dec->avs2_dec.hc.cur_pic->index;
- /*if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- mv_buf_size = 0x120000 * 4;*/
+
if (decoder_bmmu_box_alloc_buf_phy
(dec->bmmu_box,
MV_BUFFER_IDX(i),
mv_buf_size,
DRIVER_NAME,
- &buf_addr) < 0)
+ &buf_addr) < 0) {
ret = -1;
- else
- dec->avs2_dec.hc.cur_pic->
- mpred_mv_wr_start_addr
- = buf_addr;
+ } else {
+ dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr = buf_addr;
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr,
+ 0, mv_buf_size);
+ }
}
#endif
if (ret < 0) {
avs2_print(dec, AVS2_DBG_BUFMGR,
- "avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n",
- ret);
+ "avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n", ret);
WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
#ifdef AVS2_10B_MMU
if (dec->mmu_enable)
avs2_recycle_mmu_buf(dec);
#endif
if (dec->m_ins_flag) {
- dec->dec_result = DEC_RESULT_DONE;
+ int slice_type = 0;
+ struct avs2_frame_s *cur_pic = dec->avs2_dec.hc.cur_pic;
+
+ if (cur_pic != NULL) {
+ slice_type = cur_pic->slice_type;
+ } else {
+ slice_type = dec->avs2_dec.img.type;
+ }
+
+ dec->gvs->frame_count++;
+ dec->gvs->drop_frame_count++;
+ dec->gvs->error_frame_count++;
+
+ if (slice_type == I_IMG) {
+ dec->gvs->i_lost_frames++;
+ dec->gvs->i_concealed_frames++;
+ dec->gvs->i_decoded_frames++;
+ } else if ((slice_type == P_IMG) ||
+ (slice_type == F_IMG)) {
+ dec->gvs->p_lost_frames++;
+ dec->gvs->p_concealed_frames++;
+ dec->gvs->p_decoded_frames++;
+ } else if (slice_type == B_IMG) {
+ dec->gvs->b_lost_frames++;
+ dec->gvs->b_concealed_frames++;
+ dec->gvs->b_decoded_frames++;
+ }
+
+ dec->dec_result = DEC_RESULT_ERROR;
amhevc_stop();
vdec_schedule_work(&dec->work);
}
goto irq_handled_exit;
} else {
- PRINT_LINE();
- dec->avs2_dec.hc.cur_pic->stream_offset =
- READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- /*
- struct PIC_BUFFER_CONFIG_s *cur_pic
- = &cm->cur_frame->buf;
- cur_pic->decode_idx = dec->frame_count;
- */
+ struct avs2_frame_s *cur_pic = dec->avs2_dec.hc.cur_pic;
+
+ if (cur_pic != NULL) {
+ dec->gvs->frame_count++;
+ if (cur_pic->slice_type == I_IMG) {
+ dec->gvs->i_decoded_frames++;
+ } else if ((cur_pic->slice_type == P_IMG) ||
+ (cur_pic->slice_type == F_IMG)) {
+ dec->gvs->p_decoded_frames++;
+ } else if (cur_pic->slice_type == B_IMG) {
+ dec->gvs->b_decoded_frames++;
+ }
+ }
+
+ cur_pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
if (!dec->m_ins_flag) {
dec->frame_count++;
- decode_frame_count[dec->index]
- = dec->frame_count;
+ decode_frame_count[dec->index] = dec->frame_count;
}
/*MULTI_INSTANCE_SUPPORT*/
if (dec->chunk) {
- dec->avs2_dec.hc.cur_pic->pts =
- dec->chunk->pts;
- dec->avs2_dec.hc.cur_pic->pts64 =
- dec->chunk->pts64;
+ cur_pic->pts = dec->chunk->pts;
+ cur_pic->pts64 = dec->chunk->pts64;
}
/**/
- dec->avs2_dec.hc.cur_pic->bit_depth
- = dec->avs2_dec.input.sample_bit_depth;
- dec->avs2_dec.hc.cur_pic->double_write_mode
- = get_double_write_mode(dec);
+ cur_pic->bit_depth = dec->avs2_dec.input.sample_bit_depth;
+ cur_pic->double_write_mode = get_double_write_mode(dec);
decode_slice:
PRINT_LINE();
@@ -6449,14 +5907,13 @@
"=>fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, dis2/dis3/dis4 %d %d %d img->tr %d\n",
dec->avs2_dec.fref[0]->imgtr_fwRefDistance,
dec->avs2_dec.fref[1]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[2]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[3]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[4]->imgtr_fwRefDistance,
- dec->avs2_dec.img.tr);
+ dec->avs2_dec.fref[2]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[3]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[4]->imgtr_fwRefDistance,
+ dec->avs2_dec.img.tr);
if ((debug_again & 0x2) &&
- dec->process_state ==
- PROC_STATE_INIT) {
+ dec->process_state == PROC_STATE_INIT) {
dec->process_state = PROC_STATE_DECODING;
dec_again_process(dec);
goto irq_handled_exit;
@@ -6505,8 +5962,7 @@
READ_VREG(HEVC_STREAM_END_ADDR),
READ_VREG(HEVC_STREAM_LEVEL),
READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR)
- );
+ READ_VREG(HEVC_STREAM_RD_PTR));
debug_tag = READ_HREG(DEBUG_REG1);
if (debug_tag & 0x10000) {
@@ -6522,8 +5978,7 @@
if ((i & 0xf) == 0)
pr_info("%03x: ", i);
for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- dec->lmem_ptr[i + 3 - ii]);
+ pr_info("%04x ", dec->lmem_ptr[i + 3 - ii]);
}
if (((i + ii) & 0xf) == 0)
pr_info("\n");
@@ -6544,8 +5999,7 @@
else
WRITE_HREG(DEBUG_REG1, 0);
} else if (debug_tag != 0) {
- pr_info(
- "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
+ pr_info("dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
READ_HREG(DEBUG_REG2),
READ_VREG(HEVC_PARSER_LCU_START));
if (((udebug_pause_pos & 0xffff)
@@ -6577,10 +6031,6 @@
if ((dec->pic_list_init_flag) &&
get_free_buf_count(dec) <= 0) {
- /*
- if (dec->wait_buf == 0)
- pr_info("set wait_buf to 1\r\n");
- */
dec->wait_buf = 1;
dec->process_busy = 0;
if (debug & AVS2_DBG_IRQ_EVENT)
@@ -6601,7 +6051,7 @@
uint8_t empty_flag;
unsigned int buf_level;
- enum receviver_start_e state = RECEIVER_INACTIVE;
+ enum receiver_start_e state = RECEIVER_INACTIVE;
if (dec->m_ins_flag) {
if (hw_to_vdec(dec)->next_status
== VDEC_STATUS_DISCONNECTED) {
@@ -6641,32 +6091,17 @@
/* receiver has no buffer to recycle */
if ((state == RECEIVER_INACTIVE) &&
(kfifo_is_empty(&dec->display_q) &&
- buf_level > 0x200)
- ) {
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
+ buf_level > 0x200)) {
+ WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
}
}
-
- if ((debug & AVS2_DBG_DIS_SYS_ERROR_PROC) == 0) {
- /* receiver has no buffer to recycle */
- /*if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&dec->display_q))) {
- pr_info("avs2 something error,need reset\n");
- }*/
- }
}
} else {
if (
(decode_timeout_val > 0) &&
(dec->start_process_time > 0) &&
- ((1000 * (jiffies - dec->start_process_time) / HZ)
- > decode_timeout_val)
- ) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
+ ((1000 * (jiffies - dec->start_process_time) / HZ) > decode_timeout_val)) {
+ int current_lcu_idx = READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff;
if (dec->last_lcu_idx == current_lcu_idx) {
if (dec->decode_timeout_count > 0)
dec->decode_timeout_count--;
@@ -6701,8 +6136,7 @@
__func__,
dec->chunk->size,
dec->chunk->offset,
- get_data_check_sum(dec, dec->chunk->size)
- );
+ get_data_check_sum(dec, dec->chunk->size));
dump_data(dec, dec->chunk->size);
}
if (debug & AVS2_DBG_DUMP_PIC_LIST) {
@@ -6747,8 +6181,6 @@
}
debug &= ~AVS2_DBG_DUMP_LMEM_BUF;
}
- /*if (debug & AVS2_DBG_HW_RESET) {
- }*/
if (radr != 0) {
if (rval != 0) {
@@ -6799,13 +6231,11 @@
/*don't changed at start.*/
if (dec->get_frame_dur && dec->show_frame_num > 60 &&
dec->frame_dur > 0 && dec->saved_resolution !=
- frame_width * frame_height *
- (96000 / dec->frame_dur)) {
+ frame_width * frame_height * (96000 / dec->frame_dur)) {
int fps = 96000 / dec->frame_dur;
if (hevc_source_changed(VFORMAT_AVS2,
frame_width, frame_height, fps) > 0)
- dec->saved_resolution = frame_width *
- frame_height * fps;
+ dec->saved_resolution = frame_width * frame_height * fps;
}
timer->expires = jiffies + PUT_INTERVAL;
@@ -6850,8 +6280,7 @@
vstatus->total_data = dec->gvs->total_data;
vstatus->samp_cnt = dec->gvs->samp_cnt;
vstatus->offset = dec->gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
+ snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME);
return 0;
}
@@ -6871,48 +6300,16 @@
avs2_init_decoder_hw(dec);
-#if 1
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s\n", __func__);
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s\n", __func__);
data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 |
- (1 << 0)/*stream_fetch_enable*/
- ;
+ data32 = data32 | (1 << 0); /*stream_fetch_enable*/
+
WRITE_VREG(HEVC_STREAM_CONTROL, data32);
-#if 0
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
-#endif
WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
-#endif
-
-
WRITE_VREG(HEVC_WAIT_FLAG, 1);
- /* WRITE_VREG(HEVC_MPSR, 1); */
-
/* clear mailbox interrupt */
WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
@@ -6971,25 +6368,21 @@
on_no_keyframe_skiped = 0;
width = dec->vavs2_amstream_dec_info.width;
height = dec->vavs2_amstream_dec_info.height;
- dec->frame_dur =
- (dec->vavs2_amstream_dec_info.rate ==
- 0) ? 3600 : dec->vavs2_amstream_dec_info.rate;
+ dec->frame_dur = (dec->vavs2_amstream_dec_info.rate == 0) ?
+ 3600 : dec->vavs2_amstream_dec_info.rate;
if (width && height)
dec->frame_ar = height * 0x100 / width;
-/*
-TODO:FOR VERSION
-*/
+
avs2_print(dec, AVS2_DBG_BUFMGR,
"avs2: ver (%d,%d) decinfo: %dx%d rate=%d\n", avs2_version,
- 0, width, height, dec->frame_dur);
+ 0, width, height, dec->frame_dur);
if (dec->frame_dur == 0)
dec->frame_dur = 96000 / 24;
#ifdef I_ONLY_SUPPORT
if (i_only_flag & 0x100)
dec->i_only = i_only_flag & 0xff;
- else if ((unsigned long) dec->vavs2_amstream_dec_info.param
- & 0x08)
+ else if ((unsigned long) dec->vavs2_amstream_dec_info.param & 0x08)
dec->i_only = 0x7;
else
dec->i_only = 0x0;
@@ -7004,7 +6397,6 @@
kfifo_put(&dec->newframe_q, vf);
}
-
ret = avs2_local_init(dec);
return ret;
@@ -7017,6 +6409,7 @@
int fw_size = 0x1000 * 16;
struct firmware_s *fw = NULL;
struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
timer_setup(&dec->timer, vavs2_put_timer_func, 0);
@@ -7024,6 +6417,7 @@
if (vavs2_local_init(dec) < 0)
return -EBUSY;
+ avs2_dec->start_time = div64_u64(local_clock(), 1000);
vdec_set_vframe_comm(vdec, DRIVER_NAME);
fw = vmalloc(sizeof(struct firmware_s) + fw_size);
@@ -7042,11 +6436,6 @@
if (dec->m_ins_flag) {
dec->timer.expires = jiffies + PUT_INTERVAL;
- /*add_timer(&dec->timer);
-
- dec->stat |= STAT_TIMER_ARM;
- dec->stat |= STAT_ISR_REG;*/
-
INIT_WORK(&dec->work, avs2_work);
dec->fw = fw;
@@ -7060,7 +6449,7 @@
amhevc_disable();
vfree(fw);
pr_err("AVS2: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
+ fw_tee_enabled() ? "TEE" : "local", ret);
return -EBUSY;
}
@@ -7072,10 +6461,10 @@
vavs2_prot_init(dec);
if (vdec_request_threaded_irq(VDEC_IRQ_0,
- vavs2_isr,
- vavs2_isr_thread_fn,
- IRQF_ONESHOT,/*run thread on this irq disabled*/
- "vavs2-irq", (void *)dec)) {
+ vavs2_isr,
+ vavs2_isr_thread_fn,
+ IRQF_ONESHOT,/*run thread on this irq disabled*/
+ "vavs2-irq", (void *)dec)) {
pr_info("vavs2 irq register error.\n");
amhevc_disable();
return -ENOENT;
@@ -7102,7 +6491,6 @@
dec->stat |= STAT_TIMER_ARM;
- /* dec->stat |= STAT_KTHREAD; */
dec->process_busy = 0;
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
"%d, vavs2_init, RP=0x%x\n",
@@ -7196,8 +6584,7 @@
dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
dec->index, FRAME_BUFFERS,
dec->need_cache_size,
- tvp_flag
- );
+ tvp_flag);
if (!dec->mmu_box) {
pr_err("avs2 alloc mmu box failed!!\n");
return -1;
@@ -7209,8 +6596,7 @@
dec->dw_mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
dec->index, FRAME_BUFFERS,
dec->need_cache_size,
- tvp_flag
- );
+ tvp_flag);
if (!dec->dw_mmu_box) {
pr_err("avs2 alloc dw mmu box failed!!\n");
dec->dw_mmu_enable = 0;
@@ -7224,7 +6610,8 @@
4 + PAGE_SHIFT,
CODEC_MM_FLAGS_CMA_CLEAR |
CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
+ tvp_flag,
+ BMMU_ALLOC_FLAGS_WAITCLEAR);
if (!dec->bmmu_box) {
pr_err("avs2 alloc bmmu box failed!!\n");
return -1;
@@ -7235,7 +6622,6 @@
static int amvdec_avs2_probe(struct platform_device *pdev)
{
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- /*struct BUF_s BUF[MAX_BUF_NUM];*/
struct AVS2Decoder_s *dec = &gAVS2Decoder;
int ret;
pr_info("%s\n", __func__);
@@ -7281,7 +6667,7 @@
}
ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
- work_buf_size, DRIVER_NAME, &pdata->mem_start);
+ work_buf_size, DRIVER_NAME, &pdata->mem_start);
if (ret < 0) {
uninit_mmu_buffers(dec);
mutex_unlock(&vavs2_mutex);
@@ -7291,11 +6677,10 @@
dec->buf_start = pdata->mem_start;
-
if (debug) {
avs2_print(dec, 0,
"===AVS2 decoder mem resource 0x%lx size 0x%x\n",
- pdata->mem_start, dec->buf_size);
+ pdata->mem_start, dec->buf_size);
}
if (pdata->sys_info) {
@@ -7317,7 +6702,7 @@
pdata->private = dec;
pdata->dec_status = vavs2_dec_status;
- /*pdata->set_isreset = vavs2_set_isreset;*/
+
is_reset = 0;
if (vavs2_init(pdata) < 0) {
pr_info("\namvdec_avs2 init failed.\n");
@@ -7328,8 +6713,7 @@
return -ENODEV;
}
/*set the max clk for smooth playing...*/
- hevc_source_changed(VFORMAT_AVS2,
- 4096, 2048, 60);
+ hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
mutex_unlock(&vavs2_mutex);
return 0;
@@ -7345,13 +6729,11 @@
vavs2_stop(dec);
-
hevc_source_changed(VFORMAT_AVS2, 0, 0, 0);
-
#ifdef DEBUG_PTS
pr_info("pts missed %ld, pts hit %ld, duration %d\n",
- dec->pts_missed, dec->pts_hit, dec->frame_dur);
+ dec->pts_missed, dec->pts_hit, dec->frame_dur);
#endif
mutex_unlock(&vavs2_mutex);
@@ -7418,33 +6800,36 @@
avs2_print(dec, 0, "padding: ");
for (jj = padding_size; jj > 0; jj--)
- avs2_print_cont(dec,
- 0,
- "%02x ", *(data - jj));
- avs2_print_cont(dec, 0, "data adr %p\n",
- data);
+ avs2_print_cont(dec, 0, "%02x ", *(data - jj));
+ avs2_print_cont(dec, 0, "data adr %p\n", data);
for (jj = 0; jj < size; jj++) {
if ((jj & 0xf) == 0)
- avs2_print(dec,
- 0,
- "%06x:", jj);
- avs2_print_cont(dec,
- 0,
- "%02x ", data[jj]);
+ avs2_print(dec, 0, "%06x:", jj);
+ avs2_print_cont(dec, 0, "%02x ", data[jj]);
if (((jj + 1) & 0xf) == 0)
- avs2_print(dec,
- 0,
- "\n");
+ avs2_print(dec, 0, "\n");
}
- avs2_print(dec,
- 0,
- "\n");
+ avs2_print(dec, 0, "\n");
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
+void wait_hevc_search_done(struct AVS2Decoder_s *dec)
+{
+ int count = 0;
+ WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+ while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+ usleep_range(100, 101);
+ count++;
+ if (count > 100) {
+ avs2_print(dec, 0, "%s timeout\n", __func__);
+ break;
+ }
+ }
+}
+
static void avs2_work(struct work_struct *work)
{
struct AVS2Decoder_s *dec = container_of(work,
@@ -7463,8 +6848,7 @@
if (((dec->dec_result == DEC_RESULT_GET_DATA) ||
(dec->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(dec)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
+ && (hw_to_vdec(dec)->next_status != VDEC_STATUS_DISCONNECTED)) {
if (!vdec_has_more_input(vdec)) {
dec->dec_result = DEC_RESULT_EOS;
vdec_schedule_work(&dec->work);
@@ -7502,8 +6886,7 @@
"%s: chunk size 0x%x sum 0x%x\n",
__func__, r,
(debug & PRINT_FLAG_VDEC_STATUS) ?
- get_data_check_sum(dec, r) : 0
- );
+ get_data_check_sum(dec, r) : 0);
if (debug & PRINT_FLAG_VDEC_DATA)
dump_data(dec, dec->chunk->size);
@@ -7528,9 +6911,10 @@
vdec_schedule_work(&dec->work);
}
return;
- } else if (dec->dec_result == DEC_RESULT_DONE) {
- /* if (!dec->ctx_valid)
- dec->ctx_valid = 1; */
+ } else if ((dec->dec_result == DEC_RESULT_DONE)
+ || (dec->dec_result == DEC_RESULT_ERROR)) {
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
dec->slice_idx++;
dec->frame_count++;
dec->process_state = PROC_STATE_INIT;
@@ -7540,6 +6924,20 @@
if (dec->mmu_enable)
dec->used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
#endif
+
+ if ((pic != NULL) && (pic->error_mark) &&
+ (dec->dec_result == DEC_RESULT_DONE)) {
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_concealed_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_concealed_frames++;
+ }
+ }
+
avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
"%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
__func__,
@@ -7549,9 +6947,7 @@
READ_VREG(HEVC_STREAM_WR_PTR),
READ_VREG(HEVC_STREAM_RD_PTR),
READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- dec->start_shift_bytes
- );
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT) - dec->start_shift_bytes);
vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
} else if (dec->dec_result == DEC_RESULT_AGAIN) {
/*
@@ -7564,20 +6960,15 @@
return;
}
} else if (dec->dec_result == DEC_RESULT_EOS) {
- avs2_print(dec, 0,
- "%s: end of stream\n",
- __func__);
+ avs2_print(dec, 0, "%s: end of stream\n", __func__);
dec->eos = 1;
if ( dec->avs2_dec.hc.cur_pic != NULL) {
- check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
avs2_post_process(&dec->avs2_dec);
avs2_prepare_display_buf(dec);
}
vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
} else if (dec->dec_result == DEC_RESULT_FORCE_EXIT) {
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS, "%s: force exit\n", __func__);
if (dec->stat & STAT_VDEC_RUN) {
amhevc_stop();
dec->stat &= ~STAT_VDEC_RUN;
@@ -7595,6 +6986,20 @@
del_timer_sync(&dec->timer);
dec->stat &= ~STAT_TIMER_ARM;
}
+
+ wait_hevc_search_done(dec);
+
+ if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+ avs2_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+ __func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+ avs2_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+ avs2_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+ avs2_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+ }
+
/* mark itself has all HW resource released and input released */
if (vdec->parallel_dec ==1)
vdec_core_finish_run(vdec, CORE_MASK_HEVC);
@@ -7602,7 +7007,7 @@
vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
if (dec->vdec_cb)
- dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg);
+ dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg, CORE_MASK_HEVC);
}
static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec)
@@ -7631,38 +7036,21 @@
dec->first_sc_checked = 1;
avs2_print(dec, 0, "vavs2 cached=%d need_size=%d speed= %d ms\n",
size, (dec->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - dec->sc_start_time) * 1000/HZ);
+ (int)(get_jiffies_64() - dec->sc_start_time) * 1000/HZ);
}
if (dec->next_again_flag &&
(!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
+ u32 parser_wr_ptr = STBUF_READ(&vdec->vbuf, get_wp);
if (parser_wr_ptr >= dec->pre_parser_wr_ptr &&
(parser_wr_ptr - dec->pre_parser_wr_ptr) <
again_threshold) {
int r = vdec_sync_input(vdec);
avs2_print(dec,
- PRINT_FLAG_VDEC_DETAIL, "%s buf lelvel:%x\n", __func__, r);
+ PRINT_FLAG_VDEC_DETAIL, "%s buf level:%x\n", __func__, r);
return 0;
}
}
-/*
- if (vdec_stream_based(vdec) && (dec->pic_list_init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level)
- return 0;
- }
-*/
if ((dec->pic_list_init_flag == 0) ||
get_free_buf_count(dec) >=
@@ -7672,8 +7060,7 @@
if (dec->pic_list_init_flag) {
if (run_ready_max_vf_only_num > 0 &&
get_vf_ref_only_buf_count(dec) >=
- run_ready_max_vf_only_num
- )
+ run_ready_max_vf_only_num)
ret = 0;
if (run_ready_display_q_num > 0 &&
kfifo_len(&dec->display_q) >=
@@ -7702,7 +7089,7 @@
}
static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
+ void (*callback)(struct vdec_s *, void *, int), void *arg)
{
struct AVS2Decoder_s *dec =
(struct AVS2Decoder_s *)vdec->private;
@@ -7711,7 +7098,7 @@
run_count[dec->index]++;
dec->vdec_cb_arg = arg;
dec->vdec_cb = callback;
- /* dec->chunk = vdec_prepare_input(vdec); */
+
hevc_reset_core(vdec);
if (vdec_stream_based(vdec)) {
@@ -7747,12 +7134,12 @@
dec->chunk ? ((vdec_frame_based(vdec) &&
(debug & PRINT_FLAG_VDEC_STATUS)) ?
get_data_check_sum(dec, r) : 0) : 0,
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- dec->start_shift_bytes);
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ dec->start_shift_bytes);
if (vdec_frame_based(vdec) && dec->chunk) {
u8 *data = NULL;
if (!dec->chunk->block->is_mapped)
@@ -7762,11 +7149,9 @@
data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
- avs2_print_cont(dec, 0, "data adr %p:",
- data);
+ avs2_print_cont(dec, 0, "data adr %p:", data);
for (ii = 0; ii < 8; ii++)
- avs2_print_cont(dec, 0, "%02x ",
- data[ii]);
+ avs2_print_cont(dec, 0, "%02x ", data[ii]);
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
@@ -7780,8 +7165,7 @@
} else if (amhevc_loadmc_ex(VFORMAT_AVS2, NULL, dec->fw->data) < 0) {
vdec->mc_loaded = 0;
amhevc_disable();
- avs2_print(dec, 0,
- "%s: Error amvdec_loadmc fail\n", __func__);
+ avs2_print(dec, 0, "%s: Error amvdec_loadmc fail\n", __func__);
dec->dec_result = DEC_RESULT_FORCE_EXIT;
vdec_schedule_work(&dec->work);
return;
@@ -7790,7 +7174,6 @@
vdec->mc_type = VFORMAT_AVS2;
}
-
if (avs2_hw_ctx_restore(dec) < 0) {
vdec_schedule_work(&dec->work);
return;
@@ -7834,13 +7217,11 @@
static void reset(struct vdec_s *vdec)
{
-
struct AVS2Decoder_s *dec =
(struct AVS2Decoder_s *)vdec->private;
avs2_print(dec,
PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
-
}
static irqreturn_t avs2_irq_cb(struct vdec_s *vdec, int irq)
@@ -7868,8 +7249,7 @@
"width/height (%d/%d), used_buf_num %d\n",
dec->avs2_dec.img.width,
dec->avs2_dec.img.height,
- dec->used_buf_num
- );
+ dec->used_buf_num);
avs2_print(dec, 0,
"is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
@@ -7880,11 +7260,10 @@
display_frame_count[dec->index],
run_count[dec->index],
not_run_ready[dec->index],
- input_empty[dec->index]
- );
+ input_empty[dec->index]);
if (vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
+ enum receiver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
NULL);
@@ -7895,18 +7274,17 @@
}
avs2_print(dec, 0,
- "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
- __func__,
- kfifo_len(&dec->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&dec->display_q),
- VF_POOL_SIZE,
- dec->vf_pre_count,
- dec->vf_get_count,
- dec->vf_put_count,
- get_free_buf_count(dec),
- run_ready_min_buf_num
- );
+ "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
+ __func__,
+ kfifo_len(&dec->newframe_q),
+ VF_POOL_SIZE,
+ kfifo_len(&dec->display_q),
+ VF_POOL_SIZE,
+ dec->vf_pre_count,
+ dec->vf_get_count,
+ dec->vf_put_count,
+ get_free_buf_count(dec),
+ run_ready_min_buf_num);
dump_pic_list(dec);
@@ -7963,8 +7341,7 @@
STBUF_READ(&vdec->vbuf, get_wp));
if (input_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_DATA)
- ) {
+ (debug & PRINT_FLAG_VDEC_DATA)) {
int jj;
if (dec->chunk && dec->chunk->block &&
dec->chunk->size > 0) {
@@ -7980,20 +7357,16 @@
dec->chunk->size);
for (jj = 0; jj < dec->chunk->size; jj++) {
if ((jj & 0xf) == 0)
- avs2_print(dec, 0,
- "%06x:", jj);
- avs2_print_cont(dec, 0,
- "%02x ", data[jj]);
+ avs2_print(dec, 0, "%06x:", jj);
+ avs2_print_cont(dec, 0, "%02x ", data[jj]);
if (((jj + 1) & 0xf) == 0)
- avs2_print_cont(dec, 0,
- "\n");
+ avs2_print_cont(dec, 0, "\n");
}
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}
-
}
static int ammvdec_avs2_probe(struct platform_device *pdev)
@@ -8004,11 +7377,12 @@
int i;
struct vframe_content_light_level_s content_light_level;
struct vframe_master_display_colour_s vf_dp;
- /*struct BUF_s BUF[MAX_BUF_NUM];*/
struct AVS2Decoder_s *dec = NULL;
+ static struct vframe_operations_s vf_tmp_ops;
pr_info("%s\n", __func__);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+ if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2)) {
pr_info("%s, chip id %d is not support avs2\n",
__func__, get_cpu_major_id());
return -1;
@@ -8017,8 +7391,7 @@
pr_info("\nammvdec_avs2 memory resource undefined.\n");
return -EFAULT;
}
- /*dec = (struct AVS2Decoder_s *)devm_kzalloc(&pdev->dev,
- sizeof(struct AVS2Decoder_s), GFP_KERNEL);*/
+
memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
dec = vzalloc(sizeof(struct AVS2Decoder_s));
if (dec == NULL) {
@@ -8044,16 +7417,12 @@
pdata->threaded_irq_handler = avs2_threaded_irq_cb;
pdata->dump_state = avs2_dump_state;
- /*
- * memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- * memset(dec, 0, sizeof(struct AVS2Decoder_s));
- * memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- */
-
dec->index = pdev->id;
dec->m_ins_flag = 1;
+ dec->error_proc_policy = error_proc_policy;
if (is_rdma_enable()) {
- dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &dec->rdma_phy_adr, GFP_KERNEL);
+ dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle,
+ RDMA_SIZE, &dec->rdma_phy_adr, "AVS2_RDMA_BUF");
for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
dec->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
dec->rdma_adr[i * 4 + 1] = i;
@@ -8082,8 +7451,12 @@
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+ memcpy(&vf_tmp_ops, &vavs2_vf_provider, sizeof(struct vframe_operations_s));
+ if (without_display_mode == 1) {
+ vf_tmp_ops.get = NULL;
+ }
vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vavs2_vf_provider, dec);
+ &vf_tmp_ops, dec);
dec->provider_name = pdata->vf_provider_name;
platform_set_drvdata(pdev, pdata);
@@ -8095,7 +7468,7 @@
dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
- /*use ptr config for doubel_write_mode, etc*/
+ /*use ptr config for double_write_mode, etc*/
avs2_print(dec, 0, "pdata->config=%s\n", pdata->config);
if (get_config_int(pdata->config, "avs2_double_write_mode",
&config_val) == 0)
@@ -8117,6 +7490,14 @@
&config_val) == 0)
dec->sidebind_channel_id = config_val;
+ if (get_config_int(pdata->config,
+ "parm_metadata_config_flag",
+ &config_val) == 0) {
+ dec->high_bandwidth_flag = config_val & VDEC_CFG_FLAG_HIGH_BANDWIDTH;
+ if (dec->high_bandwidth_flag)
+ avs2_print(dec, 0, "high bandwidth\n");
+ }
+
if (get_config_int(pdata->config, "HDRStaticInfo",
&vf_dp.present_flag) == 0
&& vf_dp.present_flag == 1) {
@@ -8156,9 +7537,6 @@
}
dec->vf_dp = vf_dp;
} else {
- /*dec->vavs2_amstream_dec_info.width = 0;
- dec->vavs2_amstream_dec_info.height = 0;
- dec->vavs2_amstream_dec_info.rate = 30;*/
dec->double_write_mode = double_write_mode;
dec->dynamic_buf_margin = dynamic_buf_num_margin;
}
@@ -8181,7 +7559,6 @@
#endif
if (amvdec_avs2_mmu_init(dec) < 0) {
pr_err("avs2 alloc bmmu box failed!!\n");
- /* devm_kfree(&pdev->dev, (void *)dec); */
vfree((void *)dec);
return -1;
}
@@ -8191,10 +7568,12 @@
&dec->cma_alloc_addr);
if (ret < 0) {
uninit_mmu_buffers(dec);
- /* devm_kfree(&pdev->dev, (void *)dec); */
vfree((void *)dec);
return ret;
}
+ if (!vdec_secure(pdata))
+ codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
dec->buf_start = dec->cma_alloc_addr;
dec->buf_size = work_buf_size;
@@ -8230,14 +7609,12 @@
pr_info("\namvdec_avs2 init failed.\n");
avs2_local_uninit(dec);
uninit_mmu_buffers(dec);
- /* devm_kfree(&pdev->dev, (void *)dec); */
vfree((void *)dec);
pdata->dec_status = NULL;
return -ENODEV;
}
vdec_set_prepare_level(pdata, start_decode_buf_level);
- hevc_source_changed(VFORMAT_AVS2,
- 4096, 2048, 60);
+ hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
if (pdata->parallel_dec == 1)
vdec_core_request(pdata, CORE_MASK_HEVC);
else {
@@ -8283,14 +7660,14 @@
release_cuva_data(pic);
}
-
#ifdef DEBUG_PTS
pr_info("pts missed %ld, pts hit %ld, duration %d\n",
dec->pts_missed, dec->pts_hit, dec->frame_dur);
#endif
if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
- /* devm_kfree(&pdev->dev, (void *)dec); */
+ decoder_dma_free_coherent(dec->rdma_mem_handle,
+ RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
+
vfree((void *)dec);
return 0;
}
@@ -8347,7 +7724,6 @@
static int __init amvdec_avs2_driver_init_module(void)
{
-
#ifdef AVS2_10B_MMU
struct BuffInfo_s *p_buf_info;
@@ -8392,9 +7768,11 @@
}
if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2)) {
amvdec_avs2_profile.name = "avs2_unsupport";
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+ } else if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M)) {
if (vdec_is_support_4k())
amvdec_avs2_profile.profile =
"4k, 10bit, dwrite, compressed";
@@ -8427,7 +7805,6 @@
}
/****************************************/
-
module_param(bit_depth_luma, uint, 0664);
MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\n");
@@ -8546,7 +7923,6 @@
module_param(on_no_keyframe_skiped, uint, 0664);
MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
-
module_param(start_decode_buf_level, int, 0664);
MODULE_PARM_DESC(start_decode_buf_level,
"\n avs2 start_decode_buf_level\n");
@@ -8583,10 +7959,10 @@
MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs2 enable_force_video_signal_type\n");
module_param(force_bufspec, uint, 0664);
-MODULE_PARM_DESC(force_bufspec, "\n amvdec_h265 force_bufspec\n");
+MODULE_PARM_DESC(force_bufspec, "\n amvdec_avs2 force_bufspec\n");
module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs2 udebug_flag\n");
module_param(udebug_pause_pos, uint, 0664);
MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
@@ -8604,10 +7980,9 @@
module_param(again_threshold, uint, 0664);
MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-
module_param(force_disp_pic_index, int, 0664);
MODULE_PARM_DESC(force_disp_pic_index,
- "\n amvdec_h265 force_disp_pic_index\n");
+ "\n amvdec_avs2 force_disp_pic_index\n");
module_param(without_display_mode, uint, 0664);
MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.h b/drivers/frame_provider/decoder/avs2/vavs2.h
index 071bfb3..6bba092 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.h
+++ b/drivers/frame_provider/decoder/avs2/vavs2.h
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/amports/vavs2.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,8 +11,12 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
-*/
-
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef VAVS2_H
#define VAVS2_H
diff --git a/drivers/frame_provider/decoder/avs2_fb/Makefile b/drivers/frame_provider/decoder/avs2_fb/Makefile
new file mode 100644
index 0000000..d18ff35
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/Makefile
@@ -0,0 +1,7 @@
+MODULE_NAME = amvdec_avs2_fb
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs2_fb.o avs2_bufmgr.o
+
+PR_FMT = $(subst amvdec_,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c
new file mode 100644
index 0000000..a7edcac
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c
@@ -0,0 +1,1898 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/sched/clock.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+#include "avs2_global.h"
+
+#undef pr_info
+#define pr_info pr_cont
+
+#define assert(chk_cond) {\
+ if (!(chk_cond))\
+ pr_info("error line %d\n", __LINE__);\
+ while (!(chk_cond))\
+ ;\
+}
+
+int16_t get_param(uint16_t value, int8_t *print_info)
+{
+ if (is_avs2_print_param())
+ pr_info("%s = %x\n", print_info, value);
+ return (int16_t)value;
+}
+
+void readAlfCoeff(struct avs2_decoder *avs2_dec, struct ALFParam_s *Alfp)
+{
+ int32_t pos;
+ union param_u *rpm_param = &avs2_dec->param;
+
+ int32_t f = 0, symbol, pre_symbole;
+ const int32_t numCoeff = (int32_t)ALF_MAX_NUM_COEF;
+
+ switch (Alfp->componentID) {
+ case ALF_Cb:
+ case ALF_Cr: {
+ for (pos = 0; pos < numCoeff; pos++) {
+ if (Alfp->componentID == ALF_Cb)
+ Alfp->coeffmulti[0][pos] =
+ get_param(rpm_param->alf.alf_cb_coeffmulti[pos],
+ "Chroma ALF coefficients");
+ else
+ Alfp->coeffmulti[0][pos] =
+ get_param(rpm_param->alf.alf_cr_coeffmulti[pos],
+ "Chroma ALF coefficients");
+#if Check_Bitstream
+ if (pos <= 7)
+ assert(Alfp->coeffmulti[0][pos] >= -64
+ && Alfp->coeffmulti[0][pos] <= 63);
+ if (pos == 8)
+ assert(Alfp->coeffmulti[0][pos] >= -1088
+ && Alfp->coeffmulti[0][pos] <= 1071);
+#endif
+ }
+ }
+ break;
+ case ALF_Y: {
+ int32_t region_distance_idx = 0;
+ Alfp->filters_per_group =
+ get_param(rpm_param->alf.alf_filters_num_m_1,
+ "ALF_filter_number_minus_1");
+#if Check_Bitstream
+ assert(Alfp->filters_per_group >= 0
+ && Alfp->filters_per_group <= 15);
+#endif
+ Alfp->filters_per_group = Alfp->filters_per_group + 1;
+
+ memset(Alfp->filterPattern, 0, NO_VAR_BINS * sizeof(int32_t));
+ pre_symbole = 0;
+ symbol = 0;
+ for (f = 0; f < Alfp->filters_per_group; f++) {
+ if (f > 0) {
+ if (Alfp->filters_per_group != 16) {
+ symbol = get_param(rpm_param->alf.region_distance
+ [region_distance_idx++],
+ "Region distance");
+ } else {
+ symbol = 1;
+ }
+ Alfp->filterPattern[symbol + pre_symbole] = 1;
+ pre_symbole = symbol + pre_symbole;
+ }
+
+ for (pos = 0; pos < numCoeff; pos++) {
+ Alfp->coeffmulti[f][pos] =
+ get_param(rpm_param->alf.alf_y_coeffmulti[f][pos],
+ "Luma ALF coefficients");
+#if Check_Bitstream
+ if (pos <= 7)
+ assert(Alfp->coeffmulti[f][pos] >= -64 &&
+ Alfp->coeffmulti[f][pos] <= 63);
+ if (pos == 8)
+ assert(Alfp->coeffmulti[f][pos] >= -1088 &&
+ Alfp->coeffmulti[f][pos] <= 1071);
+#endif
+ }
+ }
+
+#if Check_Bitstream
+ assert(pre_symbole >= 0 && pre_symbole <= 15);
+#endif
+ }
+ break;
+ default: {
+ pr_info("Not a legal component ID\n");
+ assert(0);
+ return; /* exit(-1);*/
+ }
+ }
+}
+
+void Read_ALF_param(struct avs2_decoder *avs2_dec)
+{
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ union param_u *rpm_param = &avs2_dec->param;
+ int32_t compIdx;
+ if (input->alf_enable) {
+ img->pic_alf_on[0] =
+ get_param(rpm_param->alf.picture_alf_enable_Y,
+ "alf_pic_flag_Y");
+ img->pic_alf_on[1] =
+ get_param(rpm_param->alf.picture_alf_enable_Cb,
+ "alf_pic_flag_Cb");
+ img->pic_alf_on[2] =
+ get_param(rpm_param->alf.picture_alf_enable_Cr,
+ "alf_pic_flag_Cr");
+
+ avs2_dec->m_alfPictureParam[ALF_Y].alf_flag
+ = img->pic_alf_on[ALF_Y];
+ avs2_dec->m_alfPictureParam[ALF_Cb].alf_flag
+ = img->pic_alf_on[ALF_Cb];
+ avs2_dec->m_alfPictureParam[ALF_Cr].alf_flag
+ = img->pic_alf_on[ALF_Cr];
+ if (img->pic_alf_on[0]
+ || img->pic_alf_on[1]
+ || img->pic_alf_on[2]) {
+ for (compIdx = 0;
+ compIdx < NUM_ALF_COMPONENT;
+ compIdx++) {
+ if (img->pic_alf_on[compIdx]) {
+ readAlfCoeff(
+ avs2_dec,
+ &avs2_dec->m_alfPictureParam[compIdx]);
+ }
+ }
+ }
+ }
+
+}
+
+void Get_SequenceHeader(struct avs2_decoder *avs2_dec)
+{
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ union param_u *rpm_param = &avs2_dec->param;
+ /*int32_t i, j;*/
+
+ input->profile_id =
+ get_param(rpm_param->p.profile_id, "profile_id");
+ input->level_id =
+ get_param(rpm_param->p.level_id, "level_id");
+ hd->progressive_sequence =
+ get_param(rpm_param->p.progressive_sequence,
+ "progressive_sequence");
+#if INTERLACE_CODING
+ hd->is_field_sequence =
+ get_param(rpm_param->p.is_field_sequence,
+ "field_coded_sequence");
+#endif
+#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
+ img->is_field_sequence = hd->is_field_sequence;
+#endif
+ hd->horizontal_size =
+ get_param(rpm_param->p.horizontal_size, "horizontal_size");
+ hd->vertical_size =
+ get_param(rpm_param->p.vertical_size, "vertical_size");
+ input->chroma_format =
+ get_param(rpm_param->p.chroma_format, "chroma_format");
+ input->output_bit_depth = 8;
+ input->sample_bit_depth = 8;
+ hd->sample_precision = 1;
+ if (input->profile_id == BASELINE10_PROFILE) { /* 10bit profile (0x52)*/
+ input->output_bit_depth =
+ get_param(rpm_param->p.sample_precision,
+ "sample_precision");
+ input->output_bit_depth = 6 + (input->output_bit_depth) * 2;
+ input->sample_bit_depth =
+ get_param(rpm_param->p.encoding_precision,
+ "encoding_precision");
+ input->sample_bit_depth = 6 + (input->sample_bit_depth) * 2;
+ } else { /* other profile*/
+ hd->sample_precision =
+ get_param(rpm_param->p.sample_precision,
+ "sample_precision");
+ }
+ hd->aspect_ratio_information =
+ get_param(rpm_param->p.aspect_ratio_information,
+ "aspect_ratio_information");
+ hd->frame_rate_code =
+ get_param(rpm_param->p.frame_rate_code, "frame_rate_code");
+
+ hd->bit_rate_lower =
+ get_param(rpm_param->p.bit_rate_lower, "bit_rate_lower");
+ /*CHECKMARKERBIT*/
+ hd->bit_rate_upper =
+ get_param(rpm_param->p.bit_rate_upper, "bit_rate_upper");
+ hd->low_delay =
+ get_param(rpm_param->p.low_delay, "low_delay");
+
+ /*CHECKMARKERBIT*/
+#if M3480_TEMPORAL_SCALABLE
+ hd->temporal_id_exist_flag =
+ get_param(rpm_param->p.temporal_id_exist_flag,
+ "temporal_id exist flag"); /*get
+ Extention Flag*/
+#endif
+ /*u_v(18, "bbv buffer size");*/
+ input->g_uiMaxSizeInBit =
+ get_param(rpm_param->p.g_uiMaxSizeInBit,
+ "Largest Coding Block Size");
+
+ hd->background_picture_enable = 0x01 ^
+ ((get_param(rpm_param->p.avs2_seq_flags,
+ "background_picture_disable") >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1);
+
+ hd->b_dmh_enabled = 1;
+
+ hd->b_mhpskip_enabled =
+ get_param(rpm_param->p.avs2_seq_flags >> B_MHPSKIP_ENABLED_BIT,
+ "mhpskip enabled") & 0x1;
+ hd->dhp_enabled =
+ get_param(rpm_param->p.avs2_seq_flags >> DHP_ENABLED_BIT,
+ "dhp enabled") & 0x1;
+ hd->wsm_enabled =
+ get_param(rpm_param->p.avs2_seq_flags >> WSM_ENABLED_BIT,
+ "wsm enabled") & 0x1;
+
+ img->inter_amp_enable =
+ get_param(rpm_param->p.avs2_seq_flags >> INTER_AMP_ENABLE_BIT,
+ "Asymmetric Motion Partitions") & 0x1;
+ input->useNSQT =
+ get_param(rpm_param->p.avs2_seq_flags >> USENSQT_BIT,
+ "useNSQT") & 0x1;
+ input->useSDIP =
+ get_param(rpm_param->p.avs2_seq_flags >> USESDIP_BIT,
+ "useNSIP") & 0x1;
+
+ hd->b_secT_enabled =
+ get_param(rpm_param->p.avs2_seq_flags >> B_SECT_ENABLED_BIT,
+ "secT enabled") & 0x1;
+
+ input->sao_enable =
+ get_param(rpm_param->p.avs2_seq_flags >> SAO_ENABLE_BIT,
+ "SAO Enable Flag") & 0x1;
+ input->alf_enable =
+ get_param(rpm_param->p.avs2_seq_flags >> ALF_ENABLE_BIT,
+ "ALF Enable Flag") & 0x1;
+ hd->b_pmvr_enabled =
+ get_param(rpm_param->p.avs2_seq_flags >> B_PMVR_ENABLED_BIT,
+ "pmvr enabled") & 0x1;
+
+ hd->gop_size = get_param(rpm_param->p.num_of_RPS,
+ "num_of_RPS");
+
+ if (hd->low_delay == 0) {
+ hd->picture_reorder_delay =
+ get_param(rpm_param->p.picture_reorder_delay,
+ "picture_reorder_delay");
+ }
+
+ input->crossSliceLoopFilter =
+ get_param(rpm_param->p.avs2_seq_flags >> CROSSSLICELOOPFILTER_BIT,
+ "Cross Loop Filter Flag") & 0x1;
+
+#if BCBR
+ if ((input->profile_id == SCENE_PROFILE ||
+ input->profile_id == SCENE10_PROFILE) &&
+ hd->background_picture_enable) {
+ hd->bcbr_enable = u_v(1, "block_composed_background_picture_enable");
+ u_v(1, "reserved bits");
+ } else {
+ hd->bcbr_enable = 0;
+ u_v(2, "reserved bits");
+ }
+#endif
+
+ img->width = hd->horizontal_size;
+ img->height = hd->vertical_size;
+ img->width_cr = (img->width >> 1);
+
+ if (input->chroma_format == 1) {
+ img->height_cr = (img->height >> 1);
+ }
+
+ img->PicWidthInMbs = img->width / MIN_CU_SIZE;
+ img->PicHeightInMbs = img->height / MIN_CU_SIZE;
+ img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
+ img->buf_cycle = input->buf_cycle + 1;
+ img->max_mb_nr = (img->width * img->height) / (MIN_CU_SIZE * MIN_CU_SIZE);
+
+#ifdef AML
+avs2_dec->lcu_size = get_param(rpm_param->p.lcu_size, "lcu_size");
+avs2_dec->lcu_size = 1<<(avs2_dec->lcu_size);
+#endif
+hc->seq_header++;
+}
+
+void Get_I_Picture_Header(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ union param_u *rpm_param = &avs2_dec->param;
+
+#if RD1501_FIX_BG /*//Longfei.Wang@mediatek.com*/
+ hd->background_picture_flag = 0;
+ hd->background_picture_output_flag = 0;
+ img->typeb = 0;
+#endif
+
+ hd->time_code_flag =
+ get_param(rpm_param->p.time_code_flag, "time_code_flag");
+
+ if (hd->time_code_flag) {
+ hd->time_code =
+ get_param(rpm_param->p.time_code, "time_code");
+ }
+ if (hd->background_picture_enable) {
+ hd->background_picture_flag =
+ get_param(rpm_param->p.background_picture_flag,
+ "background_picture_flag");
+
+ if (hd->background_picture_flag) {
+ img->typeb = BACKGROUND_IMG;
+ } else {
+ img->typeb = 0;
+ }
+
+ if (img->typeb == BACKGROUND_IMG) {
+ hd->background_picture_output_flag =
+ get_param(rpm_param->p.background_picture_output_flag,
+ "background_picture_output_flag");
+ }
+ }
+
+ {
+ img->coding_order =
+ get_param(rpm_param->p.coding_order, "coding_order");
+
+#if M3480_TEMPORAL_SCALABLE
+ if (hd->temporal_id_exist_flag == 1) {
+ hd->cur_layer =
+ get_param(rpm_param->p.cur_layer,
+ "temporal_id");
+ }
+#endif
+#if RD1501_FIX_BG /*Longfei.Wang@mediatek.com*/
+ if (hd->low_delay == 0
+ && !(hd->background_picture_flag &&
+ !hd->background_picture_output_flag)) { /*cdp*/
+#else
+ if (hd->low_delay == 0 &&
+ !(hd->background_picture_enable &&
+ !hd->background_picture_output_flag)) { /*cdp*/
+#endif
+ hd->displaydelay =
+ get_param(rpm_param->p.displaydelay,
+ "picture_output_delay");
+ }
+
+ }
+ {
+ int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
+ int32_t predict;
+ int32_t j;
+ predict = get_param(rpm_param->p.predict, "use RCS in SPS");
+ RPS_idx = get_param(rpm_param->p.RPS_idx,
+ "predict for RCS");
+ /*gop size16*/
+ hd->curr_RPS.referred_by_others =
+ get_param(rpm_param->p.referred_by_others_cur, "refered by others");
+ hd->curr_RPS.num_of_ref =
+ get_param(rpm_param->p.num_of_ref_cur,
+ "num of reference picture");
+ for (j = 0; j < hd->curr_RPS.num_of_ref; j++) {
+ hd->curr_RPS.ref_pic[j] =
+ get_param(rpm_param->p.ref_pic_cur[j],
+ "delta COI of ref pic");
+ }
+ hd->curr_RPS.num_to_remove =
+ get_param(rpm_param->p.num_to_remove_cur,
+ "num of removed picture");
+#ifdef SANITY_CHECK
+ if (hd->curr_RPS.num_to_remove > MAXREF) {
+ hd->curr_RPS.num_to_remove = MAXREF;
+ pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n",
+ __func__, hd->curr_RPS.num_to_remove);
+ }
+#endif
+
+ for (j = 0; j < hd->curr_RPS.num_to_remove; j++) {
+ hd->curr_RPS.remove_pic[j] =
+ get_param(
+ rpm_param->p.remove_pic_cur[j],
+ "delta COI of removed pic");
+ }
+ }
+ /*xyji 12.23*/
+
+ hd->progressive_frame = get_param(rpm_param->p.progressive_frame,
+ "progressive_frame");
+
+ if (!hd->progressive_frame) {
+ img->picture_structure = get_param(rpm_param->p.picture_structure,
+ "picture_structure");
+ } else {
+ img->picture_structure = 1;
+ }
+
+ hd->top_field_first = get_param(rpm_param->p.top_field_first,
+ "top_field_first");
+ hd->repeat_first_field = get_param(rpm_param->p.repeat_first_field,
+ "repeat_first_field");
+#if INTERLACE_CODING
+ if (hd->is_field_sequence) {
+ hd->is_top_field = get_param(rpm_param->p.is_top_field,
+ "is_top_field");
+#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
+ img->is_top_field = hd->is_top_field;
+#endif
+ }
+#endif
+ img->qp = hd->picture_qp;
+ img->type = I_IMG;
+}
+
+/*
+ * Function:pb picture header
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ */
+
+void Get_PB_Picture_Header(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ union param_u *rpm_param = &avs2_dec->param;
+
+ hd->picture_coding_type =
+ get_param(rpm_param->p.picture_coding_type,
+ "picture_coding_type");
+
+ if (hd->background_picture_enable &&
+ (hd->picture_coding_type == 1 ||
+ hd->picture_coding_type == 3)) {
+ if (hd->picture_coding_type == 1) {
+ hd->background_pred_flag =
+ get_param(rpm_param->p.background_pred_flag,
+ "background_pred_flag");
+ } else {
+ hd->background_pred_flag = 0;
+ }
+ if (hd->background_pred_flag == 0) {
+
+ hd->background_reference_enable =
+ get_param(rpm_param->p.background_reference_enable,
+ "background_reference_enable");
+ } else {
+#if RD170_FIX_BG
+ hd->background_reference_enable = 1;
+#else
+ hd->background_reference_enable = 0;
+#endif
+ }
+
+ } else {
+ hd->background_pred_flag = 0;
+ hd->background_reference_enable = 0;
+ }
+
+ if (hd->picture_coding_type == 1) {
+ img->type = P_IMG;
+ } else if (hd->picture_coding_type == 3) {
+ img->type = F_IMG;
+ } else {
+ img->type = B_IMG;
+ }
+
+ if (hd->picture_coding_type == 1 &&
+ hd->background_pred_flag) {
+ img->typeb = BP_IMG;
+ } else {
+ img->typeb = 0;
+ }
+
+ {
+ img->coding_order =
+ get_param(rpm_param->p.coding_order, "coding_order");
+
+#if M3480_TEMPORAL_SCALABLE
+ if (hd->temporal_id_exist_flag == 1) {
+ hd->cur_layer = get_param(rpm_param->p.cur_layer, "temporal_id");
+ }
+#endif
+
+ if (hd->low_delay == 0) {
+ hd->displaydelay =
+ get_param(rpm_param->p.displaydelay, "displaydelay");
+ }
+ }
+ {
+ int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
+ int32_t predict;
+ predict = get_param(rpm_param->p.predict, "use RPS in SPS");
+ if (predict) {
+ RPS_idx = get_param(rpm_param->p.RPS_idx, "predict for RPS");
+ hd->curr_RPS = hd->decod_RPS[RPS_idx];
+ } /*else*/
+ {
+ /*gop size16*/
+ int32_t j;
+ hd->curr_RPS.referred_by_others =
+ get_param(rpm_param->p.referred_by_others_cur,
+ "refered by others");
+ hd->curr_RPS.num_of_ref =
+ get_param(rpm_param->p.num_of_ref_cur,
+ "num of reference picture");
+ for (j = 0; j < hd->curr_RPS.num_of_ref; j++) {
+ hd->curr_RPS.ref_pic[j] =
+ get_param(rpm_param->p.ref_pic_cur[j],
+ "delta COI of ref pic");
+ }
+ hd->curr_RPS.num_to_remove =
+ get_param(rpm_param->p.num_to_remove_cur,
+ "num of removed picture");
+#ifdef SANITY_CHECK
+ if (hd->curr_RPS.num_to_remove > MAXREF) {
+ hd->curr_RPS.num_to_remove = MAXREF;
+ pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n",
+ __func__, hd->curr_RPS.num_to_remove);
+ }
+#endif
+ for (j = 0;
+ j < hd->curr_RPS.num_to_remove; j++) {
+ hd->curr_RPS.remove_pic[j] =
+ get_param(
+ rpm_param->p.remove_pic_cur[j],
+ "delta COI of removed pic");
+ }
+ }
+ }
+
+ hd->progressive_frame =
+ get_param(rpm_param->p.progressive_frame,
+ "progressive_frame");
+
+ if (!hd->progressive_frame) {
+ img->picture_structure =
+ get_param(rpm_param->p.picture_structure,
+ "picture_structure");
+ } else {
+ img->picture_structure = 1;
+ }
+
+ hd->top_field_first =
+ get_param(rpm_param->p.top_field_first,
+ "top_field_first");
+ hd->repeat_first_field =
+ get_param(rpm_param->p.repeat_first_field,
+ "repeat_first_field");
+#if INTERLACE_CODING
+ if (hd->is_field_sequence) {
+ hd->is_top_field =
+ get_param(rpm_param->p.is_top_field,
+ "is_top_field");
+#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
+ img->is_top_field = hd->is_top_field;
+#endif
+ }
+#endif
+
+ img->random_access_decodable_flag =
+ get_param(rpm_param->p.random_access_decodable_flag,
+ "random_access_decodable_flag");
+
+ img->qp = hd->picture_qp;
+}
+
+void calc_picture_distance(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+ if (img->coding_order < img->PrevPicDistanceLsb) {
+ int32_t i, j;
+
+ hc->total_frames++;
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if (
+ avs2_dec->fref[i]->imgtr_fwRefDistance
+ >= 0) {
+ avs2_dec->fref[i]->
+ imgtr_fwRefDistance -= 256;
+ avs2_dec->fref[i]->
+ imgcoi_ref -= 256;
+ }
+#if RD170_FIX_BG
+ for (j = 0; j < MAXREF; j++) {
+#else
+ for (j = 0; j < 4; j++) {
+#endif
+ avs2_dec->fref[i]->ref_poc[j] -= 256;
+ }
+ }
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
+ avs2_dec->outprint.stdoutdata[i].frame_num -= 256;
+ avs2_dec->outprint.stdoutdata[i].tr -= 256;
+ }
+
+ hd->last_output -= 256;
+ hd->curr_IDRtr -= 256;
+ hd->curr_IDRcoi -= 256;
+ hd->next_IDRtr -= 256;
+ hd->next_IDRcoi -= 256;
+ }
+ if (hd->low_delay == 0) {
+ img->tr = img->coding_order +
+ hd->displaydelay - hd->picture_reorder_delay;
+ } else {
+ img->tr = img->coding_order;
+ }
+
+#if REMOVE_UNUSED
+ img->pic_distance = img->tr;
+#else
+ img->pic_distance = img->tr % 256;
+#endif
+ hc->picture_distance = img->pic_distance;
+}
+
+int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec)
+{
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+
+ int32_t refnum;
+
+ int32_t memory_size = 0;
+
+ img->buf_cycle = input->buf_cycle + 1;
+
+ img->buf_cycle *= 2;
+
+ hc->background_ref = hc->backgroundReferenceFrame;
+
+ for (refnum = 0; refnum < REF_MAXBUFFER; refnum++) {
+ avs2_dec->fref[refnum] = &avs2_dec->frm_pool[refnum];
+
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("[t] avs2_dec->fref[%d]@0x%p\n",
+ refnum, avs2_dec->fref[refnum]);
+ avs2_dec->fref[refnum]->imgcoi_ref = -257;
+ avs2_dec->fref[refnum]->is_output = -1;
+ avs2_dec->fref[refnum]->referred_by_others = -1;
+ avs2_dec->fref[refnum]->imgtr_fwRefDistance = -256;
+ init_frame_t(avs2_dec->fref[refnum]);
+#ifdef AML
+ avs2_dec->fref[refnum]->index = refnum;
+#endif
+ }
+#ifdef AML
+ avs2_dec->f_bg = NULL;
+
+ avs2_dec->m_bg = &avs2_dec->frm_pool[REF_MAXBUFFER];
+
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("[t] avs2_dec->m_bg@0x%p\n",
+ avs2_dec->m_bg);
+ avs2_dec->m_bg->imgcoi_ref = -257;
+ avs2_dec->m_bg->is_output = -1;
+ avs2_dec->m_bg->referred_by_others = -1;
+ avs2_dec->m_bg->imgtr_fwRefDistance = -256;
+ init_frame_t(avs2_dec->m_bg);
+ avs2_dec->m_bg->index = refnum;
+#endif
+
+#if BCBR
+ /*init BCBR related*/
+ img->iNumCUsInFrame =
+ ((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
+ * ((img->height + MAX_CU_SIZE - 1)
+ / MAX_CU_SIZE);
+#endif
+ return memory_size;
+}
+
+#ifdef AML
+static void free_unused_buffers(struct avs2_decoder *avs2_dec)
+{
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+
+ int32_t refnum;
+
+ img->buf_cycle = input->buf_cycle + 1;
+
+ img->buf_cycle *= 2;
+
+ hc->background_ref = hc->backgroundReferenceFrame;
+
+ for (refnum = 0; refnum < REF_MAXBUFFER; refnum++) {
+#ifndef NO_DISPLAY
+ if (avs2_dec->fref[refnum]->vf_ref > 0 ||
+ avs2_dec->fref[refnum]->to_prepare_disp)
+ continue;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+ if (avs2_dec->fref[refnum]->backend_ref > 0)
+ continue;
+#endif
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("%s[t] avs2_dec->fref[%d]@0x%p\n",
+ __func__, refnum, avs2_dec->fref[refnum]);
+ avs2_dec->fref[refnum]->imgcoi_ref = -257;
+ avs2_dec->fref[refnum]->is_output = -1;
+ avs2_dec->fref[refnum]->referred_by_others = -1;
+ avs2_dec->fref[refnum]->imgtr_fwRefDistance = -256;
+ memset(avs2_dec->fref[refnum]->ref_poc, 0,
+ sizeof(avs2_dec->fref[refnum]->ref_poc));
+ }
+ avs2_dec->f_bg = NULL;
+
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("%s[t] avs2_dec->m_bg@0x%p\n",
+ __func__, avs2_dec->m_bg);
+ avs2_dec->m_bg->imgcoi_ref = -257;
+ avs2_dec->m_bg->is_output = -1;
+ avs2_dec->m_bg->referred_by_others = -1;
+ avs2_dec->m_bg->imgtr_fwRefDistance = -256;
+ memset(avs2_dec->m_bg->ref_poc, 0,
+ sizeof(avs2_dec->m_bg->ref_poc));
+
+#if BCBR
+ /*init BCBR related*/
+ img->iNumCUsInFrame =
+ ((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
+ * ((img->height + MAX_CU_SIZE - 1)
+ / MAX_CU_SIZE);
+#endif
+}
+#endif
+
+void init_frame_t(struct avs2_frame_s *currfref)
+{
+ memset(currfref, 0, sizeof(struct avs2_frame_s));
+ currfref->imgcoi_ref = -257;
+ currfref->is_output = -1;
+ currfref->referred_by_others = -1;
+ currfref->imgtr_fwRefDistance = -256;
+ memset(currfref->ref_poc, 0, sizeof(currfref->ref_poc));
+}
+
+void get_reference_list_info(struct avs2_decoder *avs2_dec, int8_t *str)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+
+ int8_t str_tmp[16];
+ int32_t i;
+
+ if (img->num_of_references > 0) {
+ strcpy(str, "[");
+ for (i = 0; i < img->num_of_references; i++) {
+#if RD1510_FIX_BG
+ if (img->type == B_IMG) {
+ sprintf(str_tmp, "%4d ",
+ hc->f_rec->ref_poc[img->num_of_references - 1 - i]);
+ } else {
+ sprintf(str_tmp, "%4d ",
+ hc->f_rec->ref_poc[i]);
+ }
+#else
+ sprintf(str_tmp, "%4d ",
+ avs2_dec->fref[i]->imgtr_fwRefDistance);
+#endif
+ str_tmp[5] = '\0';
+ strcat(str, str_tmp);
+ }
+ strcat(str, "]");
+ } else {
+ str[0] = '\0';
+ }
+}
+
+int prepare_RefInfo(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+ int32_t i, j;
+ int32_t ii;
+ int32_t tmp_ref;
+ struct avs2_frame_s *tmp_fref;
+ int32_t error_mark = 0;
+
+ /*update IDR frame*/
+ if (img->tr > hd->next_IDRtr && hd->curr_IDRtr != hd->next_IDRtr) {
+ hd->curr_IDRtr = hd->next_IDRtr;
+ hd->curr_IDRcoi = hd->next_IDRcoi;
+ }
+ /* re-order the ref buffer according to RPS*/
+ img->num_of_references = hd->curr_RPS.num_of_ref;
+
+ /*rain*/
+ if (is_avs2_print_bufmgr_detail()) {
+ pr_info("%s: coding_order is %d, curr_IDRcoi is %d\n",
+ __func__, img->coding_order, hd->curr_IDRcoi);
+ for (ii = 0; ii < MAXREF; ii++) {
+ pr_info("ref_pic(%d)=%d\n",
+ ii, hd->curr_RPS.ref_pic[ii]);
+ }
+ for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
+ pr_info(
+ "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d\n",
+ ii, avs2_dec->fref[ii]->index,
+ avs2_dec->fref[ii]->imgcoi_ref,
+ avs2_dec->fref[ii]->imgtr_fwRefDistance);
+ }
+ }
+
+ for (i = 0; i < hd->curr_RPS.num_of_ref; i++) {
+ /*int32_t accumulate = 0;*/
+ /* copy tmp_fref from avs2_dec->fref[i] */
+ tmp_fref = avs2_dec->fref[i];
+
+#if REMOVE_UNUSED
+ for (j = i; j < avs2_dec->ref_maxbuffer; j++) {
+ /*/////////////to be modified IDR*/
+ if (avs2_dec->fref[j]->imgcoi_ref == img->coding_order -
+ hd->curr_RPS.ref_pic[i]) {
+ break;
+ }
+ }
+#else
+
+ for (j = i; j < avs2_dec->ref_maxbuffer; j++) {
+ /*/////////////to be modified IDR*/
+ int32_t k , tmp_tr;
+ for (k = 0; k < avs2_dec->ref_maxbuffer; k++) {
+ if (((int32_t)img->coding_order -
+ (int32_t)hd->curr_RPS.ref_pic[i]) ==
+ avs2_dec->fref[k]->imgcoi_ref &&
+ avs2_dec->fref[k]->imgcoi_ref >= -256) {
+ break;
+ }
+ }
+ if (k == avs2_dec->ref_maxbuffer) {
+ tmp_tr = -1-1;
+ } else {
+ tmp_tr = avs2_dec->fref[k]->imgtr_fwRefDistance;
+ }
+ if (tmp_tr < hd->curr_IDRtr) {
+ hd->curr_RPS.ref_pic[i] = img->coding_order - hd->curr_IDRcoi;
+
+ for (k = 0; k < i; k++) {
+ if (hd->curr_RPS.ref_pic[k] ==
+ hd->curr_RPS.ref_pic[i]) {
+ accumulate++;
+ break;
+ }
+ }
+ }
+ if (avs2_dec->fref[j]->imgcoi_ref ==
+ img->coding_order - hd->curr_RPS.ref_pic[i]) {
+ break;
+ }
+ }
+ if (j == avs2_dec->ref_maxbuffer || accumulate)
+ img->num_of_references--;
+#endif
+ if (j != avs2_dec->ref_maxbuffer) {
+ /* copy avs2_dec->fref[i] from avs2_dec->fref[j] */
+ avs2_dec->fref[i] = avs2_dec->fref[j];
+ /* copy avs2_dec->fref[j] from ferf[tmp] */
+ avs2_dec->fref[j] = tmp_fref;
+ if (is_avs2_print_bufmgr_detail()) {
+ pr_info("%s, switch %d %d: ", __func__, i, j);
+ for (ii = 0; ii < hd->curr_RPS.num_of_ref || ii <= j; ii++)
+ pr_info("%d ",avs2_dec->fref[ii]->index);
+ pr_info("\n");
+ }
+ }
+ }
+ if ((img->type == B_IMG &&
+ (avs2_dec->fref[0]->imgtr_fwRefDistance <= img->tr
+ || avs2_dec->fref[1]->imgtr_fwRefDistance >= img->tr
+ || avs2_dec->fref[1]->imgtr_fwRefDistance == -256))) {
+ if (get_error_policy(avs2_dec) & 0x2) {
+ pr_info("wrong reference configuration for B frame\n");
+ pr_info("fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, img->tr %d\n",
+ avs2_dec->fref[0]->imgtr_fwRefDistance,
+ avs2_dec->fref[1]->imgtr_fwRefDistance,
+ img->tr);
+ if (avs2_dec->fref[1]->imgtr_fwRefDistance != -256) {
+ avs2_dec->bufmgr_error_flag = 1;
+ }
+ return -1;
+ } else {
+ error_mark = 1;
+ }
+ }
+ if (img->type == P_IMG) {
+ for (ii = 0; ii < img->num_of_references;ii++) {
+ tmp_ref = img->coding_order - hd->curr_RPS.ref_pic[ii];
+ if ((avs2_dec->fref[ii]->imgcoi_ref != tmp_ref) &&
+ (avs2_dec->fref[ii]->imgcoi_ref != (tmp_ref - 256))) {
+ if (get_error_policy(avs2_dec) & 0x2) {
+ pr_info("wrong reference configuration for P frame\n");
+ pr_info("fref[%d] imgcoi_ref %d, ref_pic[%d] %d\n",
+ ii,avs2_dec->fref[ii]->imgcoi_ref,
+ ii,hd->curr_RPS.ref_pic[ii]);
+ return -1;
+ } else {
+ error_mark = 1;
+ }
+ }
+ }
+ }
+
+#if !FIX_PROFILE_LEVEL_DPB_RPS_1
+ /* delete the frame that will never be used*/
+ for (i = 0; i < hd->curr_RPS.num_to_remove; i++) {
+ for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
+ if (avs2_dec->fref[j]->imgcoi_ref >= -256
+ && avs2_dec->fref[j]->imgcoi_ref
+ == img->coding_order -
+ hd->curr_RPS.remove_pic[i]) {
+ break;
+ }
+ }
+ if (j < avs2_dec->ref_maxbuffer &&
+ j >= img->num_of_references) {
+ avs2_dec->fref[j]->imgcoi_ref = -257;
+#if M3480_TEMPORAL_SCALABLE
+ avs2_dec->fref[j]->temporal_id = -1;
+#endif
+ if (avs2_dec->fref[j]->is_output == -1) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
+ }
+ }
+ }
+#endif
+
+ /* add inter-view reference picture*/
+
+ /* add current frame to ref buffer*/
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if ((avs2_dec->fref[i]->imgcoi_ref < -256
+ || abs(avs2_dec->fref[i]->imgtr_fwRefDistance - img->tr) >= 128)
+ && avs2_dec->fref[i]->is_output == -1
+ && avs2_dec->fref[i]->bg_flag == 0
+#ifdef NEW_FRONT_BACK_CODE
+ && avs2_dec->fref[i]->backend_ref == 0
+#endif
+ && avs2_dec->fref[i]->vf_ref == 0
+ && avs2_dec->fref[i]->to_prepare_disp == 0
+ ) {
+ break;
+ }
+ }
+
+ if (i == avs2_dec->ref_maxbuffer) {
+ pr_info("%s, warning, no enough buf\n", __func__);
+ return -2;
+ }
+
+ hc->f_rec = avs2_dec->fref[i];
+ hc->currentFrame = hc->f_rec->ref;
+ hc->f_rec->imgtr_fwRefDistance = img->tr;
+ hc->f_rec->imgcoi_ref = img->coding_order;
+#if M3480_TEMPORAL_SCALABLE
+ hc->f_rec->temporal_id = hd->cur_layer;
+#endif
+ hc->f_rec->is_output = 1;
+#ifdef AML
+ hc->f_rec->poc = img->tr;
+ hc->f_rec->error_mark = error_mark;
+ hc->f_rec->decoded_lcu = 0;
+ hc->f_rec->back_done_mark = 1;
+ hc->f_rec->slice_type = img->type;
+ hc->f_rec->time = div64_u64(local_clock(), 1000) - avs2_dec->start_time;
+#endif
+ hc->f_rec->referred_by_others = hd->curr_RPS.referred_by_others;
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d img_type %d\n",
+ __func__, i, img->tr, img->coding_order, img->type);
+
+ if (img->type != B_IMG) {
+ for (j = 0;
+ j < img->num_of_references; j++) {
+ hc->f_rec->ref_poc[j] = avs2_dec->fref[j]->imgtr_fwRefDistance;
+ }
+ } else {
+ hc->f_rec->ref_poc[0] = avs2_dec->fref[1]->imgtr_fwRefDistance;
+ hc->f_rec->ref_poc[1] = avs2_dec->fref[0]->imgtr_fwRefDistance;
+ }
+
+#if M3480_TEMPORAL_SCALABLE
+
+ for (j = img->num_of_references;
+ j < 4; j++) {
+ /**/
+ hc->f_rec->ref_poc[j] = 0;
+ }
+
+ if (img->type == INTRA_IMG) {
+ int32_t l;
+ for (l = 0; l < 4; l++) {
+ hc->f_rec->ref_poc[l] = img->tr;
+ }
+ }
+
+#endif
+
+/*////////////////////////////////////////////////////////////////////////*/
+ /* updata ref pointer*/
+
+ if (img->type != I_IMG) {
+
+ img->imgtr_next_P = img->type == B_IMG ?
+ avs2_dec->fref[0]->imgtr_fwRefDistance : img->tr;
+ if (img->type == B_IMG) {
+ hd->trtmp = avs2_dec->fref[0]->imgtr_fwRefDistance;
+ avs2_dec->fref[0]->imgtr_fwRefDistance =
+ avs2_dec->fref[1]->imgtr_fwRefDistance;
+ }
+ }
+
+ /*rain*/
+ if (is_avs2_print_bufmgr_detail()) {
+ for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
+ pr_info(
+ "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, is_out %d, bg %d, vf_ref %d, backend_ref %d, ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
+ ii, avs2_dec->fref[ii]->index,
+ avs2_dec->fref[ii]->imgcoi_ref,
+ avs2_dec->fref[ii]->imgtr_fwRefDistance,
+ avs2_dec->fref[ii]->referred_by_others,
+ avs2_dec->fref[ii]->is_output,
+ avs2_dec->fref[ii]->bg_flag,
+ avs2_dec->fref[ii]->vf_ref,
+#ifdef NEW_FRONT_BACK_CODE
+ avs2_dec->fref[ii]->backend_ref,
+#else
+ 0,
+#endif
+ avs2_dec->fref[ii]->ref_poc[0],
+ avs2_dec->fref[ii]->ref_poc[1],
+ avs2_dec->fref[ii]->ref_poc[2],
+ avs2_dec->fref[ii]->ref_poc[3],
+ avs2_dec->fref[ii]->ref_poc[4],
+ avs2_dec->fref[ii]->ref_poc[5],
+ avs2_dec->fref[ii]->ref_poc[6]);
+ }
+ }
+ return 0;
+}
+
+int32_t init_frame(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+#if RD1510_FIX_BG
+ if (img->type == I_IMG &&
+ img->typeb == BACKGROUND_IMG) { /*G/GB frame*/
+ img->num_of_references = 0;
+ } else if (img->type == P_IMG && img->typeb == BP_IMG) {
+ /* only one reference frame(G\GB) for S frame*/
+ img->num_of_references = 1;
+ }
+#endif
+
+ if (img->typeb == BACKGROUND_IMG &&
+ hd->background_picture_output_flag == 0) {
+ hc->currentFrame = hc->background_ref;
+#ifdef AML
+ hc->cur_pic = avs2_dec->m_bg;
+#endif
+ } else {
+ if (prepare_RefInfo(avs2_dec) < 0)
+ return -1;
+#ifdef AML
+ hc->cur_pic = hc->f_rec;
+#endif
+ }
+
+#ifdef FIX_CHROMA_FIELD_MV_BK_DIST
+ if (img->typeb == BACKGROUND_IMG
+ && img->is_field_sequence) {
+ avs2_dec->bk_img_is_top_field = img->is_top_field;
+ }
+#endif
+ return 0;
+}
+
+void delete_trbuffer(struct outdata_s *data, int32_t pos)
+{
+ int32_t i;
+ for (i = pos; i < data->buffer_num - 1; i++) {
+ data->stdoutdata[i] = data->stdoutdata[i + 1];
+ }
+ data->buffer_num--;
+}
+
+#if RD170_FIX_BG
+void flushDPB(struct avs2_decoder *avs2_dec)
+{
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ int j, tmp_min, i, pos = -1;
+ int search_times = avs2_dec->outprint.buffer_num;
+
+ tmp_min = 1 << 20;
+ i = 0, j = 0;
+ pos = -1;
+
+ for (j = 0; j < search_times; j++) {
+ pos = -1;
+ tmp_min = (1 << 20);
+ /*search for min poi picture to display*/
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
+ if (avs2_dec->outprint.stdoutdata[i].tr < tmp_min) {
+ pos = i;
+ tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
+ }
+ }
+
+ if (pos != -1) {
+ hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
+ report_frame(avs2_dec, &avs2_dec->outprint, pos);
+ if (avs2_dec->outprint.stdoutdata[pos].typeb
+ == BACKGROUND_IMG &&
+ avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag
+ == 0) {
+ /*write_GB_frame(hd->p_out_background);*/
+ } else {
+ write_frame(avs2_dec,
+ avs2_dec->outprint.stdoutdata[pos].tr);
+ }
+
+ delete_trbuffer(&avs2_dec->outprint, pos);
+ }
+ }
+
+ /*clear dpb info*/
+ for (j = 0; j < REF_MAXBUFFER; j++) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
+ avs2_dec->fref[j]->imgcoi_ref = -257;
+ avs2_dec->fref[j]->temporal_id = -1;
+ avs2_dec->fref[j]->referred_by_others = 0;
+ }
+}
+#endif
+
+static int frame_postprocessing(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+ int32_t pointer_tmp = avs2_dec->outprint.buffer_num;
+ int32_t i;
+ struct STDOUT_DATA_s *p_outdata;
+#if RD160_FIX_BG
+ int32_t j, tmp_min, output_cur_dec_pic, pos = -1;
+ int32_t search_times = avs2_dec->outprint.buffer_num;
+#endif
+ /*pic dist by Grandview Semi. @ [06-07-20 15:25]*/
+ img->PrevPicDistanceLsb = (img->coding_order % 256);
+
+ pointer_tmp = avs2_dec->outprint.buffer_num;
+ p_outdata = &avs2_dec->outprint.stdoutdata[pointer_tmp];
+
+ p_outdata->type = img->type;
+ p_outdata->typeb = img->typeb;
+ p_outdata->frame_num = img->tr;
+ p_outdata->tr = img->tr;
+
+ p_outdata->qp = 0;
+
+ p_outdata->tmp_time = hd->tmp_time;
+ p_outdata->picture_structure = img->picture_structure;
+
+#if RD1501_FIX_BG
+ p_outdata->background_picture_output_flag = hd->background_picture_output_flag;
+ /*Longfei.Wang@mediatek.com*/
+#endif
+
+#if RD160_FIX_BG
+ p_outdata->picture_reorder_delay = hd->picture_reorder_delay;
+#endif
+ avs2_dec->outprint.buffer_num++;
+
+#if RD170_FIX_BG
+ search_times = avs2_dec->outprint.buffer_num;
+#endif
+ /* record the reference list*/
+ strcpy(p_outdata->str_reference_list, hc->str_list_reference);
+
+#if !REF_OUTPUT
+ #error "!!!REF_OUTPUT should be 1"
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
+ min_tr(avs2_dec->outprint, &pos);
+ if (avs2_dec->outprint.stdoutdata[pos].tr < img->tr
+ || avs2_dec->outprint.stdoutdata[pos].tr
+ == (hd->last_output + 1)) {
+ hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
+ report_frame(avs2_dec, &avs2_dec->outprint, pos);
+ delete_trbuffer(&avs2_dec->outprint, pos);
+ i--;
+ } else {
+ break;
+ }
+ }
+#else
+#if RD160_FIX_BG /*Longfei.Wang@mediatek.com*/
+ tmp_min = 1 << 20;
+ i = 0, j = 0;
+ output_cur_dec_pic = 0;
+ pos = -1;
+ for (j = 0; j < search_times; j++) {
+ pos = -1;
+ tmp_min = (1 << 20);
+ /*search for min poi picture to display*/
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
+ if ((avs2_dec->outprint.stdoutdata[i].tr < tmp_min) &&
+ ((avs2_dec->outprint.stdoutdata[i].tr
+ + avs2_dec->outprint.stdoutdata[i].picture_reorder_delay)
+ <= (int32_t)img->coding_order)) {
+ pos = i;
+ tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
+ }
+ }
+
+ if ((0 == hd->displaydelay) && (0 == output_cur_dec_pic)) {
+ if (img->tr <= tmp_min) {/*fred.chiu@mediatek.com*/
+ /*output current decode picture
+ right now*/
+ pos = avs2_dec->outprint.buffer_num - 1;
+ output_cur_dec_pic = 1;
+ }
+ }
+ if (pos != -1) {
+ hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
+ report_frame(avs2_dec, &avs2_dec->outprint, pos);
+ if (avs2_dec->outprint.stdoutdata[pos].typeb
+ == BACKGROUND_IMG &&
+ avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag == 0) {
+ } else {
+ write_frame(avs2_dec, avs2_dec->outprint.stdoutdata[pos].tr);
+ }
+ delete_trbuffer(&avs2_dec->outprint, pos);
+ }
+
+ }
+
+#else
+ #error "!!!RD160_FIX_BG should be defined"
+ if (img->coding_order +
+ (uint32_t)hc->total_frames * 256 >=
+ (uint32_t)hd->picture_reorder_delay) {
+ int32_t tmp_min, pos = -1;
+ tmp_min = 1 << 20;
+
+ for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
+ if (avs2_dec->outprint.stdoutdata[i].tr
+ < tmp_min &&
+ avs2_dec->outprint.stdoutdata[i].tr
+ >= hd->last_output) {
+ /*GB has the same "tr" with "last_output"*/
+ pos = i;
+ tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
+ }
+ }
+
+ if (pos != -1) {
+ hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
+ report_frame(avs2_dec, &avs2_dec->outprint, pos);
+#if RD1501_FIX_BG
+ if (avs2_dec->outprint.stdoutdata[pos].typeb
+ == BACKGROUND_IMG && avs2_dec->
+ outprint.stdoutdata[pos].
+ background_picture_output_flag == 0) {
+#else
+ if (avs2_dec->outprint.stdoutdata[pos].typeb
+ == BACKGROUND_IMG &&
+ hd->background_picture_output_flag == 0) {
+#endif
+ write_GB_frame(hd->p_out_background);
+ } else {
+ write_frame(avs2_dec,
+ avs2_dec->outprint.stdoutdata[pos].tr);
+ }
+ delete_trbuffer(&avs2_dec->outprint, pos);
+ }
+
+ }
+#endif
+#endif
+ return pos;
+ }
+
+void write_frame(struct avs2_decoder *avs2_dec, int32_t pos)
+{
+ int32_t j;
+
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("%s(pos = %d)\n", __func__, pos);
+
+ for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
+ if (avs2_dec->fref[j]->imgtr_fwRefDistance == pos) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance_bak = pos;
+ avs2_dec->fref[j]->is_output = -1;
+ avs2_dec->fref[j]->to_prepare_disp =
+ avs2_dec->to_prepare_disp_count++;
+ if (avs2_dec->fref[j]->referred_by_others == 0
+ || avs2_dec->fref[j]->imgcoi_ref == -257) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
+ avs2_dec->fref[j]->imgcoi_ref = -257;
+#if M3480_TEMPORAL_SCALABLE
+ avs2_dec->fref[j]->temporal_id = -1;
+#endif
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("%s, fref index %d\n", __func__, j);
+ }
+ break;
+ }
+ }
+}
+
+/*rain???, outdata *data*/
+void report_frame(struct avs2_decoder *avs2_dec,
+ struct outdata_s *data, int32_t pos)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+ int8_t *Frmfld;
+ int8_t Frm[] = "FRM";
+ int8_t Fld[] = "FLD";
+ struct STDOUT_DATA_s *p_stdoutdata = &data->stdoutdata[pos];
+ const int8_t *typ;
+
+ if (p_stdoutdata->picture_structure) {
+ Frmfld = Frm;
+ } else {
+ Frmfld = Fld;
+ }
+#if INTERLACE_CODING
+ if (img->is_field_sequence) { /*rcs??*/
+ Frmfld = Fld;
+ }
+#endif
+ if ((p_stdoutdata->tr + hc->total_frames * 256)
+ == hd->end_SeqTr) { /* I picture*/
+ {
+ img->sequence_end_flag = 0;
+ }
+ }
+ if ((p_stdoutdata->tr + hc->total_frames * 256)
+ == hd->next_IDRtr) {
+#if !RD170_FIX_BG
+ if (hd->vec_flag) /**/
+#endif
+ {
+ hd->vec_flag = 0;
+ }
+ }
+
+ if (p_stdoutdata->typeb == BACKGROUND_IMG) {
+ typ = (hd->background_picture_output_flag != 0) ? "G" : "GB";
+ } else {
+#if REMOVE_UNUSED
+ typ = (p_stdoutdata->type == INTRA_IMG)
+ ? "I" : (p_stdoutdata->type == INTER_IMG) ?
+ ((p_stdoutdata->typeb == BP_IMG) ? "S" : "P")
+ : (p_stdoutdata->type == F_IMG ? "F" : "B");
+#else
+ typ = (p_stdoutdata->type == INTRA_IMG) ? "I" :
+ (p_stdoutdata->type == INTER_IMG) ?
+ ((p_stdoutdata->type == BP_IMG) ? "S" : "P")
+ : (p_stdoutdata->type == F_IMG ? "F" : "B");
+#endif
+ }
+
+ if (is_avs2_print_bufmgr_detail())
+ pr_info(" %s\n", p_stdoutdata->str_reference_list);
+
+ hd->FrameNum++;
+}
+
+void avs2_prepare_header(struct avs2_decoder *avs2_dec, int32_t start_code)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+
+ switch (start_code) {
+ case SEQUENCE_HEADER_CODE:
+ img->new_sequence_flag = 1;
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("SEQUENCE\n");
+#ifdef TO_CHECK
+#if SEQ_CHANGE_CHECKER
+ if (seq_checker_buf == NULL) {
+ seq_checker_buf = malloc(length);
+ seq_checker_length = length;
+ memcpy(seq_checker_buf, Buf, length);
+ } else {
+ if ((seq_checker_length != length) ||
+ (memcmp(seq_checker_buf, Buf, length) != 0)) {
+ free(seq_checker_buf);
+#if RD170_FIX_BG
+ seq_checker_buf = NULL;
+ seq_checker_length = 0;
+ seq_checker_buf = malloc(length);
+ seq_checker_length = length;
+ memcpy(seq_checker_buf, Buf, length);
+#endif
+ }
+ }
+#endif
+#if RD170_FIX_BG
+ if (input->alf_enable && alfParAllcoated == 1) {
+ ReleaseAlfGlobalBuffer();
+ alfParAllcoated = 0;
+ }
+#endif
+/*TO_CHECK*/
+#endif
+#if FIX_FLUSH_DPB_BY_LF
+ if (hd->vec_flag) {
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("vec_flag is 1, flushDPB and reinit bugmgr\n");
+
+ flushDPB(avs2_dec);
+
+ hd->vec_flag = 0;
+#ifdef AML
+ free_unused_buffers(avs2_dec);
+#else
+ free_global_buffers(avs2_dec);
+#endif
+ img->number = 0;
+ img->PrevPicDistanceLsb = 0;
+ avs2_dec->init_hw_flag = 0;
+ }
+#endif
+
+#if FIX_SEQ_END_FLUSH_DPB_BY_LF
+ if (img->new_sequence_flag
+ && img->sequence_end_flag) {
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("new_sequence_flag after sequence_end_flag, flushDPB and reinit bugmgr\n");
+ flushDPB(avs2_dec);
+
+#ifdef AML
+ free_unused_buffers(avs2_dec);
+#else
+ free_global_buffers(avs2_dec);
+#endif
+ img->number = 0;
+ img->PrevPicDistanceLsb = 0;
+ avs2_dec->init_hw_flag = 0;
+ }
+#endif
+ img->seq_header_indicate = 1;
+ break;
+ case I_PICTURE_START_CODE:
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("PIC-I\n");
+ Get_SequenceHeader(avs2_dec);
+ Get_I_Picture_Header(avs2_dec);
+ calc_picture_distance(avs2_dec);
+ Read_ALF_param(avs2_dec);
+ if (!img->seq_header_indicate) {
+ img->B_discard_flag = 1;
+ break;
+ }
+ break;
+ case PB_PICTURE_START_CODE:
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("PIC-PB\n");
+ Get_SequenceHeader(avs2_dec);
+ Get_PB_Picture_Header(avs2_dec);
+ calc_picture_distance(avs2_dec);
+ Read_ALF_param(avs2_dec);
+ /* xiaozhen zheng, 20071009*/
+ if (!img->seq_header_indicate) {
+ img->B_discard_flag = 1;
+ break;
+ }
+
+ if (img->seq_header_indicate == 1
+ && img->type != B_IMG) {
+ img->B_discard_flag = 0;
+ }
+ if (img->type == B_IMG && img->B_discard_flag == 1
+ && !img->random_access_decodable_flag) {
+ break;
+ }
+
+ break;
+ case SEQUENCE_END_CODE:
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("SEQUENCE_END_CODE\n");
+#ifdef TO_CHECK
+#if SEQ_CHANGE_CHECKER
+ if (seq_checker_buf != NULL) {
+ free(seq_checker_buf);
+ seq_checker_buf = NULL;
+ seq_checker_length = 0;
+ }
+#endif
+#endif
+img->new_sequence_flag = 1;
+img->sequence_end_flag = 1;
+break;
+ case VIDEO_EDIT_CODE:
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("VIDEO_EDIT_CODE\n");
+ hd->vec_flag = 1;
+#ifdef TO_CHECK
+#if SEQ_CHANGE_CHECKER
+ if (seq_checker_buf != NULL) {
+ free(seq_checker_buf);
+ seq_checker_buf = NULL;
+ seq_checker_length = 0;
+ }
+#endif
+#endif
+
+break;
+ }
+}
+
+#ifdef AML
+static uint32_t log2i(uint32_t val)
+{
+ uint32_t ret = -1;
+ while (val != 0) {
+ val >>= 1;
+ ret++;
+ }
+ return ret;
+}
+#endif
+
+int32_t avs2_process_header(struct avs2_decoder *avs2_dec)
+{
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ int32_t lcu_x_num_div;
+ int32_t lcu_y_num_div;
+
+ int32_t N8_SizeScale;
+ {
+ N8_SizeScale = 1;
+
+ if (hd->horizontal_size %
+ (MIN_CU_SIZE * N8_SizeScale) != 0) {
+ img->auto_crop_right =
+ (MIN_CU_SIZE * N8_SizeScale) -
+ (hd->horizontal_size %
+ (MIN_CU_SIZE * N8_SizeScale));
+ } else
+ img->auto_crop_right = 0;
+
+#if !INTERLACE_CODING
+ if (hd->progressive_sequence) /**/
+#endif
+ {
+ if (hd->vertical_size %
+ (MIN_CU_SIZE * N8_SizeScale) != 0) {
+ img->auto_crop_bottom =
+ (MIN_CU_SIZE * N8_SizeScale) -
+ (hd->vertical_size %
+ (MIN_CU_SIZE * N8_SizeScale));
+ } else
+ img->auto_crop_bottom = 0;
+ }
+
+ /* Reinit parameters (NOTE: need to do
+ before init_frame //*/
+ img->width =
+ (hd->horizontal_size + img->auto_crop_right);
+ img->height =
+ (hd->vertical_size + img->auto_crop_bottom);
+ img->width_cr = (img->width >> 1);
+
+ if (input->chroma_format == 1)
+ img->height_cr = (img->height >> 1);
+
+ img->PicWidthInMbs = img->width / MIN_CU_SIZE;
+ img->PicHeightInMbs = img->height / MIN_CU_SIZE;
+ img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
+ img->max_mb_nr = (img->width * img->height) / (MIN_CU_SIZE * MIN_CU_SIZE);
+ }
+
+ if (img->new_sequence_flag && img->sequence_end_flag) {
+ hd->end_SeqTr = img->tr;
+ img->sequence_end_flag = 0;
+ }
+ if (img->new_sequence_flag) {
+ hd->next_IDRtr = img->tr;
+ hd->next_IDRcoi = img->coding_order;
+ img->new_sequence_flag = 0;
+ }
+
+ img->current_mb_nr = 0;
+
+ if (init_frame(avs2_dec) < 0) {
+ pr_info("%s, warning, init_frame error!\n", __func__);
+ return -1;
+ }
+
+ img->types = img->type; /* jlzheng 7.15*/
+
+ if (img->type != B_IMG) {
+ hd->pre_img_type = img->type;
+ hd->pre_img_types = img->types;
+ }
+
+#ifdef AML
+ avs2_dec->lcu_size_log2 = log2i(avs2_dec->lcu_size);
+ lcu_x_num_div = (img->width/avs2_dec->lcu_size);
+ lcu_y_num_div = (img->height/avs2_dec->lcu_size);
+ avs2_dec->lcu_x_num = ((img->width % avs2_dec->lcu_size) == 0) ?
+ lcu_x_num_div : lcu_x_num_div+1;
+ avs2_dec->lcu_y_num = ((img->height % avs2_dec->lcu_size) == 0) ?
+ lcu_y_num_div : lcu_y_num_div+1;
+ avs2_dec->lcu_total = avs2_dec->lcu_x_num*avs2_dec->lcu_y_num;
+#endif
+ return SOP;
+}
+
+int avs2_post_process(struct avs2_decoder *avs2_dec)
+{
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ int32_t i;
+ int ret;
+ if (img->typeb == BACKGROUND_IMG && hd->background_picture_enable) {
+#ifdef AML
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if (avs2_dec->fref[i]->bg_flag != 0) {
+ avs2_dec->fref[i]->bg_flag = 0;
+ if (is_avs2_print_bufmgr_detail())
+ pr_info(
+ "clear old BACKGROUND_IMG for index %d\r\n",
+ avs2_dec->fref[i]->index);
+ }
+ }
+ if (is_avs2_print_bufmgr_detail())
+ pr_info(
+ "post_process: set BACKGROUND_IMG flag for %d\r\n",
+ hc->cur_pic->index);
+ avs2_dec->f_bg = hc->cur_pic;
+ hc->cur_pic->bg_flag = 1;
+#endif
+ }
+
+#if BCBR
+ if (hd->background_picture_enable
+ && hd->bcbr_enable && img->number > 0)
+ updateBgReference();
+#endif
+
+ if (img->typeb == BACKGROUND_IMG &&
+ hd->background_picture_output_flag == 0)
+ hd->background_number++;
+
+ if (img->type == B_IMG) {
+ avs2_dec->fref[0]->imgtr_fwRefDistance
+ = hd->trtmp;
+ }
+
+ /* record the reference list information*/
+ get_reference_list_info(avs2_dec, avs2_dec->hc.str_list_reference);
+
+ ret = frame_postprocessing(avs2_dec);
+
+#if FIX_PROFILE_LEVEL_DPB_RPS_1
+ /* delete the frame that will never be used*/
+ {
+ int32_t i, j;
+ if (is_avs2_print_bufmgr_detail()) {
+ pr_info("%s, coding_order %d to remove %d buf: ",
+ __func__,
+ img->coding_order,
+ hd->curr_RPS.num_to_remove);
+ for (i = 0; i < hd->curr_RPS.num_to_remove; i++)
+ pr_info("%d ", hd->curr_RPS.remove_pic[i]);
+ pr_info("\n");
+ }
+ for (i = 0; i < hd->curr_RPS.num_to_remove; i++) {
+ for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
+
+ if (avs2_dec->fref[j]->imgcoi_ref >= -256
+ && avs2_dec->fref[j]->imgcoi_ref ==
+ img->coding_order -
+ hd->curr_RPS.remove_pic[i])
+ break;
+ }
+ if (j < avs2_dec->ref_maxbuffer) { /**/
+#if FIX_RPS_PICTURE_REMOVE
+/* Label new frames as "un-referenced" */
+ avs2_dec->fref[j]->referred_by_others = 0;
+
+ /* remove frames which have been outputted */
+ if (avs2_dec->fref[j]->is_output == -1) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
+ avs2_dec->fref[j]->imgcoi_ref = -257;
+ avs2_dec->fref[j]->temporal_id = -1;
+
+ }
+#else
+ avs2_dec->fref[j]->imgcoi_ref = -257;
+#if M3480_TEMPORAL_SCALABLE
+ avs2_dec->fref[j]->temporal_id = -1;
+#endif
+ if (avs2_dec->fref[j]->is_output == -1) {
+ avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
+ }
+#endif
+ }
+ }
+ }
+#endif
+
+ /*! TO 19.11.2001 Known Problem: for init_frame
+ * we have to know the picture type of the
+ * actual frame*/
+ /*! in case the first slice of the P-Frame
+ * following the I-Frame was lost we decode this
+ * P-Frame but! do not write it because it
+ * was
+ * assumed to be an I-Frame in init_frame.So we
+ * force the decoder to*/
+ /*! guess the right picture type. This is a hack
+ * a should be removed by the time there is a
+ * clean*/
+ /*! solution where we do not have to know the
+ * picture type for the function init_frame.*/
+ /*! End TO 19.11.2001//Lou*/
+
+ {
+ if (img->type == I_IMG ||
+ img->type == P_IMG ||
+ img->type == F_IMG)
+ img->number++;
+ else {
+ hc->Bframe_ctr++; /* B
+ pictures*/
+ }
+ }
+ return ret;
+}
+
+void init_avs2_decoder(struct avs2_decoder *avs2_dec)
+{
+ int32_t i, j, k;
+
+ struct inp_par *input = &avs2_dec->input;
+ struct ImageParameters_s *img = &avs2_dec->img;
+ struct Video_Com_data_s *hc = &avs2_dec->hc;
+ struct Video_Dec_data_s *hd = &avs2_dec->hd;
+ if (is_avs2_print_bufmgr_detail())
+ pr_info("[t] struct avs2_dec @0x%p\n", avs2_dec);
+ memset(avs2_dec, 0, sizeof(struct avs2_decoder));
+#ifdef AML
+ avs2_dec->to_prepare_disp_count = 1;
+#endif
+ /*
+ * ALFParam init
+ */
+ for (i = 0; i < 3; i++) {
+ avs2_dec->m_alfPictureParam[i].alf_flag = 0; /*1*/
+ avs2_dec->m_alfPictureParam[i].num_coeff = 9; /*1*/
+ avs2_dec->m_alfPictureParam[i].filters_per_group = 3; /*1*/
+ avs2_dec->m_alfPictureParam[i].componentID = i; /*1*/
+ for (j = 0; j < 16; j++) {
+ avs2_dec->m_alfPictureParam[i].filterPattern[j] = 0;
+ /*16*/
+ }
+ for (j = 0; j < 16; j++) {
+ for (k = 0; k < 9; k++) {
+ avs2_dec->m_alfPictureParam[i].coeffmulti[j][k] = 0;
+ /*16*9*/
+ }
+ }
+ }
+
+ img->seq_header_indicate = 0;
+ img->B_discard_flag = 0;
+
+ hd->eos = 0;
+
+ if (input->ref_pic_order) { /*ref order*/
+ hd->dec_ref_num = 0;
+ }
+
+ avs2_dec->outprint.buffer_num = 0;
+
+ hd->last_output = -1;
+ hd->end_SeqTr = -1;
+ hd->curr_IDRtr = 0;
+ hd->curr_IDRcoi = 0;
+ hd->next_IDRtr = 0;
+ hd->next_IDRcoi = 0;
+ /* Allocate Slice data struct*/
+ img->number = 0;
+ img->type = I_IMG;
+
+ img->imgtr_next_P = 0;
+
+ img->imgcoi_next_ref = 0;
+
+ img->num_of_references = 0;
+ hc->seq_header = 0;
+
+ img->new_sequence_flag = 1;
+
+ hd->vec_flag = 0;
+
+ hd->FrameNum = 0;
+
+ /* B pictures*/
+ hc->Bframe_ctr = 0;
+ hc->total_frames = 0;
+
+ /* time for total decoding session*/
+ hc->tot_time = 0;
+}
+
diff --git a/drivers/frame_provider/decoder/avs2_fb/avs2_fb_hw.c b/drivers/frame_provider/decoder/avs2_fb/avs2_fb_hw.c
new file mode 100644
index 0000000..911b65b
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_fb_hw.c
@@ -0,0 +1,2840 @@
+#include "../../../include/regs/dos_registers.h"
+
+#define LPF_SPCC_ENABLE
+
+/* to do */
+//#define DOUBLE_WRITE_VH0_TEMP 0
+//#define DOUBLE_WRITE_VH1_TEMP 0
+//#define DOUBLE_WRITE_VH0_HALF 0
+//#define DOUBLE_WRITE_VH1_HALF 0
+//#define DOS_BASE_ADR 0
+
+//#define HEVCD_MPP_DECOMP_AXIURG_CTL 0
+
+/**/
+#ifdef FOR_S5
+ulong dos_reg_compat_convert(ulong adr);
+#endif
+#define print_scratch_error(a)
+//#define MEM_MAP_MODE 0
+
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec);
+
+//typedef union param_u param_t;
+static void WRITE_BACK_RET(struct avs2_decoder *avs2_dec)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0xcc00000; //ret
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "WRITE_BACK_RET()\ninstruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0; //nop
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+}
+
+static void WRITE_BACK_8(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint8_t data)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x20<<22) | ((spr_addr&0xfff)<<8) | (data&0xff); //mtspi data, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data,
+ avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void WRITE_BACK_16(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint8_t rd_addr, uint16_t data)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6) | (rd_addr&0x3f); // movi rd_addr, data[15:0]
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x,%x)\ninstruction[%3d] = %8x, data= %x\n",
+ __func__, spr_addr, rd_addr, data,
+ avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], data&0xffff);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f); // mtsp rd_addr, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void WRITE_BACK_32(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint32_t data)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6); // movi COMMON_REG_0, data
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data,
+ avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ data = (data & 0xffff0000)>>16;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1b<<22) | (data<<6); // mvihi COMMON_REG_0, data[31:16]
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8); // mtsp COMMON_REG_0, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void READ_INS_WRITE(struct avs2_decoder *avs2_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t position, uint8_t size)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+ //spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+ spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x,%x,%x,%x)\n",
+ __func__, spr_addr0, spr_addr1, rd_addr, position, size);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f); //mtsp rd_addr, src_addr1
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+//Caution: pc offset fixed to 4, the data of cmp_addr need ready before call this function
+void READ_CMP_WRITE(struct avs2_decoder *avs2_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t cmp_addr, uint8_t position, uint8_t size)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+ //spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+ spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x,%x,%x,%x,%x)\n",
+ __func__, spr_addr0, spr_addr1, rd_addr, cmp_addr, position, size);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x29<<22) | (4<<12) | ((rd_addr&0x3f)<<6) | cmp_addr; //cbne current_pc+4, rd_addr, cmp_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0; //nop
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f); //mtsp rd_addr, src_addr1
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void READ_WRITE_DATA16(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint16_t data, uint8_t position, uint8_t size)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ struct AVS2Decoder_s, avs2_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8); //mfsp COMON_REG_0, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s(%x,%x,%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data, position, size,
+ avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | (data<<6) | 1; //movi COMMON_REG_1, data
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | (0<<6) | 1; //ins COMMON_REG_0, COMMON_REG_1, position, size
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8); //mtsp COMMON_REG_0, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+ WRITE_BACK_RET(avs2_dec);
+ avs2_dec->ins_offset = 256;
+ }
+#endif
+}
+
+#if 0
+void READ_BACK_32(struct AVS2Decoder_s *dec, uint32_t spr_addr, uint8_t rd_addr)
+{
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, spr_addr
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+}
+#endif
+
+static int32_t config_mc_buffer_fb(struct AVS2Decoder_s *dec)
+{
+ int32_t i,j;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+ struct avs2_frame_s *pic;
+ //if (avs2_dec->img.type == I_IMG)
+ // return 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "Entered config_mc_buffer....\n");
+ if (avs2_dec->f_bg != NULL) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+ avs2_dec->f_bg->mc_canvas_y, avs2_dec->f_bg->mc_canvas_u_v);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (7 << 8) | (0<<1) | 1); // L0:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (15 << 8) | (0<<1) | 1); // L0:BG
+ WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (15 << 8) | (0<<1) | 1); // L0:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (avs2_dec->f_bg->mc_canvas_u_v<<16)|(avs2_dec->f_bg->mc_canvas_u_v<<8)|avs2_dec->f_bg->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs2_dec->f_bg->mc_canvas_u_v<<16)|(avs2_dec->f_bg->mc_canvas_u_v<<8)|avs2_dec->f_bg->mc_canvas_y);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (23 << 8) | (0<<1) | 1); // L1:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (31 << 8) | (0<<1) | 1); // L1:BG
+ WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (31 << 8) | (0<<1) | 1); // L1:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (avs2_dec->f_bg->mc_canvas_u_v<<16)|(avs2_dec->f_bg->mc_canvas_u_v<<8)|avs2_dec->f_bg->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs2_dec->f_bg->mc_canvas_u_v<<16)|(avs2_dec->f_bg->mc_canvas_u_v<<8)|avs2_dec->f_bg->mc_canvas_y);
+
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+ for (j = 0; j < MAXREF; j++) {
+ if (avs2_dec->f_bg == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = avs2_dec->f_bg;
+ break;
+ }
+ }
+#endif
+ }
+
+ if (avs2_dec->img.type == I_IMG)
+ return 0;
+
+ if (avs2_dec->img.type == P_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for P_IMG, img type %d\n", avs2_dec->img.type);
+ //refer to prepare_RefInfo()
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+#endif
+
+ }
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
+ } else if (avs2_dec->img.type == F_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for F_IMG, img type %d\n", avs2_dec->img.type);
+ //refer to prepare_RefInfo()
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+#endif
+ }
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+ WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (16 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ } else {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for B_IMG\n");
+ //refer to prepare_RefInfo()
+ pic = avs2_dec->fref[1];
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", 1, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+#endif
+
+ pic = avs2_dec->fref[0];
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+ WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (16 << 8) | (0<<1) | 1);
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n", 0, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+#endif
+ }
+ return 0;
+}
+
+#ifdef NEW_FRONT_BACK_CODE
+/*copy from simulation code*/
+
+#define FB_LMEM_SIZE_LOG2 6
+#define FB_LMEM_SIZE (1 << FB_LMEM_SIZE_LOG2)
+#define FB_VCPU_IMEM_SIZE 0x400
+#define FB_SYSTEM_IMEM_SIZE 0x400
+#define FB_SCALELUT_LMEM_SIZE 0x400
+
+#if 0
+#define FB_PARSER_SAO0_BLOCK_SIZE (4*1024*4)*64
+#define FB_PARSER_SAO1_BLOCK_SIZE (4*1024*4)*64
+#define FB_MPRED_IMP0_BLOCK_SIZE (4*1024*4)*256
+#define FB_MPRED_IMP1_BLOCK_SIZE (4*1024*4)*256
+#else
+#define FB_PARSER_SAO0_BLOCK_SIZE (4*1024*4)
+#define FB_PARSER_SAO1_BLOCK_SIZE (4*1024*4)
+#define FB_MPRED_IMP0_BLOCK_SIZE (4*1024*4)
+#define FB_MPRED_IMP1_BLOCK_SIZE (4*1024*4)
+#endif
+/**/
+#define BUF_BLOCK_NUM 256
+
+#define FB_IFBUF_SCALELUT_BLOCK_SIZE FB_SCALELUT_LMEM_SIZE
+#define FB_IFBUF_VCPU_IMEM_BLOCK_SIZE FB_VCPU_IMEM_SIZE
+#define FB_IFBUF_SYS_IMEM_BLOCK_SIZE FB_SYSTEM_IMEM_SIZE
+#define FB_IFBUF_LMEM0_BLOCK_SIZE FB_LMEM_SIZE
+#define FB_IFBUF_LMEM1_BLOCK_SIZE FB_LMEM_SIZE
+
+#define IFBUF_SCALELUT_SIZE (FB_IFBUF_SCALELUT_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_VCPU_IMEM_SIZE (FB_IFBUF_VCPU_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_SYS_IMEM_SIZE (FB_IFBUF_SYS_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM0_SIZE (FB_IFBUF_LMEM0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM1_SIZE (FB_IFBUF_LMEM1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO0_SIZE (FB_PARSER_SAO0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO1_SIZE (FB_PARSER_SAO1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP0_SIZE (FB_MPRED_IMP0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP1_SIZE (FB_MPRED_IMP1_BLOCK_SIZE * BUF_BLOCK_NUM)
+
+static void copy_loopbufs_ptr(buff_ptr_t* trg, buff_ptr_t* src)
+{
+ trg->mmu0_ptr = src->mmu0_ptr;
+ trg->mmu1_ptr = src->mmu1_ptr;
+ trg->scalelut_ptr = src->scalelut_ptr;
+ trg->vcpu_imem_ptr = src->vcpu_imem_ptr;
+ trg->sys_imem_ptr = src->sys_imem_ptr;
+ trg->sys_imem_ptr_v = src->sys_imem_ptr_v;
+ trg->lmem0_ptr = src->lmem0_ptr;
+ trg->lmem1_ptr = src->lmem1_ptr;
+ trg->parser_sao0_ptr = src->parser_sao0_ptr;
+ trg->parser_sao1_ptr = src->parser_sao1_ptr;
+ trg->mpred_imp0_ptr = src->mpred_imp0_ptr;
+ trg->mpred_imp1_ptr = src->mpred_imp1_ptr;
+ //
+ trg->scalelut_ptr_pre = src->scalelut_ptr_pre;
+ trg->scalelut_ptr_changed = src->scalelut_ptr_changed;
+}
+
+static void print_loopbufs_ptr(struct AVS2Decoder_s *dec, char* mark, buff_ptr_t* ptr)
+{
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s:mmu0_ptr 0x%x, mmu1_ptr 0x%x, scalelut_ptr 0x%x (changed %d) pre_ptr 0x%x, vcpu_imem_ptr 0x%x, sys_imem_ptr 0x%x (vir 0x%x), lmem0_ptr 0x%x, lmem1_ptr 0x%x, parser_sao0_ptr 0x%x, parser_sao1_ptr 0x%x, mpred_imp0_ptr 0x%x, mpred_imp1_ptr 0x%x\n",
+ mark,
+ ptr->mmu0_ptr,
+ ptr->mmu1_ptr,
+ ptr->scalelut_ptr,
+ ptr->scalelut_ptr_changed,
+ ptr->scalelut_ptr_pre,
+ ptr->vcpu_imem_ptr,
+ ptr->sys_imem_ptr,
+ ptr->sys_imem_ptr_v,
+ ptr->lmem0_ptr,
+ ptr->lmem1_ptr,
+ ptr->parser_sao0_ptr,
+ ptr->parser_sao1_ptr,
+ ptr->mpred_imp0_ptr,
+ ptr->mpred_imp1_ptr);
+}
+
+static int init_mmu_fb_bufstate(struct AVS2Decoder_s *dec, int mmu_fb_4k_number)
+{
+ int ret;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ dma_addr_t tmp_phy_adr;
+ int mmu_map_size = ((mmu_fb_4k_number * 4) >> 6) << 6;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s: mmu_fb_4k_number %d\n", __func__, mmu_fb_4k_number);
+
+ if (mmu_fb_4k_number < 0)
+ return -1;
+
+ dec->mmu_box_fb = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, 2, (mmu_fb_4k_number << 12) * 2, 0);
+
+ dec->fb_buf_mmu0_addr = dma_alloc_coherent(amports_get_dma_device(),
+ mmu_map_size, &tmp_phy_adr, GFP_KERNEL);
+ avs2_dec->fb_buf_mmu0.buf_start = tmp_phy_adr;
+ if (dec->fb_buf_mmu0_addr == NULL) {
+ avs2_print(dec, 0, "%s: failed to alloc fb_mmu0_map\n", __func__);
+ return -1;
+ }
+ memset(dec->fb_buf_mmu0_addr, 0, mmu_map_size);
+ avs2_dec->fb_buf_mmu0.buf_size = mmu_map_size;
+ avs2_dec->fb_buf_mmu0.buf_end = avs2_dec->fb_buf_mmu0.buf_start + mmu_map_size;
+
+ dec->fb_buf_mmu1_addr = dma_alloc_coherent(amports_get_dma_device(),
+ mmu_map_size, &tmp_phy_adr, GFP_KERNEL);
+ avs2_dec->fb_buf_mmu1.buf_start = tmp_phy_adr;
+ if (dec->fb_buf_mmu1_addr == NULL) {
+ avs2_print(dec, 0, "%s: failed to alloc fb_mmu1_map\n", __func__);
+ return -1;
+ }
+ memset(dec->fb_buf_mmu1_addr, 0, mmu_map_size);
+ avs2_dec->fb_buf_mmu1.buf_size = mmu_map_size;
+ avs2_dec->fb_buf_mmu1.buf_end = avs2_dec->fb_buf_mmu1.buf_start + mmu_map_size;
+
+ ret = decoder_mmu_box_alloc_idx(dec->mmu_box_fb,
+ 0, mmu_fb_4k_number, dec->fb_buf_mmu0_addr);
+ if (ret != 0) {
+ avs2_print(dec, 0, "%s: failed to alloc fb_mmu0 pages");
+ return -1;
+ }
+
+ ret = decoder_mmu_box_alloc_idx(dec->mmu_box_fb,
+ 1, mmu_fb_4k_number, dec->fb_buf_mmu1_addr);
+ if (ret != 0) {
+ avs2_print(dec, 0, "%s: failed to alloc fb_mmu1 pages");
+ return -1;
+ }
+
+ dec->mmu_fb_4k_number = mmu_fb_4k_number;
+ avs2_dec->fr.mmu0_ptr = avs2_dec->fb_buf_mmu0.buf_start;
+ avs2_dec->bk.mmu0_ptr = avs2_dec->fb_buf_mmu0.buf_start;
+ avs2_dec->fr.mmu1_ptr = avs2_dec->fb_buf_mmu1.buf_start;
+ avs2_dec->bk.mmu1_ptr = avs2_dec->fb_buf_mmu1.buf_start;
+
+ return 0;
+}
+
+static void init_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+/*simulation code: change to use linux APIs; also need write uninit_fb_bufstate()*/
+ int ret;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ dma_addr_t tmp_phy_adr;
+ unsigned long tmp_adr;
+ int mmu_fb_4k_number = dec->fb_ifbuf_num * avs2_mmu_page_num(dec,
+ dec->init_pic_w, dec->init_pic_h, 1);
+
+ ret = init_mmu_fb_bufstate(dec, mmu_fb_4k_number);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc mmu fb buffer\n", __func__);
+ return ;
+ }
+
+ avs2_dec->fb_buf_scalelut.buf_size = IFBUF_SCALELUT_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_SCALELUT_ID, avs2_dec->fb_buf_scalelut.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_scalelut.buf_size);
+ }
+
+ avs2_dec->fb_buf_scalelut.buf_start = tmp_adr;
+ avs2_dec->fb_buf_scalelut.buf_end = avs2_dec->fb_buf_scalelut.buf_start + avs2_dec->fb_buf_scalelut.buf_size;
+
+ avs2_dec->fb_buf_vcpu_imem.buf_size = IFBUF_VCPU_IMEM_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_VCPU_IMEM_ID, avs2_dec->fb_buf_vcpu_imem.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_vcpu_imem.buf_size);
+ }
+
+ avs2_dec->fb_buf_vcpu_imem.buf_start = tmp_adr;
+ avs2_dec->fb_buf_vcpu_imem.buf_end = avs2_dec->fb_buf_vcpu_imem.buf_start + avs2_dec->fb_buf_vcpu_imem.buf_size;
+
+ avs2_dec->fb_buf_sys_imem.buf_size = IFBUF_SYS_IMEM_SIZE * dec->fb_ifbuf_num;
+ avs2_dec->fb_buf_sys_imem_addr = dma_alloc_coherent(amports_get_dma_device(),
+ avs2_dec->fb_buf_sys_imem.buf_size, &tmp_phy_adr, GFP_KERNEL);
+ avs2_dec->fb_buf_sys_imem.buf_start = tmp_phy_adr;
+ if (avs2_dec->fb_buf_sys_imem_addr == NULL) {
+ pr_err("%s: failed to alloc fb_buf_sys_imem\n", __func__);
+ return;
+ }
+ avs2_dec->fb_buf_sys_imem.buf_end = avs2_dec->fb_buf_sys_imem.buf_start + avs2_dec->fb_buf_sys_imem.buf_size;
+
+ avs2_dec->fb_buf_lmem0.buf_size = IFBUF_LMEM0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_LMEM0_ID, avs2_dec->fb_buf_lmem0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_lmem0.buf_size);
+ }
+
+ avs2_dec->fb_buf_lmem0.buf_start = tmp_adr;
+ avs2_dec->fb_buf_lmem0.buf_end = avs2_dec->fb_buf_lmem0.buf_start + avs2_dec->fb_buf_lmem0.buf_size;
+
+ avs2_dec->fb_buf_lmem1.buf_size = IFBUF_LMEM1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_LMEM1_ID, avs2_dec->fb_buf_lmem1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_lmem1.buf_size);
+ }
+
+ avs2_dec->fb_buf_lmem1.buf_start = tmp_adr;
+ avs2_dec->fb_buf_lmem1.buf_end = avs2_dec->fb_buf_lmem1.buf_start + avs2_dec->fb_buf_lmem1.buf_size;
+
+ avs2_dec->fb_buf_parser_sao0.buf_size = IFBUF_PARSER_SAO0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_PARSER_SAO0_ID, avs2_dec->fb_buf_parser_sao0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_parser_sao0.buf_size);
+ }
+
+ avs2_dec->fb_buf_parser_sao0.buf_start = tmp_adr;
+ avs2_dec->fb_buf_parser_sao0.buf_end = avs2_dec->fb_buf_parser_sao0.buf_start + avs2_dec->fb_buf_parser_sao0.buf_size;
+
+ avs2_dec->fb_buf_parser_sao1.buf_size = IFBUF_PARSER_SAO1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_PARSER_SAO1_ID, avs2_dec->fb_buf_parser_sao1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_parser_sao1.buf_size);
+ }
+
+ avs2_dec->fb_buf_parser_sao1.buf_start = tmp_adr;
+ avs2_dec->fb_buf_parser_sao1.buf_end = avs2_dec->fb_buf_parser_sao1.buf_start + avs2_dec->fb_buf_parser_sao1.buf_size;
+
+ avs2_dec->fb_buf_mpred_imp0.buf_size = IFBUF_MPRED_IMP0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUFF_MPRED_IMP0_ID, avs2_dec->fb_buf_mpred_imp0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_mpred_imp0.buf_size);
+ }
+
+ avs2_dec->fb_buf_mpred_imp0.buf_start = tmp_adr;
+ avs2_dec->fb_buf_mpred_imp0.buf_end = avs2_dec->fb_buf_mpred_imp0.buf_start + avs2_dec->fb_buf_mpred_imp0.buf_size;
+
+ avs2_dec->fb_buf_mpred_imp1.buf_size = IFBUF_MPRED_IMP1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUFF_MPRED_IMP1_ID, avs2_dec->fb_buf_mpred_imp1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ if (ret) {
+ avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+ } else {
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_mpred_imp1.buf_size);
+ }
+
+ avs2_dec->fb_buf_mpred_imp1.buf_start = tmp_adr;
+ avs2_dec->fb_buf_mpred_imp1.buf_end = avs2_dec->fb_buf_mpred_imp1.buf_start + avs2_dec->fb_buf_mpred_imp1.buf_size;
+
+ avs2_dec->fr.scalelut_ptr = avs2_dec->fb_buf_scalelut.buf_start;
+ avs2_dec->bk.scalelut_ptr = avs2_dec->fb_buf_scalelut.buf_start;
+ avs2_dec->fr.vcpu_imem_ptr = avs2_dec->fb_buf_vcpu_imem.buf_start;
+ avs2_dec->bk.vcpu_imem_ptr = avs2_dec->fb_buf_vcpu_imem.buf_start;
+ avs2_dec->fr.sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+ avs2_dec->bk.sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+ avs2_dec->fr.lmem0_ptr = avs2_dec->fb_buf_lmem0.buf_start;
+ avs2_dec->bk.lmem0_ptr = avs2_dec->fb_buf_lmem0.buf_start;
+ avs2_dec->fr.lmem1_ptr = avs2_dec->fb_buf_lmem1.buf_start;
+ avs2_dec->bk.lmem1_ptr = avs2_dec->fb_buf_lmem1.buf_start;
+ avs2_dec->fr.parser_sao0_ptr = avs2_dec->fb_buf_parser_sao0.buf_start;
+ avs2_dec->bk.parser_sao0_ptr = avs2_dec->fb_buf_parser_sao0.buf_start;
+ avs2_dec->fr.parser_sao1_ptr = avs2_dec->fb_buf_parser_sao1.buf_start;
+ avs2_dec->bk.parser_sao1_ptr = avs2_dec->fb_buf_parser_sao1.buf_start;
+ avs2_dec->fr.mpred_imp0_ptr = avs2_dec->fb_buf_mpred_imp0.buf_start;
+ avs2_dec->bk.mpred_imp0_ptr = avs2_dec->fb_buf_mpred_imp0.buf_start;
+ avs2_dec->fr.mpred_imp1_ptr = avs2_dec->fb_buf_mpred_imp1.buf_start;
+ avs2_dec->bk.mpred_imp1_ptr = avs2_dec->fb_buf_mpred_imp1.buf_start;
+ avs2_dec->fr.scalelut_ptr_pre = 0;
+ avs2_dec->bk.scalelut_ptr_pre = 0;
+ avs2_dec->fr.scalelut_ptr_changed = 0;
+ avs2_dec->bk.scalelut_ptr_changed = 0;
+
+ avs2_dec->fr.sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr; //for linux
+
+ print_loopbufs_ptr(dec, "init", &avs2_dec->fr);
+}
+
+static void uninit_mmu_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ if (dec->fb_buf_mmu0_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs2_dec->fb_buf_mmu0.buf_size, dec->fb_buf_mmu0_addr,
+ avs2_dec->fb_buf_mmu0.buf_start);
+ dec->fb_buf_mmu0_addr = NULL;
+ }
+ if (dec->fb_buf_mmu1_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs2_dec->fb_buf_mmu1.buf_size, dec->fb_buf_mmu1_addr,
+ avs2_dec->fb_buf_mmu1.buf_start);
+ dec->fb_buf_mmu1_addr = NULL;
+ }
+ if (dec->mmu_box_fb) {
+ decoder_mmu_box_free(dec->mmu_box_fb);
+ dec->mmu_box_fb = NULL;
+ }
+ dec->mmu_fb_4k_number = 0;
+}
+
+static void uninit_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+ int i;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ for (i = 0; i < FB_LOOP_BUF_COUNT; i++) {
+ if (i != BMMU_IFBUF_SYS_IMEM_ID)
+ decoder_bmmu_box_free_idx(dec->bmmu_box, i);
+ }
+
+ if (avs2_dec->fb_buf_sys_imem_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs2_dec->fb_buf_sys_imem.buf_size, avs2_dec->fb_buf_sys_imem_addr,
+ avs2_dec->fb_buf_sys_imem.buf_start);
+ avs2_dec->fb_buf_sys_imem_addr = NULL;
+ }
+
+ uninit_mmu_fb_bufstate(dec);
+}
+
+static void config_bufstate_front_hw(struct avs2_decoder *avs2_dec)
+{
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_START, avs2_dec->fb_buf_mmu0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_END, avs2_dec->fb_buf_mmu0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0, avs2_dec->fr.mmu0_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_START, avs2_dec->fb_buf_mmu1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_END, avs2_dec->fb_buf_mmu1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1, avs2_dec->fr.mmu1_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_parser_sao0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_parser_sao0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_parser_sao1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_parser_sao1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config mpred_imp_if data write buffer start address
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_mpred_imp0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_mpred_imp0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_mpred_imp1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_mpred_imp1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config other buffers
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_scalelut.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_scalelut.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.scalelut_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.scalelut_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, avs2_dec->fr.scalelut_ptr_pre);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_vcpu_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_vcpu_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_sys_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_sys_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//config lmem buffers
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_lmem0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_lmem0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM0_BLOCK_SIZE);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_lmem1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_lmem1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM1_BLOCK_SIZE);
+}
+
+static void config_bufstate_back_hw(struct avs2_decoder *avs2_dec)
+{
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_START, avs2_dec->fb_buf_mmu0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_END, avs2_dec->fb_buf_mmu0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0, avs2_dec->bk.mmu0_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_START, avs2_dec->fb_buf_mmu1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_END, avs2_dec->fb_buf_mmu1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1, avs2_dec->bk.mmu1_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_parser_sao0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_parser_sao0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 1);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_parser_sao1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_parser_sao1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config mpred_imp_if data write buffer start address
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 2);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_mpred_imp0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_mpred_imp0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 3);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_mpred_imp1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_mpred_imp1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config other buffers
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 4);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_scalelut.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_scalelut.buf_end);
+// if (avs2_dec->bk.scalelut_ptr_changed)
+// WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr);
+// else
+// WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr_pre);
+// WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, avs2_dec->bk.scalelut_ptr_pre);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 7);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_vcpu_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_vcpu_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 8);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_sys_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_sys_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config lmem buffers
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 5);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_lmem0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_lmem0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 6);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_lmem1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_lmem1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+}
+
+static void read_bufstate_front(struct avs2_decoder *avs2_dec)
+{
+ //struct AVS2Decoder_s *dec = container_of(avs2_dec,
+ //struct AVS2Decoder_s, avs2_dec);
+ //uint32_t tmp;
+ avs2_dec->fr.mmu0_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0);
+ avs2_dec->fr.mmu1_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+ //tmp = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ //if (avs2_dec->fr.scalelut_ptr == tmp)
+ // avs2_dec->fr.scalelut_ptr_changed = 0;
+ //else
+ // avs2_dec->fr.scalelut_ptr_changed = 1;
+ //avs2_dec->fr.scalelut_ptr = tmp;
+ avs2_dec->fr.scalelut_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ //avs2_dec->fr.scalelut_ptr_pre = READ_VREG(HEVC_ASSIST_RING_F_THRESHOLD);
+ //avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ //"pic_end_ptr = %x; pic_start_ptr = %x\n", avs2_dec->fr.scalelut_ptr, avs2_dec->fr.scalelut_ptr_pre);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+ avs2_dec->fr.vcpu_imem_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+ avs2_dec->fr.lmem0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+ avs2_dec->fr.lmem1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+ avs2_dec->fr.parser_sao0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+ avs2_dec->fr.parser_sao1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+ avs2_dec->fr.mpred_imp0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+ avs2_dec->fr.mpred_imp1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+
+ avs2_dec->fr.sys_imem_ptr = avs2_dec->sys_imem_ptr;
+ avs2_dec->fr.sys_imem_ptr_v = avs2_dec->sys_imem_ptr_v;
+}
+
+/*hw config*/
+
+/**/
+static int compute_losless_comp_body_size(struct AVS2Decoder_s *dec,
+ int width, int height,
+ uint8_t is_bit_depth_10);
+static int compute_losless_comp_header_size(struct AVS2Decoder_s *dec,
+ int width, int height);
+
+static void config_work_space_hw(struct AVS2Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ struct BuffInfo_s* buf_spec = &dec->work_space_buf_store;
+ int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+ /*
+ int losless_comp_body_size;
+ cur_pic = dec->avs2_dec.hc.cur_pic;
+ losless_comp_body_size =
+ compute_losless_comp_body_size(
+ dec, cur_pic->pic_w,
+ cur_pic->pic_h, (dec->avs2_dec.hc.cur_pic->bit_depth == AVS2_BITS_10));
+ */
+ int losless_comp_header_size =
+ compute_losless_comp_header_size(
+ dec, dec->init_pic_w,
+ dec->init_pic_h);
+ int losless_comp_body_size =
+ compute_losless_comp_body_size(dec,
+ dec->init_pic_w,
+ dec->init_pic_h, is_bit_depth_10);
+ int losless_comp_body_size_dw = losless_comp_body_size;
+ int losless_comp_header_size_dw = losless_comp_header_size;
+
+ if (front_flag) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s front %x %x %x %x %x %x %x %x\n", __func__,
+ buf_spec->start_adr,
+ buf_spec->rpm.buf_start,
+ buf_spec->short_term_rps.buf_start,
+ buf_spec->rcs.buf_start,
+ buf_spec->sps.buf_start,
+ buf_spec->pps.buf_start,
+ buf_spec->swap_buf.buf_start,
+ buf_spec->swap_buf2.buf_start,
+ buf_spec->scalelut.buf_start);
+ WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+ //WRITE_VREG(HEVC_RPM_BUFFER, buf_spec->rpm.buf_start);
+ WRITE_VREG(AVS2_ALF_SWAP_BUFFER, buf_spec->short_term_rps.buf_start);
+ WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
+ WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
+ WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
+ //WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
+ //WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
+ //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
+ }
+
+ if (back_flag) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s back %x %x %x %x %x %x %x\n", __func__,
+ buf_spec->ipp.buf_start,
+ buf_spec->ipp1.buf_start,
+ buf_spec->sao_up.buf_start,
+ buf_spec->scalelut.buf_start,
+ buf_spec->dblk_para.buf_start,
+ buf_spec->dblk_data.buf_start,
+ buf_spec->dblk_data2.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,buf_spec->ipp.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2,buf_spec->ipp1.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE_DBE1,buf_spec->ipp1.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2_DBE1,buf_spec->ipp.buf_start);
+ //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+#ifdef AVS2_10B_MMU
+ //WRITE_VREG(H265_MMU_MAP_BUFFER, FRAME_MMU_MAP_ADDR);
+ WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, dec->frame_mmu_map_phy_addr);
+ WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR_DBE1, dec->frame_mmu_map_phy_addr_1); //new dual
+#else
+ // WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, dec->dw_frame_mmu_map_phy_addr_1); //new dual
+ //printk("WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, 0x%x\n", FRAME_MMU_MAP_ADDR_DW_0);
+ //printk("WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, 0x%x\n", FRAME_MMU_MAP_ADDR_DW_1);
+ }
+#endif
+ //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
+
+ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFG4_DBE1, buf_spec->dblk_para.buf_start);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFG4: 0x%x\n", buf_spec->dblk_para.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFG5_DBE1, buf_spec->dblk_data.buf_start);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFG5: 0x%x\n", buf_spec->dblk_data.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFGE_DBE1, buf_spec->dblk_data2.buf_start);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFGE: 0x%x\n", buf_spec->dblk_data2.buf_start);
+
+#ifdef LOSLESS_COMPRESS_MODE
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+#if 1
+ data32 &= ~(1<<9);
+#else
+ if (params->p.bit_depth != 0x00)
+ data32 &= ~(1<<9);
+ else
+ data32 |= (1<<9);
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+#if 1
+ data32 &= ~(1<<9);
+#else
+ if (params->p.bit_depth != 0x00)
+ data32 &= ~(1<<9);
+ else
+ data32 |= (1<<9);
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,0x0);
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,(0x1<< 4)); // bit[4] : paged_mem_mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,0x0);
+#else
+ // WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe
+#if 1
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1, (0<<3)); // bit[3] smem mode
+#else
+ if (params->p.bit_depth != 0x00) WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+ else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe
+#endif
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,(losless_comp_body_size >> 5));
+#endif
+ //WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+ //WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff); //8-bit mode
+ WRITE_VREG(HEVC_CM_BODY_LENGTH,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH,losless_comp_header_size);
+ WRITE_VREG(HEVC_CM_BODY_LENGTH_DBE1,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET_DBE1,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH_DBE1,losless_comp_header_size);
+#else // LOSLESS_COMPRESS_MODE
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31);
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,0x1 << 31);
+#endif
+#ifdef AVS2_10B_MMU
+ #if 1
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/4);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2 + buf_spec->mmu_vbh.buf_size/4);
+ #else
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2);
+ #endif
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+ data32 |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#endif
+#ifdef AVS2_10B_MMU_DW
+if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size_dw);
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2_DBE1,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2_DBE1,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2_DBE1,losless_comp_header_size_dw);
+
+ #if 1
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/4);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2 + buf_spec->mmu_vbh_dw.buf_size/4);
+ #else
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+ #endif
+
+ #ifdef AVS2_10B_MMU_DW
+ #if 1
+ #ifndef FOR_S5
+ WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+ WRITE_VREG(HEVC_DW_VH0_ADDDR_DBE1, DOUBLE_WRITE_VH0_HALF);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR_DBE1, DOUBLE_WRITE_VH1_HALF);
+ #endif
+ #else
+ //WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+ //WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+ WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+ #endif
+ #endif
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+}
+#endif
+
+ } // back_flag
+ if (front_flag) {
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+#ifdef CO_MV_COMPRESS
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1<<1);
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+#endif
+ } // front_flag
+
+}
+
+static void hevc_init_decoder_hw(struct AVS2Decoder_s *dec,
+ uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ int32_t i;
+
+int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+};
+
+int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+};
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Entering hevc_init_decoder_hw\n");
+#if 0
+ printk("[test.c] Test Parser Register Read/Write\n");
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x00010001) { print_scratch_error(25); return; }
+ WRITE_VREG(HEVC_PARSER_VERSION, 0x5a5a55aa);
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x5a5a55aa) { print_scratch_error(26); return; }
+
+ // test Parser Reset
+ WRITE_VREG(DOS_SW_RESET1, (1<<3)); // reset_whole parser
+ WRITE_VREG(DOS_SW_RESET1, 0); // reset_whole parser
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x00010001) { print_scratch_error(27); return; }
+#endif
+
+#if 0 // JT
+ printk("[test.c] Enable BitStream Fetch\n");
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 |
+ (1 << 0) // stream_fetch_enable
+ ;
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x00000100) { print_scratch_error(29); return; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x00000300) { print_scratch_error(30); return; }
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x12345678) { print_scratch_error(31); return; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x9abcdef0) { print_scratch_error(32); return; }
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
+#endif // JT
+
+#if 0 //def AVS2_10B_HED_FB
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Init AVS2_10B_HED_FB\n");
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 |
+ (1 << 3) | // fb_read_avs2_enable0
+ (1 << 6) | // fb_read_avs2_enable1
+ (1 << 1) | // fb_avs2_enable
+ (0 << 13) | // fb_read_avs3_enable0
+ (0 << 14) | // fb_read_avs3_enable1
+ (0 << 9) | // fb_avs3_enable
+ (3 << 7) //core0_en, core1_en,hed_fb_en
+ ;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+// data32 = READ_VREG(P_HEVC_ASSIST_FB_W_CTL);
+// data32 = data32 |
+// (1 << 0) // hed_fb_wr_en
+ ;
+// WRITE_VREG(P_HEVC_ASSIST_FB_W_CTL, data32);
+
+//#ifdef H265_10B_HED_SAME_FB
+// printk("[test.c] Init H265_10B_HED_SAME_FB\n");
+// data32 = READ_VREG(P_HEVC_ASSIST_FB_R_CTL);
+// data32 = data32 |
+// (1 << 0) // hed_fb_rd_en
+// ;
+// WRITE_VREG(P_HEVC_ASSIST_FB_R_CTL, data32);
+//#endif
+
+#endif
+#if 1 //move to ucode
+ if (!efficiency_mode && front_flag) {
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable HEVC Parser Interrupt\n");
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+ data32 = data32 |
+ (1 << 24) | // stream_buffer_empty_int_amrisc_enable
+ (1 << 22) | // stream_fifo_empty_int_amrisc_enable
+ (1 << 7) | // dec_done_int_cpu_enable
+ (1 << 4) | // startcode_found_int_cpu_enable
+ (0 << 3) | // startcode_found_int_amrisc_enable
+ (1 << 0) // parser_int_enable
+ ;
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable HEVC Parser Shift\n");
+
+ data32 = READ_VREG(HEVC_SHIFT_STATUS);
+#ifdef AVS2
+ data32 = data32 |
+ (0 << 1) | // emulation_check_on // AVS2 emulation on/off will be controlled in microcode according to startcode type
+ (1 << 0) // startcode_check_on
+ ;
+#else
+ data32 = data32 |
+ (1 << 1) | // emulation_check_on
+ (1 << 0) // startcode_check_on
+ ;
+#endif
+ WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+
+ WRITE_VREG(HEVC_SHIFT_CONTROL,
+ (6 << 20) | // emu_push_bits (6-bits for AVS2)
+ (0 << 19) | // emu_3_enable // maybe turned on in microcode
+ (0 << 18) | // emu_2_enable // maybe turned on in microcode
+ (0 << 17) | // emu_1_enable // maybe turned on in microcode
+ (0 << 16) | // emu_0_enable // maybe turned on in microcode
+ (0 << 14) | // disable_start_code_protect
+ (3 << 6) | // sft_valid_wr_position
+ (2 << 4) | // emulate_code_length_sub_1
+ (2 << 1) | // start_code_length_sub_1
+ (1 << 0) // stream_shift_enable
+ );
+
+ WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
+ (0 << 30) | // data_protect_fill_00_enable
+ (1 << 29) // data_protect_fill_ff_enable
+ );
+
+ WRITE_VREG(HEVC_CABAC_CONTROL,
+ (1 << 0) // cabac_enable
+ );
+
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
+ (1 << 0) // hevc_parser_core_clk_en
+ );
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
+
+ }
+#endif
+
+ if (!efficiency_mode && back_flag) {
+#if 0 // Dual Core : back Microcode will always initial SCALELUT
+ // Initial IQIT_SCALELUT memory -- just to avoid X in simulation
+ printk("[test.c] Initial IQIT_SCALELUT memory -- just to avoid X in simulation...\n");
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // cfg_p_addr
+ for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // cfg_p_addr
+ for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, 0);
+#endif
+
+ // Zero out canvas registers in IPP -- avoid simulation X
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i=0; i<32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+ }
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR_DBE1, (0 << 8) | (0<<1) | 1);
+ for (i=0; i<32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#endif
+ }
+ }
+
+ if (!efficiency_mode && front_flag) {
+#ifdef ENABLE_SWAP_TEST
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+#endif
+
+ //WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
+ //WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, decode_pic_num);
+#if 0
+ // Send parser_cmd
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] SEND Parser Command ...\n");
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1<<16) | (0<<0));
+ for (i=0; i<PARSER_CMD_NUMBER; i++) {
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
+ }
+
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
+#endif
+#if 1 //move to ucode
+
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ (1 << 9) | // parser_alf_if_en
+ // (1 << 8) | // sao_sw_pred_enable
+ (1 << 5) | // parser_sao_if_en
+ (1 << 2) | // parser_mpred_if_en
+ (1 << 0) // parser_scaler_if_en
+ );
+#endif
+ }
+
+#if 0
+//def MULTI_INSTANCE_SUPPORT
+ // Begin of Multi-instance
+ WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+ WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+ data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
+ WRITE_VREG(DOS_SW_RESET3, (1<<18)); // reset mpred
+ WRITE_VREG(DOS_SW_RESET3, 0);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+
+ // End of Multi-instance
+#endif
+ // Changed to Start MPRED in microcode
+ /*
+ printk("[test.c] Start MPRED\n");
+ WRITE_VREG(HEVC_MPRED_INT_STATUS,
+ (1<<31)
+ );
+ */
+
+ // AVS2 default seq_wq_matrix config
+ if (!efficiency_mode && back_flag) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Config AVS2 default seq_wq_matrix ...\n");
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+ for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+ for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+ for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+ for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Reset IPP\n");
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (0 << 1) | // enable ipp
+ (4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (1 << 0) // software reset ipp and mpp
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (1 << 1) | // enable ipp
+ (4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (0 << 0) // software reset ipp and mpp
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+ (0 << 1) | // enable ipp
+ (4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (1 << 0) // software reset ipp and mpp
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+ (1 << 1) | // enable ipp
+ (4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (0 << 0) // software reset ipp and mpp
+ );
+
+ // Init dblk
+#define LPF_LINEBUF_MODE_CTU_BASED
+ //must be defined for DUAL_CORE
+
+ data32 = READ_VREG(HEVC_DBLK_CFGB);
+ data32 |= (2 << 0);
+ WRITE_VREG(HEVC_DBLK_CFGB, data32); // [3:0] cfg_video_type -> AVS2
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+ WRITE_VREG(HEVC_DBLK_CFG0, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+ WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+
+ data32 = READ_VREG(HEVC_DBLK_CFGB_DBE1);
+ data32 |= (2 << 0);
+ WRITE_VREG(HEVC_DBLK_CFGB_DBE1, data32); // [3:0] cfg_video_type -> AVS2
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+ WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+ WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Bitstream level Init for DBLK .Done.\n");
+
+ // Initialize mcrcc and decomp perf counters
+#if 0
+ mcrcc_perfcount_reset();
+ decomp_perfcount_reset();
+#endif
+ }//back_flag end
+ if (back_flag) {
+#if 0
+ //to do: move to config_sao_hw_fb
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~(3 << 14));
+ data32 |= (2 << 14); /* line align with 64*/
+ data32 &= (~0x3000);
+ data32 |= (MEM_MAP_MODE << 12); /* [13:12] axi_aformat, 0-Linear,
+ 1-32x32, 2-64x32 */
+ data32 &= (~0xff0);
+ #ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable == 0)
+ data32 |= ((dec->endian >> 8) & 0xfff);
+ #else
+ data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+ #endif
+ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+
+ if (get_double_write_mode(dec) == 0)
+ data32 |= 0x2; /*disable double write*/
+ else if (get_double_write_mode(dec) & 0x10)
+ data32 |= 0x1; /*disable cm*/
+
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+ WRITE_VREG(HEVC_SAO_CTRL1_DBE1, data32);
+
+ if (get_double_write_mode(dec) & 0x10) {
+ /* [23:22] dw_v1_ctrl
+ [21:20] dw_v0_ctrl
+ [19:18] dw_h1_ctrl
+ [17:16] dw_h0_ctrl
+ */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ data32 &= ~(0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+ } else {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
+ WRITE_VREG(HEVC_SAO_CTRL26, 0);
+ WRITE_VREG(HEVC_SAO_CTRL26_DBE1, 0);
+ }
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 &= (~(0xff << 16));
+ if ((get_double_write_mode(dec) & 0xf) == 8 ||
+ (get_double_write_mode(dec) & 0xf) == 9) {
+ data32 |= (0xff<<16);
+ WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
+ WRITE_VREG(HEVC_SAO_CTRL26_DBE1, 0xf);
+ } else if ((get_double_write_mode(dec) & 0xf) == 2 ||
+ (get_double_write_mode(dec) & 0xf) == 3)
+ data32 |= (0xff<<16);
+ else if ((get_double_write_mode(dec) & 0xf) == 4)
+ data32 |= (0x33<<16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+ }
+#endif
+ if (dec->mmu_enable) {
+ data32 = READ_VREG(HEVC_SAO_CTRL9);
+ data32 |= 0x1;
+ WRITE_VREG(HEVC_SAO_CTRL9, data32);
+ WRITE_VREG(HEVC_SAO_CTRL9_DBE1, data32);
+ }
+ #ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ data32 = READ_VREG(HEVC_SAO_CTRL9);
+ data32 |= (1 << 10);
+ WRITE_VREG(HEVC_SAO_CTRL9, data32);
+ WRITE_VREG(HEVC_SAO_CTRL9_DBE1, data32);
+ }
+ #endif
+ }
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Leaving hevc_init_decoder_hw\n");
+ return;
+}
+
+extern void config_cuva_buf(struct AVS2Decoder_s *dec);
+static int32_t avs2_hw_init(struct AVS2Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ uint32_t tmp = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s front_flag %d back_flag %d\n", __func__, front_flag, back_flag);
+ if (dec->front_back_mode != 1) {
+ if (front_flag)
+ avs2_hw_ctx_restore(dec);
+ if (back_flag) {
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+
+ }
+ return 0;
+ }
+
+ if (front_flag) {
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 | (3 << 7) | (1 << 1);
+ tmp = (1 << 0) | (1 << 9) | (1 << 10);
+ data32 &= ~tmp;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+ }
+
+ if (back_flag) {
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 | (3 << 7) | (1 << 3) | (1 << 6);
+ tmp = (1 << 2) | (1 << 13) | (1 << 11) | (1 << 5) | (1 << 14) | (1 << 12);
+ data32 &= ~tmp;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+ }
+
+ config_work_space_hw(dec, front_flag, back_flag);
+
+ if (!efficiency_mode && front_flag && dec->pic_list_init_flag)
+ init_pic_list_hw_fb(dec);
+
+ hevc_init_decoder_hw(dec, front_flag, back_flag);
+
+//Start JT
+#if 1 //move to ucode
+ if (!efficiency_mode && front_flag) {
+#if 0
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable BitStream Fetch\n");
+
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 |
+ (1 << 0) // stream_fetch_enable
+ ;
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x00000100) { print_scratch_error(29); return -1; }
+ /*data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x00000300) { print_scratch_error(30); return; }*/
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x12345678) { print_scratch_error(31); return -1; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x9abcdef0) { print_scratch_error(32); return -1; }
+#endif
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000); // 0x000000 - 0x000003 emulate code for AVS2
+ }
+#endif
+// End JT
+
+ if (!efficiency_mode && back_flag) {
+// Set MCR fetch priorities
+ data32 = 0x1 | (0x1 << 2) | (0x1 <<3) | (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
+ WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
+ WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL_DBE1, data32);
+
+ // Set IPP MULTICORE CFG
+ WRITE_VREG(HEVCD_IPP_MULTICORE_CFG, 1);
+ WRITE_VREG(HEVCD_IPP_MULTICORE_CFG_DBE1, 1);
+
+#ifdef DYN_CACHE
+ if (dec->front_back_mode == 1) {
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE_DBE1,0x2b);//enable new mcrcc
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+ }
+#endif
+ }
+
+if (front_flag) {
+ unsigned int decode_mode;
+
+ WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+
+#if 1 // JT
+
+#if 0 //def SIMULATION
+ if (decode_pic_begin == 0)
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+ else
+ WRITE_VREG(HEVC_WAIT_FLAG, 0);
+#else
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+#endif
+
+ /* disable PSCALE for hardware sharing */
+#ifdef DOS_PROJECT
+#else
+#ifndef FOR_S5
+ WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+#endif
+#endif
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+ //WRITE_VREG(DEBUG_REG1, 0x0); //no debug
+ WRITE_VREG(NAL_SEARCH_CTL, 0x8); //check SEQUENCE/I_PICTURE_START in ucode
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+#ifdef MULTI_INSTANCE_SUPPORT
+ if (!dec->m_ins_flag)
+ decode_mode = DECODE_MODE_SINGLE;
+ else if (vdec_frame_based(hw_to_vdec(dec)))
+ decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
+ else
+ decode_mode = DECODE_MODE_MULTI_STREAMBASE;
+ if (dec->avs2_dec.bufmgr_error_flag &&
+ (error_handle_policy & 0x1)) {
+ dec->bufmgr_error_count++;
+ dec->avs2_dec.bufmgr_error_flag = 0;
+ if (dec->bufmgr_error_count >
+ (re_search_seq_threshold & 0xff)
+ && dec->frame_count >
+ ((re_search_seq_threshold >> 8) & 0xff)) {
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ dec->start_decoding_flag = 0;
+ avs2_dec->hd.vec_flag = 1;
+ dec->skip_PB_before_I = 1;
+ avs2_print(dec, 0,
+ "!!Bufmgr error, search seq again (0x%x %d %d)\n",
+ error_handle_policy,
+ dec->frame_count,
+ dec->bufmgr_error_count);
+ dec->bufmgr_error_count = 0;
+ }
+ }
+ decode_mode |= (dec->start_decoding_flag << 16);
+
+ WRITE_VREG(DECODE_MODE, decode_mode);
+ //WRITE_VREG(HEVC_DECODE_SIZE, 0);
+ //WRITE_VREG(DECODE_MODE, 1); //DECODE_MODE_MULTI_STREAMBASE
+ WRITE_VREG(HEVC_DECODE_SIZE, 0xffffffff);
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "decode_mode 0x%x\n", decode_mode);
+ config_cuva_buf(dec);
+#endif
+
+ //WRITE_VREG(XIF_DOS_SCRATCH31, 0x0);
+ //WRITE_VREG(HEVC_MPSR, 1);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[test.c] P_HEVC_MPSR!\n");
+#endif
+ }
+ if (back_flag) {
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+ }
+
+ return 0;
+}
+
+static void release_free_mmu_buffers(struct AVS2Decoder_s *dec)
+{
+ int ii;
+
+ if (!(dec->error_proc_policy & 0x2))
+ return ;
+
+ for (ii = 0; ii < dec->avs2_dec.ref_maxbuffer;ii++) {
+ struct avs2_frame_s *pic = dec->avs2_dec.fref[ii];
+
+ if (pic->bg_flag == 0 &&
+ pic->is_output == -1 &&
+ pic->mmu_alloc_flag &&
+#ifdef NEW_FRONT_BACK_CODE
+ pic->backend_ref == 0 &&
+#endif
+ pic->vf_ref == 0) {
+ if (pic->referred_by_others == 0) {
+#ifdef AVS2_10B_MMU
+ pic->mmu_alloc_flag = 0;
+ /*release_buffer_4k(
+ dec->avs2_dec.fref[ii]->index);*/
+ decoder_mmu_box_free_idx(dec->mmu_box,
+ pic->index);
+ if (dec->front_back_mode)
+ decoder_mmu_box_free_idx(dec->mmu_box_1,
+ pic->index);
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+ decoder_mmu_box_free_idx(dec->dw_mmu_box,
+ pic->index);
+ if (dec->front_back_mode && dec->dw_mmu_box_1)
+ decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+ pic->index);
+ }
+
+#endif
+#ifndef MV_USE_FIXED_BUF
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ MV_BUFFER_IDX(pic->index));
+ pic->mpred_mv_wr_start_addr = 0;
+#endif
+ }
+ }
+ }
+
+}
+
+static int BackEnd_StartDecoding(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+ int cur_mmu_4k_number;
+ int i = 0;
+
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "Start BackEnd Decoding %d (wr pos %d, rd pos %d) poc %d\n",
+ avs2_dec->backend_decoded_count, avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos, pic->poc);
+ if (dec->front_back_mode != 1 &&
+ dec->front_back_mode != 3) {
+ copy_loopbufs_ptr(&avs2_dec->bk, &avs2_dec->next_bk[avs2_dec->fb_rd_pos]);
+ print_loopbufs_ptr(dec, "bk", &avs2_dec->bk);
+ avs2_hw_init(dec, 0, 1);
+
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ return 0;
+ }
+#if 0
+#ifdef AVS2_10B_MMU
+ alloc_mmu(&avs2_mmumgr_0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+ alloc_mmu(&avs2_mmumgr_1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#ifdef AVS2_10B_MMU_DW
+ alloc_mmu(&avs2_mmumgr_dw0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+ alloc_mmu(&avs2_mmumgr_dw1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#endif
+ pic->mmu_alloc_flag = 1;
+#endif
+#else
+
+ mutex_lock(&dec->fb_mutex);
+ for (i = 0; (i < MAXREF) && (pic->error_mark == 0); i++) {
+ if ((pic->ref_pic[i]) && (pic->ref_pic[i]->error_mark)) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s ref pic(%d) has error_mark, skip\n", __func__, i);
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_concealed_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_concealed_frames++;
+ }
+ pic->error_mark = 1;
+ break;
+ }
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ if ((dec->error_proc_policy & 0x2) && pic->error_mark) {
+ mutex_lock(&dec->fb_mutex);
+ dec->gvs->drop_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_lost_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_lost_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_lost_frames++;
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR, "%s pic has error_mark, skip\n", __func__);
+ pic_backend_ref_operation(dec, 0);
+ return 1;
+ }
+
+ cur_mmu_4k_number = avs2_mmu_page_num(dec,
+ pic->width, pic->height / 2 + 32 + 8, pic->depth == 10);
+
+ if (cur_mmu_4k_number < 0)
+ return -1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s:pic->index %d, mmu_4k_number %d\n", __func__, pic->index, cur_mmu_4k_number);
+
+ if (dec->mmu_enable) {
+ decoder_mmu_box_alloc_idx(
+ dec->mmu_box,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->frame_mmu_map_addr);
+
+ decoder_mmu_box_alloc_idx(
+ dec->mmu_box_1,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->frame_mmu_map_addr_1);
+ if (dec->dw_mmu_enable) {
+ decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->dw_frame_mmu_map_addr);
+
+ decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box_1,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->dw_frame_mmu_map_addr_1);
+ }
+ }
+ pic->mmu_alloc_flag = 1;
+#endif
+ copy_loopbufs_ptr(&avs2_dec->bk, &avs2_dec->next_bk[avs2_dec->fb_rd_pos]);
+ print_loopbufs_ptr(dec, "bk", &avs2_dec->bk);
+
+ if (dec->front_back_mode == 1)
+ amhevc_reset_b();
+
+ if (efficiency_mode)
+ WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 1);
+ else
+ WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 0);
+ avs2_hw_init(dec, 0, 1);
+ if (dec->front_back_mode == 3) {
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ } else {
+ config_bufstate_back_hw(avs2_dec);
+ WRITE_VREG(PIC_DECODE_COUNT_DBE, avs2_dec->backend_decoded_count);
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, HEVC_BE_DECODE_DATA);
+ WRITE_VREG(HEVC_SAO_CRC, 0);
+ amhevc_start_b();
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC_BACK);
+ }
+
+ return 0;
+}
+
+#if 1
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec)
+{
+ int i;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+
+ dec->avs2_dec.ins_offset = 0;
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
+#if 0
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (0x1 << 2));
+
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (0x1 << 2));
+#endif
+#endif
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+#if 0
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+#else
+ pic = avs2_dec->init_fref[i];
+#endif
+ if (pic->index < 0)
+ break;
+#ifdef AVS2_10B_MMU
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->header_adr
+ | (pic->mc_canvas_y << 8)|0x1);*/
+ //WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ // (0x1 << 1) | (pic->index << 8));
+
+#ifdef DUAL_CORE_64
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2)
+ WRITE_BACK_16(avs2_dec, HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+ else
+ WRITE_BACK_16(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+#endif
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_y_adr
+ | (pic->mc_canvas_y << 8) | 0x1);*/
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_u_v_adr
+ | (pic->mc_canvas_u_v << 8)| 0x1);*/
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+#ifdef DUAL_CORE_64
+#ifdef AVS2_10B_MMU
+ WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->header_adr >> 5);
+#else
+ WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->mc_u_v_adr >> 5);
+#endif
+/*DUAL_CORE_64*/
+#endif
+ }
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#ifdef DUAL_CORE_64
+ WRITE_BACK_8(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ 0x1);
+#endif
+#if 0
+ /*Zero out canvas registers in IPP -- avoid simulation X*/
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 1);
+ for (i = 0; i < 32; i++) {
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+ WRITE_BACK_8(avs2_dec, HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+ }
+#endif
+}
+
+#else
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec)
+{
+ int i;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+ dec->avs2_dec.ins_offset = 0;
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+ if (pic->index < 0)
+ break;
+#ifdef AVS2_10B_MMU
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+ }
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#if 0
+ /*Zero out canvas registers in IPP -- avoid simulation X*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 1);
+ for (i = 0; i < 32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+ }
+#endif
+}
+#endif
+
+static void config_mpred_hw_fb(struct AVS2Decoder_s *dec)
+{
+ //int32_t i;
+ uint32_t data32;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+ struct avs2_frame_s* col_pic = avs2_dec->fref[0];
+
+ //int32_t AMVP_MAX_NUM_CANDS_MEM=3;
+ //int32_t AMVP_MAX_NUM_CANDS=2;
+ //int32_t NUM_CHROMA_MODE=5;
+ //int32_t DM_CHROMA_IDX=36;
+ //int32_t above_ptr_ctrl =0;
+ //int32_t buffer_linear =1;
+ //int32_t cu_size_log2 =3;
+ int32_t mpred_mv_rd_start_addr ;
+ //int32_t mpred_curr_lcu_x;
+ //int32_t mpred_curr_lcu_y;
+ //int32_t mpred_above_buf_start ;
+ //int32_t mpred_mv_rd_ptr ;
+ //int32_t mpred_mv_rd_ptr_p1 ;
+ int32_t mpred_mv_rd_end_addr;
+ int32_t MV_MEM_UNIT_l;
+ //int32_t mpred_mv_wr_ptr ;
+
+ int32_t above_en;
+ int32_t mv_wr_en;
+ int32_t mv_rd_en;
+ int32_t col_isIntra;
+ //if (dec->slice_type!=2)
+ if (avs2_dec->img.type != I_IMG)
+ {
+ above_en=1;
+ mv_wr_en=1;
+ mv_rd_en=1;
+ col_isIntra=0;
+ }
+ else
+ {
+ above_en=1;
+ mv_wr_en=1;
+ mv_rd_en=0;
+ col_isIntra=0;
+ }
+
+ mpred_mv_rd_start_addr=col_pic->mpred_mv_wr_start_addr;
+ //data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
+ //mpred_curr_lcu_x =data32 & 0xffff;
+ //mpred_curr_lcu_y =(data32>>16) & 0xffff;
+
+ MV_MEM_UNIT_l=avs2_dec->lcu_size_log2 == 6 ? 0x200 : avs2_dec->lcu_size_log2 == 5 ? 0x80 : 0x20;
+
+ mpred_mv_rd_end_addr=mpred_mv_rd_start_addr + ((avs2_dec->lcu_x_num*avs2_dec->lcu_y_num)*MV_MEM_UNIT_l);
+
+ //mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "cur pic index %d col pic index %d\n", cur_pic->index, col_pic->index);
+
+ WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR, cur_pic->mpred_mv_wr_start_addr);
+ WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, col_pic->mpred_mv_wr_start_addr);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[MPRED CO_MV] write 0x%x read 0x%x\n", cur_pic->mpred_mv_wr_start_addr, col_pic->mpred_mv_wr_start_addr);
+
+ data32 =
+ ((avs2_dec->bk_img_is_top_field) << 13) |
+ ((avs2_dec->hd.background_picture_enable & 1) << 12) |
+ ((avs2_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+ ((avs2_dec->hd.b_pmvr_enabled & 1) << 6) |
+ ((avs2_dec->img.is_top_field & 1) << 5) |
+ ((avs2_dec->img.is_field_sequence & 1) << 4) |
+ ((avs2_dec->img.typeb & 7) << 1) |
+ (avs2_dec->hd.background_reference_enable & 0x1);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n", data32, avs2_dec->hd.curr_RPS.num_of_ref);
+ WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+
+#if 0
+ data32 = ((dec->lcu_x_num - dec->tile_width_lcu)*MV_MEM_UNIT);
+ WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);
+ WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);
+
+ data32 = READ_VREG(HEVC_MPRED_CTRL0);
+ data32 = (
+ dec->slice_type |
+ dec->new_pic<<2 |
+ dec->new_tile<<3|
+ dec->isNextSliceSegment<<4|
+ dec->TMVPFlag<<5|
+ dec->LDCFlag<<6|
+ dec->ColFromL0Flag<<7|
+ above_ptr_ctrl<<8 |
+ above_en<<9|
+ mv_wr_en<<10|
+ mv_rd_en<<11|
+ col_isIntra<<12|
+ buffer_linear<<13|
+ dec->LongTerm_Curr<<14|
+ dec->LongTerm_Col<<15|
+ avs2_dec->lcu_size_log2<<16|
+ cu_size_log2<<20|
+ dec->plevel<<24
+ );
+ WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+
+ data32 = READ_VREG(HEVC_MPRED_CTRL1);
+ data32 = (
+#ifdef DOS_PROJECT
+//no set in m8baby test1902
+ (data32 & (0x1<<24)) | // Don't override clk_forced_on ,
+#endif
+ dec->MaxNumMergeCand |
+ AMVP_MAX_NUM_CANDS<<4 |
+ AMVP_MAX_NUM_CANDS_MEM<<8|
+ NUM_CHROMA_MODE<<12|
+ DM_CHROMA_IDX<<16
+ );
+ WRITE_VREG(HEVC_MPRED_CTRL1,data32);
+
+ data32 = (
+ dec->pic_w|
+ dec->pic_h<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+ data32 = (
+ (dec->lcu_x_num-1) |
+ (dec->lcu_y_num-1)<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU,data32);
+
+ data32 = (
+ dec->tile_start_lcu_x |
+ dec->tile_start_lcu_y<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_START,data32);
+
+ data32 = (
+ dec->tile_width_lcu |
+ dec->tile_height_lcu<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU,data32);
+
+ data32 = (
+ dec->RefNum_L0 |
+ dec->RefNum_L1<<8|
+ 0
+ //col_RefNum_L0<<16|
+ //col_RefNum_L1<<24
+ );
+ WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+ data32 = (
+ dec->LongTerm_Ref
+ );
+ WRITE_VREG(HEVC_MPRED_LT_REF,data32);
+
+ data32=0;
+ for (i=0;i<dec->RefNum_L0;i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+ data32=0;
+ for (i=0;i<dec->RefNum_L1;i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s: dis %d %d %d %d %d %d %d fref0_ref_poc %d %d %d %d %d %d %d\n",
+ __func__, avs2_dec->fref[0]->imgtr_fwRefDistance,
+ avs2_dec->fref[1]->imgtr_fwRefDistance, avs2_dec->fref[2]->imgtr_fwRefDistance,
+ avs2_dec->fref[3]->imgtr_fwRefDistance,avs2_dec->fref[4]->imgtr_fwRefDistance,
+ avs2_dec->fref[5]->imgtr_fwRefDistance,avs2_dec->fref[6]->imgtr_fwRefDistance,
+ avs2_dec->fref[0]->ref_poc[0],
+ avs2_dec->fref[0]->ref_poc[1],
+ avs2_dec->fref[0]->ref_poc[2],
+ avs2_dec->fref[0]->ref_poc[3],
+ avs2_dec->fref[0]->ref_poc[4],
+ avs2_dec->fref[0]->ref_poc[5],
+ avs2_dec->fref[0]->ref_poc[6]
+ );
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "pic_distance %d, imgtr_next_P %d\n",
+ avs2_dec->img.pic_distance, avs2_dec->img.imgtr_next_P);
+ WRITE_VREG(HEVC_MPRED_CUR_POC, avs2_dec->img.pic_distance);
+ WRITE_VREG(HEVC_MPRED_COL_POC, avs2_dec->img.imgtr_next_P);
+
+ //below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> Ref_POC_xx_L1 in pair write order!!!
+ WRITE_VREG(HEVC_MPRED_L0_REF00_POC, avs2_dec->fref[0]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF00_POC, avs2_dec->fref[0]->ref_poc[0]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF01_POC,avs2_dec->fref[1]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF01_POC,avs2_dec->fref[0]->ref_poc[1]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF02_POC,avs2_dec->fref[2]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF02_POC,avs2_dec->fref[0]->ref_poc[2]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF03_POC,avs2_dec->fref[3]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF03_POC,avs2_dec->fref[0]->ref_poc[3]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF04_POC,avs2_dec->fref[4]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF04_POC,avs2_dec->fref[0]->ref_poc[4]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF05_POC,avs2_dec->fref[5]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF05_POC,avs2_dec->fref[0]->ref_poc[5]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF06_POC,avs2_dec->fref[6]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF06_POC,avs2_dec->fref[0]->ref_poc[6]);
+
+#if 0
+ if (dec->new_pic)
+ {
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,mpred_above_buf_start);
+ WRITE_VREG(HEVC_MPRED_MV_WPTR,mpred_mv_wr_ptr);
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_start_addr);
+ }
+ else if (!dec->isNextSliceSegment)
+ {
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ }
+#endif
+ WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dw_fb(struct AVS2Decoder_s *dec, struct avs2_frame_s *pic,
+ u32 mc_buffer_size_u_v_h)
+{
+
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ int dw_mode = get_double_write_mode(dec);
+ uint32_t data = 0, data32;
+ if ((dw_mode & 0x10) == 0) {
+ WRITE_BACK_8(avs2_dec, HEVC_SAO_CTRL26, 0);
+
+ //data32 = READ_VREG(HEVC_SAO_CTRL5);
+ //data32 &= (~(0xff << 16));
+ if (((dw_mode & 0xf) == 8) ||
+ ((dw_mode & 0xf) == 9)) {
+ data = 0xff; //data32 |= (0xff << 16);
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_BACK_8(avs2_dec, HEVC_SAO_CTRL26, 0xf);
+ } else {
+ if ((dw_mode & 0xf) == 2 ||
+ (dw_mode & 0xf) == 3)
+ data = 0xff; //data32 |= (0xff<<16);
+ else if ((dw_mode & 0xf) == 4 ||
+ (dw_mode & 0xf) == 5)
+ data = 0x33; //data32 |= (0x33<<16);
+
+ /*if (dec->mem_saving_mode == 1)
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 1, 9, 1); //data32 |= (1 << 9);
+ else*/
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 0, 9, 1); //data32 &= ~(1 << 9);
+ /*if (workaround_enable & 1)
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 1, 7, 1); //data32 |= (1 << 7);*/
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, data, 16, 8);
+ }
+
+ /* m8baby test1902 */
+ //data32 = READ_VREG(HEVC_SAO_CTRL1);
+ //data32 &= (~0x3000);
+ /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+ //data32 |= (dec->mem_map_mode << 12);
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, MEM_MAP_MODE, 12, 2);
+ //data32 &= (~0xff0);
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable == 0)
+ data = ((dec->endian >> 8) & 0xfff); //endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf)
+#else
+ data = ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, data, 0, 12);
+
+ //data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+ if (dw_mode == 0)
+ data = 0x2; //data32 |= 0x2; /*disable double write*/
+ else if (dw_mode & 0x10)
+ data = 0x1; //data32 |= 0x1; /*disable cm*/
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, data, 0, 2);
+
+ //data32 &= (~(3 << 14));
+ //data32 |= (2 << 14);
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, 2, 14, 2);
+ //WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+#if 0
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ unsigned int data;
+ data = (0x57 << 8) | /* 1st/2nd write both enable*/
+ (0x0 << 0); /* h265 video format*/
+ if (dec->init_pic_w >= 1280)
+ data |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
+ data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
+ if (dw_mode == 0)
+ data |= (0x1 << 8); /*enable first write*/
+ else if (dw_mode & 0x10)
+ data |= (0x1 << 9); /*double write only*/
+ else
+ data |= ((0x1 << 8) |(0x1 << 9));
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGB, data);
+ //WRITE_VREG(HEVC_DBLK_CFGB, data);
+ }
+#else
+ //data32 &= (~0x300); /*[8]:first write enable (compress)
+ // [9]:double write enable (uncompress)*/
+ if (dw_mode == 0)
+ data = 1; //data32 |= (0x1 << 8); /*enable first write*/
+ else if (dw_mode == 0x10)
+ data = 2; //data32 |= (0x1 << 9); /*double write only*/
+ else
+ data = 3; //data32 |= ((0x1 << 8) | (0x1 << 9));
+ //WRITE_VREG(HEVC_DBLK_CFGB, data32);
+ READ_WRITE_DATA16(avs2_dec, HEVC_DBLK_CFGB, data, 8, 2);
+#endif
+ if (dw_mode & 0x10) {
+ /* [23:22] dw_v1_ctrl
+ *[21:20] dw_v0_ctrl
+ *[19:18] dw_h1_ctrl
+ *[17:16] dw_h0_ctrl
+ */
+ //data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ //data32 &= ~(0xff << 16);
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 0, 16, 8);
+ }
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+ data32 = pic->mc_y_adr;
+ if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ if ((dw_mode & 0x10) == 0)
+ WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, data32);
+
+ if (dec->mmu_enable)
+ WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0);
+ WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ }
+#endif
+#else
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+ data32 = (mc_buffer_size_u_v_h << 16) << 1;
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_LENGTH, data32);
+
+ data32 = (mc_buffer_size_u_v_h << 16);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_LENGTH, data32);
+
+}
+
+static void config_sao_hw_fb(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic = avs2_dec->hc.cur_pic;
+ //union param_u* params = &avs2_dec->param;
+ //uint32_t data32; // data32_2;
+ int32_t pic_width = avs2_dec->img.width;
+ int32_t pic_height = avs2_dec->img.height;
+ int32_t lcu_size_log2 = avs2_dec->lcu_size_log2;
+ int32_t lcu_size = 1<<lcu_size_log2;
+ int32_t pic_width_lcu = ( pic_width % lcu_size ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+ int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+ int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+ int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+ int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+ config_dw_fb(dec, pic, mc_buffer_size_u_v_h);
+#if 0 // no dual mode
+ data32 = READ_VREG(HEVC_SAO_CTRL0);
+ data32 &= (~0xf);
+ data32 |= avs2_dec->lcu_size_log2;
+ WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#else
+ READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL0, avs2_dec->lcu_size_log2, 0, 4);
+#endif
+
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+ if ((get_double_write_mode(dec) & 0x20) == 0) {
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+ if (dec->dw_mmu_enable) {
+ WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0);
+ }
+
+#ifdef AVS2_10B_MMU
+ ///WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs2_dec->cm_header_start + (pic->index * MMU_COMPRESS_HEADER_SIZE));
+ //WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, avs2_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS2_10B_MMU_DW
+ //if (dec->dw_mmu_enable) {
+ ///WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+ // WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ //}
+#endif
+
+#else
+ ///WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+ data32 = (mc_buffer_size_u_v_h<<16)<<1;
+ //WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_LENGTH ,data32);
+
+ ///WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+ //WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+ data32 = (mc_buffer_size_u_v_h<<16);
+ ///WRITE_VREG(HEVC_SAO_C_LENGTH ,data32);
+ WRITE_BACK_32(avs2_dec, HEVC_SAO_C_LENGTH ,data32);
+ ///WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+ //WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+ ///WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+ //WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+#ifdef AVS2_10B_NV21
+ SHOULD NOT DEFINED !!
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ data32 &= (~0x3);
+ data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
+ data32 &= ~(0xff << 16); // set them all 0 for H265_NV21 (no down-scale)
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
+ WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgSAO .done.\n");
+}
+
+static void config_dblk_hw_fb(struct AVS2Decoder_s *dec)
+{
+ /*
+ * Picture level de-block parameter configuration here
+ */
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ union param_u *rpm_param = &avs2_dec->param;
+ uint32_t data32;
+
+#if 0 // NOT Dual Mode
+ data32 = READ_VREG(HEVC_DBLK_CFG1);
+ data32 = (((data32>>20)&0xfff)<<20) |
+ (((avs2_dec->input.sample_bit_depth == 10) ? 0xa:0x0)<<16) | // [16 +: 4]: {luma_bd[1:0],chroma_bd[1:0]}
+ (((data32>>2)&0x3fff)<<2) |
+ (((rpm_param->p.lcu_size == 6) ? 0:(rpm_param->p.lcu_size == 5) ? 1:2)<<0);// [ 0 +: 2]: lcu_size
+#ifdef LPF_SPCC_ENABLE
+ //data32 |= (dec->pic_w <= 64)?(1<<20):0; // if pic width isn't more than one CTU, disable pipeline
+ data32 |= (0x3<<20); // SPCC_ENABLE
+#endif
+ WRITE_VREG(HEVC_DBLK_CFG1, data32);
+#else
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0x6450101; //mfsp COMMON_REG_1, HEVC_DBLK_CFG1
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((((avs2_dec->input.sample_bit_depth == 10) ? 0xa:0x0)&0xffff)<<6); // movi COMMON_REG_0, data
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x, bit_depth %x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], avs2_dec->input.sample_bit_depth);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0x9604040; //ins COMMON_REG_1, COMMON_REG_0, 16, 4
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((((rpm_param->p.lcu_size == 6) ? 0:(rpm_param->p.lcu_size == 5) ? 1:2))<<6); // movi COMMON_REG_0, data
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x, rpm_param->p.lcu_size %x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], rpm_param->p.lcu_size);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0x9402040; //ins COMMON_REG_1, COMMON_REG_0, 0, 2
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#ifdef LPF_SPCC_ENABLE
+ avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | (3<<6); // movi COMMON_REG_0, data
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0x9682040; //ins COMMON_REG_1, COMMON_REG_0, 20, 2
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#endif
+
+ avs2_dec->instruction[avs2_dec->ins_offset] = 0x6050101; //mtsp COMMON_REG_1, HEVC_DBLK_CFG1
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+ avs2_dec->ins_offset++;
+#endif
+
+ data32 = (avs2_dec->img.height<<16) | avs2_dec->img.width;
+ //WRITE_VREG(HEVC_DBLK_CFG2, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFG2, data32);
+
+ data32 = ((avs2_dec->input.crossSliceLoopFilter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+ ((rpm_param->p.loop_filter_disable & 0x1)<<26) | // [26 +: 1]: loop_filter_disable
+ ((avs2_dec->input.useNSQT & 0x1)<<25) | // [25 +: 1]: useNSQT
+ ((avs2_dec->img.type & 0x7)<<22) | // [22 +: 3]: imgtype
+ ((rpm_param->p.alpha_c_offset&0x1f) <<17) | // [17 +: 5]: alpha_c_offset (-8~8)
+ ((rpm_param->p.beta_offset&0x1f) <<12) | // [12 +: 5]: beta_offset (-8~8)
+ ((rpm_param->p.chroma_quant_param_delta_cb&0x3f)<<6) | // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+ ((rpm_param->p.chroma_quant_param_delta_cr&0x3f)<<0); // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+ ///WRITE_VREG(HEVC_DBLK_CFG9, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFG9, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d),lcuSize(%d),NSQT(%d)\n",
+ avs2_dec->input.crossSliceLoopFilter,rpm_param->p.loop_filter_disable,
+ avs2_dec->input.sample_bit_depth,avs2_dec->lcu_size,avs2_dec->input.useNSQT);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: alphaCOffset(%d),betaOffset(%d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+ rpm_param->p.alpha_c_offset,rpm_param->p.beta_offset,
+ rpm_param->p.chroma_quant_param_delta_cb,rpm_param->p.chroma_quant_param_delta_cr);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: .done.\n");
+}
+
+static void reconstructCoefInfo(struct AVS2Decoder_s *dec,
+ int32_t compIdx, struct ALFParam_s *alfParam);
+static void config_alf_hw_fb(struct AVS2Decoder_s *dec)
+{
+ /*
+ * Picture level ALF parameter configuration here
+ */
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ uint32_t data32;
+ int32_t i,j;
+ int32_t m_filters_per_group;
+ struct ALFParam_s *m_alfPictureParam_y = &avs2_dec->m_alfPictureParam[0];
+ struct ALFParam_s *m_alfPictureParam_cb = &avs2_dec->m_alfPictureParam[1];
+ struct ALFParam_s *m_alfPictureParam_cr = &avs2_dec->m_alfPictureParam[2];
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filterPattern[0]=0x%x,[15]=0x%x\n",
+ m_alfPictureParam_y->componentID,
+ m_alfPictureParam_y->alf_flag,
+ m_alfPictureParam_y->filters_per_group,
+ m_alfPictureParam_y->filterPattern[0],m_alfPictureParam_y->filterPattern[15]);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[t]alfy,num_coeff(%d),coeffmulti[0][0]=0x%x,[0][1]=0x%x,[1][0]=0x%x,[1][1]=0x%x\n",
+ m_alfPictureParam_y->num_coeff,
+ m_alfPictureParam_y->coeffmulti[0][0],
+ m_alfPictureParam_y->coeffmulti[0][1],
+ m_alfPictureParam_y->coeffmulti[1][0],
+ m_alfPictureParam_y->coeffmulti[1][1]);
+
+ // Cr
+ for (i=0;i<16;i++) dec->m_varIndTab[i] = 0;
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 2, m_alfPictureParam_cr);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cr(%d), alf_cr_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cr->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Cb
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 1, m_alfPictureParam_cb);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cb(%d), alf_cb_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cb->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Y
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 0, m_alfPictureParam_y);
+ data32 = ((dec->m_varIndTab[7] & 0xf) << 28) | ((dec->m_varIndTab[6] & 0xf) << 24) |
+ ((dec->m_varIndTab[5] & 0xf) << 20) | ((dec->m_varIndTab[4] & 0xf) << 16) |
+ ((dec->m_varIndTab[3] & 0xf) << 12) | ((dec->m_varIndTab[2] & 0xf) << 8) |
+ ((dec->m_varIndTab[1] & 0xf) << 4) | ((dec->m_varIndTab[0] & 0xf) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_varIndTab[15] & 0xf) << 28) | ((dec->m_varIndTab[14] & 0xf) << 24) |
+ ((dec->m_varIndTab[13] & 0xf) << 20) | ((dec->m_varIndTab[12] & 0xf) << 16) |
+ ((dec->m_varIndTab[11] & 0xf) << 12) | ((dec->m_varIndTab[10] & 0xf) << 8) |
+ ((dec->m_varIndTab[ 9] & 0xf) << 4) | ((dec->m_varIndTab[ 8] & 0xf) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_y(%d), alf_y_tab(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_y->alf_flag,
+ dec->m_varIndTab[ 0],dec->m_varIndTab[ 1],dec->m_varIndTab[ 2],dec->m_varIndTab[ 3],
+ dec->m_varIndTab[ 4],dec->m_varIndTab[ 5],dec->m_varIndTab[ 6],dec->m_varIndTab[ 7],
+ dec->m_varIndTab[ 8],dec->m_varIndTab[ 9],dec->m_varIndTab[10],dec->m_varIndTab[11],
+ dec->m_varIndTab[12],dec->m_varIndTab[13],dec->m_varIndTab[14],dec->m_varIndTab[15]);
+
+ m_filters_per_group = (m_alfPictureParam_y->alf_flag == 0) ? 1 : m_alfPictureParam_y->filters_per_group;
+ for (i=0;i<m_filters_per_group;i++) {
+ data32 = ((dec->m_filterCoeffSym[i][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[i][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[i][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[i][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[i][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+ ((dec->m_filterCoeffSym[i][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[i][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[i][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[i][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[i][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+ }
+ if (debug & AVS2_DBG_BUFMGR_DETAIL) {
+ for (i=0;i<m_filters_per_group;i++)
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] alf_y_coef[%d](%d %d %d %d %d %d %d %d %d)\n",i,dec->m_filterCoeffSym[i][0],dec->m_filterCoeffSym[i][1],dec->m_filterCoeffSym[i][2],
+ dec->m_filterCoeffSym[i][3],dec->m_filterCoeffSym[i][4],dec->m_filterCoeffSym[i][5],
+ dec->m_filterCoeffSym[i][6],dec->m_filterCoeffSym[i][7],dec->m_filterCoeffSym[i][8]);
+ }
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgALF .done.\n");
+}
+
+static void config_mcrcc_axi_hw_fb(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ //uint32_t rdata32;
+ //uint32_t rdata32_2;
+
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+ WRITE_BACK_8(avs2_dec, HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+
+ if (avs2_dec->img.type == I_IMG) { // I-PIC
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+ WRITE_BACK_8(avs2_dec, HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+ return;
+ }
+
+#if 0
+ mcrcc_get_hitrate();
+ decomp_get_hitrate();
+ decomp_get_comprate();
+#endif
+
+ if ((avs2_dec->img.type == B_IMG) || (avs2_dec->img.type == F_IMG)) { // B-PIC or F_PIC
+ // Programme canvas0
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+ READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+ // Programme canvas1
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (1<<1) | 0);
+ WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1, (16 << 8) | (1<<1) | 0);
+ ///rdata32_2 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32_2 = rdata32_2 & 0xffff;
+ ///rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ ///if ( rdata32 == rdata32_2 ) {
+ /// rdata32_2 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ /// rdata32_2 = rdata32_2 & 0xffff;
+ /// rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ ///}
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32_2);
+ READ_CMP_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 1, 0, 16, 16);
+ } else { // P-PIC
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+ WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+ READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+ // Programme canvas1
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32);
+ READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 0, 16, 16);
+ }
+
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+ WRITE_BACK_16(avs2_dec, HEVCD_MCRCC_CTL1, 0, 0xff0); // enable mcrcc progressive-mode
+ return;
+}
+
+static void config_other_hw_fb(struct AVS2Decoder_s *dec)
+{
+
+}
+
+#endif
diff --git a/drivers/frame_provider/decoder/avs2_fb/avs2_global.h b/drivers/frame_provider/decoder/avs2_fb/avs2_global.h
new file mode 100644
index 0000000..5c395ed
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_global.h
@@ -0,0 +1,1718 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_
+
+#include <linux/amlogic/media/utils/amstream.h>
+
+#define NEW_FB_CODE
+#define NEW_FRONT_BACK_CODE
+/* #include <stdio.h> //!< for FILE */
+/* #include <stdlib.h> */
+
+#define AML
+#define SANITY_CHECK
+#undef NO_DISPLAY
+
+#define P010_ENABLE
+
+#define OW_TRIPLE_WRITE
+
+/* #include "define.h" */
+#define RD "19.2"
+#define VERSION "19.2"
+
+#define RESERVED_PROFILE_ID 0x24
+#define BASELINE_PICTURE_PROFILE 18
+#define BASELINE_PROFILE 32 /* 0x20 */
+#define BASELINE10_PROFILE 34 /* 0x22 */
+
+#define SCENE_PROFILE 48 /* 0x21 */
+#define SCENE10_PROFILE 50 /* 0x23 */
+
+#define TRACE 0 /* !< 0:Trace off 1:Trace on */
+
+#define LARGE_INSTRUCTION_SPACE_SUPORT
+
+/* Type definitions and file operation for Windows/Linux
+ * All file operations for windows are replaced with native (FILE *) operations
+ * Falei LUO (falei.luo@vipl.ict.ac.cn)
+ * */
+
+#define _FILE_OFFSET_BITS 64 /* for 64 bit fseeko */
+#define fseek fseeko
+
+#define int16 int16_t
+#define int64 int64_t
+
+/* ////////////////// bug fix ///////////////////////////// */
+#define ALFSliceFix 1
+#define WRITENBIT_FIX 1
+#define FIX_PROFILE_LEVEL_DPB_RPS_1 1
+#define FIX_PROFILE_LEVEL_DPB_RPS_2 1
+#define FIX_RPS_PICTURE_REMOVE 1 /* flluo@pku.edu.cn */
+#define Mv_Clip 1 /* yuquanhe@hisilicon.com */
+#define REMOVE_UNUSED 1 /* yuquanhe@hisilicon.com */
+#define SAO_Height_Fix 1 /* yuquanhe@hisilicon.com */
+#define B_BACKGROUND_Fix 1 /* yuquanhe@hisilicon.com */
+#define Check_Bitstream 1 /* yuquanhe@hisilicon.com */
+#define Wq_param_Clip 1 /* yuquanhe@hisilicon.com */
+ /* luofalei flluo@pku.edu.cn , wlq15@mails.tsinghua.edu.cn ,
+ Longfei.Wang@mediatek.com */
+#define RD1501_FIX_BG 1
+ /* yuquanhe@hisilicon.com ; he-yuan.lin@mstarsemi.com */
+#define Mv_Rang 1
+ /* Longfei.Wang@mediatek.com ;fred.chiu@mediatek.com
+ jie1222.chen@samsung.com */
+#define RD160_FIX_BG 1
+ /* Y_K_Tu@novatek.com.tw, he-yuan.lin@mstarsemi.com,
+ victor.huang@montage-tech.com M4041 */
+#define RD1601_FIX_BG 1
+#define SEQ_CHANGE_CHECKER 1 /* he-yuan.lin@mstarsemi.com */
+#define M4140_END_OF_SLICE_CHECKER 1 /* he-yuan.lin@mstarsemi.com */
+ /* wlq15@mails.tsinghua.edu.cn */
+#define Mv_check_bug 1
+#define SAO_ASSERTION_FIX 1 /* fred.chiu@mediatek.com */
+#define FIELD_HORI_MV_NO_SCALE_FIX 1 /* fred.chiu@mediatek.com */
+#define RD170_FIX_BG 1
+#define FIX_CHROMA_FIELD_MV_BK_DIST 1
+#define FIX_LUMA_FIELD_MV_BK_DIST 1
+#define FIX_CHROMA_FIELD_MV_CLIP 1
+#if 1
+#define FIX_FLUSH_DPB_BY_LF 1 /* fred.chiu@mediatek.com */
+#define FIX_SEQ_END_FLUSH_DPB_BY_LF 1 /* fred.chiu@mediatek.com */
+#else
+#define FIX_FLUSH_DPB_BY_LF 0 /* fred.chiu@mediatek.com */
+#define FIX_SEQ_END_FLUSH_DPB_BY_LF 0 /* fred.chiu@mediatek.com */
+#endif
+#define RD191_FIX_BUG 1 /* yuquanhe@hsilicon.com */
+#define SYM_MV_SCALE_FIX 1/* peisong.chen@broadcom.com */
+#define BUG_10BIT_REFINEQP 0 /* wangzhenyu */
+
+#if RD191_FIX_BUG
+#endif
+
+/************************
+ * AVS2 macros start
+ **************************/
+
+#define INTERLACE_CODING 1
+#if INTERLACE_CODING /* M3531: MV scaling compensation */
+/* Luma component */
+#define HALF_PIXEL_COMPENSATION 1 /* common functions definition */
+#define HALF_PIXEL_COMPENSATION_PMV 1 /* spacial MV prediction */
+#define HALF_PIXEL_COMPENSATION_DIRECT 1 /* B direct mode */
+ /* MV derivation method 1, weighted P_skip mode */
+#define HALF_PIXEL_COMPENSATION_M1 1
+ /* M1 related with mv-scaling function */
+#define HALF_PIXEL_COMPENSATION_M1_FUNCTION 1
+#define HALF_PIXEL_COMPENSATION_MVD 1 /* MV scaling from FW->BW */
+/* Chroma components */
+ /* chroma MV is scaled with luma MV for 4:2:0 format */
+#define HALF_PIXEL_CHROMA 1
+ /* half pixel compensation for p skip/direct */
+#define HALF_PIXEL_PSKIP 1
+#define INTERLACE_CODING_FIX 1 /* HLS fix */
+#define OUTPUT_INTERLACE_MERGED_PIC 1
+
+#endif
+/*
+ *******************************
+AVS2 10bit/12bit profile
+ ********************************
+ */
+
+#define DBFIX_10bit 1
+
+#define BUG_10bit 1
+
+/*
+ ***************************************
+AVS2 HIGH LEVEL SYNTAX
+ ***************************************
+ */
+#define AVS2_HDR_HLS 1
+ /* AVS2 HDR technology //yuquanhe@hisilicon.com */
+#define AVS2_HDR_Tec 1
+#if AVS2_HDR_Tec
+#define HDR_CHROMA_DELTA_QP 1 /* M3905 */
+#define HDR_ADPTIVE_UV_DELTA 1
+#endif
+/*
+ *************************************
+AVS2 S2
+ *************************************
+ */
+#define AVS2_S2_FASTMODEDECISION 1
+#define RD1510_FIX_BG 1 /* 20160714, flluo@pku.edu.cn */
+
+/* ////////////////// prediction techniques ///////////////////////////// */
+#define LAM_2Level_TU 0.8
+
+#define DIRECTION 4
+#define DS_FORWARD 4
+#define DS_BACKWARD 2
+#define DS_SYM 3
+#define DS_BID 1
+
+#define MH_PSKIP_NUM 4
+#define NUM_OFFSET 0
+#define BID_P_FST 1
+#define BID_P_SND 2
+#define FW_P_FST 3
+#define FW_P_SND 4
+#define WPM_NUM 3
+ /* M3330 changes it to 2, the original value is 3 */
+#define MAX_MVP_CAND_NUM 2
+
+#define DMH_MODE_NUM 5 /* Number of DMH mode */
+#define TH_ME 0 /* Threshold of ME */
+
+#define MV_SCALE 1
+
+/* ///// reference picture management // */
+#define FIX_MAX_REF 1 /* Falei LUO, flluo@pku.edu.cn */
+#if FIX_MAX_REF
+ /* maximum number of reference frame for each frame */
+#define MAXREF 7
+#define MAXGOP 32
+#endif
+
+/* #define REF_MAXBUFFER 7 */
+/* more bufferes for displaying and background */
+/* #define REF_MAXBUFFER 15 */
+#if 1
+#define REF_MAXBUFFER 23
+#define REF_BUFFER 16
+#else
+#if RD170_FIX_BG
+#define REF_MAXBUFFER 16
+#else
+#define REF_MAXBUFFER 7
+#endif
+#endif
+
+#ifdef TO_PORTING
+ /* block-composed background reference, fangdong@mail.ustc.edu.cn */
+#define BCBR 1
+#else
+#define BCBR 0
+#endif
+/* one more buffer for background when background_picture_output_flag is 0*/
+#define AVS2_MAX_BUFFER_NUM (REF_MAXBUFFER + 1)
+
+/* /////////////////Adaptive Loop Filter////////////////////////// */
+#define NUM_ALF_COEFF_CTX 1
+#define NUM_ALF_LCU_CTX 4
+
+#define LAMBDA_SCALE_LUMA (1.0)
+#define LAMBDA_SCALE_CHROMA (1.0)
+
+/* ////////////////// entropy coding ///////////////////////////// */
+ /* M3090: Make sure rs1 will not overflow for 8-bit unsign char */
+#define NUN_VALUE_BOUND 254
+#define Encoder_BYPASS_Final 1 /* M3484 */
+#define Decoder_Bypass_Annex 0 /* M3484 */
+#define Decoder_Final_Annex 0 /* M3540 */
+
+/* ////////////////// coefficient coding ///// */
+ /* M3035 size of an coefficient group, 4x4 */
+#define CG_SIZE 16
+
+#define SWAP(x, y) {\
+ (y) = (y) ^ (x);\
+ (x) = (y) ^ (x);\
+ (y) = (x) ^ (y);\
+}
+
+/* ////////////////// encoder optimization /////// */
+#define TH 2
+
+#define M3624MDLOG /* reserved */
+
+#define TDRDO 1 /* M3528 */
+/* #define FIX_TDRDO_BG 1 // flluo@pku.edu.cn, 20160318// */
+#define RATECONTROL 1 /* M3580 M3627 M3689 */
+#define AQPO 1 /* M3623 */
+#define AQPOM3694 0
+#define AQPOM4063 1
+#define AQPOM3762 1
+#define BGQPO 1 /* M4061 */
+#if BGQPO
+#define LONGREFERENCE 32
+#endif
+
+/* #define REPORT */
+/* ////////////////// Quantization /////////////////////////////////////// */
+ /* Adaptive frequency weighting quantization */
+#define FREQUENCY_WEIGHTING_QUANTIZATION 1
+#if FREQUENCY_WEIGHTING_QUANTIZATION
+#define CHROMA_DELTA_QP 1
+#define AWQ_WEIGHTING 1
+#define AWQ_LARGE_BLOCK_ENABLE 1
+#define COUNT_BIT_OVERHEAD 0
+#define AWQ_LARGE_BLOCK_EXT_MAPPING 1
+#endif
+
+#define QuantClip 1
+#define QuantMatrixClipFix 1 /* 20160418, fllu@pku.edu.cn */
+
+#define WQ_MATRIX_FCD 1
+#if !WQ_MATRIX_FCD
+#define WQ_FLATBASE_INBIT 7
+#else
+#define WQ_FLATBASE_INBIT 6
+#endif
+
+#define REFINED_QP 1
+
+/* ////////////////// delta QP ///// */
+ /* M3122: the minimum dQP unit is Macro block */
+#define MB_DQP 1
+ /* M3122: 1 represents left prediction
+ and 0 represents previous prediction */
+#define LEFT_PREDICTION 1
+
+/* //////////////////////SAO///////// */
+#define NUM_BO_OFFSET 32
+#define MAX_NUM_SAO_CLASSES 32
+#define NUM_SAO_BO_CLASSES_LOG2 5
+#define NUM_SAO_BO_CLASSES_IN_BIT 5
+#define MAX_DOUBLE (1.7e + 308)
+#define NUM_SAO_EO_TYPES_LOG2 2
+#define NUM_SAO_BO_CLASSES (1<<NUM_SAO_BO_CLASSES_LOG2)
+#define SAO_RATE_THR 0.75
+#define SAO_RATE_CHROMA_THR 1
+#define SAO_SHIFT_PIX_NUM 4
+
+#define SAO_PARA_CROSS_SLICE 1
+#define SAO_MULSLICE_FTR_FIX 1
+
+/* /////////////////// Transform ///////////////////// */
+#define SEC_TR_SIZE 4
+ /* apply secT to greater than or equal to 8x8 block, */
+#define SEC_TR_MIN_BITSIZE 3
+
+#define BUGFIXED_COMBINED_ST_BD 1
+
+/* /////////////////// Scalable ///////////////////// */
+#define M3480_TEMPORAL_SCALABLE 1
+#define TEMPORAL_MAXLEVEL 8
+#define TEMPORAL_MAXLEVEL_BIT 3
+
+/*
+ *************************************
+ * AVS2 macros end
+ *
+ *************************************
+ */
+
+#define CHROMA 1
+#define LUMA_8x8 2
+#define NUM_BLOCK_TYPES 8
+
+#if (!defined clamp)
+ /* !< clamp a to the range of [b;c] */
+#define clamp(a, b, c) ((a) < (b) ? (b) : ((a) > (c) ? (c) : (a)))
+#endif
+
+ /* POC200301 moved from defines.h */
+#define LOG2_MAX_FRAME_NUM_MINUS4 4
+ /* !< bytes for one frame */
+#define MAX_CODED_FRAME_SIZE 15000000
+
+/* ----------------------- */
+/* FLAGS and DEFINES for new chroma intra prediction, Dzung Hoang */
+/* Threshold values to zero out quantized transform coefficients. */
+/* Recommend that _CHROMA_COEFF_COST_ be low to improve chroma quality */
+#define _LUMA_COEFF_COST_ 4 /* !< threshold for luma coeffs */
+ /* !< Number of pixels padded around the reference frame (>=4) */
+#define IMG_PAD_SIZE 64
+
+#define OUTSTRING_SIZE 255
+
+ /* !< abs macro, faster than procedure */
+#define absm(A) ((A) < (0) ? (-(A)) : (A))
+ /* !< used for start value for some variables */
+#define MAX_VALUE 999999
+
+#define Clip1(a) ((a) > 255 ? 255:((a) < 0 ? 0 : (a)))
+#define Clip3(min, max, val) (((val) < (min)) ?\
+ (min) : (((val) > (max)) ? (max) : (val)))
+
+/* --------------------------------------------- */
+
+/* block size of block transformed by AVS */
+#define PSKIPDIRECT 0
+#define P2NX2N 1
+#define P2NXN 2
+#define PNX2N 3
+#define PHOR_UP 4
+#define PHOR_DOWN 5
+#define PVER_LEFT 6
+#define PVER_RIGHT 7
+#define PNXN 8
+#define I8MB 9
+#define I16MB 10
+#define IBLOCK 11
+#define InNxNMB 12
+#define INxnNMB 13
+#define MAXMODE 14 /* add yuqh 20130824 */
+#define LAMBDA_ACCURACY_BITS 16
+#define LAMBDA_FACTOR(lambda) ((int)((double)(1 << LAMBDA_ACCURACY_BITS)\
+ * lambda + 0.5))
+#define WEIGHTED_COST(factor, bits) (((factor) * (bits))\
+ >> LAMBDA_ACCURACY_BITS)
+#define MV_COST(f, s, cx, cy, px, py) (WEIGHTED_COST(f, mvbits[((cx) << (s))\
+ - px] + mvbits[((cy) << (s)) - py]))
+#define REF_COST(f, ref) (WEIGHTED_COST(f, refbits[(ref)]))
+
+#define BWD_IDX(ref) (((ref) < 2) ? 1 - (ref) : (ref))
+#define REF_COST_FWD(f, ref) (WEIGHTED_COST(f,\
+ ((img->num_ref_pic_active_fwd_minus1 == 0) ?\
+ 0 : refbits[(ref)])))
+#define REF_COST_BWD(f, ef) (WEIGHTED_COST(f,\
+ ((img->num_ref_pic_active_bwd_minus1 == 0) ?\
+ 0 : BWD_IDX(refbits[ref]))))
+
+#define IS_INTRA(MB) ((MB)->cuType == I8MB ||\
+ (MB)->cuType == I16MB ||\
+ (MB)->cuType == InNxNMB || (MB)->cuType == INxnNMB)
+#define IS_INTER(MB) ((MB)->cuType != I8MB &&\
+ (MB)->cuType != I16MB && (MB)->cuType != InNxNMB\
+ && (MB)->cuType != INxnNMB)
+#define IS_INTERMV(MB) ((MB)->cuType != I8MB &&\
+ (MB)->cuType != I16MB && (MB)->cuType != InNxNMB &&\
+ (MB)->cuType != INxnNMB && (MB)->cuType != 0)
+
+#define IS_DIRECT(MB) ((MB)->cuType == PSKIPDIRECT && (img->type == B_IMG))
+#define IS_P_SKIP(MB) ((MB)->cuType == PSKIPDIRECT &&\
+ (((img->type == F_IMG)) || ((img->type == P_IMG))))
+#define IS_P8x8(MB) ((MB)->cuType == PNXN)
+
+/* Quantization parameter range */
+#define MIN_QP 0
+#define MAX_QP 63
+#define SHIFT_QP 11
+
+/* Picture types */
+#define INTRA_IMG 0 /* !< I frame */
+#define INTER_IMG 1 /* !< P frame */
+#define B_IMG 2 /* !< B frame */
+#define I_IMG 0 /* !< I frame */
+#define P_IMG 1 /* !< P frame */
+#define F_IMG 4 /* !< F frame */
+
+#define BACKGROUND_IMG 3
+
+#define BP_IMG 5
+
+/* Direct Mode types */
+#define MIN_CU_SIZE 8
+#define MIN_BLOCK_SIZE 4
+#define MIN_CU_SIZE_IN_BIT 3
+#define MIN_BLOCK_SIZE_IN_BIT 2
+#define BLOCK_MULTIPLE (MIN_CU_SIZE/(MIN_BLOCK_SIZE))
+#define MAX_CU_SIZE 64
+#define MAX_CU_SIZE_IN_BIT 6
+#define B4X4_IN_BIT 2
+#define B8X8_IN_BIT 3
+#define B16X16_IN_BIT 4
+#define B32X32_IN_BIT 5
+#define B64X64_IN_BIT 6
+ /* !< # luma intra prediction modes */
+#define NUM_INTRA_PMODE 33
+ /* number of luma modes for full RD search */
+#define NUM_MODE_FULL_RD 9
+ /* !< #chroma intra prediction modes */
+#define NUM_INTRA_PMODE_CHROMA 5
+
+/* luma intra prediction modes */
+
+#define DC_PRED 0
+#define PLANE_PRED 1
+#define BI_PRED 2
+#define VERT_PRED 12
+#define HOR_PRED 24
+
+/* chroma intra prediction modes */
+#define DM_PRED_C 0
+#define DC_PRED_C 1
+#define HOR_PRED_C 2
+#define VERT_PRED_C 3
+#define BI_PRED_C 4
+
+#define EOS 1 /* !< End Of Sequence */
+ /* !< Start Of Picture */
+#define SOP 2
+
+#define DECODING_OK 0
+#define SEARCH_SYNC 1
+#define DECODE_MB 1
+
+#ifndef max
+ /* !< Macro returning max value */
+#define max(a, b) ((a) > (b) ? (a) : (b))
+ /* !< Macro returning min value */
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define XY_MIN_PMV 1
+#if XY_MIN_PMV
+#define MVPRED_xy_MIN 0
+#else
+#define MVPRED_MEDIAN 0
+#endif
+#define MVPRED_L 1
+#define MVPRED_U 2
+#define MVPRED_UR 3
+
+#define DUAL 4
+#define FORWARD 0
+#define BACKWARD 1
+#define SYM 2
+#define BID 3
+#define INTRA -1
+
+#define BUF_CYCLE 5
+
+#define ROI_M3264 1 /* ROI Information Encoding */
+
+#define PicExtensionData 1
+
+#define REF_OUTPUT 1 /* M3337 */
+
+/* MV scaling 14 bit */
+#define MULTI 16384
+#define HALF_MULTI 8192
+#define OFFSET 14
+/* end of MV scaling */
+ /* store the middle pixel's mv in a motion information unit */
+#define MV_DECIMATION_FACTOR 4
+
+/* BUGFIX_AVAILABILITY_INTRA */
+#define NEIGHBOR_INTRA_LEFT 0
+#define NEIGHBOR_INTRA_UP 1
+#define NEIGHBOR_INTRA_UP_RIGHT 2
+#define NEIGHBOR_INTRA_UP_LEFT 3
+#define NEIGHBOR_INTRA_LEFT_DOWN 4
+/* end of BUGFIX_AVAILABILITY_INTRA */
+
+/* end #include "define.h" */
+
+/*#include "commonStructures.h"*/
+
+/*typedef uint16_t byte;*/ /* !< byte type definition */
+#define byte uint16_t
+#define pel_t byte
+
+enum BitCountType_e {
+ BITS_HEADER,
+ BITS_TOTAL_MB,
+ BITS_MB_MODE,
+ BITS_INTER_MB,
+ BITS_CBP_MB,
+ BITS_CBP01_MB,
+ BITS_COEFF_Y_MB,
+ BITS_COEFF_UV_MB,
+ BITS_DELTA_QUANT_MB,
+ BITS_SAO_MB,
+ MAX_BITCOUNTER_MB
+};
+
+enum SAOEOClasses {
+/* EO Groups, the assignments depended on
+how you implement the edgeType calculation */
+ SAO_CLASS_EO_FULL_VALLEY = 0,
+ SAO_CLASS_EO_HALF_VALLEY = 1,
+ SAO_CLASS_EO_PLAIN = 2,
+ SAO_CLASS_EO_HALF_PEAK = 3,
+ SAO_CLASS_EO_FULL_PEAK = 4,
+ SAO_CLASS_BO = 5,
+ NUM_SAO_EO_CLASSES = SAO_CLASS_BO,
+ NUM_SAO_OFFSET
+};
+
+struct SAOstatdata {
+ int32_t diff[MAX_NUM_SAO_CLASSES];
+ int32_t count[MAX_NUM_SAO_CLASSES];
+};
+
+struct CopyRight_s {
+ int32_t extension_id;
+ int32_t copyright_flag;
+ int32_t copyright_id;
+ int32_t original_or_copy;
+ int32_t reserved;
+ int32_t copyright_number;
+};
+
+struct CameraParameters_s {
+ int32_t reserved;
+ int32_t camera_id;
+ int32_t height_of_image_device;
+ int32_t focal_length;
+ int32_t f_number;
+ int32_t vertical_angle_of_view;
+ int32_t camera_position_x;
+ int32_t camera_position_y;
+ int32_t camera_position_z;
+ int32_t camera_direction_x;
+ int32_t camera_direction_y;
+ int32_t camera_direction_z;
+ int32_t image_plane_vertical_x;
+ int32_t image_plane_vertical_y;
+ int32_t image_plane_vertical_z;
+};
+
+/* ! SNRParameters */
+struct SNRParameters_s {
+ double snr_y; /* !< current Y SNR */
+ double snr_u; /* !< current U SNR */
+ double snr_v; /* !< current V SNR */
+ double snr_y1; /* !< SNR Y(dB) first frame */
+ double snr_u1; /* !< SNR U(dB) first frame */
+ double snr_v1; /* !< SNR V(dB) first frame */
+ double snr_ya; /* !< Average SNR Y(dB) remaining frames */
+ double snr_ua; /* !< Average SNR U(dB) remaining frames */
+ double snr_va; /* !< Average SNR V(dB) remaining frames */
+#if INTERLACE_CODING
+ double i_snr_ya; /* !< current Y SNR */
+ double i_snr_ua; /* !< current U SNR */
+ double i_snr_va; /* !< current V SNR */
+#endif
+};
+
+/* signal to noise ratio parameters */
+
+/* ! codingUnit */
+struct codingUnit {
+ uint32_t ui_MbBitSize;
+ int32_t uiBitSize; /* size of MB */
+ /* !< number of current syntax element */
+ int32_t currSEnr;
+ int32_t slice_nr;
+ int32_t delta_quant; /* !< for rate control */
+ int32_t delta_qp;
+ int32_t qp;
+ int32_t bitcounter[MAX_BITCOUNTER_MB];
+ struct codingUnit
+ *mb_available[3][3]; /*!< pointer to neighboring MBs
+ in a 3x3 window of current MB, which is located at [1][1] \n
+ NULL pointer identifies neighboring MBs which are unavailable */
+ /* some storage of codingUnit syntax elements for global access */
+ int32_t cuType;
+ int32_t weighted_skipmode;
+
+ int32_t md_directskip_mode;
+
+ int32_t trans_size;
+ int
+ /* !< indices correspond to [forw,backw][block_y][block_x][x,y, dmh] */
+ mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][3];
+
+ int32_t intra_pred_modes[BLOCK_MULTIPLE * BLOCK_MULTIPLE];
+ int32_t real_intra_pred_modes[BLOCK_MULTIPLE * BLOCK_MULTIPLE];
+ int32_t l_ipred_mode;
+ int32_t cbp, cbp_blk;
+ uint32_t cbp_bits;
+
+ int32_t b8mode[4];
+ int32_t b8pdir[4];
+ /* !< chroma intra prediction mode */
+ int32_t c_ipred_mode;
+
+ /* !< pointer to neighboring MB (AEC) */
+ struct codingUnit *mb_available_up;
+ /* !< pointer to neighboring MB (AEC) */
+ struct codingUnit *mb_available_left;
+ int32_t mbAddrA, mbAddrB, mbAddrC, mbAddrD;
+ /* !<added by mz, 2008.04 */
+ int32_t slice_set_index;
+ /* added by mz, 2008.04 */
+ int32_t slice_header_flag;
+ int32_t sliceqp; /* added by mz, 2008.04 */
+#if MB_DQP
+ int32_t previouse_qp;
+ int32_t left_cu_qp;
+#endif
+ int32_t block_available_up;
+ int32_t block_available_left;
+
+};
+
+/* image parameters */
+struct syntaxelement;
+struct slice;
+struct alfdatapart;
+struct SAOBlkParam_s {
+ int32_t modeIdc; /* NEW, MERGE, OFF */
+ /* NEW: EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, above */
+ int32_t typeIdc;
+ int32_t startBand; /* BO: starting band index */
+ int32_t startBand2;
+ int32_t deltaband;
+ int32_t offset[MAX_NUM_SAO_CLASSES];
+};
+struct ALFParam_s {
+ int32_t alf_flag;
+ int32_t num_coeff;
+ int32_t filters_per_group;
+ int32_t componentID;
+ int32_t filterPattern[16]; /* *filterPattern; */
+ int32_t coeffmulti[16][9]; /* **coeffmulti; */
+};
+
+enum ALFComponentID {
+ ALF_Y = 0,
+ ALF_Cb,
+ ALF_Cr,
+ NUM_ALF_COMPONENT
+};
+struct ALF_APS_s {
+ int32_t usedflag;
+ int32_t cur_number;
+ int32_t max_number;
+ struct ALFParam_s alf_par[NUM_ALF_COMPONENT];
+};
+
+/* ------------------------------------------------------
+ * frame data
+ */
+struct avs2_frame_s {
+ int32_t imgcoi_ref;
+ byte * *referenceFrame[3];
+ int32_t **refbuf;
+ int32_t ***mvbuf;
+#if 0
+ double saorate[NUM_SAO_COMPONENTS];
+#endif
+ byte ***ref;
+
+ int32_t imgtr_fwRefDistance;
+ int32_t referred_by_others;
+ int32_t is_output;
+ int32_t to_prepare_disp;
+#if M3480_TEMPORAL_SCALABLE
+ /* temporal level setted in configure file */
+ int32_t temporal_id;
+#endif
+ byte **oneForthRefY;
+#if FIX_MAX_REF
+ int32_t ref_poc[MAXREF];
+#else
+ int32_t ref_poc[4];
+#endif
+#ifdef AML
+ int32_t index;
+ int32_t mmu_alloc_flag;
+ int32_t lcu_size_log2;
+ /*uint32_t header_adr;*/
+ uint32_t mc_y_adr;
+ uint32_t mc_u_v_adr;
+ uint32_t mc_canvas_y;
+ uint32_t mc_canvas_u_v;
+ uint32_t mpred_mv_wr_start_addr;
+ uint8_t bg_flag;
+ /**/
+ unsigned long header_adr;
+ /*AVS2_10B_MMU_DW*/
+ unsigned long dw_header_adr;
+
+ int buf_size;
+ int lcu_total;
+ int comp_body_size;
+ uint32_t dw_y_adr;
+ uint32_t dw_u_v_adr;
+ int y_canvas_index;
+ int uv_canvas_index;
+ struct canvas_config_s canvas_config[2];
+ int double_write_mode;
+ int bit_depth;
+ unsigned long cma_alloc_addr;
+ int BUF_index;
+ int pic_w;
+ int pic_h;
+ u32 stream_offset;
+ u32 pts;
+ u64 pts64;
+ /**/
+ int vf_ref;
+ int decode_idx;
+ int slice_type;
+ int32_t imgtr_fwRefDistance_bak;
+ int32_t error_mark;
+ int32_t decoded_lcu;
+#endif
+#ifndef MV_USE_FIXED_BUF
+ int mv_buf_index;
+#endif
+
+ /* picture qos information*/
+ struct vframe_qos_s vqos;
+
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
+
+ char *cuva_data_buf;
+ int cuva_data_size;
+#ifdef NEW_FB_CODE
+ unsigned char back_done_mark;
+ //unsigned char flush_mark;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+ int backend_ref;
+ int width;
+ int height;
+ int depth;
+ struct avs2_frame_s *ref_pic[MAXREF];
+#endif
+#ifdef OW_TRIPLE_WRITE
+ unsigned int tw_y_adr;
+ unsigned int tw_u_v_adr;
+
+ //int tw_y_canvas_index;
+ //int tw_uv_canvas_index;
+ struct canvas_config_s tw_canvas_config[2];
+
+ u32 triple_write_mode;
+#endif
+#ifdef AML
+ u64 time;
+ s32 poc;
+ u32 hw_front_decode_time;
+ u32 stream_size; // For stream base mode
+#endif
+};
+
+struct ImageParameters_s {
+ struct codingUnit *mb_data;
+ int32_t number; /* <! frame number */
+ int32_t numIPFrames;
+
+ int32_t type;
+ int32_t typeb;
+ int32_t typeb_before;
+
+ int32_t qp; /* <! quant for the current frame */
+ int32_t current_mb_nr; /* bitstream order */
+ int32_t current_slice_nr;
+ int32_t tr; /* <! temporal reference, 8 bit, */
+
+ int32_t width; /* !< Number of pels */
+ int32_t width_cr; /* !< Number of pels chroma */
+ int32_t height; /* !< Number of lines */
+ int32_t height_cr; /* !< Number of lines chroma */
+ int32_t PicWidthInMbs;
+ int32_t PicSizeInMbs;
+ int32_t block8_x, block8_y;
+ int32_t subblock_x;
+ int32_t subblock_y;
+
+ int32_t num_of_references;
+ /* <! Bug Fix: correct picture size for outputted reconstructed pictures */
+ int32_t auto_crop_right;
+ int32_t auto_crop_bottom;
+ int32_t buf_cycle;
+ int32_t picture_structure;
+ /* <! pointer to current Slice data struct */
+ struct slice *currentSlice;
+
+ int32_t **predBlock; /* !< current best prediction mode */
+ int32_t **predBlockTmp;
+ /* !< the diff pixel values between original image and prediction */
+ int32_t **resiY;
+ /* !< Array containing square values,used for snr computation */
+ int32_t *quad;
+
+ /* //location of current MB////// */
+ int32_t mb_y; /* !< current MB vertical */
+ int32_t mb_x; /* !< current MB horizontal */
+ int32_t pix_y; /* !< current pixel vertical */
+ int32_t pix_x; /* !< current pixel horizontal */
+ int32_t pix_c_y; /* !< current pixel chroma vertical */
+ int32_t pix_c_x; /* !< current pixel chroma horizontal */
+
+ int32_t imgtr_next_P;
+
+ int32_t imgcoi_next_ref;
+
+ /* !< GH ipredmode[90][74];prediction mode for inter frames */
+ /* fix from ver 4.1 */
+ int32_t **ipredmode;
+ int32_t **rec_ipredmode;
+
+ /* //////////////decoder////////////////////////// */
+ int32_t max_mb_nr;
+ int32_t **intra_block;
+
+ int32_t block_y;
+ int32_t block_x;
+ /* <! final 4x4 block. Extended to 16x16 for AVS */
+ int32_t resiUV[2][MAX_CU_SIZE][MAX_CU_SIZE];
+
+ int32_t **fw_refFrArr; /* <! [72][88]; */
+ int32_t **bw_refFrArr; /* <! [72][88]; */
+
+ int32_t random_access_decodable_flag;
+
+ int32_t seq_header_indicate;
+ int32_t B_discard_flag;
+
+ /* B pictures */
+ uint32_t pic_distance;
+
+ uint32_t coding_order;
+
+ uint32_t PrevPicDistanceLsb;
+ int32_t CurrPicDistanceMsb;
+
+ int32_t PicHeightInMbs;
+
+ int32_t types;
+
+ int32_t new_sequence_flag;
+ int32_t sequence_end_flag; /* <! rm52k_r2 */
+
+ int32_t current_slice_set_index; /* <! added by mz, 2008.04 */
+ int32_t current_slice_header_flag; /* <! added by mz, 2008.04 */
+ int32_t slice_set_qp[64]; /* <! added by mz, 2008.04 */
+
+ int32_t inter_amp_enable;
+
+ /* ////////////////////////encoder////////////////////////// */
+
+ /* int32_t nb_references; //!< replaced by "num_of_references" */
+
+ int32_t framerate;
+
+ int32_t ***predBlockY; /* !< all 9 prediction modes */
+ /* !< new chroma 8x8 intra prediction modes */
+ int32_t ****predBlockUV;
+
+ int32_t **Coeff_all;/* qyu 0821 */
+
+ struct syntaxelement *MB_SyntaxElements; /* !< by oliver 0612 */
+
+ /* B pictures */
+
+ int32_t b_frame_to_code;
+ int32_t num_ref_pic_active_fwd_minus1;
+ int32_t num_ref_pic_active_bwd_minus1;
+ int32_t mv_range_flag;
+
+ uint32_t frame_num; /* frame_num for this frame */
+ int32_t slice_offset;
+ /* the following are sent in the slice header */
+ int32_t NoResidueDirect;
+ int32_t coded_mb_nr;
+ int32_t progressive_frame;
+ int32_t tc_reserve_bit;
+ /* the last MB no in current slice. Yulj 2004.07.15 */
+ int32_t mb_no_currSliceLastMB;
+ int32_t Seqheader_flag; /* Added by cjw, 20070327 */
+ int32_t EncodeEnd_flag; /* Carmen, 2007/12/19 */
+
+ uint16_t bbv_delay;
+
+ int32_t tmp_fwBSkipMv[DIRECTION + 1][2];
+ int32_t tmp_bwBSkipMv[DIRECTION + 1][2];
+
+ int32_t tmp_pref_fst[MH_PSKIP_NUM + NUM_OFFSET + 1];
+ int32_t tmp_pref_snd[MH_PSKIP_NUM + NUM_OFFSET + 1];
+ int32_t tmp_fstPSkipMv[MH_PSKIP_NUM + NUM_OFFSET + 1][3];
+ int32_t tmp_sndPSkipMv[MH_PSKIP_NUM + NUM_OFFSET + 1][3];
+#if BCBR
+byte *org_ref_y;
+byte *org_ref_u;
+byte *org_ref_v;
+int32_t *BLCUidx;
+int32_t *DQPList;
+int32_t iNumCUsInFrame;
+
+byte *org_ref2_y;
+byte *org_ref2_u;
+byte *org_ref2_v;
+int32_t ref2Num;
+#endif
+/* //////////////SAO parameter////////////////// */
+double *cur_saorate;
+#if 0
+int32_t slice_sao_on[NUM_SAO_COMPONENTS];
+#endif
+int32_t pic_alf_on[NUM_ALF_COMPONENT];
+struct alfdatapart *dp_ALF;
+
+#if INTERLACE_CODING
+int32_t is_field_sequence;
+int32_t is_top_field;
+#endif
+
+};
+
+/* ! struct for context management */
+struct BiContextType_s {
+ uint8_t MPS; /* 1 bit */
+ uint32_t LG_PMPS; /* 10 bits */
+ uint8_t cycno; /* 2 bits */
+};
+
+/***********************************************************************
+ * D a t a t y p e s f o r A E C
+ ************************************************************************/
+
+struct pix_pos {
+ int32_t available; /* ABCD */
+ int32_t mb_addr; /* MB position */
+ int32_t x;
+ int32_t y;
+ int32_t pos_x; /* 4x4 x-pos */
+ int32_t pos_y;
+};
+
+struct STDOUT_DATA_s {
+ int32_t type;
+ int32_t typeb;
+
+ int32_t frame_num;
+ int32_t tr;
+ int32_t qp;
+ double snr_y;
+ double snr_u;
+ double snr_v;
+ int32_t tmp_time;
+ int32_t picture_structure;
+ int32_t curr_frame_bits;
+ int32_t emulate_bits;
+
+ uint32_t DecMD5Value[4];
+#if RD1501_FIX_BG
+int32_t background_picture_output_flag;/* Longfei.Wang@mediatek.com */
+#endif
+#if RD160_FIX_BG
+int32_t picture_reorder_delay;
+#endif
+int8_t str_reference_list[128]; /* reference list information */
+};
+
+/**********************************************************************
+ * C O N T E X T S F O R T M L S Y N T A X E L E M E N T S
+ **********************************************************************
+ */
+#define NUM_CuType_CTX (11 + 10)
+#define NUM_B8_TYPE_CTX 9
+#define NUM_MVD_CTX 15
+#define NUM_PMV_IDX_CTX 10
+#define NUM_REF_NO_CTX 6
+#define NUM_DELTA_QP_CTX 4
+#define NUM_INTER_DIR_CTX 18
+#define NUM_INTER_DIR_DHP_CTX 3
+#define NUM_B8_TYPE_DHP_CTX 1
+#define NUM_AMP_CTX 2
+#define NUM_C_INTRA_MODE_CTX 4
+#define NUM_CBP_CTX 4
+#define NUM_BCBP_CTX 4
+#define NUM_MAP_CTX 17
+#define NUM_LAST_CTX 17
+
+#define NUM_INTRA_MODE_CTX 7
+
+#define NUM_ABS_CTX 5
+#define NUM_TU_CTX 3
+#define NUM_SPLIT_CTX 8 /* CU depth */
+#if BCBR
+#define NUM_BGBLCOK_CTX 1
+#endif
+
+#define NUM_BRP_CTX 8
+
+#define NUM_LAST_CG_CTX_LUMA 12
+#define NUM_LAST_CG_CTX_CHROMA 6
+#define NUM_SIGCG_CTX_LUMA 2
+#define NUM_SIGCG_CTX_CHROMA 1
+#define NUM_LAST_POS_CTX_LUMA 56
+#define NUM_LAST_POS_CTX_CHROMA 16
+#define NUM_LAST_CG_CTX (NUM_LAST_CG_CTX_LUMA + NUM_LAST_CG_CTX_CHROMA)
+#define NUM_SIGCG_CTX (NUM_SIGCG_CTX_LUMA + NUM_SIGCG_CTX_CHROMA)
+#define NUM_LAST_POS_CTX (NUM_LAST_POS_CTX_LUMA + NUM_LAST_POS_CTX_CHROMA)
+#define NUM_SAO_MERGE_FLAG_CTX 3
+#define NUM_SAO_MODE_CTX 1
+#define NUM_SAO_OFFSET_CTX 2
+#define NUM_INTER_DIR_MIN_CTX 2
+
+/*end #include "commonStructures.h"*/
+
+/*#include "commonVariables.h"*/
+
+/*
+extern struct CameraParameters_s *camera;
+extern struct SNRParameters_s *snr;
+extern struct ImageParameters_s *img;
+ */
+
+/* avs2_frame_t *fref[REF_MAXBUFFER]; */
+
+#define ET_SIZE 300 /* !< size of error text buffer */
+
+/* ------------------------------------------------------
+ * common data
+ */
+struct Video_Com_data_s {
+ int32_t Bframe_ctr;
+
+ /* FILE *p_log; //!< SNR file */
+ /* FILE *p_trace; //!< Trace file */
+
+ int32_t tot_time;
+
+ /* Tsinghua for picture_distance 200701 */
+ int32_t picture_distance;
+
+ /* M3178 PKU Reference Manage */
+ int32_t coding_order;
+ /* !< current encoding/decoding frame pointer */
+ struct avs2_frame_s *f_rec;
+ int32_t seq_header;
+ /* !< Array for reference frames of each block */
+ int32_t **refFrArr;
+ int32_t **p_snd_refFrArr;
+
+ byte ***currentFrame; /* [yuv][height][width] */
+#ifdef AML
+ struct avs2_frame_s *cur_pic; /*either f_rec or m_bg*/
+#endif
+ byte **backgroundReferenceFrame[3];
+ byte ***background_ref;
+
+ int32_t total_frames;
+
+ /* mv_range, 20071009 */
+ int32_t Min_V_MV;
+ int32_t Max_V_MV;
+ int32_t Min_H_MV;
+ int32_t Max_H_MV;
+ /* !< buffer for error message for exit with error(void) */
+ int8_t errortext[ET_SIZE];
+ int8_t str_list_reference[128];
+
+};
+/* extern Video_Com_data *hc; */
+
+/*end #include "commonVariables.h"*/
+/* #define USE_PARAM_TXT */
+/*
+#if FIX_CHROMA_FIELD_MV_BK_DIST
+int8_t bk_img_is_top_field;
+#endif
+*/
+/* void write_GB_frame(FILE *p_dec); */
+
+#if !FIX_MAX_REF
+#define MAXREF 4
+#define MAXGOP 32
+#endif
+
+struct StatBits {
+ int32_t curr_frame_bits;
+ int32_t prev_frame_bits;
+ int32_t emulate_bits;
+ int32_t prev_emulate_bits;
+ int32_t last_unit_bits;
+ int32_t bitrate;
+ int32_t total_bitrate[1000];
+ int32_t coded_pic_num;
+ int32_t time_s;
+};
+
+struct reference_management {
+ int32_t poc;
+ int32_t qp_offset;
+ int32_t num_of_ref;
+ int32_t referred_by_others;
+ int32_t ref_pic[MAXREF];
+ int32_t predict;
+ int32_t deltaRPS;
+ int32_t num_to_remove;
+ int32_t remove_pic[MAXREF];
+};
+
+/* ------------------------------------------------------
+ * dec data
+ */
+struct Video_Dec_data_s {
+ byte **background_frame[3];
+ int32_t background_reference_enable;
+
+ int32_t background_picture_flag;
+ int32_t background_picture_output_flag;
+ int32_t background_picture_enable;
+
+ int32_t background_number;
+
+#if BCBR
+ int32_t bcbr_enable;
+#endif
+
+ int32_t demulate_enable;
+ int32_t currentbitoffset;
+
+ int32_t aspect_ratio_information;
+ int32_t frame_rate_code;
+ int32_t bit_rate_lower;
+ int32_t bit_rate_upper;
+ int32_t marker_bit;
+
+ int32_t video_format;
+ int32_t color_description;
+ int32_t color_primaries;
+ int32_t transfer_characteristics;
+ int32_t matrix_coefficients;
+
+ int32_t progressive_sequence;
+#if INTERLACE_CODING
+int32_t is_field_sequence;
+#endif
+int32_t low_delay;
+int32_t horizontal_size;
+int32_t vertical_size;
+int32_t sample_precision;
+int32_t video_range;
+
+int32_t display_horizontal_size;
+int32_t display_vertical_size;
+int32_t TD_mode;
+int32_t view_packing_mode;
+int32_t view_reverse;
+
+int32_t b_pmvr_enabled;
+int32_t dhp_enabled;
+int32_t b_dmh_enabled;
+int32_t b_mhpskip_enabled;
+int32_t wsm_enabled;
+int32_t b_secT_enabled;
+
+int32_t tmp_time;
+int32_t FrameNum;
+int32_t eos;
+int32_t pre_img_type;
+int32_t pre_img_types;
+/* int32_t pre_str_vec; */
+int32_t pre_img_tr;
+int32_t pre_img_qp;
+int32_t pre_tmp_time;
+int32_t RefPicExist; /* 20071224 */
+int32_t BgRefPicExist;
+int32_t dec_ref_num; /* ref order */
+
+/* video edit code */ /* M1956 by Grandview 2006.12.12 */
+int32_t vec_flag;
+
+/* Copyright_extension(void) header */
+int32_t copyright_flag;
+int32_t copyright_identifier;
+int32_t original_or_copy;
+int64_t copyright_number_1;
+int64_t copyright_number_2;
+int64_t copyright_number_3;
+/* Camera_parameters_extension */
+int32_t camera_id;
+int32_t height_of_image_device;
+int32_t focal_length;
+int32_t f_number;
+int32_t vertical_angle_of_view;
+int32_t camera_position_x_upper;
+int32_t camera_position_x_lower;
+int32_t camera_position_y_upper;
+int32_t camera_position_y_lower;
+int32_t camera_position_z_upper;
+int32_t camera_position_z_lower;
+int32_t camera_direction_x;
+int32_t camera_direction_y;
+int32_t camera_direction_z;
+int32_t image_plane_vertical_x;
+int32_t image_plane_vertical_y;
+int32_t image_plane_vertical_z;
+
+#if AVS2_HDR_HLS
+/* mastering_display_and_content_metadata_extension(void) header */
+int32_t display_primaries_x0;
+int32_t display_primaries_y0;
+int32_t display_primaries_x1;
+int32_t display_primaries_y1;
+int32_t display_primaries_x2;
+int32_t display_primaries_y2;
+int32_t white_point_x;
+int32_t white_point_y;
+int32_t max_display_mastering_luminance;
+int32_t min_display_mastering_luminance;
+int32_t maximum_content_light_level;
+int32_t maximum_frame_average_light_level;
+#endif
+
+/* I_pictures_header(void) */
+int32_t top_field_first;
+int32_t repeat_first_field;
+int32_t progressive_frame;
+#if INTERLACE_CODING
+int32_t is_top_field;
+#endif
+/* int32_t fixed_picture_qp; //qyu 0927 */
+int32_t picture_qp;
+int32_t fixed_picture_qp;
+int32_t time_code_flag;
+int32_t time_code;
+int32_t loop_filter_disable;
+int32_t loop_filter_parameter_flag;
+/* int32_t alpha_offset; */
+/* int32_t beta_offset; */
+
+/* Pb_picture_header(void) */
+int32_t picture_coding_type;
+
+/*picture_display_extension(void)*/
+int32_t frame_centre_horizontal_offset[4];
+int32_t frame_centre_vertical_offset[4];
+
+/* slice_header(void) */
+int32_t img_width;
+int32_t slice_vertical_position;
+int32_t slice_vertical_position_extension;
+int32_t fixed_slice_qp;
+int32_t slice_qp;
+int32_t slice_horizontal_positon; /* added by mz, 2008.04 */
+int32_t slice_horizontal_positon_extension;
+
+int32_t StartCodePosition;
+int32_t background_pred_flag;
+
+/* Reference Manage */
+int32_t displaydelay;
+int32_t picture_reorder_delay;
+#if M3480_TEMPORAL_SCALABLE
+int32_t temporal_id_exist_flag;
+#endif
+
+int32_t gop_size;
+struct reference_management decod_RPS[MAXGOP];
+struct reference_management curr_RPS;
+int32_t last_output;
+int32_t trtmp;
+#if M3480_TEMPORAL_SCALABLE
+int32_t cur_layer;
+#endif
+
+/* Adaptive frequency weighting quantization */
+#if FREQUENCY_WEIGHTING_QUANTIZATION
+int32_t weight_quant_enable_flag;
+int32_t load_seq_weight_quant_data_flag;
+
+int32_t pic_weight_quant_enable_flag;
+int32_t pic_weight_quant_data_index;
+int32_t weighting_quant_param;
+int32_t weighting_quant_model;
+int16_t quant_param_undetail[6]; /* M2148 2007-09 */
+int16_t quant_param_detail[6]; /* M2148 2007-09 */
+int32_t WeightQuantEnable; /* M2148 2007-09 */
+int32_t mb_adapt_wq_disable; /* M2331 2008-04 */
+int32_t mb_wq_mode; /* M2331 2008-04 */
+#if CHROMA_DELTA_QP
+int32_t chroma_quant_param_disable;
+int32_t chroma_quant_param_delta_u;
+int32_t chroma_quant_param_delta_v;
+#endif
+
+int32_t b_pre_dec_intra_img;
+int32_t pre_dec_img_type;
+int32_t CurrentSceneModel;
+#endif
+
+int32_t curr_IDRcoi;
+int32_t curr_IDRtr;
+int32_t next_IDRtr;
+int32_t next_IDRcoi;
+int32_t end_SeqTr;
+
+#if MB_DQP
+int32_t lastQP;
+/* FILE * testQP; */
+#endif
+
+};
+/* extern Video_Dec_data *hd; */
+
+struct DecodingEnvironment_s {
+ uint32_t Dbuffer;
+ int32_t Dbits_to_go;
+ uint8_t *Dcodestrm;
+ int32_t *Dcodestrm_len;
+};
+
+/* added at rm52k version */
+
+struct inp_par;
+
+/* ! Slice */
+struct slice {
+ int32_t picture_id;
+ int32_t qp;
+ int32_t picture_type; /* !< picture type */
+ int32_t start_mb_nr;
+ /* !< number of different partitions */
+ int32_t max_part_nr;
+
+ /* added by lzhang */
+ /* !< pointer to struct of context models for use in AEC */
+ struct SyntaxInfoContexts_s *syn_ctx;
+};
+
+struct alfdatapart {
+ struct Bitstream_s *bitstream;
+ struct DecodingEnvironment_s de_AEC;
+ struct SyntaxInfoContexts_s *syn_ctx;
+};
+/* static int32_t alfParAllcoated = 0; */
+
+/* input parameters from configuration file */
+struct inp_par {
+ int32_t buf_cycle; /* <! Frame buffer size */
+ int32_t ref_pic_order; /* <! ref order */
+ int32_t output_dec_pic; /* <! output_dec_pic */
+ int32_t profile_id;
+ int32_t level_id;
+ int32_t chroma_format;
+ int32_t g_uiMaxSizeInBit;
+ int32_t alpha_c_offset;
+ int32_t beta_offset;
+ int32_t useNSQT;
+#if MB_DQP
+ int32_t useDQP;
+#endif
+ int32_t useSDIP;
+ int32_t sao_enable;
+#if M3480_TEMPORAL_SCALABLE
+ int32_t temporal_id_exist_flag;
+#endif
+ int32_t alf_enable;
+
+ int32_t crossSliceLoopFilter;
+
+ int32_t sample_bit_depth; /* sample bit depth */
+ /* decoded file bit depth (assuming output_bit_depth is
+ less or equal to sample_bit_depth) */
+ int32_t output_bit_depth;
+
+ int32_t MD5Enable;
+
+#if OUTPUT_INTERLACE_MERGED_PIC
+ int32_t output_interlace_merged_picture;
+#endif
+
+};
+
+/* extern struct inp_par *input; */
+
+struct outdata_s {
+#if RD170_FIX_BG
+ struct STDOUT_DATA_s stdoutdata[REF_MAXBUFFER];
+#else
+ struct STDOUT_DATA_s stdoutdata[8];
+#endif
+ int32_t buffer_num;
+};
+/* outdata outprint; */
+
+#define PAYLOAD_TYPE_IDERP 8
+
+struct Bitstream_s *AllocBitstream(void);
+void FreeBitstream(void);
+#if TRACE
+void tracebits2(const int8_t *trace_str, int32_t len, int32_t info);
+#endif
+
+/* int32_t direct_mv[45][80][4][4][3]; // only to verify result */
+
+#define I_PICTURE_START_CODE 0xB3
+#define PB_PICTURE_START_CODE 0xB6
+#define SLICE_START_CODE_MIN 0x00
+#define SLICE_START_CODE_MAX 0x8F
+#define USER_DATA_START_CODE 0xB2
+#define SEQUENCE_HEADER_CODE 0xB0
+#define EXTENSION_START_CODE 0xB5
+#define SEQUENCE_END_CODE 0xB1
+#define VIDEO_EDIT_CODE 0xB7
+
+#define SEQUENCE_DISPLAY_EXTENSION_ID 2
+#define COPYRIGHT_EXTENSION_ID 4
+#define CAMERAPARAMETERS_EXTENSION_ID 11
+#define PICTURE_DISPLAY_EXTENSION_ID 7
+#if M3480_TEMPORAL_SCALABLE
+#define TEMPORAL_SCALABLE_EXTENSION_ID 3
+#endif
+
+#if ROI_M3264
+#if RD1501_FIX_BG
+#define LOCATION_DATA_EXTENSION_ID 12
+#else
+#define LOCATION_DATA_EXTENSION_ID 15
+#endif
+#endif
+
+#if AVS2_HDR_HLS
+#define MASTERING_DISPLAY_AND_CONTENT_METADATA_EXTENSION 10
+#endif
+
+void malloc_slice(void);
+void free_slice(void);
+
+void read_ipred_modes(void);
+
+int32_t AEC_startcode_follows(int32_t eos_bit);
+
+/* extern uint32_t max_value_s; */
+
+/*ComAdaptiveLoopFilter.h*/
+#define ALF_MAX_NUM_COEF 9
+#define NO_VAR_BINS 16
+
+#define RPM_BEGIN 0x100
+#define ALF_BEGIN 0x180
+#define RPM_END 0x280
+#define RPM_VALID_END 0x236
+
+union param_u {
+ struct {
+ uint16_t data[RPM_END - RPM_BEGIN];
+ } l;
+ struct {
+ /*sequence*/
+ uint16_t profile_id;
+ uint16_t level_id;
+ uint16_t progressive_sequence;
+ uint16_t is_field_sequence;
+ uint16_t horizontal_size;
+ uint16_t vertical_size;
+ uint16_t chroma_format;
+ uint16_t sample_precision;
+ uint16_t encoding_precision;
+ uint16_t aspect_ratio_information;
+ uint16_t frame_rate_code;
+ uint16_t bit_rate_lower;
+ uint16_t bit_rate_upper;
+ uint16_t low_delay;
+ uint16_t temporal_id_exist_flag;
+ uint16_t g_uiMaxSizeInBit;
+
+#define BACKGROUND_PICTURE_DISABLE_BIT 11
+#define B_MHPSKIP_ENABLED_BIT 10
+#define DHP_ENABLED_BIT 9
+#define WSM_ENABLED_BIT 8
+#define INTER_AMP_ENABLE_BIT 7
+#define USENSQT_BIT 6
+#define USESDIP_BIT 5
+#define B_SECT_ENABLED_BIT 4
+#define SAO_ENABLE_BIT 3
+#define ALF_ENABLE_BIT 2
+#define B_PMVR_ENABLED_BIT 1
+#define CROSSSLICELOOPFILTER_BIT 0
+ uint16_t avs2_seq_flags;
+
+ uint16_t num_of_RPS;
+ uint16_t picture_reorder_delay;
+ /*PIC*/
+ uint16_t time_code_flag;
+ uint16_t time_code;
+ uint16_t background_picture_flag;
+ uint16_t background_picture_output_flag;
+ uint16_t coding_order;
+ uint16_t cur_layer;
+ uint16_t displaydelay; /*???*/
+ uint16_t predict; /*???*/
+ uint16_t RPS_idx; /*???*/
+ uint16_t referred_by_others_cur;
+ uint16_t num_of_ref_cur;
+ uint16_t ref_pic_cur[8];
+ uint16_t num_to_remove_cur;
+ uint16_t remove_pic_cur[8];
+ uint16_t progressive_frame;
+ uint16_t picture_structure;
+ uint16_t top_field_first;
+ uint16_t repeat_first_field;
+ uint16_t is_top_field;
+
+ uint16_t picture_coding_type;
+ uint16_t background_pred_flag;
+ uint16_t background_reference_enable;
+ uint16_t random_access_decodable_flag;
+ uint16_t lcu_size;
+ uint16_t alpha_c_offset;
+ uint16_t beta_offset;
+ uint16_t chroma_quant_param_delta_cb;
+ uint16_t chroma_quant_param_delta_cr;
+ uint16_t loop_filter_disable;
+
+ uint16_t video_signal_type;
+ uint16_t color_description;
+ uint16_t display_primaries_x[3];
+ uint16_t display_primaries_y[3];
+ uint16_t white_point_x;
+ uint16_t white_point_y;
+ uint16_t max_display_mastering_luminance;
+ uint16_t min_display_mastering_luminance;
+ uint16_t max_content_light_level;
+ uint16_t max_picture_average_light_level;
+ } p;
+ struct {
+ uint16_t padding[ALF_BEGIN - RPM_BEGIN];
+ uint16_t picture_alf_enable_Y;
+ uint16_t picture_alf_enable_Cb;
+ uint16_t picture_alf_enable_Cr;
+ uint16_t alf_filters_num_m_1;
+ uint16_t region_distance[16];
+ uint16_t alf_cb_coeffmulti[9];
+ uint16_t alf_cr_coeffmulti[9];
+ uint16_t alf_y_coeffmulti[16][9];
+ } alf;
+};
+
+struct buff_s {
+ u32 buf_start;
+ u32 buf_size;
+ u32 buf_end;
+};
+#ifdef NEW_FB_CODE
+#define MAX_FB_IFBUF_NUM 16
+
+typedef struct buff_s buff_t;
+typedef struct hevc_state_s hevc_stru_t;
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+//new dual
+typedef struct {
+ uint32_t mmu0_ptr;
+ uint32_t mmu1_ptr;
+ uint32_t scalelut_ptr;
+ uint32_t vcpu_imem_ptr;
+ uint32_t sys_imem_ptr;
+ uint32_t lmem0_ptr;
+ uint32_t lmem1_ptr;
+ uint32_t parser_sao0_ptr;
+ uint32_t parser_sao1_ptr;
+ uint32_t mpred_imp0_ptr;
+ uint32_t mpred_imp1_ptr;
+ //
+ uint32_t scalelut_ptr_pre;
+ uint8_t scalelut_ptr_changed;
+ //for linux
+ void *sys_imem_ptr_v;
+} buff_ptr_t;
+#endif
+
+struct avs2_decoder {
+ uint8_t init_hw_flag;
+ struct inp_par input;
+ struct ImageParameters_s img;
+ struct Video_Com_data_s hc;
+ struct Video_Dec_data_s hd;
+ union param_u param;
+ struct avs2_frame_s frm_pool[AVS2_MAX_BUFFER_NUM];
+ struct avs2_frame_s *fref[REF_MAXBUFFER];
+ struct avs2_frame_s *init_fref[REF_MAXBUFFER];
+#ifdef AML
+ /*used for background
+ when background_picture_output_flag is 0*/
+ struct avs2_frame_s *m_bg;
+ /*current background picture, ether m_bg or fref[..]*/
+ struct avs2_frame_s *f_bg;
+#endif
+ struct outdata_s outprint;
+ uint32_t cm_header_start;
+ struct ALFParam_s m_alfPictureParam[NUM_ALF_COMPONENT];
+#ifdef FIX_CHROMA_FIELD_MV_BK_DIST
+ int8_t bk_img_is_top_field;
+#endif
+#ifdef AML
+ int32_t lcu_size;
+ int32_t lcu_size_log2;
+ int32_t lcu_x_num;
+ int32_t lcu_y_num;
+ int32_t lcu_total;
+ int32_t ref_maxbuffer;
+ int32_t to_prepare_disp_count;
+ int8_t bufmgr_error_flag;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+ //avs2_frame_t *cur_pic;
+
+ uint8_t wait_working_buf;
+ uint8_t front_pause_flag; /*multi pictures in one packe*/
+ /*FB mgr*/
+ uint8_t fb_wr_pos;
+ uint8_t fb_rd_pos;
+ buff_t fb_buf_mmu0;
+ buff_t fb_buf_mmu1;
+ buff_t fb_buf_scalelut;
+ buff_t fb_buf_vcpu_imem;
+ buff_t fb_buf_sys_imem;
+ buff_t fb_buf_lmem0;
+ buff_t fb_buf_lmem1;
+ buff_t fb_buf_parser_sao0;
+ buff_t fb_buf_parser_sao1;
+ buff_t fb_buf_mpred_imp0;
+ buff_t fb_buf_mpred_imp1;
+ uint32_t frontend_decoded_count;
+ uint32_t backend_decoded_count;
+ buff_ptr_t fr;
+ buff_ptr_t bk;
+ buff_ptr_t next_bk[MAX_FB_IFBUF_NUM];
+ struct avs2_frame_s *next_be_decode_pic[MAX_FB_IFBUF_NUM];
+ /**/
+ /*for WRITE_BACK_RET*/
+ //uint32_t instruction[256];
+ uint32_t sys_imem_ptr;
+ void *sys_imem_ptr_v;
+ void *fb_buf_sys_imem_addr;
+ uint32_t instruction[256*4]; //avoid code crash, but only 256 used
+ uint32_t ins_offset;
+#endif
+#ifdef AML
+ u64 start_time;
+#endif
+};
+
+extern void write_frame(struct avs2_decoder *avs2_dec, int32_t pos);
+extern void init_frame_t(struct avs2_frame_s *currfref);
+extern void report_frame(struct avs2_decoder *avs2_dec,
+ struct outdata_s *data, int32_t pos);
+
+extern int avs2_post_process(struct avs2_decoder *avs2_dec);
+extern void avs2_prepare_header(struct avs2_decoder *avs2_dec,
+ int32_t start_code);
+extern int32_t avs2_process_header(struct avs2_decoder *avs2_dec);
+
+extern void init_avs2_decoder(struct avs2_decoder *avs2_dec);
+
+extern int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec);
+
+extern bool is_avs2_print_param(void);
+extern bool is_avs2_print_bufmgr_detail(void);
+extern int get_error_policy(struct avs2_decoder *avs2_dec);
+#endif
+
diff --git a/drivers/frame_provider/decoder/avs2_fb/vavs2.h b/drivers/frame_provider/decoder/avs2_fb/vavs2.h
new file mode 100644
index 0000000..6bba092
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/vavs2.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#ifndef VAVS2_H
+#define VAVS2_H
+
+#define AVS2_10B_MMU
+#define AVS2_10B_MMU_DW
+
+void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
+unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
+#endif
diff --git a/drivers/frame_provider/decoder/avs2_fb/vavs2_fb.c b/drivers/frame_provider/decoder/avs2_fb/vavs2_fb.c
new file mode 100644
index 0000000..e8aa769
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/vavs2_fb.c
@@ -0,0 +1,10311 @@
+/*
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/frame_sync/tsync.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+#include <linux/slab.h>
+#include <linux/sched/clock.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../include/regs/dos_registers.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+#include "../utils/config_parser.h"
+#include "../utils/firmware.h"
+#include "../utils/vdec_feature.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "avs2_global.h"
+#include "../../../common/media_utils/media_utils.h"
+#include "../../decoder/utils/vdec_profile.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+#define MEM_NAME "codec_avs2"
+
+#define FOR_S5
+
+#define I_ONLY_SUPPORT
+#define MIX_STREAM_SUPPORT
+#define CONSTRAIN_MAX_BUF_NUM
+//#ifdef S5
+#define DYN_CACHE //!!!enable it on S5
+//#endif
+#define CO_MV_COMPRESS
+
+#include "vavs2.h"
+#define HEVC_SHIFT_LENGTH_PROTECT 0x313a
+#define HEVC_MPRED_CTRL4 0x324c
+//#define HEVC_MPRED_CTRL9 0x325b
+#define HEVC_DBLK_CFGD 0x350d
+#define HEVC_CM_HEADER_START_ADDR 0x3628
+#define HEVC_DBLK_CFGB 0x350b
+#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
+#define HEVC_SAO_MMU_VH1_ADDR 0x363b
+#define HEVC_SAO_MMU_VH0_ADDR 0x363a
+
+#define HEVC_CM_BODY_LENGTH2 0x3663
+#define HEVC_CM_HEADER_OFFSET2 0x3664
+#define HEVC_CM_HEADER_LENGTH2 0x3665
+
+#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
+
+#define HEVC_CM_HEADER_START_ADDR 0x3628
+#define HEVC_CM_HEADER_START_ADDR2 0x364a
+#define HEVC_SAO_MMU_VH1_ADDR 0x363b
+#define HEVC_SAO_MMU_VH0_ADDR 0x363a
+#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
+#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
+
+#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
+#define HEVC_SAO_MMU_STATUS2 0x3650
+#define HEVC_DW_VH0_ADDDR 0x365e
+#define HEVC_DW_VH1_ADDDR 0x365f
+
+#define HEVC_SAO_CTRL9 0x362d
+
+/*
+ * AVS2_DEC_STATUS define
+*/
+/*internal*/
+#define AVS2_DEC_IDLE 0
+#define AVS2_SEQUENCE 1
+#define AVS2_I_PICTURE 2
+#define AVS2_PB_PICTURE 3
+#define AVS2_DISCARD_STARTCODE 4
+#define AVS2_DISCARD_NAL 4
+
+#define AVS2_SLICE_DECODING 6
+
+#define SWAP_IN_CMD 0x10
+#define SWAP_OUT_CMD 0x11
+#define SWAP_OUTIN_CMD 0x12
+#define SWAP_DONE 0x13
+#define SWAP_POST_INIT 0x14
+
+/*head*/
+#define AVS2_HEAD_SEQ_READY 0x21
+#define AVS2_HEAD_PIC_I_READY 0x22
+#define AVS2_HEAD_PIC_PB_READY 0x23
+#define AVS2_HEAD_SEQ_END_READY 0x24
+#define AVS2_STARTCODE_SEARCH_DONE 0x25
+
+/*pic done*/
+#define HEVC_DECPIC_DATA_DONE 0x30
+#define HEVC_DECPIC_DATA_ERROR 0x31
+#define HEVC_NAL_DECODE_DONE 0x32
+#define AVS2_DECODE_BUFEMPTY 0x33
+#define AVS2_DECODE_TIMEOUT 0x34
+#define AVS2_DECODE_OVER_SIZE 0x35
+#define AVS2_EOS 0x36
+
+/*cmd*/
+#define AVS2_10B_DISCARD_NAL 0xf0
+#define AVS2_SEARCH_NEW_PIC 0xf1
+#define AVS2_ACTION_ERROR 0xfe
+#define HEVC_ACTION_ERROR 0xfe
+#define AVS2_ACTION_DONE 0xff
+/*AVS2_DEC_STATUS end*/
+
+//???
+#define HEVC_BE_DECODE_DATA 0xa0
+#define HEVC_BE_DECODE_DATA_DONE 0xb0
+#define HEVC_BE_DECODE_TIMEOUT 0xc0
+
+#define VF_POOL_SIZE 32
+
+#undef pr_info
+#define pr_info pr_cont
+
+#define DECODE_MODE_SINGLE (0 | (0x80 << 24))
+#define DECODE_MODE_MULTI_STREAMBASE (1 | (0x80 << 24))
+#define DECODE_MODE_MULTI_FRAMEBASE (2 | (0x80 << 24))
+
+#define VP9_TRIGGER_FRAME_DONE 0x100
+#define VP9_TRIGGER_FRAME_ENABLE 0x200
+
+#define MV_MEM_UNIT 0x200
+/*---------------------------------------------------
+ Include "parser_cmd.h"
+---------------------------------------------------*/
+#define PARSER_CMD_SKIP_CFG_0 0x0000090b
+
+#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
+
+#define PARSER_CMD_SKIP_CFG_2 0x001b1910
+
+#define PARSER_CMD_NUMBER 37
+#if 0
+static unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
+ 0x0401,
+ 0x8401,
+ 0x0800,
+ 0x0402,
+ 0x9002,
+ 0x1423,
+ 0x8CC3,
+ 0x1423,
+ 0x8804,
+ 0x9825,
+ 0x0800,
+ 0x04FE,
+ 0x8406,
+ 0x8411,
+ 0x1800,
+ 0x8408,
+ 0x8409,
+ 0x8C2A,
+ 0x9C2B,
+ 0x1C00,
+ 0x840F,
+ 0x8407,
+ 0x8000,
+ 0x8408,
+ 0x2000,
+ 0xA800,
+ 0x8410,
+ 0x04DE,
+ 0x840C,
+ 0x840D,
+ 0xAC00,
+ 0xA000,
+ 0x08C0,
+ 0x08E0,
+ 0xA40E,
+ 0xFC00,
+ 0x7C00
+};
+#endif
+
+static int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+};
+
+static int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+};
+/* to remove, fix build error */
+
+#define MULTI_INSTANCE_SUPPORT
+
+#ifndef STAT_KTHREAD
+#define STAT_KTHREAD 0x40
+#endif
+
+#ifdef MULTI_INSTANCE_SUPPORT
+#define MAX_DECODE_INSTANCE_NUM 12
+#define MULTI_DRIVER_NAME "ammvdec_avs2_fb"
+
+#define lock_buffer(dec, flags) \
+ spin_lock_irqsave(&dec->buffer_lock, flags)
+
+#define unlock_buffer(dec, flags) \
+ spin_unlock_irqrestore(&dec->buffer_lock, flags)
+
+static u32 debug_mask = 0xffffffff;
+#define get_dbg_flag(dec) ((debug_mask & (1 << dec->index)) ? debug : 0)
+
+static unsigned int max_decode_instance_num
+ = MAX_DECODE_INSTANCE_NUM;
+static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
+static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
+static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
+#ifdef NEW_FB_CODE
+static unsigned int max_process_time_back[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count_back[MAX_DECODE_INSTANCE_NUM];
+#endif
+static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
+static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
+
+static u32 decode_timeout_val = 200;
+#endif
+static int start_decode_buf_level = 0x8000;
+
+static u32 work_buf_size;
+
+static u32 mv_buf_margin;
+static int pre_decode_buf_level = 0x1000;
+static u32 again_threshold;
+
+/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
+/* double_write_mode:
+ * 0, no double write;
+ * 1, 1:1 ratio;
+ * 2, (1/4):(1/4) ratio;
+ * 3, (1/4):(1/4) ratio, with both compressed frame included
+ * 4, (1/2):(1/2) ratio;
+ * 8, (1/8):(1/8) ratio;
+ * 0x10, double write only
+ * 0x100, if > 1080p,use mode 4,else use mode 1;
+ * 0x200, if > 1080p,use mode 2,else use mode 1;
+ * 0x300, if > 720p, use mode 4, else use mode 1;
+ * 0x10000, double write p010 enable
+ */
+static u32 double_write_mode = 0x80000003;
+
+/* triple_write_mode:
+ * 0, no triple write;
+ * 1, 1:1 ratio;
+ * 2, (1/4):(1/4) ratio;
+ * 3, (1/4):(1/4) ratio, with both compressed frame included
+ * 4, (1/2):(1/2) ratio;
+ * 5, (1/2):(1/2) ratio, with both compressed frame included
+ * 8, (1/8):(1/8) ratio
+ * 0x10000, triple write p010 enable
+ */
+static u32 triple_write_mode;
+
+static u32 without_display_mode;
+static u32 dump_yuv_frame = 0;
+static u32 paral_alloc_buffer_mode = 1;
+
+/*
+bit0: if dpb abnormal, check dpb buffer status and flush dpb.
+bit1: 0:show error frame.
+*/
+static unsigned int error_proc_policy = 0x3;
+
+static u32 mv_buf_dynamic_alloc;
+
+#define DRIVER_NAME "amvdec_avs2_fb"
+#define DRIVER_HEADER_NAME "amvdec_avs2_header_fb"
+
+#define PUT_INTERVAL (HZ/100)
+#define ERROR_SYSTEM_RESET_COUNT 200
+
+#define PTS_NORMAL 0
+#define PTS_NONE_REF_USE_DURATION 1
+
+#define PTS_MODE_SWITCHING_THRESHOLD 3
+#define PTS_MODE_SWITCHING_RECOVERY_THRESHOLD 3
+
+#define DUR2PTS(x) ((x)*90/96)
+
+struct AVS2Decoder_s;
+static int vavs2_vf_states(struct vframe_states *states, void *);
+static struct vframe_s *vavs2_vf_peek(void *);
+static struct vframe_s *vavs2_vf_get(void *);
+static void vavs2_vf_put(struct vframe_s *, void *);
+static int vavs2_event_cb(int type, void *data, void *private_data);
+static void set_vframe(struct AVS2Decoder_s *dec,
+ struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy);
+static void fill_frame_info(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic, unsigned int framesize, unsigned int pts);
+static int vavs2_stop(struct AVS2Decoder_s *dec);
+static s32 vavs2_init(struct vdec_s *vdec);
+static void vavs2_prot_init(struct AVS2Decoder_s *dec);
+static int vavs2_local_init(struct AVS2Decoder_s *dec);
+static void vavs2_put_timer_func(struct timer_list *timer);
+static void dump_data(struct AVS2Decoder_s *dec, int size);
+static unsigned char get_data_check_sum
+ (struct AVS2Decoder_s *dec, int size);
+static void dump_pic_list(struct AVS2Decoder_s *dec);
+static struct avs2_frame_s *get_pic_by_index(
+ struct AVS2Decoder_s *dec, int index);
+static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec);
+static void avs2_work_implement(struct AVS2Decoder_s *dec);
+
+#ifdef NEW_FB_CODE
+static unsigned int decode_timeout_val_back = 200;
+static unsigned int efficiency_mode = 1;
+static unsigned int back_timer_check_count = 3;
+
+static void avs2_work_back(struct work_struct *work);
+static void avs2_work_back_implement(struct AVS2Decoder_s *dec,
+ struct vdec_s *vdec,int from);
+static void avs2_timeout_work_back(struct work_struct *work);
+#endif
+
+static const char vavs2_dec_id[] = "vavs2-dev";
+
+#define PROVIDER_NAME "decoder.avs2"
+#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs2"
+
+static const struct vframe_operations_s vavs2_vf_provider = {
+ .peek = vavs2_vf_peek,
+ .get = vavs2_vf_get,
+ .put = vavs2_vf_put,
+ .event_cb = vavs2_event_cb,
+ .vf_states = vavs2_vf_states,
+};
+
+static struct vframe_provider_s vavs2_vf_prov;
+
+static u32 bit_depth_luma;
+static u32 bit_depth_chroma;
+static u32 frame_width;
+static u32 frame_height;
+static u32 video_signal_type;
+static u32 pts_unstable;
+static u32 on_no_keyframe_skiped;
+
+static u32 force_video_signal_type;
+static u32 enable_force_video_signal_type;
+#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
+#define HDR_CUVA_MASK 0x40000000
+
+static const char * const video_format_names[] = {
+ "component", "PAL", "NTSC", "SECAM",
+ "MAC", "unspecified", "Reserved", "Reserved"
+};
+
+static inline int div_r32(int64_t m, int n)
+{
+#ifndef CONFIG_ARM64
+ int64_t qu = 0;
+ qu = div_s64(m, n);
+ return (int)qu;
+#else
+ return (int)(m/n);
+#endif
+}
+
+enum vpx_bit_depth_t {
+ AVS2_BITS_8 = 8, /**< 8 bits */
+ AVS2_BITS_10 = 10, /**< 10 bits */
+ AVS2_BITS_12 = 12, /**< 12 bits */
+};
+
+enum alloc_buffer_status_t {
+ BUFFER_INIT = 0,
+ BUFFER_ALLOCATING = 1,
+ BUFFER_ALLOCATE_DONE = 2,
+};
+
+/*USE_BUF_BLOCK*/
+struct BUF_s {
+ int index;
+ unsigned int alloc_flag;
+ /*buffer */
+ unsigned int cma_page_count;
+ unsigned long alloc_addr;
+ unsigned long start_adr;
+ unsigned int size;
+
+ unsigned int free_start_adr;
+} /*BUF_t */;
+
+struct MVBUF_s {
+ unsigned long start_adr;
+ unsigned int size;
+ int used_flag;
+} /*MVBUF_t */;
+
+#define WR_PTR_INC_NUM 128
+
+#define SIMULATION
+#define DOS_PROJECT
+#undef MEMORY_MAP_IN_REAL_CHIP
+
+#ifdef AVS2_10B_NV21
+#define MEM_MAP_MODE 2 /* 0:linear 1:32x32 2:64x32*/
+#else
+#define MEM_MAP_MODE 0 /* 0:linear 1:32x32 2:64x32*/
+#endif
+
+#ifdef AVS2_10B_NV21
+#else
+#define LOSLESS_COMPRESS_MODE
+#endif
+
+#define AVS2_DBG_BUFMGR 0x01
+#define AVS2_DBG_BUFMGR_MORE 0x02
+#define AVS2_DBG_BUFMGR_DETAIL 0x04
+#define AVS2_DBG_IRQ_EVENT 0x08
+#define AVS2_DBG_OUT_PTS 0x10
+#define AVS2_DBG_PRINT_SOURCE_LINE 0x20
+#define AVS2_DBG_PRINT_PARAM 0x40
+#define AVS2_DBG_PRINT_PIC_LIST 0x80
+#define AVS2_DBG_SEND_PARAM_WITH_REG 0x100
+#define AVS2_DBG_MERGE 0x200
+#define AVS2_DBG_DBG_LF_PRINT 0x400
+#define AVS2_DBG_REG 0x800
+#define AVS2_DBG_PIC_LEAK 0x1000
+#define AVS2_DBG_PIC_LEAK_WAIT 0x2000
+#define AVS2_DBG_HDR_INFO 0x4000
+#define AVS2_DBG_QOS_INFO 0x8000
+#define AVS2_DBG_DIS_LOC_ERROR_PROC 0x10000
+#define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000
+#define AVS2_DBG_DUMP_PIC_LIST 0x40000
+#define AVS2_DBG_TRIG_SLICE_SEGMENT_PROC 0x80000
+#define AVS2_DBG_FORCE_UNCOMPRESS 0x100000
+#define AVS2_DBG_BE_SIMULATE_IRQ 0x200000
+#define AVS2_DBG_FORCE_SEND_AGAIN 0x400000
+#define AVS2_DBG_DUMP_DATA 0x800000
+#define AVS2_DBG_DUMP_LMEM_BUF 0x1000000
+#define AVS2_DBG_DUMP_RPM_BUF 0x2000000
+#define AVS2_DBG_CACHE 0x4000000
+#define IGNORE_PARAM_FROM_CONFIG 0x8000000
+/*MULTI_INSTANCE_SUPPORT*/
+#define PRINT_FLAG_ERROR 0
+#define PRINT_FLAG_VDEC_STATUS 0x20000000
+#define PRINT_FLAG_VDEC_DETAIL 0x40000000
+#define PRINT_FLAG_VDEC_DATA 0x80000000
+
+#define PRINT_LINE() \
+ do { \
+ if (debug & AVS2_DBG_PRINT_SOURCE_LINE)\
+ pr_info("%s line %d\n", __func__, __LINE__);\
+ } while (0)
+
+static u32 fbdebug_flag;
+
+static u32 debug;
+
+static u32 debug_again;
+
+bool is_avs2_print_param(void)
+{
+ bool ret = false;
+ if (debug & AVS2_DBG_PRINT_PARAM)
+ ret = true;
+ return ret;
+}
+
+inline bool is_avs2_print_bufmgr_detail(void)
+{
+ bool ret = false;
+ if (debug & AVS2_DBG_BUFMGR_DETAIL)
+ ret = true;
+ return ret;
+}
+static bool is_reset;
+/*for debug*/
+static u32 force_bufspec;
+/*
+ udebug_flag:
+ bit 0, enable ucode print
+ bit 1, enable ucode detail print
+ bit [31:16] not 0, pos to dump lmem
+ bit 2, pop bits to lmem
+ bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
+*/
+static u32 udebug_flag;
+/*
+ when udebug_flag[1:0] is not 0
+ udebug_pause_pos not 0,
+ pause position
+*/
+static u32 udebug_pause_pos;
+/*
+ when udebug_flag[1:0] is not 0
+ and udebug_pause_pos is not 0,
+ pause only when DEBUG_REG2 is equal to this val
+*/
+static u32 udebug_pause_val;
+
+static u32 udebug_pause_decode_idx;
+
+static u32 force_disp_pic_index;
+
+#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
+static u32 cuva_buf_size = 512;
+
+#define DEBUG_REG
+#ifdef DEBUG_REG
+static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
+{
+ if (adr != 0)
+ WRITE_VREG(adr, val);
+
+ if (debug & AVS2_DBG_REG) {
+ adr = dos_reg_compat_convert(adr);
+ pr_info("%s(%x, %x)\n", __func__, adr, val);
+ }
+}
+
+#undef WRITE_VREG
+#define WRITE_VREG WRITE_VREG_DBG2
+#endif
+
+#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
+#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
+#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
+
+#define INVALID_IDX -1 /* Invalid buffer index.*/
+
+#define FRAME_BUFFERS (AVS2_MAX_BUFFER_NUM)
+#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
+#define MAX_BUF_NUM (FRAME_BUFFERS)
+
+#define FRAME_CONTEXTS_LOG2 2
+#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
+/*buffer + header buffer + workspace*/
+
+#ifdef NEW_FB_CODE
+#define BMMU_IFBUF_SCALELUT_ID (0)
+#define BMMU_IFBUF_VCPU_IMEM_ID (BMMU_IFBUF_SCALELUT_ID + 1)
+#define BMMU_IFBUF_SYS_IMEM_ID (BMMU_IFBUF_VCPU_IMEM_ID + 1)
+#define BMMU_IFBUF_LMEM0_ID (BMMU_IFBUF_SYS_IMEM_ID + 1)
+#define BMMU_IFBUF_LMEM1_ID (BMMU_IFBUF_LMEM0_ID + 1)
+#define BMMU_IFBUF_PARSER_SAO0_ID (BMMU_IFBUF_LMEM1_ID + 1)
+#define BMMU_IFBUF_PARSER_SAO1_ID (BMMU_IFBUF_PARSER_SAO0_ID + 1)
+#define BMMU_IFBUFF_MPRED_IMP0_ID (BMMU_IFBUF_PARSER_SAO1_ID + 1)
+#define BMMU_IFBUFF_MPRED_IMP1_ID (BMMU_IFBUFF_MPRED_IMP0_ID + 1)
+#define FB_LOOP_BUF_COUNT (BMMU_IFBUFF_MPRED_IMP1_ID + 1)
+#else
+#define FB_LOOP_BUF_COUNT 0
+#endif
+
+#define MV_USE_FIXED_BUF
+#ifdef MV_USE_FIXED_BUF
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1)
+#else
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + ((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define MV_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
+//#define DW_HEADER_BUFFER_IDX(n) ((FRAME_BUFFERS * 3) + n+1)
+#endif
+
+#define CO_MV_BUF_SIZE_1080P 0x3fc00
+#define CO_MV_BUF_SIZE_4K 0x120000
+#define CO_MV_BUF_SIZE_8K 0x480000
+
+#ifdef NEW_FB_CODE
+static u32 fb_ifbuf_num = 3;
+/*
+ 0: single core mode
+ 1: front_back_mode
+ 2: front_back_test_mode
+*/
+static u32 front_back_mode = 1;
+#endif
+
+struct BuffInfo_s {
+ u32 max_width;
+ u32 max_height;
+ u32 start_adr;
+ u32 end_adr;
+ struct buff_s ipp;
+#ifdef NEW_FRONT_BACK_CODE
+ struct buff_s ipp1;
+#endif
+ struct buff_s sao_abv;
+ struct buff_s sao_vb;
+ struct buff_s short_term_rps;
+ struct buff_s rcs;
+ struct buff_s sps;
+ struct buff_s pps;
+ struct buff_s sao_up;
+ struct buff_s swap_buf;
+ struct buff_s swap_buf2;
+ struct buff_s scalelut;
+ struct buff_s dblk_para;
+ struct buff_s dblk_data;
+ struct buff_s dblk_data2;
+#ifdef AVS2_10B_MMU
+ struct buff_s mmu_vbh;
+ struct buff_s cm_header;
+#endif
+#ifdef AVS2_10B_MMU_DW
+ struct buff_s mmu_vbh_dw;
+ struct buff_s cm_header_dw;
+#endif
+ struct buff_s mpred_above;
+#ifdef MV_USE_FIXED_BUF
+ struct buff_s mpred_mv;
+#endif
+ struct buff_s rpm;
+ struct buff_s lmem;
+};
+
+#define DEC_RESULT_NONE 0
+#define DEC_RESULT_DONE 1
+#define DEC_RESULT_AGAIN 2
+#define DEC_RESULT_CONFIG_PARAM 3
+#define DEC_RESULT_ERROR 4
+#define DEC_INIT_PICLIST 5
+#define DEC_UNINIT_PICLIST 6
+#define DEC_RESULT_GET_DATA 7
+#define DEC_RESULT_GET_DATA_RETRY 8
+#define DEC_RESULT_EOS 9
+#define DEC_RESULT_FORCE_EXIT 10
+#define DEC_RESULT_WAIT_BUFFER 11
+
+#ifdef NEW_FB_CODE
+#define DEC_BACK_RESULT_NONE 0
+#define DEC_BACK_RESULT_DONE 1
+#define DEC_BACK_RESULT_TIMEOUT 2
+#define DEC_BACK_RESULT_FORCE_EXIT 10
+#endif
+
+#define PROC_STATE_INIT 0
+#define PROC_STATE_HEAD_DONE 1
+#define PROC_STATE_DECODING 2
+#define PROC_STATE_HEAD_AGAIN 3
+#define PROC_STATE_DECODE_AGAIN 4
+#define PROC_STATE_TEST1 5
+
+static void avs2_work(struct work_struct *work);
+struct loop_filter_info_n;
+struct loopfilter;
+struct segmentation;
+
+struct AVS2Decoder_s {
+ int pic_list_init_flag;
+ int pic_list_wait_alloc_done_flag;
+ unsigned char index;
+ spinlock_t buffer_lock;
+ struct device *cma_dev;
+ struct platform_device *platform_dev;
+ void (*vdec_cb)(struct vdec_s *, void *, int);
+ void *vdec_cb_arg;
+ struct vframe_chunk_s *chunk;
+ int dec_result;
+ struct work_struct work;
+ u32 start_shift_bytes;
+
+ struct BuffInfo_s work_space_buf_store;
+ unsigned long buf_start;
+ u32 buf_size;
+ u32 cma_alloc_count;
+ unsigned long cma_alloc_addr;
+ uint8_t eos;
+ unsigned long int start_process_time;
+ unsigned last_lcu_idx;
+ int decode_timeout_count;
+ unsigned timeout_num;
+
+ int double_write_mode;
+
+ unsigned char m_ins_flag;
+ char *provider_name;
+ int frame_count;
+ u32 stat;
+ struct timer_list timer;
+ u32 frame_dur;
+ u32 frame_ar;
+ u32 vavs2_ratio;
+ int fatal_error;
+ uint8_t init_flag;
+ uint8_t first_sc_checked;
+ uint8_t process_busy;
+ uint8_t process_state;
+ u32 ucode_pause_pos;
+
+ int show_frame_num;
+#ifndef AVS2_10B_MMU
+ struct buff_s mc_buf_spec;
+#endif
+ struct dec_sysinfo vavs2_amstream_dec_info;
+ void *rpm_addr;
+ void *lmem_addr;
+ dma_addr_t rpm_phy_addr;
+ dma_addr_t lmem_phy_addr;
+ unsigned short *lmem_ptr;
+ unsigned short *debug_ptr;
+
+#ifdef AVS2_10B_MMU
+ bool mmu_enable;
+
+ u32 cuva_size;
+ void *cuva_addr;
+ dma_addr_t cuva_phy_addr;
+
+ void *frame_mmu_map_addr;
+ dma_addr_t frame_mmu_map_phy_addr;
+#endif
+#ifdef AVS2_10B_MMU_DW
+ bool dw_mmu_enable;
+ void *dw_mmu_box;
+ void *dw_frame_mmu_map_addr;
+ dma_addr_t dw_frame_mmu_map_phy_addr;
+#endif
+ unsigned int use_cma_flag;
+
+ struct BUF_s m_BUF[MAX_BUF_NUM];
+ struct MVBUF_s m_mv_BUF[MAX_BUF_NUM];
+ u32 used_buf_num;
+ DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
+ struct vframe_s vfpool[VF_POOL_SIZE];
+ u32 vf_pre_count;
+ u32 vf_get_count;
+ u32 vf_put_count;
+ int buf_num;
+ unsigned int losless_comp_body_size;
+
+ u32 video_signal_type;
+ u32 video_ori_signal_type;
+
+ int pts_mode;
+ int last_lookup_pts;
+ int last_pts;
+ u64 last_lookup_pts_us64;
+ u64 last_pts_us64;
+ u64 shift_byte_count;
+ u32 shift_byte_count_lo;
+ u32 shift_byte_count_hi;
+ int pts_mode_switching_count;
+ int pts_mode_recovery_count;
+
+ bool get_frame_dur;
+ u32 saved_resolution;
+
+ /**/
+ int refresh_frame_flags;
+ uint8_t hold_ref_buf;
+ struct BuffInfo_s *work_space_buf;
+#ifndef AVS2_10B_MMU
+ struct buff_s *mc_buf;
+#endif
+ unsigned int frame_width;
+ unsigned int frame_height;
+
+ unsigned short *rpm_ptr;
+ int init_pic_w;
+ int init_pic_h;
+
+ int slice_type;
+
+ int decode_idx;
+ int slice_idx;
+ uint8_t wait_buf;
+ uint8_t error_flag;
+ unsigned int bufmgr_error_count;
+
+ /* bit 0, for decoding; bit 1, for displaying */
+ uint8_t ignore_bufmgr_error;
+ uint8_t skip_PB_before_I;
+ int PB_skip_mode;
+ int PB_skip_count_after_decoding;
+
+ struct vdec_info *gvs;
+
+ unsigned int dec_status;
+ u32 last_put_idx;
+ int new_frame_displayed;
+ void *mmu_box;
+ void *bmmu_box;
+ struct vframe_master_display_colour_s vf_dp;
+ struct firmware_s *fw;
+#ifdef AVS2_10B_MMU
+ int cur_fb_idx_mmu;
+ long used_4k_num;
+#endif
+ struct avs2_decoder avs2_dec;
+#define ALF_NUM_BIT_SHIFT 6
+#define NO_VAR_BINS 16
+ int32_t m_filterCoeffSym[16][9];
+ int32_t m_varIndTab[NO_VAR_BINS];
+
+ struct vframe_s vframe_dummy;
+ /* start_decoding_flag,
+ bit 0, SEQ ready
+ bit 1, I ready
+ */
+ unsigned char start_decoding_flag;
+ uint32_t mpred_abv_start_addr;
+ uint32_t mpred_abv_start_addr_bak;
+ u8 next_again_flag;
+ u32 pre_parser_wr_ptr;
+ int need_cache_size;
+ u64 sc_start_time;
+#ifdef I_ONLY_SUPPORT
+ u32 i_only;
+#endif
+ int frameinfo_enable;
+ struct vframe_qos_s vframe_qos;
+ u32 dynamic_buf_margin;
+ int sidebind_type;
+ int sidebind_channel_id;
+ u32 endian;
+ dma_addr_t rdma_phy_adr;
+ unsigned *rdma_adr;
+ int hdr_flag;
+ bool high_bandwidth_flag;
+ ulong rpm_mem_handle;
+ ulong lmem_phy_handle;
+ ulong frame_mmu_map_handle;
+ ulong frame_dw_mmu_map_handle;
+ ulong rdma_mem_handle;
+ ulong cuva_handle;
+#ifdef NEW_FB_CODE
+ u32 front_back_mode;
+ int fb_ifbuf_num;
+ //int pic_wr_count;
+ //int pic_rd_count;
+ //struct PIC_s *decoded_PIC[MAX_REF_PIC_NUM];
+ //u32 flush_count;
+
+ /*init_fb_bufstate() for linux APIs*/
+ struct work_struct work_back;
+ struct work_struct timeout_work_back;
+
+ void *frame_mmu_map_addr_1;
+ dma_addr_t frame_mmu_map_phy_addr_1;
+ void *mmu_box_1;
+
+ void *dw_mmu_box_1;
+ void *dw_frame_mmu_map_addr_1;
+ dma_addr_t dw_frame_mmu_map_phy_addr_1;
+
+ void *mmu_box_fb;
+ void *fb_buf_mmu0_addr;
+ void *fb_buf_mmu1_addr;
+ /**/
+ void (*vdec_back_cb)(struct vdec_s *, void *, int);
+ void *vdec_back_cb_arg;
+ struct firmware_s *fw_back;
+ struct timer_list timer_back;
+ unsigned long int start_process_time_back;
+ unsigned int decode_timeout_count_back;
+ unsigned int timeout_num_back;
+
+ int dec_back_result;
+ u32 dec_status_back;
+ struct mutex fb_mutex;
+ int mmu_fb_4k_number;
+ ulong frame_mmu_map_handle_1;
+ ulong frame_dw_mmu_map_handle_1;
+#endif
+ uint32_t ASSIST_MBOX0_IRQ_REG;
+ uint32_t ASSIST_MBOX0_CLR_REG;
+ uint32_t ASSIST_MBOX0_MASK;
+ uint32_t backend_ASSIST_MBOX0_IRQ_REG;
+ uint32_t backend_ASSIST_MBOX0_CLR_REG;
+ uint32_t backend_ASSIST_MBOX0_MASK;
+
+ unsigned char print_buf[1024*16+16];
+ int print_buf_len;
+ struct trace_decoder_name trace;
+ u32 last_stbuf_level;
+ u32 again_count;
+ u32 error_proc_policy;
+#ifdef OW_TRIPLE_WRITE
+ int triple_write_mode;
+#endif
+ struct mutex slice_header_lock;
+ u32 last_monitor_data;
+ u32 back_timer_check_count;
+};
+
+static int compute_losless_comp_body_size(
+ struct AVS2Decoder_s *dec, int width, int height,
+ uint8_t is_bit_depth_10);
+
+static int avs2_mmu_page_num(struct AVS2Decoder_s *dec,
+ int w, int h, int bit_depth_10);
+
+static int avs2_debug(struct AVS2Decoder_s *dec,
+ int flag, const char *fmt, ...)
+{
+#define HEVC_PRINT_BUF 512
+ unsigned char buf[HEVC_PRINT_BUF];
+ int len = 0;
+ if (dec && dec->print_buf_len>0) {
+ dec->print_buf_len = 0;
+ pr_info("%s", dec->print_buf);
+ }
+ if (dec == NULL ||
+ (flag == 0) ||
+ (debug & flag)) {
+ va_list args;
+ va_start(args, fmt);
+ if (dec)
+ len = sprintf(buf, "[%d]", dec->index);
+ vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+ pr_info("%s", buf);
+ va_end(args);
+ }
+ return 0;
+}
+
+#define avs2_print(dec, flag, fmt, args...) \
+ do { \
+ if (dec == NULL || \
+ (flag == 0) || \
+ ((debug_mask & \
+ (1 << dec->index)) \
+ && (debug & flag))) { \
+ avs2_debug(dec, flag, fmt, ##args); \
+ } \
+ } while (0)
+
+static void avs2_print_flush(struct AVS2Decoder_s *dec)
+{
+ if (dec->print_buf_len>0) {
+ dec->print_buf_len = 0;
+ pr_info("%s", dec->print_buf);
+ }
+}
+
+static int avs2_print_cont(struct AVS2Decoder_s *dec,
+ int flag, const char *fmt, ...)
+{
+ //unsigned char buf[HEVC_PRINT_BUF];
+ //int len = 0;
+ if (dec == NULL ||
+ (flag == 0) ||
+ ((debug_mask &
+ (1 << dec->index))
+ && (debug & flag))) {
+ va_list args;
+
+ va_start(args, fmt);
+#if 0
+ vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+ pr_info("%s", buf);
+#else
+ if (dec->print_buf_len<1024*16)
+ dec->print_buf_len += vsnprintf(dec->print_buf+dec->print_buf_len,
+ 1024*16-dec->print_buf_len, fmt, args);
+ else
+ pr_info("print_buf is full\n");
+#endif
+ va_end(args);
+ }
+ return 0;
+}
+
+#define PROB_SIZE (496 * 2 * 4)
+#define PROB_BUF_SIZE (0x5000)
+#define COUNT_BUF_SIZE (0x300 * 4 * 4)
+#define MAX_FRAME_4K_NUM 0x1200
+#define MAX_FRAME_8K_NUM 0x4800
+#define MAX_SIZE_4K (4096 * 2304)
+#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
+#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
+
+static int get_frame_mmu_map_size(void)
+{
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ return (MAX_FRAME_8K_NUM * 4);
+
+ return (MAX_FRAME_4K_NUM * 4);
+}
+
+static int get_compress_header_size(struct AVS2Decoder_s *dec)
+{
+ int w = ALIGN(dec->init_pic_w, 64);
+ int h = ALIGN(dec->init_pic_h, 64);
+
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ (IS_8K_SIZE(w, h)))
+ return MMU_COMPRESS_HEADER_SIZE_8K;
+ else if (IS_4K_SIZE(w, h))
+ return MMU_COMPRESS_HEADER_SIZE_4K;
+ return MMU_COMPRESS_HEADER_SIZE_1080P;
+}
+
+static void reset_process_time(struct AVS2Decoder_s *dec)
+{
+ if (dec->start_process_time) {
+// unsigned process_time =
+// 1000 * (jiffies - dec->start_process_time) / HZ;
+ dec->start_process_time = 0;
+// if (process_time > max_process_time[dec->index])
+// max_process_time[dec->index] = process_time;
+ }
+}
+
+static void start_process_time(struct AVS2Decoder_s *dec)
+{
+ dec->start_process_time = jiffies;
+ dec->decode_timeout_count = 0;
+ dec->last_lcu_idx = 0;
+}
+
+static void update_decoded_pic(struct AVS2Decoder_s *dec);
+
+static void timeout_process(struct AVS2Decoder_s *dec)
+{
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+ dec->timeout_num++;
+ avs2_print(dec, 0, "%s decoder timeout\n", __func__);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ amhevc_stop_f();
+ } else
+#endif
+ amhevc_stop();
+
+ if (pic && (pic->error_mark == 0) &&
+ (pic->decoded_lcu == 0)) {
+ update_decoded_pic(dec);
+ pic->error_mark = 1;
+ }
+
+ dec->dec_result = DEC_RESULT_DONE;
+ reset_process_time(dec);
+ vdec_schedule_work(&dec->work);
+}
+
+#ifdef NEW_FB_CODE
+static void reset_process_time_back(struct AVS2Decoder_s *dec)
+{
+ if (dec->start_process_time_back) {
+ unsigned int process_time =
+ 1000 * (jiffies - dec->start_process_time_back) / HZ;
+ dec->start_process_time_back = 0;
+ if (process_time > max_process_time_back[dec->index])
+ max_process_time_back[dec->index] = process_time;
+ }
+}
+
+static void start_process_time_back(struct AVS2Decoder_s *dec)
+{
+ dec->start_process_time_back = jiffies;
+ dec->decode_timeout_count_back = 2;
+ dec->back_timer_check_count = back_timer_check_count;
+}
+
+/*
+static void restart_process_time_back(struct AVS2Decoder_s *dec)
+{
+ dec->start_process_time_back = jiffies;
+ dec->decode_timeout_count_back = 2;
+}
+*/
+static void timeout_process_back(struct AVS2Decoder_s *dec)
+{
+ /*
+ * In this very timeout point,the vh265_work arrives,
+ * or in some cases the system become slow, then come
+ * this second timeout. In both cases we return.
+ */
+ if (work_pending(&dec->work_back) ||
+ work_busy(&dec->work_back) ||
+ work_busy(&dec->timeout_work_back) ||
+ work_pending(&dec->timeout_work_back)) {
+ pr_err("%s avs2[%d] work back pending, do nothing.\n",__func__, dec->index);
+ return;
+ }
+
+ /* disable interrupt before timeout */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 0);
+
+ avs2_print(dec,
+ 0, "%s decoder timeout\n", __func__);
+ dec->timeout_num_back++;
+#if 0
+ amhevc_stop();
+ read_decode_info(dec);
+ hevc_print(dec,
+ 0, "%s decoder timeout\n", __func__);
+ check_pic_decoded_error(dec,
+ dec->pic_decoded_lcu_idx);
+ /*The current decoded frame is marked
+ error when the decode timeout*/
+ if (dec->cur_pic != NULL)
+ dec->cur_pic->error_mark = 1;
+ dec->decoded_poc = dec->curr_POC;
+ dec->decoding_pic = NULL;
+ dec->dec_result = DEC_RESULT_DONE;
+#endif
+ reset_process_time_back(dec);
+
+ if (work_pending(&dec->work_back))
+ return;
+ dec->dec_back_result = DEC_BACK_RESULT_TIMEOUT;
+ vdec_schedule_work(&dec->timeout_work_back);
+}
+#endif
+
+static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec)
+{
+ u32 dw_mode;
+
+ dw_mode = (dec->m_ins_flag && ((double_write_mode & 0x80000000) == 0)) ?
+ dec->double_write_mode : (double_write_mode & 0x7fffffff);
+ if (dw_mode & 0x20) {
+ if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
+ && ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3))
+ dw_mode = 0;
+ }
+
+ return dw_mode;
+}
+
+static int get_double_write_mode(struct AVS2Decoder_s *dec)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(dec) & 0xffff;
+ int w = dec->avs2_dec.img.width;
+ int h = dec->avs2_dec.img.height;
+ u32 dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w * h > 1920 * 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w * h > 1920 * 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w * h > 1280 * 768)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ dw = valid_dw_mode;
+ break;
+ }
+ return dw;
+}
+
+#ifdef OW_TRIPLE_WRITE
+static int get_triple_write_mode(struct AVS2Decoder_s *dec)
+{
+ int tw = ((triple_write_mode & 0x80000000) == 0) ?
+ dec->triple_write_mode : (triple_write_mode & 0x7fffffff);
+
+ return (tw & 0xffff);
+}
+#endif
+
+#ifdef P010_ENABLE
+static __inline__ bool is_dw_p010(struct AVS2Decoder_s *dec)
+{
+ int a = (double_write_mode & 0x80000000) ? (double_write_mode & 0x10000) : 0;
+
+ return ((dec->double_write_mode & 0x10000) || a);
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+ int a = (triple_write_mode & 0x80000000) ? (triple_write_mode & 0x10000) : 0;
+
+ return ((dec->triple_write_mode & 0x10000) || a);
+}
+
+#else
+
+static __inline__ bool is_dw_p010(struct AVS2Decoder_s *dec)
+{
+ return 0;
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+ return 0;
+}
+#endif
+
+/* for double write buf alloc */
+static int get_double_write_mode_init(struct AVS2Decoder_s *dec)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(dec);
+ u32 dw;
+ int w = dec->init_pic_w;
+ int h = dec->init_pic_h;
+
+ dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 768)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ dw = valid_dw_mode;
+ break;
+ }
+ return dw;
+}
+
+#ifdef AVS2_10B_MMU
+int avs2_alloc_mmu(
+ struct AVS2Decoder_s *dec,
+ int cur_buf_idx,
+ int pic_width,
+ int pic_height,
+ unsigned short bit_depth,
+ unsigned int *mmu_index_adr)
+{
+ int bit_depth_10 = (bit_depth == AVS2_BITS_10);
+ int cur_mmu_4k_number;
+ int ret;
+
+ cur_mmu_4k_number = avs2_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+ if (cur_mmu_4k_number < 0)
+ return -1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s:mmu_4k_number %d\n", __func__, cur_mmu_4k_number);
+
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+ ret = decoder_mmu_box_alloc_idx(
+ dec->mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+
+ return ret;
+}
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+int avs2_alloc_dw_mmu(
+ struct AVS2Decoder_s *dec,
+ int cur_buf_idx,
+ int pic_width,
+ int pic_height,
+ unsigned short bit_depth,
+ unsigned int *mmu_index_adr)
+{
+ int bit_depth_10 = (bit_depth == AVS2_BITS_10);
+ int cur_mmu_4k_number;
+ int ret;
+
+ cur_mmu_4k_number = avs2_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+
+ if (cur_mmu_4k_number < 0)
+ return -1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s:mmu_4k_number %d\n", __func__, cur_mmu_4k_number);
+
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+ ret = decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+
+ return ret;
+}
+#endif
+
+static int get_free_buf_count(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ int i;
+ int count = 0;
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+ && avs2_dec->fref[i]->is_output == -1
+ && avs2_dec->fref[i]->bg_flag == 0
+#ifdef NEW_FRONT_BACK_CODE
+ && avs2_dec->fref[i]->backend_ref == 0
+#endif
+ && avs2_dec->fref[i]->vf_ref == 0
+ && avs2_dec->fref[i]->to_prepare_disp == 0
+ ) {
+
+ count++;
+ }
+ }
+
+ return count;
+}
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+static int get_vf_ref_only_buf_count(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ int i;
+ int count = 0;
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+ && avs2_dec->fref[i]->is_output == -1
+ && avs2_dec->fref[i]->bg_flag == 0
+ && avs2_dec->fref[i]->vf_ref > 0
+ && avs2_dec->fref[i]->to_prepare_disp == 0) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+int get_error_policy(struct avs2_decoder *avs2_dec)
+{
+ struct AVS2Decoder_s *dec = container_of(avs2_dec, struct AVS2Decoder_s, avs2_dec);
+
+ return dec->error_proc_policy;
+}
+
+static int get_used_buf_count(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ int i;
+ int count = 0;
+ for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
+ if ((avs2_dec->fref[i]->imgcoi_ref >= -256)
+ || avs2_dec->fref[i]->is_output != -1
+ || avs2_dec->fref[i]->bg_flag != 0
+ || avs2_dec->fref[i]->vf_ref != 0
+ || avs2_dec->fref[i]->to_prepare_disp != 0) {
+ count++;
+ }
+ }
+
+ return count;
+}
+#endif
+
+int avs2_bufmgr_init(struct AVS2Decoder_s *dec, struct BuffInfo_s *buf_spec_i,
+ struct buff_s *mc_buf_i) {
+
+ dec->frame_count = 0;
+#ifdef AVS2_10B_MMU
+ dec->used_4k_num = -1;
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+#endif
+ spin_lock_init(&dec->buffer_lock);
+
+ /* private init */
+ dec->work_space_buf = buf_spec_i;
+#ifndef AVS2_10B_MMU
+ dec->mc_buf = mc_buf_i;
+#endif
+ dec->rpm_addr = NULL;
+ dec->lmem_addr = NULL;
+
+ dec->use_cma_flag = 0;
+ dec->decode_idx = 0;
+ dec->slice_idx = 0;
+
+ dec->wait_buf = 0;
+ dec->error_flag = 0;
+ dec->skip_PB_before_I = 0;
+
+ dec->pts_mode = PTS_NORMAL;
+ dec->last_pts = 0;
+ dec->last_lookup_pts = 0;
+ dec->last_pts_us64 = 0;
+ dec->last_lookup_pts_us64 = 0;
+ dec->shift_byte_count = 0;
+ dec->shift_byte_count_lo = 0;
+ dec->shift_byte_count_hi = 0;
+ dec->pts_mode_switching_count = 0;
+ dec->pts_mode_recovery_count = 0;
+
+ dec->buf_num = 0;
+
+ dec->bufmgr_error_count = 0;
+#ifdef NEW_FB_CODE
+ dec->start_process_time_back = 0;
+ dec->decode_timeout_count_back = 0;
+ dec->timeout_num_back = 0;
+ dec->decode_timeout_count_back = 0;
+#endif
+ return 0;
+}
+
+#define HEVC_CM_BODY_START_ADDR 0x3626
+#define HEVC_CM_BODY_LENGTH 0x3627
+#define HEVC_CM_HEADER_LENGTH 0x3629
+#define HEVC_CM_HEADER_OFFSET 0x362b
+
+#define LOSLESS_COMPRESS_MODE
+
+static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
+static u32 enable_mem_saving = 1;
+static u32 force_w_h;
+
+static u32 force_fps;
+
+const u32 avs2_version = 201602101;
+static u32 radr;
+static u32 rval;
+static u32 pop_shorts;
+static u32 dbg_cmd;
+static u32 dbg_skip_decode_index;
+/*
+ * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
+ * bit 8~23, for HEVC_SAO_CTRL1 endian config
+ */
+static u32 endian;
+#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
+#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
+#define HEVC_CONFIG_P010_LE (0x77007)
+
+#ifdef ERROR_HANDLE_DEBUG
+static u32 dbg_nal_skip_flag;
+ /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
+static u32 dbg_nal_skip_count;
+#endif
+/*for debug*/
+static u32 decode_pic_begin;
+static uint slice_parse_begin;
+static u32 step;
+#ifdef MIX_STREAM_SUPPORT
+static u32 buf_alloc_width = 4096;
+static u32 buf_alloc_height = 2304;
+
+static u32 dynamic_buf_num_margin = 4;
+#else
+static u32 buf_alloc_width;
+static u32 buf_alloc_height;
+static u32 dynamic_buf_num_margin = 7;
+#endif
+#ifdef CONSTRAIN_MAX_BUF_NUM
+static u32 run_ready_max_vf_only_num;
+static u32 run_ready_display_q_num;
+ /*0: not check
+ 0xff: avs2_dec.ref_maxbuffer
+ */
+static u32 run_ready_max_buf_num = 0xff;
+#endif
+static u32 buf_alloc_depth = 10;
+static u32 buf_alloc_size;
+/*
+bit[0]: 0,
+ bit[1]: 0, always release cma buffer when stop
+ bit[1]: 1, never release cma buffer when stop
+bit[0]: 1, when stop, release cma buffer if blackout is 1;
+do not release cma buffer is blackout is not 1
+
+bit[2]: 0, when start decoding, check current displayed buffer
+ (only for buffer decoded by vp9) if blackout is 0
+ 1, do not check current displayed buffer
+
+bit[3]: 1, if blackout is not 1, do not release current
+ displayed cma buffer always.
+*/
+/* set to 1 for fast play;
+ set to 8 for other case of "keep last frame"
+*/
+static u32 buffer_mode = 1;
+/* buffer_mode_dbg: debug only*/
+static u32 buffer_mode_dbg = 0xffff0000;
+
+/*
+bit 0, 1: only display I picture;
+bit 1, 1: only decode I picture;
+*/
+static u32 i_only_flag;
+
+static u32 max_decoding_time;
+/*
+error handling
+*/
+/*error_handle_policy:
+bit 0: search seq again if buffer mgr error occur
+ (buffer mgr error count need big than
+ re_search_seq_threshold)
+bit 1: 1, display from I picture;
+ 0, display from any correct pic
+*/
+
+static u32 error_handle_policy = 1;
+/*
+re_search_seq_threshold:
+ bit 7~0: buffer mgr error research seq count
+ bit 15~8: frame count threshold
+*/
+static u32 re_search_seq_threshold = 0x800; /*0x8;*/
+
+static u32 max_buf_num = (REF_BUFFER + 1);
+
+static u32 run_ready_min_buf_num = 2;
+
+static DEFINE_MUTEX(vavs2_mutex);
+
+#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
+#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
+#define AVS2_ALF_SWAP_BUFFER HEVC_ASSIST_SCRATCH_2
+#define HEVC_RCS_BUFFER HEVC_ASSIST_SCRATCH_3
+#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
+#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
+#ifdef AVS2_10B_MMU
+#define AVS2_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
+#else
+#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
+#endif
+#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
+
+#define AVS2_CUVA_ADR HEVC_ASSIST_SCRATCH_A
+#define AVS2_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_B
+
+#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
+#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
+#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_9
+#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
+#define HEVC_EFFICIENCY_MODE HEVC_ASSIST_SCRATCH_L
+/*!!!*/
+#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M
+#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
+//#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_6
+#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
+#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
+
+/*
+ucode parser/search control
+bit 0: 0, header auto parse; 1, header manual parse
+bit 1: 0, auto skip for noneseamless stream; 1, no skip
+bit [3:2]: valid when bit1 == 0;
+0, auto skip nal before first vps/sps/pps/idr;
+1, auto skip nal before first vps/sps/pps
+2, auto skip nal before first vps/sps/pps,
+ and not decode until the first I slice (with slice address of 0)
+
+3, auto skip before first I slice (nal_type >=16 && nal_type <= 21)
+bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
+bit [16]: for NAL_UNIT_EOS when bit0 is 0:
+ 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
+bit [17]: for NAL_SEI when bit0 is 0:
+ 0, do not parse SEI in ucode; 1, parse SEI in ucode
+bit [31:20]: used by ucode for debug purpose
+*/
+#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
+ /*DECODE_MODE: set before start decoder
+ bit 7~0: decode mode
+ bit 23~16: start_decoding_flag
+ bit [0] - SEQ_ready
+ bit [2:1] - I Picture Count
+ bit 31~24: chip feature
+ */
+#define DECODE_MODE HEVC_ASSIST_SCRATCH_J
+#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
+ /*read only*/
+#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE HEVC_ASSIST_SCRATCH_Z
+#define HEVC_EFFICIENCY_MODE_BACK HEVC_ASSIST_SCRATCH_10
+
+#define EE_ASSIST_MBOX0_IRQ_REG 0x3f70
+#define EE_ASSIST_MBOX0_CLR_REG 0x3f71
+#define EE_ASSIST_MBOX0_MASK 0x3f72
+#endif
+
+#define RPM_BUF_SIZE (0x600 * 2)
+#define LMEM_BUF_SIZE (0x600 * 2)
+
+ /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
+#define VBH_BUF_SIZE_1080P 0x3000
+#define VBH_BUF_SIZE_4K 0x5000
+#define VBH_BUF_SIZE_8K 0xa000
+#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
+ /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
+ HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
+#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
+#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
+#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
+#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
+
+/* necessary 4K page size align for t7/t3 decoder and after */
+#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
+
+#define WORK_BUF_SPEC_NUM 6
+static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = {
+ {
+ /* 8M bytes */
+ .max_width = 1920,
+ .max_height = 1088,
+ .ipp = {
+ /* IPP work space calculation :
+ 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+ .buf_size = 0x4000,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000,
+ },
+#endif
+ .sao_abv = {
+ .buf_size = 0x30000,
+ },
+ .sao_vb = {
+ .buf_size = 0x30000,
+ },
+ .short_term_rps = {
+ /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800) */
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
+ total 0x0400 bytes */
+ .buf_size = 0x400,
+ },
+ .sps = {
+ /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes*/
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
+ total 0x2000 bytes*/
+ .buf_size = 0x2000,
+ },
+ .sao_up = {
+ /* SAO UP STORE AREA - Max 640(10240/16) LCU,
+ each has 16 bytes total 0x2800 bytes */
+ .buf_size = 0x2800,
+ },
+ .swap_buf = {
+ /* 256cyclex64bit = 2K bytes 0x800
+ (only 144 cycles valid) */
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+ .scalelut = {
+ /* support up to 32 SCALELUT 1024x32 =
+ 32Kbytes (0x8000) */
+ .buf_size = 0x8000,
+ },
+ .dblk_para = {
+ /* DBLK -> Max 256(4096/16) LCU,
+ each para 1024bytes(total:0x40000),
+ data 1024bytes(total:0x40000)*/
+ .buf_size = 0x40000,
+ },
+ .dblk_data = {
+ .buf_size = 0x40000,
+ },
+ .dblk_data2 = {
+ .buf_size = 0x40000,
+ },
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {
+ .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
+ },
+#endif
+ .mpred_above = {
+ .buf_size = 0x8000, /* 2 * size of hevc*/
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {/* 1080p, 0x40000 per buffer */
+ .buf_size = 0x40000 * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x400 * 2,
+ }
+ },
+ {
+ .max_width = 4096,
+ .max_height = 2304,
+ .ipp = {
+ /* IPP work space calculation :
+ 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+ .buf_size = 0x4000,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000,
+ },
+#endif
+ .sao_abv = {
+ .buf_size = 0x30000,
+ },
+ .sao_vb = {
+ .buf_size = 0x30000,
+ },
+ .short_term_rps = {
+ /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800) */
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+ total 0x0400 bytes */
+ .buf_size = 0x400,
+ },
+ .sps = {
+ /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes */
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
+ total 0x2000 bytes */
+ .buf_size = 0x2000,
+ },
+ .sao_up = {
+ /* SAO UP STORE AREA - Max 640(10240/16) LCU,
+ each has 16 bytes total 0x2800 bytes */
+ .buf_size = 0x2800,
+ },
+ .swap_buf = {
+ /* 256cyclex64bit = 2K bytes 0x800
+ (only 144 cycles valid) */
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+ .scalelut = {
+ /* support up to 32 SCALELUT 1024x32 = 32Kbytes
+ (0x8000) */
+ .buf_size = 0x8000,
+ },
+ .dblk_para = {
+ /* DBLK -> Max 256(4096/16) LCU,
+ each para 1024bytes(total:0x40000),
+ data 1024bytes(total:0x40000)*/
+ .buf_size = 0x80000,
+ },
+ .dblk_data = {
+ /*DBLK -> Max 256(4096/16) LCU,
+ each para 1024bytes(total:0x40000),
+ data 1024bytes(total:0x40000)*/
+ .buf_size = 0x80000,
+ },
+ .dblk_data2 = {
+ .buf_size = 0x80000,
+ },
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {
+ .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
+ },
+#endif
+ .mpred_above = {
+ .buf_size = 0x10000, /* 2 * size of hevc*/
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {
+ /* .buf_size = 0x100000*16,
+ //4k2k , 0x100000 per buffer */
+ /* 4096x2304 , 0x120000 per buffer */
+ .buf_size = 0x120000 * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x400 * 2,
+ }
+ },
+ {
+ .max_width = 4096 * 2,
+ .max_height = 2304 * 2,
+ .ipp = {
+ /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
+ round to 16k*/
+ .buf_size = 0x4000 * 2,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000 * 2,
+ },
+#endif
+ .sao_abv = {
+ .buf_size = 0x30000 * 2,
+ },
+ .sao_vb = {
+ .buf_size = 0x30000 * 2,
+ },
+ .short_term_rps = {
+ /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800)*/
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+ total 0x0400 bytes*/
+ .buf_size = 0x400,
+ },
+ .sps = {
+ /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes*/
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
+ 0x2000 bytes*/
+ .buf_size = 0x2000,
+ },
+ .sao_up = {
+ /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
+ total 0x2800 bytes*/
+ .buf_size = 0x2800 * 2,
+ },
+ .swap_buf = {
+ /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+ .scalelut = {
+ /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
+ .buf_size = 0x8000 * 2,
+ },
+ .dblk_para = {
+ .buf_size = 0x40000 * 2,
+ },
+ .dblk_data = {
+ .buf_size = 0x80000 * 2,
+ },
+ .dblk_data2 = {
+ .buf_size = 0x80000 * 2,
+ },
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {
+ .buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/
+ },
+#endif
+ .mpred_above = {
+ .buf_size = 0x8000 * 2,
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {
+ /*4k2k , 0x100000 per buffer*/
+ .buf_size = 0x120000 * FRAME_BUFFERS * 4,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x400 * 2,
+ }
+ },
+ {
+ /* 8M bytes */
+ .max_width = 1920, //2048
+ .max_height = 1088, //1152
+ .ipp = {.buf_size = 0x1e00}, //IPP work space calculation :4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {.buf_size = 0x1e00}, //IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+ .short_term_rps = {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, // RCS STORE AREA - Max 32 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+ .sao_up = {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .swap_buf = {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+ .scalelut = {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .dblk_para = {.buf_size = 0x4100}, //(ctu_numb_x+1) * 128 = (2048/16+1)*128= 0x4080
+ .dblk_data = {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+ .dblk_data2 = {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_1080P}, /*2*16*(more than 2304)/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_1080P}, //2*16*2304/4, 4K
+#endif
+ .mpred_above = {.buf_size = 0x2000}, // 2 * size of hevc: (pic_width/64)*16*16 byte = 2048/64*16*16=0x2000
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS}, // 1080p, 0x40000 per buffer
+#endif
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+ .lmem = {.buf_size = 0x400 * 2},
+ },
+ {
+ .max_width = 4096,
+ .max_height = 2304,
+ .ipp = {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+ .short_term_rps = {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, // RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,total 0x2000 bytes
+ .sao_up = {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .swap_buf = {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+ .scalelut = {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .dblk_para = {.buf_size = 0x8100}, //(ctu_numb_x+1) * 128 = (4096/16+1) * 128 = 0x8080
+ .dblk_data = {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+ .dblk_data2 = {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_4K},/*2*16*(more than 2304)/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_4K}, //2*16*2304/4, 4K
+#endif
+ .mpred_above = {.buf_size = 0x4000}, //(pic_width/64)*16*16 byte = 4096/64*16*16=0x4000
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS}, //.buf_size = 0x100000*16, 4k2k => 0x100000 per buffer 4096x2304 => 0x120000 per buffer
+#endif
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+ .lmem = {.buf_size = 0x400 * 2},
+ },
+ {
+ .max_width = 4096 * 2,
+ .max_height = 2304 * 2,
+ .ipp = {.buf_size = 0x4000 * 2}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {.buf_size = 0x4000 * 2}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+#ifdef USE_SIM_BUFSPEC
+ .sao_abv = {.buf_size = 0x30000 * 2},
+ .sao_vb = {.buf_size = 0x30000 * 2},
+#else
+ .sao_abv = {.buf_size = 0},
+ .sao_vb = {.buf_size = 0},
+#endif
+ .short_term_rps = {.buf_size = 0x800}, //SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+ .rcs = {.buf_size = 0x400}, //RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+ .sps = {.buf_size = 0x800}, //SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+ .pps = {.buf_size = 0x2000}, //PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+#ifdef USE_SIM_BUFSPEC
+ .sao_up = {.buf_size = 0x2800 * 2}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+#else
+ .sao_up = {.buf_size = 0}, //SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+#endif
+ .swap_buf = {.buf_size = 0x800}, //256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+ .swap_buf2 = {.buf_size = 0x800},
+#ifdef USE_SIM_BUFSPEC
+ .scalelut = {.buf_size = 0x8000 * 2}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+#else
+ .scalelut = {.buf_size = 0}, //support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+#endif
+#ifdef FOR_S5
+ .dblk_para = { .buf_size = 0x40000 * 2},
+ .dblk_data = { .buf_size = 0x80000 * 2},
+ .dblk_data2 = { .buf_size = 0x80000 * 2},
+#else
+ .dblk_para = {.buf_size = 0x10100}, //(ctu_numb_x+1) * 128 = (8192/16+1)*128 = 0x10080
+ .dblk_data = {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+ .dblk_data2 = {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+#endif
+#ifdef USE_SIM_BUFSPEC
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {.buf_size = 0x5000 * 2}, //2*16*2304/4, 4K
+ .cm_header = {.buf_size = MMU_COMPRESS_HEADER_SIZE * AVS2_BUFFER_NUM}, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+#endif
+#ifdef AVS2_10B_MMU_DW
+ .mmu_vbh_dw = {.buf_size = 0x5000 * 2}, //2*16*2304/4, 4K
+ .cm_header_dw = {.buf_size = MMU_COMPRESS_HEADER_SIZE_DW * AVS2_BUFFER_NUM}, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+#endif
+#else
+#ifdef AVS2_10B_MMU
+ .mmu_vbh = {.buf_size = VBH_BUF_SIZE_8K}, /*2*16*2304/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+ .mmu_vbh_dw = {.buf_size = DW_VBH_BUF_SIZE_8K}, //2*16*2304/4, 4K
+#endif
+#endif
+#ifdef FOR_S5
+ .mpred_above = {.buf_size = 0x8000 * 2},
+#else
+ .mpred_above = {.buf_size = 0x8000}, //(pic_width/64)*16*16 byte = 8192/64*16*16=0x8000
+#endif
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {.buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS}, //4k2k , 0x100000 per buffer
+#endif
+ .rpm = {.buf_size = RPM_BUF_SIZE},
+#ifdef FOR_S5
+ .lmem = {.buf_size = 0x600 * 2},
+#else
+ .lmem = {.buf_size = 0x400 * 2},
+#endif
+ }
+};
+
+#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
+#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
+#ifndef MV_USE_FIXED_BUF
+static uint32_t get_mv_buf_size(struct AVS2Decoder_s *dec, int width, int height) {
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ uint32_t size;
+ if (mv_buf_dynamic_alloc == 1) {
+ int mv_mem_unit =
+ avs2_dec->lcu_size_log2 == 6 ? 0x200 : avs2_dec->lcu_size_log2 ==
+ 5 ? 0x80 : 0x20;
+ int extended_pic_width = (width + avs2_dec->lcu_size -1)
+ & (~(avs2_dec->lcu_size - 1));
+ int extended_pic_height = (height + avs2_dec->lcu_size -1)
+ & (~(avs2_dec->lcu_size - 1));
+ int lcu_x_num = extended_pic_width / avs2_dec->lcu_size;
+ int lcu_y_num = extended_pic_height / avs2_dec->lcu_size;
+ int new_size = lcu_x_num * lcu_y_num * mv_mem_unit;
+ size = (new_size + 0xffff) & (~0xffff);
+
+ } else {
+ if (IS_8K_SIZE(width, height))
+ size = CO_MV_BUF_SIZE_8K;
+ else if (IS_4K_SIZE(width, height))
+ size = CO_MV_BUF_SIZE_4K;
+ else
+ size = CO_MV_BUF_SIZE_1080P;
+ }
+ return size;
+}
+#endif
+
+static void config_hevc_irq_num(struct AVS2Decoder_s *dec)
+{
+ PRINT_LINE();
+#ifdef NEW_FB_CODE
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ dec->ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = EE_ASSIST_MBOX0_MASK;
+ dec->backend_ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->backend_ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->backend_ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+ } else {
+ dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+ dec->backend_ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+ dec->backend_ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+ dec->backend_ASSIST_MBOX0_MASK = EE_ASSIST_MBOX0_MASK;
+ }
+#else
+ dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+#endif
+}
+
+#ifdef NEW_FB_CODE
+
+void pic_backend_ref_operation(struct AVS2Decoder_s *dec, bool add_flag)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic = NULL;
+ int i = 0;
+
+ mutex_lock(&dec->fb_mutex);
+ if (add_flag) {
+ pic = dec->avs2_dec.hc.cur_pic;
+ pic->backend_ref = 1;
+ pic->back_done_mark = 0;
+ } else {
+ pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+ pic->backend_ref--;
+ if (pic->backend_ref < 0) {
+ pic->backend_ref = 0;
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:pic(%px) backend_ref error\n",
+ __func__, pic);
+ }
+ pic->back_done_mark = 1;
+ }
+
+ for (i = 0; (i < MAXREF) && (pic->ref_pic[i] != NULL); i++) {
+ if (add_flag) {
+ pic->ref_pic[i]->backend_ref++;
+ } else {
+ pic->ref_pic[i]->backend_ref--;
+ if (pic->ref_pic[i]->backend_ref < 0) {
+ pic->ref_pic[i]->backend_ref = 0;
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:ref_pic(%px) backend_ref error\n",
+ __func__, pic->ref_pic[i]);
+ }
+ }
+ }
+
+ mutex_unlock(&dec->fb_mutex);
+}
+
+#include "avs2_fb_hw.c"
+
+/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+static int front_decpic_done_update(struct AVS2Decoder_s *dec, uint8_t reset_flag)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ pic_backend_ref_operation(dec, 1);
+ if (dec->front_back_mode == 1) {
+ read_bufstate_front(avs2_dec);
+ print_loopbufs_ptr(dec, "fr", &avs2_dec->fr);
+
+ WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 1);
+
+#if 0 //def RESET_FRONT_PER_PICTURE
+ if (reset_flag) {
+ /*not multi pictures in one packe*/
+ amhevc_stop_f();
+ //save_stream_context(dec->work_space_buf->swap_buf.buf_start);
+ }
+#endif
+ } else {
+ if (reset_flag) /*not multi pictures in one packe*/
+ amhevc_stop();
+ }
+
+ avs2_dec->frontend_decoded_count++;
+ avs2_dec->next_be_decode_pic[avs2_dec->fb_wr_pos] = avs2_dec->hc.cur_pic;
+
+ mutex_lock(&dec->fb_mutex);
+ avs2_dec->fb_wr_pos++;
+ if (avs2_dec->fb_wr_pos >= dec->fb_ifbuf_num)
+ avs2_dec->fb_wr_pos = 0;
+
+ if (avs2_dec->fb_wr_pos == avs2_dec->fb_rd_pos) {
+ avs2_dec->wait_working_buf = 1;
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "fb_wr_pos %d fb_rd_pos %d, set wait_working_buf = 1\n", avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos);
+ } else {
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "fb_wr_pos %d fb_rd_pos %d\n", avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos);
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ return 0;
+}
+
+#endif
+
+/*Losless compression body buffer size 4K per 64x32 (jt)*/
+static int compute_losless_comp_body_size(struct AVS2Decoder_s *dec,
+ int width, int height,
+ uint8_t is_bit_depth_10)
+{
+ int width_x64;
+ int height_x32;
+ int bsize;
+ width_x64 = width + 63;
+ width_x64 >>= 6;
+ height_x32 = height + 31;
+ height_x32 >>= 5;
+#ifdef AVS2_10B_MMU
+ bsize = (is_bit_depth_10 ? 4096 : 3200)
+ * width_x64 * height_x32;
+#else
+ bsize = (is_bit_depth_10 ? 4096 : 3072)
+ * width_x64 * height_x32;
+#endif
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s(%d,%d,%d)=>%d\n",
+ __func__, width, height,
+ is_bit_depth_10, bsize);
+
+ return bsize;
+}
+
+/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
+static int compute_losless_comp_header_size(struct AVS2Decoder_s *dec,
+ int width, int height)
+{
+ int width_x128;
+ int height_x64;
+ int hsize;
+ width_x128 = width + 127;
+ width_x128 >>= 7;
+ height_x64 = height + 63;
+ height_x64 >>= 6;
+
+ hsize = 32 * width_x128 * height_x64;
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s(%d,%d)=>%d\n",
+ __func__, width, height,
+ hsize);
+
+ return hsize;
+}
+
+static void init_buff_spec(struct AVS2Decoder_s *dec,
+ struct BuffInfo_s *buf_spec)
+{
+ void *mem_start_virt;
+ buf_spec->ipp.buf_start =
+ WORKBUF_ALIGN(buf_spec->start_adr);
+#ifdef NEW_FRONT_BACK_CODE
+ buf_spec->ipp1.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+ buf_spec->sao_abv.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp1.buf_start + buf_spec->ipp1.buf_size);
+#else
+ buf_spec->sao_abv.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+#endif
+ buf_spec->sao_vb.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+ buf_spec->short_term_rps.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+ buf_spec->rcs.buf_start =
+ WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+ buf_spec->sps.buf_start =
+ WORKBUF_ALIGN(buf_spec->rcs.buf_start + buf_spec->rcs.buf_size);
+ buf_spec->pps.buf_start =
+ WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+ buf_spec->sao_up.buf_start =
+ WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+ buf_spec->swap_buf.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+ buf_spec->swap_buf2.buf_start =
+ WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+ buf_spec->scalelut.buf_start =
+ WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+ buf_spec->dblk_para.buf_start =
+ WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+ buf_spec->dblk_data.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+ buf_spec->dblk_data2.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+#ifdef AVS2_10B_MMU
+ buf_spec->mmu_vbh.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ #ifdef AVS2_10B_MMU_DW
+ buf_spec->mmu_vbh_dw.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
+ #else
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ #endif
+#else /* AVS2_10B_MMU */
+ #ifdef AVS2_10B_MMU_DW
+ buf_spec->mmu_vbh_dw.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
+ #else
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ #endif
+#endif /* AVS2_10B_MMU */
+#ifdef MV_USE_FIXED_BUF
+ buf_spec->mpred_mv.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->rpm.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+#else
+ buf_spec->rpm.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+#endif
+ buf_spec->lmem.buf_start =
+ WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->end_adr =
+ WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+
+ if (dec) {
+ mem_start_virt =
+ codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
+ if (mem_start_virt) {
+ memset(mem_start_virt, 0, buf_spec->dblk_para.buf_size);
+ codec_mm_dma_flush(mem_start_virt,
+ buf_spec->dblk_para.buf_size,
+ DMA_TO_DEVICE);
+ } else {
+ /*not virt for tvp playing,
+ may need clear on ucode.*/
+ pr_err("mem_start_virt failed\n");
+ }
+ if (debug) {
+ pr_info("%s workspace (%x %x) size = %x\n", __func__,
+ buf_spec->start_adr, buf_spec->end_adr,
+ buf_spec->end_adr - buf_spec->start_adr);
+ }
+ if (debug) {
+ pr_info("ipp.buf_start :%x\n",
+ buf_spec->ipp.buf_start);
+#ifdef NEW_FRONT_BACK_CODE
+ pr_info("ipp1.buf_start :%x\n",
+ buf_spec->ipp1.buf_start);
+#endif
+ pr_info("sao_abv.buf_start :%x\n",
+ buf_spec->sao_abv.buf_start);
+ pr_info("sao_vb.buf_start :%x\n",
+ buf_spec->sao_vb.buf_start);
+ pr_info("short_term_rps.buf_start :%x\n",
+ buf_spec->short_term_rps.buf_start);
+ pr_info("rcs.buf_start :%x\n",
+ buf_spec->rcs.buf_start);
+ pr_info("sps.buf_start :%x\n",
+ buf_spec->sps.buf_start);
+ pr_info("pps.buf_start :%x\n",
+ buf_spec->pps.buf_start);
+ pr_info("sao_up.buf_start :%x\n",
+ buf_spec->sao_up.buf_start);
+ pr_info("swap_buf.buf_start :%x\n",
+ buf_spec->swap_buf.buf_start);
+ pr_info("swap_buf2.buf_start :%x\n",
+ buf_spec->swap_buf2.buf_start);
+ pr_info("scalelut.buf_start :%x\n",
+ buf_spec->scalelut.buf_start);
+ pr_info("dblk_para.buf_start :%x\n",
+ buf_spec->dblk_para.buf_start);
+ pr_info("dblk_data.buf_start :%x\n",
+ buf_spec->dblk_data.buf_start);
+ pr_info("dblk_data2.buf_start :%x\n",
+ buf_spec->dblk_data2.buf_start);
+ #ifdef AVS2_10B_MMU
+ pr_info("mmu_vbh.buf_start :%x\n",
+ buf_spec->mmu_vbh.buf_start);
+ #endif
+ #ifdef AVS2_10B_MMU_DW
+ pr_info("mmu_vbh_dw.buf_start :%x\n",
+ buf_spec->mmu_vbh_dw.buf_start);
+ #endif
+ pr_info("mpred_above.buf_start :%x\n",
+ buf_spec->mpred_above.buf_start);
+#ifdef MV_USE_FIXED_BUF
+ pr_info("mpred_mv.buf_start :%x\n",
+ buf_spec->mpred_mv.buf_start);
+#endif
+ if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
+ pr_info("rpm.buf_start :%x\n",
+ buf_spec->rpm.buf_start);
+ }
+ }
+ }
+
+}
+
+static void uninit_mmu_buffers(struct AVS2Decoder_s *dec)
+{
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+ decoder_mmu_box_free(dec->dw_mmu_box);
+ dec->dw_mmu_box = NULL;
+ }
+#endif
+ decoder_mmu_box_free(dec->mmu_box);
+ dec->mmu_box = NULL;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (dec->mmu_box_1)
+ decoder_mmu_box_free(dec->mmu_box_1);
+ dec->mmu_box_1 = NULL;
+ if (dec->dw_mmu_enable && dec->dw_mmu_box_1) {
+ decoder_mmu_box_free(dec->dw_mmu_box_1);
+ dec->dw_mmu_box_1 = NULL;
+ }
+ }
+ if (dec->front_back_mode) {
+ uninit_fb_bufstate(dec);
+ }
+#endif
+ if (dec->bmmu_box)
+ decoder_bmmu_box_free(dec->bmmu_box);
+ dec->bmmu_box = NULL;
+}
+
+#ifndef AVS2_10B_MMU
+static void init_buf_list(struct AVS2Decoder_s *dec)
+{
+ int i;
+ int buf_size;
+ int mc_buffer_end = dec->mc_buf->buf_start + dec->mc_buf->buf_size;
+
+ if (IS_8K_SIZE(dec->vavs2_amstream_dec_info.width, dec->vavs2_amstream_dec_info.height))
+ dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin;
+ else
+ dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin - 4;
+
+ if (dec->used_buf_num > MAX_BUF_NUM)
+ dec->used_buf_num = MAX_BUF_NUM;
+ if (buf_alloc_size > 0) {
+ buf_size = buf_alloc_size;
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "[Buffer Management] init_buf_list:\n");
+ } else {
+ int pic_width = dec->init_pic_w;
+ int pic_height = dec->init_pic_h;
+
+ /*SUPPORT_10BIT*/
+ int losless_comp_header_size = compute_losless_comp_header_size
+ (dec, pic_width, pic_height);
+ int losless_comp_body_size = compute_losless_comp_body_size
+ (dec, pic_width, pic_height, buf_alloc_depth == 10);
+ int mc_buffer_size = losless_comp_header_size
+ + losless_comp_body_size;
+ int mc_buffer_size_h = (mc_buffer_size + 0xffff)>>16;
+
+ int dw_mode = get_double_write_mode_init(dec);
+
+ if (dw_mode) {
+ int pic_width_dw = pic_width /
+ get_double_write_ratio(dw_mode);
+ int pic_height_dw = pic_height /
+ get_double_write_ratio(dw_mode);
+ int lcu_size = 64; /*fixed 64*/
+ int pic_width_64 = (pic_width_dw + 63) & (~0x3f);
+ int pic_height_32 = (pic_height_dw + 31) & (~0x1f);
+ int pic_width_lcu =
+ (pic_width_64 % lcu_size) ? pic_width_64 / lcu_size
+ + 1 : pic_width_64 / lcu_size;
+ int pic_height_lcu =
+ (pic_height_32 % lcu_size) ? pic_height_32 / lcu_size
+ + 1 : pic_height_32 / lcu_size;
+ int lcu_total = pic_width_lcu * pic_height_lcu;
+ int mc_buffer_size_u_v = lcu_total * lcu_size * lcu_size / 2;
+ int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
+ /*64k alignment*/
+ buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
+ } else
+ buf_size = 0;
+
+ if (mc_buffer_size & 0xffff) { /*64k alignment*/
+ mc_buffer_size_h += 1;
+ }
+ if ((dw_mode & 0x10) == 0)
+ buf_size += (mc_buffer_size_h << 16);
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "init_buf_list num %d (width %d height %d):\n",
+ dec->used_buf_num, pic_width, pic_height);
+ }
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (((i + 1) * buf_size) > dec->mc_buf->buf_size)
+ dec->use_cma_flag = 1;
+
+ dec->m_BUF[i].alloc_flag = 0;
+ dec->m_BUF[i].index = i;
+
+ dec->use_cma_flag = 1;
+ if (dec->use_cma_flag) {
+ dec->m_BUF[i].cma_page_count =
+ PAGE_ALIGN(buf_size) / PAGE_SIZE;
+ if (decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ VF_BUFFER_IDX(i), buf_size, DRIVER_NAME,
+ &dec->m_BUF[i].alloc_addr) < 0) {
+ dec->m_BUF[i].cma_page_count = 0;
+ if (i <= 5) {
+ dec->fatal_error |=
+ DECODER_FATAL_ERROR_NO_MEM;
+ }
+ break;
+ }
+ dec->m_BUF[i].start_adr = dec->m_BUF[i].alloc_addr;
+ } else {
+ dec->m_BUF[i].cma_page_count = 0;
+ dec->m_BUF[i].alloc_addr = 0;
+ dec->m_BUF[i].start_adr =
+ dec->mc_buf->buf_start + i * buf_size;
+ }
+ dec->m_BUF[i].size = buf_size;
+ dec->m_BUF[i].free_start_adr = dec->m_BUF[i].start_adr;
+
+ if (((dec->m_BUF[i].start_adr + buf_size) > mc_buffer_end)
+ && (dec->m_BUF[i].alloc_addr == 0)) {
+ if (debug) {
+ avs2_print(dec, 0,
+ "Max mc buffer or mpred_mv buffer is used\n");
+ }
+ break;
+ }
+
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "Buffer %d: start_adr %p size %x\n", i,
+ (void *)dec->m_BUF[i].start_adr,
+ dec->m_BUF[i].size);
+ }
+ dec->buf_num = i;
+}
+#endif
+
+static u32 calc_buffer_u_v_h_size(u32 w, u32 h, u32 ratio, u32 lcu_size)
+{
+ int pic_width_dw = w / ratio;
+ int pic_height_dw = h / ratio;
+
+ int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
+ (pic_width_dw / lcu_size + 1) : (pic_width_dw / lcu_size);
+ int pic_height_lcu_dw = (pic_height_dw % lcu_size) ?
+ (pic_height_dw / lcu_size + 1) : (pic_height_dw / lcu_size);
+
+ int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
+ int mc_buffer_size_u_v = (lcu_total_dw * lcu_size * lcu_size) >> 1; // div 2
+
+ return ((mc_buffer_size_u_v + 0xffff) >> 16);
+}
+
+static int config_pic(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic)
+{
+ int ret = -1;
+ int i;
+ int pic_width = dec->init_pic_w;
+ int pic_height = dec->init_pic_h;
+
+ int32_t lcu_size = dec->avs2_dec.lcu_size;
+ int pic_width_64 = (pic_width + 63) & (~0x3f);
+ int pic_height_32 = (pic_height + 31) & (~0x1f);
+ int pic_width_lcu = (pic_width_64 % lcu_size) ?
+ pic_width_64 / lcu_size + 1
+ : pic_width_64 / lcu_size;
+ int pic_height_lcu = (pic_height_32 % lcu_size) ?
+ pic_height_32 / lcu_size + 1
+ : pic_height_32 / lcu_size;
+ int lcu_total = pic_width_lcu * pic_height_lcu;
+ int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+
+ u32 y_adr = 0;
+ int buf_size = 0;
+
+ int losless_comp_header_size =
+ compute_losless_comp_header_size(
+ dec, pic_width, pic_height);
+ int losless_comp_body_size = compute_losless_comp_body_size(
+ dec, pic_width,
+ pic_height, is_bit_depth_10);
+ int mc_buffer_size = losless_comp_header_size + losless_comp_body_size;
+ int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16;
+ //int mc_buffer_size_u_v = 0;
+ int mc_buffer_size_u_v_h = 0;
+ int dw_uv_size;
+ int dw_mode = get_double_write_mode_init(dec);
+#ifdef OW_TRIPLE_WRITE
+ int tw_mode = get_triple_write_mode(dec);
+#endif
+
+ if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+ pic_height, get_double_write_ratio(dw_mode & 0xf), lcu_size);
+ /*64k alignment*/
+ buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
+ buf_size = ((buf_size + 0xffff) >> 16) << 16;
+#ifdef P010_ENABLE
+ if (is_dw_p010(dec)) { //double size mem for p010 mode
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ }
+#endif
+ }
+#ifdef OW_TRIPLE_WRITE
+ if (tw_mode) {
+ mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+ pic_height, get_double_write_ratio(tw_mode), lcu_size);
+
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ if (is_tw_p010(dec)) {
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ }
+ }
+#endif
+
+ if (mc_buffer_size & 0xffff) /*64k alignment*/
+ mc_buffer_size_h += 1;
+
+#ifdef AVS2_10B_MMU
+ if (dec->mmu_enable) {
+ pic->header_adr = decoder_bmmu_box_get_phy_addr(
+ dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
+
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ pic->dw_header_adr = pic->header_adr
+ + get_compress_header_size(dec);
+ }
+#endif
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "buf_size %d, MMU header_adr %d: %ld\n",
+ buf_size, pic->index, pic->header_adr);
+ }
+#else
+ if ((dw_mode & 0x10) == 0)
+ buf_size += (mc_buffer_size_h << 16);
+#endif
+
+ i = pic->index;
+
+#ifndef AVS2_10B_MMU
+ if (debug) {
+ pr_err("start %x .size=%d\n",
+ dec->mc_buf_spec.buf_start + i * buf_size, buf_size);
+ }
+ for (i = 0; i < dec->buf_num; i++) {
+ y_adr = ((dec->m_BUF[i].free_start_adr + 0xffff) >> 16) << 16;
+ /*64k alignment*/
+ if ((y_adr+buf_size) <= (dec->m_BUF[i].start_adr+
+ dec->m_BUF[i].size)) {
+ dec->m_BUF[i].free_start_adr = y_adr + buf_size;
+ break;
+ }
+ }
+ if (i < dec->buf_num)
+#else
+ if (buf_size > 0 && pic->cma_alloc_addr == 0) {
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ VF_BUFFER_IDX(i),
+ buf_size, DRIVER_NAME,
+ &pic->cma_alloc_addr);
+
+ if (ret < 0) {
+ avs2_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
+ VF_BUFFER_IDX(i),
+ buf_size);
+ return ret;
+ }
+
+ if (pic->cma_alloc_addr) {
+ y_adr = pic->cma_alloc_addr;
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(y_adr, 0, buf_size);
+ } else {
+ avs2_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
+ VF_BUFFER_IDX(i),
+ buf_size);
+ return -1;
+ }
+ }
+#endif
+ {
+ /*ensure get_pic_by_POC()
+ not get the buffer not decoded*/
+ dw_uv_size = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+
+ pic->BUF_index = i;
+ pic->lcu_total = lcu_total;
+
+ pic->comp_body_size = losless_comp_body_size;
+ pic->buf_size = buf_size;
+ pic->mc_canvas_y = pic->index;
+ pic->mc_canvas_u_v = pic->index;
+#ifndef AVS2_10B_MMU
+ pic->mc_y_adr = y_adr;
+ if (dw_mode & 0x10) {
+ pic->mc_u_v_adr = y_adr + (dw_uv_size << 1);
+
+ pic->mc_canvas_y = (pic->index << 1);
+ pic->mc_canvas_u_v = (pic->index << 1) + 1;
+
+ pic->dw_y_adr = y_adr;
+ pic->dw_u_v_adr = pic->mc_u_v_adr;
+ } else
+#endif
+ if (dw_mode) {
+#ifdef AVS2_10B_MMU
+ pic->dw_y_adr = y_adr;
+ pic->dw_u_v_adr = pic->dw_y_adr + (dw_uv_size << 1);
+ pic->mc_y_adr = pic->dw_y_adr;
+ pic->mc_u_v_adr = pic->dw_u_v_adr;
+#else
+ pic->dw_y_adr = y_adr + (mc_buffer_size_h << 16);
+ pic->dw_u_v_adr = pic->dw_y_adr + (dw_uv_size << 1);
+#endif
+ }
+ if (tw_mode) {
+ if (dw_mode) {
+ pic->tw_y_adr = pic->dw_u_v_adr + dw_uv_size; //base dw buf addr
+ } else {
+ pic->tw_y_adr = y_adr; //base no dw buf addr
+ }
+ pic->tw_u_v_adr = pic->tw_y_adr + (mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1));
+ }
+
+#ifdef MV_USE_FIXED_BUF
+ pic->mpred_mv_wr_start_addr = dec->work_space_buf->mpred_mv.buf_start +
+ pic->index * (dec->work_space_buf->mpred_mv.buf_size / FRAME_BUFFERS);
+ if (pic->mpred_mv_wr_start_addr >
+ (dec->work_space_buf->mpred_mv.buf_start
+ + dec->work_space_buf->mpred_mv.buf_size)) {
+ avs2_print(dec, 0, "err: fixed mv buf out of size, 0x0%x\n",
+ pic->mpred_mv_wr_start_addr);
+ pic->mpred_mv_wr_start_addr = dec->work_space_buf->mpred_mv.buf_start;
+ }
+#endif
+ if (debug) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s index %d BUF_index %d mc_y_adr %x ",
+ __func__, pic->index,
+ pic->BUF_index,
+ pic->mc_y_adr);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "comp_body_size %x comp_buf_size %x ",
+ pic->comp_body_size,
+ pic->buf_size);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "mpred_mv_wr_start_adr %d ",
+ pic->mpred_mv_wr_start_addr);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "dw_y_adr %d, pic->dw_u_v_adr =%d ",
+ pic->dw_y_adr,
+ pic->dw_u_v_adr);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "tw y_addr %x, uv_addr %x\n",
+ pic->tw_y_adr, pic->tw_u_v_adr);
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static void init_pic_list(struct AVS2Decoder_s *dec)
+{
+ int i;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+#ifdef AVS2_10B_MMU
+ if (dec->mmu_enable) {
+ for (i = 0; i < dec->used_buf_num; i++) {
+ unsigned long buf_addr;
+ u32 header_size = get_compress_header_size(dec);
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable)
+ header_size <<= 1;
+#endif
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ HEADER_BUFFER_IDX(i), header_size,
+ DRIVER_HEADER_NAME,
+ &buf_addr) < 0) {
+ avs2_print(dec, 0,
+ "%s malloc compress header failed %d\n",
+ DRIVER_HEADER_NAME, i);
+ dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+ return;
+ }
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(buf_addr, 0, header_size);
+ }
+ }
+#endif
+ dec->frame_height = avs2_dec->img.height;
+ dec->frame_width = avs2_dec->img.width;
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+ avs2_dec->init_fref[i] = pic;
+ pic->index = i;
+ pic->BUF_index = -1;
+ pic->mv_buf_index = -1;
+ if (config_pic(dec, pic) < 0) {
+ if (debug)
+ avs2_print(dec, 0, "Config_pic %d fail\n", pic->index);
+ pic->index = -1;
+ break;
+ }
+ pic->pic_w = avs2_dec->img.width;
+ pic->pic_h = avs2_dec->img.height;
+ }
+ for (; i < dec->used_buf_num; i++) {
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+ pic->index = -1;
+ pic->BUF_index = -1;
+ pic->mv_buf_index = -1;
+ }
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s ok, used_buf_num = %d\n",
+ __func__, dec->used_buf_num);
+ dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATE_DONE;
+}
+
+static void init_pic_list_hw(struct AVS2Decoder_s *dec)
+{
+ int i;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+ if (pic->index < 0)
+ break;
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+
+#ifdef DUAL_CORE_64
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2)
+ WRITE_VREG(HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+ else
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+#endif
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+#ifdef DUAL_CORE_64
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+/*DUAL_CORE_64*/
+#endif
+ }
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#endif
+ /*Zero out canvas registers in IPP -- avoid simulation X*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 1);
+ for (i = 0; i < 32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+ }
+}
+
+static void dump_pic_list(struct AVS2Decoder_s *dec)
+{
+ int ii;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
+ avs2_print(dec, 0,
+ "fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d) backend_ref %d, back done %d, time %lld\n",
+ ii, avs2_dec->fref[ii]->index,
+ avs2_dec->fref[ii]->decode_idx,
+ avs2_dec->fref[ii]->mv_buf_index,
+ avs2_dec->fref[ii]->imgcoi_ref,
+ avs2_dec->fref[ii]->imgtr_fwRefDistance,
+ avs2_dec->fref[ii]->referred_by_others,
+ avs2_dec->fref[ii]->to_prepare_disp,
+ avs2_dec->fref[ii]->is_output,
+ avs2_dec->fref[ii]->bg_flag,
+ avs2_dec->fref[ii]->vf_ref,
+ avs2_dec->fref[ii]->error_mark,
+ avs2_dec->fref[ii]->decoded_lcu,
+ avs2_dec->fref[ii]->ref_poc[0],
+ avs2_dec->fref[ii]->ref_poc[1],
+ avs2_dec->fref[ii]->ref_poc[2],
+ avs2_dec->fref[ii]->ref_poc[3],
+ avs2_dec->fref[ii]->ref_poc[4],
+ avs2_dec->fref[ii]->ref_poc[5],
+ avs2_dec->fref[ii]->ref_poc[6],
+ avs2_dec->fref[ii]->backend_ref,
+ avs2_dec->fref[ii]->back_done_mark,
+ avs2_dec->fref[ii]->time
+ );
+ }
+ return;
+}
+
+static int config_mc_buffer(struct AVS2Decoder_s *dec)
+{
+ int32_t i;
+#ifdef NEW_FRONT_BACK_CODE
+ int32_t j;
+#endif
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "Entered config_mc_buffer....\n");
+ if (avs2_dec->f_bg != NULL) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+ avs2_dec->f_bg->mc_canvas_y, avs2_dec->f_bg->mc_canvas_u_v);
+
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (15 << 8) | (0<<1) | 1); /* L0:BG*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs2_dec->f_bg->mc_canvas_u_v << 16) |
+ (avs2_dec->f_bg->mc_canvas_u_v << 8) |
+ avs2_dec->f_bg->mc_canvas_y);
+
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (31 << 8) | (0<<1) | 1); /* L1:BG*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs2_dec->f_bg->mc_canvas_u_v << 16) |
+ (avs2_dec->f_bg->mc_canvas_u_v << 8) |
+ avs2_dec->f_bg->mc_canvas_y);
+
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ for (j = 0; j < MAXREF; j++) {
+ if (avs2_dec->f_bg == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = avs2_dec->f_bg;
+ break;
+ }
+ }
+ }
+#endif
+ }
+
+ if (avs2_dec->img.type == I_IMG)
+ return 0;
+
+ if (avs2_dec->img.type == P_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for P_IMG, img type %d\n",
+ avs2_dec->img.type);
+ /*refer to prepare_RefInfo()*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v << 16) |
+ (pic->mc_canvas_u_v << 8) |
+ pic->mc_canvas_y);
+
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
+ i, pic->mc_canvas_u_v, pic->mc_canvas_y,
+ pic->error_mark);
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
+ } else if (avs2_dec->img.type == F_IMG) {
+ int valid_ref_cnt;
+ valid_ref_cnt = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for F_IMG, img type %d\n",
+ avs2_dec->img.type);
+ /*refer to prepare_RefInfo()*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ if (pic->referred_by_others != 1)
+ continue;
+ valid_ref_cnt++;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v << 16) |
+ (pic->mc_canvas_u_v << 8) |
+ pic->mc_canvas_y);
+
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
+ i, pic->mc_canvas_u_v, pic->mc_canvas_y,
+ pic->error_mark);
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ if (valid_ref_cnt != avs2_dec->img.num_of_references)
+ cur_pic->error_mark = 1;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (16 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs2_dec->img.num_of_references; i++) {
+ pic = avs2_dec->fref[i];
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v << 16) |
+ (pic->mc_canvas_u_v << 8) |
+ pic->mc_canvas_y);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x\n",
+ i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ } else {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for B_IMG\n");
+ /*refer to prepare_RefInfo()*/
+ pic = avs2_dec->fref[1];
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0<<1) | 1);
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v << 16) |
+ (pic->mc_canvas_u_v << 8) |
+ pic->mc_canvas_y);
+
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
+ 1, pic->mc_canvas_u_v, pic->mc_canvas_y,
+ pic->error_mark);
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+ }
+#endif
+
+ pic = avs2_dec->fref[0];
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (16 << 8) | (0<<1) | 1);
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16) |
+ (pic->mc_canvas_u_v<<8) |
+ pic->mc_canvas_y);
+
+ if (pic->error_mark)
+ cur_pic->error_mark = 1;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
+ 0, pic->mc_canvas_u_v, pic->mc_canvas_y,
+ pic->error_mark);
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ for (j = 0; j < MAXREF; j++) {
+ if (pic == cur_pic->ref_pic[j])
+ break;
+ if (cur_pic->ref_pic[j] == NULL) {
+ cur_pic->ref_pic[j] = pic;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ return 0;
+}
+
+static void config_mcrcc_axi_hw(struct AVS2Decoder_s *dec)
+{
+ uint32_t rdata32;
+ uint32_t rdata32_2;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); /* reset mcrcc*/
+
+ if (avs2_dec->img.type == I_IMG) { /* I-PIC*/
+ /* remove reset -- disables clock */
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
+ return;
+ }
+
+ if ((avs2_dec->img.type == B_IMG) ||
+ (avs2_dec->img.type == F_IMG)) { /*B-PIC or F_PIC*/
+ /*Programme canvas0 */
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 0);
+ rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | (rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
+
+ /*Programme canvas1 */
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (16 << 8) | (1 << 1) | 0);
+ rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32_2 = rdata32_2 & 0xffff;
+ rdata32_2 = rdata32_2 | (rdata32_2 << 16);
+ if (rdata32 == rdata32_2) {
+ rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32_2 = rdata32_2 & 0xffff;
+ rdata32_2 = rdata32_2 | (rdata32_2 << 16);
+ }
+ WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32_2);
+ } else { /* P-PIC */
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (1 << 1) | 0);
+ rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | (rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
+
+ /*Programme canvas1*/
+ rdata32 =
+ READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | (rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
+ }
+ /*enable mcrcc progressive-mode */
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);
+ return;
+}
+
+static void config_mpred_hw(struct AVS2Decoder_s *dec)
+{
+ uint32_t data32;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+ struct avs2_frame_s *col_pic = avs2_dec->fref[0];
+ int32_t mpred_mv_rd_start_addr;
+ //int32_t mpred_curr_lcu_x;
+ //int32_t mpred_curr_lcu_y;
+ int32_t mpred_mv_rd_end_addr;
+ int32_t above_en;
+ int32_t mv_wr_en;
+ int32_t mv_rd_en;
+ int32_t col_isIntra;
+ int mv_mem_unit;
+ if (avs2_dec->img.type != I_IMG) {
+ above_en = 1;
+ mv_wr_en = 1;
+ mv_rd_en = 1;
+ col_isIntra = 0;
+ } else {
+ above_en = 1;
+ mv_wr_en = 1;
+ mv_rd_en = 0;
+ col_isIntra = 0;
+ }
+
+ mpred_mv_rd_start_addr = col_pic->mpred_mv_wr_start_addr;
+ //data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
+ //mpred_curr_lcu_x = data32 & 0xffff;
+ //mpred_curr_lcu_y = (data32 >> 16) & 0xffff;
+
+ mv_mem_unit = avs2_dec->lcu_size_log2 == 6 ?
+ 0x200 : (avs2_dec->lcu_size_log2 == 5 ?
+ 0x80 : 0x20);
+
+ mpred_mv_rd_end_addr = mpred_mv_rd_start_addr +
+ ((avs2_dec->lcu_x_num * avs2_dec->lcu_y_num) * mv_mem_unit);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "cur pic index %d col pic index %d\n",
+ cur_pic->index, col_pic->index);
+
+ WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
+ cur_pic->mpred_mv_wr_start_addr);
+ WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
+ col_pic->mpred_mv_wr_start_addr);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[MPRED CO_MV] write 0x%x read 0x%x\n",
+ cur_pic->mpred_mv_wr_start_addr,
+ col_pic->mpred_mv_wr_start_addr);
+
+ data32 =
+ ((avs2_dec->bk_img_is_top_field) << 13) |
+ ((avs2_dec->hd.background_picture_enable & 1) << 12) |
+ ((avs2_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+ ((avs2_dec->hd.b_pmvr_enabled & 1) << 6) |
+ ((avs2_dec->img.is_top_field & 1) << 5) |
+ ((avs2_dec->img.is_field_sequence & 1) << 4) |
+ ((avs2_dec->img.typeb & 7) << 1) |
+ (avs2_dec->hd.background_reference_enable & 0x1);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n",
+ data32, avs2_dec->hd.curr_RPS.num_of_ref);
+ WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s: dis %d %d %d %d %d %d %d fref0_ref_poc %d %d %d %d %d %d %d\n",
+ __func__,
+ avs2_dec->fref[0]->imgtr_fwRefDistance,
+ avs2_dec->fref[1]->imgtr_fwRefDistance,
+ avs2_dec->fref[2]->imgtr_fwRefDistance,
+ avs2_dec->fref[3]->imgtr_fwRefDistance,
+ avs2_dec->fref[4]->imgtr_fwRefDistance,
+ avs2_dec->fref[5]->imgtr_fwRefDistance,
+ avs2_dec->fref[6]->imgtr_fwRefDistance,
+ avs2_dec->fref[0]->ref_poc[0],
+ avs2_dec->fref[0]->ref_poc[1],
+ avs2_dec->fref[0]->ref_poc[2],
+ avs2_dec->fref[0]->ref_poc[3],
+ avs2_dec->fref[0]->ref_poc[4],
+ avs2_dec->fref[0]->ref_poc[5],
+ avs2_dec->fref[0]->ref_poc[6]);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "pic_distance %d, imgtr_next_P %d\n",
+ avs2_dec->img.pic_distance, avs2_dec->img.imgtr_next_P);
+
+ WRITE_VREG(HEVC_MPRED_CUR_POC, avs2_dec->img.pic_distance);
+ WRITE_VREG(HEVC_MPRED_COL_POC, avs2_dec->img.imgtr_next_P);
+
+ /*below MPRED Ref_POC_xx_Lx registers
+ must follow Ref_POC_xx_L0 ->
+ Ref_POC_xx_L1 in pair write order!!!*/
+ WRITE_VREG(HEVC_MPRED_L0_REF00_POC,
+ avs2_dec->fref[0]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF00_POC,
+ avs2_dec->fref[0]->ref_poc[0]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF01_POC,
+ avs2_dec->fref[1]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF01_POC,
+ avs2_dec->fref[0]->ref_poc[1]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF02_POC,
+ avs2_dec->fref[2]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF02_POC,
+ avs2_dec->fref[0]->ref_poc[2]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF03_POC,
+ avs2_dec->fref[3]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF03_POC,
+ avs2_dec->fref[0]->ref_poc[3]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF04_POC,
+ avs2_dec->fref[4]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF04_POC,
+ avs2_dec->fref[0]->ref_poc[4]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF05_POC,
+ avs2_dec->fref[5]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF05_POC,
+ avs2_dec->fref[0]->ref_poc[5]);
+
+ WRITE_VREG(HEVC_MPRED_L0_REF06_POC,
+ avs2_dec->fref[6]->imgtr_fwRefDistance);
+ WRITE_VREG(HEVC_MPRED_L1_REF06_POC,
+ avs2_dec->fref[0]->ref_poc[6]);
+
+ WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,
+ mpred_mv_rd_end_addr);
+}
+
+static void config_dblk_hw(struct AVS2Decoder_s *dec)
+{
+ /*
+ * Picture level de-block parameter configuration here
+ */
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ union param_u *rpm_param = &avs2_dec->param;
+ uint32_t data32;
+
+ data32 = READ_VREG(HEVC_DBLK_CFG1);
+ data32 = (((data32 >> 20) & 0xfff) << 20) |
+ (((avs2_dec->input.sample_bit_depth == 10)
+ ? 0xa : 0x0) << 16) | /*[16 +: 4]: {luma_bd[1:0],
+ chroma_bd[1:0]}*/
+ (((data32 >> 2) & 0x3fff) << 2) |
+ (((rpm_param->p.lcu_size == 6)
+ ? 0 : (rpm_param->p.lcu_size == 5)
+ ? 1 : 2) << 0);/*[ 0 +: 2]: lcu_size*/
+ WRITE_VREG(HEVC_DBLK_CFG1, data32);
+
+ data32 = (avs2_dec->img.height << 16) |
+ avs2_dec->img.width;
+ WRITE_VREG(HEVC_DBLK_CFG2, data32);
+ /*
+ [27 +: 1]: cross_slice_loopfilter_enable_flag
+ [26 +: 1]: loop_filter_disable
+ [25 +: 1]: useNSQT
+ [22 +: 3]: imgtype
+ [17 +: 5]: alpha_c_offset (-8~8)
+ [12 +: 5]: beta_offset (-8~8)
+ [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+ [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+ */
+ data32 = ((avs2_dec->input.crossSliceLoopFilter & 0x1) << 27) |
+ ((rpm_param->p.loop_filter_disable & 0x1) << 26) |
+ ((avs2_dec->input.useNSQT & 0x1) << 25) |
+ ((avs2_dec->img.type & 0x7) << 22) |
+ ((rpm_param->p.alpha_c_offset & 0x1f) << 17) |
+ ((rpm_param->p.beta_offset & 0x1f) << 12) |
+ ((rpm_param->p.chroma_quant_param_delta_cb & 0x3f) << 6) |
+ ((rpm_param->p.chroma_quant_param_delta_cr & 0x3f) << 0);
+
+ WRITE_VREG(HEVC_DBLK_CFG9, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d),lcuSize(%d),NSQT(%d)\n",
+ avs2_dec->input.crossSliceLoopFilter,
+ rpm_param->p.loop_filter_disable,
+ avs2_dec->input.sample_bit_depth,
+ avs2_dec->lcu_size,
+ avs2_dec->input.useNSQT);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: alphaCOffset(%d),betaOffset(%d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+ rpm_param->p.alpha_c_offset,
+ rpm_param->p.beta_offset,
+ rpm_param->p.chroma_quant_param_delta_cb,
+ rpm_param->p.chroma_quant_param_delta_cr);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgDBLK: .done.\n");
+}
+
+static void config_sao_hw(struct AVS2Decoder_s *dec)
+{
+ uint32_t data32;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+ int lcu_size = 64;
+ int mc_buffer_size_u_v = cur_pic->lcu_total * lcu_size*lcu_size/2;
+ int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
+ int dw_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+ int tw_mode = get_triple_write_mode(dec);
+#endif
+
+ data32 = READ_VREG(HEVC_SAO_CTRL0);
+ data32 &= (~0xf);
+ data32 |= avs2_dec->lcu_size_log2;
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "%s, lcu_size_log2 = %d, config HEVC_SAO_CTRL0 0x%x\n",
+ __func__,
+ avs2_dec->lcu_size_log2,
+ data32);
+
+ WRITE_VREG(HEVC_SAO_CTRL0, data32);
+
+#ifndef AVS2_10B_MMU
+ if ((dw_mode & 0x10) == 0)
+ WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr);
+#endif
+ if ((dw_mode & 0x20) == 0) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
+ WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_WPTR, cur_pic->dw_u_v_adr);
+ } else {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+#ifdef OW_TRIPLE_WRITE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+ if (tw_mode) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR3, cur_pic->tw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR3, cur_pic->tw_u_v_adr);
+ } else {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR3, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR3, 0xffffffff);
+ }
+ }
+#endif
+
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, cur_pic->dw_header_adr);
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
+ }
+#endif
+
+ data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec) + 1);
+ WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
+ data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+ WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
+
+ if (tw_mode) {
+ data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1);
+ WRITE_VREG(HEVC_SAO_Y_LENGTH3, data32);
+ data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec));
+ WRITE_VREG(HEVC_SAO_C_LENGTH3, data32);
+
+ if (debug & AVS2_DBG_REG) {
+ avs2_print(dec, 0, "triple write SAO_Y_ADDR3 %x, SAO_Y_LENGTH3 %x, SAO_C_ADDR3 %x, SAO_C_LENGTH3 %x\n",
+ READ_VREG(HEVC_SAO_Y_START_ADDR3), READ_VREG(HEVC_SAO_Y_LENGTH3),
+ READ_VREG(HEVC_SAO_C_START_ADDR3), READ_VREG(HEVC_SAO_C_LENGTH3));
+ }
+ }
+
+#ifdef AVS2_10B_NV21
+#ifdef DOS_PROJECT
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
+ data32 |= (MEM_MAP_MODE << 12);
+ data32 &= (~0x3);
+ data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
+
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ data32 &= (~(3 << 14));
+ data32 |= (2 << 14);
+
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+ /*[23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl
+ [17:16] dw_h0_ctrl*/
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ data32 &= ~(0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ ata32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
+ data32 |= (MEM_MAP_MODE << 4);
+ WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#else
+ /*m8baby test1902*/
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
+ data32 |= (MEM_MAP_MODE << 12);
+ data32 &= (~0xff0);
+ /*data32 |= 0x670;*/ /*Big-Endian per 64-bit*/
+ data32 |= 0x880; /*.Big-Endian per 64-bit */
+ data32 &= (~0x3);
+ data32 |= 0x1; /*[1]:dw_disable [0]:cm_disable*/
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+ /* [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl
+ [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl*/
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /* set them all 0 for H265_NV21 (no down-scale)*/
+ data32 &= ~(0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+ /*
+ * [3:0] little_endian
+ * [5:4] address_format 00:linear 01:32x32 10:64x32
+ * [7:6] reserved
+ * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
+ * [11:10] reserved
+ * [12] CbCr_byte_swap
+ * [31:13] reserved
+ */
+
+ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
+ data32 |= (MEM_MAP_MODE << 4);
+ data32 &= (~0xF);
+ data32 |= 0x8; /*Big-Endian per 64-bit*/
+
+ data32 &= (~(3 << 8));
+ data32 |= (2 << 8);
+ WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+#else
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~(3 << 14));
+ data32 |= (2 << 14); /* line align with 64*/
+ data32 &= (~0x3000);
+ data32 |= (MEM_MAP_MODE << 12); /* [13:12] axi_aformat, 0-Linear,
+ 1-32x32, 2-64x32 */
+ data32 &= (~0xff0);
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable == 0)
+ data32 |= ((dec->endian >> 8) & 0xfff);
+#else
+ data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+
+ if (dw_mode == 0)
+ data32 |= 0x2; /*disable double write*/
+ else if (dw_mode & 0x10)
+ data32 |= 0x1; /*disable cm*/
+
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+ if (dw_mode & 0x10) {
+ /* [23:22] dw_v1_ctrl
+ [21:20] dw_v0_ctrl
+ [19:18] dw_h1_ctrl
+ [17:16] dw_h0_ctrl
+ */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ data32 &= ~(0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ } else {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
+ WRITE_VREG(HEVC_SAO_CTRL26, 0);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 &= (~(0xff << 16));
+ if ((dw_mode & 0xf) == 8 || (dw_mode & 0xf) == 9) {
+ data32 |= (0xff<<16);
+ WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
+ } else if ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3)
+ data32 |= (0xff<<16);
+ else if ((dw_mode & 0xf) == 4)
+ data32 |= (0x33<<16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+#ifdef P010_ENABLE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+ data32 = READ_VREG(HEVC_SAO_CTRL3);
+ if (is_dw_p010(dec)) {
+ data32 |= (1 << 1);
+ WRITE_VREG(HEVC_SAO_CTRL3, data32);
+ } else {
+ data32 &= ~(1 << 1);
+ WRITE_VREG(HEVC_SAO_CTRL3, data32);
+ }
+ }
+#endif
+#ifdef OW_TRIPLE_WRITE
+ if (tw_mode) {
+ data32 = READ_VREG(HEVC_SAO_CTRL31);
+ data32 &= ~0xfff;
+ if ((tw_mode == 2) || (tw_mode == 3)) {
+ data32 |= ((0xf << 6) | 0xf); //1:4
+ } else if ((tw_mode == 4) || (tw_mode == 5)) {
+ data32 |= ((0x3 << 6) | 0x3); //1:2
+ } else if ((tw_mode == 8) || (tw_mode == 9)) {
+ data32 |= ((0x3f << 6) | 0x3f);
+ }
+ WRITE_VREG(HEVC_SAO_CTRL31, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL32);
+ data32 &= (~0xfff); /* clr endian, blkmod and align */
+ data32 |= ((dec->endian >> 12) & 0xff);
+ data32 |= ((mem_map_mode & 0x3) << 8);
+ /* Linear_LineAlignment 00:16byte 01:32byte 10:64byte */
+ data32 |= (2 << 10);
+ WRITE_VREG(HEVC_SAO_CTRL32, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL3);
+ data32 |= (1 << 2); /* enable triple write */
+#ifdef P010_ENABLE
+ if (is_tw_p010(dec)) {
+ data32 |= (1 << 3); /* enable triple write p010 */
+ } else {
+ data32 &= ~(1 << 3);
+ }
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL3, data32);
+
+ if (debug & AVS2_DBG_REG) {
+ pr_info("%s, HEVC_SAO_CTRL3 %x, HEVC_SAO_CTRL31 %x, HEVC_SAO_CTRL32 %x\n",
+ __func__, READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL31), READ_VREG(HEVC_SAO_CTRL32));
+ }
+ }
+#endif
+
+ /*
+ * [3:0] little_endian
+ * [5:4] address_format 00:linear 01:32x32 10:64x32
+ * [7:6] reserved
+ * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
+ * [11:10] reserved
+ * [12] CbCr_byte_swap
+ * [31:13] reserved
+ */
+ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
+ data32 |= (mem_map_mode << 4);
+ data32 &= (~0xF);
+ data32 |= (dec->endian & 0xf); /* valid only when double write only */
+ /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
+ data32 &= (~(3 << 8));
+ data32 |= (2 << 8); /* line align with 64 for dw only */
+ WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+#ifndef AVS2_10B_NV21
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ struct BuffInfo_s *buf_spec = NULL;
+ buf_spec = &dec->work_space_buf_store;
+ WRITE_VREG(HEVC_DW_VH0_ADDDR, buf_spec->mmu_vbh_dw.buf_start + (2 * DW_VBH_BUF_SIZE(buf_spec)));
+ WRITE_VREG(HEVC_DW_VH1_ADDDR, buf_spec->mmu_vbh_dw.buf_start + (3 * DW_VBH_BUF_SIZE(buf_spec)));
+ }
+#endif
+#endif
+}
+
+static void reconstructCoefficients(struct AVS2Decoder_s *dec,
+ struct ALFParam_s *alfParam)
+{
+ int32_t g, sum, i, coeffPred;
+ for (g = 0; g < alfParam->filters_per_group; g++) {
+ sum = 0;
+ for (i = 0; i < alfParam->num_coeff - 1; i++) {
+ sum += (2 * alfParam->coeffmulti[g][i]);
+ dec->m_filterCoeffSym[g][i] = alfParam->coeffmulti[g][i];
+ }
+ coeffPred = (1 << ALF_NUM_BIT_SHIFT) - sum;
+ dec->m_filterCoeffSym[g][alfParam->num_coeff - 1] = coeffPred +
+ alfParam->coeffmulti[g][alfParam->num_coeff - 1];
+ }
+}
+
+static void reconstructCoefInfo(struct AVS2Decoder_s *dec,
+ int32_t compIdx, struct ALFParam_s *alfParam)
+{
+ int32_t i;
+ if (compIdx == ALF_Y) {
+ if (alfParam->filters_per_group > 1) {
+ for (i = 1; i < NO_VAR_BINS; ++i) {
+ if (alfParam->filterPattern[i])
+ dec->m_varIndTab[i] =
+ dec->m_varIndTab[i - 1] + 1;
+ else
+ dec->m_varIndTab[i] =
+ dec->m_varIndTab[i - 1];
+ }
+ }
+ }
+ reconstructCoefficients(dec, alfParam);
+}
+
+static void config_alf_hw(struct AVS2Decoder_s *dec)
+{
+ /*
+ * Picture level ALF parameter configuration here
+ */
+ uint32_t data32;
+ int32_t i, j;
+ int32_t m_filters_per_group;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct ALFParam_s *m_alfPictureParam_y =
+ &avs2_dec->m_alfPictureParam[0];
+ struct ALFParam_s *m_alfPictureParam_cb =
+ &avs2_dec->m_alfPictureParam[1];
+ struct ALFParam_s *m_alfPictureParam_cr =
+ &avs2_dec->m_alfPictureParam[2];
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filterPattern[0]=0x%x,[15]=0x%x\n",
+ m_alfPictureParam_y->componentID,
+ m_alfPictureParam_y->alf_flag,
+ m_alfPictureParam_y->filters_per_group,
+ m_alfPictureParam_y->filterPattern[0],
+ m_alfPictureParam_y->filterPattern[15]);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[t]alfy,num_coeff(%d),coeffmulti[0][0]=0x%x,[0][1]=0x%x,[1][0]=0x%x,[1][1]=0x%x\n",
+ m_alfPictureParam_y->num_coeff,
+ m_alfPictureParam_y->coeffmulti[0][0],
+ m_alfPictureParam_y->coeffmulti[0][1],
+ m_alfPictureParam_y->coeffmulti[1][0],
+ m_alfPictureParam_y->coeffmulti[1][1]);
+
+ /*Cr*/
+ for (i = 0; i < 16; i++)
+ dec->m_varIndTab[i] = 0;
+ for (j = 0; j < 16; j++)
+ for (i = 0; i < 9; i++)
+ dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 2, m_alfPictureParam_cr);
+ data32 =
+ ((dec->m_filterCoeffSym[0][4] & 0xf) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 =
+ ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4] >> 4) & 0x7) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cr(%d), alf_cr_coef(%d %d %d %d %d %d %d %d %d)\n",
+ m_alfPictureParam_cr->alf_flag,
+ dec->m_filterCoeffSym[0][0],
+ dec->m_filterCoeffSym[0][1],
+ dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],
+ dec->m_filterCoeffSym[0][4],
+ dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],
+ dec->m_filterCoeffSym[0][7],
+ dec->m_filterCoeffSym[0][8]);
+
+ /* Cb*/
+ for (j = 0; j < 16; j++)
+ for (i = 0; i < 9; i++)
+ dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 1, m_alfPictureParam_cb);
+ data32 =
+ ((dec->m_filterCoeffSym[0][4] & 0xf) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 =
+ ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4] >> 4) & 0x7) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cb(%d), alf_cb_coef(%d %d %d %d %d %d %d %d %d)\n",
+ m_alfPictureParam_cb->alf_flag,
+ dec->m_filterCoeffSym[0][0],
+ dec->m_filterCoeffSym[0][1],
+ dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],
+ dec->m_filterCoeffSym[0][4],
+ dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],
+ dec->m_filterCoeffSym[0][7],
+ dec->m_filterCoeffSym[0][8]);
+
+ /* Y*/
+ for (j = 0; j < 16; j++)
+ for (i = 0; i < 9; i++)
+ dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 0, m_alfPictureParam_y);
+ data32 =
+ ((dec->m_varIndTab[7] & 0xf) << 28) |
+ ((dec->m_varIndTab[6] & 0xf) << 24) |
+ ((dec->m_varIndTab[5] & 0xf) << 20) |
+ ((dec->m_varIndTab[4] & 0xf) << 16) |
+ ((dec->m_varIndTab[3] & 0xf) << 12) |
+ ((dec->m_varIndTab[2] & 0xf) << 8) |
+ ((dec->m_varIndTab[1] & 0xf) << 4) |
+ ((dec->m_varIndTab[0] & 0xf) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_varIndTab[15] & 0xf) << 28) |
+ ((dec->m_varIndTab[14] & 0xf) << 24) |
+ ((dec->m_varIndTab[13] & 0xf) << 20) |
+ ((dec->m_varIndTab[12] & 0xf) << 16) |
+ ((dec->m_varIndTab[11] & 0xf) << 12) |
+ ((dec->m_varIndTab[10] & 0xf) << 8) |
+ ((dec->m_varIndTab[9] & 0xf) << 4) |
+ ((dec->m_varIndTab[8] & 0xf) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_y(%d), alf_y_tab(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)\n",
+ m_alfPictureParam_y->alf_flag,
+ dec->m_varIndTab[0],
+ dec->m_varIndTab[1],
+ dec->m_varIndTab[2],
+ dec->m_varIndTab[3],
+ dec->m_varIndTab[4],
+ dec->m_varIndTab[5],
+ dec->m_varIndTab[6],
+ dec->m_varIndTab[7],
+ dec->m_varIndTab[8],
+ dec->m_varIndTab[9],
+ dec->m_varIndTab[10],
+ dec->m_varIndTab[11],
+ dec->m_varIndTab[12],
+ dec->m_varIndTab[13],
+ dec->m_varIndTab[14],
+ dec->m_varIndTab[15]);
+
+ m_filters_per_group =
+ (m_alfPictureParam_y->alf_flag == 0) ?
+ 1 : m_alfPictureParam_y->filters_per_group;
+ for (i = 0; i < m_filters_per_group; i++) {
+ data32 =
+ ((dec->m_filterCoeffSym[i][4] & 0xf) << 28) |
+ ((dec->m_filterCoeffSym[i][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[i][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[i][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[i][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 =
+ /*[31] last indication*/
+ ((i == m_filters_per_group-1) << 31) |
+ ((dec->m_filterCoeffSym[i][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[i][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[i][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[i][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[i][4] >> 4) & 0x7) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ }
+ if (debug & AVS2_DBG_BUFMGR_DETAIL) {
+ for (i = 0; i < m_filters_per_group; i++)
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "[c] alf_y_coef[%d](%d %d %d %d %d %d %d %d %d)\n",
+ i, dec->m_filterCoeffSym[i][0],
+ dec->m_filterCoeffSym[i][1],
+ dec->m_filterCoeffSym[i][2],
+ dec->m_filterCoeffSym[i][3],
+ dec->m_filterCoeffSym[i][4],
+ dec->m_filterCoeffSym[i][5],
+ dec->m_filterCoeffSym[i][6],
+ dec->m_filterCoeffSym[i][7],
+ dec->m_filterCoeffSym[i][8]);
+ }
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgALF .done.\n");
+}
+
+static void config_other_hw(struct AVS2Decoder_s *dec)
+{
+ uint32_t data32;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+ int bit_depth = cur_pic->bit_depth;
+ int losless_comp_header_size =
+ compute_losless_comp_header_size(
+ dec, cur_pic->pic_w,
+ cur_pic->pic_h);
+ int losless_comp_body_size =
+ compute_losless_comp_body_size(
+ dec, cur_pic->pic_w,
+ cur_pic->pic_h, (bit_depth == AVS2_BITS_10));
+ cur_pic->comp_body_size = losless_comp_body_size;
+
+#ifdef LOSLESS_COMPRESS_MODE
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ if (bit_depth == AVS2_BITS_10)
+ data32 &= ~(1 << 9);
+ else
+ data32 |= (1 << 9);
+
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+#ifdef AVS2_10B_MMU
+ /*bit[4] : paged_mem_mode*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
+#else
+ /*bit[3] smem mdoe*/
+ if (bit_depth == AVS2_BITS_10)
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0 << 3));
+ else
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1 << 3));
+#endif
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
+ /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
+ WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
+#else
+#ifdef P010_ENABLE
+ if (get_double_write_mode(dec) & 0x10) {
+ if (is_dw_p010(dec)) {
+ /* Enable P010 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+ (0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+ } else {
+ /* Enable NV21 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+ }
+ }
+#endif
+#endif
+}
+
+static u32 init_cuva_size;
+static int cuva_data_is_available(struct AVS2Decoder_s *dec, u32 reg_val)
+{
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s:reg_val: %u \n",
+ __func__, reg_val);
+ if (reg_val != 0 && reg_val != init_cuva_size)
+ return 1;
+ else
+ return 0;
+}
+
+void config_cuva_buf(struct AVS2Decoder_s *dec)
+{
+ WRITE_VREG(AVS2_CUVA_ADR, dec->cuva_phy_addr);
+ init_cuva_size = (dec->cuva_size >> 4) << 16;
+ WRITE_VREG(AVS2_CUVA_DATA_SIZE, init_cuva_size);
+}
+
+static void set_cuva_data(struct AVS2Decoder_s *dec)
+{
+ int i;
+ unsigned short *cuva_adr;
+ unsigned int size_reg_val =
+ READ_VREG(AVS2_CUVA_DATA_SIZE);
+ unsigned int cuva_count = 0;
+ int cuva_size = 0;
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+ if (pic == NULL || 0 == cuva_data_is_available(dec, size_reg_val)) {
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "%s:pic 0x%p or data not available\n",
+ __func__, pic);
+ return;
+ }
+
+ cuva_adr = (unsigned short *)dec->cuva_addr;
+ cuva_count = ((size_reg_val >> 16) << 4) >> 1;
+ cuva_size = dec->cuva_size;
+ dec->hdr_flag |= HDR_CUVA_MASK;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
+ __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
+ if (cuva_size > 0 && cuva_count > 0) {
+ int new_size;
+ char *new_buf;
+
+ new_size = cuva_size;
+ new_buf = vzalloc(new_size);
+ if (new_buf) {
+ unsigned char *p = new_buf;
+ int len = 0;
+ pic->cuva_data_buf = new_buf;
+
+ for (i = 0; i < cuva_count; i += 4) {
+ int j;
+
+ for (j = 0; j < 4; j++) {
+ unsigned short aa = cuva_adr[i + 3 - j];
+ *p = aa & 0xff;
+ p++;
+ len++;
+ }
+ }
+ if (len > 0) {
+ pic->cuva_data_size = len;
+ }
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s: cuva: (size %d)\n", __func__, pic->cuva_data_size);
+ if (get_dbg_flag(dec) & AVS2_DBG_HDR_INFO) {
+ for (i = 0; i < pic->cuva_data_size; i++) {
+ pr_info("%02x ", pic->cuva_data_buf[i]);
+ if (((i + 1) & 0xf) == 0)
+ pr_info("\n");
+ }
+ pr_info("\n");
+ }
+
+ } else {
+ avs2_print(dec, 0, "new buf alloc failed\n");
+ if (pic->cuva_data_buf)
+ vfree(pic->cuva_data_buf);
+ pic->cuva_data_buf = NULL;
+ pic->cuva_data_size = 0;
+ }
+ }
+}
+
+static void release_cuva_data(struct avs2_frame_s *pic)
+{
+ if (pic == NULL)
+ return;
+ if (pic->cuva_data_buf) {
+ vfree(pic->cuva_data_buf);
+ }
+ pic->cuva_data_buf = NULL;
+ pic->cuva_data_size = 0;
+}
+
+static void avs2_config_work_space_hw(struct AVS2Decoder_s *dec)
+{
+ struct BuffInfo_s *buf_spec = dec->work_space_buf;
+ int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+#ifdef LOSLESS_COMPRESS_MODE
+ int losless_comp_header_size =
+ compute_losless_comp_header_size(
+ dec, dec->init_pic_w,
+ dec->init_pic_h);
+ int losless_comp_body_size =
+ compute_losless_comp_body_size(dec,
+ dec->init_pic_w,
+ dec->init_pic_h, is_bit_depth_10);
+#endif
+#ifdef AVS2_10B_MMU
+ unsigned int data32;
+#endif
+ if (debug && dec->init_flag == 0)
+ avs2_print(dec, 0,
+ "%s %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
+ __func__,
+ buf_spec->ipp.buf_start,
+ buf_spec->start_adr,
+ buf_spec->short_term_rps.buf_start,
+ buf_spec->rcs.buf_start,
+ buf_spec->sps.buf_start,
+ buf_spec->pps.buf_start,
+ buf_spec->sao_up.buf_start,
+ buf_spec->swap_buf.buf_start,
+ buf_spec->swap_buf2.buf_start,
+ buf_spec->scalelut.buf_start,
+ buf_spec->dblk_para.buf_start,
+ buf_spec->dblk_data.buf_start,
+ buf_spec->dblk_data2.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start);
+ if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0)
+ WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+ WRITE_VREG(AVS2_ALF_SWAP_BUFFER, buf_spec->short_term_rps.buf_start);
+ WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
+ WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
+ WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(AVS2_MMU_MAP_BUFFER, dec->frame_mmu_map_phy_addr);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
+ }
+#endif
+ WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
+ WRITE_VREG(HEVC_DBLK_CFG3, 0x404010); //default value
+ else
+ WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); // make left storage 2 x 4k]
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "HEVC_DBLK_CFG3 = %x\n", READ_VREG(HEVC_DBLK_CFG3));
+ }
+
+ /* cfg_p_addr */
+ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
+ /* cfg_d_addr */
+ WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
+
+ WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
+
+#ifdef LOSLESS_COMPRESS_MODE
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 &= ~(1<<9);
+
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+#ifdef AVS2_10B_MMU
+ /*bit[4] : paged_mem_mode*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0);
+#else
+ /* bit[3] smem mode*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3));
+
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
+#endif
+/*8-bit mode */
+ WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
+#else
+#ifdef P010_ENABLE
+ if (get_double_write_mode(dec) & 0x10) {
+ if (is_dw_p010(dec)) {
+ /* Enable P010 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+ (0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+ } else {
+ /* Enable NV21 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+ }
+ }
+#endif
+#endif
+
+#ifdef AVS2_10B_MMU
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + VBH_BUF_SIZE(buf_spec));
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<10);
+#if 0
+ if (debug & AVS2_DBG_FORCE_UNCOMPRESS)
+ data32 |= 0x80;
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ u32 data_tmp;
+ data_tmp = READ_VREG(HEVC_SAO_CTRL9);
+ data_tmp |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
+
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size);
+
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec));
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+#endif
+
+ WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+
+#ifdef CO_MV_COMPRESS
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1 << 1);
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+ }
+#endif
+}
+
+static void decomp_perfcount_reset(void)
+{
+ if (debug & AVS2_DBG_CACHE)
+ pr_info("[cache_util.c] Entered decomp_perfcount_reset...\n");
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
+ return;
+}
+
+static void mcrcc_perfcount_reset(void)
+{
+ if (debug & AVS2_DBG_CACHE)
+ pr_info("[cache_util.c] Entered mcrcc_perfcount_reset...\n");
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
+ return;
+}
+
+static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec)
+{
+ unsigned int data32;
+ unsigned int decode_mode;
+ int i;
+
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+ /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+ data32 &= ~(7 << 29);
+ data32 |= (3 << 29);
+
+ data32 = data32 |
+ (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
+ (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
+ (1 << 7) |/*dec_done_int_cpu_enable*/
+ (1 << 4) |/*startcode_found_int_cpu_enable*/
+ (0 << 3) |/*startcode_found_int_amrisc_enable*/
+ (1 << 0); /*parser_int_enable*/
+
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STATUS);
+ data32 = data32 |
+ (0 << 1) |/*emulation_check_off VP9
+ do not have emulation*/
+ (1 << 0);/*startcode_check_on*/
+
+ WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+ WRITE_VREG(HEVC_SHIFT_CONTROL,
+ (6 << 20) | /* emu_push_bits (6-bits for AVS2)*/
+ (0 << 19) | /* emu_3_enable, maybe turned on in microcode*/
+ (0 << 18) | /* emu_2_enable, maybe turned on in microcode*/
+ (0 << 17) | /* emu_1_enable, maybe turned on in microcode*/
+ (0 << 16) | /* emu_0_enable, maybe turned on in microcode*/
+ (0 << 14) | /*disable_start_code_protect*/
+ (3 << 6) | /* sft_valid_wr_position*/
+ (2 << 4) | /* emulate_code_length_sub_1*/
+ (2 << 1) | /* start_code_length_sub_1*/
+ (1 << 0)); /* stream_shift_enable*/
+
+ WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
+ (0 << 30) | /*data_protect_fill_00_enable*/
+ (1 << 29)); /*data_protect_fill_ff_enable*/
+
+ WRITE_VREG(HEVC_CABAC_CONTROL, (1 << 0));/*cabac_enable*/
+
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0));/* hevc_parser_core_clk_en*/
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
+
+ /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/
+ if (is_rdma_enable())
+ rdma_back_end_work(dec->rdma_phy_adr, RDMA_SIZE);
+ else {
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+ }
+
+#ifdef ENABLE_SWAP_TEST
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+#endif
+ if (!dec->m_ins_flag)
+ decode_mode = DECODE_MODE_SINGLE;
+ else if (vdec_frame_based(hw_to_vdec(dec)))
+ decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
+ else
+ decode_mode = DECODE_MODE_MULTI_STREAMBASE;
+ if (dec->avs2_dec.bufmgr_error_flag &&
+ (error_handle_policy & 0x1)) {
+ dec->bufmgr_error_count++;
+ dec->avs2_dec.bufmgr_error_flag = 0;
+ if (dec->bufmgr_error_count >
+ (re_search_seq_threshold & 0xff)
+ && dec->frame_count >
+ ((re_search_seq_threshold >> 8) & 0xff)) {
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ dec->start_decoding_flag = 0;
+ avs2_dec->hd.vec_flag = 1;
+ dec->skip_PB_before_I = 1;
+ avs2_print(dec, 0,
+ "!!Bufmgr error, search seq again (0x%x %d %d)\n",
+ error_handle_policy,
+ dec->frame_count,
+ dec->bufmgr_error_count);
+ dec->bufmgr_error_count = 0;
+ }
+ }
+ decode_mode |= (dec->start_decoding_flag << 16);
+
+ WRITE_VREG(DECODE_MODE, decode_mode);
+ WRITE_VREG(HEVC_DECODE_SIZE, 0);
+ WRITE_VREG(HEVC_DECODE_COUNT, 0);
+#ifdef DYN_CACHE
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "HEVC DYN MCRCC\n");
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+ }
+#endif
+#if 0
+ /*Send parser_cmd*/
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
+ for (i = 0; i < PARSER_CMD_NUMBER; i++)
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
+#endif
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ (1 << 9) | /* parser_alf_if_en*/
+ /* (1 << 8) |*/ /*sao_sw_pred_enable*/
+ (1 << 5) | /*parser_sao_if_en*/
+ (1 << 2) | /*parser_mpred_if_en*/
+ (1 << 0) /*parser_scaler_if_en*/
+ );
+
+#ifdef MULTI_INSTANCE_SUPPORT
+ WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+ WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+ for (i = 0; i < 8; i++)
+ data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
+
+ WRITE_VREG(DOS_SW_RESET3, (1<<18)); /* reset mpred */
+ WRITE_VREG(DOS_SW_RESET3, 0);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+#endif
+
+ /*AVS2 default seq_wq_matrix config*/
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "Config AVS2 default seq_wq_matrix ...\n");
+ /*4x4*/
+ /* default seq_wq_matrix_4x4 begin address*/
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64);
+ for (i = 0; i < 16; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ /*8x8*/
+ /*default seq_wq_matrix_8x8 begin address*/
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);
+ for (i = 0; i < 64; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (0 << 1) | /*enable ipp*/
+ (1 << 0)); /*software reset ipp and mpp*/
+
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (1 << 1) | /*enable ipp*/
+ (0 << 0)); /*software reset ipp and mpp*/
+
+ /* Init dblk*/
+ data32 = READ_VREG(HEVC_DBLK_CFGB);
+ data32 |= (2 << 0);
+ /* [3:0] cfg_video_type -> AVS2*/
+
+ data32 &= (~0x300); /*[8]:first write enable (compress)
+ [9]:double write enable (uncompress)*/
+ if (get_double_write_mode(dec) == 0)
+ data32 |= (0x1 << 8); /*enable first write*/
+ else if (get_double_write_mode(dec) == 0x10)
+ data32 |= (0x1 << 9); /*double write only*/
+ else
+ data32 |= ((0x1 << 8) | (0x1 << 9));
+ WRITE_VREG(HEVC_DBLK_CFGB, data32);
+
+ WRITE_VREG(HEVC_DBLK_CFG0, (1 << 0)); /* [0] rst_sync*/
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "Bitstream level Init for DBLK .Done.\n");
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ mcrcc_perfcount_reset();
+ decomp_perfcount_reset();
+ }
+
+ return;
+}
+
+#ifdef CONFIG_HEVC_CLK_FORCED_ON
+static void config_avs2_clk_forced_on(void)
+{
+ unsigned int rdata32;
+ /*IQIT*/
+ rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
+ WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
+
+ /* DBLK*/
+ rdata32 = READ_VREG(HEVC_DBLK_CFG0);
+ WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
+
+ /* SAO*/
+ rdata32 = READ_VREG(HEVC_SAO_CTRL1);
+ WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
+
+ /*MPRED*/
+ rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
+ WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
+
+ /* PARSER*/
+ rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
+ WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
+ WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
+ WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
+ rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1));
+
+ /*IPP*/
+ rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
+ WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
+
+ /* MCRCC*/
+ rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
+ WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
+}
+#endif
+
+static struct AVS2Decoder_s gAVS2Decoder;
+
+static void avs2_local_uninit(struct AVS2Decoder_s *dec)
+{
+ dec->rpm_ptr = NULL;
+ dec->lmem_ptr = NULL;
+ if (dec->rpm_addr) {
+ decoder_dma_free_coherent(dec->rpm_mem_handle,
+ RPM_BUF_SIZE, dec->rpm_addr,
+ dec->rpm_phy_addr);
+ dec->rpm_addr = NULL;
+ }
+
+ if (dec->cuva_addr) {
+ decoder_dma_free_coherent(dec->cuva_handle,
+ dec->cuva_size, dec->cuva_addr,
+ dec->cuva_phy_addr);
+ dec->cuva_addr = NULL;
+ }
+
+ if (dec->lmem_addr) {
+ if (dec->lmem_phy_addr)
+ decoder_dma_free_coherent(dec->lmem_phy_handle,
+ LMEM_BUF_SIZE, dec->lmem_addr,
+ dec->lmem_phy_addr);
+ dec->lmem_addr = NULL;
+ }
+
+#ifdef AVS2_10B_MMU
+ if (dec->frame_mmu_map_addr) {
+ if (dec->frame_mmu_map_phy_addr)
+ decoder_dma_free_coherent(dec->frame_mmu_map_handle,
+ get_frame_mmu_map_size(), dec->frame_mmu_map_addr,
+ dec->frame_mmu_map_phy_addr);
+ dec->frame_mmu_map_addr = NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (dec->frame_mmu_map_phy_addr_1)
+ decoder_dma_free_coherent(dec->frame_mmu_map_handle_1,
+ get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+ dec->frame_mmu_map_phy_addr_1);
+
+ dec->frame_mmu_map_addr_1 = NULL;
+ }
+#endif
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_frame_mmu_map_addr) {
+ if (dec->dw_frame_mmu_map_phy_addr)
+ decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
+ get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr,
+ dec->dw_frame_mmu_map_phy_addr);
+ dec->dw_frame_mmu_map_addr = NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && dec->dw_frame_mmu_map_addr_1) {
+ if (dec->dw_frame_mmu_map_phy_addr_1)
+ decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle_1,
+ get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+ dec->dw_frame_mmu_map_phy_addr_1);
+
+ dec->dw_frame_mmu_map_addr_1 = NULL;
+ }
+#endif
+#endif
+
+ if (dec->gvs)
+ vfree(dec->gvs);
+ dec->gvs = NULL;
+}
+
+static int avs2_local_init(struct AVS2Decoder_s *dec)
+{
+ int ret = -1;
+ int bufspec_index = 0;
+ /*int losless_comp_header_size, losless_comp_body_size;*/
+
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct BuffInfo_s *cur_buf_info = NULL;
+
+ cur_buf_info = &dec->work_space_buf_store;
+ if (force_bufspec) {
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[force_bufspec & 0xf],
+ //sizeof(struct BuffInfo_s));
+ bufspec_index = force_bufspec & 0xf;
+ pr_info("force buffer spec %d\n", force_bufspec & 0xf);
+ } else {
+ if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ bufspec_index = 2;
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */
+ //sizeof(struct BuffInfo_s));
+ else
+ bufspec_index = 1;
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */
+ //sizeof(struct BuffInfo_s));
+ } else
+ bufspec_index = 0;
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[0],/* 1080p */
+ //sizeof(struct BuffInfo_s));
+ } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
+ if (vdec_is_support_4k()) {
+ bufspec_index = 5;
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[5], /* 8k */
+ //sizeof(struct BuffInfo_s));
+ } else
+ bufspec_index = 3;
+ //memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */
+ //sizeof(struct BuffInfo_s));
+ }
+ }
+ memcpy(cur_buf_info, &amvavs2_workbuff_spec[bufspec_index],
+ sizeof(struct BuffInfo_s));
+ pr_info("buffer spec %d\n", bufspec_index);
+
+ cur_buf_info->start_adr = dec->buf_start;
+#ifndef AVS2_10B_MMU
+ dec->mc_buf_spec.buf_end = dec->buf_start + dec->buf_size;
+#endif
+
+ init_buff_spec(dec, cur_buf_info);
+
+ init_avs2_decoder(&dec->avs2_dec);
+
+#ifdef AVS2_10B_MMU
+ avs2_bufmgr_init(dec, cur_buf_info, NULL);
+#else
+ dec->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff) & (~0xffff);
+ dec->mc_buf_spec.buf_size = (dec->mc_buf_spec.buf_end
+ - dec->mc_buf_spec.buf_start);
+ if (debug) {
+ pr_err("dec->mc_buf_spec.buf_start %x-%x\n",
+ dec->mc_buf_spec.buf_start,
+ dec->mc_buf_spec.buf_start +
+ dec->mc_buf_spec.buf_size);
+ }
+ avs2_bufmgr_init(dec, cur_buf_info, &dec->mc_buf_spec);
+#endif
+ if ((buf_alloc_width & buf_alloc_height) == 0) {
+ if (!vdec_is_support_4k()
+ && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
+ buf_alloc_width = 1920;
+ buf_alloc_height = 1088;
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ buf_alloc_width = 3840;
+ buf_alloc_height = 2160;
+ }
+ }
+ dec->init_pic_w = buf_alloc_width ? buf_alloc_width :
+ (dec->vavs2_amstream_dec_info.width ?
+ dec->vavs2_amstream_dec_info.width :
+ dec->work_space_buf->max_width);
+ dec->init_pic_h = buf_alloc_height ? buf_alloc_height :
+ (dec->vavs2_amstream_dec_info.height ?
+ dec->vavs2_amstream_dec_info.height :
+ dec->work_space_buf->max_height);
+
+#ifndef AVS2_10B_MMU
+ init_buf_list(dec);
+#else
+ if (IS_8K_SIZE(dec->vavs2_amstream_dec_info.width, dec->vavs2_amstream_dec_info.height))
+ dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin;
+ else
+ dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin - 4;
+
+ if (dec->used_buf_num > MAX_BUF_NUM)
+ dec->used_buf_num = MAX_BUF_NUM;
+ if (dec->used_buf_num > FRAME_BUFFERS)
+ dec->used_buf_num = FRAME_BUFFERS;
+#endif
+ dec->avs2_dec.ref_maxbuffer = dec->used_buf_num - 1;
+
+ pts_unstable = ((unsigned long)(dec->vavs2_amstream_dec_info.param)
+ & 0x40) >> 6;
+
+ if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
+ dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
+ RPM_BUF_SIZE,
+ &dec->rpm_phy_addr, "AVS2_RPM_BUF");
+ if (dec->rpm_addr == NULL) {
+ pr_err("%s: failed to alloc rpm buffer\n", __func__);
+ return -1;
+ }
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "rpm_phy_addr %x\n", (u32) dec->rpm_phy_addr);
+ dec->rpm_ptr = dec->rpm_addr;
+ }
+
+ if (cuva_buf_size > 0) {
+ dec->cuva_size = AUX_BUF_ALIGN(cuva_buf_size);
+
+ dec->cuva_addr = decoder_dma_alloc_coherent(&dec->cuva_handle,
+ dec->cuva_size, &dec->cuva_phy_addr, "AVS2_CUVA_BUF");
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s, cuva_size = %d cuva_phy_addr %x dec->cuva_addr = %px\n",
+ __func__, dec->cuva_size, (u32)dec->cuva_phy_addr, dec->cuva_addr);
+ if (dec->cuva_addr == NULL) {
+ pr_err("%s: failed to alloc cuva buffer\n", __func__);
+ return -1;
+ }
+ }
+
+ dec->lmem_addr = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
+ LMEM_BUF_SIZE,
+ &dec->lmem_phy_addr, "AVS2_LMEM_BUF");
+ if (dec->lmem_addr == NULL) {
+ pr_err("%s: failed to alloc lmem buffer\n", __func__);
+ return -1;
+ } else
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s, lmem_phy_addr %x\n",
+ __func__, (u32)dec->lmem_phy_addr);
+ dec->lmem_ptr = dec->lmem_addr;
+
+#ifdef AVS2_10B_MMU
+ if (dec->mmu_enable) {
+ dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
+ get_frame_mmu_map_size(),
+ &dec->frame_mmu_map_phy_addr, "AVS2_MMU_BUF");
+ if (dec->frame_mmu_map_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->frame_mmu_map_addr, 0, get_frame_mmu_map_size());
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && dec->frame_mmu_map_addr_1 == NULL) {
+ dec->frame_mmu_map_addr_1 = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle_1,
+ get_frame_mmu_map_size(),
+ &dec->frame_mmu_map_phy_addr_1, "AVS2_MMU_BUF_1");
+ if (dec->frame_mmu_map_addr_1 == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+ }
+#endif
+ }
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
+ get_frame_mmu_map_size(),
+ &dec->dw_frame_mmu_map_phy_addr, "AVS2_DWMMU_BUF");
+ if (dec->dw_frame_mmu_map_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->dw_frame_mmu_map_addr, 0, get_frame_mmu_map_size());
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->dw_frame_mmu_map_addr_1 = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle_1,
+ get_frame_mmu_map_size(),
+ &dec->dw_frame_mmu_map_phy_addr_1, "AVS2_DWMMU_BUF_1");
+ if (dec->dw_frame_mmu_map_addr_1 == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->dw_frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+ }
+#endif
+ }
+#endif
+#ifdef NEW_FB_CODE
+ avs2_dec->wait_working_buf = 0;
+ avs2_dec->front_pause_flag = 0; /*multi pictures in one packe*/
+ if (dec->front_back_mode) {
+ avs2_dec->frontend_decoded_count = 0;
+ avs2_dec->backend_decoded_count = 0;
+ avs2_dec->fb_wr_pos = 0;
+ avs2_dec->fb_rd_pos = 0;
+ init_fb_bufstate(dec);
+ copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+ }
+#endif
+ ret = 0;
+ return ret;
+}
+
+/********************************************
+ * Mailbox command
+ ********************************************/
+#define CMD_FINISHED 0
+#define CMD_ALLOC_VIEW 1
+#define CMD_FRAME_DISPLAY 3
+#define CMD_DEBUG 10
+
+#define DECODE_BUFFER_NUM_MAX 32
+#define DISPLAY_BUFFER_NUM 6
+
+#define video_domain_addr(adr) (adr&0x7fffffff)
+#define DECODER_WORK_SPACE_SIZE 0x800000
+
+#define spec2canvas(x) \
+ (((x)->uv_canvas_index << 16) | \
+ ((x)->uv_canvas_index << 8) | \
+ ((x)->y_canvas_index << 0))
+
+static void set_canvas(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic)
+{
+ int canvas_w = ALIGN(pic->pic_w, 64)/4;
+ int canvas_h = ALIGN(pic->pic_h, 32)/4;
+ int blkmode = mem_map_mode;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ /*CANVAS_BLKMODE_64X32*/
+ if (pic->double_write_mode) {
+ canvas_w = pic->pic_w /
+ get_double_write_ratio(pic->double_write_mode);
+ canvas_h = pic->pic_h /
+ get_double_write_ratio(pic->double_write_mode);
+ /*sao_crtl1 aligned with 64*/
+ canvas_w = ALIGN(canvas_w, 64);
+ canvas_h = ALIGN(canvas_h, 32);
+
+ if (vdec->parallel_dec == 1) {
+ if (pic->y_canvas_index == -1)
+ pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->uv_canvas_index == -1)
+ pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->y_canvas_index = 128 + pic->index * 2;
+ pic->uv_canvas_index = 128 + pic->index * 2 + 1;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->dw_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index,
+ pic->dw_u_v_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+#ifdef MULTI_INSTANCE_SUPPORT
+ pic->canvas_config[0].phy_addr = pic->dw_y_adr;
+ pic->canvas_config[0].width = canvas_w;
+ pic->canvas_config[0].height = canvas_h;
+ pic->canvas_config[0].block_mode = blkmode;
+ pic->canvas_config[0].endian = 7;
+ pic->canvas_config[0].bit_depth = is_dw_p010(dec);
+
+ pic->canvas_config[1].phy_addr = pic->dw_u_v_adr;
+ pic->canvas_config[1].width = canvas_w;
+ pic->canvas_config[1].height = canvas_h;
+ pic->canvas_config[1].block_mode = blkmode;
+ pic->canvas_config[1].endian = 7;
+ pic->canvas_config[1].bit_depth = is_dw_p010(dec);
+
+ ATRACE_COUNTER(dec->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr);
+#endif
+ } else {
+ #ifndef AVS2_10B_MMU
+ if (vdec->parallel_dec == 1) {
+ if (pic->y_canvas_index == -1)
+ pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->uv_canvas_index == -1)
+ pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->y_canvas_index = 128 + pic->index;
+ pic->uv_canvas_index = 128 + pic->index;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->mc_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index,
+ pic->mc_u_v_adr,canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+
+ ATRACE_COUNTER(dec->trace.set_canvas0_addr, spec2canvas(pic));
+ #endif
+ }
+
+#ifdef OW_TRIPLE_WRITE
+ if (pic->triple_write_mode) {
+ canvas_w = pic->pic_w /
+ get_double_write_ratio(pic->triple_write_mode & 0xf); //same ratio with double write
+ canvas_h = pic->pic_h /
+ get_double_write_ratio(pic->triple_write_mode & 0xf);
+
+ canvas_w = ALIGN(canvas_w, 64);
+ canvas_h = ALIGN(canvas_h, 32);
+
+#if 0
+ if (vdec->parallel_dec == 1) {
+ if (pic->tw_y_canvas_index == -1)
+ pic->tw_y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->tw_uv_canvas_index == -1)
+ pic->tw_uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->tw_y_canvas_index = 128 + pic->index * 2;
+ pic->tw_uv_canvas_index = 128 + pic->index * 2 + 1;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->dw_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
+ canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+#endif
+ pic->tw_canvas_config[0].phy_addr = pic->tw_y_adr;
+ pic->tw_canvas_config[0].width = canvas_w;
+ pic->tw_canvas_config[0].height = canvas_h;
+ pic->tw_canvas_config[0].block_mode = blkmode;
+ pic->tw_canvas_config[0].endian = 7;
+ pic->tw_canvas_config[0].bit_depth = is_tw_p010(dec);
+
+ pic->tw_canvas_config[1].phy_addr = pic->tw_u_v_adr;
+ pic->tw_canvas_config[1].width = canvas_w;
+ pic->tw_canvas_config[1].height = canvas_h;
+ pic->tw_canvas_config[1].block_mode = blkmode;
+ pic->tw_canvas_config[1].endian = 7;
+ pic->tw_canvas_config[1].bit_depth = is_tw_p010(dec);
+ }
+#endif
+}
+
+static void set_frame_info(struct AVS2Decoder_s *dec, struct vframe_s *vf)
+{
+ unsigned int ar = 0;
+ unsigned int pixel_ratio = 0;;
+
+ vf->duration = dec->frame_dur;
+ vf->duration_pulldown = 0;
+ vf->flag = 0;
+ vf->prop.master_display_colour = dec->vf_dp;
+ if (dec->hdr_flag & HDR_CUVA_MASK)
+ dec->video_signal_type |= 1 << 31;
+ vf->signal_type = dec->video_signal_type;
+
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "signal_type 0x%x \n",
+ vf->signal_type);
+
+ pixel_ratio = dec->vavs2_amstream_dec_info.ratio;
+
+ if (dec->vavs2_ratio == 0) {
+ /* always stretch to 16:9 */
+ vf->ratio_control |= (0x90 <<
+ DISP_RATIO_ASPECT_RATIO_BIT);
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ } else {
+ switch (pixel_ratio) {
+ case 1:
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ ar = (vf->height * dec->vavs2_ratio) / vf->width;
+ break;
+ case 2:
+ vf->sar_width = 4;
+ vf->sar_height = 3;
+ ar = (vf->height * 3 * dec->vavs2_ratio) / (vf->width * 4);
+ break;
+ case 3:
+ vf->sar_width = 16;
+ vf->sar_height = 9;
+ ar = (vf->height * 9 * dec->vavs2_ratio) / (vf->width * 16);
+ break;
+ case 4:
+ vf->sar_width = 221;
+ vf->sar_height = 100;
+ ar = (vf->height * 100 * dec->vavs2_ratio) / (vf->width *
+ 221);
+ break;
+ default:
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ ar = (vf->height * dec->vavs2_ratio) / vf->width;
+ break;
+ }
+ }
+
+ ar = min_t(u32, ar, DISP_RATIO_ASPECT_RATIO_MAX);
+ vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
+
+ vf->sidebind_type = dec->sidebind_type;
+ vf->sidebind_channel_id = dec->sidebind_channel_id;
+ vf->codec_vfmt = VFORMAT_AVS2;
+
+ return;
+}
+
+static int vavs2_vf_states(struct vframe_states *states, void *op_arg)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+
+ states->vf_pool_size = VF_POOL_SIZE;
+ states->buf_free_num = kfifo_len(&dec->newframe_q);
+ states->buf_avail_num = kfifo_len(&dec->display_q);
+
+ if (step == 2)
+ states->buf_avail_num = 0;
+ return 0;
+}
+
+static struct vframe_s *vavs2_vf_peek(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+ if (step == 2)
+ return NULL;
+
+ if (force_disp_pic_index & 0x100) {
+ if (force_disp_pic_index & 0x200)
+ return NULL;
+ return &dec->vframe_dummy;
+ }
+
+ if (kfifo_len(&dec->display_q) > VF_POOL_SIZE) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "kfifo len:%d invalid, peek error\n",
+ kfifo_len(&dec->display_q));
+ return NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ struct vframe_s *vf_tmp;
+ if (kfifo_peek(&dec->display_q, &vf_tmp) && vf_tmp) {
+ uint8_t index = vf_tmp->index & 0xff;
+ struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+ if (!pic->back_done_mark)
+ return NULL;
+ } else
+ return NULL;
+ }
+#endif
+
+ if (kfifo_peek(&dec->display_q, &vf))
+ return vf;
+
+ return NULL;
+}
+
+static struct avs2_frame_s *get_pic_by_index(
+ struct AVS2Decoder_s *dec, int index)
+{
+ int i;
+ struct avs2_frame_s *pic = NULL;
+ if (index == (dec->used_buf_num - 1))
+ pic = dec->avs2_dec.m_bg;
+ else if (index >= 0 && index < dec->used_buf_num) {
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (dec->avs2_dec.frm_pool[i].index == index)
+ pic = &dec->avs2_dec.frm_pool[i];
+ }
+ }
+ return pic;
+}
+
+static void update_vf_memhandle(struct AVS2Decoder_s *dec,
+ struct vframe_s *vf, struct avs2_frame_s *pic)
+{
+ vf->mem_handle = NULL;
+ vf->mem_handle_1 = NULL;
+ vf->mem_head_handle = NULL;
+ vf->mem_dw_handle = NULL;
+
+#ifdef AVS2_10B_MMU
+ if (vf->type & VIDTYPE_SCATTER) {
+#ifdef AVS2_10B_MMU_DW
+ if (pic->double_write_mode & 0x20) {
+ vf->mem_handle =
+ decoder_mmu_box_get_mem_handle(dec->dw_mmu_box, pic->index);
+ if (dec->front_back_mode)
+ vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->dw_mmu_box_1, pic->index);
+ vf->mem_head_handle =
+ decoder_bmmu_box_get_mem_handle(dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->BUF_index));
+ vf->mem_dw_handle = NULL;
+ } else
+#endif
+ {
+ vf->mem_handle = decoder_mmu_box_get_mem_handle(
+ dec->mmu_box,
+ pic->index);
+ if (dec->front_back_mode)
+ vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->mmu_box_1, pic->index);
+ vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->index));
+ if (dec->double_write_mode == 3)
+ vf->mem_dw_handle =
+ decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->BUF_index));
+ else
+ vf->mem_dw_handle = NULL;
+ }
+ } else {
+ vf->mem_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->index));
+ vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->index));
+ }
+#else
+ vf->mem_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->index));
+#endif
+}
+
+static struct vframe_s *vavs2_vf_get(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+ unsigned long flags = 0;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (step == 2)
+ return NULL;
+ else if (step == 1)
+ step = 2;
+
+ if (force_disp_pic_index & 0x100) {
+ int idx = force_disp_pic_index & 0xff;
+ struct avs2_frame_s *pic = NULL;
+ if (idx >= 0
+ && idx < dec->avs2_dec.ref_maxbuffer)
+ pic = get_pic_by_index(dec, idx);
+ if (pic == NULL)
+ return NULL;
+ if (force_disp_pic_index & 0x200)
+ return NULL;
+
+ vf = &dec->vframe_dummy;
+
+ set_vframe(dec, vf, pic, 1);
+
+ force_disp_pic_index |= 0x200;
+ return vf;
+ }
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (kfifo_peek(&dec->display_q, &vf) && vf) {
+ uint8_t index = vf->index & 0xff;
+ if (index < dec->used_buf_num) {
+ struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+ if (!pic->back_done_mark)
+ return NULL;
+ } else
+ return NULL;
+ } else
+ return NULL;
+ }
+#endif
+
+ lock_buffer(dec, flags);
+ if (kfifo_get(&dec->display_q, &vf)) {
+ uint8_t index = vf->index & 0xff;
+
+
+ if (index < dec->used_buf_num) {
+ struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+ if (pic == NULL &&
+ (debug & AVS2_DBG_PIC_LEAK)) {
+ int i;
+ avs2_print(dec, 0,
+ "%s error index 0x%x pic not exist\n",
+ __func__, index);
+ dump_pic_list(dec);
+ for (i = 0; i < 10; i++) {
+ pic = get_pic_by_index(dec, index);
+ pr_info("pic = %p\n", pic);
+ }
+
+ if (debug & AVS2_DBG_PIC_LEAK)
+ debug |= AVS2_DBG_PIC_LEAK_WAIT;
+ unlock_buffer(dec, flags);
+ return NULL;
+ }
+
+ if ((dec->error_proc_policy & 0x2) &&
+ pic && pic->error_mark) {
+ kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+ dec->vf_pre_count--;
+ if (pic->vf_ref > 0)
+ pic->vf_ref--;
+ avs2_print(dec, AVS2_DBG_BUFMGR, "%s pic has error_mark, get err\n", __func__);
+#ifdef MULTI_INSTANCE_SUPPORT
+ vdec_up(vdec);
+#endif
+ unlock_buffer(dec, flags);
+ return NULL;
+ }
+
+ ATRACE_COUNTER(dec->trace.vf_get_name, (long)vf);
+ ATRACE_COUNTER(dec->trace.disp_q_name, kfifo_len(&dec->display_q));
+#ifdef MULTI_INSTANCE_SUPPORT
+ ATRACE_COUNTER(dec->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr);
+#else
+ ATRACE_COUNTER(dec->trace.get_canvas0_addr, vf->canvas0Addr);
+#endif
+
+ vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+ vf->vf_ud_param.ud_param.buf_len = 0;
+ vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+ vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+ vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+ vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS2 << 3);
+ vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+ if (vf->pts)
+ vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+ vf->omx_index = dec->vf_get_count;
+ dec->vf_get_count++;
+ if (pic) {
+ if (dec->front_back_mode == 1) {
+ update_vf_memhandle(dec, vf, pic);
+ decoder_do_frame_check(hw_to_vdec(dec), vf);
+#ifdef NEW_FB_CODE
+ fill_frame_info(dec, pic, pic->stream_size, vf->pts);
+ vdec_fill_vdec_frame(vdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#endif
+ }
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n",
+ __func__, index,
+ pic->imgtr_fwRefDistance_bak,
+ dec->vf_get_count,
+ vf->type,
+ vf->width, vf->height,
+ vf->pts,
+ vf->pts_us64);
+ }
+ unlock_buffer(dec, flags);
+ return vf;
+ }
+ }
+ unlock_buffer(dec, flags);
+ return NULL;
+}
+
+static void vavs2_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+ struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
+ uint8_t index;
+ unsigned long flags = 0;
+
+ if (vf == (&dec->vframe_dummy))
+ return;
+
+ if (!vf)
+ return;
+
+ ATRACE_COUNTER(dec->trace.vf_put_name, (long)vf);
+#ifdef MULTI_INSTANCE_SUPPORT
+ ATRACE_COUNTER(dec->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr);
+#else
+ ATRACE_COUNTER(dec->trace.put_canvas0_addr, vf->canvas0Addr);
+#endif
+
+ lock_buffer(dec, flags);
+ index = vf->index & 0xff;
+ kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(dec->trace.new_q_name, kfifo_len(&dec->newframe_q));
+ dec->vf_put_count++;
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s index putcount 0x%x %d\n",
+ __func__, vf->index,
+ dec->vf_put_count);
+
+ if (index < dec->used_buf_num) {
+ struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+
+ if (pic && pic->vf_ref > 0)
+ pic->vf_ref--;
+ else {
+ if (pic)
+ avs2_print(dec, 0,
+ "%s, error pic (index %d) vf_ref is %d\n",
+ __func__, index, pic->vf_ref);
+ else
+ avs2_print(dec, 0,
+ "%s, error pic (index %d) is NULL\n",
+ __func__, index);
+ }
+ if (dec->wait_buf)
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG,
+ 0x1);
+ dec->last_put_idx = index;
+ dec->new_frame_displayed++;
+ }
+ unlock_buffer(dec, flags);
+
+#ifdef MULTI_INSTANCE_SUPPORT
+ vdec_up(vdec);
+#endif
+
+}
+
+static int vavs2_event_cb(int type, void *data, void *private_data)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)private_data;
+
+ if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
+ struct provider_state_req_s *req =
+ (struct provider_state_req_s *)data;
+ if (req->req_type == REQ_STATE_SECURE)
+ req->req_result[0] = vdec_secure(hw_to_vdec(dec));
+ else
+ req->req_result[0] = 0xffffffff;
+ } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
+ struct provider_aux_req_s *req =
+ (struct provider_aux_req_s *)data;
+ unsigned char index;
+ unsigned long flags;
+ struct avs2_frame_s *pic = NULL;
+
+ if (!req->vf) {
+ req->aux_size = dec->vf_put_count;
+ return 0;
+ }
+ lock_buffer(dec, flags);
+ index = req->vf->index & 0xff;
+ req->aux_buf = NULL;
+ req->aux_size = 0;
+ req->format = VFORMAT_AVS2;
+ if (index < dec->used_buf_num) {
+ pic = get_pic_by_index(dec, index);
+ req->aux_buf = pic->cuva_data_buf;
+ req->aux_size = pic->cuva_data_size;
+ }
+ unlock_buffer(dec, flags);
+
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s pic 0x%p index %d =>size %d\n",
+ __func__, pic, index, req->aux_size);
+ }
+
+ return 0;
+}
+
+static struct avs2_frame_s *get_disp_pic(struct AVS2Decoder_s *dec)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic = NULL;
+ int32_t j;
+ int32_t pre_disp_count_min = 0x7fffffff;
+ for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
+ if (avs2_dec->fref[j]->to_prepare_disp &&
+ avs2_dec->fref[j]->to_prepare_disp <
+ pre_disp_count_min) {
+ pre_disp_count_min =
+ avs2_dec->fref[j]->to_prepare_disp;
+ pic = avs2_dec->fref[j];
+ }
+ }
+ if (pic)
+ pic->to_prepare_disp = 0;
+
+ return pic;
+}
+
+static void fill_frame_info(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic, unsigned int framesize, unsigned int pts)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (pic->slice_type == I_IMG)
+ pic->vqos.type = 1;
+ else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG))
+ pic->vqos.type = 2;
+ else if (pic->slice_type == B_IMG)
+ pic->vqos.type = 3;
+
+ if (input_frame_based(hw_to_vdec(dec)))
+ pic->vqos.size = pic->frame_size;
+ else {
+ if (!((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv))
+ && vdec_stream_based(vdec))
+ pic->vqos.size = pic->stream_size;
+ else if (framesize == 0)
+ pic->vqos.size = pic->stream_size;
+ else
+ pic->vqos.size = framesize;
+ }
+
+ if (pic->error_mark)
+ pic->vqos.decode_buffer = 3;
+ else
+ pic->vqos.decode_buffer = 0;
+
+ pic->vqos.pts = pts;
+ pic->vqos.num++;
+
+ if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+ avs2_print(dec, 0, "slice:%d, poc:%d, size %d, decode_buffer:%d, time:%dus\n",
+ pic->vqos.type, pic->poc, pic->vqos.size, pic->vqos.decode_buffer, pic->hw_decode_time);
+
+ avs2_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_mv, pic->vqos.avg_mv, pic->vqos.min_mv);
+
+ avs2_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_qp, pic->vqos.avg_qp, pic->vqos.min_qp);
+
+ avs2_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_skip, pic->vqos.avg_skip, pic->vqos.min_skip);
+ }
+
+ return ;
+}
+
+static void set_vframe(struct AVS2Decoder_s *dec,
+ struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy)
+{
+ unsigned long flags;
+ u32 stream_offset = pic->stream_offset;
+ unsigned int frame_size = 0;
+ int pts_discontinue;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s index = %d pos = %d\r\n",
+ __func__, pic->index,
+ pic->imgtr_fwRefDistance);
+#ifdef OW_TRIPLE_WRITE
+ if ((pic->triple_write_mode) ||
+ (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0))
+#else
+ if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0)
+#endif
+ set_canvas(dec, pic);
+
+ display_frame_count[dec->index]++;
+
+ if (!dummy) {
+#ifdef MULTI_INSTANCE_SUPPORT
+ if (vdec_frame_based(vdec)) {
+ vf->pts = pic->pts;
+ vf->pts_us64 = pic->pts64;
+ } else {
+#endif
+ if (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
+ if (pts_lookup_offset_us64
+ (PTS_TYPE_VIDEO, stream_offset,
+ &vf->pts, &frame_size, 0,
+ &vf->pts_us64) != 0) {
+#ifdef DEBUG_PTS
+ dec->pts_missed++;
+#endif
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+ }
+#ifdef DEBUG_PTS
+ else
+ dec->pts_hit++;
+#endif
+ if (pts_unstable)
+ dec->pts_mode = PTS_NONE_REF_USE_DURATION;
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 0)
+#endif
+ fill_frame_info(dec, pic, frame_size, vf->pts);
+
+ if ((dec->pts_mode == PTS_NORMAL) && (vf->pts != 0)
+ && dec->get_frame_dur) {
+ int pts_diff = (int)vf->pts - dec->last_lookup_pts;
+
+ if (pts_diff < 0) {
+ dec->pts_mode_switching_count++;
+ dec->pts_mode_recovery_count = 0;
+
+ if (dec->pts_mode_switching_count >=
+ PTS_MODE_SWITCHING_THRESHOLD) {
+ dec->pts_mode = PTS_NONE_REF_USE_DURATION;
+ pr_info("HEVC: switch to n_d mode.\n");
+ }
+
+ } else {
+ int p = PTS_MODE_SWITCHING_RECOVERY_THRESHOLD;
+ dec->pts_mode_recovery_count++;
+ if (dec->pts_mode_recovery_count > p) {
+ dec->pts_mode_switching_count = 0;
+ dec->pts_mode_recovery_count = 0;
+ }
+ }
+ }
+
+ pts_discontinue = (abs(dec->last_pts - vf->pts) >=
+ tsync_vpts_discontinuity_margin());
+
+ if (vf->pts != 0)
+ dec->last_lookup_pts = vf->pts;
+
+ if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
+ && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
+ !first_pts_checkin_complete(PTS_TYPE_AUDIO))))
+ vf->pts = dec->last_pts + DUR2PTS(dec->frame_dur);
+ dec->last_pts = vf->pts;
+
+ if (vf->pts_us64 != 0)
+ dec->last_lookup_pts_us64 = vf->pts_us64;
+
+ if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
+ && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
+ !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) {
+ vf->pts_us64 = dec->last_pts_us64 +
+ (DUR2PTS(dec->frame_dur) * 100 / 9);
+ }
+
+ dec->last_pts_us64 = vf->pts_us64;
+ }
+
+ vf->index = 0xff00 | pic->index;
+
+ if (pic->double_write_mode & 0x10) {
+ /* double write only */
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = 0;
+ } else {
+#ifdef AVS2_10B_MMU
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = pic->header_adr;
+#ifdef AVS2_10B_MMU_DW
+ vf->dwBodyAddr = 0;
+ vf->dwHeadAddr = 0;
+ if (pic->double_write_mode & 0x20) {
+ u32 mode = pic->double_write_mode & 0xf;
+ if (mode == 5 || mode == 3)
+ vf->dwHeadAddr = pic->dw_header_adr;
+ else if ((mode == 1 || mode == 2 || mode == 4)
+ && ((debug & AVS2_DBG_OUT_PTS) == 0)) {
+ vf->compHeadAddr = pic->dw_header_adr;
+ pr_info("Use dw mmu for display\n");
+ }
+ }
+#endif
+#else
+ vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+ vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
+#endif
+ }
+ if (pic->double_write_mode &&
+ ((pic->double_write_mode & 0x20) == 0)) {
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
+ vf->type |= VIDTYPE_VIU_NV21;
+ if (pic->double_write_mode == 3) {
+ vf->type |= VIDTYPE_COMPRESS;
+#ifdef AVS2_10B_MMU
+ vf->type |= VIDTYPE_SCATTER;
+#endif
+ }
+#ifdef MULTI_INSTANCE_SUPPORT
+ if (dec->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+ vf->canvas0_config[0] = pic->canvas_config[0];
+ vf->canvas0_config[1] = pic->canvas_config[1];
+
+ vf->canvas1_config[0] = pic->canvas_config[0];
+ vf->canvas1_config[1] = pic->canvas_config[1];
+ } else
+#endif
+ vf->canvas0Addr = vf->canvas1Addr =
+ spec2canvas(pic);
+ } else {
+ vf->canvas0Addr = vf->canvas1Addr = 0;
+ vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
+#ifdef AVS2_10B_MMU
+ vf->type |= VIDTYPE_SCATTER;
+#endif
+ }
+
+ switch (pic->bit_depth) {
+ case AVS2_BITS_8:
+ vf->bitdepth = BITDEPTH_Y8 |
+ BITDEPTH_U8 | BITDEPTH_V8;
+ break;
+ case AVS2_BITS_10:
+ case AVS2_BITS_12:
+ vf->bitdepth = BITDEPTH_Y10 |
+ BITDEPTH_U10 | BITDEPTH_V10;
+ break;
+ default:
+ vf->bitdepth = BITDEPTH_Y10 |
+ BITDEPTH_U10 | BITDEPTH_V10;
+ break;
+ }
+ if ((vf->type & VIDTYPE_COMPRESS) == 0)
+ vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
+ if (pic->bit_depth == AVS2_BITS_8)
+ vf->bitdepth |= BITDEPTH_SAVING_MODE;
+
+ set_frame_info(dec, vf);
+
+ if (dec->high_bandwidth_flag) {
+ vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH;
+ }
+
+ vf->width = pic->pic_w /
+ get_double_write_ratio(pic->double_write_mode);
+ vf->height = pic->pic_h /
+ get_double_write_ratio(pic->double_write_mode);
+ if (force_w_h != 0) {
+ vf->width = (force_w_h >> 16) & 0xffff;
+ vf->height = force_w_h & 0xffff;
+ }
+ if ((pic->double_write_mode & 0x20) &&
+ ((pic->double_write_mode & 0xf) == 2 ||
+ (pic->double_write_mode & 0xf) == 4)) {
+ vf->compWidth = pic->pic_w /
+ get_double_write_ratio(pic->double_write_mode & 0xf);
+ vf->compHeight = pic->pic_h /
+ get_double_write_ratio(pic->double_write_mode & 0xf);
+ } else {
+ vf->compWidth = pic->pic_w;
+ vf->compHeight = pic->pic_h;
+ }
+
+#ifdef OW_TRIPLE_WRITE
+ if (!pic->double_write_mode && pic->triple_write_mode) {
+ vf->type |= VIDTYPE_VIU_NV21; //nv12 flag
+ vf->canvas0_config[0] = pic->tw_canvas_config[0];
+ vf->canvas0_config[1] = pic->tw_canvas_config[1];
+ vf->canvas1_config[0] = pic->tw_canvas_config[0];
+ vf->canvas1_config[1] = pic->tw_canvas_config[1];
+ vf->width = pic->pic_w /
+ get_double_write_ratio(pic->triple_write_mode & 0xf); //tw same ratio defined with dw
+ vf->height = pic->pic_h /
+ get_double_write_ratio(pic->triple_write_mode & 0xf);
+ avs2_print(dec, 0, "output triple write w %d, h %d, bitdepth %s\n",
+ vf->width, vf->height, vf->canvas0_config[0].bit_depth?"10":"8");
+ }
+#endif
+
+ if (force_fps & 0x100) {
+ u32 rate = force_fps & 0xff;
+ if (rate)
+ vf->duration = 96000/rate;
+ else
+ vf->duration = 0;
+ }
+ if (dec->front_back_mode != 1)
+ update_vf_memhandle(dec, vf, pic);
+
+ if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+ /* offset for tsplayer pts lookup */
+ u64 frame_type = 0;
+ if (pic->slice_type == I_IMG)
+ frame_type = KEYFRAME_FLAG;
+ else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG))
+ frame_type = PFRAME_FLAG;
+ else
+ frame_type = BFRAME_FLAG;
+ vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
+ vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ /* lookup by decoder */
+ checkout_pts_offset pts_info;
+ u64 frame_type = 0;
+ if (pic->slice_type == I_IMG)
+ frame_type = KEYFRAME_FLAG;
+ else if (pic->slice_type == P_IMG)
+ frame_type = PFRAME_FLAG;
+ else
+ frame_type = BFRAME_FLAG;
+ pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+ avs2_print(dec, AVS2_DBG_OUT_PTS,
+ "avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld(0x%llx) slice_type %d, duration %d\n",
+ vf->pts, vf->pts_us64, vf->pts_us64, pic->slice_type, vf->duration);
+
+ lock_buffer(dec, flags);
+ if (!dummy) {
+ pic->vf_ref = 1;
+ }
+
+ dec->vf_pre_count++;
+ unlock_buffer(dec, flags);
+}
+
+static inline void dec_update_gvs(struct AVS2Decoder_s *dec)
+{
+ if (dec->gvs->frame_height != dec->frame_height) {
+ dec->gvs->frame_width = dec->frame_width;
+ dec->gvs->frame_height = dec->frame_height;
+ }
+ /*if (dec->gvs->frame_dur != dec->frame_dur) {
+ dec->gvs->frame_dur = dec->frame_dur;
+ if (dec->frame_dur != 0)
+ dec->gvs->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+ 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
+ else
+ dec->gvs->frame_rate = -1;
+ }*/
+ dec->gvs->status = dec->stat | dec->fatal_error;
+}
+
+static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
+{
+#ifndef NO_DISPLAY
+ struct vframe_s *vf = NULL;
+ /*unsigned short slice_type;*/
+ struct avs2_frame_s *pic;
+ struct vdec_s *pvdec = hw_to_vdec(dec);
+ while (1) {
+ pic = get_disp_pic(dec);
+ if (pic == NULL)
+ break;
+
+ if (force_disp_pic_index & 0x100) {
+ /*recycle directly*/
+ continue;
+ }
+
+ if ((dec->error_proc_policy & 0x2) &&
+ pic->error_mark) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "!!!error pic, skip\n", 0);
+ continue;
+ }
+
+ if (dec->start_decoding_flag != 0) {
+ if (dec->skip_PB_before_I &&
+ pic->slice_type != I_IMG) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+ "!!!slice type %d (not I) skip\n", 0, pic->slice_type);
+ continue;
+ }
+ dec->skip_PB_before_I = 0;
+ }
+
+ if (kfifo_get(&dec->newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return -1;
+ }
+
+ if (vf) {
+ set_vframe(dec, vf, pic, 0);
+ if (dec->front_back_mode != 1)
+ decoder_do_frame_check(pvdec, vf);
+ vdec_vframe_ready(pvdec, vf);
+ kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(dec->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(dec->trace.new_q_name, kfifo_len(&dec->newframe_q));
+ ATRACE_COUNTER(dec->trace.disp_q_name, kfifo_len(&dec->display_q));
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 0) {
+#endif
+ dec_update_gvs(dec);
+ /*count info*/
+ vdec_count_info(dec->gvs, 2, pic->stream_offset);
+ dec->gvs->bit_depth_luma = pic->depth;
+ dec->gvs->bit_depth_chroma = pic->depth;
+ dec->gvs->double_write_mode = pic->double_write_mode;
+ vdec_fill_vdec_frame(pvdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#ifdef NEW_FB_CODE
+ }
+#endif
+
+ pvdec->vdec_fps_detec(pvdec->id);
+ if (without_display_mode == 0) {
+ if (dec->front_back_mode != 1)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ } else
+ vavs2_vf_put(vavs2_vf_get(dec), dec);
+ }
+ }
+/*!NO_DISPLAY*/
+#endif
+ return 0;
+}
+
+static void get_rpm_param(union param_u *params)
+{
+ int i;
+ unsigned int data32;
+ if (debug & AVS2_DBG_BUFMGR)
+ pr_info("enter %s\r\n", __func__);
+ for (i = 0; i < (RPM_END - RPM_BEGIN); i++) {
+ do {
+ data32 = READ_VREG(RPM_CMD_REG);
+ } while ((data32 & 0x10000) == 0);
+ params->l.data[i] = data32&0xffff;
+ WRITE_VREG(RPM_CMD_REG, 0);
+ }
+ if (debug & AVS2_DBG_BUFMGR)
+ pr_info("leave %s\r\n", __func__);
+}
+
+static void debug_buffer_mgr_more(struct AVS2Decoder_s *dec)
+{
+ int i;
+ if (!(debug & AVS2_DBG_BUFMGR_MORE))
+ return;
+ //avs2_print(dec, 0, "avs3_param: (%d)\n", dec->avs2_dec.img.number);
+ pr_info("avs2_param: (%d)\n", dec->avs2_dec.img.number);
+ for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
+ avs2_print_cont(dec, 0, "%04x ", dec->avs2_dec.param.l.data[i]);
+ if (((i + 1) & 0xf) == 0) {
+ avs2_print_cont(dec, 0, "\n");
+ avs2_print_flush(dec);
+ }
+ }
+ avs2_print(dec, 0, "\n");
+}
+
+#ifdef AVS2_10B_MMU
+static void avs2_recycle_mmu_buf_tail(struct AVS2Decoder_s *dec)
+{
+ if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+ if (dec->used_4k_num == -1) {
+ dec->used_4k_num =
+ (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "pic index %d page_start %d\n",
+ dec->cur_fb_idx_mmu, dec->used_4k_num);
+ if (dec->m_ins_flag)
+ hevc_mmu_dma_check(hw_to_vdec(dec));
+ decoder_mmu_box_free_idx_tail(dec->mmu_box,
+ dec->cur_fb_idx_mmu, dec->used_4k_num);
+ }
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+ dec->used_4k_num = -1;
+ }
+}
+
+static void avs2_recycle_mmu_buf(struct AVS2Decoder_s *dec)
+{
+ if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+ decoder_mmu_box_free_idx(dec->mmu_box,
+ dec->cur_fb_idx_mmu);
+
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+ dec->used_4k_num = -1;
+ }
+}
+#endif
+
+static void dec_again_process(struct AVS2Decoder_s *dec)
+{
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ dec->dec_result = DEC_RESULT_AGAIN;
+ if (dec->process_state ==
+ PROC_STATE_DECODING) {
+ dec->process_state =
+ PROC_STATE_DECODE_AGAIN;
+ } else if (dec->process_state ==
+ PROC_STATE_HEAD_DONE) {
+ dec->process_state =
+ PROC_STATE_HEAD_AGAIN;
+ }
+ dec->next_again_flag = 1;
+ reset_process_time(dec);
+
+ vdec_schedule_work(&dec->work);
+}
+
+static void check_pic_error(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic)
+{
+ if (pic == NULL)
+ return ;
+
+ if (pic->decoded_lcu != dec->avs2_dec.lcu_total) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s error pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index, pic->imgtr_fwRefDistance,
+ pic->decoded_lcu, dec->avs2_dec.lcu_total);
+ pic->error_mark = 1;
+ } else {
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index, pic->imgtr_fwRefDistance,
+ pic->decoded_lcu, dec->avs2_dec.lcu_total);
+
+ }
+}
+static void update_decoded_pic(struct AVS2Decoder_s *dec)
+{
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+ if (pic) {
+ dec->avs2_dec.hc.cur_pic->decoded_lcu =
+ (READ_VREG(HEVC_PARSER_LCU_START)
+ & 0xffffff) + 1;
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index, pic->imgtr_fwRefDistance,
+ pic->decoded_lcu, dec->avs2_dec.lcu_total);
+ }
+}
+/* +[SE] [BUG][BUG-171463][chuanqi.wang]: get frame rate by video sequeue*/
+static int get_frame_rate(union param_u *params, struct AVS2Decoder_s *dec)
+{
+ int tmp = 0;
+
+ switch (params->p.frame_rate_code) {
+ case 1:
+ case 2:
+ tmp = 24;
+ break;
+ case 3:
+ tmp = 25;
+ break;
+ case 4:
+ case 5:
+ tmp = 30;
+ break;
+ case 6:
+ tmp = 50;
+ break;
+ case 7:
+ case 8:
+ tmp = 60;
+ break;
+ case 9:
+ tmp = 100;
+ break;
+ case 10:
+ tmp = 120;
+ break;
+ default:
+ tmp = 25;
+ break;
+ }
+
+ if (!params->p.progressive_sequence)
+ tmp = tmp / 2;
+ dec->frame_dur = div_u64(96000ULL, tmp);
+ dec->get_frame_dur = true;
+ return 0;
+}
+
+#define HEVC_MV_INFO 0x310d
+#define HEVC_QP_INFO 0x3137
+#define HEVC_SKIP_INFO 0x3136
+
+static void get_qos_info(struct AVS2Decoder_s *dec, struct vframe_qos_s* vqos, int poc, int core_num)
+{
+ uint32_t blk88_y_count;
+ uint32_t blk88_c_count;
+ uint32_t blk22_mv_count;
+ uint32_t rdata32;
+ int32_t mv_hi;
+ int32_t mv_lo;
+ uint32_t rdata32_l;
+ uint32_t mvx_L0_hi;
+ uint32_t mvy_L0_hi;
+ uint32_t mvx_L1_hi;
+ uint32_t mvy_L1_hi;
+ int64_t value;
+ uint64_t temp_value;
+ int pic_number = poc;
+ uint64_t ctrl_reg = HEVC_PIC_QUALITY_CTRL;
+ uint64_t data_reg = HEVC_PIC_QUALITY_DATA;
+
+#ifdef NEW_FB_CODE
+ if (core_num == 1) {
+ ctrl_reg = HEVC_PIC_QUALITY_CTRL_DBE1;
+ data_reg = HEVC_PIC_QUALITY_DATA_DBE1;
+ }
+#endif
+
+ /* set rd_idx to 0 */
+ WRITE_VREG(ctrl_reg, 0);
+
+ blk88_y_count = READ_VREG(data_reg);
+ if (blk88_y_count == 0) {
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] NO Data yet.\n",
+ pic_number);
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* qp_y_sum */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
+ pic_number, rdata32 / blk88_y_count, rdata32, blk88_y_count);
+
+ vqos->avg_qp = rdata32 * 10 / blk88_y_count;
+ /* intra_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] Y intra rate : %d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+
+ /* skipped_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+
+ vqos->avg_skip = rdata32 * 1000 / blk88_y_count;
+ /* coeff_non_zero_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
+ pic_number, (100 - rdata32 * 100 /blk88_y_count), '%', rdata32);
+
+ /* blk66_c_count */
+ blk88_c_count = READ_VREG(data_reg);
+ if (blk88_c_count == 0) {
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] NO Data yet.\n",
+ pic_number);
+
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* qp_c_sum */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] C QP AVG : %d (%d/%d)\n",
+ pic_number, rdata32 / blk88_c_count, rdata32, blk88_c_count);
+
+ /* intra_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] C intra rate : %d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_c_count, '%', rdata32);
+
+ /* skipped_cu_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] C skipped rate : %d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_c_count, '%', rdata32);
+
+ /* coeff_non_zero_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
+ pic_number, (100 - rdata32 * 100 / blk88_c_count), '%', rdata32);
+
+
+ /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
+ 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
+ rdata32 = READ_VREG(data_reg);
+
+ vqos->min_qp = (rdata32 >> 0) & 0xff;
+ vqos->max_qp = (rdata32>>8) & 0xff;
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] Y QP max: %d min: %d\n",
+ pic_number, (rdata32>>8) & 0xff, (rdata32>>0) & 0xff);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] C QP min: %d, max: %d\n",
+ pic_number, (rdata32 >> 16) & 0xff, (rdata32 >> 24) & 0xff);
+
+ /* blk22_mv_count */
+ blk22_mv_count = READ_VREG(data_reg);
+ if (blk22_mv_count == 0) {
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] NO MV Data yet.\n",
+ pic_number);
+
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* mvy_L1_count[39:32], mvx_L1_count[39:32],
+ mvy_L0_count[39:32], mvx_L0_count[39:32] */
+ rdata32 = READ_VREG(data_reg);
+ /* should all be 0x00 or 0xff */
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MV AVG High Bits: 0x%X\n",
+ pic_number, rdata32);
+
+ mvx_L0_hi = ((rdata32 >> 0) & 0xff);
+ mvy_L0_hi = ((rdata32 >> 8) & 0xff);
+ mvx_L1_hi = ((rdata32 >> 16) & 0xff);
+ mvy_L1_hi = ((rdata32 >> 24) & 0xff);
+
+ /* mvx_L0_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvx_L0_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+
+ if (mvx_L0_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+ value = div_s64(value * 10, blk22_mv_count);
+ vqos->avg_mv = value;
+
+ value = div_s64(value, 10);
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
+ pic_number, (int)value, value, blk22_mv_count);
+
+ /* mvy_L0_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvy_L0_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+
+ if (mvy_L0_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
+ pic_number, rdata32_l / blk22_mv_count, value, blk22_mv_count);
+
+ /* mvx_L1_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvx_L1_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+ if (mvx_L1_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
+ pic_number, rdata32_l / blk22_mv_count, value, blk22_mv_count);
+
+ /* mvy_L1_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvy_L1_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+ if (mvy_L1_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
+ pic_number, rdata32_l / blk22_mv_count, value, blk22_mv_count);
+
+ /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ vqos->max_mv = mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ vqos->min_mv = mv_lo;
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L0 MAX: %d MIN: %d\n",
+ pic_number, mv_hi, mv_lo);
+
+ /* {mvy_L0_max, mvy_L0_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L0 MIN: %d MAX: %d\n",
+ pic_number, mv_lo, mv_hi);
+
+ /* {mvx_L1_max, mvx_L1_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L1 MAX: %d MIN: %d\n",
+ pic_number, mv_hi, mv_lo);
+
+ /* {mvy_L1_max, mvy_L1_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L1 MAX:%d MIN: %d\n",
+ pic_number, mv_hi, mv_lo);
+
+ rdata32 = READ_VREG(ctrl_reg);
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
+ pic_number, rdata32);
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+}
+
+/* only when we decoded one field or one frame,
+we can call this function to get qos info*/
+static void get_picture_qos_info(struct AVS2Decoder_s *dec, bool back_flag)
+{
+ struct avs2_frame_s *picture = NULL;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct vframe_qos_s vqos_0, vqos_1;
+
+ if (back_flag) {
+#ifdef NEW_FB_CODE
+ picture = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+#endif
+ } else {
+ picture = dec->avs2_dec.hc.cur_pic;
+ }
+
+ if (!picture) {
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s decode picture is none exist\n", __func__);
+ return;
+ }
+
+ if (vdec->mvfrm) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ if (back_flag) {
+ picture->hw_decode_time =
+ local_clock() - vdec->hw_back_decode_start;
+ if (picture->hw_decode_time < picture->hw_front_decode_time)
+ picture->hw_decode_time = picture->hw_front_decode_time;
+
+ } else {
+ picture->hw_front_decode_time =
+ local_clock() - vdec->hw_front_decode_start;
+ return ;
+ }
+ } else
+#endif
+ picture->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "slice_type:%d, poc:%d, hw_decode_time:%d\n",
+ picture->slice_type, picture->imgtr_fwRefDistance, picture->hw_decode_time);
+
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
+ unsigned char a[3];
+ unsigned char i, j, t;
+ unsigned long data;
+
+ data = READ_VREG(HEVC_MV_INFO);
+ if (picture->slice_type == I_IMG)
+ data = 0;
+ a[0] = data & 0xff;
+ a[1] = (data >> 8) & 0xff;
+ a[2] = (data >> 16) & 0xff;
+
+ for (i = 0; i < 3; i++)
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ picture->vqos.max_mv = a[2];
+ picture->vqos.avg_mv = a[1];
+ picture->vqos.min_mv = a[0];
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+
+ data = READ_VREG(HEVC_QP_INFO);
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++)
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ picture->vqos.max_qp = a[2];
+ picture->vqos.avg_qp = a[1];
+ picture->vqos.min_qp = a[0];
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+ data = READ_VREG(HEVC_SKIP_INFO);
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++)
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ picture->vqos.max_skip = a[2];
+ picture->vqos.avg_skip = a[1];
+ picture->vqos.min_skip = a[0];
+
+ avs2_print(dec, AVS2_DBG_QOS_INFO,
+ "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+ } else {
+ picture->vqos.max_mv = 0;
+ picture->vqos.avg_mv = 0;
+ picture->vqos.min_mv = 0;
+
+ picture->vqos.max_skip = 0;
+ picture->vqos.avg_skip = 0;
+ picture->vqos.min_skip = 0;
+
+ picture->vqos.max_qp = 0;
+ picture->vqos.avg_qp = 0;
+ picture->vqos.min_qp = 0;
+
+ get_qos_info(dec, &vqos_0, picture->poc, 0);
+
+ if (back_flag) {
+#ifdef NEW_FB_CODE
+ get_qos_info(dec, &vqos_1, picture->poc, 1);
+
+ vqos_0.max_mv = max(vqos_0.max_mv, vqos_1.max_mv);
+ vqos_0.min_mv = min(vqos_0.min_mv, vqos_1.min_mv);
+ vqos_0.max_qp = max(vqos_0.max_qp, vqos_1.max_qp);
+ vqos_0.min_qp = min(vqos_0.min_qp, vqos_1.min_qp);
+
+ vqos_0.avg_qp = (vqos_0.avg_qp + vqos_1.avg_qp) / 20;
+ vqos_0.avg_skip = (vqos_0.avg_skip + vqos_1.avg_skip) / 20;
+ vqos_0.avg_mv = (vqos_0.avg_mv + vqos_1.avg_mv) / 20;
+#endif
+ } else {
+ vqos_0.avg_qp = vqos_0.avg_qp / 10;
+ vqos_0.avg_skip = vqos_0.avg_skip / 10;
+ vqos_0.avg_mv = vqos_0.avg_mv / 10;
+ }
+
+ picture->vqos = vqos_0;
+ }
+}
+
+static int avs2_mmu_page_num(struct AVS2Decoder_s *dec,
+ int w, int h, int bit_depth_10)
+{
+ int picture_size;
+ int cur_mmu_4k_number, max_frame_num;
+
+ picture_size = compute_losless_comp_body_size(dec, w, h, bit_depth_10);
+ cur_mmu_4k_number = ((picture_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ max_frame_num = MAX_FRAME_8K_NUM;
+ else
+ max_frame_num = MAX_FRAME_4K_NUM;
+
+ if (cur_mmu_4k_number > max_frame_num) {
+ pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
+ cur_mmu_4k_number, w, h);
+ return -1;
+ }
+
+ return cur_mmu_4k_number;
+}
+
+#ifdef NEW_FB_CODE
+irqreturn_t avs2_back_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+
+ dec->dec_status_back = READ_VREG(HEVC_DEC_STATUS_DBE);
+ if (dec->dec_status_back == HEVC_BE_DECODE_DATA_DONE) {
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC_BACK);
+ }
+ /*BackEnd_Handle()*/
+ if (dec->front_back_mode != 1) {
+ avs2_print(dec, AVS2_DBG_IRQ_EVENT,
+ "[BE] %s\n", __func__);
+ if (dec->front_back_mode == 3)
+ dec->dec_status_back = HEVC_BE_DECODE_DATA_DONE;
+ return IRQ_WAKE_THREAD;
+ }
+
+ if (debug & AVS2_DBG_IRQ_EVENT)
+ avs2_print(dec, 0,
+ "[BE] avs2 back isr dec_status_back = 0x%x\n",
+ dec->dec_status_back
+ );
+
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) && READ_VREG(DEBUG_REG1_DBE)) {
+ pr_info("[BE] dbg%x: %x, HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+ READ_VREG(DEBUG_REG1_DBE),
+ READ_VREG(DEBUG_REG2_DBE),
+ READ_VREG(HEVC_SAO_CRC),
+ READ_VREG(HEVC_SAO_CRC_DBE1));
+ WRITE_VREG(DEBUG_REG1_DBE, 0);
+ }
+ if (debug & AVS2_DBG_IRQ_EVENT) {
+ pr_info("[BE] HEVC_CM_BODY_START_ADDR done= %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR));
+ pr_info("[BE] HEVC_CM_HEADER_START_ADDR done= %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR));
+ pr_info("[BE] HEVC_SAO_Y_START_ADDR done= %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR));
+ pr_info("[BE] HEVC_SAO_Y_LENGTH done= %x\n", READ_VREG(HEVC_SAO_Y_LENGTH));
+ pr_info("[BE] HEVC_SAO_C_START_ADDR done= %x\n", READ_VREG(HEVC_SAO_C_START_ADDR));
+ pr_info("[BE] HEVC_SAO_C_LENGTH done= %x\n", READ_VREG(HEVC_SAO_C_LENGTH));
+ pr_info("[BE] HEVC_SAO_Y_WPTR done= %x\n", READ_VREG(HEVC_SAO_Y_WPTR));
+ pr_info("[BE] HEVC_SAO_C_WPTR done= %x\n", READ_VREG(HEVC_SAO_C_WPTR));
+ pr_info("[BE] HEVC_SAO_CTRL0 done= %x\n", READ_VREG(HEVC_SAO_CTRL0));
+ pr_info("[BE] HEVC_SAO_CTRL1 done= %x\n", READ_VREG(HEVC_SAO_CTRL1));
+ pr_info("[BE] HEVC_SAO_CTRL2 done= %x\n", READ_VREG(HEVC_SAO_CTRL2));
+ pr_info("[BE] HEVC_SAO_CTRL3 done= %x\n", READ_VREG(HEVC_SAO_CTRL3));
+ pr_info("[BE] HEVC_SAO_CTRL4 done= %x\n", READ_VREG(HEVC_SAO_CTRL4));
+ pr_info("[BE] HEVC_SAO_CTRL5 done= %x\n", READ_VREG(HEVC_SAO_CTRL5));
+
+ pr_info("[BE] HEVC_CM_BODY_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR_DBE1));
+ pr_info("[BE] HEVC_CM_HEADER_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR_DBE1));
+ pr_info("[BE] HEVC_SAO_Y_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR_DBE1));
+ pr_info("[BE] HEVC_SAO_Y_LENGTH_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_LENGTH_DBE1));
+ pr_info("[BE] HEVC_SAO_C_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_START_ADDR_DBE1));
+ pr_info("[BE] HEVC_SAO_C_LENGTH_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_LENGTH_DBE1));
+ pr_info("[BE] HEVC_SAO_Y_WPTR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_WPTR_DBE1));
+ pr_info("[BE] HEVC_SAO_C_WPTR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_WPTR_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL0_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL0_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL1_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL1_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL2_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL2_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL3_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL3_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL4_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL4_DBE1));
+ pr_info("[BE] HEVC_SAO_CTRL5_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL5_DBE1));
+ }
+
+ if (dec->dec_status_back == AVS2_DEC_IDLE) {
+ return IRQ_HANDLED;
+ }
+ /**/
+ return IRQ_WAKE_THREAD;
+}
+
+static int file_write(struct file* fp, char *wdata, unsigned int size)
+{
+ int ret = 0, cnt = 0;
+
+ if (fp == NULL)
+ return 0;
+
+ while (ret < size) {
+ ret += media_write(fp, wdata + ret, size - ret, &fp->f_pos);
+ if (++cnt > 2)
+ break;
+ }
+
+ return ret;
+}
+
+static void pic_yuv_dump(struct avs2_frame_s* pic)
+{
+ u8 *vaddr_y, *vaddr_uv;
+ struct file *fp_yuv = NULL;
+ char file_name[64] = {0};
+ u32 i;
+
+ ulong phy_y = pic->dw_y_adr;
+ ulong phy_uv = pic->dw_u_v_adr;
+ u32 w = pic->pic_w / get_double_write_ratio(pic->double_write_mode);
+ u32 h = pic->pic_h / get_double_write_ratio(pic->double_write_mode);
+ u32 buf_w = ALIGN(w, 64);
+ u32 buf_h = ALIGN(h, 32);
+
+ if (!dump_yuv_frame)
+ return;
+
+ pr_info("%s, buf w %d, h %d, pic w %d, h %d\n", __func__, buf_w, buf_h, w, h);
+
+ snprintf(file_name, 64, "/data/tmp/dec_dump_%ux%u.raw", w, h);
+
+ fp_yuv = media_open(file_name,
+ O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+
+ if (IS_ERR(fp_yuv)) {
+ return;
+ }
+
+ for (i = 0; i < h; i++) {
+ vaddr_y = codec_mm_vmap(phy_y, buf_w);
+ if (vaddr_y) {
+ codec_mm_dma_flush(vaddr_y, buf_w, DMA_FROM_DEVICE);
+ file_write(fp_yuv, vaddr_y, w);
+ codec_mm_unmap_phyaddr(vaddr_y);
+ }
+ phy_y += buf_w;
+ }
+
+ for (i = 0; i < h / 2; i++) {
+ vaddr_uv = codec_mm_vmap(phy_uv, buf_w);
+ if (vaddr_uv) {
+ codec_mm_dma_flush(vaddr_uv, buf_w, DMA_FROM_DEVICE);
+ file_write(fp_yuv, vaddr_uv, w);
+ codec_mm_unmap_phyaddr(vaddr_uv);
+ }
+ phy_uv += buf_w;
+ }
+ pr_info("dump idx: %d %dx%d\n", dump_yuv_frame, buf_w, buf_h);
+ dump_yuv_frame--;
+ media_close(fp_yuv, NULL);
+}
+
+irqreturn_t avs2_back_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ unsigned int dec_status = dec->dec_status_back;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ /*simulation code: if (READ_VREG(HEVC_DEC_STATUS_DBE)==HEVC_BE_DECODE_DATA_DONE)*/
+ if (dec_status == HEVC_BE_DECODE_DATA_DONE || dec->front_back_mode == 2) {
+ struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+
+ get_picture_qos_info(dec, true);
+
+ dec_update_gvs(dec);
+ /*count info*/
+ vdec_count_info(dec->gvs, 2, pic->stream_offset);
+ dec->gvs->bit_depth_luma = pic->depth;
+ dec->gvs->bit_depth_chroma = pic->depth;
+ dec->gvs->double_write_mode = pic->double_write_mode;
+
+ reset_process_time_back(dec);
+ vdec->back_pic_done = true;
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "BackEnd data done %d, fb_rd_pos %d, poc %d HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+ avs2_dec->backend_decoded_count, avs2_dec->fb_rd_pos, pic->poc,
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+ READ_VREG(HEVC_SAO_CRC) : 0,
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+ READ_VREG(HEVC_SAO_CRC_DBE1) : 0);
+
+ if (dec->front_back_mode == 1) {
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "MMU0 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0));
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "MMU1 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1));
+ pic_yuv_dump(pic);
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS2_DEC_IDLE);
+ WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 2);
+ }
+
+ pic_backend_ref_operation(dec, 0);
+
+ if (without_display_mode == 0) {
+ struct vframe_s *vf = NULL;
+ if (kfifo_peek(&dec->display_q, &vf) && vf) {
+ struct avs2_frame_s *peek_pic =
+ &dec->avs2_dec.frm_pool[vf->index & 0xff];
+ if (peek_pic == pic)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ }
+ } else
+ vavs2_vf_put(vavs2_vf_get(dec), dec);
+
+ if (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3) {
+ unsigned used_4k_num0;
+ unsigned used_4k_num1;
+ used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+ if (dec->front_back_mode == 3)
+ used_4k_num1 = used_4k_num0;
+ else
+ used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS_DBE1) >> 16;
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "decoder_mmu_box_free_idx_tail index %d core0 %d core1 %d\n",
+ pic->index, used_4k_num0, used_4k_num1);
+ decoder_mmu_box_free_idx_tail(
+ dec->mmu_box,
+ pic->index,
+ used_4k_num0);
+ decoder_mmu_box_free_idx_tail(
+ dec->mmu_box_1,
+ pic->index,
+ used_4k_num1);
+ if (dec->dw_mmu_enable) {
+ used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+ if (dec->front_back_mode == 3)
+ used_4k_num1 = used_4k_num0;
+ else
+ used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS2_DBE1) >> 16;
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "DW decoder_mmu_box_free_idx_tail core0 %d core1 %d\n",
+ used_4k_num0, used_4k_num1);
+ decoder_mmu_box_free_idx_tail(
+ dec->dw_mmu_box,
+ pic->index,
+ used_4k_num0);
+ decoder_mmu_box_free_idx_tail(
+ dec->dw_mmu_box_1,
+ pic->index,
+ used_4k_num1);
+ }
+ }
+
+#if 1 //def RESET_BACK_PER_PICTURE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_b();
+#endif
+ /*if (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3)
+ release_free_mmu_buffers(dec);*/
+
+ if (avs2_dec->front_pause_flag) {
+ /*multi pictures in one packe*/
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG,
+ 0x1);
+ }
+#ifdef NEW_FB_CODE
+ dec->dec_back_result = DEC_BACK_RESULT_DONE;
+ avs2_work_back_implement(dec, vdec, 0);
+#endif
+ }
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static irqreturn_t vavs2_isr_thread_fn(int irq, void *data)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data;
+ unsigned int dec_status = dec->dec_status;
+ int i, ret;
+ int32_t start_code = 0;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+#ifdef NEW_FB_CODE
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+#endif
+
+ if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+ (dec_status == AVS2_HEAD_PIC_PB_READY)) {
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
+ } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
+ }
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%s decode_status 0x%x process_state %d lcu 0x%x\n",
+ __func__, dec_status, dec->process_state,
+ READ_VREG(HEVC_PARSER_LCU_START));
+
+#ifndef G12A_BRINGUP_DEBUG
+ if (dec->eos) {
+ PRINT_LINE();
+ goto irq_handled_exit;
+ }
+#endif
+ dec->wait_buf = 0;
+ if (dec_status == AVS2_DECODE_BUFEMPTY) {
+ PRINT_LINE();
+ if (dec->m_ins_flag) {
+ reset_process_time(dec);
+ if (!vdec_frame_based(hw_to_vdec(dec)))
+ dec_again_process(dec);
+ else {
+ dec->dec_result = DEC_RESULT_DONE;
+ reset_process_time(dec);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
+ }
+ goto irq_handled_exit;
+ } else if ((dec_status == HEVC_DECPIC_DATA_DONE)
+ || (dec_status == HEVC_DECPIC_DATA_ERROR)) {
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+ mutex_lock(&dec->slice_header_lock);
+ mutex_unlock(&dec->slice_header_lock);
+ PRINT_LINE();
+ vdec->front_pic_done = true;
+
+ if ((pic != NULL) && (vdec_stream_based(hw_to_vdec(dec)))
+ && (dec_status == HEVC_DECPIC_DATA_DONE))
+ pic->stream_size = vdec_get_stream_size(hw_to_vdec(dec));
+
+ if ((dec->front_back_mode == 0) &&
+ get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "HEVC_DECPIC_DATA_DONE: decode_idx %d shiftcnt=0x%x, HEVC_SAO_CRC %x\n",
+ dec->frame_count,
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_SAO_CRC));
+ } else {
+ if (pic != NULL)
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "FrontEnd data done %d, fb_rd_pos %d, pic index %d, poc %d stream crc %x shiftbyte %x\n",
+ avs2_dec->frontend_decoded_count, avs2_dec->fb_rd_pos, dec->avs2_dec.hc.cur_pic->index,
+ pic->poc, READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ else
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "FrontEnd data done %d, fb_rd_pos %d, stream crc %x shiftbyte %x\n",
+ avs2_dec->frontend_decoded_count, avs2_dec->fb_rd_pos,
+ READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ }
+#ifdef AVS2_10B_MMU
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode != 1)
+#endif
+ avs2_recycle_mmu_buf_tail(dec);
+#endif
+
+ dec->start_decoding_flag |= 0x3;
+ if (dec->m_ins_flag) {
+ if (dec_status == HEVC_DECPIC_DATA_ERROR &&
+ (pic != NULL))
+ pic->error_mark = 1;
+ set_cuva_data(dec);
+ update_decoded_pic(dec);
+ check_pic_error(dec, pic);
+ get_picture_qos_info(dec, 0);
+ reset_process_time(dec);
+ dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ /*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+ if (pic != NULL)
+ front_decpic_done_update(dec, 1); /*not multi pictures in one packe*/
+ } else
+#endif
+ amhevc_stop();
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
+ avs2_work_implement(dec);
+ }
+ goto irq_handled_exit;
+ }
+ PRINT_LINE();
+ if (dec_status == AVS2_DECODE_OVER_SIZE) {
+ avs2_print(dec, 0,
+ "avs2 decode oversize !!\n");
+ debug |= (AVS2_DBG_DIS_LOC_ERROR_PROC |
+ AVS2_DBG_DIS_SYS_ERROR_PROC);
+ dec->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
+ if (dec->m_ins_flag)
+ reset_process_time(dec);
+ goto irq_handled_exit;
+ }
+ PRINT_LINE();
+
+ if (dec->m_ins_flag)
+ reset_process_time(dec);
+
+ if (dec_status == AVS2_HEAD_SEQ_READY)
+ start_code = SEQUENCE_HEADER_CODE;
+ else if (dec_status == AVS2_HEAD_PIC_I_READY)
+ start_code = I_PICTURE_START_CODE;
+ else if (dec_status == AVS2_HEAD_PIC_PB_READY)
+ start_code = PB_PICTURE_START_CODE;
+ else if (dec_status == AVS2_STARTCODE_SEARCH_DONE)
+ /*SEQUENCE_END_CODE, VIDEO_EDIT_CODE*/
+ start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
+
+ if (dec->process_state ==
+ PROC_STATE_HEAD_AGAIN) {
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)) {
+ avs2_print(dec, 0,
+ "PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n",
+ start_code);
+ if (dec->m_ins_flag) {
+ dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
+ goto irq_handled_exit;
+ } else {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "PROC_STATE_HEAD_AGAIN, start_code 0x%x\r\n",
+ start_code);
+ dec->process_state = PROC_STATE_HEAD_DONE;
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+ goto irq_handled_exit;
+ }
+ } else if (dec->process_state ==
+ PROC_STATE_DECODE_AGAIN) {
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "PROC_STATE_DECODE_AGAIN=> decode_slice, start_code 0x%x\r\n",
+ start_code);
+ if ((dec->front_back_mode == 1) && (dec->pic_list_init_flag == 0) &&
+ (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATE_DONE)) {
+ dec->pic_list_init_flag = 1;
+ goto alloc_buffer_done;
+ }
+ else
+ goto decode_slice;
+ } else {
+ avs2_print(dec, 0,
+ "PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
+ start_code);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+ goto irq_handled_exit;
+ }
+ }
+
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)
+ || (start_code == SEQUENCE_END_CODE)
+ || (start_code == VIDEO_EDIT_CODE)) {
+ PRINT_LINE();
+
+ if (dec->avs2_dec.hc.cur_pic != NULL) {
+#ifndef NEW_FB_CODE
+ int32_t ii;
+#endif
+ avs2_post_process(&dec->avs2_dec);
+
+ if (debug & AVS2_DBG_PRINT_PIC_LIST)
+ dump_pic_list(dec);
+
+ if (dec->front_back_mode != 1 || !efficiency_mode)
+ avs2_prepare_display_buf(dec);
+ dec->avs2_dec.hc.cur_pic = NULL;
+#ifdef NEW_FB_CODE
+ //release_free_mmu_buffers(dec);
+#else
+ for (ii = 0; ii < dec->avs2_dec.ref_maxbuffer; ii++) {
+ struct avs2_frame_s *pic =
+ dec->avs2_dec.fref[ii];
+ if (pic->bg_flag == 0 &&
+ pic->is_output == -1 &&
+ pic->mmu_alloc_flag &&
+ pic->vf_ref == 0) {
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+ if (pic->referred_by_others == 0) {
+#ifdef AVS2_10B_MMU
+ pic->mmu_alloc_flag = 0;
+
+ decoder_mmu_box_free_idx(dec->mmu_box,
+ pic->index);
+#endif
+#ifndef MV_USE_FIXED_BUF
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ MV_BUFFER_IDX(pic->index));
+ pic->mpred_mv_wr_start_addr = 0;
+#endif
+ }
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+ }
+ }
+#endif
+ }
+ }
+
+ if ((dec_status == AVS2_HEAD_PIC_I_READY)
+ || (dec_status == AVS2_HEAD_PIC_PB_READY)) {
+ PRINT_LINE();
+
+ if (debug & AVS2_DBG_SEND_PARAM_WITH_REG) {
+ get_rpm_param(
+ &dec->avs2_dec.param);
+ } else {
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
+ for (i = 0; i < (RPM_VALID_END - RPM_BEGIN); i += 4) {
+ int ii;
+ for (ii = 0; ii < 4; ii++)
+ dec->avs2_dec.param.l.data[i + ii] =
+ dec->rpm_ptr[i + 3 - ii];
+ }
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
+ }
+#ifdef SANITY_CHECK
+ if (dec->avs2_dec.param.p.num_of_ref_cur >
+ dec->avs2_dec.ref_maxbuffer) {
+ pr_info("Warning: Wrong num_of_ref_cur %d, force to %d\n",
+ dec->avs2_dec.param.p.num_of_ref_cur,
+ dec->avs2_dec.ref_maxbuffer);
+ dec->avs2_dec.param.p.num_of_ref_cur =
+ dec->avs2_dec.ref_maxbuffer;
+ }
+#endif
+ PRINT_LINE();
+
+ debug_buffer_mgr_more(dec);
+ get_frame_rate(&dec->avs2_dec.param, dec);
+
+ if (dec->avs2_dec.param.p.video_signal_type & (1<<14)) {
+ union param_u *pPara;
+
+ avs2_print(dec, AVS2_DBG_HDR_INFO, "avs2 HDR meta data present\n");
+ pPara = &dec->avs2_dec.param;
+
+ /*clean this flag*/
+ pPara->p.video_signal_type &= ~(1<<14);
+
+ dec->vf_dp.present_flag = 1;
+
+ dec->vf_dp.white_point[0] = pPara->p.white_point_x;
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "white_point[0]:0x%x\n",
+ dec->vf_dp.white_point[0]);
+
+ dec->vf_dp.white_point[1] = pPara->p.white_point_y;
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "white_point[1]:0x%x\n",
+ dec->vf_dp.white_point[1]);
+
+ for (i = 0; i < 3; i++) {
+ dec->vf_dp.primaries[i][0] = pPara->p.display_primaries_x[i];
+ dec->vf_dp.primaries[i][1] = pPara->p.display_primaries_y[i];
+
+ if (debug & AVS2_DBG_HDR_INFO) {
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "primaries[%d][0]:0x%x\n",
+ i,
+ dec->vf_dp.primaries[i][0]);
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "primaries[%d][1]:0x%x\n",
+ i,
+ dec->vf_dp.primaries[i][1]);
+ }
+ }
+
+ dec->vf_dp.luminance[0] = pPara->p.max_display_mastering_luminance;
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "luminance[0]:0x%x\n",
+ dec->vf_dp.luminance[0]);
+
+ dec->vf_dp.luminance[1] = pPara->p.min_display_mastering_luminance;
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "luminance[1]:0x%x\n",
+ dec->vf_dp.luminance[1]);
+
+ dec->vf_dp.content_light_level.present_flag = 1;
+ dec->vf_dp.content_light_level.max_content = pPara->p.max_content_light_level;
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "max_content:0x%x\n",
+ dec->vf_dp.content_light_level.max_content);
+
+ dec->vf_dp.content_light_level.max_pic_average
+ = pPara->p.max_picture_average_light_level;
+
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "max_pic_average:0x%x\n",
+ dec->vf_dp.content_light_level.max_pic_average);
+ }
+
+ if (dec->video_ori_signal_type !=
+ ((dec->avs2_dec.param.p.video_signal_type << 16)
+ | dec->avs2_dec.param.p.color_description)) {
+ u32 v = dec->avs2_dec.param.p.video_signal_type;
+ u32 c = dec->avs2_dec.param.p.color_description;
+ u32 convert_c = c;
+
+ if (v & 0x2000) {
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "video_signal_type present:\n");
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ " %s %s\n",
+ video_format_names[(v >> 10) & 7],
+ ((v >> 9) & 1) ?
+ "full_range" : "limited");
+ if (v & 0x100) {
+ u32 transfer;
+ u32 maxtrix;
+
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "color_description present:\n");
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "color_primarie = %d\n", v & 0xff);
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "transfer_characteristic = %d\n", (c >> 8) & 0xff);
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ " matrix_coefficient = %d\n", c & 0xff);
+
+ transfer = (c >> 8) & 0xFF;
+ if (transfer >= 15)
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "unsupport transfer_characteristic\n");
+ else if (transfer == 14)
+ transfer = 18; /* HLG */
+ else if (transfer == 13)
+ transfer = 32;
+ else if (transfer == 12)
+ transfer = 16;
+ else if (transfer == 11)
+ transfer = 15;
+
+ maxtrix = c & 0xFF;
+ if (maxtrix >= 10)
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ "unsupport matrix_coefficient\n");
+ else if (maxtrix == 9)
+ maxtrix = 10;
+ else if (maxtrix == 8)
+ maxtrix = 9;
+
+ convert_c = (transfer << 8) | (maxtrix);
+
+ avs2_print(dec, AVS2_DBG_HDR_INFO,
+ " convered c:0x%x\n",
+ convert_c);
+ }
+ }
+
+ if (enable_force_video_signal_type)
+ dec->video_signal_type = force_video_signal_type;
+ else {
+ dec->video_signal_type = (v << 16) | convert_c;
+ dec->video_ori_signal_type = (v << 16) | c;
+ }
+
+ video_signal_type = dec->video_signal_type;
+ }
+ dec->frame_width = dec->avs2_dec.param.p.horizontal_size;
+ dec->frame_height = dec->avs2_dec.param.p.vertical_size;
+ }
+ PRINT_LINE();
+ avs2_prepare_header(&dec->avs2_dec, start_code);
+
+ mutex_lock(&dec->slice_header_lock);
+ if (start_code == SEQUENCE_HEADER_CODE ||
+ start_code == VIDEO_EDIT_CODE ||
+ start_code == SEQUENCE_END_CODE) {
+ if (dec->m_ins_flag &&
+ vdec_frame_based(hw_to_vdec(dec)))
+ dec->start_decoding_flag |= 0x1;
+ dec->process_state = PROC_STATE_HEAD_DONE;
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+ } else if (start_code == I_PICTURE_START_CODE ||
+ start_code == PB_PICTURE_START_CODE) {
+ ret = 0;
+
+#ifdef NEW_FB_CODE
+ if (dec->m_ins_flag) {
+ u32 width = dec->avs2_dec.param.p.horizontal_size;
+ u32 height = dec->avs2_dec.param.p.vertical_size;
+ u8 bit_depth = AVS2_BITS_8;
+ int cur_mmu_fb_4k_number = 0;
+
+ if (dec->avs2_dec.param.p.profile_id == BASELINE10_PROFILE) {
+ bit_depth = dec->avs2_dec.param.p.encoding_precision;
+ bit_depth = 6 + bit_depth * 2;
+ }
+ cur_mmu_fb_4k_number = dec->fb_ifbuf_num * avs2_mmu_page_num(dec,
+ width, height, (bit_depth == 10));
+
+ if ((dec->front_back_mode == 1) &&
+ (start_code == I_PICTURE_START_CODE) &&
+ (dec->mmu_fb_4k_number < cur_mmu_fb_4k_number) &&
+ (cur_mmu_fb_4k_number > 0)) {
+ dec->init_pic_h = dec->avs2_dec.param.p.vertical_size;
+ dec->init_pic_w = dec->avs2_dec.param.p.horizontal_size;
+
+ amhevc_stop_f();
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s: need realloc cur_mmu_fb_4k_number %d, mmu_4k_number %d\n",
+ __func__, cur_mmu_fb_4k_number, dec->mmu_fb_4k_number);
+ uninit_mmu_fb_bufstate(dec);
+ init_mmu_fb_bufstate(dec, cur_mmu_fb_4k_number);
+ dec_again_process(dec);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+ }
+#endif
+
+ //dec->avs2_dec.ins_offset = 0; //move to init_pic_list_hw_fb
+ if (dec->pic_list_init_flag == 0) {
+ avs2_init_global_buffers(&dec->avs2_dec);
+ /*avs2_dec->m_bg->index is
+ set to dec->used_buf_num - 1*/
+ if ((dec->front_back_mode == 1) && (paral_alloc_buffer_mode & 1)) {
+ if ((dec->pic_list_wait_alloc_done_flag == BUFFER_INIT)) {
+ dec->dec_result = DEC_RESULT_WAIT_BUFFER;
+ avs2_print(dec, AVS2_DBG_BUFMGR, "alloc buffer\n");
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+ vdec_schedule_work(&dec->work);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+ } else
+ init_pic_list(dec);
+#ifdef NEW_FB_CODE
+ if ((dec->front_back_mode == 1) ||
+ (dec->front_back_mode == 3))
+ init_pic_list_hw_fb(dec);
+ else
+#endif
+ init_pic_list_hw(dec);
+ dec->pic_list_init_flag = 1;
+ }
+
+alloc_buffer_done:
+
+ ret = avs2_process_header(&dec->avs2_dec);
+ if (!dec->m_ins_flag)
+ dec->slice_idx++;
+
+ if (dec->m_ins_flag && ret > 0
+ && dec->avs2_dec.hc.cur_pic->cuva_data_buf != NULL)
+ release_cuva_data(dec->avs2_dec.hc.cur_pic);
+
+ PRINT_LINE();
+#ifdef I_ONLY_SUPPORT
+ if ((start_code == PB_PICTURE_START_CODE) &&
+ (dec->i_only & 0x2))
+ ret = -2;
+#endif
+
+ if (ret >= 0) {
+#ifdef AVS2_10B_MMU
+ if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ ) {
+ ret = avs2_alloc_mmu(dec,
+ dec->avs2_dec.hc.cur_pic->index,
+ dec->avs2_dec.img.width,
+ dec->avs2_dec.img.height,
+ dec->avs2_dec.input.sample_bit_depth,
+ dec->frame_mmu_map_addr);
+ if (ret >= 0) {
+ dec->cur_fb_idx_mmu =
+ dec->avs2_dec.hc.cur_pic->index;
+ dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
+ } else
+ pr_err("can't alloc need mmu1,idx %d ret =%d\n",
+ dec->avs2_dec.hc.cur_pic->index,
+ ret);
+ }
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ ret = avs2_alloc_dw_mmu(dec,
+ dec->avs2_dec.hc.cur_pic->index,
+ dec->avs2_dec.img.width,
+ dec->avs2_dec.img.height,
+ dec->avs2_dec.input.sample_bit_depth,
+ dec->dw_frame_mmu_map_addr);
+ if (ret >= 0) {
+ dec->cur_fb_idx_mmu =
+ dec->avs2_dec.hc.cur_pic->index;
+ dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
+ } else
+ pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
+ dec->avs2_dec.hc.cur_pic->index,
+ ret);
+ }
+#endif
+ }
+
+#ifndef MV_USE_FIXED_BUF
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+
+ if (ret >= 0 && dec->avs2_dec.hc.cur_pic->
+ mpred_mv_wr_start_addr == 0) {
+ unsigned long buf_addr;
+ unsigned mv_buf_size = get_mv_buf_size(
+ dec,
+ dec->avs2_dec.hc.cur_pic->pic_w,
+ dec->avs2_dec.hc.cur_pic->pic_h);
+ int i = dec->avs2_dec.hc.cur_pic->index;
+
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ MV_BUFFER_IDX(i),
+ mv_buf_size,
+ DRIVER_NAME,
+ &buf_addr) < 0) {
+ ret = -1;
+ } else {
+ dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr = buf_addr;
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr,
+ 0, mv_buf_size);
+ }
+ }
+
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+#endif
+ if (ret < 0) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n", ret);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
+ #ifdef AVS2_10B_MMU
+ if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ )
+ avs2_recycle_mmu_buf(dec);
+ #endif
+ if (dec->m_ins_flag) {
+ int slice_type = 0;
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+#ifdef NEW_FB_CODE
+ mutex_lock(&dec->fb_mutex);
+#endif
+ if (cur_pic != NULL) {
+ slice_type = cur_pic->slice_type;
+ } else {
+ slice_type = dec->avs2_dec.img.type;
+ }
+
+ dec->gvs->frame_count++;
+ dec->gvs->drop_frame_count++;
+ dec->gvs->error_frame_count++;
+
+ if (slice_type == I_IMG) {
+ dec->gvs->i_lost_frames++;
+ dec->gvs->i_concealed_frames++;
+ dec->gvs->i_decoded_frames++;
+ } else if ((slice_type == P_IMG) ||
+ (slice_type == F_IMG)) {
+ dec->gvs->p_lost_frames++;
+ dec->gvs->p_concealed_frames++;
+ dec->gvs->p_decoded_frames++;
+ } else if (slice_type == B_IMG) {
+ dec->gvs->b_lost_frames++;
+ dec->gvs->b_concealed_frames++;
+ dec->gvs->b_decoded_frames++;
+ }
+#ifdef NEW_FB_CODE
+ mutex_unlock(&dec->fb_mutex);
+#endif
+
+ dec->dec_result = DEC_RESULT_ERROR;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ } else {
+ struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+#ifdef NEW_FRONT_BACK_CODE
+ if (dec->front_back_mode) {
+ cur_pic->width = avs2_dec->img.width;
+ cur_pic->height = avs2_dec->img.height;
+ cur_pic->depth = avs2_dec->input.sample_bit_depth;
+ for (i = 0; i < MAXREF; i++)
+ cur_pic->ref_pic[i] = NULL;
+ }
+#endif
+
+ if (cur_pic != NULL) {
+ dec->gvs->frame_count++;
+ if (cur_pic->slice_type == I_IMG) {
+ dec->gvs->i_decoded_frames++;
+ } else if ((cur_pic->slice_type == P_IMG) ||
+ (cur_pic->slice_type == F_IMG)) {
+ dec->gvs->p_decoded_frames++;
+ } else if (cur_pic->slice_type == B_IMG) {
+ dec->gvs->b_decoded_frames++;
+ }
+ }
+
+ cur_pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+
+ if (!dec->m_ins_flag) {
+ dec->frame_count++;
+ decode_frame_count[dec->index] = dec->frame_count;
+ }
+ /*MULTI_INSTANCE_SUPPORT*/
+ if (dec->chunk) {
+ cur_pic->pts = dec->chunk->pts;
+ cur_pic->pts64 = dec->chunk->pts64;
+ }
+
+ cur_pic->bit_depth = dec->avs2_dec.input.sample_bit_depth;
+ cur_pic->double_write_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+ cur_pic->triple_write_mode = get_triple_write_mode(dec);
+#endif
+
+ if (vdec->mvfrm)
+ cur_pic->frame_size = vdec->mvfrm->frame_size;
+decode_slice:
+ PRINT_LINE();
+
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+ if (!efficiency_mode) {
+ config_mc_buffer_fb(dec);
+ config_mcrcc_axi_hw_fb(dec);
+ }
+ config_mpred_hw_fb(dec);
+ if (!efficiency_mode) {
+ config_dblk_hw_fb(dec);
+ config_sao_hw_fb(dec);
+ config_alf_hw_fb(dec);
+ }
+ config_other_hw_fb(dec);
+ } else {
+#endif
+ config_mc_buffer(dec);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 0)
+#endif
+ config_mcrcc_axi_hw(dec);
+ config_mpred_hw(dec);
+ config_dblk_hw(dec);
+ config_sao_hw(dec);
+ config_alf_hw(dec);
+ config_other_hw(dec);
+#ifdef NEW_FB_CODE
+ }
+#endif
+ ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "=>fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, dis2/dis3/dis4 %d %d %d img->tr %d\n",
+ dec->avs2_dec.fref[0]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[1]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[2]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[3]->imgtr_fwRefDistance,
+ dec->avs2_dec.fref[4]->imgtr_fwRefDistance,
+ dec->avs2_dec.img.tr);
+
+ if ((debug_again & 0x2) &&
+ dec->process_state == PROC_STATE_INIT) {
+ dec->process_state = PROC_STATE_DECODING;
+ dec_again_process(dec);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+
+ dec->process_state = PROC_STATE_DECODING;
+#ifdef NEW_FRONT_BACK_CODE
+ if ((!efficiency_mode) && (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3)) {
+
+ WRITE_BACK_RET(avs2_dec);
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "write system instruction, ins_offset = %d, addr = 0x%x\n",
+ avs2_dec->ins_offset, avs2_dec->fr.sys_imem_ptr);
+ avs2_dec->sys_imem_ptr = avs2_dec->fr.sys_imem_ptr;
+ avs2_dec->sys_imem_ptr_v = avs2_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset > 512) {
+ avs2_print(dec, 0, "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs2_dec->ins_offset);
+ avs2_dec->ins_offset = 512;
+ } else if (avs2_dec->ins_offset < 256) {
+ avs2_dec->ins_offset = 256;
+ WRITE_BACK_RET(avs2_dec);
+ }
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+ avs2_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs2_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+
+ if (avs2_dec->ins_offset > 256) {
+ avs2_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs2_dec->ins_offset);
+ avs2_dec->ins_offset = 256;
+ }
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+ avs2_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs2_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+
+ if (avs2_dec->sys_imem_ptr >= avs2_dec->fb_buf_sys_imem.buf_end) {
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "sys_imem_ptr is 0x%x, wrap around\n", avs2_dec->sys_imem_ptr);
+ avs2_dec->sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+ avs2_dec->sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr;
+ }
+ if (dec->front_back_mode == 1) {
+ //WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+ //imem_count++;
+ WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+ }
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ }
+ else
+#endif
+ {
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+ }
+ }
+
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC);
+ }
+
+ if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+ (dec_status == AVS2_HEAD_PIC_PB_READY)) {
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+ }
+
+ if ((dec->front_back_mode == 1) && efficiency_mode) {
+ if (dec->pic_list_init_flag == 2) {
+#ifdef NEW_FB_CODE
+ if ((dec->front_back_mode == 1) ||
+ (dec->front_back_mode == 3))
+ init_pic_list_hw_fb(dec);
+ else
+#endif
+ init_pic_list_hw(dec);
+ }
+
+ if ((dec->front_back_mode == 1 || dec->front_back_mode == 3) &&
+ (start_code == I_PICTURE_START_CODE ||
+ start_code == PB_PICTURE_START_CODE)) {
+
+ int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+ };
+ int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+ };
+ config_mc_buffer_fb(dec);
+ config_mcrcc_axi_hw_fb(dec);
+ config_dblk_hw_fb(dec);
+ config_sao_hw_fb(dec);
+ config_alf_hw_fb(dec);
+
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+ for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+ for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+ for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+ for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+ WRITE_BACK_RET(avs2_dec);
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "write system instruction, ins_offset = %d, addr = 0x%x\n",
+ avs2_dec->ins_offset, avs2_dec->fr.sys_imem_ptr);
+ avs2_dec->sys_imem_ptr = avs2_dec->fr.sys_imem_ptr;
+ avs2_dec->sys_imem_ptr_v = avs2_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs2_dec->ins_offset > 512) {
+ avs2_print(dec, 0, "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs2_dec->ins_offset);
+ avs2_dec->ins_offset = 512;
+ } else if (avs2_dec->ins_offset < 256) {
+ avs2_dec->ins_offset = 256;
+ WRITE_BACK_RET(avs2_dec);
+ }
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+ avs2_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs2_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+
+ if (avs2_dec->ins_offset > 256) {
+ avs2_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs2_dec->ins_offset);
+ avs2_dec->ins_offset = 256;
+ }
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+ avs2_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs2_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+
+ if (avs2_dec->sys_imem_ptr >= avs2_dec->fb_buf_sys_imem.buf_end) {
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "sys_imem_ptr is 0x%x, wrap around\n", avs2_dec->sys_imem_ptr);
+ avs2_dec->sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+ avs2_dec->sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr;
+ }
+ if (dec->front_back_mode == 1) {
+ //WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+ //imem_count++;
+ WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+ }
+ }
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)
+ || (start_code == SEQUENCE_END_CODE)
+ || (start_code == VIDEO_EDIT_CODE)) {
+
+ avs2_prepare_display_buf(dec);
+ }
+ }
+ PRINT_LINE();
+ mutex_unlock(&dec->slice_header_lock);
+
+irq_handled_exit:
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t vavs2_isr(int irq, void *data)
+{
+ int i;
+ unsigned int dec_status;
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data;
+ uint debug_tag = 0;
+
+ dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
+ if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC);
+ }
+
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ if ((debug & AVS2_DBG_BE_SIMULATE_IRQ)
+ &&(READ_VREG(DEBUG_REG1_DBE) ||
+ READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ }
+
+ if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+ (dec_status == AVS2_HEAD_PIC_PB_READY)) {
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
+ } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_PIC_DONE);
+ }
+
+ if (!dec)
+ return IRQ_HANDLED;
+ if (dec->init_flag == 0)
+ return IRQ_HANDLED;
+ if (dec->process_busy)/*on process.*/
+ return IRQ_HANDLED;
+ dec->dec_status = dec_status;
+ dec->process_busy = 1;
+ if (debug & AVS2_DBG_IRQ_EVENT) {
+ if (dec->front_back_mode != 1)
+ avs2_print(dec, 0,
+ "avs2 isr dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_SAO_CRC %x\n",
+ dec_status, READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+ READ_VREG(HEVC_SAO_CRC) : 0
+ );
+ else
+ avs2_print(dec, 0,
+ "avs2 isr dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_DECODE_SIZE %x [BE] pc %x psr %x DEC_STATUS %x\n",
+ dec_status, READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ READ_VREG(HEVC_DECODE_SIZE),
+ READ_VREG(HEVC_MPC_E_DBE),
+ READ_VREG(HEVC_MPSR_DBE),
+ READ_VREG(HEVC_DEC_STATUS_DBE)
+ );
+ }
+ if (udebug_flag)
+ debug_tag = READ_HREG(DEBUG_REG1);
+ if (debug_tag & 0x10000) {
+ dma_sync_single_for_cpu(
+ amports_get_dma_device(),
+ dec->lmem_phy_addr,
+ LMEM_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
+ pr_info("LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
+ for (i = 0; i < 0x400; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ", dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == dec->decode_idx) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_HREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ dec->ucode_pause_pos = udebug_pause_pos;
+ } else if (debug_tag & 0x20000)
+ dec->ucode_pause_pos = 0xffffffff;
+ if (dec->ucode_pause_pos)
+ reset_process_time(dec);
+ else
+ WRITE_HREG(DEBUG_REG1, 0);
+ } else if (debug_tag != 0) {
+ pr_info("dbg%x: %x lcu %x stream crc %x, shiftbytes 0x%x decbytes 0x%x\n",
+ READ_HREG(DEBUG_REG1), READ_HREG(DEBUG_REG2), READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ (u32)(READ_VREG(HEVC_SHIFT_BYTE_COUNT) - dec->start_shift_bytes));
+
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == dec->decode_idx) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_HREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ dec->ucode_pause_pos = udebug_pause_pos;
+ }
+ if (dec->ucode_pause_pos)
+ reset_process_time(dec);
+ else
+ WRITE_HREG(DEBUG_REG1, 0);
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ }
+
+ if (!dec->m_ins_flag) {
+ if (dec->error_flag == 1) {
+ dec->error_flag = 2;
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ } else if (dec->error_flag == 3) {
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ }
+
+ if ((dec->pic_list_init_flag) &&
+ get_free_buf_count(dec) <= 0) {
+ dec->wait_buf = 1;
+ dec->process_busy = 0;
+ if (debug & AVS2_DBG_IRQ_EVENT)
+ avs2_print(dec, 0, "wait_buf\n");
+ return IRQ_HANDLED;
+ } else if (force_disp_pic_index) {
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ }
+ }
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_END);
+ return IRQ_WAKE_THREAD;
+}
+
+#ifdef NEW_FB_CODE
+static void avs2_check_timer_back_func(struct timer_list *timer)
+{
+ struct AVS2Decoder_s *dec = container_of(timer,
+ struct AVS2Decoder_s, timer_back);
+
+ if (dec->init_flag == 0) {
+ if (dec->stat & STAT_TIMER_BACK_ARM) {
+ mod_timer(&dec->timer_back, jiffies + PUT_INTERVAL);
+ }
+ return;
+ }
+
+ if (
+ (decode_timeout_val_back > 0) &&
+ (dec->start_process_time_back > 0) &&
+ ((1000 * (jiffies - dec->start_process_time_back) / HZ)
+ > decode_timeout_val_back)
+ ) {
+ if (dec->decode_timeout_count_back > 0)
+ dec->decode_timeout_count_back--;
+ if (dec->decode_timeout_count_back == 0)
+ timeout_process_back(dec);
+ }
+
+ if (debug & AVS2_DBG_BE_SIMULATE_IRQ) {
+ //struct vdec_s *vdec = hw_to_vdec(dec);
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ //if (avs3_back_irq_cb(vdec, 0) == IRQ_WAKE_THREAD)
+ // avs3_back_threaded_irq_cb(vdec, 0);
+ }
+
+ if ((dec->back_timer_check_count != 0) &&
+ !(dec->error_proc_policy & 0x2) &&
+ (decode_timeout_val_back > 0)) {
+ int current_monitor_data = 0;
+
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (READ_VREG(HEVC_PATH_MONITOR_CTRL) & 0xfffffe0f) | 0x91);
+ current_monitor_data = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (dec->last_monitor_data == current_monitor_data) {
+ if (dec->back_timer_check_count > 0)
+ dec->back_timer_check_count--;
+ if (dec->back_timer_check_count == 0) {
+ timeout_process_back(dec);
+ }
+ } else {
+ dec->back_timer_check_count = back_timer_check_count;
+ }
+ dec->last_monitor_data = current_monitor_data;
+ mod_timer(timer, jiffies + 1);
+ } else
+ mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+#endif
+
+static void vavs2_put_timer_func(struct timer_list *timer)
+{
+ struct AVS2Decoder_s *dec = container_of(timer,
+ struct AVS2Decoder_s, timer);
+ uint8_t empty_flag;
+ unsigned int buf_level;
+
+ enum receiver_start_e state = RECEIVER_INACTIVE;
+
+ if (dec->init_flag == 0) {
+ if (dec->stat & STAT_TIMER_ARM) {
+ timer->expires = jiffies + PUT_INTERVAL;
+ add_timer(&dec->timer);
+ }
+ return;
+ }
+ if (dec->m_ins_flag == 0) {
+ if (vf_get_receiver(dec->provider_name)) {
+ state =
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE,
+ NULL);
+ if ((state == RECEIVER_STATE_NULL)
+ || (state == RECEIVER_STATE_NONE))
+ state = RECEIVER_INACTIVE;
+ } else
+ state = RECEIVER_INACTIVE;
+
+ empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
+ /* error watchdog */
+ if (empty_flag == 0) {
+ /* decoder has input */
+ if ((debug & AVS2_DBG_DIS_LOC_ERROR_PROC) == 0) {
+
+ buf_level = READ_VREG(HEVC_STREAM_LEVEL);
+ /* receiver has no buffer to recycle */
+ if ((state == RECEIVER_INACTIVE) &&
+ (kfifo_is_empty(&dec->display_q) &&
+ buf_level > 0x200)) {
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ }
+ }
+ }
+ } else {
+ if (
+ (decode_timeout_val > 0) &&
+ (dec->start_process_time > 0) &&
+ ((1000 * (jiffies - dec->start_process_time) / HZ) > decode_timeout_val)) {
+ int current_lcu_idx = READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff;
+ if (dec->last_lcu_idx == current_lcu_idx) {
+ if (dec->decode_timeout_count > 0)
+ dec->decode_timeout_count--;
+ if (dec->decode_timeout_count == 0) {
+ if (input_frame_based(
+ hw_to_vdec(dec)) ||
+ (READ_VREG(HEVC_STREAM_LEVEL) > 0x200))
+ timeout_process(dec);
+ else {
+ avs2_print(dec, 0,
+ "timeout & empty, again\n");
+ dec_again_process(dec);
+ }
+ }
+ } else {
+ start_process_time(dec);
+ dec->last_lcu_idx = current_lcu_idx;
+ }
+ }
+ }
+
+ if ((dec->ucode_pause_pos != 0) &&
+ (dec->ucode_pause_pos != 0xffffffff) &&
+ udebug_pause_pos != dec->ucode_pause_pos) {
+ dec->ucode_pause_pos = 0;
+ WRITE_HREG(DEBUG_REG1, 0);
+ }
+ if (debug & AVS2_DBG_DUMP_DATA) {
+ debug &= ~AVS2_DBG_DUMP_DATA;
+ avs2_print(dec, 0,
+ "%s: chunk size 0x%x off 0x%x sum 0x%x\n",
+ __func__,
+ dec->chunk->size,
+ dec->chunk->offset,
+ get_data_check_sum(dec, dec->chunk->size));
+ dump_data(dec, dec->chunk->size);
+ }
+ if (debug & AVS2_DBG_DUMP_PIC_LIST) {
+ dump_pic_list(dec);
+ debug &= ~AVS2_DBG_DUMP_PIC_LIST;
+ }
+ if (debug & AVS2_DBG_TRIG_SLICE_SEGMENT_PROC) {
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ debug &= ~AVS2_DBG_TRIG_SLICE_SEGMENT_PROC;
+ }
+ if (debug & AVS2_DBG_DUMP_RPM_BUF) {
+ int i;
+
+ pr_info("RPM:\n");
+ for (i = 0; i < RPM_BUF_SIZE; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ",
+ dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+ debug &= ~AVS2_DBG_DUMP_RPM_BUF;
+ }
+ if (debug & AVS2_DBG_DUMP_LMEM_BUF) {
+ int i;
+
+ pr_info("LMEM:\n");
+ for (i = 0; i < LMEM_BUF_SIZE; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ",
+ dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+ debug &= ~AVS2_DBG_DUMP_LMEM_BUF;
+ }
+
+ if (radr != 0) {
+ if (rval != 0) {
+ WRITE_VREG(radr, rval);
+ pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
+ } else
+ pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
+ rval = 0;
+ radr = 0;
+ }
+ if (pop_shorts != 0) {
+ int i;
+ u32 sum = 0;
+ pr_info("pop stream 0x%x shorts\r\n", pop_shorts);
+ for (i = 0; i < pop_shorts; i++) {
+ u32 data =
+ (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
+ WRITE_HREG(HEVC_SHIFT_COMMAND,
+ (1<<7)|16);
+ if ((i & 0xf) == 0)
+ pr_info("%04x:", i);
+ pr_info("%04x ", data);
+ if (((i + 1) & 0xf) == 0)
+ pr_info("\r\n");
+ sum += data;
+ }
+ pr_info("\r\nsum = %x\r\n", sum);
+ pop_shorts = 0;
+ }
+ if (dbg_cmd != 0) {
+ if (dbg_cmd == 1) {
+ u32 disp_laddr;
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
+ get_double_write_mode(dec) == 0) {
+ disp_laddr =
+ READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
+ } else {
+ struct canvas_s cur_canvas;
+ canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
+ & 0xff), &cur_canvas);
+ disp_laddr = cur_canvas.addr;
+ }
+ pr_info("current displayed buffer address %x\r\n",
+ disp_laddr);
+ }
+ dbg_cmd = 0;
+ }
+ /*don't changed at start.*/
+ if (dec->get_frame_dur && dec->show_frame_num > 60 &&
+ dec->frame_dur > 0 && dec->saved_resolution !=
+ frame_width * frame_height * (96000 / dec->frame_dur)) {
+ int fps = 96000 / dec->frame_dur;
+ if (hevc_source_changed(VFORMAT_AVS2,
+ frame_width, frame_height, fps) > 0)
+ dec->saved_resolution = frame_width * frame_height * fps;
+ }
+
+ timer->expires = jiffies + PUT_INTERVAL;
+ add_timer(timer);
+}
+
+int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+
+ if (!dec)
+ return -1;
+
+ vstatus->frame_width = dec->frame_width;
+ vstatus->frame_height = dec->frame_height;
+
+ if (dec->frame_dur != 0)
+ vstatus->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+ 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
+ else
+ vstatus->frame_rate = -1;
+ vstatus->error_count = 0;
+ vstatus->status = dec->stat | dec->fatal_error;
+ vstatus->frame_dur = dec->frame_dur;
+ vstatus->bit_rate = dec->gvs->bit_rate;
+ vstatus->frame_data = dec->gvs->frame_data;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->frame_count = dec->gvs->frame_count;
+ vstatus->error_frame_count = dec->gvs->error_frame_count;
+ vstatus->drop_frame_count = dec->gvs->drop_frame_count;
+ vstatus->i_decoded_frames = dec->gvs->i_decoded_frames;
+ vstatus->i_lost_frames = dec->gvs->i_lost_frames;
+ vstatus->i_concealed_frames = dec->gvs->i_concealed_frames;
+ vstatus->p_decoded_frames = dec->gvs->p_decoded_frames;
+ vstatus->p_lost_frames = dec->gvs->p_lost_frames;
+ vstatus->p_concealed_frames = dec->gvs->p_concealed_frames;
+ vstatus->b_decoded_frames = dec->gvs->b_decoded_frames;
+ vstatus->b_lost_frames = dec->gvs->b_lost_frames;
+ vstatus->b_concealed_frames = dec->gvs->b_concealed_frames;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->samp_cnt = dec->gvs->samp_cnt;
+ vstatus->offset = dec->gvs->offset;
+ snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME);
+ return 0;
+}
+
+int vavs2_set_isreset(struct vdec_s *vdec, int isreset)
+{
+ is_reset = isreset;
+ return 0;
+}
+
+static void vavs2_prot_init(struct AVS2Decoder_s *dec)
+{
+ avs2_config_work_space_hw(dec);
+ if (dec->pic_list_init_flag)
+ init_pic_list_hw(dec);
+
+ avs2_init_decoder_hw(dec);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s\n", __func__);
+#if 0
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 | (1 << 0); /*stream_fetch_enable*/
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
+
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+ WRITE_VREG(DEBUG_REG1, 0x0);
+ /*check vps/sps/pps/i-slice in ucode*/
+ WRITE_VREG(NAL_SEARCH_CTL, 0x8);
+
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+
+ config_cuva_buf(dec);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ WRITE_VREG(HEVC_SAO_CRC, 0);
+ if (dec->front_back_mode == 1)
+ WRITE_VREG(HEVC_SAO_CRC_DBE1, 0);
+ }
+
+}
+
+#ifdef I_ONLY_SUPPORT
+static int vavs2_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ if (i_only_flag & 0x100)
+ return 0;
+ if (trickmode == TRICKMODE_I || trickmode == TRICKMODE_I_HEVC)
+ dec->i_only = 0x3;
+ else if (trickmode == TRICKMODE_NONE)
+ dec->i_only = 0x0;
+ return 0;
+}
+#endif
+
+static int vavs2_local_init(struct AVS2Decoder_s *dec)
+{
+ int i;
+ int ret;
+ int width, height;
+
+ dec->vavs2_ratio = dec->vavs2_amstream_dec_info.ratio;
+
+ dec->gvs = vzalloc(sizeof(struct vdec_info));
+ if (NULL == dec->gvs) {
+ avs2_print(dec, 0,
+ "the struct of vdec status malloc failed.\n");
+ return -1;
+ }
+#ifdef DEBUG_PTS
+ dec->pts_missed = 0;
+ dec->pts_hit = 0;
+#endif
+ dec->new_frame_displayed = 0;
+ dec->last_put_idx = -1;
+ dec->saved_resolution = 0;
+ dec->get_frame_dur = false;
+ on_no_keyframe_skiped = 0;
+ width = dec->vavs2_amstream_dec_info.width;
+ height = dec->vavs2_amstream_dec_info.height;
+ dec->frame_dur = (dec->vavs2_amstream_dec_info.rate == 0) ?
+ 3600 : dec->vavs2_amstream_dec_info.rate;
+ if (width && height)
+ dec->frame_ar = height * 0x100 / width;
+
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "avs2: ver (%d,%d) decinfo: %dx%d rate=%d\n", avs2_version,
+ 0, width, height, dec->frame_dur);
+
+ if (dec->frame_dur == 0)
+ dec->frame_dur = 96000 / 24;
+#ifdef I_ONLY_SUPPORT
+ if (i_only_flag & 0x100)
+ dec->i_only = i_only_flag & 0xff;
+ else if ((unsigned long) dec->vavs2_amstream_dec_info.param & 0x08)
+ dec->i_only = 0x7;
+ else
+ dec->i_only = 0x0;
+#endif
+ INIT_KFIFO(dec->display_q);
+ INIT_KFIFO(dec->newframe_q);
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ const struct vframe_s *vf = &dec->vfpool[i];
+ dec->vfpool[i].index = -1;
+ kfifo_put(&dec->newframe_q, vf);
+ }
+
+ ret = avs2_local_init(dec);
+
+ return ret;
+}
+
+static s32 vavs2_init(struct vdec_s *vdec)
+{
+ int ret = -1, size = -1;
+ int fw_size = 0x1000 * 16;
+ struct firmware_s *fw = NULL;
+#ifdef NEW_FB_CODE
+ struct firmware_s *fw_back = NULL;
+#endif
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ timer_setup(&dec->timer, vavs2_put_timer_func, 0);
+#ifdef NEW_FB_CODE
+ timer_setup(&dec->timer_back, avs2_check_timer_back_func, 0);
+ dec->stat |= STAT_TIMER_BACK_INIT;
+#endif
+
+ dec->stat |= STAT_TIMER_INIT;
+ if (vavs2_local_init(dec) < 0)
+ return -EBUSY;
+
+ avs2_dec->start_time = div64_u64(local_clock(), 1000);
+ vdec_set_vframe_comm(vdec, DRIVER_NAME);
+
+ fw = vmalloc(sizeof(struct firmware_s) + fw_size);
+ if (IS_ERR_OR_NULL(fw))
+ return -ENOMEM;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+ fw_back = vzalloc(sizeof(struct firmware_s) + fw_size);
+ if (IS_ERR_OR_NULL(fw_back))
+ return -ENOMEM;
+
+ size = get_firmware_data(VIDEO_DEC_AVS2_FRONT, fw->data);
+
+ fw_back->len = get_firmware_data(VIDEO_DEC_AVS2_BACK, fw_back->data);
+ if (fw_back->len < 0) {
+ pr_err("get back firmware fail.\n");
+ vfree(fw_back);
+ return -1;
+ }
+ } else
+#endif
+ size = get_firmware_data(VIDEO_DEC_AVS2_MMU, fw->data);
+ if (size < 0) {
+ pr_err("get firmware fail.\n");
+ vfree(fw);
+ return -1;
+ }
+
+ fw->len = fw_size;
+
+ if (dec->m_ins_flag) {
+ dec->timer.expires = jiffies + PUT_INTERVAL;
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->timer_back.expires = jiffies + PUT_INTERVAL;
+ dec->fw_back = fw_back;
+ }
+#endif
+
+ INIT_WORK(&dec->work, avs2_work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ INIT_WORK(&dec->work_back, avs2_work_back);
+ INIT_WORK(&dec->timeout_work_back, avs2_timeout_work_back);
+ mutex_init(&dec->fb_mutex);
+ }
+#endif
+ dec->fw = fw;
+
+ return 0;
+ }
+
+ amhevc_enable();
+
+ ret = amhevc_loadmc_ex(VFORMAT_AVS2, NULL, fw->data);
+ if (ret < 0) {
+ amhevc_disable();
+ vfree(fw);
+ pr_err("AVS2: the %s fw loading failed, err: %x\n",
+ fw_tee_enabled() ? "TEE" : "local", ret);
+ return -EBUSY;
+ }
+
+ vfree(fw);
+
+ dec->stat |= STAT_MC_LOAD;
+
+ /* enable AMRISC side protocol */
+ vavs2_prot_init(dec);
+
+ if (vdec_request_threaded_irq(VDEC_IRQ_0,
+ vavs2_isr,
+ vavs2_isr_thread_fn,
+ IRQF_ONESHOT,/*run thread on this irq disabled*/
+ "vavs2-irq", (void *)dec)) {
+ pr_info("vavs2 irq register error.\n");
+ amhevc_disable();
+ return -ENOENT;
+ }
+
+ dec->stat |= STAT_ISR_REG;
+
+ dec->provider_name = PROVIDER_NAME;
+ vf_provider_init(&vavs2_vf_prov, PROVIDER_NAME,
+ &vavs2_vf_provider, dec);
+ vf_reg_provider(&vavs2_vf_prov);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
+ if (dec->frame_dur != 0) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)
+ ((unsigned long)dec->frame_dur));
+ }
+ dec->stat |= STAT_VF_HOOK;
+
+ dec->timer.expires = jiffies + PUT_INTERVAL;
+ add_timer(&dec->timer);
+
+ dec->stat |= STAT_TIMER_ARM;
+
+ dec->process_busy = 0;
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "%d, vavs2_init, RP=0x%x\n",
+ __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
+ return 0;
+}
+
+static int vmavs2_stop(struct AVS2Decoder_s *dec)
+{
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+#endif
+ if (dec->stat & STAT_VF_HOOK) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT,
+ NULL);
+
+ vf_unreg_provider(&vavs2_vf_prov);
+ dec->stat &= ~STAT_VF_HOOK;
+ }
+ avs2_local_uninit(dec);
+ reset_process_time(dec);
+ cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ cancel_work_sync(&dec->work_back);
+ vfree(dec->fw_back);
+ dec->fw_back = NULL;
+ }
+#endif
+ uninit_mmu_buffers(dec);
+ if (dec->fw) {
+ vfree(dec->fw);
+ dec->fw = NULL;
+ }
+
+ return 0;
+}
+
+static int vavs2_stop(struct AVS2Decoder_s *dec)
+{
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ if (dec->stat & STAT_VDEC_RUN) {
+ amhevc_stop();
+ dec->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (dec->stat & STAT_ISR_REG) {
+ if (!dec->m_ins_flag)
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 0);
+ vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+ dec->stat &= ~STAT_ISR_REG;
+ }
+
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+#endif
+
+ if (dec->stat & STAT_VF_HOOK) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT,
+ NULL);
+
+ vf_unreg_provider(&vavs2_vf_prov);
+ dec->stat &= ~STAT_VF_HOOK;
+ }
+ avs2_local_uninit(dec);
+
+ if (dec->m_ins_flag) {
+ cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ cancel_work_sync(&dec->work_back);
+ vfree(dec->fw_back);
+ dec->fw_back = NULL;
+ }
+#endif
+ } else
+ amhevc_disable();
+ uninit_mmu_buffers(dec);
+
+ return 0;
+}
+
+static int amvdec_avs2_mmu_init(struct AVS2Decoder_s *dec)
+{
+ int tvp_flag = vdec_secure(hw_to_vdec(dec)) ?
+ CODEC_MM_FLAGS_TVP : 0;
+ int buf_size = 48;
+
+ dec->need_cache_size = buf_size * SZ_1M;
+ dec->sc_start_time = get_jiffies_64();
+#ifdef AVS2_10B_MMU
+ if (dec->mmu_enable) {
+ dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag);
+ if (!dec->mmu_box) {
+ pr_err("avs2 alloc mmu box failed!!\n");
+ return -1;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->mmu_box_1) {
+ pr_err("avs2 alloc mmu box1 failed!!\n");
+ return -1;
+ }
+ }
+ }
+#endif
+#ifdef AVS2_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ dec->dw_mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag);
+ if (!dec->dw_mmu_box) {
+ pr_err("avs2 alloc dw mmu box failed!!\n");
+ dec->dw_mmu_enable = 0;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->dw_mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->dw_mmu_box_1) {
+ pr_err("avs2 alloc dw mmu box1 failed!!\n");
+ dec->dw_mmu_enable = 0;
+ }
+ }
+#endif
+ }
+#endif
+ dec->bmmu_box = decoder_bmmu_box_alloc_box(
+ DRIVER_NAME,
+ dec->index,
+ MAX_BMMU_BUFFER_NUM,
+ 4 + PAGE_SHIFT,
+ CODEC_MM_FLAGS_CMA_CLEAR |
+ CODEC_MM_FLAGS_FOR_VDECODER |
+ tvp_flag,
+ BMMU_ALLOC_FLAGS_WAITCLEAR);
+ if (!dec->bmmu_box) {
+ pr_err("avs2 alloc bmmu box failed!!\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int amvdec_avs2_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ struct AVS2Decoder_s *dec = &gAVS2Decoder;
+ int ret;
+ pr_info("%s\n", __func__);
+
+ dec = vzalloc(sizeof(struct AVS2Decoder_s));
+ if (!dec)
+ return -ENOMEM;
+
+ pdata->private = dec;
+ platform_set_drvdata(pdev, pdata);
+
+ mutex_lock(&vavs2_mutex);
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ dec->eos = 0;
+ dec->start_process_time = 0;
+ dec->timeout_num = 0;
+ dec->fatal_error = 0;
+ dec->show_frame_num = 0;
+ if (pdata == NULL) {
+ avs2_print(dec, 0,
+ "\namvdec_avs2 memory resource undefined.\n");
+ mutex_unlock(&vavs2_mutex);
+ return -EFAULT;
+ }
+ dec->m_ins_flag = 0;
+ dec->platform_dev = pdev;
+ platform_set_drvdata(pdev, pdata);
+
+#ifdef NEW_FB_CODE
+ dec->front_back_mode = 0;
+#endif
+ config_hevc_irq_num(dec);
+
+#ifdef AVS2_10B_MMU_DW
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
+ dec->dw_mmu_enable =
+ (get_double_write_mode(dec) & 0x20) ? 1 : 0;
+ } else {
+ dec->dw_mmu_enable = 0;
+ }
+#endif
+ if (amvdec_avs2_mmu_init(dec) < 0) {
+ mutex_unlock(&vavs2_mutex);
+ pr_err("avs2 alloc bmmu box failed!!\n");
+ return -1;
+ }
+
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+ work_buf_size, DRIVER_NAME, &pdata->mem_start);
+ if (ret < 0) {
+ uninit_mmu_buffers(dec);
+ mutex_unlock(&vavs2_mutex);
+ return ret;
+ }
+ dec->buf_size = work_buf_size;
+
+ dec->buf_start = pdata->mem_start;
+
+ if (debug) {
+ avs2_print(dec, 0,
+ "===AVS2 decoder mem resource 0x%lx size 0x%x\n",
+ pdata->mem_start, dec->buf_size);
+ }
+
+ if (pdata->sys_info) {
+ dec->vavs2_amstream_dec_info = *pdata->sys_info;
+ dec->frame_width = dec->vavs2_amstream_dec_info.width;
+ dec->frame_height = dec->vavs2_amstream_dec_info.height;
+ } else {
+ dec->vavs2_amstream_dec_info.width = 0;
+ dec->vavs2_amstream_dec_info.height = 0;
+ dec->vavs2_amstream_dec_info.rate = 30;
+ }
+ dec->cma_dev = pdata->cma_dev;
+
+ dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
+ if (is_support_vdec_canvas())
+ dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+ if (endian)
+ dec->endian = endian;
+
+ pdata->private = dec;
+ pdata->dec_status = vavs2_dec_status;
+
+ is_reset = 0;
+ if (vavs2_init(pdata) < 0) {
+ pr_info("\namvdec_avs2 init failed.\n");
+ avs2_local_uninit(dec);
+ uninit_mmu_buffers(dec);
+ pdata->dec_status = NULL;
+ mutex_unlock(&vavs2_mutex);
+ return -ENODEV;
+ }
+ /*set the max clk for smooth playing...*/
+ hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
+ mutex_unlock(&vavs2_mutex);
+
+ return 0;
+}
+
+static int amvdec_avs2_remove(struct platform_device *pdev)
+{
+ struct AVS2Decoder_s *dec = &gAVS2Decoder;
+ if (debug)
+ pr_info("amvdec_avs2_remove\n");
+
+ mutex_lock(&vavs2_mutex);
+
+ vavs2_stop(dec);
+
+ hevc_source_changed(VFORMAT_AVS2, 0, 0, 0);
+
+#ifdef DEBUG_PTS
+ pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+ dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+
+ mutex_unlock(&vavs2_mutex);
+
+ return 0;
+}
+
+/****************************************/
+
+static struct platform_driver amvdec_avs2_driver = {
+ .probe = amvdec_avs2_probe,
+ .remove = amvdec_avs2_remove,
+#ifdef CONFIG_PM
+ .suspend = amhevc_suspend,
+ .resume = amhevc_resume,
+#endif
+ .driver = {
+ .name = DRIVER_NAME,
+ }
+};
+static struct codec_profile_t amvdec_avs2_profile = {
+ .name = "avs2_fb",
+ .profile = ""
+};
+static struct codec_profile_t amvdec_avs2_profile_mult;
+static unsigned char get_data_check_sum
+ (struct AVS2Decoder_s *dec, int size)
+{
+ int jj;
+ int sum = 0;
+ u8 *data = NULL;
+
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ for (jj = 0; jj < size; jj++)
+ sum += data[jj];
+
+#if 0
+//DEBUG only
+ for (jj = size-1; jj>=(size-16); jj--) {
+ if (data[jj])
+ break;
+ }
+ if (jj<(size-16)) {
+ for (jj = size-1; jj>=(size-16); jj--)
+ data[jj] = 0xff;
+ }
+#endif
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ return sum;
+}
+
+static void dump_data(struct AVS2Decoder_s *dec, int size)
+{
+ int jj;
+ u8 *data = NULL;
+ int padding_size = dec->chunk->offset &
+ (VDEC_FIFO_ALIGN - 1);
+
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ avs2_print(dec, 0, "padding: ");
+ for (jj = padding_size; jj > 0; jj--)
+ avs2_print_cont(dec, 0, "%02x ", *(data - jj));
+ avs2_print_cont(dec, 0, "data adr %p\n", data);
+
+ for (jj = 0; jj < size; jj++) {
+ if ((jj & 0xf) == 0)
+ avs2_print(dec, 0, "%06x:", jj);
+ avs2_print_cont(dec, 0, "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0) {
+ avs2_print(dec, 0, "\n");
+ avs2_print_flush(dec);
+ }
+ }
+ avs2_print(dec, 0, "\n");
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+}
+
+static bool is_stbuf_stagnant_full(struct AVS2Decoder_s *dec)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ u32 cur_level, last_level, reset_level;
+
+ ulong wp = STBUF_READ(&vdec->vbuf, get_wp);
+ ulong rp = STBUF_READ(&vdec->vbuf, get_rp);
+
+ if (wp >= rp)
+ cur_level = wp - rp;
+ else
+ cur_level = rp + vdec->vbuf.buf_size - wp;
+
+ last_level = dec->last_stbuf_level;
+ dec->last_stbuf_level = cur_level;
+ reset_level = (vdec->vbuf.buf_size > (SZ_1M * 10)) ? (SZ_1M * 10) : (vdec->vbuf.buf_size >> 1);
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "cur level %x, last level %x, reset lvl %x\n", cur_level, last_level, reset_level);
+ if ((cur_level == last_level) && (cur_level >= reset_level))
+ return true;
+
+ return false;
+}
+
+void wait_hevc_search_done(struct AVS2Decoder_s *dec)
+{
+ int count = 0;
+ WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+ while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+ usleep_range(100, 101);
+ count++;
+ if (count > 100) {
+ avs2_print(dec, 0, "%s timeout\n", __func__);
+ break;
+ }
+ }
+}
+
+static int avs2_wait_alloc_buf(void *args)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)args;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ init_pic_list(dec);
+
+ vdec_up(vdec);
+
+ return 0;
+}
+
+static void avs2_work_implement(struct AVS2Decoder_s *dec)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (dec->dec_result == DEC_RESULT_DONE || dec->dec_result == DEC_RESULT_WAIT_BUFFER)
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_START);
+ else if (dec->dec_result == DEC_RESULT_AGAIN)
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_AGAIN);
+
+ /* finished decoding one frame or error,
+ * notify vdec core to switch context
+ */
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "%s dec_result %d %x %x %x\n",
+ __func__,
+ dec->dec_result,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR));
+
+ if (efficiency_mode && dec->pic_list_init_flag == 1)
+ dec->pic_list_init_flag =2;
+
+ if (((dec->dec_result == DEC_RESULT_GET_DATA) ||
+ (dec->dec_result == DEC_RESULT_GET_DATA_RETRY))
+ && (hw_to_vdec(dec)->next_status != VDEC_STATUS_DISCONNECTED)) {
+ if (!vdec_has_more_input(vdec)) {
+ dec->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+
+ if (dec->dec_result == DEC_RESULT_GET_DATA) {
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s DEC_RESULT_GET_DATA %x %x %x\n",
+ __func__,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR));
+ vdec_vframe_dirty(vdec, dec->chunk);
+ vdec_clean_input(vdec);
+ }
+
+ if (get_free_buf_count(dec) >=
+ run_ready_min_buf_num) {
+ int r;
+ int decode_size;
+ r = vdec_prepare_input(vdec, &dec->chunk);
+ if (r < 0) {
+ dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
+
+ avs2_print(dec,
+ PRINT_FLAG_VDEC_DETAIL,
+ "amvdec_avs2: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ dec->dec_result = DEC_RESULT_NONE;
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s: chunk size 0x%x sum 0x%x\n",
+ __func__, r,
+ (debug & PRINT_FLAG_VDEC_STATUS) ?
+ get_data_check_sum(dec, r) : 0);
+ if (debug & PRINT_FLAG_VDEC_DATA)
+ dump_data(dec, dec->chunk->size);
+
+ decode_size = dec->chunk->size +
+ (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+
+ WRITE_VREG(HEVC_DECODE_SIZE,
+ READ_VREG(HEVC_DECODE_SIZE) + decode_size);
+
+ vdec_enable_input(vdec);
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+
+ start_process_time(dec);
+
+ } else{
+ dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
+
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "amvdec_avs2: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ }
+ return;
+ } else if ((dec->dec_result == DEC_RESULT_DONE)
+ || (dec->dec_result == DEC_RESULT_ERROR)) {
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+ dec->slice_idx++;
+ dec->frame_count++;
+ dec->process_state = PROC_STATE_INIT;
+ decode_frame_count[dec->index] = dec->frame_count;
+
+ if ((pic != NULL) && (pic->error_mark) &&
+ (dec->dec_result == DEC_RESULT_DONE)) {
+#ifdef NEW_FB_CODE
+ mutex_lock(&dec->fb_mutex);
+#endif
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_concealed_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_concealed_frames++;
+ }
+
+ if (pic->backend_ref == 0) {
+ dec->gvs->drop_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_lost_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_lost_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_lost_frames++;
+ }
+ }
+#ifdef NEW_FB_CODE
+ mutex_unlock(&dec->fb_mutex);
+#endif
+ }
+
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
+ __func__,
+ dec->frame_count,
+ dec->dec_result,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT) - dec->start_shift_bytes);
+ vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+ } else if (dec->dec_result == DEC_RESULT_AGAIN) {
+ /*
+ stream base: stream buf empty or timeout
+ frame base: vdec_prepare_input fail
+ */
+ if (!vdec_has_more_input(vdec)) {
+ dec->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+
+ if (vdec_stream_based(vdec) && !dec->start_decoding_flag) {
+ if (is_stbuf_stagnant_full(dec)) {
+ if (++dec->again_count > 0x100) {
+ vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+ dec->again_count = 0;
+ dec->last_stbuf_level = 0;
+ pr_info("avs2 have not found pic to start\n");
+ }
+ }
+ }
+ } else if (dec->dec_result == DEC_RESULT_EOS) {
+ avs2_print(dec, 0, "%s: end of stream\n", __func__);
+ dec->eos = 1;
+ if ( dec->avs2_dec.hc.cur_pic != NULL) {
+ avs2_post_process(&dec->avs2_dec);
+ avs2_prepare_display_buf(dec);
+ }
+ vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+ } else if (dec->dec_result == DEC_RESULT_FORCE_EXIT) {
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS, "%s: force exit\n", __func__);
+ if (dec->stat & STAT_VDEC_RUN) {
+ amhevc_stop();
+ dec->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (dec->stat & STAT_ISR_REG) {
+ if (!dec->m_ins_flag)
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 0);
+ vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+ dec->stat &= ~STAT_ISR_REG;
+ }
+ } else if (dec->dec_result == DEC_RESULT_WAIT_BUFFER) {
+ pr_err("DEC_RESULT_WAIT_BUFFER in\n");
+ vdec_post_task(avs2_wait_alloc_buf, dec);
+ dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATING;
+ dec->process_state =
+ PROC_STATE_DECODE_AGAIN;
+ }
+
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+
+#ifdef NEW_FRONT_BACK_CODE
+ if (!vdec->front_pic_done && (dec->front_back_mode == 1)) {
+ fb_hw_status_clear(true);
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s, clear front, status 0x%x, status_back 0x%x\n",
+ __func__, dec->dec_status, dec->dec_status_back);
+ }
+#endif
+ wait_hevc_search_done(dec);
+
+ if (dec->dec_result == DEC_RESULT_DONE || dec->dec_result == DEC_RESULT_WAIT_BUFFER)
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_END);
+
+ if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+ avs2_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+ __func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+ avs2_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+ avs2_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+ avs2_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+ }
+
+ /* mark itself has all HW resource released and input released */
+ if (vdec->parallel_dec ==1)
+ vdec_core_finish_run(vdec, CORE_MASK_HEVC);
+ else
+ vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+
+ if (dec->vdec_cb)
+ dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg, CORE_MASK_HEVC);
+}
+
+static void avs2_work(struct work_struct *work)
+{
+ struct AVS2Decoder_s *dec = container_of(work,
+ struct AVS2Decoder_s, work);
+
+ avs2_work_implement(dec);
+}
+
+#ifdef NEW_FB_CODE
+static void avs2_work_back_implement(struct AVS2Decoder_s *dec,
+ struct vdec_s *vdec,int from)
+{
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "[BE] %s result %d\n", __func__, dec->dec_back_result);
+
+ if (dec->dec_back_result == DEC_BACK_RESULT_TIMEOUT) {
+ struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+
+ mutex_lock(&dec->fb_mutex);
+ if (pic->error_mark == 0) {
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == I_IMG) {
+ dec->gvs->i_concealed_frames++;
+ } else if ((pic->slice_type == P_IMG) ||
+ (pic->slice_type == F_IMG)) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == B_IMG) {
+ dec->gvs->b_concealed_frames++;
+ }
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ pic ->error_mark = 1;
+ pic_backend_ref_operation(dec, 0);
+
+ if (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3)
+ release_free_mmu_buffers(dec);
+ }
+
+ avs2_dec->backend_decoded_count++;
+
+ mutex_lock(&dec->fb_mutex);
+ avs2_dec->fb_rd_pos++;
+ if (avs2_dec->fb_rd_pos >= dec->fb_ifbuf_num)
+ avs2_dec->fb_rd_pos = 0;
+
+ avs2_dec->wait_working_buf = 0;
+ mutex_unlock(&dec->fb_mutex);
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS2_DEC_IDLE);
+ amhevc_stop_b();
+
+ if (!vdec->back_pic_done && (dec->front_back_mode == 1)) {
+ fb_hw_status_clear(false);
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s, clear back, status 0x%x, status_back 0x%x\n",
+ __func__, dec->dec_status, dec->dec_status_back);
+ }
+
+ if (dec->stat & STAT_TIMER_BACK_ARM) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+
+ vdec_core_finish_run(vdec, CORE_MASK_HEVC_BACK);
+
+ if (dec->vdec_back_cb)
+ dec->vdec_back_cb(hw_to_vdec(dec), dec->vdec_back_cb_arg, CORE_MASK_HEVC_BACK);
+
+}
+
+static void avs2_work_back(struct work_struct *work)
+{
+ struct AVS2Decoder_s *dec = container_of(work,
+ struct AVS2Decoder_s, work_back);
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ avs2_work_back_implement(dec, vdec, 0);
+
+}
+
+static void avs2_timeout_work_back(struct work_struct *work)
+{
+ struct AVS2Decoder_s *dec = container_of(work,
+ struct AVS2Decoder_s, timeout_work_back);
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (work_pending(&dec->work_back))
+ return;
+ avs2_work_back_implement(dec, vdec, 1);
+}
+#endif
+
+static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec)
+{
+ /* new to do ... */
+ vavs2_prot_init(dec);
+ return 0;
+}
+
+#ifdef NEW_FB_CODE
+ /*run_ready_back*/
+static unsigned long check_input_data(struct vdec_s *vdec, unsigned long mask)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+ if (fbdebug_flag & 0x1)
+ return 0;
+
+ if (((avs2_dec->fb_wr_pos != avs2_dec->fb_rd_pos) || avs2_dec->wait_working_buf) &&
+ (dec->front_back_mode))
+ return mask;
+ else
+ return 0;
+}
+#endif
+
+static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ int tvp = vdec_secure(hw_to_vdec(dec)) ?
+ CODEC_MM_FLAGS_TVP : 0;
+ unsigned long ret = 0;
+ avs2_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
+
+ if ((debug & AVS2_DBG_BE_SIMULATE_IRQ)
+ &&(READ_VREG(DEBUG_REG1_DBE) ||
+ READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ }
+
+ if (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATING)
+ return 0;
+
+ if ((fbdebug_flag & 0x2) &&
+ dec->front_back_mode &&
+ (dec->avs2_dec.hc.cur_pic != NULL) &&
+ (dec->avs2_dec.hc.cur_pic->back_done_mark == 0))
+ return 0;
+
+ if (debug & AVS2_DBG_PIC_LEAK_WAIT)
+ return ret;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && avs2_dec->wait_working_buf)
+ return 0xffffffff;
+#endif
+
+ if (dec->eos)
+ return ret;
+ if (!dec->first_sc_checked) {
+ int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp);
+#ifdef NEW_FB_CODE
+/* to do:
+ for dec->mmu_box_1
+*/
+#endif
+ dec->first_sc_checked = 1;
+ avs2_print(dec, 0, "vavs2 cached=%d need_size=%d speed= %d ms\n",
+ size, (dec->need_cache_size >> PAGE_SHIFT),
+ (int)(get_jiffies_64() - dec->sc_start_time) * 1000/HZ);
+ }
+
+ if (dec->next_again_flag &&
+ (!vdec_frame_based(vdec))) {
+ u32 parser_wr_ptr = STBUF_READ(&vdec->vbuf, get_wp);
+ if (parser_wr_ptr >= dec->pre_parser_wr_ptr &&
+ (parser_wr_ptr - dec->pre_parser_wr_ptr) <
+ again_threshold) {
+ int r = vdec_sync_input(vdec);
+ avs2_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s buf lelvel:%x\n", __func__, r);
+ return 0;
+ }
+ }
+
+ if ((dec->pic_list_init_flag == 0) ||
+ get_free_buf_count(dec) >=
+ run_ready_min_buf_num)
+ ret = 1;
+#ifdef CONSTRAIN_MAX_BUF_NUM
+ if (dec->pic_list_init_flag) {
+ if (run_ready_max_vf_only_num > 0 &&
+ get_vf_ref_only_buf_count(dec) >=
+ run_ready_max_vf_only_num)
+ ret = 0;
+ if (run_ready_display_q_num > 0 &&
+ kfifo_len(&dec->display_q) >=
+ run_ready_display_q_num)
+ ret = 0;
+
+ if (run_ready_max_buf_num == 0xff &&
+ get_used_buf_count(dec) >=
+ dec->avs2_dec.ref_maxbuffer)
+ ret = 0;
+ else if (run_ready_max_buf_num &&
+ get_used_buf_count(dec) >=
+ run_ready_max_buf_num)
+ ret = 0;
+ }
+#endif
+ if (ret)
+ not_run_ready[dec->index] = 0;
+ else
+ not_run_ready[dec->index]++;
+
+ if (vdec->parallel_dec == 1)
+#ifdef NEW_FB_CODE
+ return ret ? mask : mask & ~(CORE_MASK_HEVC);
+#else
+ return ret ? CORE_MASK_HEVC : 0;
+#endif
+ else
+ return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
+}
+
+#ifdef NEW_FB_CODE
+static void run_back(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ int loadr = 0;
+ int ret = 0;
+
+ if (vdec->mc_back_loaded || dec->front_back_mode != 1) {
+ /*firmware have load before,
+ and not changes to another.
+ ignore reload.
+ */
+ } else {
+ loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS2, vdec,
+ "avs2_back", dec->fw_back->data);
+
+ if (loadr < 0) {
+ amhevc_disable();
+ avs2_print(dec, 0, "AVS2: the %s back fw loading failed, err: %x\n",
+ fw_tee_enabled() ? "TEE" : "local", loadr);
+ dec->dec_back_result = DEC_BACK_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&dec->work_back);
+ return;
+ }
+
+ //vdec->mc_back_loaded = 1;
+ vdec->mc_back_type = VFORMAT_HEVC;
+ }
+
+ mod_timer(&dec->timer_back, jiffies);
+ dec->stat |= STAT_TIMER_BACK_ARM;
+
+ vdec->back_pic_done = false;
+ run_count_back[dec->index]++;
+ dec->vdec_back_cb_arg = arg;
+ dec->vdec_back_cb = callback;
+ //pr_err("run h265_HEVC_back_test\n");
+ //vdec_post_task(h265_HEVC_back_test, hevc);
+ ret = BackEnd_StartDecoding(dec);
+
+ if (ret == 1) {
+ dec->dec_back_result = DEC_BACK_RESULT_DONE;
+ vdec_schedule_work(&dec->work_back);
+ } else {
+ start_process_time_back(dec);
+ }
+
+ vdec->hw_back_decode_start = local_clock();
+}
+
+#if 0
+static void start_front_end_multi_pic_decoding(struct AVS2Decoder_s *dec)
+{ /*multi pictures in one packe*/
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ printk("Start FrontEnd Decoding %d\n", avs2_dec->frontend_decoded_count);
+ printk("copy loopbuf to next_bk[%d]\n",avs2_dec->fb_wr_pos);
+ copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+
+ if (dec->front_back_mode == 1)
+ config_bufstate_front_hw(avs2_dec);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+}
+#endif
+#endif
+
+static void run(struct vdec_s *vdec, unsigned long mask,
+ void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ int r;
+
+#ifdef NEW_FB_CODE
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ /*simulation code: if (dec_status == AVS2_DEC_IDLE)*/
+ //pr_err("mask = 0x%lx\n", mask);
+ if (dec->front_back_mode == 0 || (mask & CORE_MASK_HEVC)) {
+#endif
+ run_count[dec->index]++;
+ dec->vdec_cb_arg = arg;
+ dec->vdec_cb = callback;
+
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_RUN_START);
+#ifdef NEW_FRONT_BACK_CODE
+ if (debug & PRINT_FLAG_VDEC_STATUS)
+ WRITE_VREG(HEVC_STREAM_CRC, 0);
+ vdec->front_pic_done = false;
+
+ /*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+ if (dec->front_back_mode) {
+ avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "Start FrontEnd Decoding %d\n", avs2_dec->frontend_decoded_count);
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "copy loopbuf to next_bk[%d]\n",avs2_dec->fb_wr_pos);
+ copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+
+ //if (avs2_dec->frontend_decoded_count>0) {
+ if (dec->front_back_mode == 1)
+ amhevc_reset_f();
+ else
+ hevc_reset_core(vdec);
+ //}
+ } else
+#endif
+ hevc_reset_core(vdec);
+
+ if (vdec_stream_based(vdec)) {
+ dec->pre_parser_wr_ptr =
+ STBUF_READ(&vdec->vbuf, get_wp);
+ dec->next_again_flag = 0;
+ }
+
+ r = vdec_prepare_input(vdec, &dec->chunk);
+ if (r < 0) {
+ input_empty[dec->index]++;
+
+ dec->dec_result = DEC_RESULT_AGAIN;
+
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "ammvdec_avs2: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ input_empty[dec->index] = 0;
+ dec->dec_result = DEC_RESULT_NONE;
+ if (debug)
+ dec->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+
+ if (debug & PRINT_FLAG_VDEC_STATUS) {
+ int ii;
+ avs2_print(dec, 0,
+ "%s (%d): size 0x%x (0x%x 0x%x) sum 0x%x (%x %x %x %x %x) bytes 0x%x",
+ __func__,
+ dec->frame_count, r,
+ dec->chunk ? dec->chunk->size : 0,
+ dec->chunk ? dec->chunk->offset : 0,
+ dec->chunk ? ((vdec_frame_based(vdec) &&
+ (debug & PRINT_FLAG_VDEC_STATUS)) ?
+ get_data_check_sum(dec, r) : 0) : 0,
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ dec->start_shift_bytes);
+ if (vdec_frame_based(vdec) && dec->chunk) {
+ u8 *data = NULL;
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, 8);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ avs2_print_cont(dec, 0, "data adr %p:", data);
+ for (ii = 0; ii < 8; ii++)
+ avs2_print_cont(dec, 0, "%02x ", data[ii]);
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ }
+ avs2_print_cont(dec, 0, "\r\n");
+ }
+
+ ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
+
+ if (vdec->mc_loaded) {
+ /*firmware have load before,
+ and not changes to another.
+ ignore reload.
+ */
+ } else {
+#ifdef NEW_FB_CODE
+ int loadr = 0;
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3)
+ loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS2, vdec,
+ "avs2_front", dec->fw->data);
+ else
+#endif
+ if (amhevc_loadmc_ex(VFORMAT_AVS2, NULL, dec->fw->data) < 0) {
+ vdec->mc_loaded = 0;
+ amhevc_disable();
+ avs2_print(dec, 0,
+ "%s: Error amvdec_loadmc fail\n", __func__);
+ dec->dec_result = DEC_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ //vdec->mc_loaded = 1;
+ vdec->mc_type = VFORMAT_AVS2;
+ }
+ ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
+
+ ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (efficiency_mode)
+ WRITE_VREG(HEVC_EFFICIENCY_MODE, 1);
+ else
+ WRITE_VREG(HEVC_EFFICIENCY_MODE, 0);
+ avs2_hw_init(dec, 1, 0);
+ //config_decode_mode(dec);
+ if (dec->front_back_mode == 1)
+ config_bufstate_front_hw(avs2_dec);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); //?? to remove
+ } else
+#endif
+
+ if (avs2_hw_ctx_restore(dec) < 0) {
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
+
+ if (vdec_frame_based(vdec))
+ WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
+
+ vdec_enable_input(vdec);
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_SEARCH_NEW_PIC);
+
+ if (vdec_frame_based(vdec) && dec->chunk) {
+ if (debug & PRINT_FLAG_VDEC_DATA)
+ dump_data(dec, dec->chunk->size);
+
+ r = dec->chunk->size +
+ (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = dec->chunk->size;
+ }
+
+ WRITE_VREG(HEVC_DECODE_SIZE, r);
+ WRITE_VREG(HEVC_DECODE_COUNT, dec->slice_idx);
+ dec->init_flag = 1;
+
+ avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "%s: start hevc (%x %x %x) HEVC_DECODE_SIZE %x\n",
+ __func__,
+ READ_VREG(HEVC_DEC_STATUS_REG),
+ READ_VREG(HEVC_MPC_E),
+ READ_VREG(HEVC_MPSR),
+ READ_VREG(HEVC_DECODE_SIZE));
+
+ start_process_time(dec);
+ mod_timer(&dec->timer, jiffies);
+ dec->stat |= STAT_TIMER_ARM;
+ dec->stat |= STAT_ISR_REG;
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ vdec->hw_front_decode_start = local_clock();
+ amhevc_start_f();
+ } else
+#endif
+ amhevc_start();
+ dec->stat |= STAT_VDEC_RUN;
+ ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_RUN_END);
+#ifdef NEW_FB_CODE
+ }
+ if (dec->front_back_mode &&
+ (mask & CORE_MASK_HEVC_BACK)) {
+ run_back(vdec, callback, arg);
+ }
+#endif
+}
+
+static void reset(struct vdec_s *vdec)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+
+ avs2_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
+}
+
+static irqreturn_t avs2_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ return vavs2_isr(0, dec);
+}
+
+static irqreturn_t avs2_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ return vavs2_isr_thread_fn(0, dec);
+}
+
+static void avs2_dump_state(struct vdec_s *vdec)
+{
+ struct AVS2Decoder_s *dec =
+ (struct AVS2Decoder_s *)vdec->private;
+ int i;
+
+ if (radr != 0) {
+ if (rval != 0) {
+ WRITE_VREG(radr, rval);
+ pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
+ } else
+ pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
+ rval = 0;
+ radr = 0;
+ return;
+ }
+
+ avs2_print(dec, 0, "====== %s\n", __func__);
+
+ avs2_print(dec, 0,
+ "width/height (%d/%d), used_buf_num %d, ref_maxbuffer %d\n",
+ dec->avs2_dec.img.width,
+ dec->avs2_dec.img.height,
+ dec->used_buf_num,
+ dec->avs2_dec.ref_maxbuffer);
+
+ avs2_print(dec, 0,
+ "front_back_mode (%d), is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
+ dec->front_back_mode,
+ input_frame_based(vdec),
+ dec->eos,
+ dec->dec_result,
+ decode_frame_count[dec->index],
+ display_frame_count[dec->index],
+ run_count[dec->index],
+ not_run_ready[dec->index],
+ input_empty[dec->index]);
+
+ if (vf_get_receiver(vdec->vf_provider_name)) {
+ enum receiver_start_e state =
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE,
+ NULL);
+ avs2_print(dec, 0,
+ "\nreceiver(%s) state %d\n",
+ vdec->vf_provider_name,
+ state);
+ }
+
+ avs2_print(dec, 0,
+ "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready), used_cont %d\n",
+ __func__,
+ kfifo_len(&dec->newframe_q),
+ VF_POOL_SIZE,
+ kfifo_len(&dec->display_q),
+ VF_POOL_SIZE,
+ dec->vf_pre_count,
+ dec->vf_get_count,
+ dec->vf_put_count,
+ get_free_buf_count(dec),
+ run_ready_min_buf_num,
+ get_used_buf_count(dec));
+
+ dump_pic_list(dec);
+
+ for (i = 0; i < MAX_BUF_NUM; i++) {
+ avs2_print(dec, 0,
+ "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
+ i,
+ dec->m_mv_BUF[i].start_adr,
+ dec->m_mv_BUF[i].size,
+ dec->m_mv_BUF[i].used_flag);
+ }
+
+ avs2_print(dec, 0,
+ "HEVC_DEC_STATUS_REG=0x%x\n",
+ READ_VREG(HEVC_DEC_STATUS_REG));
+ avs2_print(dec, 0,
+ "HEVC_MPC_E=0x%x\n",
+ READ_VREG(HEVC_MPC_E));
+ avs2_print(dec, 0,
+ "DECODE_MODE=0x%x\n",
+ READ_VREG(DECODE_MODE));
+ avs2_print(dec, 0,
+ "NAL_SEARCH_CTL=0x%x\n",
+ READ_VREG(NAL_SEARCH_CTL));
+ avs2_print(dec, 0,
+ "HEVC_PARSER_LCU_START=0x%x\n",
+ READ_VREG(HEVC_PARSER_LCU_START));
+ avs2_print(dec, 0,
+ "HEVC_DECODE_SIZE=0x%x\n",
+ READ_VREG(HEVC_DECODE_SIZE));
+ avs2_print(dec, 0,
+ "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ avs2_print(dec, 0,
+ "HEVC_STREAM_START_ADDR=0x%x\n",
+ READ_VREG(HEVC_STREAM_START_ADDR));
+ avs2_print(dec, 0,
+ "HEVC_STREAM_END_ADDR=0x%x\n",
+ READ_VREG(HEVC_STREAM_END_ADDR));
+ avs2_print(dec, 0,
+ "HEVC_STREAM_LEVEL=0x%x\n",
+ READ_VREG(HEVC_STREAM_LEVEL));
+ avs2_print(dec, 0,
+ "HEVC_STREAM_WR_PTR=0x%x\n",
+ READ_VREG(HEVC_STREAM_WR_PTR));
+ avs2_print(dec, 0,
+ "HEVC_STREAM_RD_PTR=0x%x\n",
+ READ_VREG(HEVC_STREAM_RD_PTR));
+ avs2_print(dec, 0,
+ "PARSER_VIDEO_RP=0x%x\n",
+ STBUF_READ(&vdec->vbuf, get_rp));
+ avs2_print(dec, 0,
+ "PARSER_VIDEO_WP=0x%x\n",
+ STBUF_READ(&vdec->vbuf, get_wp));
+
+ if (input_frame_based(vdec) &&
+ (debug & PRINT_FLAG_VDEC_DATA)) {
+ int jj;
+ if (dec->chunk && dec->chunk->block &&
+ dec->chunk->size > 0) {
+ u8 *data = NULL;
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, dec->chunk->size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+ avs2_print(dec, 0,
+ "frame data size 0x%x\n",
+ dec->chunk->size);
+ for (jj = 0; jj < dec->chunk->size; jj++) {
+ if ((jj & 0xf) == 0)
+ avs2_print(dec, 0, "%06x:", jj);
+ avs2_print_cont(dec, 0, "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ avs2_print_cont(dec, 0, "\n");
+ }
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ }
+ }
+ if (dec->front_back_mode == 1) {
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ avs2_print(dec, 0,
+ "[BE] dec_back_result 0x%x, frontend_decoded_count %d, backend_decoded_count %d, fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+ dec->dec_back_result,
+ avs2_dec->frontend_decoded_count,
+ avs2_dec->backend_decoded_count,
+ avs2_dec->fb_wr_pos,
+ avs2_dec->fb_rd_pos,
+ avs2_dec->wait_working_buf
+ );
+
+ avs2_print(dec, 0,
+ "[BE] HEVC_DEC_STATUS_DBE=0x%x\n",
+ READ_VREG(HEVC_DEC_STATUS_DBE));
+ avs2_print(dec, 0,
+ "[BE] HEVC_MPC_E_DBE=0x%x\n",
+ READ_VREG(HEVC_MPC_E_DBE));
+ avs2_print(dec, 0,
+ "[BE] HEVC_MPSR_DBE=0x%x\n",
+ READ_VREG(HEVC_MPSR_DBE));
+ avs2_print(dec, 0,
+ "[BE] DEBUG_REG1_DBE=0x%x\n",
+ READ_VREG(DEBUG_REG1_DBE));
+ avs2_print(dec, 0,
+ "[BE] DEBUG_REG2_DBE=0x%x\n",
+ READ_VREG(DEBUG_REG2_DBE));
+ }
+
+}
+
+static int ammvdec_avs2_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ int ret;
+ int config_val;
+ int i;
+ struct vframe_content_light_level_s content_light_level;
+ struct vframe_master_display_colour_s vf_dp;
+ struct AVS2Decoder_s *dec = NULL;
+ static struct vframe_operations_s vf_tmp_ops;
+
+ pr_info("%s\n", __func__);
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+ pr_info("%s, chip id %d is not support avs2\n",
+ __func__, get_cpu_major_id());
+ return -1;
+ }
+ if (pdata == NULL) {
+ pr_info("\nammvdec_avs2 memory resource undefined.\n");
+ return -EFAULT;
+ }
+
+ memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
+
+ dec = vzalloc(sizeof(struct AVS2Decoder_s));
+ if (dec == NULL) {
+ pr_info("\nammvdec_avs2 device data allocation failed\n");
+ return -ENOMEM;
+ }
+
+ if (pdata->parallel_dec == 1) {
+ int i;
+ for (i = 0; i < AVS2_MAX_BUFFER_NUM; i++) {
+ dec->avs2_dec.frm_pool[i].y_canvas_index = -1;
+ dec->avs2_dec.frm_pool[i].uv_canvas_index = -1;
+ }
+ }
+ pdata->private = dec;
+ pdata->dec_status = vavs2_dec_status;
+#ifdef I_ONLY_SUPPORT
+ pdata->set_trickmode = vavs2_set_trickmode;
+#endif
+ pdata->run_ready = run_ready;
+ pdata->run = run;
+#ifdef NEW_FB_CODE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) {
+ dec->front_back_mode = front_back_mode;
+ } else {
+ dec->front_back_mode = 0;
+ }
+ dec->fb_ifbuf_num = fb_ifbuf_num;
+ if (dec->fb_ifbuf_num > MAX_FB_IFBUF_NUM)
+ dec->fb_ifbuf_num = MAX_FB_IFBUF_NUM;
+ pdata->check_input_data = NULL;
+ if (dec->front_back_mode) {
+ pdata->check_input_data = check_input_data;
+ pdata->reset = NULL;
+ pdata->back_irq_handler = avs2_back_irq_cb;
+ pdata->back_threaded_irq_handler = avs2_back_threaded_irq_cb;
+ } else
+#endif
+ pdata->reset = reset;
+ pdata->irq_handler = avs2_irq_cb;
+ pdata->threaded_irq_handler = avs2_threaded_irq_cb;
+ pdata->dump_state = avs2_dump_state;
+
+ dec->index = pdev->id;
+ dec->m_ins_flag = 1;
+ dec->error_proc_policy = error_proc_policy;
+ config_hevc_irq_num(dec);
+
+ if (is_rdma_enable()) {
+ dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle,
+ RDMA_SIZE, &dec->rdma_phy_adr, "AVS2_RDMA_BUF");
+ for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
+ dec->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
+ dec->rdma_adr[i * 4 + 1] = i;
+ dec->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
+ dec->rdma_adr[i * 4 + 3] = 0;
+ if (i == SCALELUT_DATA_WRITE_NUM - 1) {
+ dec->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
+ }
+ }
+ }
+
+ snprintf(dec->trace.vdec_name, sizeof(dec->trace.vdec_name),
+ "avs2-%d", dec->index);
+ snprintf(dec->trace.pts_name, sizeof(dec->trace.pts_name),
+ "%s-pts", dec->trace.vdec_name);
+ snprintf(dec->trace.vf_get_name, sizeof(dec->trace.vf_get_name),
+ "%s-vf_get", dec->trace.vdec_name);
+ snprintf(dec->trace.vf_put_name, sizeof(dec->trace.vf_put_name),
+ "%s-vf_put", dec->trace.vdec_name);
+ snprintf(dec->trace.set_canvas0_addr, sizeof(dec->trace.set_canvas0_addr),
+ "%s-set_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.get_canvas0_addr, sizeof(dec->trace.get_canvas0_addr),
+ "%s-get_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.put_canvas0_addr, sizeof(dec->trace.put_canvas0_addr),
+ "%s-put_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.new_q_name, sizeof(dec->trace.new_q_name),
+ "%s-newframe_q", dec->trace.vdec_name);
+ snprintf(dec->trace.disp_q_name, sizeof(dec->trace.disp_q_name),
+ "%s-dispframe_q", dec->trace.vdec_name);
+ snprintf(dec->trace.decode_time_name, sizeof(dec->trace.decode_time_name),
+ "decoder_time%d", pdev->id);
+ snprintf(dec->trace.decode_run_time_name, sizeof(dec->trace.decode_run_time_name),
+ "decoder_run_time%d", pdev->id);
+ snprintf(dec->trace.decode_header_memory_time_name, sizeof(dec->trace.decode_header_memory_time_name),
+ "decoder_header_time%d", pdev->id);
+ snprintf(dec->trace.decode_work_time_name, sizeof(dec->trace.decode_work_time_name),
+ "decoder_work_time%d", pdev->id);
+
+ if (pdata->use_vfm_path) {
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ VFM_DEC_PROVIDER_NAME);
+ dec->frameinfo_enable = 1;
+ } else
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+
+ memcpy(&vf_tmp_ops, &vavs2_vf_provider, sizeof(struct vframe_operations_s));
+ if (without_display_mode == 1) {
+ vf_tmp_ops.get = NULL;
+ }
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vf_tmp_ops, dec);
+
+ dec->provider_name = pdata->vf_provider_name;
+ platform_set_drvdata(pdev, pdata);
+
+ dec->platform_dev = pdev;
+ dec->video_signal_type = 0;
+ dec->video_ori_signal_type = 0;
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX)
+ dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
+
+ if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
+ /*use ptr config for double_write_mode, etc*/
+ avs2_print(dec, 0, "pdata->config=%s\n", pdata->config);
+ if (get_config_int(pdata->config, "avs2_double_write_mode",
+ &config_val) == 0)
+ dec->double_write_mode = config_val;
+ else
+ dec->double_write_mode = double_write_mode;
+#ifdef OW_TRIPLE_WRITE
+ if (get_config_int(pdata->config, "avs2_triple_write_mode",
+ &config_val) == 0)
+ dec->triple_write_mode = config_val;
+ else
+ dec->triple_write_mode = triple_write_mode;
+#endif
+ if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
+ &config_val) == 0)
+ dec->dynamic_buf_margin = config_val;
+ else
+ dec->dynamic_buf_margin = 0;
+
+ if (get_config_int(pdata->config, "sidebind_type",
+ &config_val) == 0)
+ dec->sidebind_type = config_val;
+
+ if (get_config_int(pdata->config, "sidebind_channel_id",
+ &config_val) == 0)
+ dec->sidebind_channel_id = config_val;
+
+ if (get_config_int(pdata->config,
+ "parm_metadata_config_flag",
+ &config_val) == 0) {
+ dec->high_bandwidth_flag = config_val & VDEC_CFG_FLAG_HIGH_BANDWIDTH;
+ if (dec->high_bandwidth_flag)
+ avs2_print(dec, 0, "high bandwidth\n");
+ }
+
+ if (get_config_int(pdata->config, "HDRStaticInfo",
+ &vf_dp.present_flag) == 0
+ && vf_dp.present_flag == 1) {
+ get_config_int(pdata->config, "mG.x",
+ &vf_dp.primaries[0][0]);
+ get_config_int(pdata->config, "mG.y",
+ &vf_dp.primaries[0][1]);
+ get_config_int(pdata->config, "mB.x",
+ &vf_dp.primaries[1][0]);
+ get_config_int(pdata->config, "mB.y",
+ &vf_dp.primaries[1][1]);
+ get_config_int(pdata->config, "mR.x",
+ &vf_dp.primaries[2][0]);
+ get_config_int(pdata->config, "mR.y",
+ &vf_dp.primaries[2][1]);
+ get_config_int(pdata->config, "mW.x",
+ &vf_dp.white_point[0]);
+ get_config_int(pdata->config, "mW.y",
+ &vf_dp.white_point[1]);
+ get_config_int(pdata->config, "mMaxDL",
+ &vf_dp.luminance[0]);
+ get_config_int(pdata->config, "mMinDL",
+ &vf_dp.luminance[1]);
+ vf_dp.content_light_level.present_flag = 1;
+ get_config_int(pdata->config, "mMaxCLL",
+ &content_light_level.max_content);
+ get_config_int(pdata->config, "mMaxFALL",
+ &content_light_level.max_pic_average);
+ vf_dp.content_light_level = content_light_level;
+ dec->video_signal_type = (1 << 29)
+ | (5 << 26) /* unspecified */
+ | (0 << 25) /* limit */
+ | (1 << 24) /* color available */
+ | (9 << 16) /* 2020 */
+ | (16 << 8) /* 2084 */
+ | (9 << 0); /* 2020 */
+ }
+ dec->vf_dp = vf_dp;
+ } else {
+ dec->double_write_mode = double_write_mode;
+ dec->dynamic_buf_margin = dynamic_buf_num_margin;
+ }
+ video_signal_type = dec->video_signal_type;
+
+ if (double_write_mode) {
+ dec->double_write_mode = get_double_write_mode(dec);
+ }
+
+ if (!dec->dynamic_buf_margin && dynamic_buf_num_margin)
+ dec->dynamic_buf_margin = dynamic_buf_num_margin;
+ if ((dec->double_write_mode & 0x10) == 0)
+ dec->mmu_enable = 1;
+
+#ifdef AVS2_10B_MMU_DW
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
+ dec->dw_mmu_enable =
+ (get_double_write_mode(dec) & 0x20) ? 1 : 0;
+ } else {
+ dec->dw_mmu_enable = 0;
+ }
+#endif
+#ifdef OW_TRIPLE_WRITE
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3X) {
+ if ((dec->triple_write_mode) || (triple_write_mode) ||
+ (dec->double_write_mode & 0x10000) || (double_write_mode & 0x10000)) {
+ double_write_mode &= ~(1 <<16);
+ dec->double_write_mode &= ~(1 <<16);
+ triple_write_mode = 0;
+ dec->triple_write_mode = 0;
+ pr_err("%s warn: unsupport triple write or p010 mode, force disabled\n", __func__);
+ }
+ }
+#endif
+
+ if (amvdec_avs2_mmu_init(dec) < 0) {
+ pr_err("avs2 alloc bmmu box failed!!\n");
+ vfree((void *)dec);
+ return -1;
+ }
+ dec->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+ dec->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
+ &dec->cma_alloc_addr);
+ if (ret < 0) {
+ uninit_mmu_buffers(dec);
+ vfree((void *)dec);
+ return ret;
+ }
+ if (!vdec_secure(pdata))
+ codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
+ dec->buf_start = dec->cma_alloc_addr;
+ dec->buf_size = work_buf_size;
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ dec->fatal_error = 0;
+ dec->show_frame_num = 0;
+
+ if (debug) {
+ pr_info("===AVS2 decoder mem resource 0x%lx size 0x%x\n",
+ dec->buf_start,
+ dec->buf_size);
+ }
+
+ if (pdata->sys_info) {
+ dec->vavs2_amstream_dec_info = *pdata->sys_info;
+ dec->frame_width = dec->vavs2_amstream_dec_info.width;
+ dec->frame_height = dec->vavs2_amstream_dec_info.height;
+ } else {
+ dec->vavs2_amstream_dec_info.width = 0;
+ dec->vavs2_amstream_dec_info.height = 0;
+ dec->vavs2_amstream_dec_info.rate = 30;
+ }
+
+ dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
+ if (is_support_vdec_canvas())
+ dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+ if (is_dw_p010(dec) || is_tw_p010(dec))
+ dec->endian = HEVC_CONFIG_P010_LE;
+ if (endian)
+ dec->endian = endian;
+
+ dec->cma_dev = pdata->cma_dev;
+ if (vavs2_init(pdata) < 0) {
+ pr_info("\namvdec_avs2 init failed.\n");
+ avs2_local_uninit(dec);
+ uninit_mmu_buffers(dec);
+ vfree((void *)dec);
+ pdata->dec_status = NULL;
+ return -ENODEV;
+ }
+ mutex_init(&dec->slice_header_lock);
+ vdec_set_prepare_level(pdata, start_decode_buf_level);
+ hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
+ if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode)
+ vdec_core_request(pdata, CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+ else
+#endif
+ vdec_core_request(pdata, CORE_MASK_HEVC);
+ } else {
+ vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
+ | CORE_MASK_COMBINE);
+ }
+
+ return 0;
+}
+
+static int ammvdec_avs2_remove(struct platform_device *pdev)
+{
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)
+ (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+ struct avs2_frame_s *pic;
+ int i;
+
+ if (debug)
+ pr_info("amvdec_avs2_remove\n");
+
+ vmavs2_stop(dec);
+
+ if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode)
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+ else
+#endif
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
+ } else
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
+
+ vdec_set_status(hw_to_vdec(dec), VDEC_STATUS_DISCONNECTED);
+ if (pdata->parallel_dec == 1) {
+ for (i = 0; i < AVS2_MAX_BUFFER_NUM; i++) {
+ pdata->free_canvas_ex(dec->avs2_dec.frm_pool[i].y_canvas_index, pdata->id);
+ pdata->free_canvas_ex(dec->avs2_dec.frm_pool[i].uv_canvas_index, pdata->id);
+ }
+ }
+
+ for (i = 0; i < dec->used_buf_num; i++) {
+ if (i == (dec->used_buf_num - 1))
+ pic = avs2_dec->m_bg;
+ else
+ pic = avs2_dec->fref[i];
+ release_cuva_data(pic);
+ }
+
+#ifdef DEBUG_PTS
+ pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+ dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+ if (is_rdma_enable())
+ decoder_dma_free_coherent(dec->rdma_mem_handle,
+ RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
+
+ vfree((void *)dec);
+ return 0;
+}
+
+static struct platform_driver ammvdec_avs2_driver = {
+ .probe = ammvdec_avs2_probe,
+ .remove = ammvdec_avs2_remove,
+#ifdef CONFIG_PM
+ .suspend = amvdec_suspend,
+ .resume = amvdec_resume,
+#endif
+ .driver = {
+ .name = MULTI_DRIVER_NAME,
+ }
+};
+#endif
+static struct mconfig avs2_configs[] = {
+ MC_PU32("bit_depth_luma", &bit_depth_luma),
+ MC_PU32("bit_depth_chroma", &bit_depth_chroma),
+ MC_PU32("frame_width", &frame_width),
+ MC_PU32("frame_height", &frame_height),
+ MC_PU32("debug", &debug),
+ MC_PU32("radr", &radr),
+ MC_PU32("rval", &rval),
+ MC_PU32("pop_shorts", &pop_shorts),
+ MC_PU32("dbg_cmd", &dbg_cmd),
+ MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
+ MC_PU32("endian", &endian),
+ MC_PU32("step", &step),
+ MC_PU32("udebug_flag", &udebug_flag),
+ MC_PU32("decode_pic_begin", &decode_pic_begin),
+ MC_PU32("slice_parse_begin", &slice_parse_begin),
+ MC_PU32("i_only_flag", &i_only_flag),
+ MC_PU32("error_handle_policy", &error_handle_policy),
+ MC_PU32("buf_alloc_width", &buf_alloc_width),
+ MC_PU32("buf_alloc_height", &buf_alloc_height),
+ MC_PU32("buf_alloc_depth", &buf_alloc_depth),
+ MC_PU32("buf_alloc_size", &buf_alloc_size),
+ MC_PU32("buffer_mode", &buffer_mode),
+ MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
+ MC_PU32("max_buf_num", &max_buf_num),
+ MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
+ MC_PU32("mem_map_mode", &mem_map_mode),
+ MC_PU32("double_write_mode", &double_write_mode),
+ MC_PU32("enable_mem_saving", &enable_mem_saving),
+ MC_PU32("force_w_h", &force_w_h),
+ MC_PU32("force_fps", &force_fps),
+ MC_PU32("max_decoding_time", &max_decoding_time),
+ MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped),
+ MC_PU32("start_decode_buf_level", &start_decode_buf_level),
+ MC_PU32("decode_timeout_val", &decode_timeout_val),
+};
+static struct mconfig_node avs2_node;
+static int __init amvdec_avs2_driver_init_module(void)
+{
+#ifdef AVS2_10B_MMU
+ struct BuffInfo_s *p_buf_info;
+
+ if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ p_buf_info = &amvavs2_workbuff_spec[2];
+ else
+ p_buf_info = &amvavs2_workbuff_spec[1];
+ } else
+ p_buf_info = &amvavs2_workbuff_spec[0];
+ } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
+ if (vdec_is_support_4k()) {
+ p_buf_info = &amvavs2_workbuff_spec[5];
+ } else
+ p_buf_info = &amvavs2_workbuff_spec[3];
+ }
+
+ init_buff_spec(NULL, p_buf_info);
+ work_buf_size =
+ (p_buf_info->end_adr - p_buf_info->start_adr
+ + 0xffff) & (~0xffff);
+
+#endif
+ pr_debug("amvdec_avs2 module init\n");
+
+#ifdef ERROR_HANDLE_DEBUG
+ dbg_nal_skip_flag = 0;
+ dbg_nal_skip_count = 0;
+#endif
+ udebug_flag = 0;
+ decode_pic_begin = 0;
+ slice_parse_begin = 0;
+ step = 0;
+ buf_alloc_size = 0;
+ if (platform_driver_register(&ammvdec_avs2_driver))
+ pr_err("failed to register ammvdec_avs2 driver\n");
+
+ if (platform_driver_register(&amvdec_avs2_driver)) {
+ pr_err("failed to register amvdec_avs2 driver\n");
+ return -ENODEV;
+ }
+ if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
+ amvdec_avs2_profile.name = "avs2_fb_unsupport";
+ } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+ if (vdec_is_support_4k())
+ amvdec_avs2_profile.profile =
+ "4k, 10bit, dwrite, compressed";
+ else
+ amvdec_avs2_profile.profile =
+ "10bit, dwrite, compressed";
+ } else {
+ /* cpu id larger than sm1 support 8k */
+ amvdec_avs2_profile.profile =
+ "8k, 10bit, dwrite, compressed";
+ }
+
+ vcodec_profile_register(&amvdec_avs2_profile);
+ amvdec_avs2_profile_mult = amvdec_avs2_profile;
+ amvdec_avs2_profile_mult.name = "mavs2_fb";
+ vcodec_profile_register(&amvdec_avs2_profile_mult);
+
+ INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node,
+ "avs2_fb", avs2_configs, CONFIG_FOR_RW);
+ vcodec_feature_register(VFORMAT_AVS2, 0);
+ return 0;
+}
+
+static void __exit amvdec_avs2_driver_remove_module(void)
+{
+ pr_debug("amvdec_avs2 module remove.\n");
+ platform_driver_unregister(&ammvdec_avs2_driver);
+ platform_driver_unregister(&amvdec_avs2_driver);
+}
+
+/****************************************/
+module_param(bit_depth_luma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\n");
+
+module_param(error_proc_policy, uint, 0664);
+MODULE_PARM_DESC(error_proc_policy, "\n amvdec_avs2 error_proc_policy\n");
+
+module_param(bit_depth_chroma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_avs2 bit_depth_chroma\n");
+
+module_param(frame_width, uint, 0664);
+MODULE_PARM_DESC(frame_width, "\n amvdec_avs2 frame_width\n");
+
+module_param(frame_height, uint, 0664);
+MODULE_PARM_DESC(frame_height, "\n amvdec_avs2 frame_height\n");
+
+module_param(debug, uint, 0664);
+MODULE_PARM_DESC(debug, "\n amvdec_avs2 debug\n");
+
+module_param(debug_again, uint, 0664);
+MODULE_PARM_DESC(debug_again, "\n amvdec_avs2 debug_again\n");
+
+module_param(radr, uint, 0664);
+MODULE_PARM_DESC(radr, "\nradr\n");
+
+module_param(rval, uint, 0664);
+MODULE_PARM_DESC(rval, "\nrval\n");
+
+module_param(pop_shorts, uint, 0664);
+MODULE_PARM_DESC(pop_shorts, "\nrval\n");
+
+module_param(dbg_cmd, uint, 0664);
+MODULE_PARM_DESC(dbg_cmd, "\ndbg_cmd\n");
+
+module_param(dbg_skip_decode_index, uint, 0664);
+MODULE_PARM_DESC(dbg_skip_decode_index, "\ndbg_skip_decode_index\n");
+
+module_param(endian, uint, 0664);
+MODULE_PARM_DESC(endian, "\nrval\n");
+
+module_param(step, uint, 0664);
+MODULE_PARM_DESC(step, "\n amvdec_avs2 step\n");
+
+module_param(decode_pic_begin, uint, 0664);
+MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_avs2 decode_pic_begin\n");
+
+module_param(slice_parse_begin, uint, 0664);
+MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_avs2 slice_parse_begin\n");
+
+module_param(i_only_flag, uint, 0664);
+MODULE_PARM_DESC(i_only_flag, "\n amvdec_avs2 i_only_flag\n");
+
+module_param(error_handle_policy, uint, 0664);
+MODULE_PARM_DESC(error_handle_policy, "\n amvdec_avs2 error_handle_policy\n");
+
+module_param(re_search_seq_threshold, uint, 0664);
+MODULE_PARM_DESC(re_search_seq_threshold, "\n amvdec_avs2 re_search_seq_threshold\n");
+
+module_param(buf_alloc_width, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
+
+module_param(buf_alloc_height, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
+
+module_param(buf_alloc_depth, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
+
+module_param(buf_alloc_size, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
+
+module_param(buffer_mode, uint, 0664);
+MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
+
+module_param(buffer_mode_dbg, uint, 0664);
+MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
+/*USE_BUF_BLOCK*/
+module_param(max_buf_num, uint, 0664);
+MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
+
+module_param(dynamic_buf_num_margin, uint, 0664);
+MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+module_param(run_ready_max_vf_only_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_max_vf_only_num, "\n run_ready_max_vf_only_num\n");
+
+module_param(run_ready_display_q_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_display_q_num, "\n run_ready_display_q_num\n");
+
+module_param(run_ready_max_buf_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_max_buf_num, "\n run_ready_max_buf_num\n");
+#endif
+
+module_param(mv_buf_margin, uint, 0664);
+MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n");
+
+module_param(run_ready_min_buf_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
+
+module_param(mem_map_mode, uint, 0664);
+MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
+
+module_param(double_write_mode, uint, 0664);
+MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
+
+#ifdef OW_TRIPLE_WRITE
+module_param(triple_write_mode, uint, 0664);
+MODULE_PARM_DESC(triple_write_mode, "\n triple_write_mode\n");
+#endif
+
+module_param(enable_mem_saving, uint, 0664);
+MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
+
+module_param(force_w_h, uint, 0664);
+MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
+
+module_param(force_fps, uint, 0664);
+MODULE_PARM_DESC(force_fps, "\n force_fps\n");
+
+module_param(max_decoding_time, uint, 0664);
+MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
+
+module_param(on_no_keyframe_skiped, uint, 0664);
+MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
+
+module_param(start_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(start_decode_buf_level,
+ "\n avs2 start_decode_buf_level\n");
+
+module_param(decode_timeout_val, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val,
+ "\n avs2 decode_timeout_val\n");
+
+module_param_array(decode_frame_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(display_frame_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(max_process_time, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(run_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(input_empty, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(not_run_ready, uint,
+ &max_decode_instance_num, 0664);
+
+module_param(video_signal_type, uint, 0664);
+MODULE_PARM_DESC(video_signal_type, "\n amvdec_avs2 video_signal_type\n");
+
+module_param(force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(force_video_signal_type, "\n amvdec_avs2 force_video_signal_type\n");
+
+module_param(enable_force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs2 enable_force_video_signal_type\n");
+
+module_param(force_bufspec, uint, 0664);
+MODULE_PARM_DESC(force_bufspec, "\n amvdec_avs2 force_bufspec\n");
+
+module_param(fbdebug_flag, uint, 0664);
+MODULE_PARM_DESC(fbdebug_flag, "\n amvdec_avs2 fbdebug_flag\n");
+
+module_param(udebug_flag, uint, 0664);
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs2 udebug_flag\n");
+
+module_param(udebug_pause_pos, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
+
+module_param(udebug_pause_val, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
+
+module_param(udebug_pause_decode_idx, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
+
+module_param(pre_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(pre_decode_buf_level,
+ "\n amvdec_avs2 pre_decode_buf_level\n");
+
+module_param(again_threshold, uint, 0664);
+MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
+
+module_param(force_disp_pic_index, int, 0664);
+MODULE_PARM_DESC(force_disp_pic_index,
+ "\n amvdec_avs2 force_disp_pic_index\n");
+
+module_param(without_display_mode, uint, 0664);
+MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
+
+module_param(mv_buf_dynamic_alloc, uint, 0664);
+MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
+
+module_param(paral_alloc_buffer_mode, uint, 0664);
+MODULE_PARM_DESC(paral_alloc_buffer_mode, "\n paral_alloc_buffer_mode\n");
+
+#ifdef NEW_FB_CODE
+module_param(front_back_mode, uint, 0664);
+MODULE_PARM_DESC(front_back_mode, "\n amvdec_avs2 front_back_mode\n");
+
+module_param(fb_ifbuf_num, uint, 0664);
+MODULE_PARM_DESC(fb_ifbuf_num, "\n amvdec_avs2 fb_ifbuf_num\n");
+
+module_param(decode_timeout_val_back, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val_back,
+ "\n avs2 decode_timeout_val_back\n");
+
+module_param(back_timer_check_count, uint, 0664);
+MODULE_PARM_DESC(back_timer_check_count,
+ "\n avs2 back_timer_check_count\n");
+
+module_param(dump_yuv_frame, uint, 0664);
+MODULE_PARM_DESC(dump_yuv_frame, "\n amvdec_avs2 dump_yuv_frame\n");
+
+module_param_array(max_process_time_back, uint,
+ &max_decode_instance_num, 0664);
+
+module_param(efficiency_mode, uint, 0664);
+MODULE_PARM_DESC(efficiency_mode, "\n efficiency_mode\n");
+
+#endif
+
+module_init(amvdec_avs2_driver_init_module);
+module_exit(amvdec_avs2_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC avs2 Video Decoder Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/avs3/Makefile b/drivers/frame_provider/decoder/avs3/Makefile
new file mode 100644
index 0000000..cc45a95
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/Makefile
@@ -0,0 +1,7 @@
+MODULE_NAME = amvdec_avs3
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS3) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs3.o avs3_bufmgr.o dec_eco.o com_picman.o
+
+PR_FMT = $(subst amvdec_,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c b/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c
new file mode 100644
index 0000000..d331169
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c
@@ -0,0 +1,1124 @@
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+#define CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+#endif
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#else
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/sched/clock.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+//#define printf printk
+#endif
+#include "avs3_global.h"
+#define CONV_LOG2(v) (com_tbl_log2[v])
+
+void set_livcdata_dec(DEC id_lib, LibVCData *libvc_data)
+{
+ DEC_CTX * tmp_ctx = (DEC_CTX *)id_lib;
+ tmp_ctx->dpm.libvc_data = libvc_data;
+}
+
+void init_libvcdata(LibVCData *libvc_data)
+{
+ int i, j;
+ libvc_data->bits_dependencyFile = 0;
+ libvc_data->bits_libpic = 0;
+
+ libvc_data->library_picture_enable_flag = 0;
+#if IPPPCRR
+#if LIB_PIC_UPDATE
+ libvc_data->lib_pic_update = 0;
+ libvc_data->update = 0;
+ libvc_data->countRL = 0;
+ libvc_data->encode_skip = 0;
+ libvc_data->end_of_intra_period = 0;
+#else
+ libvc_data->first_pic_as_libpic = 0;
+#endif
+#endif
+#if CRR_ENC_OPT_CFG
+ libvc_data->lib_in_l0 = 2;
+ libvc_data->lib_in_l1 = 0;
+ libvc_data->pb_ref_lib = 0;
+ libvc_data->rl_ref_lib = 2;
+ libvc_data->max_list_refnum = 2;
+ libvc_data->libpic_idx = -1;
+#endif
+ libvc_data->is_libpic_processing = 0;
+ libvc_data->is_libpic_prepared = 0;
+
+ libvc_data->num_candidate_pic = 0;
+ libvc_data->num_lib_pic = 0;
+ libvc_data->num_RLpic = 0;
+
+ libvc_data->num_libpic_outside = 0;
+
+ for (i = 0; i < MAX_CANDIDATE_PIC; i++)
+ {
+ libvc_data->list_poc_of_candidate_pic[i] = -1;
+ libvc_data->list_candidate_pic[i] = NULL;
+
+ libvc_data->list_hist_feature_of_candidate_pic[i].num_component = 0;
+ libvc_data->list_hist_feature_of_candidate_pic[i].num_of_hist_interval = 0;
+ libvc_data->list_hist_feature_of_candidate_pic[i].length_of_interval = 0;
+ for (j = 0; j < MAX_NUM_COMPONENT; j++)
+ {
+ libvc_data->list_hist_feature_of_candidate_pic[i].list_hist_feature[j] = NULL;
+ }
+
+ libvc_data->list_poc_of_RLpic[i] = -1;
+ libvc_data->list_libidx_for_RLpic[i] = -1;
+
+ }
+ for (i = 0; i < MAX_NUM_LIBPIC; i++)
+ {
+ libvc_data->list_poc_of_libpic[i] = -1;
+ libvc_data->list_libpic_outside[i] = NULL;
+ libvc_data->list_library_index_outside[i] = -1;
+ }
+}
+
+static const s8 com_tbl_log2[257] =
+{
+ /* 0, 1 */
+ -1, -1,
+ /* 2, 3 */
+ 1, -1,
+ /* 4 ~ 7 */
+ 2, -1, -1, -1,
+ /* 8 ~ 15 */
+ 3, -1, -1, -1, -1, -1, -1, -1,
+ /* 16 ~ 31 */
+ 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 31 ~ 63 */
+ 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 64 ~ 127 */
+ 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 128 ~ 255 */
+ 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 256 */
+ 8
+ };
+
+COM_PIC *dec_pull_frm(DEC_CTX *ctx, int state)
+{
+ int ret;
+ COM_PIC *pic = NULL;
+ int library_picture_index;
+ //*imgb = NULL;
+#if LIBVC_ON
+ // output lib pic and corresponding library_picture_index
+ if (ctx->info.sqh.library_stream_flag)
+ {
+ pic = ctx->pic;
+ library_picture_index = ctx->info.pic_header.library_picture_index;
+
+ //output to the buffer outside the decoder
+ ret = com_picman_out_libpic(pic, library_picture_index, &ctx->dpm);
+ if (pic)
+ {
+ printf("%s output index %d\n", __func__, pic->buf_cfg.index);
+ //com_assert_rv(pic->imgb != NULL, COM_ERR);
+ //pic->imgb->addref(pic->imgb);
+ //*imgb = pic->imgb;
+ }
+ //Don't output the reconstructed libpics to yuv. Because lib pic should not display.
+
+ return pic;
+ }
+ else
+#endif
+ {
+ pic = com_picman_out_pic( &ctx->dpm, &ret, ctx->info.pic_header.decode_order_index, state ); //MX: doi is not increase mono, but in the range of [0,255]
+ if (pic)
+ {
+ printf("%s output index %d\n", __func__, pic->buf_cfg.index);
+ //com_assert_rv(pic->imgb != NULL, COM_ERR);
+ /* increase reference count */
+ //pic->imgb->addref(pic->imgb);
+ //*imgb = pic->imgb;
+ }
+ return pic;
+ }
+}
+
+static void make_stat(DEC_CTX * ctx, int btype, DEC_STAT * stat)
+{
+ int i, j;
+ stat->read = 0;
+ stat->ctype = btype;
+ stat->stype = 0;
+ stat->fnum = -1;
+#if LIBVC_ON
+ stat->is_RLpic_flag = ctx->info.pic_header.is_RLpic_flag;
+#endif
+ if (ctx)
+ {
+ //stat->read = COM_BSR_GET_READ_BYTE(&ctx->bs);
+ if (btype == COM_CT_SLICE)
+ {
+ stat->fnum = ctx->pic_cnt;
+ stat->stype = ctx->info.pic_header.slice_type;
+ /* increase decoded picture count */
+ ctx->pic_cnt++;
+ stat->poc = ctx->ptr;
+ for (i = 0; i < 2; i++)
+ {
+ stat->refpic_num[i] = ctx->dpm.num_refp[i];
+ for (j = 0; j < stat->refpic_num[i]; j++)
+ {
+#if LIBVC_ON
+ stat->refpic[i][j] = ctx->refp[j][i].pic->ptr;
+#else
+ stat->refpic[i][j] = ctx->refp[j][i].ptr;
+#endif
+ }
+ }
+ }
+ else if (btype == COM_CT_PICTURE)
+ {
+ stat->fnum = -1;
+ stat->stype = ctx->info.pic_header.slice_type;
+ stat->poc = ctx->info.pic_header.dtr;
+ for (i = 0; i < 2; i++)
+ {
+ stat->refpic_num[i] = ctx->dpm.num_refp[i];
+ for (j = 0; j < stat->refpic_num[i]; j++)
+ {
+#if LIBVC_ON
+ stat->refpic[i][j] = ctx->refp[j][i].pic->ptr;
+#else
+ stat->refpic[i][j] = ctx->refp[j][i].ptr;
+#endif
+ }
+ }
+ }
+ }
+
+#if PRINT_SQH_PARAM_DEC
+#if PHASE_2_PROFILE
+ stat->profile_id = ctx->info.sqh.profile_id;
+#endif
+ stat->internal_bit_depth = ctx->info.sqh.encoding_precision == 2 ? 10 : 8;;
+#if ENHANCE_TSPCM
+ stat->intra_tools = (ctx->info.sqh.tscpm_enable_flag << 0) + (ctx->info.sqh.enhance_tscpm_enable_flag << 1) +
+ (ctx->info.sqh.ipf_enable_flag << 2) + (ctx->info.sqh.dt_intra_enable_flag << 3) + (ctx->info.sqh.ipcm_enable_flag << 4);
+#if MIPF
+ stat->intra_tools += (ctx->info.sqh.mipf_enable_flag << 5);
+#endif
+#else
+ stat->intra_tools = (ctx->info.sqh.tscpm_enable_flag << 0) + (ctx->info.sqh.ipf_enable_flag << 1) + (ctx->info.sqh.dt_intra_enable_flag << 2) + (ctx->info.sqh.ipcm_enable_flag << 3);
+#if MIPF
+ stat->intra_tools += (ctx->info.sqh.mipf_enable_flag << 4);
+#endif
+#endif
+
+#if PMC
+ stat->intra_tools += (ctx->info.sqh.pmc_enable_flag << 6);
+#endif
+
+#if IPF_CHROMA
+ stat->intra_tools += (ctx->info.sqh.chroma_ipf_enable_flag << 7);
+#endif
+#if IIP
+ stat->intra_tools += (ctx->info.sqh.iip_enable_flag << 8);
+#endif
+ stat->inter_tools = (ctx->info.sqh.affine_enable_flag << 0) + (ctx->info.sqh.amvr_enable_flag << 1) + (ctx->info.sqh.umve_enable_flag << 2) + (ctx->info.sqh.emvr_enable_flag << 3);
+ stat->inter_tools+= (ctx->info.sqh.smvd_enable_flag << 4) + (ctx->info.sqh.num_of_hmvp_cand << 10);
+#if AWP
+ stat->inter_tools += ctx->info.sqh.awp_enable_flag << 5;
+#endif
+ stat->trans_tools = (ctx->info.sqh.secondary_transform_enable_flag << 0) + (ctx->info.sqh.position_based_transform_enable_flag << 1);
+
+ stat->filte_tools = (ctx->info.sqh.sample_adaptive_offset_enable_flag << 0) + (ctx->info.sqh.adaptive_leveling_filter_enable_flag << 1);
+
+ stat->scc_tools = 0;
+#if FIMC
+ stat->scc_tools += (ctx->info.sqh.fimc_enable_flag << 0);
+#endif
+#if IBC_BVP
+ stat->scc_tools += (ctx->info.sqh.num_of_hbvp_cand << 1);
+#endif
+#endif
+}
+
+static void sequence_deinit(DEC_CTX * ctx)
+{
+ com_picman_deinit(&ctx->dpm);
+}
+
+static int sequence_init(DEC_CTX * ctx, COM_SQH * sqh, int max_pb_size)
+{
+ int size;
+ int ret;
+
+ ctx->info.bit_depth_internal = (sqh->encoding_precision == 2) ? 10 : 8;
+ assert(sqh->sample_precision == 1 || sqh->sample_precision == 2);
+ ctx->info.bit_depth_input = (sqh->sample_precision == 1) ? 8 : 10;
+ ctx->info.qp_offset_bit_depth = (8 * (ctx->info.bit_depth_internal - 8));
+
+ sequence_deinit(ctx);
+ ctx->info.pic_width = ((sqh->horizontal_size + MINI_SIZE - 1) / MINI_SIZE) * MINI_SIZE;
+ ctx->info.pic_height = ((sqh->vertical_size + MINI_SIZE - 1) / MINI_SIZE) * MINI_SIZE;
+ ctx->info.max_cuwh = 1 << sqh->log2_max_cu_width_height;
+ ctx->info.log2_max_cuwh = CONV_LOG2(ctx->info.max_cuwh);
+
+ size = ctx->info.max_cuwh;
+ ctx->info.pic_width_in_lcu = (ctx->info.pic_width + (size - 1)) / size;
+ ctx->info.pic_height_in_lcu = (ctx->info.pic_height + (size - 1)) / size;
+ ctx->info.f_lcu = ctx->info.pic_width_in_lcu * ctx->info.pic_height_in_lcu;
+ ctx->info.pic_width_in_scu = (ctx->info.pic_width + ((1 << MIN_CU_LOG2) - 1)) >> MIN_CU_LOG2;
+ ctx->info.pic_height_in_scu = (ctx->info.pic_height + ((1 << MIN_CU_LOG2) - 1)) >> MIN_CU_LOG2;
+ ctx->info.f_scu = ctx->info.pic_width_in_scu * ctx->info.pic_height_in_scu;
+#if ASP
+ ctx->info.skip_me_asp = FALSE;
+ ctx->info.skip_umve_asp = FALSE;
+#endif
+
+ ctx->pa.width = ctx->info.pic_width;
+ ctx->pa.height = ctx->info.pic_height;
+ ctx->pa.pad_l = PIC_PAD_SIZE_L;
+ ctx->pa.pad_c = PIC_PAD_SIZE_C;
+ ret = com_picman_init(&ctx->dpm, max_pb_size, MAX_NUM_REF_PICS, &ctx->pa);
+ com_assert_g(COM_SUCCEEDED(ret), ERR);
+
+ /*
+ ...
+ */
+
+ ctx->info.pic_header.tool_alf_on = ctx->info.sqh.adaptive_leveling_filter_enable_flag;
+#if ALF_SHAPE || ALF_IMP
+ ctx->info.pic_header.tool_alf_shape_on = ctx->info.sqh.adaptive_filter_shape_enable_flag;
+#endif
+ create_alf_global_buffer(ctx);
+ ctx->info.pic_header.pic_alf_on = ctx->pic_alf_on;
+
+ return COM_OK;
+ERR:
+ sequence_deinit(ctx);
+ ctx->init_flag = 0;
+ return ret;
+}
+
+int dec_cnk(DEC_CTX * ctx, DEC_STAT * stat, unsigned char start_code,
+ union param_u *param, int max_pb_size)
+{
+ COM_PIC_HEADER *pic_header;
+ COM_SQH * sqh;
+ COM_SH_EXT *shext;
+ COM_CNKH *cnkh;
+ int ret = COM_OK;
+ int i;
+ PRINT_LINE();
+ if (stat)
+ {
+ com_mset(stat, 0, sizeof(DEC_STAT));
+ }
+ sqh = &ctx->info.sqh;
+ pic_header = &ctx->info.pic_header;
+ shext = &ctx->info.shext;
+ cnkh = &ctx->info.cnkh;
+
+ /* set error status */
+#ifdef TRACE_RDO_EXCLUDE_I
+#if TRACE_RDO_EXCLUDE_I
+ if (pic_header->slice_type != SLICE_I)
+ {
+#endif
+#endif
+ COM_TRACE_SET(1);
+#ifdef TRACE_RDO_EXCLUDE_I
+#if TRACE_RDO_EXCLUDE_I
+ }
+ else
+ {
+ COM_TRACE_SET(0);
+ }
+#endif
+#endif
+ /* bitstream reader initialization */
+ //com_bsr_init(bs, bitb->addr, bitb->ssize, NULL);
+ //SET_SBAC_DEC(bs, &ctx->sbac_dec);
+
+ //start_store_param("", bs->cur[3]);
+ if (start_code == 0xB0)
+ {
+ cnkh->ctype = COM_CT_SQH;
+ ret = dec_eco_sqh(param, sqh);
+ PRINT_LINE();
+ com_assert_rv(COM_SUCCEEDED(ret), ret);
+ PRINT_LINE();
+#if LIBVC_ON
+ ctx->dpm.libvc_data->is_libpic_processing = sqh->library_stream_flag;
+ ctx->dpm.libvc_data->library_picture_enable_flag = sqh->library_picture_enable_flag;
+ /*
+ if (ctx->dpm.libvc_data->library_picture_enable_flag && !ctx->dpm.libvc_data->is_libpic_prepared)
+ {
+ ret = COM_ERR_UNEXPECTED;
+ printf("\nError: when decode seq.bin with library picture enable, you need to input libpic.bin at the same time by using param: --input_libpics.");
+ com_assert_rv(ctx->dpm.libvc_data->library_picture_enable_flag == ctx->dpm.libvc_data->is_libpic_prepared, ret);
+ }
+ */
+#endif
+ PRINT_LINE();
+
+#if EXTENSION_USER_DATA
+ //extension_and_user_data(ctx, param, 0, sqh, pic_header);
+#endif
+ if ( !ctx->init_flag )
+ {
+ PRINT_LINE();
+ ret = sequence_init(ctx, sqh, max_pb_size);
+ PRINT_LINE();
+ com_assert_rv(COM_SUCCEEDED(ret), ret);
+ //g_DOIPrev = g_CountDOICyCleTime = 0;
+ PRINT_LINE();
+ ctx->init_flag = 1;
+ }
+ }
+ else if ( start_code == 0xB1 )
+ {
+ ctx->init_flag = 0;
+ cnkh->ctype = COM_CT_SEQ_END;
+ }
+ else if (start_code == 0xB3 || start_code == 0xB6)
+ {
+ int need_minus_256 = 0;
+ PRINT_LINE();
+ cnkh->ctype = COM_CT_PICTURE;
+ if (ctx->init_flag != 1)
+ return COM_ERR_MALFORMED_BITSTREAM;
+ /* decode slice header */
+ pic_header->low_delay = sqh->low_delay;
+ ret = dec_eco_pic_header(param, pic_header, sqh, &need_minus_256, start_code);
+ if (need_minus_256)
+ {
+ com_picman_dpbpic_doi_minus_cycle_length( &ctx->dpm );
+ }
+
+ ctx->wq[0] = pic_header->wq_4x4_matrix;
+ ctx->wq[1] = pic_header->wq_8x8_matrix;
+
+ if (!sqh->library_stream_flag)
+ {
+ com_picman_check_repeat_doi(&ctx->dpm, pic_header);
+ }
+
+#if EXTENSION_USER_DATA && WRITE_MD5_IN_USER_DATA
+ //extension_and_user_data(ctx, param, 1, sqh, pic_header);
+#endif
+ com_construct_ref_list_doi(pic_header);
+
+ //add by Yuqun Fan, init rpl list at ph instead of sh
+#if HLS_RPL
+#if LIBVC_ON
+ if (!sqh->library_stream_flag)
+#endif
+ {
+ ret = com_picman_refpic_marking_decoder(&ctx->dpm, pic_header);
+ if (avs3_get_error_policy() & 0x4)
+ com_assert_rv(ret == COM_OK, ret);
+ }
+ com_cleanup_useless_pic_buffer_in_pm(&ctx->dpm);
+
+ /* reference picture lists construction */
+ ret = com_picman_refp_rpl_based_init_decoder(&ctx->dpm, pic_header, ctx->refp);
+
+#if AWP
+ if (ctx->info.pic_header.slice_type == SLICE_P || ctx->info.pic_header.slice_type == SLICE_B)
+ {
+ for (i = 0; i < ctx->dpm.num_refp[REFP_0]; i++)
+ {
+ ctx->info.pic_header.ph_poc[REFP_0][i] = ctx->refp[i][REFP_0].ptr;
+ }
+ }
+
+ if (ctx->info.pic_header.slice_type == SLICE_B)
+ {
+ for (i = 0; i < ctx->dpm.num_refp[REFP_1]; i++)
+ {
+ ctx->info.pic_header.ph_poc[REFP_1][i] = ctx->refp[i][REFP_1].ptr;
+ }
+ }
+#endif
+#else
+ /* initialize reference pictures */
+ //ret = com_picman_refp_init(&ctx->dpm, ctx->info.sqh.num_ref_pics_act, sh->slice_type, ctx->ptr, ctx->info.sh.temporal_id, ctx->last_intra_ptr, ctx->refp);
+#endif
+ if (avs3_get_error_policy() & 0x4) {
+ com_assert_rv(COM_SUCCEEDED(ret), ret);
+ } else if (ret != 0) {
+ ret = 0;
+ goto NEW_PICTURE;
+ }
+#ifdef ORI_CODE
+ }
+ else if (start_code >= 0x00 && start_code <= 0x8E)
+ {
+#endif
+ cnkh->ctype = COM_CT_SLICE;
+ ret = dec_eco_patch_header(param, sqh, pic_header, shext, ctx->patch);
+ /* initialize slice */
+#ifdef ORI_CODE
+ ret = slice_init(ctx, ctx->core, pic_header);
+#else
+ ctx->dtr_prev_low = pic_header->dtr;
+ ctx->dtr = pic_header->dtr;
+ ctx->ptr = pic_header->dtr; /* PTR */
+#endif
+ com_assert_rv(COM_SUCCEEDED(ret), ret);
+#if 1
+ if (is_avs3_print_bufmgr_detail())
+ com_picman_print_state(&ctx->dpm);
+ if (pic_header->rpl_l0.ref_pic_active_num > 0) {
+ char tmpbuf[128];
+ int pos = 0;
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", ctx->refp[i][REFP_0].ptr);
+ printf("rpl_l0 num %d: %s\n", pic_header->rpl_l0.ref_pic_active_num, tmpbuf);
+ }
+ if (pic_header->rpl_l1.ref_pic_active_num > 0) {
+ char tmpbuf[128];
+ int pos = 0;
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", ctx->refp[i][REFP_1].ptr);
+ printf("rpl_l1 num %d: %s\n", pic_header->rpl_l1.ref_pic_active_num, tmpbuf);
+ }
+#endif
+NEW_PICTURE:
+ /* get available frame buffer for decoded image */
+ ctx->pic = com_picman_get_empty_pic(&ctx->dpm, &ret);
+ com_assert_rv(ctx->pic, ret);
+ /* get available frame buffer for decoded image */
+ ctx->map.map_refi = ctx->pic->map_refi;
+ ctx->map.map_mv = ctx->pic->map_mv;
+ /* decode slice layer */
+
+ //ret = dec_pic(ctx, ctx->core, sqh, pic_header, shext);
+
+#if 0
+/*AML*/
+/*put to post_process*/
+ /* put decoded picture to DPB */
+#if LIBVC_ON
+ if (sqh->library_stream_flag)
+ {
+ ret = com_picman_put_libpic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index, ctx->info.pic_header.temporal_id, 1, ctx->refp, pic_header);
+ }
+ else
+#endif
+ {
+ ret = com_picman_put_pic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index,
+ pic_header->picture_output_delay, ctx->info.pic_header.temporal_id, 1, ctx->refp);
+ assert((&ctx->dpm)->cur_pb_size <= sqh->max_dpb_size);
+ }
+#endif
+ }
+ else
+ {
+ //stop_store_param();
+ return COM_ERR_MALFORMED_BITSTREAM;
+ }
+ PRINT_LINE();
+ make_stat(ctx, cnkh->ctype, stat);
+ PRINT_LINE();
+ //stop_store_param();
+ return ret;
+}
+
+void allocate_alf_param(ALF_PARAM **alf_param, int comp_idx
+#if ALF_SHAPE
+ , int num_coef
+#endif
+)
+{
+ //*alf_param = (ALF_PARAM *)malloc(sizeof(ALF_PARAM));
+ (*alf_param)->alf_flag = 0;
+#if ALF_SHAPE
+ (*alf_param)->num_coeff = num_coef;
+#else
+ (*alf_param)->num_coeff = ALF_MAX_NUM_COEF;
+#endif
+ (*alf_param)->filters_per_group = 1;
+#if ALF_IMP
+ (*alf_param)->dir_index = 0;
+ (*alf_param)->max_filter_num = (comp_idx == Y_C) ? NO_VAR_BINS : 1;
+#endif
+ (*alf_param)->component_id = comp_idx;
+
+#ifdef ORI_CODE
+ (*alf_param)->coeff_multi = NULL;
+ (*alf_param)->filter_pattern = NULL;
+ switch (comp_idx)
+ {
+ case Y_C:
+#if ALF_SHAPE
+ get_mem_2D_int(&((*alf_param)->coeff_multi), NO_VAR_BINS, num_coef);
+#else
+ get_mem_2D_int(&((*alf_param)->coeff_multi), NO_VAR_BINS, ALF_MAX_NUM_COEF);
+#endif
+ get_mem_1D_int(&((*alf_param)->filter_pattern), NO_VAR_BINS);
+ break;
+ case U_C:
+ case V_C:
+#if ALF_SHAPE
+ get_mem_2D_int(&((*alf_param)->coeff_multi), 1, num_coef);
+#else
+ get_mem_2D_int(&((*alf_param)->coeff_multi), 1, ALF_MAX_NUM_COEF);
+#endif
+ break;
+ default:
+ printf("Not a legal component ID\n");
+ assert(0);
+ exit(-1);
+ }
+#endif
+}
+
+void create_alf_global_buffer(DEC_CTX *ctx)
+{
+ int i;
+#if ALF_SHAPE
+ int num_coef = (ctx->info.sqh.adaptive_filter_shape_enable_flag) ? ALF_MAX_NUM_COEF_SHAPE2 : ALF_MAX_NUM_COEF;
+#endif
+ for (i = 0; i < N_C; i++)
+ {
+ allocate_alf_param(&ctx->info.pic_header.alf_picture_param[i], i
+#if ALF_SHAPE
+ , num_coef
+#endif
+ );
+ }
+}
+
+void avs3_bufmgr_init(struct avs3_decoder *hw)
+{
+ int i;
+ //DEC_CTX *ctx = &hw->ctx;
+ hw->ctx.dpm.hw = hw;
+ for (i = 0; i < NUM_ALF_COMPONENT; i++)
+ hw->p_alfPictureParam[i] = &hw->m_alfPictureParam[i];
+ hw->ctx.info.pic_header.alf_picture_param = &hw->p_alfPictureParam[0];
+
+ init_pic_pool(hw);
+
+ init_libvcdata(&hw->libvc_data);
+ set_livcdata_dec(&hw->ctx, &hw->libvc_data);
+}
+
+int avs3_param_error_check(union param_u *param)
+{
+ if (param->p.sqh_max_dpb_size > MAX_PB_SIZE) {
+ pr_err("%s, param->p.sqh_max_dpb_size %d error\n", __func__, param->p.sqh_max_dpb_size);
+ return COM_ERR;
+ }
+
+ if ((param->p.pic_header_rpl_l0_ref_pic_num > MAX_NUM_REF_PICS) ||
+ (param->p.pic_header_rpl_l1_ref_pic_num > MAX_NUM_REF_PICS)) {
+ pr_info("%s, rpl_ref_pic_num %d, %d error\n", __func__,
+ param->p.pic_header_rpl_l0_ref_pic_num,
+ param->p.pic_header_rpl_l1_ref_pic_num);
+ return COM_ERR;
+ }
+
+ return COM_OK;
+}
+
+int avs3_bufmgr_process(struct avs3_decoder *hw, int start_code)
+{
+ int ret;
+ COM_PIC *pic;
+ DEC_CTX *ctx = &hw->ctx;
+ int i;
+ printf("%s start_code 0x%x\n", __func__, start_code);
+
+ if (avs3_param_error_check(&hw->param))
+ return COM_ERR;
+
+ ret = dec_cnk(&hw->ctx, &hw->stat, start_code, &hw->param,
+ hw->max_pb_size);
+ if (start_code == SEQUENCE_HEADER_CODE) {
+ hw->lcu_size = hw->ctx.info.max_cuwh;
+ hw->lcu_size_log2 = hw->ctx.info.log2_max_cuwh;
+ hw->lcu_x_num = hw->ctx.info.pic_width_in_lcu;
+ hw->lcu_y_num = hw->ctx.info.pic_height_in_lcu;
+ hw->lcu_total = hw->ctx.info.f_lcu;
+ printf("lcu_size %d lcu_size_log2 %d lcu_total %d\n", hw->lcu_size, hw->lcu_size_log2, hw->lcu_total);
+ } else if (start_code == I_PICTURE_START_CODE || start_code == PB_PICTURE_START_CODE) {
+ //hw->input.sample_bit_depth = hw->ctx.info.bit_depth_input;
+ hw->input.sample_bit_depth = hw->ctx.info.bit_depth_internal;
+ hw->input.alf_enable = ctx->info.sqh.adaptive_leveling_filter_enable_flag;
+ for (i = 0; i < NUM_ALF_COMPONENT; i++)
+ hw->img.pic_alf_on[i] = hw->ctx.pic_alf_on[i];
+ hw->img.width = hw->ctx.pa.width;
+ hw->img.height = hw->ctx.pa.height;
+ hw->slice_type = hw->ctx.info.pic_header.slice_type;
+ pic = ctx->pic;
+ if (pic && (!ret)) {
+ hw->cur_pic = &pic->buf_cfg;
+ printf("set refpic before cur_pic index %d, pic %p L0 num:%d, L1 num:%d\n",
+ hw->cur_pic->index, hw->cur_pic, hw->cur_pic->list0_num_refp, hw->cur_pic->list1_num_refp);
+ hw->cur_pic->list0_num_refp = hw->ctx.dpm.num_refp[REFP_0];
+ for (i = 0; i < hw->ctx.dpm.num_refp[REFP_0]; i++)
+ hw->cur_pic->list0_ptr[i] = hw->ctx.refp[i][REFP_0].ptr;
+#ifdef NEW_FRONT_BACK_CODE
+ for (i = 0; i < hw->cur_pic->list0_num_refp; i++)
+ hw->cur_pic->list0_index[i] = hw->ctx.refp[i][REFP_0].pic->buf_cfg.index;
+
+ hw->cur_pic->list1_num_refp = hw->ctx.dpm.num_refp[REFP_1];
+ for (i = 0; i < hw->cur_pic->list1_num_refp; i++)
+ hw->cur_pic->list1_index[i] = hw->ctx.refp[i][REFP_1].pic->buf_cfg.index;
+#endif
+ printf("set refpic after cur_pic index %d, pic %p L0 num:%d, L1 num:%d\n",
+ hw->cur_pic->index, hw->cur_pic, hw->cur_pic->list0_num_refp, hw->cur_pic->list1_num_refp);
+ }
+ //Read_ALF_param(hw);
+ }
+ return ret;
+}
+
+int check_poc_in_dpb(struct avs3_decoder *hw, int poc)
+{
+ COM_PIC * pic;
+ int i = 0;
+
+ for (i = 0; i < hw->max_pb_size; i++) {
+ pic = &hw->pic_pool[i];
+ if ((pic != NULL) && (pic->buf_cfg.used) &&
+ (poc == pic->ptr) && (!(avs3_get_error_policy() & 0x8))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int avs3_bufmgr_post_process(struct avs3_decoder *hw)
+{
+ DEC_CTX *ctx = &hw->ctx;
+ DEC_STAT *stat = &hw->stat;
+ COM_SQH *sqh = &ctx->info.sqh;
+ COM_PIC_HEADER *pic_header = &ctx->info.pic_header;
+ COM_CNKH *cnkh = &ctx->info.cnkh;
+ //COM_IMGB *imgb;
+ int ret = COM_OK;
+
+ if ((ctx->pic != NULL) && !((ctx->pic->buf_cfg.in_dpb == 0)
+ && (ctx->pic->buf_cfg.used == 1)))
+ return ret;
+
+ if (check_poc_in_dpb(hw, ctx->ptr)) {
+ ctx->pic->buf_cfg.used = 0;
+ return 2;
+ }
+
+ ctx->pic->buf_cfg.in_dpb = true;
+ if (stat)
+ {
+ com_mset(stat, 0, sizeof(DEC_STAT));
+ }
+
+ /* put decoded picture to DPB */
+#if LIBVC_ON
+ if (sqh->library_stream_flag)
+ {
+ ret = com_picman_put_libpic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index, ctx->info.pic_header.temporal_id, 1, ctx->refp, pic_header);
+ }
+ else
+#endif
+ {
+ ret = com_picman_put_pic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index,
+ pic_header->picture_output_delay, ctx->info.pic_header.temporal_id, 1, ctx->refp);
+#ifdef NEW_FRONT_BACK_CODE
+ if ((&ctx->dpm)->cur_pb_size > sqh->max_dpb_size)
+ printf("!!! (&ctx->dpm)->cur_pb_size %d > sqh->max_dpb_size %d\n",
+ (&ctx->dpm)->cur_pb_size, sqh->max_dpb_size);
+#else
+ assert((& ctx->dpm)->cur_pb_size <= sqh->max_dpb_size);
+#endif
+ }
+ cnkh->ctype = COM_CT_SLICE;
+
+ make_stat(ctx, cnkh->ctype, stat);
+ printf("### pic_cnt %d cur_num_ref_pics %d\n", ctx->pic_cnt, ctx->dpm.cur_num_ref_pics);
+#if 0
+ if (hw->stat.fnum >= 0)
+ {
+ //if (aml_print_header_info) printf(" # fnum : %d state : %d\n", stat.fnum, state);
+ COM_PIC *pic = dec_pull_frm(&hw->ctx, &imgb, 0);
+ /*
+ if (ret == COM_ERR_UNEXPECTED)
+ {
+ //v1print("bumping process completed\n");
+ //printf("COM_ERR_UNEXPECTED\n");
+ //ret = -1;
+ }
+ else if (COM_FAILED(ret))
+ {
+ //v0print("failed to pull the decoded image\n");
+ printf("failed to pull the decoded image\n");
+ ret = -1;
+ }*/
+ }
+ else
+ {
+ imgb = NULL;
+ }
+#endif
+#if 0
+ if (imgb)
+ {
+ width = imgb->width[0];
+ height = imgb->height[0];
+ if (op_flag[OP_FLAG_FNAME_OUT])
+ {
+ write_dec_img(id, op_fname_out, imgb, ((DEC_CTX *)id)->info.bit_depth_internal);
+ }
+ imgb->release(imgb);
+ pic_cnt++;
+ }
+#endif
+ return ret;
+
+}
+
+void avs3_cleanup_useless_pic_buffer_in_pm(struct avs3_decoder *hw)
+{
+ com_cleanup_useless_pic_buffer_in_pm(&hw->ctx.dpm);
+}
+
+COM_PIC * com_pic_alloc(struct avs3_decoder *hw, PICBUF_ALLOCATOR * pa, int * ret)
+{
+ COM_PIC * pic = NULL;
+ int i;
+ for (i = 0; i < hw->max_pb_size; i++) {
+ if (hw->pic_pool[i].buf_cfg.used == 0) {
+ break;
+ }
+ }
+ if (i < hw->max_pb_size) {
+ avs3_frame_t pic_cfg;
+ pic = &hw->pic_pool[i];
+ memcpy(&pic_cfg, &pic->buf_cfg, sizeof(avs3_frame_t));
+ memset(pic, 0, sizeof(COM_PIC));
+ pic->width_luma = pa->width;
+ pic->height_luma = pa->height;
+ memcpy(&pic->buf_cfg, &pic_cfg, sizeof(avs3_frame_t));
+ pic->buf_cfg.used = 1;
+ pic->buf_cfg.slice_type = hw->ctx.info.pic_header.slice_type;
+#ifdef AML
+ pic->buf_cfg.error_mark = 0;
+ pic->buf_cfg.vf_ref = 0;
+ pic->buf_cfg.backend_ref = 0;
+ pic->buf_cfg.in_dpb = false;
+ pic->buf_cfg.time = div64_u64(local_clock(), 1000) - hw->start_time;
+ pic->buf_cfg.decoded_lcu = 0;
+#ifdef NEW_FB_CODE
+ pic->buf_cfg.back_done_mark = 1;
+#endif
+#endif
+
+ }
+ if (pic)
+ printf("%s: pic index %d\n", __func__, pic->buf_cfg.index);
+ else
+ printf("%s: ret NULL\n", __func__);
+ return pic;
+ //return com_picbuf_alloc(pa->width, pa->height, pa->pad_l, pa->pad_c, ret);
+}
+
+void com_pic_free(struct avs3_decoder *hw, PICBUF_ALLOCATOR *pa, COM_PIC *pic)
+{
+ pic->buf_cfg.used = 0;
+ pic->buf_cfg.in_dpb = 0;
+ printf("%s: pic index %d\n", __func__, pic->buf_cfg.index);
+}
+
+void init_pic_pool(struct avs3_decoder *hw)
+{
+ int i;
+ COM_PIC * pic;
+ for (i = 0; i < MAX_PB_SIZE; i++) {
+ pic = &hw->pic_pool[i];
+ memset(pic, 0, sizeof (COM_PIC));
+ if (i < hw->max_pb_size) {
+ pic->buf_cfg.used = 0;
+ pic->buf_cfg.index = i;
+ } else {
+ pic->buf_cfg.used = -1;
+ pic->buf_cfg.index = -1;
+ }
+ }
+
+}
+
+#if 0
+void readAlfCoeff(struct avs3_decoder *avs3_dec, ALFParam *Alfp)
+{
+ int32_t pos;
+ union param_u *rpm_param = &avs3_dec->param;
+
+ int32_t f = 0, symbol, pre_symbole;
+ const int32_t numCoeff = (int32_t)ALF_MAX_NUM_COEF;
+
+ switch (Alfp->componentID) {
+ case ALF_Cb:
+ case ALF_Cr: {
+ for (pos = 0; pos < numCoeff; pos++) {
+ if (Alfp->componentID == ALF_Cb)
+ Alfp->coeffmulti[0][pos] = rpm_param->alf.alf_cb_coeffmulti[pos];
+ else
+ Alfp->coeffmulti[0][pos] = rpm_param->alf.alf_cr_coeffmulti[pos];
+#if Check_Bitstream
+ if (pos <= 7)
+ assert( Alfp->coeffmulti[0][pos]>=-64&& Alfp->coeffmulti[0][pos]<=63);
+ if (pos == 8)
+ assert( Alfp->coeffmulti[0][pos]>=-1088&& Alfp->coeffmulti[0][pos]<=1071);
+#endif
+ }
+ }
+ break;
+ case ALF_Y: {
+ int32_t region_distance_idx = 0;
+ Alfp->filters_per_group = rpm_param->alf.alf_filters_num_m_1;
+#if Check_Bitstream
+ assert(Alfp->filters_per_group >= 0&&Alfp->filters_per_group <= 15);
+#endif
+ Alfp->filters_per_group = Alfp->filters_per_group + 1;
+
+ memset(Alfp->filterPattern, 0, NO_VAR_BINS * sizeof(int32_t));
+ pre_symbole = 0;
+ symbol = 0;
+ for (f = 0; f < Alfp->filters_per_group; f++) {
+ if (f > 0) {
+ if (Alfp->filters_per_group != 16) {
+ symbol = rpm_param->alf.region_distance[region_distance_idx++];
+ } else {
+ symbol = 1;
+ }
+ Alfp->filterPattern[symbol + pre_symbole] = 1;
+ pre_symbole = symbol + pre_symbole;
+ }
+
+ for (pos = 0; pos < numCoeff; pos++) {
+ Alfp->coeffmulti[f][pos] = rpm_param->alf.alf_y_coeffmulti[f][pos];
+#if Check_Bitstream
+ if (pos <= 7)
+ assert( Alfp->coeffmulti[f][pos]>=-64&& Alfp->coeffmulti[f][pos]<=63);
+ if (pos == 8)
+ assert( Alfp->coeffmulti[f][pos]>=-1088&& Alfp->coeffmulti[f][pos]<=1071);
+#endif
+
+ }
+ }
+
+#if Check_Bitstream
+ assert(pre_symbole >= 0&&pre_symbole <= 15);
+
+#endif
+ }
+ break;
+ default: {
+ printf("Not a legal component ID\n");
+ assert(0);
+ exit(-1);
+ }
+ }
+}
+
+void Read_ALF_param(struct avs3_decoder *avs3_dec)
+{
+ struct inp_par *input = &avs3_dec->input;
+ ImageParameters *img = &avs3_dec->img;
+ union param_u *rpm_param = &avs3_dec->param;
+ int32_t compIdx;
+ int32_t j,k;
+ if (input->alf_enable) {
+ img->pic_alf_on[0] = rpm_param->alf.picture_alf_enable_Y;
+ img->pic_alf_on[1] = rpm_param->alf.picture_alf_enable_Cb;
+ img->pic_alf_on[2] = rpm_param->alf.picture_alf_enable_Cr;
+
+ avs3_dec->m_alfPictureParam[ALF_Y].alf_flag = img->pic_alf_on[ALF_Y];
+ avs3_dec->m_alfPictureParam[ALF_Cb].alf_flag = img->pic_alf_on[ALF_Cb];
+ avs3_dec->m_alfPictureParam[ALF_Cr].alf_flag = img->pic_alf_on[ALF_Cr];
+ if (img->pic_alf_on[0] || img->pic_alf_on[1] || img->pic_alf_on[2]) {
+ for (compIdx = 0; compIdx < NUM_ALF_COMPONENT; compIdx++) {
+ if (img->pic_alf_on[compIdx]) {
+ readAlfCoeff(avs3_dec, &avs3_dec->m_alfPictureParam[compIdx]);
+ }
+ }
+ }
+ }
+
+}
+#endif
+
+void print_param(union param_u * param)
+{
+
+ printk("sqh->profile_id = %d (0x%x)\n", param->p.sqh_profile_id, param->p.sqh_profile_id);
+ printk("sqh->level_id = %d (0x%x)\n", param->p.sqh_level_id, param->p.sqh_level_id);
+ printk("sqh->progressive_sequence = %d (0x%x)\n", param->p.sqh_progressive_sequence, param->p.sqh_progressive_sequence);
+ printk("sqh->field_coded_sequence = %d (0x%x)\n", param->p.sqh_field_coded_sequence, param->p.sqh_field_coded_sequence);
+ printk("sqh->library_stream_flag = %d (0x%x)\n", param->p.sqh_library_stream_flag, param->p.sqh_library_stream_flag);
+ printk("sqh->library_picture_enable_flag = %d (0x%x)\n", param->p.sqh_library_picture_enable_flag, param->p.sqh_library_picture_enable_flag);
+ printk("sqh->horizontal_size = %d (0x%x)\n", param->p.sqh_horizontal_size, param->p.sqh_horizontal_size);
+ printk("sqh->vertical_size = %d (0x%x)\n", param->p.sqh_vertical_size, param->p.sqh_vertical_size);
+ printk("sqh->sample_precision = %d (0x%x)\n", param->p.sqh_sample_precision, param->p.sqh_sample_precision);
+ printk("sqh->encoding_precision = %d (0x%x)\n", param->p.sqh_encoding_precision, param->p.sqh_encoding_precision);
+ printk("sqh->aspect_ratio = %d (0x%x)\n", param->p.sqh_aspect_ratio, param->p.sqh_aspect_ratio);
+ printk("sqh->frame_rate_code = %d (0x%x)\n", param->p.sqh_frame_rate_code, param->p.sqh_frame_rate_code);
+ printk("sqh->low_delay = %d (0x%x)\n", param->p.sqh_low_delay, param->p.sqh_low_delay);
+ printk("sqh->temporal_id_enable_flag = %d (0x%x)\n", param->p.sqh_temporal_id_enable_flag, param->p.sqh_temporal_id_enable_flag);
+ printk("sqh->max_dpb_size = %d (0x%x)\n", param->p.sqh_max_dpb_size, param->p.sqh_max_dpb_size);
+ printk("sqh->log2_max_cu_width_height = %d (0x%x)\n", param->p.sqh_log2_max_cu_width_height, param->p.sqh_log2_max_cu_width_height);
+ printk("sqh->adaptive_leveling_filter_enable_flag = %d (0x%x)\n", param->p.sqh_adaptive_leveling_filter_enable_flag, param->p.sqh_adaptive_leveling_filter_enable_flag);
+ printk("sqh->num_of_hmvp_cand = %d (0x%x)\n", param->p.sqh_num_of_hmvp_cand, param->p.sqh_num_of_hmvp_cand);
+ printk("sqh->output_reorder_delay = %d (0x%x)\n", param->p.sqh_output_reorder_delay, param->p.sqh_output_reorder_delay);
+ printk("sqh->cross_patch_loop_filter = %d (0x%x)\n", param->p.sqh_cross_patch_loop_filter, param->p.sqh_cross_patch_loop_filter);
+ printk("pic_header->decode_order_index = %d (0x%x)\n", param->p.pic_header_decode_order_index, param->p.pic_header_decode_order_index);
+ printk("pic_header->picture_output_delay = %d (0x%x)\n", param->p.pic_header_picture_output_delay, param->p.pic_header_picture_output_delay);
+ printk("pic_header->progressive_frame = %d (0x%x)\n", param->p.pic_header_progressive_frame, param->p.pic_header_progressive_frame);
+ printk("pic_header->top_field_first = %d (0x%x)\n", param->p.pic_header_top_field_first, param->p.pic_header_top_field_first);
+ printk("pic_header->repeat_first_field = %d (0x%x)\n", param->p.pic_header_repeat_first_field, param->p.pic_header_repeat_first_field);
+ printk("pic_header->rpl_l0_idx = %d (0x%x)\n", param->p.pic_header_rpl_l0_idx, param->p.pic_header_rpl_l0_idx);
+ printk("pic_header->rpl_l1_idx = %d (0x%x)\n", param->p.pic_header_rpl_l1_idx, param->p.pic_header_rpl_l1_idx);
+ printk("pic_header->rpl_l0.ref_pic_num = %d (0x%x)\n", param->p.pic_header_rpl_l0_ref_pic_num, param->p.pic_header_rpl_l0_ref_pic_num);
+ printk("pic_header->rpl_l1.ref_pic_num = %d (0x%x)\n", param->p.pic_header_rpl_l1_ref_pic_num, param->p.pic_header_rpl_l1_ref_pic_num);
+ printk("pic_header->rpl_l0.reference_to_library_enable_flag = %d (0x%x)\n", param->p.pic_header_rpl_l0_reference_to_library_enable_flag, param->p.pic_header_rpl_l0_reference_to_library_enable_flag);
+ printk("pic_header->rpl_l1.reference_to_library_enable_flag = %d (0x%x)\n", param->p.pic_header_rpl_l1_reference_to_library_enable_flag, param->p.pic_header_rpl_l1_reference_to_library_enable_flag);
+ printk("pic_header->loop_filter_disable_flag = %d (0x%x)\n", param->p.pic_header_loop_filter_disable_flag, param->p.pic_header_loop_filter_disable_flag);
+ printk("pic_header->random_access_decodable_flag = %d (0x%x)\n", param->p.pic_header_random_access_decodable_flag, param->p.pic_header_random_access_decodable_flag);
+ printk("pic_header->slice_type = %d (0x%x)\n", param->p.pic_header_slice_type, param->p.pic_header_slice_type);
+ printk("pic_header->num_ref_idx_active_override_flag = %d (0x%x)\n", param->p.pic_header_num_ref_idx_active_override_flag, param->p.pic_header_num_ref_idx_active_override_flag);
+ printk("pic_header->rpl_l0.ref_pic_active_num = %d (0x%x)\n", param->p.pic_header_rpl_l0_ref_pic_active_num, param->p.pic_header_rpl_l0_ref_pic_active_num);
+ printk("pic_header->rpl_l1.ref_pic_active_num = %d (0x%x)\n", param->p.pic_header_rpl_l1_ref_pic_active_num, param->p.pic_header_rpl_l1_ref_pic_active_num);
+ printk("sqh->adaptive_filter_shape_enable_flag = %d (0x%x)\n", param->p.sqh_adaptive_filter_shape_enable_flag, param->p.sqh_adaptive_filter_shape_enable_flag);
+ printk("pic->header_library_picture_index = %d (0x%x)\n", param->p.pic_header_library_picture_index, param->p.pic_header_library_picture_index);
+ printk("pic->header_top_field_picture_flag = %d (0x%x)\n", param->p.pic_header_top_field_picture_flag, param->p.pic_header_top_field_picture_flag);
+ printk("pic->header->alpha_c_offset = %d (0x%x)\n", param->p.pic_header_alpha_c_offset, param->p.pic_header_alpha_c_offset);
+ printk("pic->header->beta_offset = %d (0x%x)\n", param->p.pic_header_beta_offset, param->p.pic_header_beta_offset);
+ printk("pic->header->chroma_quant_param_delta_cb = %d (0x%x)\n", param->p.pic_header_chroma_quant_param_delta_cb, param->p.pic_header_chroma_quant_param_delta_cb);
+ printk("pic->header->chroma_quant_param_delta_cr = %d (0x%x)\n", param->p.pic_header_chroma_quant_param_delta_cr, param->p.pic_header_chroma_quant_param_delta_cr);
+};
+
+void print_alf_param(union param_u * param)
+{
+ int i, ii;
+ int pos = 0;
+ char tmpbuf[128];
+ printk("picture_alf_enable_Y %d picture_alf_enable_Cb %d picture_alf_enable_Cr %d\n", param->alf.picture_alf_enable_Y, param->alf.picture_alf_enable_Cb, param->alf.picture_alf_enable_Cr);
+ printk("alf_filters_num_m_1 %d dir_index %d\n", param->alf.alf_filters_num_m_1, param->alf.dir_index);
+ for (i = 0; i < 16; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", param->alf.region_distance[i]);
+ printk("region_distance: %s\n", tmpbuf);
+
+ pos = 0;
+ for (i = 0; i < 9; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_cb_coeffmulti[i]);
+ printk("alf_cb_coeffmulti: %s\n", tmpbuf);
+
+ pos = 0;
+ for (i = 0; i < 9; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_cr_coeffmulti[i]);
+ printk("alf_cr_coeffmulti: %s\n", tmpbuf);
+
+ for (ii = 0; ii < 16; ii++) {
+ pos = 0;
+ for (i = 0; i < 9; i++)
+ pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_y_coeffmulti[ii][i]);
+ printk("alf_y_coeffmulti[%d][]: %s\n", ii, tmpbuf);
+ }
+}
+
+void print_pic_pool(struct avs3_decoder *hw, char *mark)
+{
+ COM_PIC * pic;
+ int i;
+ int used_count = 0;
+ char tmpbuf[128];
+ COM_PM *pm = &hw->ctx.dpm;
+ int pm_count = 0, pm_ref_count = 0;
+ for (i = 0; i < hw->max_pb_size; i++) {
+ pic = &hw->pic_pool[i];
+ if (pic->buf_cfg.used)
+ used_count++;
+ }
+
+ for (i = 0; i < pm->max_pb_size; i++)
+ {
+ if (pm->pic[i] != NULL) {
+ pm_ref_count++;
+ } else {
+ break;
+ }
+ }
+
+ for (i = 0; i < pm->max_pb_size; i++)
+ {
+ if (pm->pic[i] != NULL) {
+ pm_count++;
+ }
+ }
+
+ printk("%s----pic_pool (used %d, total %d) cur_num_ref_pics %d pm count %d, pm_ref_count %d diff %d\n", mark, used_count, hw->max_pb_size,
+ hw->ctx.dpm.cur_num_ref_pics, pm_count, pm_ref_count, used_count - pm_count);
+
+ for (i = 0; i < hw->max_pb_size; i++) {
+ pic = &hw->pic_pool[i];
+ if (pic->buf_cfg.used) {
+#ifdef NEW_FRONT_BACK_CODE
+ int pos = 0, j;
+ pos += sprintf(&tmpbuf[pos], "(");
+ for (j = 0; j < pic->buf_cfg.list0_num_refp; j++)
+ pos += sprintf(&tmpbuf[pos], "%d ", pic->buf_cfg.list0_index[j]);
+ pos += sprintf(&tmpbuf[pos], ")");
+ pos += sprintf(&tmpbuf[pos], "(");
+ for (j = 0; j < pic->buf_cfg.list1_num_refp; j++)
+ pos += sprintf(&tmpbuf[pos], "%d ", pic->buf_cfg.list1_index[j]);
+ pos += sprintf(&tmpbuf[pos], ")");
+#else
+ tmpbuf[0] = 0;
+#endif
+ printk("%d (%p): buf_cfg index %d depth %d dtr %d ptr %d is_ref %d need_for_out %d, backend_ref %d, vf_ref %d, output_delay %d, w/h(%d,%d) id %d slicetype %d error_mark %d ref index:%s in_dpb %d time %lld\n",
+ i, pic, pic->buf_cfg.index, pic->buf_cfg.depth,
+ pic->dtr, pic->ptr, pic->is_ref,
+ pic->need_for_out,
+ pic->buf_cfg.backend_ref, pic->buf_cfg.vf_ref,
+ pic->picture_output_delay,
+ pic->width_luma, pic->height_luma, pic->temporal_id,
+ pic->buf_cfg.slice_type,
+ pic->buf_cfg.error_mark,
+ tmpbuf,
+ pic->buf_cfg.in_dpb,
+ pic->buf_cfg.time
+ );
+ }
+ }
+
+ for (i = 0; i < pm->max_pb_size; i++)
+ {
+ if (pm->pic[i] != NULL) {
+ printk("pm pic %p index %d\n", pm->pic[i], i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c b/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c
new file mode 100644
index 0000000..13539e5
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c
@@ -0,0 +1,3233 @@
+#include "../../../include/regs/dos_registers.h"
+#include "../../../common/media_utils/media_utils.h"
+
+#ifdef FOR_S5
+ulong dos_reg_compat_convert(ulong adr);
+#endif
+
+/* to do */
+#define DOUBLE_WRITE_VH0_TEMP 0
+#define DOUBLE_WRITE_VH1_TEMP 0
+#define DOUBLE_WRITE_VH0_HALF 0
+#define DOUBLE_WRITE_VH1_HALF 0
+//#define DOS_BASE_ADR 0xd0050000
+#if 0
+//#define HEVC_SAO_MMU_VH0_ADDR_DBE1 0
+//#define HEVC_SAO_MMU_VH1_ADDR_DBE1 0
+#define HEVCD_MPP_DECOMP_AXIURG_CTL 0
+
+#define HEVC_MPRED_POC24_CTRL0 0
+#define HEVC_MPRED_POC24_CTRL1 0
+
+#define HEVCD_MCRCC_PERFMON_CTL_DBE1 0
+#define HEVCD_MCRCC_PERFMON_DATA_DBE1 0
+#define HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1 0
+#define HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1 0
+#endif
+//#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
+//#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+/**/
+#define DOS_BASE_ADR 0x0
+
+#define print_scratch_error(a)
+//#define MEM_MAP_MODE 0
+
+//typedef union param_u param_t;
+
+#define PRINT_HEVC_DATA_PATH_MONITOR
+//static unsigned mcrcc_hit_rate;
+static unsigned mcrcc_hit_rate_0;
+static unsigned mcrcc_hit_rate_1;
+//static unsigned mcrcc_bypass_rate;
+static unsigned mcrcc_bypass_rate_0;
+static unsigned mcrcc_bypass_rate_1;
+
+static void init_pic_list_hw_fb(struct AVS3Decoder_s *dec);
+
+static void C_Reg_Rd(unsigned adr, unsigned *pval)
+{
+ *pval = READ_VREG(adr);
+}
+
+static void mcrcc_perfcount_reset_dual(struct AVS3Decoder_s *dec)
+{
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[cache_util.c] Entered mcrcc_perfcount_reset_dual...\n");
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)0x0);
+ return;
+}
+
+static void mcrcc_get_hitrate_dual(int pic_num)
+{
+ unsigned tmp;
+ unsigned raw_mcr_cnt;
+ unsigned hit_mcr_cnt;
+ unsigned byp_mcr_cnt_nchoutwin;
+ unsigned byp_mcr_cnt_nchcanv;
+ unsigned hit_mcr_0_cnt;
+ unsigned hit_mcr_1_cnt;
+ unsigned hitrate;
+ printk("[cache_util.c] Entered mcrcc_get_hitrate_dual...\n");
+
+ printk("[MCRCC CORE ] Picture : %d\n",pic_num);
+
+ // CORE 0
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchoutwin);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchcanv);
+
+ printk("[MCRCC CORE0] raw_mcr_cnt: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE0] hit_mcr_cnt: %d\n",hit_mcr_cnt);
+ printk("[MCRCC CORE0] byp_mcr_cnt_nchoutwin: %d\n",byp_mcr_cnt_nchoutwin);
+ printk("[MCRCC CORE0] byp_mcr_cnt_nchcanv: %d\n",byp_mcr_cnt_nchcanv);
+
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
+ printk("[MCRCC CORE0] miss_mcr_0_cnt: %d\n",tmp);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
+ printk("[MCRCC CORE0] miss_mcr_1_cnt: %d\n",tmp);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_0_cnt);
+ printk("[MCRCC CORE0] hit_mcr_0_cnt: %d\n",hit_mcr_0_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_1_cnt);
+ printk("[MCRCC CORE0] hit_mcr_1_cnt: %d\n",hit_mcr_1_cnt);
+
+ if ( raw_mcr_cnt != 0 ) {
+ hitrate = (hit_mcr_0_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE0] CANV0_HIT_RATE : %d\n", hitrate);
+ hitrate = (hit_mcr_1_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE0] CANV1_HIT_RATE : %d\n", hitrate);
+ hitrate = (byp_mcr_cnt_nchcanv *100 / raw_mcr_cnt);
+ printk("[MCRCC CORE0] NONCACH_CANV_BYP_RATE : %d\n", hitrate);
+ hitrate = (byp_mcr_cnt_nchoutwin *100 / raw_mcr_cnt);
+ printk("[MCRCC CORE0] CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
+ }
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ printk("[P%d MCRCC CORE0] MCRCC_HIT_RATE : %d\n", pic_num, hitrate);
+ hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 / raw_mcr_cnt);
+ printk("[P%d MCRCC CORE0] MCRCC_BYP_RATE : %d\n", pic_num, hitrate);
+ } else
+ {
+ printk("[P%d MCRCC CORE0] MCRCC_HIT_RATE : na\n", pic_num);
+ printk("[P%d MCRCC CORE0] MCRCC_BYP_RATE : na\n", pic_num);
+ }
+
+ mcrcc_hit_rate_0 = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ mcrcc_bypass_rate_0 = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+
+ // CORE 0
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x0<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x1<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x2<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &byp_mcr_cnt_nchoutwin);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x3<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &byp_mcr_cnt_nchcanv);
+
+ printk("[MCRCC CORE1] raw_mcr_cnt: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE1] hit_mcr_cnt: %d\n",hit_mcr_cnt);
+ printk("[MCRCC CORE1] byp_mcr_cnt_nchoutwin: %d\n",byp_mcr_cnt_nchoutwin);
+ printk("[MCRCC CORE1] byp_mcr_cnt_nchcanv: %d\n",byp_mcr_cnt_nchcanv);
+
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x4<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &tmp);
+ printk("[MCRCC CORE1] miss_mcr_0_cnt: %d\n",tmp);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x5<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &tmp);
+ printk("[MCRCC CORE1] miss_mcr_1_cnt: %d\n",tmp);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x6<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_0_cnt);
+ printk("[MCRCC CORE1] hit_mcr_0_cnt: %d\n",hit_mcr_0_cnt);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x7<<1));
+ C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_1_cnt);
+ printk("[MCRCC CORE1] hit_mcr_1_cnt: %d\n",hit_mcr_1_cnt);
+
+ if ( raw_mcr_cnt != 0 ) {
+ hitrate = (hit_mcr_0_cnt * 100 /raw_mcr_cnt);
+ printk("[MCRCC CORE1] CANV0_HIT_RATE : %d\n", hitrate);
+ hitrate = (hit_mcr_1_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE1] CANV1_HIT_RATE : %d\n", hitrate);
+ hitrate = (byp_mcr_cnt_nchcanv * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE1] NONCACH_CANV_BYP_RATE : %d\n", hitrate);
+ hitrate = (byp_mcr_cnt_nchoutwin * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE1] CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
+ }
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ printk("[P%d MCRCC CORE1] MCRCC_HIT_RATE : %d\n", pic_num, hitrate);
+ hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+ printk("[P%d MCRCC CORE1] MCRCC_BYP_RATE : %d\n", pic_num, hitrate);
+ } else
+ {
+ printk("[P%d MCRCC CORE1] MCRCC_HIT_RATE : na\n", pic_num);
+ printk("[P%d MCRCC CORE1] MCRCC_BYP_RATE : na\n", pic_num);
+ }
+
+ mcrcc_hit_rate_1 = (hit_mcr_cnt * 100 /raw_mcr_cnt);
+ mcrcc_bypass_rate_1 = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+
+ return;
+}
+
+static void decomp_perfcount_reset_dual(struct AVS3Decoder_s *dec)
+{
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[cache_util.c] Entered decomp_perfcount_reset_dual...\n");
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)0x0);
+ return;
+}
+
+static void decomp_get_hitrate_dual(int pic_num)
+{
+ unsigned raw_mcr_cnt;
+ unsigned hit_mcr_cnt;
+ unsigned hitrate;
+ printk("[cache_util.c] Entered decomp_get_hitrate_dual...\n");
+
+ // CORE0
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
+
+ printk("[MCRCC CORE0] hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE0] hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 /raw_mcr_cnt);
+ printk("[MCRCC CORE0] DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+ } else
+ {
+ printk("[MCRCC CORE0] DECOMP_HCACHE_HIT_RATE : na\n");
+ }
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
+
+ printk("[MCRCC CORE0] dcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE0] dcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE0] DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+
+ hitrate = (mcrcc_hit_rate_0 + (mcrcc_bypass_rate_0 * hit_mcr_cnt / raw_mcr_cnt ));
+ printk("[MCRCC CORE0] MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate);
+
+ } else
+ {
+ printk("[MCRCC CORE0] DECOMP_DCACHE_HIT_RATE : na\n");
+ }
+
+ // CORE1
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x0<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x1<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+
+ printk("[MCRCC CORE1] hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE1] hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE1] DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+ } else
+ {
+ printk("[MCRCC CORE1] DECOMP_HCACHE_HIT_RATE : na\n");
+ }
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x2<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x3<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+
+ printk("[MCRCC CORE1] dcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+ printk("[MCRCC CORE1] dcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+ if ( raw_mcr_cnt != 0 )
+ {
+ hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+ printk("[MCRCC CORE1] DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+
+ hitrate = (mcrcc_hit_rate_1 + (mcrcc_bypass_rate_1 * hit_mcr_cnt / raw_mcr_cnt));
+ printk("[MCRCC CORE1] MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate);
+
+ } else
+ {
+ printk("[MCRCC CORE1] DECOMP_DCACHE_HIT_RATE : na\n");
+ }
+
+ return;
+}
+
+static void decomp_get_comprate_dual(int pic_num)
+{
+ unsigned raw_ucomp_cnt;
+ unsigned fast_comp_cnt;
+ unsigned slow_comp_cnt;
+ unsigned comprate;
+
+ printk("[cache_util.c] Entered decomp_get_comprate_dual...\n");
+
+ // CORE0
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &fast_comp_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &slow_comp_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_ucomp_cnt);
+
+ printk("[MCRCC CORE0] decomp_fast_comp_total: %d\n",fast_comp_cnt);
+ printk("[MCRCC CORE0] decomp_slow_comp_total: %d\n",slow_comp_cnt);
+ printk("[MCRCC CORE0] decomp_raw_uncomp_total: %d\n",raw_ucomp_cnt);
+
+ if ( raw_ucomp_cnt != 0 )
+ {
+ comprate = ((fast_comp_cnt + slow_comp_cnt) *100 / raw_ucomp_cnt);
+ printk("[MCRCC CORE0] DECOMP_COMP_RATIO : %d\n", comprate);
+ } else
+ {
+ printk("[MCRCC CORE0] DECOMP_COMP_RATIO : na\n");
+ }
+
+ // CORE1
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x4<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &fast_comp_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x5<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &slow_comp_cnt);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x6<<1));
+ C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_ucomp_cnt);
+
+ printk("[MCRCC CORE1] decomp_fast_comp_total: %d\n",fast_comp_cnt);
+ printk("[MCRCC CORE1] decomp_slow_comp_total: %d\n",slow_comp_cnt);
+ printk("[MCRCC CORE1] decomp_raw_uncomp_total: %d\n",raw_ucomp_cnt);
+
+ if ( raw_ucomp_cnt != 0 )
+ {
+ comprate = ((fast_comp_cnt + slow_comp_cnt) * 100 /raw_ucomp_cnt);
+ printk("[MCRCC CORE1] DECOMP_COMP_RATIO : %d\n", comprate);
+ } else
+ {
+ printk("[MCRCC CORE1] DECOMP_COMP_RATIO : na\n");
+ }
+
+ return;
+}
+
+static void print_mcrcc_hit_info(int pic_num) {
+ //printk("before call mcrcc_get_hitrate\r\n");
+ mcrcc_get_hitrate_dual(pic_num);
+ decomp_get_hitrate_dual(pic_num);
+ decomp_get_comprate_dual(pic_num);
+}
+
+static void WRITE_BACK_RET(struct avs3_decoder *avs3_dec)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0xcc00000; //ret
+ avs3_print(dec, AVS3_DBG_REG,
+ "WRITE_BACK_RET()\ninstruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0; //nop
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+}
+
+static void WRITE_BACK_8(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint8_t data)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x20<<22) | ((spr_addr&0xfff)<<8) | (data&0xff); //mtspi data, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data,
+ avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void WRITE_BACK_16(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint8_t rd_addr, uint16_t data)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6) | (rd_addr&0x3f); // movi rd_addr, data[15:0]
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x,%x)\ninstruction[%3d] = %8x, data= %x\n",
+ __func__, spr_addr, rd_addr, data,
+ avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset], data&0xffff);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f); // mtsp rd_addr, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void WRITE_BACK_32(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint32_t data)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6); // movi COMMON_REG_0, data
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data,
+ avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ data = (data & 0xffff0000)>>16;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1b<<22) | (data<<6); // mvihi COMMON_REG_0, data[31:16]
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8); // mtsp COMMON_REG_0, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void READ_INS_WRITE(struct avs3_decoder *avs3_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t position, uint8_t size)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+ //spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+ spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x,%x,%x,%x)\n",
+ __func__, spr_addr0, spr_addr1, rd_addr, position, size);
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f); //mtsp rd_addr, src_addr1
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+//Caution: pc offset fixed to 4, the data of cmp_addr need ready before call this function
+void READ_CMP_WRITE(struct avs3_decoder *avs3_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t cmp_addr, uint8_t position, uint8_t size)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+ //spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+ spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x,%x,%x,%x,%x)\n",
+ __func__, spr_addr0, spr_addr1, rd_addr, cmp_addr, position, size);
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x29<<22) | (4<<12) | ((rd_addr&0x3f)<<6) | cmp_addr; //cbne current_pc+4, rd_addr, cmp_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0; //nop
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, src_addr0
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f); //ins rd_addr, rd_addr, position, size
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f); //mtsp rd_addr, src_addr1
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+static void READ_WRITE_DATA16(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint16_t data, uint8_t position, uint8_t size)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ //spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8); //mfsp COMON_REG_0, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "%s(%x,%x,%x,%x)\ninstruction[%3d] = %8x\n",
+ __func__, spr_addr, data, position, size,
+ avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | (data<<6) | 1; //movi COMMON_REG_1, data
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | (0<<6) | 1; //ins COMMON_REG_0, COMMON_REG_1, position, size
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8); //mtsp COMMON_REG_0, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+ WRITE_BACK_RET(avs3_dec);
+ avs3_dec->ins_offset = 256;
+ }
+#endif
+}
+
+#if 0
+void READ_BACK_32(struct AVS3Decoder_s *dec, uint32_t spr_addr, uint8_t rd_addr)
+{
+ struct AVS3Decoder_s *dec = container_of(avs3_dec,
+ struct AVS3Decoder_s, avs3_dec);
+ spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f); //mfsp rd_addr, spr_addr
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+}
+#endif
+
+static int32_t config_mc_buffer_fb(struct AVS3Decoder_s *dec)
+{
+ int32_t i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ //avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+ avs3_frame_t *pic;
+ //uint32_t rdata32;
+ //uint32_t rdata32_2;
+ //if (avs3_dec->img.type == I_IMG)
+ // return 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "Entered config_mc_buffer....\n");
+ if (avs3_dec->f_bg != NULL) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+ avs3_dec->f_bg->mc_canvas_y, avs3_dec->f_bg->mc_canvas_u_v);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (7 << 8) | (0<<1) | 1); // L0:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (15 << 8) | (0<<1) | 1); // L0:BG
+ WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (15 << 8) | (0<<1) | 1); // L0:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (23 << 8) | (0<<1) | 1); // L1:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (31 << 8) | (0<<1) | 1); // L1:BG
+ WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (31 << 8) | (0<<1) | 1); // L1:BG
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ }
+ if (avs3_dec->slice_type == SLICE_I)
+ return 0;
+ if (avs3_dec->slice_type == SLICE_P || avs3_dec->slice_type == SLICE_B) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for REF_0, img type %d\n", avs3_dec->slice_type);
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_0]; i++) {
+ pic = &avs3_dec->ctx.refp[i][REFP_0].pic->buf_cfg;
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "L0 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ }
+ if (avs3_dec->slice_type == SLICE_B) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for REF_1\n");
+
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+ WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (16 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ pic = &avs3_dec->ctx.refp[i][REFP_1].pic->buf_cfg;
+ ///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ /// (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "L1 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ }
+ return 0;
+}
+
+#ifdef NEW_FRONT_BACK_CODE
+/*copy from simulation code*/
+
+#define FB_LMEM_SIZE_LOG2 6
+#define FB_LMEM_SIZE (1 << FB_LMEM_SIZE_LOG2)
+#define FB_VCPU_IMEM_SIZE 0x400
+#define FB_SYSTEM_IMEM_SIZE 0x400
+#define FB_SCALELUT_LMEM_SIZE 0x400
+
+#if 0
+#define FB_PARSER_SAO0_BLOCK_SIZE (4*1024*4)*64
+#define FB_PARSER_SAO1_BLOCK_SIZE (4*1024*4)*64
+#define FB_MPRED_IMP0_BLOCK_SIZE (4*1024*4)*256
+#define FB_MPRED_IMP1_BLOCK_SIZE (4*1024*4)*256
+#else
+#define FB_PARSER_SAO0_BLOCK_SIZE (4*1024*4)
+#define FB_PARSER_SAO1_BLOCK_SIZE (4*1024*4)
+#define FB_MPRED_IMP0_BLOCK_SIZE (4*1024*4)
+#define FB_MPRED_IMP1_BLOCK_SIZE (4*1024*4)
+#endif
+/**/
+#define BUF_BLOCK_NUM 256
+
+#define FB_IFBUF_SCALELUT_BLOCK_SIZE FB_SCALELUT_LMEM_SIZE
+#define FB_IFBUF_VCPU_IMEM_BLOCK_SIZE FB_VCPU_IMEM_SIZE
+#define FB_IFBUF_SYS_IMEM_BLOCK_SIZE FB_SYSTEM_IMEM_SIZE
+#define FB_IFBUF_LMEM0_BLOCK_SIZE FB_LMEM_SIZE
+#define FB_IFBUF_LMEM1_BLOCK_SIZE FB_LMEM_SIZE
+
+#define IFBUF_SCALELUT_SIZE (FB_IFBUF_SCALELUT_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_VCPU_IMEM_SIZE (FB_IFBUF_VCPU_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_SYS_IMEM_SIZE (FB_IFBUF_SYS_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM0_SIZE (FB_IFBUF_LMEM0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM1_SIZE (FB_IFBUF_LMEM1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO0_SIZE (FB_PARSER_SAO0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO1_SIZE (FB_PARSER_SAO1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP0_SIZE (FB_MPRED_IMP0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP1_SIZE (FB_MPRED_IMP1_BLOCK_SIZE * BUF_BLOCK_NUM)
+
+static void copy_loopbufs_ptr(buff_ptr_t* trg, buff_ptr_t* src)
+{
+ trg->mmu0_ptr = src->mmu0_ptr;
+ trg->mmu1_ptr = src->mmu1_ptr;
+ trg->scalelut_ptr = src->scalelut_ptr;
+ trg->vcpu_imem_ptr = src->vcpu_imem_ptr;
+ trg->sys_imem_ptr = src->sys_imem_ptr;
+ trg->sys_imem_ptr_v = src->sys_imem_ptr_v;
+ trg->lmem0_ptr = src->lmem0_ptr;
+ trg->lmem1_ptr = src->lmem1_ptr;
+ trg->parser_sao0_ptr = src->parser_sao0_ptr;
+ trg->parser_sao1_ptr = src->parser_sao1_ptr;
+ trg->mpred_imp0_ptr = src->mpred_imp0_ptr;
+ trg->mpred_imp1_ptr = src->mpred_imp1_ptr;
+ //
+ trg->scalelut_ptr_pre = src->scalelut_ptr_pre;
+}
+
+static void print_loopbufs_ptr(struct AVS3Decoder_s *dec, char* mark, buff_ptr_t* ptr)
+{
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "==%s==:\n", mark);
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "mmu0_ptr %x, mmu1_ptr %x\nscalelut_ptr %x pre_ptr %x\nvcpu_imem_ptr %x\nsys_imem_ptr %x (vir 0x%x: %02x %02x %02x %02x)\nlmem0_ptr %x, lmem1_ptr %x\nparser_sao0_ptr %x, parser_sao1_ptr %x\nmpred_imp0_ptr %x, mpred_imp1_ptr %x\n",
+ ptr->mmu0_ptr,
+ ptr->mmu1_ptr,
+ ptr->scalelut_ptr,
+ ptr->scalelut_ptr_pre,
+ ptr->vcpu_imem_ptr,
+ ptr->sys_imem_ptr,
+ ptr->sys_imem_ptr_v,
+ ((u8 *)(ptr->sys_imem_ptr_v))[0], ((u8 *)(ptr->sys_imem_ptr_v))[1],
+ ((u8 *)(ptr->sys_imem_ptr_v))[2], ((u8 *)(ptr->sys_imem_ptr_v))[3],
+ ptr->lmem0_ptr,
+ ptr->lmem1_ptr,
+ ptr->parser_sao0_ptr,
+ ptr->parser_sao1_ptr,
+ ptr->mpred_imp0_ptr,
+ ptr->mpred_imp1_ptr);
+}
+
+static void print_loopbufs_ptr2(struct AVS3Decoder_s *dec, char* mark, buff_ptr_t* p_ptr, buff_ptr_t* ptr)
+{
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "==%s==:\n", mark);
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "mmu0_ptr (%x=>%x%s) mmu1_ptr (%x=>%x%s)\nscalelut_ptr (%x=>%x%s) pre_ptr (%x=>%x%s)\nvcpu_imem_ptr (%x=>%x%s)\nsys_imem_ptr (%x=>%x%s) (vir 0x%x: %02x %02x %02x %02x)\nlmem0_ptr (%x=>%x%s), lmem1_ptr (%x=>%x%s)\nparser_sao0_ptr (%x=>%x%s), parser_sao1_ptr (%x=>%x%s)\nmpred_imp0_ptr (%x=>%x%s), mpred_imp1_ptr (%x=>%x%s)\n",
+ p_ptr->mmu0_ptr, ptr->mmu0_ptr, (ptr->mmu0_ptr<p_ptr->mmu0_ptr)?" wrap":"",
+ p_ptr->mmu1_ptr, ptr->mmu1_ptr, (ptr->mmu1_ptr<p_ptr->mmu1_ptr)?" wrap":"",
+ p_ptr->scalelut_ptr, ptr->scalelut_ptr, (ptr->scalelut_ptr<p_ptr->scalelut_ptr)?" wrap":"",
+ p_ptr->scalelut_ptr_pre, ptr->scalelut_ptr_pre, (ptr->scalelut_ptr_pre<p_ptr->scalelut_ptr_pre)?" wrap":"",
+ p_ptr->vcpu_imem_ptr, ptr->vcpu_imem_ptr, (ptr->vcpu_imem_ptr<p_ptr->vcpu_imem_ptr)?" wrap":"",
+ p_ptr->sys_imem_ptr, ptr->sys_imem_ptr, (ptr->sys_imem_ptr<p_ptr->sys_imem_ptr)?" wrap":"",
+ p_ptr->sys_imem_ptr_v,
+ ((u8 *)(ptr->sys_imem_ptr_v))[0], ((u8 *)(ptr->sys_imem_ptr_v))[1],
+ ((u8 *)(ptr->sys_imem_ptr_v))[2], ((u8 *)(ptr->sys_imem_ptr_v))[3],
+ p_ptr->lmem0_ptr, ptr->lmem0_ptr, (ptr->lmem0_ptr<p_ptr->lmem0_ptr)?" wrap":"",
+ p_ptr->lmem1_ptr, ptr->lmem1_ptr, (ptr->lmem1_ptr<p_ptr->lmem1_ptr)?" wrap":"",
+ p_ptr->parser_sao0_ptr, ptr->parser_sao0_ptr, (ptr->parser_sao0_ptr<p_ptr->parser_sao0_ptr)?" wrap":"",
+ p_ptr->parser_sao1_ptr, ptr->parser_sao1_ptr, (ptr->parser_sao1_ptr<p_ptr->parser_sao1_ptr)?" wrap":"",
+ p_ptr->mpred_imp0_ptr, ptr->mpred_imp0_ptr, (ptr->mpred_imp0_ptr<p_ptr->mpred_imp0_ptr)?" wrap":"",
+ p_ptr->mpred_imp1_ptr, ptr->mpred_imp1_ptr, (ptr->mpred_imp1_ptr<p_ptr->mpred_imp1_ptr)?" wrap":"");
+}
+
+static void print_loopbufs_adr_size(struct AVS3Decoder_s *dec)
+{
+ int i;
+ uint32_t adr, size;
+ char *name[9] = {"parser_sao0", "parser_sao1", "mpred_imp0", "mpred_imp1", "scalelut", "lmem0", "lmem1", "vcpu_imem", "sys_imem"};
+
+ avs3_print_cont(dec, 0, "loopbuf memory:\n");
+ for (i=0; i<9; i++) {
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+ adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+ size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+ avs3_print_cont(dec, 0, "%s start 0x%x size 0x%x\n", name[i], adr, size);
+ }
+ avs3_print_flush(dec);
+}
+
+static u32 dump_fb_mmu_buffer(struct AVS3Decoder_s *dec, void *mmu_map_adr, u32 mmu_map_size, u8 *file)
+{
+ int i;
+ u8 *adr = (u8 *)mmu_map_adr;
+ u32 page_phy_adr;
+ loff_t off = 0;
+ int mode = O_CREAT | O_WRONLY | O_TRUNC;
+ struct file *fp = NULL;
+
+ u32 total_check_sum = 0;
+ if (file) {
+ fp = media_open(file, mode, 0666);
+ }
+
+ for (i = 0; i < mmu_map_size; i += 4) {
+ page_phy_adr = (adr[i] | (adr[i+1]<<8) | (adr[i+2]<<16) | (adr[i+3]<<24)) << 12;
+ if (page_phy_adr)
+ d_dump(dec, page_phy_adr, 1024*4, fp, &off, &total_check_sum, 0);
+ else
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "!!%s mmu_map 0x%p, page count %d, page %d is zero\n",
+ __func__, mmu_map_adr, mmu_map_size/4, i/4);
+ }
+ if (fp) {
+ media_close(fp, current->files);
+ }
+ return total_check_sum;
+}
+
+static void fb_mmu_buffer_fill_zero(struct AVS3Decoder_s *dec, void *mmu_map_adr, u32 mmu_map_size)
+{
+ int i;
+ u32 page_phy_adr;
+ u8 *adr = (u8 *)mmu_map_adr;
+ for (i = 0; i < mmu_map_size; i += 4) {
+ page_phy_adr = (adr[i] | (adr[i+1]<<8) | (adr[i+2]<<16) | (adr[i+3]<<24)) << 12;
+ if (page_phy_adr)
+ d_dump(dec, page_phy_adr, 1024*4, NULL, NULL, NULL, 0);
+ else
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "!!%s mmu_map 0x%p, page count %d, page %d is zero\n",
+ __func__, mmu_map_adr, mmu_map_size/4, i/4);
+ }
+}
+
+static void dump_loop_buffer(struct AVS3Decoder_s *dec, int count, u8 save_file)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int i;
+ u32 total_check_sum;
+ uint32_t adr, size;
+ char *name[9] = {"parser_sao0", "parser_sao1", "mpred_imp0", "mpred_imp1", "scalelut", "lmem0", "lmem1", "vcpu_imem", "sys_imem"};
+ char file[64];
+ char mark[16];
+ for (i=0; i<9; i++) {
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+ adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+ size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+ if (save_file) {
+ if (count >= 0)
+ sprintf(&file[0], "/data/tmp/%s_%d", name[i], count);
+ else
+ sprintf(&file[0], "/data/tmp/%s", name[i]);
+ }
+ sprintf(&mark[0], "%s %d", name[i], count);
+ dump_or_fill_phy_buffer(dec, adr, size, save_file?file:NULL, 0, mark);
+ }
+ //dump mmu0
+ if (save_file) {
+ if (count >= 0)
+ sprintf(&file[0], "/data/tmp/%s_%d", "mmu0", count);
+ else
+ sprintf(&file[0], "/data/tmp/%s", "mmu0");
+ }
+ total_check_sum = dump_fb_mmu_buffer(dec, dec->fb_buf_mmu0_addr, avs3_dec->fb_buf_mmu0.buf_size, save_file?file:NULL);
+ avs3_print(dec, 0, "dump mmu0 %d (pages 0x%x) check_sum %x %s\n", count, avs3_dec->fb_buf_mmu0.buf_size/4, total_check_sum, save_file? file:"");
+
+ //dump mmu1
+ if (save_file) {
+ if (count >= 0)
+ sprintf(&file[0], "/data/tmp/%s_%d", "mmu1", count);
+ else
+ sprintf(&file[0], "/data/tmp/%s", "mmu1");
+ }
+ total_check_sum = dump_fb_mmu_buffer(dec, dec->fb_buf_mmu1_addr, avs3_dec->fb_buf_mmu1.buf_size, save_file?file:NULL);
+ avs3_print(dec, 0, "dump mmu1 %d (pages 0x%x) check_sum %x %s\n", count, avs3_dec->fb_buf_mmu1.buf_size/4, total_check_sum, save_file? file:"");
+
+ //dump bufspec
+ if (save_file) {
+ if (count >= 0)
+ sprintf(&file[0], "/data/tmp/%s_%d", "bufspec", count);
+ else
+ sprintf(&file[0], "/data/tmp/%s", "bufspec");
+ }
+ sprintf(&mark[0], "%s %d", "bufspec", count);
+ dump_or_fill_phy_buffer(dec, dec->buf_start, dec->buf_size, save_file?file:NULL, 0, mark);
+}
+
+static void loop_buffer_fill_zero(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int i;
+ uint32_t adr, size;
+ for (i=0; i<9; i++) {
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+ adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+ size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+ dump_or_fill_phy_buffer(dec, adr, size, NULL, 1, NULL);
+ }
+ fb_mmu_buffer_fill_zero(dec, dec->fb_buf_mmu0_addr, avs3_dec->fb_buf_mmu0.buf_size);
+ fb_mmu_buffer_fill_zero(dec, dec->fb_buf_mmu1_addr, avs3_dec->fb_buf_mmu1.buf_size);
+
+ dump_or_fill_phy_buffer(dec, dec->buf_start, dec->buf_size, NULL, 1, NULL);
+}
+
+static int init_mmu_fb_bufstate(struct AVS3Decoder_s *dec, int mmu_fb_4k_number)
+{
+ int ret;
+ dma_addr_t tmp_phy_adr;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int mmu_map_size = ((mmu_fb_4k_number * 4) >> 6) << 6;
+ int tvp_flag = vdec_secure(hw_to_vdec(dec)) ? CODEC_MM_FLAGS_TVP : 0;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s mmu_fb_4k_number = %d\n", __func__, mmu_fb_4k_number);
+
+ if (mmu_fb_4k_number < 0)
+ return -1;
+
+ dec->mmu_box_fb = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, 2,
+ (mmu_fb_4k_number << 12) * 2,
+ tvp_flag
+ );
+
+ dec->fb_buf_mmu0_addr =
+ dma_alloc_coherent(amports_get_dma_device(),
+ mmu_map_size,
+ &tmp_phy_adr, GFP_KERNEL);
+ avs3_dec->fb_buf_mmu0.buf_start = tmp_phy_adr;
+ if (dec->fb_buf_mmu0_addr == NULL) {
+ pr_err("%s: failed to alloc fb_mmu0_map\n", __func__);
+ return -1;
+ }
+ memset(dec->fb_buf_mmu0_addr, 0, mmu_map_size);
+ avs3_dec->fb_buf_mmu0.buf_size = mmu_map_size;
+ avs3_dec->fb_buf_mmu0.buf_end = avs3_dec->fb_buf_mmu0.buf_start + mmu_map_size;
+
+ dec->fb_buf_mmu1_addr =
+ dma_alloc_coherent(amports_get_dma_device(),
+ mmu_map_size,
+ &tmp_phy_adr, GFP_KERNEL);
+ avs3_dec->fb_buf_mmu1.buf_start = tmp_phy_adr;
+ if (dec->fb_buf_mmu1_addr == NULL) {
+ pr_err("%s: failed to alloc fb_mmu1_map\n", __func__);
+ return -1;
+ }
+ memset(dec->fb_buf_mmu1_addr, 0, mmu_map_size);
+ avs3_dec->fb_buf_mmu1.buf_size = mmu_map_size;
+ avs3_dec->fb_buf_mmu1.buf_end = avs3_dec->fb_buf_mmu1.buf_start + mmu_map_size;
+
+ ret = decoder_mmu_box_alloc_idx(
+ dec->mmu_box_fb,
+ 0,
+ mmu_fb_4k_number,
+ dec->fb_buf_mmu0_addr);
+ if (ret != 0) {
+ pr_err("%s: failed to alloc fb_mmu0 pages\n", __func__);
+ return -1;
+ }
+
+ ret = decoder_mmu_box_alloc_idx(
+ dec->mmu_box_fb,
+ 1,
+ mmu_fb_4k_number,
+ dec->fb_buf_mmu1_addr);
+ if (ret != 0) {
+ pr_err("%s: failed to alloc fb_mmu1 pages\n", __func__);
+ return -1;
+ }
+
+ dec->mmu_fb_4k_number = mmu_fb_4k_number;
+ avs3_dec->fr.mmu0_ptr = avs3_dec->fb_buf_mmu0.buf_start;
+ avs3_dec->bk.mmu0_ptr = avs3_dec->fb_buf_mmu0.buf_start;
+ avs3_dec->fr.mmu1_ptr = avs3_dec->fb_buf_mmu1.buf_start;
+ avs3_dec->bk.mmu1_ptr = avs3_dec->fb_buf_mmu1.buf_start;
+
+ return 0;
+}
+
+static void init_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+/*simulation code: change to use linux APIs; also need write uninit_fb_bufstate()*/
+ int ret;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ dma_addr_t tmp_phy_adr;
+ unsigned long tmp_adr;
+ int mmu_4k_number = dec->fb_ifbuf_num * avs3_mmu_page_num(dec, dec->init_pic_w, dec->init_pic_h, 1);
+
+ ret = init_mmu_fb_bufstate(dec, mmu_4k_number);
+ if (ret < 0) {
+ avs3_print(dec, 0, "%s: failed to alloc mmu fb buffer\n", __func__);
+ return ;
+ }
+
+ avs3_dec->fb_buf_scalelut.buf_size = IFBUF_SCALELUT_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_SCALELUT_ID, avs3_dec->fb_buf_scalelut.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_scalelut.buf_start = tmp_adr;
+ avs3_dec->fb_buf_scalelut.buf_end = avs3_dec->fb_buf_scalelut.buf_start + avs3_dec->fb_buf_scalelut.buf_size;
+
+ avs3_dec->fb_buf_vcpu_imem.buf_size = IFBUF_VCPU_IMEM_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_VCPU_IMEM_ID, avs3_dec->fb_buf_vcpu_imem.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_vcpu_imem.buf_start = tmp_adr;
+ avs3_dec->fb_buf_vcpu_imem.buf_end = avs3_dec->fb_buf_vcpu_imem.buf_start + avs3_dec->fb_buf_vcpu_imem.buf_size;
+
+ avs3_dec->fb_buf_sys_imem.buf_size = IFBUF_SYS_IMEM_SIZE * dec->fb_ifbuf_num;
+ avs3_dec->fb_buf_sys_imem_addr = dma_alloc_coherent(amports_get_dma_device(),
+ avs3_dec->fb_buf_sys_imem.buf_size, &tmp_phy_adr, GFP_KERNEL);
+ avs3_dec->fb_buf_sys_imem.buf_start = tmp_phy_adr;
+ if (avs3_dec->fb_buf_sys_imem_addr == NULL) {
+ pr_err("%s: failed to alloc fb_buf_sys_imem\n", __func__);
+ return;
+ }
+ avs3_dec->fb_buf_sys_imem.buf_end = avs3_dec->fb_buf_sys_imem.buf_start + avs3_dec->fb_buf_sys_imem.buf_size;
+
+ avs3_dec->fb_buf_lmem0.buf_size = IFBUF_LMEM0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_LMEM0_ID, avs3_dec->fb_buf_lmem0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_lmem0.buf_start = tmp_adr;
+ avs3_dec->fb_buf_lmem0.buf_end = avs3_dec->fb_buf_lmem0.buf_start + avs3_dec->fb_buf_lmem0.buf_size;
+
+ avs3_dec->fb_buf_lmem1.buf_size = IFBUF_LMEM1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_LMEM1_ID, avs3_dec->fb_buf_lmem1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_lmem1.buf_start = tmp_adr;
+ avs3_dec->fb_buf_lmem1.buf_end = avs3_dec->fb_buf_lmem1.buf_start + avs3_dec->fb_buf_lmem1.buf_size;
+
+ avs3_dec->fb_buf_parser_sao0.buf_size = IFBUF_PARSER_SAO0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_PARSER_SAO0_ID, avs3_dec->fb_buf_parser_sao0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_parser_sao0.buf_start = tmp_adr;
+ avs3_dec->fb_buf_parser_sao0.buf_end = avs3_dec->fb_buf_parser_sao0.buf_start + avs3_dec->fb_buf_parser_sao0.buf_size;
+
+ avs3_dec->fb_buf_parser_sao1.buf_size = IFBUF_PARSER_SAO1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUF_PARSER_SAO1_ID, avs3_dec->fb_buf_parser_sao1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_parser_sao1.buf_start = tmp_adr;
+ avs3_dec->fb_buf_parser_sao1.buf_end = avs3_dec->fb_buf_parser_sao1.buf_start + avs3_dec->fb_buf_parser_sao1.buf_size;
+
+ avs3_dec->fb_buf_mpred_imp0.buf_size = IFBUF_MPRED_IMP0_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUFF_MPRED_IMP0_ID, avs3_dec->fb_buf_mpred_imp0.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_mpred_imp0.buf_start = tmp_adr;
+ avs3_dec->fb_buf_mpred_imp0.buf_end = avs3_dec->fb_buf_mpred_imp0.buf_start + avs3_dec->fb_buf_mpred_imp0.buf_size;
+
+ avs3_dec->fb_buf_mpred_imp1.buf_size = IFBUF_MPRED_IMP1_SIZE * dec->fb_ifbuf_num;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ BMMU_IFBUFF_MPRED_IMP1_ID, avs3_dec->fb_buf_mpred_imp1.buf_size,
+ DRIVER_NAME, &tmp_adr);
+ avs3_dec->fb_buf_mpred_imp1.buf_start = tmp_adr;
+ avs3_dec->fb_buf_mpred_imp1.buf_end = avs3_dec->fb_buf_mpred_imp1.buf_start + avs3_dec->fb_buf_mpred_imp1.buf_size;
+
+ avs3_dec->fr.scalelut_ptr = avs3_dec->fb_buf_scalelut.buf_start;
+ avs3_dec->bk.scalelut_ptr = avs3_dec->fb_buf_scalelut.buf_start;
+ avs3_dec->fr.vcpu_imem_ptr = avs3_dec->fb_buf_vcpu_imem.buf_start;
+ avs3_dec->bk.vcpu_imem_ptr = avs3_dec->fb_buf_vcpu_imem.buf_start;
+ avs3_dec->fr.sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+ avs3_dec->bk.sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+ avs3_dec->fr.lmem0_ptr = avs3_dec->fb_buf_lmem0.buf_start;
+ avs3_dec->bk.lmem0_ptr = avs3_dec->fb_buf_lmem0.buf_start;
+ avs3_dec->fr.lmem1_ptr = avs3_dec->fb_buf_lmem1.buf_start;
+ avs3_dec->bk.lmem1_ptr = avs3_dec->fb_buf_lmem1.buf_start;
+ avs3_dec->fr.parser_sao0_ptr = avs3_dec->fb_buf_parser_sao0.buf_start;
+ avs3_dec->bk.parser_sao0_ptr = avs3_dec->fb_buf_parser_sao0.buf_start;
+ avs3_dec->fr.parser_sao1_ptr = avs3_dec->fb_buf_parser_sao1.buf_start;
+ avs3_dec->bk.parser_sao1_ptr = avs3_dec->fb_buf_parser_sao1.buf_start;
+ avs3_dec->fr.mpred_imp0_ptr = avs3_dec->fb_buf_mpred_imp0.buf_start;
+ avs3_dec->bk.mpred_imp0_ptr = avs3_dec->fb_buf_mpred_imp0.buf_start;
+ avs3_dec->fr.mpred_imp1_ptr = avs3_dec->fb_buf_mpred_imp1.buf_start;
+ avs3_dec->bk.mpred_imp1_ptr = avs3_dec->fb_buf_mpred_imp1.buf_start;
+ if (fbdebug_flag & 0x4) {
+ avs3_dec->fr.scalelut_ptr_pre = avs3_dec->fr.scalelut_ptr;
+ avs3_dec->bk.scalelut_ptr_pre = avs3_dec->bk.scalelut_ptr;
+ } else {
+ avs3_dec->fr.scalelut_ptr_pre = 0;
+ avs3_dec->bk.scalelut_ptr_pre = 0;
+ }
+
+ avs3_dec->fr.sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr; //for linux
+
+ print_loopbufs_ptr(dec, "init", &avs3_dec->fr);
+}
+
+static void uninit_mmu_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+ if (dec->fb_buf_mmu0_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs3_dec->fb_buf_mmu0.buf_size, dec->fb_buf_mmu0_addr,
+ avs3_dec->fb_buf_mmu0.buf_start);
+ dec->fb_buf_mmu0_addr = NULL;
+ }
+ if (dec->fb_buf_mmu1_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs3_dec->fb_buf_mmu1.buf_size, dec->fb_buf_mmu1_addr,
+ avs3_dec->fb_buf_mmu1.buf_start);
+ dec->fb_buf_mmu1_addr = NULL;
+ }
+
+ if (dec->mmu_box_fb) {
+ decoder_mmu_box_free(dec->mmu_box_fb);
+ dec->mmu_box_fb = NULL;
+ }
+}
+
+static void uninit_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+ int i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ for (i = 0; i < FB_LOOP_BUF_COUNT; i++) {
+ if (i != BMMU_IFBUF_SYS_IMEM_ID)
+ decoder_bmmu_box_free_idx(dec->bmmu_box, i);
+ }
+
+ if (avs3_dec->fb_buf_sys_imem_addr) {
+ dma_free_coherent(amports_get_dma_device(),
+ avs3_dec->fb_buf_sys_imem.buf_size, avs3_dec->fb_buf_sys_imem_addr,
+ avs3_dec->fb_buf_sys_imem.buf_start);
+ avs3_dec->fb_buf_sys_imem_addr = NULL;
+ }
+ uninit_mmu_fb_bufstate(dec);
+}
+
+static void config_bufstate_front_hw(struct avs3_decoder *avs3_dec)
+{
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_START, avs3_dec->fb_buf_mmu0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_END, avs3_dec->fb_buf_mmu0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0, avs3_dec->fr.mmu0_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_START, avs3_dec->fb_buf_mmu1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_END, avs3_dec->fb_buf_mmu1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1, avs3_dec->fr.mmu1_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_parser_sao0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_parser_sao0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_parser_sao1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_parser_sao1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config mpred_imp_if data write buffer start address
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_mpred_imp0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_mpred_imp0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_mpred_imp1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_mpred_imp1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config other buffers
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_scalelut.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_scalelut.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.scalelut_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.scalelut_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, avs3_dec->fr.scalelut_ptr_pre);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_vcpu_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_vcpu_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_sys_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_sys_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//config lmem buffers
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_lmem0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_lmem0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM0_BLOCK_SIZE);
+
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+ WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_lmem1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_lmem1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM1_BLOCK_SIZE);
+}
+
+static void config_bufstate_back_hw(struct avs3_decoder *avs3_dec)
+{
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_START, avs3_dec->fb_buf_mmu0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_END, avs3_dec->fb_buf_mmu0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0, avs3_dec->bk.mmu0_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_START, avs3_dec->fb_buf_mmu1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_END, avs3_dec->fb_buf_mmu1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1, avs3_dec->bk.mmu1_ptr);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_parser_sao0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_parser_sao0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.parser_sao0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 1);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_parser_sao1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_parser_sao1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.parser_sao1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config mpred_imp_if data write buffer start address
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 2);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_mpred_imp0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_mpred_imp0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.mpred_imp0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 3);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_mpred_imp1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_mpred_imp1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.mpred_imp1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config other buffers
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 4);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_scalelut.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_scalelut.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.scalelut_ptr);
+ WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, avs3_dec->bk.scalelut_ptr_pre);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 7);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_vcpu_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_vcpu_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.vcpu_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 8);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_sys_imem.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_sys_imem.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.sys_imem_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config lmem buffers
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 5);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_lmem0.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_lmem0.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.lmem0_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+ WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 6);
+ WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_lmem1.buf_start);
+ WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_lmem1.buf_end);
+ WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.lmem1_ptr);
+ //WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+}
+
+static void read_bufstate_front(struct avs3_decoder *avs3_dec)
+{
+ //uint32_t tmp;
+ avs3_dec->fr.mmu0_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0);
+ avs3_dec->fr.mmu1_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+ avs3_dec->fr.scalelut_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ //avs3_dec->fr.scalelut_ptr_pre = READ_VREG(HEVC_ASSIST_RING_F_THRESHOLD);
+ //printk("pic_end_ptr = %x; pic_start_ptr = %x\n", avs3_dec->fr.scalelut_ptr, avs3_dec->fr.scalelut_ptr_pre);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+ avs3_dec->fr.vcpu_imem_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+ avs3_dec->fr.lmem0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+ avs3_dec->fr.lmem1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+ avs3_dec->fr.parser_sao0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+ avs3_dec->fr.parser_sao1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+ avs3_dec->fr.mpred_imp0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+ WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+ avs3_dec->fr.mpred_imp1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+
+ avs3_dec->fr.sys_imem_ptr = avs3_dec->sys_imem_ptr;
+ avs3_dec->fr.sys_imem_ptr_v = avs3_dec->sys_imem_ptr_v;
+}
+
+/*hw config*/
+
+/**/
+static int compute_losless_comp_body_size(struct AVS3Decoder_s *dec,
+ int width, int height,
+ uint8_t is_bit_depth_10);
+static int compute_losless_comp_header_size(struct AVS3Decoder_s *dec,
+ int width, int height);
+
+static void config_work_space_hw(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ DEC_CTX * ctx = &dec->avs3_dec.ctx;
+ struct BuffInfo_s *buf_spec = dec->work_space_buf;
+ u32 width = dec->avs3_dec.img.width ? dec->avs3_dec.img.width : dec->init_pic_w;
+ u32 height = dec->avs3_dec.img.height ? dec->avs3_dec.img.height : dec->init_pic_h;
+ u8 is_bit_depth_10 = (ctx->info.bit_depth_internal == 8) ? 0 : 1;
+ int losless_comp_header_size =
+ compute_losless_comp_header_size(
+ dec, width,
+ height);
+ int losless_comp_body_size =
+ compute_losless_comp_body_size(dec,
+ width,
+ height, is_bit_depth_10);
+ int losless_comp_body_size_dw = losless_comp_body_size;
+ int losless_comp_header_size_dw = losless_comp_header_size;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", __func__,
+ buf_spec->ipp.buf_start,
+ buf_spec->ipp1.buf_start,
+ buf_spec->start_adr,
+ buf_spec->short_term_rps.buf_start,
+ buf_spec->rcs.buf_start,
+ buf_spec->sps.buf_start,
+ buf_spec->pps.buf_start,
+ buf_spec->sbac_top.buf_start,
+ buf_spec->sao_up.buf_start,
+ buf_spec->swap_buf.buf_start,
+ buf_spec->swap_buf2.buf_start,
+ buf_spec->scalelut.buf_start,
+ buf_spec->dblk_para.buf_start,
+ buf_spec->dblk_data.buf_start,
+ buf_spec->dblk_data2.buf_start);
+ if (back_flag) {
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,buf_spec->ipp.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2,buf_spec->ipp1.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE_DBE1,buf_spec->ipp1.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2_DBE1,buf_spec->ipp.buf_start);
+ }
+ if (front_flag) {
+ //WRITE_VREG(HEVC_RPM_BUFFER, buf_spec->rpm.buf_start);
+ if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+ WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+ }
+
+ WRITE_VREG(AVS3_ALF_SWAP_BUFFER, buf_spec->short_term_rps.buf_start);
+ WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
+ //WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
+ //WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
+ WRITE_VREG(AVS3_SBAC_TOP_BUFFER, buf_spec->sbac_top.buf_start);
+ }
+ if (back_flag) {
+ WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+ WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, dec->frame_mmu_map_phy_addr);
+ WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR_DBE1, dec->frame_mmu_map_phy_addr_1); //new dual
+ }
+
+ if (back_flag) {
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, dec->dw_frame_mmu_map_phy_addr_1); //new dual
+ }
+#endif
+ WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
+
+ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start); // cfg_cpi_addr
+ WRITE_VREG(HEVC_DBLK_CFG4_DBE1, buf_spec->dblk_para.buf_start);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFG4: 0x%x\n", buf_spec->dblk_para.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start); // cfg_xio_addr
+ WRITE_VREG(HEVC_DBLK_CFG5_DBE1, buf_spec->dblk_data.buf_start);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFG5: 0x%x\n", buf_spec->dblk_data.buf_start);
+ WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start); // cfg_adp_addr
+ WRITE_VREG(HEVC_DBLK_CFGE_DBE1, buf_spec->dblk_data2.buf_start);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ " [DBLK DBG] CFGE: 0x%x\n", buf_spec->dblk_data2.buf_start);
+
+#ifdef LOSLESS_COMPRESS_MODE
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+#if 1
+ data32 &= ~(1<<9);
+#else
+ if (params->p.bit_depth != 0x00)
+ data32 &= ~(1<<9);
+ else
+ data32 |= (1<<9);
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+#if 1
+ data32 &= ~(1<<9);
+#else
+ if (params->p.bit_depth != 0x00)
+ data32 &= ~(1<<9);
+ else
+ data32 |= (1<<9);
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#ifdef AVS3_10B_MMU
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,0x0);
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,(0x1<< 4)); // bit[4] : paged_mem_mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,0x0);
+#else
+ // WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe
+#if 1
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1, (0<<3)); // bit[3] smem mode
+#else
+ if (params->p.bit_depth != 0x00) WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+ else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe
+#endif
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,(losless_comp_body_size >> 5));
+#endif
+ //WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+ //WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff); //8-bit mode
+ WRITE_VREG(HEVC_CM_BODY_LENGTH,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH,losless_comp_header_size);
+ WRITE_VREG(HEVC_CM_BODY_LENGTH_DBE1,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET_DBE1,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH_DBE1,losless_comp_header_size);
+#else
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31);
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,0x1 << 31);
+#endif
+#ifdef AVS3_10B_MMU
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/4);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2 + buf_spec->mmu_vbh.buf_size/4);
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+ data32 |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#endif
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size_dw);
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2_DBE1,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2_DBE1,losless_comp_body_size_dw);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2_DBE1,losless_comp_header_size_dw);
+
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/4);
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2 + buf_spec->mmu_vbh_dw.buf_size/4);
+
+ #ifndef AVS3_10B_NV21
+ #ifdef AVS3_10B_MMU_DW
+ WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+ WRITE_VREG(HEVC_DW_VH0_ADDDR_DBE1, DOUBLE_WRITE_VH0_HALF);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR_DBE1, DOUBLE_WRITE_VH1_HALF);
+ #endif
+ #endif
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+ }
+#endif
+ } //back_flag end
+ if (front_flag) {
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+ #ifdef CO_MV_COMPRESS
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1<<1 | 1<<26);
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+ #else
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1<<26); //enable AVS3 mode
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+ #endif
+ }
+}
+
+static void hevc_init_decoder_hw(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ int32_t i;
+
+int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+};
+
+int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+};
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Entering hevc_init_decoder_hw\n");
+#if 0
+ printk("[test.c] Test Parser Register Read/Write\n");
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x00010001) { print_scratch_error(25); return; }
+ WRITE_VREG(HEVC_PARSER_VERSION, 0x5a5a55aa);
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x5a5a55aa) { print_scratch_error(26); return; }
+
+ // test Parser Reset
+ WRITE_VREG(DOS_SW_RESET1, (1<<3)); // reset_whole parser
+ WRITE_VREG(DOS_SW_RESET1, 0); // reset_whole parser
+ data32 = READ_VREG(HEVC_PARSER_VERSION);
+ if (data32 != 0x00010001) { print_scratch_error(27); return; }
+#endif
+
+#if 0 // JT
+ printk("[test.c] Enable BitStream Fetch\n");
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 |
+ (1 << 0) // stream_fetch_enable
+ ;
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x00000100) { print_scratch_error(29); return; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x00000300) { print_scratch_error(30); return; }
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x12345678) { print_scratch_error(31); return; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x9abcdef0) { print_scratch_error(32); return; }
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
+#endif // JT
+
+#if 0 //def AVS3_10B_HED_FB
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Init AVS3_10B_HED_FB\n");
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 |
+ (1 << 3) | // fb_read_avs2_enable0
+ (1 << 6) | // fb_read_avs2_enable1
+ (1 << 1) | // fb_avs2_enable
+ (1 << 13) | // fb_read_avs3_enable0
+ (1 << 14) | // fb_read_avs3_enable1
+ (1 << 9) | // fb_avs3_enable
+ (3 << 7) //core0_en, core1_en,hed_fb_en
+ ;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+// data32 = READ_VREG(HEVC_ASSIST_FB_W_CTL);
+// data32 = data32 |
+// (1 << 0) // hed_fb_wr_en
+ ;
+// WRITE_VREG(HEVC_ASSIST_FB_W_CTL, data32);
+
+//#ifdef H265_10B_HED_SAME_FB
+// printk("[test.c] Init H265_10B_HED_SAME_FB\n");
+// data32 = READ_VREG(HEVC_ASSIST_FB_R_CTL);
+// data32 = data32 |
+// (1 << 0) // hed_fb_rd_en
+// ;
+// WRITE_VREG(HEVC_ASSIST_FB_R_CTL, data32);
+//#endif
+
+#endif
+ if (!efficiency_mode && front_flag) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable HEVC Parser Interrupt\n");
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+ data32 = data32 |
+ (1 << 24) | // stream_buffer_empty_int_amrisc_enable
+ (1 << 22) | // stream_fifo_empty_int_amrisc_enable
+ (1 << 7) | // dec_done_int_cpu_enable
+ (1 << 4) | // startcode_found_int_cpu_enable
+ (0 << 3) | // startcode_found_int_amrisc_enable
+ (1 << 0) // parser_int_enable
+ ;
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable HEVC Parser Shift\n");
+
+ data32 = READ_VREG(HEVC_SHIFT_STATUS);
+ #ifdef AVS3
+ data32 = data32 |
+ (0 << 1) | // emulation_check_on // AVS3 emulation on/off will be controlled in microcode according to startcode type
+ (1 << 0) // startcode_check_on
+ ;
+ #else
+ data32 = data32 |
+ (1 << 1) | // emulation_check_on
+ (1 << 0) // startcode_check_on
+ ;
+ #endif
+ WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+
+ WRITE_VREG(HEVC_SHIFT_CONTROL,
+ (6 << 20) | // emu_push_bits (6-bits for AVS3)
+ (0 << 19) | // emu_3_enable // maybe turned on in microcode
+ (0 << 18) | // emu_2_enable // maybe turned on in microcode
+ (0 << 17) | // emu_1_enable // maybe turned on in microcode
+ (0 << 16) | // emu_0_enable // maybe turned on in microcode
+ (0 << 14) | // disable_start_code_protect
+ (3 << 6) | // sft_valid_wr_position
+ (2 << 4) | // emulate_code_length_sub_1
+ (2 << 1) | // start_code_length_sub_1
+ (1 << 0) // stream_shift_enable
+ );
+
+ WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
+ (0 << 30) | // data_protect_fill_00_enable
+ (1 << 29) // data_protect_fill_ff_enable
+ );
+
+ WRITE_VREG(HEVC_CABAC_CONTROL,
+ (1 << 0) // cabac_enable
+ );
+
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
+ (1 << 0) // hevc_parser_core_clk_en
+ );
+ WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
+ }
+
+ if (!efficiency_mode && back_flag) {
+#if 0 // Dual Core : back Microcode will always initial SCALELUT
+ // Initial IQIT_SCALELUT memory -- just to avoid X in simulation
+ printk("[test.c] Initial IQIT_SCALELUT memory -- just to avoid X in simulation...\n");
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // cfg_p_addr
+ for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // cfg_p_addr
+ for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, 0);
+#endif
+
+ // Zero out canvas registers in IPP -- avoid simulation X
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i=0; i<32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+ }
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR_DBE1, (0 << 8) | (0<<1) | 1);
+ for (i=0; i<32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#endif
+ }
+ }
+
+ if (front_flag) {
+#if 0
+ #ifdef ENABLE_SWAP_TEST
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+ #else
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+ #endif
+#endif
+ //WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
+ //WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, decode_pic_num);
+#if 0
+ // Send parser_cmd
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] SEND Parser Command ...\n");
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1<<16) | (0<<0));
+ for (i=0; i<PARSER_CMD_NUMBER; i++) {
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
+ }
+
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
+#endif
+
+ if (!efficiency_mode) {
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ (1 << 12) | // alf_on_sao
+ // (1 << 9) | // parser_alf_if_en
+ // (1 << 8) | // sao_sw_pred_enable
+ (1 << 5) | // parser_sao_if_en
+ (1 << 2) | // parser_mpred_if_en
+ (1 << 0) // parser_scaler_if_en
+ );
+ }
+ }
+#if 0
+//def MULTI_INSTANCE_SUPPORT
+ // Begin of Multi-instance
+ WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+ WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+ data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
+ WRITE_VREG(DOS_SW_RESET3, (1<<18)); // reset mpred
+ WRITE_VREG(DOS_SW_RESET3, 0);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+
+ // End of Multi-instance
+#endif
+ // Changed to Start MPRED in microcode
+ /*
+ printk("[test.c] Start MPRED\n");
+ WRITE_VREG(HEVC_MPRED_INT_STATUS,
+ (1<<31)
+ );
+ */
+
+ // AVS3 default seq_wq_matrix config
+ if (!efficiency_mode && back_flag) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "[test.c] Config AVS3 default seq_wq_matrix ...\n");
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+ for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+ for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+ for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+ for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Reset IPP\n");
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (0 << 1) | // enable ipp
+ (1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (1 << 0) // software reset ipp and mpp
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (1 << 1) | // enable ipp
+ (1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (0 << 0) // software reset ipp and mpp
+ );
+
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+ (0 << 1) | // enable ipp
+ (1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (1 << 0) // software reset ipp and mpp
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+ (1 << 1) | // enable ipp
+ (1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+ (0 << 0) // software reset ipp and mpp
+ );
+
+ // Init dblk
+ data32 = READ_VREG(HEVC_DBLK_CFGB);
+ data32 |= (5 << 0);
+ WRITE_VREG(HEVC_DBLK_CFGB, data32); // [3:0] cfg_video_type -> AVS3
+#define LPF_LINEBUF_MODE_CTU_BASED
+ //must be defined for DUAL_CORE
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+ WRITE_VREG(HEVC_DBLK_CFG0, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+ WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Bitstream level Init for DBLK .Done.\n");
+
+ data32 = READ_VREG(HEVC_DBLK_CFGB_DBE1);
+ data32 |= (5 << 0);
+ WRITE_VREG(HEVC_DBLK_CFGB_DBE1, data32); // [3:0] cfg_video_type -> AVS3
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+ WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+ WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Bitstream level Init for DBLK_DBE1 .Done.\n");
+
+ // Initialize mcrcc and decomp perf counters
+#if 1
+ if (dec->front_back_mode == 1) {
+ mcrcc_perfcount_reset_dual(dec);
+ decomp_perfcount_reset_dual(dec);
+ }
+#endif
+ }//back_flag end
+ //printk("[test.c] Leaving hevc_init_decoder_hw\n");
+ return;
+}
+
+extern void config_cuva_buf(struct AVS3Decoder_s *dec);
+static int32_t avs3_hw_init(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+ uint32_t data32;
+ unsigned int decode_mode;
+ uint32_t tmp = 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s front_flag %d back_flag %d\n", __func__, front_flag, back_flag);
+ if (dec->front_back_mode != 1) {
+ if (front_flag)
+ avs3_hw_ctx_restore(dec);
+ if (back_flag) {
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+
+ }
+ return 0;
+ }
+
+ if (front_flag) {
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 | (3 << 7) | (1 << 9) | (1 << 1);
+ tmp = (1 << 0) | (1 << 10);
+ data32 &= ~tmp;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32);
+ }
+
+ if (back_flag) {
+ data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+ data32 = data32 | (3 << 7) | (1 << 3) | (1 << 13) | (1 << 6) | (1 << 14);
+ tmp = (1 << 2) | (1 << 11) | (1 << 5) | (1 << 12);
+ data32 &= ~tmp;
+ WRITE_VREG(HEVC_ASSIST_FB_CTL, data32);
+ }
+
+ config_work_space_hw(dec, front_flag, back_flag);
+
+ if (!efficiency_mode && dec->pic_list_init_flag && front_flag)
+ init_pic_list_hw_fb(dec);
+
+ hevc_init_decoder_hw(dec, front_flag, back_flag);
+//Start JT
+ if (!efficiency_mode) {
+ if (front_flag) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[test.c] Enable BitStream Fetch\n");
+#if 0
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 |
+ (1 << 0) // stream_fetch_enable
+ ;
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+#if 0
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x00000100) { print_scratch_error(29); return -1; }
+ /*data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x00000300) { print_scratch_error(30); return; }*/
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x12345678) { print_scratch_error(31); return -1; }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x9abcdef0) { print_scratch_error(32); return -1; }
+#endif
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000); // 0x000000 - 0x000003 emulate code for AVS3
+ }
+ }
+// End JT
+
+ if (!efficiency_mode && back_flag) {
+ // Set MCR fetch priorities
+ data32 = 0x1 | (0x1 << 2) | (0x1 <<3) | (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
+ WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
+ WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL_DBE1, data32);
+
+ // Set IPP MULTICORE CFG
+ WRITE_VREG(HEVCD_IPP_MULTICORE_CFG, 1);
+ WRITE_VREG(HEVCD_IPP_MULTICORE_CFG_DBE1, 1);
+
+#ifdef DYN_CACHE
+ if (dec->front_back_mode == 1) {
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE_DBE1,0x2b);//enable new mcrcc
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC DYN MCRCC\n");
+ }
+#endif
+ }
+ if (front_flag) {
+ WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+ #if 1 // JT
+
+ #if 0 //def SIMULATION
+ if (decode_pic_begin == 0)
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+ else
+ WRITE_VREG(HEVC_WAIT_FLAG, 0);
+ #else
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+ #endif
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+ /* disable PSCALE for hardware sharing */
+ #ifdef DOS_PROJECT
+ #else
+ WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+ #endif
+
+ //WRITE_VREG(DEBUG_REG1, 0x0); //no debug
+ WRITE_VREG(NAL_SEARCH_CTL, 0x8); //check SEQUENCE/I_PICTURE_START in ucode
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+ WRITE_VREG(HEVC_DBG_LOG_ADR, dec->ucode_log_phy_addr);
+#endif
+ #ifdef MULTI_INSTANCE_SUPPORT
+ if (!dec->m_ins_flag)
+ decode_mode = DECODE_MODE_SINGLE;
+ else if (vdec_frame_based(hw_to_vdec(dec)))
+ decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
+ else
+ decode_mode = DECODE_MODE_MULTI_STREAMBASE;
+#ifdef FOR_S5
+ /*to do..*/
+ dec->start_decoding_flag = 3;
+ decode_mode |= (dec->start_decoding_flag << 16);
+#endif
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s set decode_mode 0x%x\n", __func__, decode_mode);
+ WRITE_VREG(DECODE_MODE, decode_mode); //DECODE_MODE_MULTI_STREAMBASE
+ config_cuva_buf(dec);
+
+ #endif
+
+ //WRITE_VREG(XIF_DOS_SCRATCH31, 0x0);
+ //WRITE_VREG(HEVC_MPSR, 1);
+ //printk("[test.c] HEVC_MPSR!\n");
+ #endif
+ }
+ if (back_flag) {
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+ }
+
+ return 0;
+}
+
+static void release_free_mmu_buffers(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int ii;
+ for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+ struct avs3_frame_s *pic =
+ &avs3_dec->pic_pool[ii].buf_cfg;
+ if (pic->used == 0 &&
+ pic->vf_ref == 0 &&
+#ifdef NEW_FRONT_BACK_CODE
+ pic->backend_ref == 0 && /*?? why need it in case0763,
+ used is supposed to be 1 if backend_ref is not 0*/
+#endif
+ pic->mmu_alloc_flag) {
+ pic->mmu_alloc_flag = 0;
+ decoder_mmu_box_free_idx(dec->mmu_box,
+ pic->index);
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_free_idx index=%d\n",
+ __func__, pic->index);
+ if (dec->front_back_mode)
+ decoder_mmu_box_free_idx(dec->mmu_box_1,
+ pic->index);
+
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+ decoder_mmu_box_free_idx(dec->dw_mmu_box,
+ pic->index);
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s DW decoder_mmu_box_free_idx index=%d\n",
+ __func__, pic->index);
+ if (dec->front_back_mode && dec->dw_mmu_box_1)
+ decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+ pic->index);
+ }
+#endif
+#ifndef MV_USE_FIXED_BUF
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ MV_BUFFER_IDX(pic->index));
+ pic->mpred_mv_wr_start_addr = 0;
+#endif
+ }
+ }
+}
+
+static void print_hevc_b_data_path_monitor(int frame_count)
+{
+ uint32_t total_clk_count;
+ uint32_t path_transfer_count;
+ uint32_t path_wait_count;
+ uint32_t path_status;
+ unsigned path_wait_ratio;
+
+ printk("\n[WAITING DATA/CMD] Parser/IQIT/IPP/DBLK/OW/DDR/MPRED_IPP_CMD/IPP_DBLK_CMD\n");
+
+ //---------------------- CORE 0 -------------------------------
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disable monitor and set rd_idx to 0
+ total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disable monitor and set rd_idx to 1
+
+ // parser --> iqit
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk("[P%d HEVC CORE0 PATH] WAITING Ratio : %d",
+ frame_count,
+ path_wait_ratio);
+
+ // iqit --> ipp
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // dblk <-- ipp
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // dblk --> ow
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count *100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // <--> DDR
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // IMP
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // path status
+ path_status = READ_VREG(HEVC_PATH_MONITOR_DATA);
+
+ // CMD
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+#if 0
+ WRITE_VREG(HEVC_PARSER_IF_MONITOR_CTRL, (2<<4)); // Disable monitor and set rd_idx to 2
+
+ // Parser-Mpred CMD
+ path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0.0;
+ else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
+ printk(" %.2f", path_wait_ratio);
+
+ // Parser-SAO CMD
+ path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+ path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+ if (path_transfer_count == 0) path_wait_ratio = 0.0;
+ else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
+ printk(" %.2f\n", path_wait_ratio);
+ }
+#else
+ printk("\n");
+#endif
+ //---------------------- CORE 1 -------------------------------
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL_DBE1, 0); // Disable monitor and set rd_idx to 0
+ total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL_DBE1, (1<<4)); // Disable monitor and set rd_idx to 1
+
+ // parser --> iqit
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+ printk("[P%d HEVC CORE1 PATH] WAITING Ratio : %d",
+ frame_count,
+ path_wait_ratio);
+
+ // iqit --> ipp
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // dblk <-- ipp
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // dblk --> ow
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // <--> DDR
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // IMP
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+ // path status
+ path_status = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+
+ // CMD
+ path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0;
+ else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+ printk(" %d", path_wait_ratio);
+
+# if 0
+ WRITE_VREG(HEVC_PARSER_IF_MONITOR_CTRL, (2<<4)); // Disable monitor and set rd_idx to 2
+
+ // Parser-Mpred CMD
+ path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0.0;
+ else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
+ printk(" %.2f", path_wait_ratio);
+
+ // Parser-SAO CMD
+ path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+ path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+ if (path_transfer_count == 0) path_wait_ratio = 0.0;
+ else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
+ printk(" %.2f\n", path_wait_ratio);
+ }
+#else
+ printk("\n");
+#endif
+}
+
+static int BackEnd_StartDecoding(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+ int picture_size;
+ int cur_mmu_4k_number, max_frame_num;
+ int i = 0;
+ struct avs3_frame_s *ref_pic = NULL;
+
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "Start BackEnd Decoding %d (wr pos %d, rd pos %d) pic index %d\n",
+ avs3_dec->backend_decoded_count, avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, pic->index);
+
+#if 0
+#ifdef AVS3_10B_MMU
+ alloc_mmu(&avs3_mmumgr_0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+ alloc_mmu(&avs3_mmumgr_1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#ifdef AVS3_10B_MMU_DW
+ alloc_mmu(&avs3_mmumgr_dw0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+ alloc_mmu(&avs3_mmumgr_dw1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#endif
+ pic->mmu_alloc_flag = 1;
+#endif
+#else
+
+ mutex_lock(&dec->fb_mutex);
+ for (i = 0; (i < pic->list0_num_refp) && (pic->error_mark == 0); i++) {
+ ref_pic = &avs3_dec->pic_pool[pic->list0_index[i]].buf_cfg;
+ if (ref_pic->error_mark) {
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_concealed_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_concealed_frames++;
+ }
+ pic->error_mark = 1;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 ref_pic %d pic error\n",
+ __func__, pic->list0_index[i]);
+ }
+ }
+
+ for (i = 0; (i < pic->list1_num_refp) && (pic->error_mark == 0); i++) {
+ ref_pic = &avs3_dec->pic_pool[pic->list1_index[i]].buf_cfg;
+ if (ref_pic->error_mark) {
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_concealed_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_concealed_frames++;
+ }
+ pic->error_mark = 1;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 ref_pic %d pic error\n",
+ __func__, pic->list1_index[i]);
+ }
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ if (pic->error_mark && (error_handle_policy & 0x4)) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s: error pic, skip\n", __func__);
+
+ mutex_lock(&dec->fb_mutex);
+ dec->gvs->drop_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_lost_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_lost_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_lost_frames++;
+ }
+ mutex_unlock(&dec->fb_mutex);
+
+ pic_backend_ref_operation(dec, pic, 0);
+
+ return 1;
+ }
+
+ picture_size = compute_losless_comp_body_size(
+ dec, pic->width, pic->height/2 + 32 + 8,
+ pic->depth == 10);
+ cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ max_frame_num = MAX_FRAME_8K_NUM;
+ else
+ max_frame_num = MAX_FRAME_4K_NUM;
+ if (cur_mmu_4k_number > max_frame_num) {
+ pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
+ cur_mmu_4k_number, pic->width, pic->height);
+ return 2;
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+ __func__, pic->index, cur_mmu_4k_number);
+
+ decoder_mmu_box_alloc_idx(
+ dec->mmu_box,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->frame_mmu_map_addr);
+
+ decoder_mmu_box_alloc_idx(
+ dec->mmu_box_1,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->frame_mmu_map_addr_1);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+ __func__, pic->index, cur_mmu_4k_number);
+
+ if (dec->dw_mmu_enable) {
+ decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->dw_frame_mmu_map_addr);
+
+ decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box_1,
+ pic->index,
+ cur_mmu_4k_number,
+ dec->dw_frame_mmu_map_addr_1);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s DW decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+ __func__, pic->index, cur_mmu_4k_number);
+ }
+ pic->mmu_alloc_flag = 1;
+#endif
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_ALLOC_MMU_END);
+
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_START);
+
+ copy_loopbufs_ptr(&avs3_dec->bk, &avs3_dec->next_bk[avs3_dec->fb_rd_pos]);
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "update loopbuf bk from next_bk[fb_rd_pos=%d]\n", avs3_dec->fb_rd_pos);
+ print_loopbufs_ptr(dec, "bk", &avs3_dec->bk);
+#ifdef NEW_FRONT_BACK_CODE
+#ifdef PRINT_HEVC_DATA_PATH_MONITOR
+ if (dec->front_back_mode == 1) {
+ if (avs3_dec->backend_decoded_count > 0 &&
+ (debug & AVS3_DBG_CACHE)) {
+ print_hevc_b_data_path_monitor(avs3_dec->backend_decoded_count-1);
+ print_mcrcc_hit_info(avs3_dec->backend_decoded_count-1);
+ }
+ }
+#endif
+#endif
+ if (dec->front_back_mode == 1)
+ amhevc_reset_b();
+ if (efficiency_mode)
+ WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 1 << 1);
+ else
+ WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 0 << 1);
+ avs3_hw_init(dec, 0, 1);
+ if (dec->front_back_mode == 3) {
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_END);
+ } else {
+ config_bufstate_back_hw(avs3_dec);
+ WRITE_VREG(PIC_DECODE_COUNT_DBE, avs3_dec->backend_decoded_count);
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, HEVC_BE_DECODE_DATA);
+ WRITE_VREG(HEVC_SAO_CRC, 0);
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_END);
+
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_FW_START);
+ amhevc_start_b();
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_FW_END);
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC_BACK);
+ }
+
+ return 0;
+}
+
+static unsigned HEVC_MPRED_L0_REF_POC_ADR[] = {
+ HEVC_MPRED_L0_REF00_POC,
+ HEVC_MPRED_L0_REF01_POC,
+ HEVC_MPRED_L0_REF02_POC,
+ HEVC_MPRED_L0_REF03_POC,
+ HEVC_MPRED_L0_REF04_POC,
+ HEVC_MPRED_L0_REF05_POC,
+ HEVC_MPRED_L0_REF06_POC,
+ HEVC_MPRED_L0_REF07_POC,
+ HEVC_MPRED_L0_REF08_POC,
+ HEVC_MPRED_L0_REF09_POC,
+ HEVC_MPRED_L0_REF10_POC,
+ HEVC_MPRED_L0_REF11_POC,
+ HEVC_MPRED_L0_REF12_POC,
+ HEVC_MPRED_L0_REF13_POC,
+ HEVC_MPRED_L0_REF14_POC,
+ HEVC_MPRED_L0_REF15_POC,
+ HEVC_MPRED_POC24_CTRL0
+};
+
+static unsigned HEVC_MPRED_L1_REF_POC_ADR[] = {
+ HEVC_MPRED_L1_REF00_POC,
+ HEVC_MPRED_L1_REF01_POC,
+ HEVC_MPRED_L1_REF02_POC,
+ HEVC_MPRED_L1_REF03_POC,
+ HEVC_MPRED_L1_REF04_POC,
+ HEVC_MPRED_L1_REF05_POC,
+ HEVC_MPRED_L1_REF06_POC,
+ HEVC_MPRED_L1_REF07_POC,
+ HEVC_MPRED_L1_REF08_POC,
+ HEVC_MPRED_L1_REF09_POC,
+ HEVC_MPRED_L1_REF10_POC,
+ HEVC_MPRED_L1_REF11_POC,
+ HEVC_MPRED_L1_REF12_POC,
+ HEVC_MPRED_L1_REF13_POC,
+ HEVC_MPRED_L1_REF14_POC,
+ HEVC_MPRED_L1_REF15_POC,
+ HEVC_MPRED_POC24_CTRL1
+};
+
+static void init_pic_list_hw_fb(struct AVS3Decoder_s *dec)
+{
+ int i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic;
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
+ avs3_dec->ins_offset = 0;
+#if 1
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+
+#ifdef DUAL_CORE_64
+ WRITE_BACK_8(avs3_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+#endif
+#endif
+ for (i = 0; i < dec->avs3_dec.max_pb_size; i++) {
+ pic = &avs3_dec->pic_pool[i].buf_cfg;
+ if (pic->index < 0)
+ break;
+#ifdef AVS3_10B_MMU
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->header_adr
+ | (pic->mc_canvas_y << 8)|0x1);*/
+ //WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ // (0x1 << 1) | (pic->index << 8));
+
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_y_adr
+ | (pic->mc_canvas_y << 8) | 0x1);*/
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_u_v_adr
+ | (pic->mc_canvas_u_v << 8)| 0x1);*/
+ WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+ }
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+
+ /*Zero out canvas registers in IPP -- avoid simulation X*/
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 1);
+ for (i = 0; i < 32; i++) {
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+ }
+}
+
+static void config_mpred_hw_fb(struct AVS3Decoder_s *dec)
+{
+ int32_t i;
+ uint32_t data32;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+ avs3_frame_t *col_pic;
+ //COM_PIC *colPic;
+
+ //int32_t AMVP_MAX_NUM_CANDS_MEM=3;
+ //int32_t AMVP_MAX_NUM_CANDS=2;
+ //int32_t NUM_CHROMA_MODE=5;
+ //int32_t DM_CHROMA_IDX=36;
+ int32_t above_ptr_ctrl =0;
+ //int32_t buffer_linear =1;
+ //int32_t cu_size_log2 =3;
+ int32_t mpred_mv_rd_start_addr ;
+ //int32_t mpred_curr_lcu_x;
+ //int32_t mpred_curr_lcu_y;
+ //int32_t mpred_above_buf_start ;
+ //int32_t mpred_mv_rd_ptr ;
+ //int32_t mpred_mv_rd_ptr_p1 ;
+ int32_t mpred_mv_rd_end_addr;
+ int32_t MV_MEM_UNIT_l;
+ //int32_t mpred_mv_wr_ptr ;
+
+ int32_t above_en;
+ int32_t mv_wr_en;
+ int32_t mv_rd_en;
+ int32_t col_isIntra;
+ int32_t col_ptr;
+ //if (hevc->slice_type!=2)
+
+ if (avs3_dec->slice_type == SLICE_P) {
+ if (avs3_dec->ctx.refp[0][REFP_0].pic != NULL)
+ col_pic = &avs3_dec->ctx.refp[0][REFP_0].pic->buf_cfg;
+ else
+ col_pic = cur_pic;
+ } else if (avs3_dec->slice_type == SLICE_B) {
+ if (avs3_dec->ctx.refp[0][REFP_1].pic != NULL)
+ col_pic = &avs3_dec->ctx.refp[0][REFP_1].pic->buf_cfg;
+ else
+ col_pic = cur_pic;
+ } else {
+ col_pic = cur_pic;
+ }
+
+ if (avs3_dec->slice_type != SLICE_I)
+ {
+ above_en=1;
+ mv_wr_en=1;
+ if (col_pic->slice_type != SLICE_I)
+ mv_rd_en=1;
+ else
+ mv_rd_en=0;
+ col_isIntra=0;
+ } else {
+ above_en=1;
+ mv_wr_en=1;
+ mv_rd_en=0;
+ col_isIntra=0;
+ }
+
+ mpred_mv_rd_start_addr=col_pic->mpred_mv_wr_start_addr;
+ /*data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
+ mpred_curr_lcu_x =data32 & 0xffff;
+ mpred_curr_lcu_y =(data32>>16) & 0xffff;*/
+
+ MV_MEM_UNIT_l=get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+ mpred_mv_rd_end_addr=mpred_mv_rd_start_addr + ((avs3_dec->lcu_x_num*avs3_dec->lcu_y_num)*MV_MEM_UNIT_l);
+
+ //mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "cur pic index %d slicetype %d col pic index %d slicetype %d\n",
+ cur_pic->index, cur_pic->slice_type,
+ col_pic->index, col_pic->slice_type);
+
+ WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR, cur_pic->mpred_mv_wr_start_addr);
+ WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, col_pic->mpred_mv_wr_start_addr);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[MPRED CO_MV] write 0x%x read 0x%x\n", cur_pic->mpred_mv_wr_start_addr, col_pic->mpred_mv_wr_start_addr);
+ /*
+ data32 =
+ ((avs3_dec->bk_img_is_top_field) << 13) |
+ ((avs3_dec->hd.background_picture_enable & 1) << 12) |
+ ((avs3_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+ ((avs3_dec->hd.b_pmvr_enabled & 1) << 6) |
+ ((avs3_dec->img.is_top_field & 1) << 5) |
+ ((avs3_dec->img.is_field_sequence & 1) << 4) |
+ ((avs3_dec->img.typeb & 7) << 1) |
+ (avs3_dec->hd.background_reference_enable & 0x1);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n", data32, avs3_dec->hd.curr_RPS.num_of_ref);
+ WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+ */
+#if 1
+ /*
+ data32 = ((hevc->lcu_x_num - hevc->tile_width_lcu)*MV_MEM_UNIT);
+ WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);
+ WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);
+ */
+ data32 = READ_VREG(HEVC_MPRED_CTRL0);
+ data32 &= (~(0x3 | (0xf << 8) | (0xf << 16)));
+ data32 = (
+ avs3_dec->slice_type |
+ /*hevc->new_pic<<2 |
+ hevc->new_tile<<3|
+ hevc->isNextSliceSegment<<4|
+ hevc->TMVPFlag<<5|
+ hevc->LDCFlag<<6|
+ hevc->ColFromL0Flag<<7|
+ */
+ above_ptr_ctrl<<8 |
+ above_en<<9|
+ mv_wr_en<<10|
+ mv_rd_en<<11|
+ avs3_dec->lcu_size_log2<<16
+ /*|cu_size_log2<<20*/
+ );
+ WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CTRL0=0x%x\n",
+ READ_VREG(HEVC_MPRED_CTRL0));
+
+ data32 = READ_VREG(HEVC_MPRED_CTRL1);
+ data32 &= (~0xf);
+ data32 |= avs3_dec->ctx.info.sqh.num_of_hmvp_cand;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "write HEVC_MPRED_CTRL1=0x%x, avs3_dec->ctx.info.sqh.num_of_hmvp_cand=%d\n",
+ data32, avs3_dec->ctx.info.sqh.num_of_hmvp_cand);
+ WRITE_VREG(HEVC_MPRED_CTRL1,data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CTRL1=0x%x\n",
+ READ_VREG(HEVC_MPRED_CTRL1));
+
+ data32 = (
+ avs3_dec->img.width|
+ avs3_dec->img.height<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+ data32 = (
+ (avs3_dec->lcu_x_num-1) |
+ (avs3_dec->lcu_y_num-1)<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU,data32);
+
+ /*data32 = (
+ hevc->tile_start_lcu_x |
+ hevc->tile_start_lcu_y<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_START,data32);
+ data32 = (
+ hevc->tile_width_lcu |
+ hevc->tile_height_lcu<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU,data32);
+ */
+ data32 = (
+ avs3_dec->ctx.dpm.num_refp[REFP_0] |
+ avs3_dec->ctx.dpm.num_refp[REFP_1]<<8|
+ 0
+ //col_RefNum_L0<<16|
+ //col_RefNum_L1<<24
+ );
+ WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+ data32=0;
+ for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_0];i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+ data32=0;
+ for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_1];i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+
+ WRITE_VREG(HEVC_MPRED_CUR_POC, avs3_dec->ctx.ptr & 0xffff);
+ if (avs3_dec->slice_type == SLICE_P) {
+ col_ptr = avs3_dec->ctx.refp[0][REFP_0].ptr;
+ //colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+ }
+ else if (avs3_dec->slice_type == SLICE_B) {
+ col_ptr = avs3_dec->ctx.refp[0][REFP_1].ptr;
+ //colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+ }
+ else {
+ col_ptr = avs3_dec->ctx.pic->ptr;
+ //colPic = avs3_dec->ctx.pic;
+ }
+ WRITE_VREG(HEVC_MPRED_COL_POC, col_ptr & 0xffff);
+ //below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> Ref_POC_xx_L1 in pair write order!!!
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_CUR_POC=0x%x, HEVC_MPRED_COL_POC=0x%x\n",
+ READ_VREG(HEVC_MPRED_CUR_POC), READ_VREG(HEVC_MPRED_COL_POC));
+
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+ data32 = 0;
+ if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+ if (i < cur_pic->list0_num_refp) {
+ data32 |= cur_pic->list0_ptr[i] & 0xffff;
+ }
+ if (i < col_pic->list0_num_refp) {
+ data32 |= ((col_pic->list0_ptr[i] & 0xffff) << 16);
+ }
+ }
+ WRITE_VREG(HEVC_MPRED_L0_REF_POC_ADR[i], data32);
+ }
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+ if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+ if (i < cur_pic->list0_num_refp) {
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[%d] ", cur_pic->list0_ptr[i]);
+ }
+ if (i < col_pic->list0_num_refp) {
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "<%d> ", col_pic->list0_ptr[i]);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_L0_REF=0x%x (readback 0x%x)\n", i,
+ data32, READ_VREG(HEVC_MPRED_L0_REF_POC_ADR[i]));
+ }
+ }
+ }
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ WRITE_VREG(HEVC_MPRED_L1_REF_POC_ADR[i], avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff);
+ }
+ if (debug) {
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_MPRED_L1_REF%02d_POC=0x%x (readback 0x%x)\n", i, avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff, READ_VREG(HEVC_MPRED_L1_REF_POC_ADR[i]));
+ }
+ }
+
+#if 0
+ if (hevc->new_pic)
+ {
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,mpred_above_buf_start);
+ WRITE_VREG(HEVC_MPRED_MV_WPTR,mpred_mv_wr_ptr);
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_start_addr);
+ }
+ else if (!hevc->isNextSliceSegment)
+ {
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ }
+#endif
+ WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dw_fb(struct AVS3Decoder_s *dec, struct avs3_frame_s *pic,
+ u32 mc_buffer_size_u_v_h)
+{
+
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int dw_mode = get_double_write_mode(dec);
+ uint32_t data, data32;
+ if ((dw_mode & 0x10) == 0) {
+ WRITE_BACK_8(avs3_dec, HEVC_SAO_CTRL26, 0);
+
+ //data32 = READ_VREG(HEVC_SAO_CTRL5);
+ //data32 &= (~(0xff << 16));
+ if (((dw_mode & 0xf) == 8) ||
+ ((dw_mode & 0xf) == 9)) {
+ data = 0xff; //data32 |= (0xff << 16);
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_BACK_8(avs3_dec, HEVC_SAO_CTRL26, 0xf);
+ } else {
+ if ((dw_mode & 0xf) == 2 ||
+ (dw_mode & 0xf) == 3)
+ data = 0xff; //data32 |= (0xff<<16);
+ else if ((dw_mode & 0xf) == 4 ||
+ (dw_mode & 0xf) == 5)
+ data = 0x33; //data32 |= (0x33<<16);
+
+ /*if (dec->mem_saving_mode == 1)
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 1, 9, 1); //data32 |= (1 << 9);
+ else*/
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 0, 9, 1); //data32 &= ~(1 << 9);
+ /*if (workaround_enable & 1)
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 1, 7, 1); //data32 |= (1 << 7);*/
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, data, 16, 8);
+ }
+
+ /* m8baby test1902 */
+ //data32 = READ_VREG(HEVC_SAO_CTRL1);
+ //data32 &= (~0x3000);
+ /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+ //data32 |= (dec->mem_map_mode << 12);
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, MEM_MAP_MODE, 12, 2);
+ //data32 &= (~0xff0);
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable == 0)
+ data = ((dec->endian >> 8) & 0xfff); //endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf)
+#else
+ data = ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, data, 0, 12);
+
+ //data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+ if (dw_mode == 0)
+ data = 0x2; //data32 |= 0x2; /*disable double write*/
+ else if (dw_mode & 0x10)
+ data = 0x1; //data32 |= 0x1; /*disable cm*/
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, data, 0, 2);
+
+ //data32 &= (~(3 << 14));
+ //data32 |= (2 << 14);
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, 2, 14, 2);
+ //WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+ //data32 &= (~0x300); /*[8]:first write enable (compress)
+ // [9]:double write enable (uncompress)*/
+ if (dw_mode == 0)
+ data = 1; //data32 |= (0x1 << 8); /*enable first write*/
+ else if (dw_mode == 0x10)
+ data = 2; //data32 |= (0x1 << 9); /*double write only*/
+ else
+ data = 3; //data32 |= ((0x1 << 8) | (0x1 << 9));
+ //WRITE_VREG(HEVC_DBLK_CFGB, data32);
+ READ_WRITE_DATA16(avs3_dec, HEVC_DBLK_CFGB, data, 8, 2);
+
+ if (dw_mode & 0x10) {
+ /* [23:22] dw_v1_ctrl
+ *[21:20] dw_v0_ctrl
+ *[19:18] dw_h1_ctrl
+ *[17:16] dw_h0_ctrl
+ */
+ //data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ //data32 &= ~(0xff << 16);
+ //WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 0, 16, 8);
+ }
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+ data32 = pic->mc_y_adr;
+ if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ if ((dw_mode & 0x10) == 0)
+ WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, data32);
+
+ if (dec->mmu_enable)
+ WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0);
+ WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ }
+#endif
+#else
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+ data32 = (mc_buffer_size_u_v_h << 16) << 1;
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_LENGTH, data32);
+
+ data32 = (mc_buffer_size_u_v_h << 16);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_LENGTH, data32);
+
+}
+
+static void config_sao_hw_fb(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_frame_t *pic = avs3_dec->cur_pic;
+ //union param_u* params = &avs3_dec->param;
+ //uint32_t data32;
+ int32_t pic_width = avs3_dec->img.width;
+ int32_t pic_height = avs3_dec->img.height;
+ int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+ int32_t lcu_size = 1<<lcu_size_log2;
+ int32_t pic_width_lcu = ( pic_width % lcu_size ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+ int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+ int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+ int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+ int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+ config_dw_fb(dec, pic, mc_buffer_size_u_v_h);
+#if 0 // no dual mode
+ data32 = READ_VREG(HEVC_SAO_CTRL0);
+ data32 &= (~0xf);
+ data32 |= avs3_dec->lcu_size_log2;
+ WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#else
+ READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL0, avs3_dec->lcu_size_log2, 0, 4);
+#endif
+
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+ if ((get_double_write_mode(dec) & 0x20) == 0) {
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+ if (dec->dw_mmu_enable) {
+ WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0);
+ }
+
+ ///WRITE_VREG(HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+ //WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+ ///WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+ //WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+#ifdef AVS3_10B_MMU
+ ///WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * MMU_COMPRESS_HEADER_SIZE));
+ //WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS3_10B_MMU_DW
+ //if (dec->dw_mmu_enable) {
+ ///WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+ // WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+ //}
+#endif
+
+#else
+ ///WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+ data32 = (mc_buffer_size_u_v_h<<16)<<1;
+ ///WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_LENGTH ,data32);
+
+ ///WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+ //WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+ data32 = (mc_buffer_size_u_v_h<<16);
+ ///WRITE_VREG(HEVC_SAO_C_LENGTH ,data32);
+ WRITE_BACK_32(avs3_dec, HEVC_SAO_C_LENGTH ,data32);
+ ///WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+ //WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+ ///WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+ //WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+
+#ifdef AVS3_10B_NV21
+ SHOULD NOT DEFINED !!
+ data32 = READ_VREG( HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ data32 &= (~0x3);
+ data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
+ WRITE_VREG( HEVC_SAO_CTRL1, data32);
+
+ data32 = READ_VREG( HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
+ data32 &= ~(0xff << 16); // set them all 0 for H265_NV21 (no down-scale)
+ WRITE_VREG( HEVC_SAO_CTRL5, data32);
+
+ data32 = READ_VREG( HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
+ WRITE_VREG( HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgSAO .done.\n");
+}
+
+static void config_dblk_hw_fb(struct AVS3Decoder_s *dec)
+{
+ /*
+ * Picture level de-block parameter configuration here
+ */
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ union param_u *rpm_param = &avs3_dec->param;
+ uint32_t data32;
+ DEC_CTX * ctx = &avs3_dec->ctx;
+ int32_t alpha_c_offset = rpm_param->p.pic_header_alpha_c_offset;
+ int32_t beta_offset = rpm_param->p.pic_header_beta_offset;
+
+ alpha_c_offset = (alpha_c_offset >=16) ? 15 : ((alpha_c_offset < -16) ? -16 : alpha_c_offset);
+ beta_offset = (beta_offset >=16) ? 15 : ((beta_offset < -16) ? -16 : beta_offset);
+
+#if 0 // NOT Dual Mode
+ data32 = READ_VREG(HEVC_DBLK_CFG1);
+ data32 = (((data32>>20)&0xfff)<<20) |
+ (((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)<<16) | // [16 +: 4]: {luma_bd[1:0],chroma_bd[1:0]}
+ (((data32>>2)&0x3fff)<<2) |
+ (((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)<<0);// [ 0 +: 2]: lcu_size
+ WRITE_VREG(HEVC_DBLK_CFG1, data32);
+#else
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0x6450101; //mfsp COMMON_REG_1, HEVC_DBLK_CFG1
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)&0xffff)<<6); // movi COMMON_REG_0, data
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0x9604040; //ins COMMON_REG_1, COMMON_REG_0, 16, 4
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)&0xffff)<<6); // movi COMMON_REG_0, data
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0x9402040; //ins COMMON_REG_1, COMMON_REG_0, 0, 2
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+ avs3_dec->instruction[avs3_dec->ins_offset] = 0x6050101; //mtsp COMMON_REG_1, HEVC_DBLK_CFG1
+ avs3_print(dec, AVS3_DBG_REG,
+ "instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+ avs3_dec->ins_offset++;
+#endif
+
+ data32 = (avs3_dec->img.height<<16) | avs3_dec->img.width;
+ ///WRITE_VREG(HEVC_DBLK_CFG2, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFG2, data32);
+
+ data32 = ((rpm_param->p.sqh_cross_patch_loop_filter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+ ((rpm_param->p.pic_header_loop_filter_disable_flag & 0x1)<<26) | // [26 +: 1]: loop_filter_disable
+ ((alpha_c_offset&0x1f) <<17) | // [17 +: 5]: alpha_c_offset (-8~8)
+ ((beta_offset&0x1f) <<12) | // [12 +: 5]: beta_offset (-8~8)
+ ((rpm_param->p.pic_header_chroma_quant_param_delta_cb&0x3f)<<6) | // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+ ((rpm_param->p.pic_header_chroma_quant_param_delta_cr&0x3f)<<0); // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+ ///WRITE_VREG(HEVC_DBLK_CFG9, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFG9, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d,%d),log2_lcuSize(%d)\n",
+ rpm_param->p.sqh_cross_patch_loop_filter,rpm_param->p.pic_header_loop_filter_disable_flag,
+ ctx->info.bit_depth_input,ctx->info.bit_depth_internal,ctx->info.log2_max_cuwh);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: alphaCOffset(%d crop to %d),betaOffset(%d crop to %d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+ rpm_param->p.pic_header_alpha_c_offset, alpha_c_offset, rpm_param->p.pic_header_beta_offset, beta_offset,
+ rpm_param->p.pic_header_chroma_quant_param_delta_cb,rpm_param->p.pic_header_chroma_quant_param_delta_cr);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: .done.\n");
+
+}
+
+static void reconstructCoefficients(struct AVS3Decoder_s *dec, ALFParam *alfParam)
+{
+ int32_t g, sum, i, coeffPred;
+ for (g = 0; g < alfParam->filters_per_group; g++) {
+ sum = 0;
+ for (i = 0; i < alfParam->num_coeff - 1; i++) {
+ sum += (2 * alfParam->coeff_multi[g][i]);
+ dec->m_filterCoeffSym[g][i] = alfParam->coeff_multi[g][i];
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n", g,i,dec->m_filterCoeffSym[g][i]);
+ }
+ coeffPred = (1 << ALF_NUM_BIT_SHIFT) - sum;
+ dec->m_filterCoeffSym[g][alfParam->num_coeff - 1] = coeffPred + alfParam->coeff_multi[g][alfParam->num_coeff - 1];
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n", g,(alfParam->num_coeff - 1),dec->m_filterCoeffSym[g][alfParam->num_coeff - 1]);
+ }
+}
+
+static void reconstructCoefInfo(struct AVS3Decoder_s *dec, int32_t compIdx, ALFParam *alfParam)
+{
+ int32_t i;
+ if (compIdx == ALF_Y) {
+ if (alfParam->filters_per_group > 1) {
+ for (i = 1; i < NO_VAR_BINS; ++i) {
+ if (alfParam->filter_pattern[i]) {
+ dec->m_varIndTab[i] = dec->m_varIndTab[i - 1] + 1;
+ } else {
+ dec->m_varIndTab[i] = dec->m_varIndTab[i - 1];
+ }
+ }
+ }
+ }
+ reconstructCoefficients(dec, alfParam);
+}
+
+static void config_alf_hw_fb(struct AVS3Decoder_s *dec)
+{
+ /*
+ * Picture level ALF parameter configuration here
+ */
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ uint32_t data32;
+ int32_t i,j;
+ int32_t m_filters_per_group;
+#ifdef USE_FORCED_ALF_PARAM
+ ALFParam forced_alf_cr;
+ forced_alf_cr.alf_flag = 1;
+ forced_alf_cr.num_coeff = 9;
+ forced_alf_cr.filters_per_group = 1;
+ forced_alf_cr.component_id = 2;
+ forced_alf_cr.coeff_multi[0][0] = -3;
+ forced_alf_cr.coeff_multi[0][1] = -3;
+ forced_alf_cr.coeff_multi[0][2] = 4;
+ forced_alf_cr.coeff_multi[0][3] = 7;
+ forced_alf_cr.coeff_multi[0][4] = 6;
+ forced_alf_cr.coeff_multi[0][5] = -1;
+ forced_alf_cr.coeff_multi[0][6] = 3;
+ forced_alf_cr.coeff_multi[0][7] = 6;
+ forced_alf_cr.coeff_multi[0][8] = 0;
+#endif
+
+ ALFParam *m_alfPictureParam_y = &avs3_dec->m_alfPictureParam[0];
+ ALFParam *m_alfPictureParam_cb = &avs3_dec->m_alfPictureParam[1];
+#ifdef USE_FORCED_ALF_PARAM
+ ALFParam *m_alfPictureParam_cr = &forced_alf_cr; // &avs3_dec->m_alfPictureParam[2];
+#else
+ ALFParam *m_alfPictureParam_cr = &avs3_dec->m_alfPictureParam[2];
+#endif
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filter_pattern[0]=0x%x,[15]=0x%x\n",
+ m_alfPictureParam_y->component_id,
+ m_alfPictureParam_y->alf_flag,
+ m_alfPictureParam_y->filters_per_group,
+ m_alfPictureParam_y->filter_pattern[0],m_alfPictureParam_y->filter_pattern[15]);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[t]alfy,num_coeff(%d),coeff_multi[0][0]=0x%x,[0][1]=0x%x,[1][0]=0x%x,[1][1]=0x%x\n",
+ m_alfPictureParam_y->num_coeff,
+ m_alfPictureParam_y->coeff_multi[0][0],
+ m_alfPictureParam_y->coeff_multi[0][1],
+ m_alfPictureParam_y->coeff_multi[1][0],
+ m_alfPictureParam_y->coeff_multi[1][1]);
+
+ // Cr
+ for (i=0;i<16;i++) dec->m_varIndTab[i] = 0;
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 2, m_alfPictureParam_cr);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cr(%d), alf_cr_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cr->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Cb
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 1, m_alfPictureParam_cb);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cb(%d), alf_cb_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cb->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Y
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 0, m_alfPictureParam_y);
+ data32 = ((dec->m_varIndTab[7] & 0xf) << 28) | ((dec->m_varIndTab[6] & 0xf) << 24) |
+ ((dec->m_varIndTab[5] & 0xf) << 20) | ((dec->m_varIndTab[4] & 0xf) << 16) |
+ ((dec->m_varIndTab[3] & 0xf) << 12) | ((dec->m_varIndTab[2] & 0xf) << 8) |
+ ((dec->m_varIndTab[1] & 0xf) << 4) | ((dec->m_varIndTab[0] & 0xf) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_varIndTab[15] & 0xf) << 28) | ((dec->m_varIndTab[14] & 0xf) << 24) |
+ ((dec->m_varIndTab[13] & 0xf) << 20) | ((dec->m_varIndTab[12] & 0xf) << 16) |
+ ((dec->m_varIndTab[11] & 0xf) << 12) | ((dec->m_varIndTab[10] & 0xf) << 8) |
+ ((dec->m_varIndTab[ 9] & 0xf) << 4) | ((dec->m_varIndTab[ 8] & 0xf) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_y(%d), alf_y_tab(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_y->alf_flag,
+ dec->m_varIndTab[ 0],dec->m_varIndTab[ 1],dec->m_varIndTab[ 2],dec->m_varIndTab[ 3],
+ dec->m_varIndTab[ 4],dec->m_varIndTab[ 5],dec->m_varIndTab[ 6],dec->m_varIndTab[ 7],
+ dec->m_varIndTab[ 8],dec->m_varIndTab[ 9],dec->m_varIndTab[10],dec->m_varIndTab[11],
+ dec->m_varIndTab[12],dec->m_varIndTab[13],dec->m_varIndTab[14],dec->m_varIndTab[15]);
+
+ m_filters_per_group = (m_alfPictureParam_y->alf_flag == 0) ? 1 : m_alfPictureParam_y->filters_per_group;
+ for (i=0;i<m_filters_per_group;i++) {
+ data32 = ((dec->m_filterCoeffSym[i][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[i][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[i][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[i][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[i][0] & 0x7f) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ data32 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+ ((dec->m_filterCoeffSym[i][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[i][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[i][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[i][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[i][4]>>4) & 0x7 ) << 0);
+ ///WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] alf_y_coef[%d](%d %d %d %d %d %d %d %d %d)\n",i,dec->m_filterCoeffSym[i][0],dec->m_filterCoeffSym[i][1],dec->m_filterCoeffSym[i][2],
+ dec->m_filterCoeffSym[i][3],dec->m_filterCoeffSym[i][4],dec->m_filterCoeffSym[i][5],
+ dec->m_filterCoeffSym[i][6],dec->m_filterCoeffSym[i][7],dec->m_filterCoeffSym[i][8]);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgALF .done.\n");
+}
+
+static void config_mcrcc_axi_hw_fb(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ //uint32_t rdata32;
+ //uint32_t rdata32_2;
+
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+ WRITE_BACK_8(avs3_dec, HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+ if (avs3_dec->slice_type == SLICE_I) {
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+ WRITE_BACK_8(avs3_dec, HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+ return;
+ }
+
+#if 0
+ mcrcc_get_hitrate();
+ decomp_get_hitrate();
+ decomp_get_comprate();
+#endif
+ if ((avs3_dec->slice_type == SLICE_B) || (avs3_dec->slice_type == SLICE_P)) {
+ // Programme canvas0
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+ READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+ // Programme canvas1
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (1<<1) | 0);
+ WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1, (16 << 8) | (1<<1) | 0);
+ ///rdata32_2 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32_2 = rdata32_2 & 0xffff;
+ ///rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ ///if ( rdata32 == rdata32_2 ) {
+ /// rdata32_2 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ /// rdata32_2 = rdata32_2 & 0xffff;
+ /// rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ ///}
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32_2);
+ READ_CMP_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 1, 0, 16, 16);
+ } else { // P-PIC
+ ///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+ WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+ READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+ // Programme canvas1
+ ///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ ///rdata32 = rdata32 & 0xffff;
+ ///rdata32 = rdata32 | ( rdata32 << 16);
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32);
+ READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 0, 16, 16);
+ }
+
+ ///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+ WRITE_BACK_16(avs3_dec, HEVCD_MCRCC_CTL1, 0, 0xff0); // enable mcrcc progressive-mode
+ return;
+}
+
+#endif
diff --git a/drivers/frame_provider/decoder/avs3/avs3_global.h b/drivers/frame_provider/decoder/avs3/avs3_global.h
new file mode 100644
index 0000000..e3d6087
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_global.h
@@ -0,0 +1,561 @@
+#ifndef AVS3_GLOBAL_H_
+#define AVS3_GLOBAL_H_
+
+//#define DEBUG_AMRISC
+
+#define LINUX
+#define NEW_FB_CODE
+#define NEW_FRONT_BACK_CODE
+#define LARGE_INSTRUCTION_SPACE_SUPORT
+#define BUFMGR_SANITY_CHECK
+
+#define P010_ENABLE
+
+#define OW_TRIPLE_WRITE
+
+#include "com_def.h"
+
+#ifdef SIMULATION
+#ifdef SYSTEM_TEST
+#define printf st_printf
+#define printk st_printf
+#else
+#define printf io_printf
+#define printk io_printf
+#endif
+#endif
+
+#define WITH_OLD_CODE
+
+#define RPM_BEGIN 0x080 //0x100
+#define ALF_BEGIN 0x100 //0x180
+#define RPM_END 0x200 //0x280
+#define RPM_VALID_END 0x1b8
+
+
+typedef union param_u {
+ struct {
+ unsigned short data[RPM_END - RPM_BEGIN];
+ } l;
+ struct {
+
+ /*sequence head*/
+ unsigned short sqh_profile_id;
+ unsigned short sqh_level_id;
+ unsigned short sqh_progressive_sequence;
+ unsigned short sqh_field_coded_sequence;
+ unsigned short sqh_library_stream_flag;
+ unsigned short sqh_library_picture_enable_flag;
+ unsigned short sqh_horizontal_size;
+ unsigned short sqh_vertical_size;
+ unsigned short sqh_sample_precision;
+ unsigned short sqh_encoding_precision;
+ unsigned short sqh_aspect_ratio;
+ unsigned short sqh_frame_rate_code;
+ unsigned short sqh_low_delay;
+ unsigned short sqh_temporal_id_enable_flag;
+ unsigned short sqh_max_dpb_size;
+ unsigned short sqh_num_ref_default_active_minus1[2];
+ unsigned short sqh_log2_max_cu_width_height;
+ unsigned short sqh_adaptive_leveling_filter_enable_flag;
+ unsigned short sqh_num_of_hmvp_cand;
+ unsigned short sqh_output_reorder_delay;
+ unsigned short sqh_cross_patch_loop_filter;
+ /*picture head*/
+ unsigned short pic_header_decode_order_index;
+ unsigned short pic_header_picture_output_delay;
+ unsigned short pic_header_progressive_frame;
+ unsigned short pic_header_top_field_first;
+ unsigned short pic_header_repeat_first_field;
+ unsigned short pic_header_ref_pic_list_sps_flag[2];
+ unsigned short pic_header_rpl_l0_idx;
+ unsigned short pic_header_rpl_l1_idx;
+ unsigned short pic_header_rpl_l0_ref_pic_num;
+ unsigned short pic_header_rpl_l0_ref_pics_ddoi[17];
+ unsigned short pic_header_rpl_l1_ref_pic_num;
+ unsigned short pic_header_rpl_l1_ref_pics_ddoi[17];
+ unsigned short pic_header_rpl_l0_reference_to_library_enable_flag;
+ unsigned short pic_header_rpl_l0_library_index_flag[17];
+ unsigned short pic_header_rpl_l1_reference_to_library_enable_flag;
+ unsigned short pic_header_rpl_l1_library_index_flag[17];
+ unsigned short pic_header_loop_filter_disable_flag;
+ unsigned short pic_header_random_access_decodable_flag;
+ unsigned short pic_header_slice_type;
+ unsigned short pic_header_num_ref_idx_active_override_flag;
+ unsigned short pic_header_rpl_l0_ref_pic_active_num;
+ unsigned short pic_header_rpl_l1_ref_pic_active_num;
+ /*patch head*/
+ /**/
+ unsigned short sqh_adaptive_filter_shape_enable_flag;
+ unsigned short pic_header_library_picture_index;
+ unsigned short pic_header_top_field_picture_flag;
+ unsigned short pic_header_alpha_c_offset;
+ unsigned short pic_header_beta_offset;
+ unsigned short pic_header_chroma_quant_param_delta_cb;
+ unsigned short pic_header_chroma_quant_param_delta_cr;
+//HDR10
+ uint16_t video_signal_type;
+ uint16_t color_description;
+ uint16_t display_primaries_x[3];
+ uint16_t display_primaries_y[3];
+ uint16_t white_point_x;
+ uint16_t white_point_y;
+ uint16_t max_display_mastering_luminance;
+ uint16_t min_display_mastering_luminance;
+ uint16_t max_content_light_level;
+ uint16_t max_picture_average_light_level;
+ } p;
+ struct {
+ uint16_t padding[ALF_BEGIN - RPM_BEGIN];
+ uint16_t picture_alf_enable_Y;
+ uint16_t picture_alf_enable_Cb;
+ uint16_t picture_alf_enable_Cr;
+ uint16_t alf_filters_num_m_1;
+ uint16_t dir_index;
+ uint16_t region_distance[16];
+ uint16_t alf_cb_coeffmulti[9];
+ uint16_t alf_cr_coeffmulti[9];
+ uint16_t alf_y_coeffmulti[16][9];
+ } alf;
+}param_t;
+
+/******************************************************************************
+ * CONTEXT used for decoding process.
+ *
+ * All have to be stored are in this structure.
+ *****************************************************************************/
+typedef struct _DEC_CTX DEC_CTX;
+struct _DEC_CTX
+{
+ COM_INFO info;
+ /* magic code */
+ u32 magic;
+ /* DEC identifier */
+ DEC id;
+ /* CORE information used for fast operation */
+ //DEC_CORE *core;
+ /* current decoding bitstream */
+ //COM_BSR bs;
+
+ /* decoded picture buffer management */
+ COM_PM dpm;
+ /* create descriptor */
+ DEC_CDSC cdsc;
+
+ /* current decoded (decoding) picture buffer */
+ COM_PIC *pic;
+#if EVS_UBVS_MODE
+ pel dpb_evs[N_C][MAX_SRB_PRED_SIZE];
+#endif
+ /* SBAC */
+ //DEC_SBAC sbac_dec;
+ u8 init_flag;
+
+ COM_MAP map;
+#if CHROMA_NOT_SPLIT
+ u8 tree_status;
+#endif
+#if MODE_CONS
+ u8 cons_pred_mode;
+#endif
+
+ /* total count of remained LCU for decoding one picture. if a picture is
+ decoded properly, this value should reach to zero */
+ int lcu_cnt;
+
+ int **edge_filter[LOOPFILTER_DIR_TYPE];
+
+ COM_PIC *pic_sao;
+ SAO_STAT_DATA ***sao_stat_data; //[SMB][comp][types]
+ SAO_BLK_PARAM **sao_blk_params; //[SMB][comp]
+ SAO_BLK_PARAM **rec_sao_blk_params;//[SMB][comp]
+
+#if ESAO
+ COM_PIC *pic_esao; //rec buff after deblock filter
+ ESAO_BLK_PARAM pic_esao_params[N_C];//comp]
+ ESAO_FUNC_POINTER func_esao_block_filter;
+#endif
+
+#if CCSAO
+#if CCSAO_ENHANCEMENT
+ COM_PIC *pic_ccsao[2];
+#else
+ COM_PIC *pic_ccsao;
+#endif
+#if !CCSAO_PH_SYNTAX
+ CCSAO_BLK_PARAM pic_ccsao_params[N_C-1];
+#endif
+ CCSAO_FUNC_POINTER ccsao_func_ptr;
+#endif
+
+ COM_PIC *pic_alf_Dec;
+ COM_PIC *pic_alf_Rec;
+ int pic_alf_on[N_C];
+ int ***coeff_all_to_write_alf;
+ //DEC_ALF_VAR *dec_alf;
+
+ u8 ctx_flags[NUM_CNID];
+
+ /**************************************************************************/
+ /* current slice number, which is increased whenever decoding a slice.
+ when receiving a slice for new picture, this value is set to zero.
+ this value can be used for distinguishing b/w slices */
+ u16 slice_num;
+ /* last coded intra picture's presentation temporal reference */
+ int last_intra_ptr;
+ /* current picture's decoding temporal reference */
+ int dtr;
+ /* previous picture's decoding temporal reference low part */
+ int dtr_prev_low;
+ /* previous picture's decoding temporal reference high part */
+ int dtr_prev_high;
+ /* current picture's presentation temporal reference */
+ int ptr;
+ /* the number of currently decoded pictures */
+ int pic_cnt;
+ /* picture buffer allocator */
+ PICBUF_ALLOCATOR pa;
+ /* bitstream has an error? */
+ u8 bs_err;
+ /* reference picture (0: forward, 1: backward) */
+ COM_REFP refp[MAX_NUM_REF_PICS][REFP_NUM];
+ /* flag for picture signature enabling */
+ u8 use_pic_sign;
+ /* picture signature (MD5 digest 128bits) */
+ u8 pic_sign[16];
+ /* flag to indicate picture signature existing or not */
+ u8 pic_sign_exist;
+ //AmlDbg* amldbg;
+
+#if PATCH
+ int patch_column_width[64];
+ int patch_row_height[128];
+ PATCH_INFO *patch;
+#endif
+
+ u8 *wq[2];
+#if CUDQP
+ COM_CU_QP_GROUP cu_qp_group;
+#endif
+};
+
+#ifdef WITH_OLD_CODE
+#define I_PICTURE_START_CODE 0xB3
+#define PB_PICTURE_START_CODE 0xB6
+#define SLICE_START_CODE_MIN 0x00
+#define SLICE_START_CODE_MAX 0x8F
+#define USER_DATA_START_CODE 0xB2
+#define SEQUENCE_HEADER_CODE 0xB0
+#define EXTENSION_START_CODE 0xB5
+#define SEQUENCE_END_CODE 0xB1
+#define VIDEO_EDIT_CODE 0xB7
+
+enum ALFComponentID {
+ ALF_Y = 0,
+ ALF_Cb,
+ ALF_Cr,
+ NUM_ALF_COMPONENT
+};
+
+#if 0
+typedef struct {
+ int32_t alf_flag;
+ int32_t num_coeff;
+ int32_t filters_per_group;
+ int32_t componentID;
+ int32_t filterPattern[16]; // *filterPattern;
+ int32_t coeffmulti[16][9]; // **coeffmulti;
+} ALFParam;
+#endif
+
+typedef ALF_PARAM ALFParam;
+
+#define INTRA_IMG 0 //!< I frame
+#define INTER_IMG 1 //!< P frame
+#define B_IMG 2 //!< B frame
+#define I_IMG 0 //!< I frame
+#define P_IMG 1 //!< P frame
+#define F_IMG 4 //!< F frame
+
+#define BACKGROUND_IMG 3
+
+typedef struct {
+ //int32_t typeb;
+ //int32_t type;
+ //int32_t tr; //<! temporal reference, 8 bit,
+ int32_t width; //!< Number of pels
+ int32_t height; //!< Number of lines
+ int32_t num_of_references;
+ int32_t pic_alf_on[NUM_ALF_COMPONENT];
+ //int32_t is_field_sequence;
+ //int32_t is_top_field;
+ int number;
+} ImageParameters;
+
+struct inp_par {
+ u32 sample_bit_depth;
+ u32 alf_enable;
+};
+#else
+#define PIC_POOL_SIZE 32
+#endif
+
+//new dual
+struct buff_s {
+ u32 buf_start;
+ u32 buf_size;
+ u32 buf_end;
+};
+typedef struct buff_s buff_t;
+
+#ifdef NEW_FRONT_BACK_CODE
+#define MAX_FB_IFBUF_NUM 16
+typedef struct {
+ uint32_t mmu0_ptr;
+ uint32_t mmu1_ptr;
+ uint32_t scalelut_ptr;
+ uint32_t vcpu_imem_ptr;
+ uint32_t sys_imem_ptr;
+ uint32_t lmem0_ptr;
+ uint32_t lmem1_ptr;
+ uint32_t parser_sao0_ptr;
+ uint32_t parser_sao1_ptr;
+ uint32_t mpred_imp0_ptr;
+ uint32_t mpred_imp1_ptr;
+ //
+ uint32_t scalelut_ptr_pre;
+ //for linux
+ void *sys_imem_ptr_v;
+} buff_ptr_t;
+#endif
+
+typedef struct avs3_decoder {
+#ifdef WITH_OLD_CODE
+ uint8_t init_hw_flag;
+ struct inp_par input;
+ ImageParameters img;
+ //Video_Com_data hc;
+ //Video_Dec_data hd;
+ //union param_u param;
+ //avs3_frame_t *fref[REF_MAXBUFFER];
+#ifdef AML
+ /*used for background
+ when background_picture_output_flag is 0*/
+ //avs3_frame_t *m_bg;
+ /*current background picture, ether m_bg or fref[..]*/
+ avs3_frame_t *f_bg;
+#endif
+ //outdata outprint;
+ uint32_t cm_header_start;
+ ALF_PARAM m_alfPictureParam[N_C];
+ ALF_PARAM *p_alfPictureParam[N_C];
+/*#ifdef FIX_CHROMA_FIELD_MV_BK_DIST*/
+ int8_t bk_img_is_top_field;
+/*#endif*/
+#ifdef AML
+ int32_t lcu_size;
+ int32_t lcu_size_log2;
+ int32_t lcu_x_num;
+ int32_t lcu_y_num;
+ int32_t lcu_total;
+#endif
+/*WITH_OLD_CODE*/
+#endif
+ union param_u param;
+ DEC_CTX ctx;
+ DEC_STAT stat;
+ COM_PIC pic_pool[MAX_PB_SIZE];
+ LibVCData libvc_data;
+ unsigned int dec_status;
+ avs3_frame_t *cur_pic;
+ avs3_frame_t *col_pic;
+ u8 slice_type;
+ u8 seq_change_flag;
+ int decode_id;
+/**/
+#ifdef NEW_FRONT_BACK_CODE
+ uint8_t wait_working_buf;
+ uint8_t front_pause_flag; /*multi pictures in one packe*/
+ /*FB mgr*/
+ uint8_t fb_wr_pos;
+ uint8_t fb_rd_pos;
+ buff_t fb_buf_mmu0;
+ buff_t fb_buf_mmu1;
+ buff_t fb_buf_scalelut;
+ buff_t fb_buf_vcpu_imem;
+ buff_t fb_buf_sys_imem;
+ buff_t fb_buf_lmem0;
+ buff_t fb_buf_lmem1;
+ buff_t fb_buf_parser_sao0;
+ buff_t fb_buf_parser_sao1;
+ buff_t fb_buf_mpred_imp0;
+ buff_t fb_buf_mpred_imp1;
+ uint32_t frontend_decoded_count;
+ uint32_t backend_decoded_count;
+ buff_ptr_t fr;
+ buff_ptr_t bk;
+ buff_ptr_t init_fr;
+ buff_ptr_t p_fr;
+ buff_ptr_t next_bk[MAX_FB_IFBUF_NUM];
+ avs3_frame_t* next_be_decode_pic[MAX_FB_IFBUF_NUM];
+ /**/
+ /*for WRITE_BACK_RET*/
+ uint32_t sys_imem_ptr;
+ void *sys_imem_ptr_v;
+ void *fb_buf_sys_imem_addr;
+ uint32_t instruction[256*4]; //avoid code crash, but only 256 used
+ uint32_t ins_offset;
+#endif
+#ifdef AML
+ int max_pb_size;
+ int8_t bufmgr_error_flag;
+ u64 start_time;
+ //int32_t ref_maxbuffer;
+#endif
+} avs3_decoder_t;
+
+void avs3_bufmgr_init(struct avs3_decoder *hw);
+
+int com_picman_out_libpic(COM_PIC * pic, int library_picture_index, COM_PM * pm);
+COM_PIC * com_picman_out_pic(COM_PM * pm, int * err, int cur_pic_doi, int state);
+int com_picman_deinit(COM_PM * pm);
+int com_picman_init(COM_PM * pm, int max_pb_size, int max_num_ref_pics, PICBUF_ALLOCATOR * pa);
+int com_picman_dpbpic_doi_minus_cycle_length( COM_PM *pm );
+int com_picman_check_repeat_doi(COM_PM * pm, COM_PIC_HEADER * pic_header);
+int com_construct_ref_list_doi( COM_PIC_HEADER *pic_header );
+int com_picman_refpic_marking_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header);
+int com_cleanup_useless_pic_buffer_in_pm( COM_PM *pm );
+int com_picman_refp_rpl_based_init_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM]);
+void com_picman_print_state(COM_PM * pm);
+COM_PIC * com_picman_get_empty_pic(COM_PM * pm, int * err);
+int com_picman_put_libpic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM], COM_PIC_HEADER * pic_header);
+int com_picman_put_pic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr,
+ u32 picture_output_delay, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM]);
+void com_pic_free(struct avs3_decoder *hw, PICBUF_ALLOCATOR *pa, COM_PIC *pic);
+COM_PIC * com_pic_alloc(struct avs3_decoder *hw, PICBUF_ALLOCATOR * pa, int * ret);
+
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code);
+int dec_eco_patch_header(union param_u *param, COM_SQH *sqh, COM_PIC_HEADER * ph, COM_SH_EXT * sh,PATCH_INFO *patch);
+int dec_eco_sqh(union param_u *param, COM_SQH * sqh);
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code);
+int dec_eco_alf_coeff(union param_u *rpm_param, ALF_PARAM *alf_param);
+int dec_eco_alf_param(union param_u *rpm_param, COM_PIC_HEADER *sh
+#if ALF_SHAPE
+ , int num_coef
+#endif
+#if ALF_IMP
+ , int max_filter_num
+#endif
+);
+
+#define AVS3_DBG_BUFMGR 0x01
+#define AVS3_DBG_IRQ_EVENT 0x02
+#define AVS3_DBG_BUFMGR_MORE 0x04
+#define AVS3_DBG_BUFMGR_DETAIL 0x08
+#define AVS3_DBG_PRINT_PARAM 0x10
+#define AVS3_DBG_PRINT_PIC_LIST 0x20
+#define AVS3_DBG_OUT_PTS 0x40
+#define AVS3_DBG_PRINT_SOURCE_LINE 0x80
+#define AVS3_DBG_SEND_PARAM_WITH_REG 0x100
+#define AVS3_DBG_MERGE 0x200
+#define AVS3_DBG_NOT_RECYCLE_MMU_TAIL 0x400
+#define AVS3_DBG_REG 0x800
+#define AVS3_DBG_PIC_LEAK 0x1000
+#define AVS3_DBG_PIC_LEAK_WAIT 0x2000
+#define AVS3_DBG_HDR_INFO 0x4000
+#define AVS3_DBG_QOS_INFO 0x8000
+#define AVS3_DBG_DIS_LOC_ERROR_PROC 0x10000
+#define AVS3_DBG_DIS_SYS_ERROR_PROC 0x20000
+#define AVS3_DBG_DUMP_PIC_LIST 0x40000
+#define AVS3_DBG_TRIG_SLICE_SEGMENT_PROC 0x80000
+#define AVS3_DBG_DISABLE_IQIT_SCALELUT_INIT 0x100000
+//#define AVS3_DBG_BE_SIMULATE_IRQ 0x200000
+#define AVS3_DBG_SAO_CRC 0x200000
+#define AVS3_DBG_FORCE_SEND_AGAIN 0x400000
+#define AVS3_DBG_DUMP_DATA 0x800000
+#define AVS3_DBG_DUMP_LMEM_BUF 0x1000000
+#define AVS3_DBG_DUMP_RPM_BUF 0x2000000
+#define AVS3_DBG_CACHE 0x4000000
+#define IGNORE_PARAM_FROM_CONFIG 0x8000000
+/*MULTI_INSTANCE_SUPPORT*/
+#define PRINT_FLAG_ERROR 0
+#define PRINT_FLAG_VDEC_STATUS 0x20000000
+#define PRINT_FLAG_VDEC_DETAIL 0x40000000
+#define PRINT_FLAG_VDEC_DATA 0x80000000
+
+u32 avs3_get_debug_flag(void);
+
+bool is_avs3_print_bufmgr_detail(void);
+
+struct AVS3Decoder_s;
+
+extern u32 debug_mask;
+extern int avs3_debug(struct AVS3Decoder_s *dec,
+ int flag, const char *fmt, ...);
+
+
+#define avs3_print(dec, flag, fmt, args...) \
+ do { \
+ if (dec == NULL || \
+ (flag == 0) || \
+ ((debug_mask & \
+ (1 << dec->index)) \
+ && (debug & flag))) { \
+ avs3_debug(dec, flag, fmt, ##args); \
+ } \
+ } while (0)
+
+//int avs3_print(struct AVS3Decoder_s *dec,
+// int flag, const char *fmt, ...);
+#define assert(x)
+#ifdef DEBUG_AMRISC
+#ifndef DEBUG_RELEASE_MODE
+#define printf(...) do {\
+ if (is_avs3_print_bufmgr_detail()) \
+ avs3_debug(NULL, 0, __VA_ARGS__); \
+} while (0)
+
+#define PRINT_LINE() \
+ do { \
+ if (avs3_get_debug_flag() & AVS3_DBG_PRINT_SOURCE_LINE)\
+ avs3_debug(NULL, 0, "%s line %d\n", __func__, __LINE__);\
+ } while (0)
+#else
+#define printf(...) do {\
+ ; \
+ } while (0)
+
+#define PRINT_LINE() \
+ do { \
+ ; \
+ } while (0)
+#endif
+#else
+
+#define printf(...) do {\
+ if (is_avs3_print_bufmgr_detail()) \
+ printk(__VA_ARGS__); \
+} while (0)
+
+#define PRINT_LINE() \
+ do { \
+ if (avs3_get_debug_flag() & AVS3_DBG_PRINT_SOURCE_LINE)\
+ pr_info("%s line %d\n", __func__, __LINE__);\
+ } while (0)
+
+#endif
+
+void create_alf_global_buffer(DEC_CTX *ctx);
+//void init_pic_list(struct avs3_decoder *hw);
+COM_PIC *dec_pull_frm(DEC_CTX *ctx, int state);
+void print_pic_pool(struct avs3_decoder *hw, char *mark);
+void init_pic_pool(struct avs3_decoder *hw);
+int avs3_bufmgr_process(struct avs3_decoder *hw, int start_code);
+int avs3_bufmgr_post_process(struct avs3_decoder *hw);
+void avs3_cleanup_useless_pic_buffer_in_pm(struct avs3_decoder *hw);
+void print_alf_param(union param_u * param);
+void print_param(union param_u * param);
+int avs3_get_error_policy(void);
+
+#endif
+
diff --git a/drivers/frame_provider/decoder/avs3/com_def.h b/drivers/frame_provider/decoder/avs3/com_def.h
new file mode 100644
index 0000000..b91b377
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_def.h
@@ -0,0 +1,2736 @@
+/* ====================================================================================================================
+
+ The copyright in this software is being made available under the License included below.
+ This software may be subject to other third party and contributor rights, including patent rights, and no such
+ rights are granted under this license.
+
+ Copyright (c) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+ Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+ Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted only for
+ the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+ promoting such standards. The following conditions are required to be met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_DEF_H_
+#define _COM_DEF_H_
+#define AML
+
+#include "com_typedef.h"
+#include "com_port.h"
+#include <linux/amlogic/media/utils/amstream.h>
+
+#if TSCPM
+#define MAX_INT 2147483647 ///< max. value of signed 32-bit integer
+#endif
+
+/* profile & level */
+#if PHASE_2_PROFILE
+#define PROFILE_ID 0x32
+#else
+#define PROFILE_ID 0x22
+#endif
+#define LEVEL_ID 0x6A
+
+/* MCABAC (START) */
+#define PROB_BITS 11 // LPS_PROB(10-bit) + MPS(1-bit)
+#define PROB_MASK ((1 << PROB_BITS) - 1) // mask for LPS_PROB + MPS
+#define MAX_PROB ((1 << PROB_BITS) - 1) // equal to PROB_LPS + PROB_MPS, 0x7FF
+#define HALF_PROB (MAX_PROB >> 1)
+#define QUAR_HALF_PROB (1 << (PROB_BITS-3))
+#define LG_PMPS_SHIFTNO 2
+#if CABAC_MULTI_PROB
+#define PROB_INIT (HALF_PROB << 1) + (HALF_PROB << PROB_BITS)
+#else
+#define PROB_INIT (HALF_PROB << 1) /* 1/2 of initialization = (HALF_PROB << 1)+ MPS(0) */
+#endif
+#define READ_BITS_INIT 16
+#define DEC_RANGE_SHIFT (READ_BITS_INIT-(PROB_BITS-2))
+
+#define COM_BSR_IS_BYTE_ALIGN(bs) !((bs)->leftbits & 0x7)
+
+#if CABAC_MULTI_PROB
+#define MAX_WINSIZE 9
+#define MIN_WINSIZE 2
+#define MCABAC_SHIFT_I 5
+#define MCABAC_SHIFT_B 5
+#define MCABAC_SHIFT_P 5
+#define CYCNO_SHIFT_BITS 21 // PROB_BITS
+#define MCABAC_PROB_BITS 10
+#define MCABAC_PROB_MASK ((1 << MCABAC_PROB_BITS) - 1)
+#define COUNTER_THR_I 8
+#define COUNTER_THR_B 16
+#define COUNTER_THR_P 16
+#endif
+
+/* MCABAC (END) */
+
+/* Multiple Reference (START) */
+#define MAX_NUM_ACTIVE_REF_FRAME_B 2 /* Maximum number of active reference frames for RA condition */
+#define MAX_NUM_ACTIVE_REF_FRAME_LDB 4 /* Maximum number of active reference frames for LDB condition */
+#define MV_SCALE_PREC 14 /* Scaling precision for motion vector prediction (2^MVP_SCALING_PRECISION) */
+/* Multiple Reference (END) */
+
+/* Max. and min. Quantization parameter */
+#define MIN_QUANT 0
+#define MAX_QUANT_BASE 63
+
+/* BIO (START) */
+#if BIO
+#define BIO_MAX_SIZE 128
+#define BIO_CLUSTER_SIZE 4
+#define BIO_WINDOW_SIZE 0
+#define BIO_AVG_WIN_SIZE (BIO_CLUSTER_SIZE + (BIO_WINDOW_SIZE << 1))
+#define LIMITBIO 768
+#define DENOMBIO 2
+#endif
+/* BIO (END) */
+
+/* IST (START)*/
+#if IST
+#define IST_MAX_COEF_SIZE 16
+#endif
+/* IST (END)*/
+
+/* SBT (START) */
+#if SBT
+#define get_sbt_idx(s) (s & 0xf)
+#define get_sbt_pos(s) ((s>>4) & 0xf)
+#define get_sbt_info(idx, pos) (idx + (pos << 4))
+#define is_sbt_horizontal(idx) (idx == 2 || idx == 4)
+#define is_sbt_quad_size(idx) (idx == 3 || idx == 4)
+//encoder only
+#define SBT_FAST 1 // early skip fast algorithm
+#define SBT_SAVELOAD 1 // save & load
+#endif
+/* SBT (END) */
+
+/* AMVR (START) */
+#define MAX_NUM_MVR 5 /* 0 (1/4-pel) ~ 4 (4-pel) */
+#if BD_AFFINE_AMVR
+#define MAX_NUM_AFFINE_MVR 3
+#endif
+#define FAST_MVR_IDX 2
+#define SKIP_MVR_IDX 1
+#if BIO
+#define BIO_MAX_MVR 1
+#endif
+/* AMVR (END) */
+
+/* ABVR (START) */
+#if IBC_ABVR
+#define MAX_NUM_BVR 2 /* 1/4-pel */
+#endif
+/* ABVR (END) */
+
+/* DB_AVS2 (START) */
+#define EDGE_TYPE_LUMA 1
+#define EDGE_TYPE_ALL 2
+#define LOOPFILTER_DIR_TYPE 2
+#define LOOPFILTER_SIZE_IN_BIT 2
+#define LOOPFILTER_SIZE (1 << LOOPFILTER_SIZE_IN_BIT)
+#define LOOPFILTER_GRID 8
+#define DB_CROSS_SLICE 1
+/* DB_AVS2 (END) */
+
+/* SAO_AVS2 (START) */
+#define NUM_BO_OFFSET 32
+#define MAX_NUM_SAO_CLASSES 32
+#define NUM_SAO_BO_CLASSES_LOG2 5
+#define NUM_SAO_BO_CLASSES_IN_BIT 5
+#define NUM_SAO_EO_TYPES_LOG2 2
+#define NUM_SAO_BO_CLASSES (1<<NUM_SAO_BO_CLASSES_LOG2)
+#define SAO_SHIFT_PIX_NUM 4
+/* SAO_AVS2 (END) */
+
+/* ESAO_AVS3 (START) */
+#if ESAO
+#define ESAO_LUMA_TYPES 2 // 1 : only 17 classes; 2: both 17 and 9 classes are applied
+#define NUM_ESAO_LUMA_TYPE0 17 //
+#define NUM_ESAO_LUMA_TYPE1 9
+
+//Y
+#define ESAO_LABEL_NUM_Y 16 //
+#define ESAO_LABEL_NUM_IN_BIT_Y 4 //bits
+#define ESAO_LABEL_CLASSES_Y 272 //16*17
+//U
+#define ESAO_LABEL_NUM_U 96
+#define ESAO_LABEL_NUM_IN_BIT_U 7
+#define ESAO_LABEL_CLASSES_U 272
+//V
+#define ESAO_LABEL_NUM_V 96
+#define ESAO_LABEL_NUM_IN_BIT_V 7
+#define ESAO_LABEL_CLASSES_V 272
+
+//maximum value among Y, U and V
+#define ESAO_LABEL_NUM_MAX 96
+#define ESAO_LABEL_NUM_IN_BIT_MAX 7
+#define ESAO_LABEL_CLASSES_MAX 272
+#endif
+/* ESAO_AVS3 (END) */
+
+#if CCSAO
+/* CCSAO_AVS3 (START) */
+#if CCSAO_ENHANCEMENT
+#define CCSAO_SET_NUM 4
+#define CCSAO_SET_NUM_BIT 2
+#endif
+
+#define CCSAO_TYPE_NUM 9
+#define CCSAO_TYPE_NUM_BIT 4
+
+#define CCSAO_BAND_NUM 16
+#define CCSAO_BAND_NUM_BIT 4
+
+#if CCSAO_ENHANCEMENT
+#define CCSAO_BAND_NUM_C 2
+#define CCSAO_BAND_NUM_BIT_C 1
+#define CCSAO_CLASS_NUM (CCSAO_BAND_NUM * CCSAO_BAND_NUM_C)
+#else
+#define CCSAO_CLASS_NUM CCSAO_BAND_NUM
+#endif
+/* CCSAO_AVS3 (END) */
+#endif
+
+/* ALF_AVS2 (START) */
+#if ALF_SHAPE
+#define ALF_MAX_NUM_COEF_SHAPE2 15
+#endif
+#define ALF_MAX_NUM_COEF 9
+#if ALF_IMP
+#define ITER_NUM 4
+#define INTERVAL_NUM_X 8
+#define INTERVAL_NUM_Y 8
+#define NO_VAR_BINS INTERVAL_NUM_X*INTERVAL_NUM_Y
+#define NO_VAR_BINS_16 16
+#else
+#define NO_VAR_BINS 16
+#endif
+#define ALF_REDESIGN_ITERATION 3
+#define LOG2_VAR_SIZE_H 2
+#define LOG2_VAR_SIZE_W 2
+#define ALF_FOOTPRINT_SIZE 7
+#define DF_CHANGED_SIZE 3
+#define ALF_NUM_BIT_SHIFT 6
+/* ALF_AVS2 (END) */
+
+/* DMVR_AVS2 (START) */
+#if DMVR
+#define DMVR_IMPLIFICATION_SUBCU_SIZE 16
+#define DMVR_ITER_COUNT 2
+#define REF_PRED_POINTS_NUM 9
+#define REF_PRED_EXTENTION_PEL_COUNT 1
+#define REF_PRED_POINTS_PER_LINE_NUM 3
+#define REF_PRED_POINTS_LINES_NUM 3
+#define DMVR_NEW_VERSION_ITER_COUNT 8
+#endif
+/* DMVR_AVS2 (END) */
+
+/* INTERPF_AVS2 (START) */
+#if INTERPF
+#define NUM_RDO_INTER_FILTER 6 //number of additional RDO
+#endif
+/* INTERPF_AVS2 (END) */
+
+/* IBC (START) */
+#if USE_IBC
+#define IBC_SEARCH_RANGE 64
+#define IBC_NUM_CANDIDATES 64
+#define IBC_FAST_METHOD_BUFFERBV 0X01
+#define IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE 0X02
+#define IBC_BITSTREAM_FLAG_RESTRIC_LOG2 6 // restrict coded flag size
+#define IBC_MAX_CU_LOG2 4 /* max block size for ibc search in unit of log2 */
+#define IBC_MAX_CAND_SIZE (1 << IBC_MAX_CU_LOG2)
+#if BVD_CODING
+#define BVD_EXG_ORDER 2
+#endif
+#endif
+/* IBC (END) */
+
+/* BVP (START) */
+#if IBC_BVP
+#define ALLOWED_HBVP_NUM 12
+#define MAX_NUM_BVP 7
+#define CBVP_TH_SIZE 32
+#define CBVP_TH_CNT 2
+#endif
+/* BVP (END) */
+
+/* SP (START) */
+#if USE_SP
+#if SP_SVP
+#define SP_SEARCH_RANGE 64
+#endif
+#define SP_STRING_INFO_NO 1024// 1 << ( MAX_CU_LOG2 + MAX_CU_LOG2 - 4)//64*64 / 4 = 1024 //number of max sp string_copy_info in a CU
+#define SP_MAX_SPS_CANDS 256
+#define SP_RECENT_CANDS 12
+#define SP_EXG_ORDER 3
+#if EVS_UBVS_MODE
+#define MAX_CU_SIZE_IN_BIT 6
+#define MAX_SRB_SIZE 15
+#define MAX_SSRB_SIZE 17
+#define MAX_SRB_PRED_SIZE 28
+#define UV_WEIGHT 0.25
+#define EVS_PV_MAX 10
+#endif
+#define GET_TRAV_X(trav_idx, cu_width) ((trav_idx) & ((cu_width)-1))
+#define GET_TRAV_Y(trav_idx, cu_width_log2) ((trav_idx) >> (cu_width_log2))
+#define IS_VALID_SP_CU_SIZE(cu_width, cu_height) (((cu_width) < 4 || (cu_height) < 4 || (cu_width) > 32 || (cu_height) > 32) ? 0 : 1)
+#if EVS_UBVS_MODE
+#define IS_VALID_CS2_CU_SIZE(cu_width, cu_height) (((cu_width) < 8 || (cu_height) < 8 || (cu_width) > 32 || (cu_height) > 32) ? 0 : 1)
+#endif
+#endif
+/* SP (END) */
+
+/* MVAP (START) */
+#if MVAP
+#define MIN_SUB_BLOCK_SIZE 8
+typedef enum _MVAP_ANGULAR_PRED_MODE
+{
+ HORIZONTAL, ///< horizontal
+ VERTICAL, ///< vertical
+ HORIZONTAL_UP, ///< horizontal up
+ HORIZONTAL_DOWN, ///< horizontal down
+ VERTICAL_RIGHT, ///< vertical right
+ ALLOWED_MVAP_NUM = 5 ///< allowed mvap number
+} MVAP_ANGULAR_PRED_MODE;
+#endif
+/* MVAP (END) */
+
+/* ETMVP (START) */
+#if ETMVP
+#define MIN_ETMVP_SIZE 8
+#define MIN_ETMVP_MC_SIZE 8
+#define MAX_ETMVP_NUM 5
+#endif
+/* ETMVP (END) */
+
+/* Common stuff (START) */
+#if defined(_MSC_VER)
+#define ALIGNED_(x) __declspec(align(x))
+#define FORCE_INLINE __forceinline
+//#define INLINE __inline
+#else
+#if defined(__GNUC__)
+#define ALIGNED_(x) __attribute__ ((aligned(x)))
+#define FORCE_INLINE __attribute__((always_inline))
+//#define INLINE __inline__
+#endif
+#endif
+#if 0
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+typedef int BOOL;
+#define TRUE 1
+#define FALSE 0
+
+/* AFFINE (START) */
+#define VER_NUM 4
+#define AFFINE_MAX_NUM_LT 3 ///< max number of motion candidates in top-left corner
+#define AFFINE_MAX_NUM_RT 2 ///< max number of motion candidates in top-right corner
+#define AFFINE_MAX_NUM_LB 2 ///< max number of motion candidates in left-bottom corner
+#define AFFINE_MAX_NUM_RB 1 ///< max number of motion candidates in right-bottom corner
+#define AFFINE_MIN_BLOCK_SIZE 4 ///< Minimum affine MC block size
+
+#define AFF_MAX_NUM_MRG 5 // maximum affine merge candidates
+#define AFF_MODEL_CAND 2 // maximum affine model based candidate
+
+#define MAX_MEMORY_ACCESS_BI ((8 + 7) * (8 + 7) / 64)
+#define MAX_MEMORY_ACCESS_UNI ((8 + 7) * (4 + 7) / 32)
+
+// AFFINE ME configuration (non-normative)
+#define AF_ITER_UNI 7 // uni search iteration time
+#define AF_ITER_BI 5 // bi search iteration time
+#define AFFINE_BI_ITER 1
+
+#define AFF_SIZE 16
+/* AFFINE (END) */
+
+/* MIPF (START) */
+#if MIPF
+#define MIPF_TH_SIZE 64
+#define MIPF_TH_SIZE_CHROMA 32
+#define MIPF_TH_DIST 1
+#define MIPF_TH_DIST_CHROMA 2
+#endif
+/* MIPF (END) */
+
+/* IPF (START) */
+#define NUM_IPF_CTX 1 ///< number of context models for MPI Idx coding
+#if DT_PARTITION
+#define DT_INTRA_BOUNDARY_FILTER_OFF 1 ///< turn off boundary filter if intra DT is ON
+#endif
+/* IPF (END) */
+
+/* For debugging (START) */
+#define ENC_DEC_TRACE 0
+#if ENC_DEC_TRACE
+#define MVF_TRACE 0 ///< use for tracing MVF
+#define TRACE_REC 0 ///< trace reconstructed pixels
+#define TRACE_RDO 0 //!< Trace only encode stream (0), only RDO (1) or all of them (2)
+#define TRACE_BIN 1 //!< trace each bin
+#if TRACE_RDO
+#define TRACE_RDO_EXCLUDE_I 0 //!< Exclude I frames
+#endif
+extern FILE *fp_trace;
+extern int fp_trace_print;
+extern int fp_trace_counter;
+#if TRACE_RDO == 1
+#define COM_TRACE_SET(A) fp_trace_print=!A
+#elif TRACE_RDO == 2
+#define COM_TRACE_SET(A)
+#else
+#define COM_TRACE_SET(A) fp_trace_print=A
+#endif
+#define COM_TRACE_STR(STR) if (fp_trace_print) { fprintf(fp_trace, STR); fflush(fp_trace); }
+#define COM_TRACE_INT(INT) if (fp_trace_print) { fprintf(fp_trace, "%d ", INT); fflush(fp_trace); }
+#define COM_TRACE_COUNTER COM_TRACE_INT(fp_trace_counter++); COM_TRACE_STR("\t")
+#define COM_TRACE_MV(X, Y) if (fp_trace_print) { fprintf(fp_trace, "(%d, %d) ", X, Y); fflush(fp_trace); }
+#define COM_TRACE_FLUSH if (fp_trace_print) fflush(fp_trace)
+#else
+#define COM_TRACE_SET(A)
+#define COM_TRACE_STR(str)
+#define COM_TRACE_INT(INT)
+#define COM_TRACE_COUNTER
+#define COM_TRACE_MV(X, Y)
+#define COM_TRACE_FLUSH
+#endif
+/* For debugging (END) */
+
+#define STRIDE_IMGB2PIC(s_imgb) ((s_imgb)>>1)
+
+#define Y_C 0 /* Y luma */
+#define U_C 1 /* Cb Chroma */
+#define V_C 2 /* Cr Chroma */
+#define N_C 3 /* number of color component */
+
+#define REFP_0 0
+#define REFP_1 1
+#define REFP_NUM 2
+
+#if ST_CHROMA
+#define CHANNEL_LUMA 0 /* Y Luma */
+#define CHANNEL_CHROMA 1 /* Cb and Cr Chroma */
+#define MAX_NUM_CHANNEL 2 /* number of color channel */
+#endif
+/* X direction motion vector indicator */
+#define MV_X 0
+/* Y direction motion vector indicator */
+#define MV_Y 1
+/* Maximum count (dimension) of motion */
+#define MV_D 2
+
+#define N_REF 2 /* left, up, right */
+
+#define NUM_NEIB 1 //since SUCO is not implemented
+
+#define MINI_SIZE_LOG2 3
+#define MINI_SIZE (1 << MINI_SIZE_LOG2)
+#define MAX_CU_LOG2 7
+#define MIN_CU_LOG2 2
+#define MAX_CU_SIZE (1 << MAX_CU_LOG2)
+#define MIN_CU_SIZE (1 << MIN_CU_LOG2)
+#define MAX_CU_DIM (MAX_CU_SIZE * MAX_CU_SIZE)
+#define MIN_CU_DIM (MIN_CU_SIZE * MIN_CU_SIZE)
+#define MAX_CU_DEPTH 6 /* 128x128 ~ 4x4 */
+#if AWP
+#define AWP_ANGLE_NUM (8)
+#define AWP_RWFERENCE_SET_NUM (7)
+#define AWP_MODE_NUM (AWP_ANGLE_NUM * AWP_RWFERENCE_SET_NUM)
+#define AWP_MV_LIST_LENGTH 5
+#define MIN_AWP_SIZE_LOG2 3 /* 8 */
+#define MAX_AWP_SIZE_LOG2 6 /* 64 */
+#define MIN_AWP_SIZE (1 << MIN_AWP_SIZE_LOG2)
+#define MAX_AWP_SIZE (1 << MAX_AWP_SIZE_LOG2)
+#define MAX_AWP_DIM (MAX_AWP_SIZE * MAX_AWP_SIZE)
+
+// encoder para
+#define AWP_RDO_NUM 7
+#define CANDIDATES_PER_PARTITION 2
+#endif
+#if AWP_MVR
+#define NUM_PARTITION_FOR_AWP_MVR_RD 42
+#endif
+#define MAX_TR_LOG2 6 /* 64x64 */
+#define MIN_TR_LOG2 1 /* 2x2 */
+#define MAX_TR_SIZE (1 << MAX_TR_LOG2)
+#define MIN_TR_SIZE (1 << MIN_TR_LOG2)
+#define MAX_TR_DIM (MAX_TR_SIZE * MAX_TR_SIZE)
+#define MIN_TR_DIM (MIN_TR_SIZE * MIN_TR_SIZE)
+
+#if TB_SPLIT_EXT
+#define MAX_NUM_PB 4
+#define MAX_NUM_TB 4
+#define PB0 0 // default PB idx
+#define TB0 0 // default TB idx
+#define TBUV0 0 // default TB idx for chroma
+
+#define NUM_SL_INTER 10
+#define NUM_SL_INTRA 8
+#endif
+
+/* maximum CB count in a LCB */
+#define MAX_CU_CNT_IN_LCU (MAX_CU_DIM/MIN_CU_DIM)
+/* pixel position to SCB position */
+#define PEL2SCU(pel) ((pel) >> MIN_CU_LOG2)
+
+#define PIC_PAD_SIZE_L (MAX_CU_SIZE + 16)
+#define PIC_PAD_SIZE_C (PIC_PAD_SIZE_L >> 1)
+
+#define NUM_AVS2_SPATIAL_MV 3
+#define NUM_SKIP_SPATIAL_MV 6
+#define MVPRED_L 0
+#define MVPRED_U 1
+#define MVPRED_UR 2
+#define MVPRED_xy_MIN 3
+
+/* for GOP 16 test, increase to 32 */
+/* maximum reference picture count. Originally, Max. 16 */
+/* for GOP 16 test, increase to 32 */
+#define MAX_NUM_REF_PICS 17
+
+#define MAX_NUM_ACTIVE_REF_FRAME 4
+
+/* DPB Extra size */
+#define EXTRA_FRAME MAX_NUM_REF_PICS
+
+/* maximum picture buffer size */
+#ifdef AML
+#define MAX_PB_SIZE (32)
+#else
+#define MAX_PB_SIZE (MAX_NUM_REF_PICS + EXTRA_FRAME)
+#endif
+/* Neighboring block availability flag bits */
+#define AVAIL_BIT_UP 0
+#define AVAIL_BIT_LE 1
+#define AVAIL_BIT_UP_LE 2
+
+/* Neighboring block availability flags */
+#define AVAIL_UP (1 << AVAIL_BIT_UP)
+#define AVAIL_LE (1 << AVAIL_BIT_LE)
+#define AVAIL_UP_LE (1 << AVAIL_BIT_UP_LE)
+
+/* MB availability check macro */
+#define IS_AVAIL(avail, pos) (((avail)&(pos)) == (pos))
+/* MB availability set macro */
+#define SET_AVAIL(avail, pos) (avail) |= (pos)
+/* MB availability remove macro */
+#define REM_AVAIL(avail, pos) (avail) &= (~(pos))
+/* MB availability into bit flag */
+#define GET_AVAIL_FLAG(avail, bit) (((avail)>>(bit)) & 0x1)
+
+/*****************************************************************************
+ * slice type
+ *****************************************************************************/
+#define SLICE_I COM_ST_I
+#define SLICE_P COM_ST_P
+#define SLICE_B COM_ST_B
+
+#define IS_INTRA_SLICE(slice_type) ((slice_type) == SLICE_I))
+#define IS_INTER_SLICE(slice_type) (((slice_type) == SLICE_P) || ((slice_type) == SLICE_B))
+
+/*****************************************************************************
+ * prediction mode
+ *****************************************************************************/
+#define MODE_INVALID -1
+#define MODE_INTRA 0
+#define MODE_INTER 1
+#define MODE_SKIP 2
+#define MODE_DIR 3
+#if USE_IBC
+#define MODE_IBC 4
+#endif
+
+/*****************************************************************************
+ * prediction direction
+ *****************************************************************************/
+typedef enum _INTER_PRED_DIR
+{
+ PRED_L0 = 0,
+ PRED_L1 = 1,
+ PRED_BI = 2,
+ PRED_DIR_NUM = 3,
+} INTER_PRED_DIR;
+
+#if BD_AFFINE_AMVR
+#define Tab_Affine_AMVR(x) ((x == 0) ? 2 : ((x == 1) ? 4 : 0) )
+#endif
+
+/*****************************************************************************
+ * skip / direct mode
+ *****************************************************************************/
+#define TRADITIONAL_SKIP_NUM (PRED_DIR_NUM + 1)
+#define ALLOWED_HMVP_NUM 8
+#define MAX_SKIP_NUM (TRADITIONAL_SKIP_NUM + ALLOWED_HMVP_NUM)
+
+#define UMVE_BASE_NUM 2
+#define UMVE_REFINE_STEP 5
+#define UMVE_MAX_REFINE_NUM (UMVE_REFINE_STEP * 4)
+#if UMVE_ENH
+#define UMVE_REFINE_STEP_SEC_SET 8
+#define UMVE_MAX_REFINE_NUM_SEC_SET (UMVE_REFINE_STEP_SEC_SET * 4)
+#endif
+
+#if AFFINE_UMVE
+#define AFFINE_UMVE_BASE_NUM AFF_MAX_NUM_MRG
+#define AFFINE_UMVE_REFINE_STEP 5
+#define AFFINE_UMVE_DIR 4
+#define AFFINE_UMVE_MAX_REFINE_NUM (AFFINE_UMVE_REFINE_STEP * AFFINE_UMVE_DIR)
+#endif
+
+#if AWP_MVR
+#define AWP_MVR_REFINE_STEP 5
+#define AWP_MVR_DIR 4
+#define AWP_MVR_MAX_REFINE_NUM (AWP_MVR_REFINE_STEP * AWP_MVR_DIR)
+#endif
+
+#if INTERPF
+#define MAX_INTER_SKIP_RDO (MAX_SKIP_NUM + NUM_RDO_INTER_FILTER)
+#else
+#define MAX_INTER_SKIP_RDO MAX_SKIP_NUM
+#endif
+
+#if EXT_AMVR_HMVP
+#define THRESHOLD_MVPS_CHECK 1.1
+#endif
+
+#if SUB_TMVP
+#define SBTMVP_MIN_SIZE 16
+#define SBTMVP_NUM 4
+#define SBTMVP_NUM_1D 2
+#endif
+
+/*****************************************************************************
+ * intra prediction direction
+ *****************************************************************************/
+#define IPD_DC 0
+#define IPD_PLN 1 /* Luma, Planar */
+#define IPD_BI 2 /* Luma, Bilinear */
+
+#define IPD_DM_C 0 /* Chroma, DM*/
+#define IPD_DC_C 1 /* Chroma, DC */
+#define IPD_HOR_C 2 /* Chroma, Horizontal*/
+#define IPD_VER_C 3 /* Chroma, Vertical */
+#define IPD_BI_C 4 /* Chroma, Bilinear */
+#if TSCPM
+#define IPD_TSCPM_C 5
+#if ENHANCE_TSPCM || PMC || EPMC
+#define IPD_TSCPM_L_C 6
+#define IPD_TSCPM_T_C 7
+#endif
+#endif
+
+#if PMC
+#define IPD_MCPM_C 8
+#define IPD_MCPM_L_C 9
+#define IPD_MCPM_T_C 10
+#endif
+#if PMC && EPMC
+#define IPD_EMCPM_C 11
+#define IPD_EMCPM_L_C 12
+#define IPD_EMCPM_T_C 13
+#define IPD_EMCPM2_C 14
+#define IPD_EMCPM2_L_C 15
+#define IPD_EMCPM2_T_C 16
+#elif EPMC
+#define IPD_EMCPM_C 8
+#define IPD_EMCPM_L_C 9
+#define IPD_EMCPM_T_C 10
+#define IPD_EMCPM2_C 11
+#define IPD_EMCPM2_L_C 12
+#define IPD_EMCPM2_T_C 13
+#endif
+#define IPD_CHROMA_CNT 5
+
+#define IPD_INVALID (-1)
+
+#define IPD_RDO_CNT 5
+
+#define IPD_HOR 24 /* Luma, Horizontal */
+#define IPD_VER 12 /* Luma, Vertical */
+#if EIPM
+#define IPD_CNT 66
+#define IPD_HOR_EXT 58
+#define IPD_VER_EXT 43
+#define IPD_DIA_R_EXT 50
+#define IPD_DIA_L_EXT 34
+#else
+#define IPD_CNT 33
+#endif
+#if IPCM
+#define IPD_IPCM 33
+#endif
+
+#define IPD_DIA_R 18 /* Luma, Right diagonal */
+#define IPD_DIA_L 3 /* Luma, Left diagonal */
+#define IPD_DIA_U 32 /* Luma, up diagonal */
+
+#if FIMC
+#define NUM_MPM 2 // Fixed for anchor
+#define CNTMPM_INIT_NUM NUM_MPM //
+#if EIPM
+#define CNTMPM_TABLE_LENGTH IPD_CNT // table length
+#else
+#define CNTMPM_TABLE_LENGTH (IPD_CNT + !!IPCM) // table length
+#endif
+#define CNTMPM_BASE_VAL 70 //
+#define CNTMPM_MAX_NUM CNTMPM_TABLE_LENGTH // Fixed for anchor
+#endif
+
+/*****************************************************************************
+* Transform
+*****************************************************************************/
+
+/*****************************************************************************
+ * reference index
+ *****************************************************************************/
+#define REFI_INVALID (-1)
+#define REFI_IS_VALID(refi) ((refi) >= 0)
+#define SET_REFI(refi, idx0, idx1) (refi)[REFP_0] = (idx0); (refi)[REFP_1] = (idx1)
+
+/*****************************************************************************
+ * macros for CU map
+
+ - [ 0: 6] : slice number (0 ~ 128)
+ - [ 7:14] : reserved
+ - [15:15] : 1 -> intra CU, 0 -> inter CU
+ - [16:22] : QP
+ - [23:23] : skip mode flag
+ - [24:24] : luma cbf
+ - [25:25] : ibc flag
+ - [26:30] : reserved
+ - [31:31] : 0 -> no encoded/decoded CU, 1 -> encoded/decoded CU
+ *****************************************************************************/
+/* set intra CU flag to map */
+#define MCU_SET_INTRA_FLAG(m) (m)=((m)|(1<<15))
+/* get intra CU flag from map */
+#define MCU_GET_INTRA_FLAG(m) (int)(((m)>>15) & 1)
+/* clear intra CU flag in map */
+#define MCU_CLEAR_INTRA_FLAG(m) (m)=((m) & 0xFFFF7FFF)
+
+/* set QP to map */
+#if CUDQP_PLATFORM_BUGFIX
+#define MCU_SET_QP(m, qp) (m)=((m&0xFF80FFFF)|((qp)&0x7F)<<16)
+#else
+#define MCU_SET_QP(m, qp) (m)=((m)|((qp)&0x7F)<<16)
+#endif
+/* get QP from map */
+#define MCU_GET_QP(m) (int)(((m)>>16)&0x7F)
+
+/* set skip mode flag */
+#define MCU_SET_SF(m) (m)=((m)|(1<<23))
+/* get skip mode flag */
+#define MCU_GET_SF(m) (int)(((m)>>23) & 1)
+/* clear skip mode flag */
+#define MCU_CLR_SF(m) (m)=((m) & (~(1<<23)))
+
+/* set cu cbf flag */
+#define MCU_SET_CBF(m) (m)=((m)|(1<<24))
+/* get cu cbf flag */
+#define MCU_GET_CBF(m) (int)(((m)>>24) & 1)
+/* clear cu cbf flag */
+#define MCU_CLR_CBF(m) (m)=((m) & (~(1<<24)))
+
+#if USE_IBC
+/* set ibc mode flag */
+#define MCU_SET_IBC(m) (m)=((m)|(1<<25))
+/* get ibc mode flag */
+#define MCU_GET_IBC(m) (int)(((m)>>25) & 1)
+/* clear ibc mode flag */
+#define MCU_CLR_IBC(m) (m)=((m) & (~(1<<25)))
+#endif
+
+/* set encoded/decoded flag of CU to map */
+#define MCU_SET_CODED_FLAG(m) (m)=((m)|(1<<31))
+/* get encoded/decoded flag of CU from map */
+#define MCU_GET_CODED_FLAG(m) (int)(((m)>>31) & 1)
+/* clear encoded/decoded CU flag to map */
+#define MCU_CLR_CODED_FLAG(m) (m)=((m) & 0x7FFFFFFF)
+
+/* multi bit setting: intra flag, encoded/decoded flag, slice number */
+#define MCU_SET_IF_COD_SN_QP(m, i, sn, qp) \
+ (m) = (((m)&0xFF807F80)|((sn)&0x7F)|((qp)<<16)|((i)<<15)|(1<<31))
+
+#define MCU_IS_COD_NIF(m) ((((m)>>15) & 0x10001) == 0x10000)
+
+#if BGC
+/*
+- [10:11] : bgc flag and bgc idx
+*/
+#define MCU_SET_BGC_FLAG(m) (m)=((m)|(1<<10))
+#define MCU_GET_BGC_FLAG(m) (int)(((m)>>10) & 1)
+#define MCU_CLR_BGC_FLAG(m) (m)=((m) & (~(1<<10)))
+#define MCU_SET_BGC_IDX(m) (m)=((m)|(1<<11))
+#define MCU_GET_BGC_IDX(m) (int)(((m)>>11) & 1)
+#define MCU_CLR_BGC_IDX(m) (m)=((m) & (~(1<<11)))
+#endif
+
+/*
+- [8:9] : affine vertex number, 00: 1(trans); 01: 2(affine); 10: 3(affine); 11: 4(affine)
+*/
+
+/* set affine CU mode to map */
+#define MCU_SET_AFF(m, v) (m)=((m & 0xFFFFFCFF)|((v)&0x03)<<8)
+/* get affine CU mode from map */
+#define MCU_GET_AFF(m) (int)(((m)>>8)&0x03)
+/* clear affine CU mode to map */
+#define MCU_CLR_AFF(m) (m)=((m) & 0xFFFFFCFF)
+
+/* set x scu offset & y scu offset relative to top-left scu of CU to map */
+#define MCU_SET_X_SCU_OFF(m, v) (m)=((m & 0xFFFF00FF)|((v)&0xFF)<<8)
+#define MCU_SET_Y_SCU_OFF(m, v) (m)=((m & 0xFF00FFFF)|((v)&0xFF)<<16)
+/* get x scu offset & y scu offset relative to top-left scu of CU in map */
+#define MCU_GET_X_SCU_OFF(m) (int)(((m)>>8)&0xFF)
+#define MCU_GET_Y_SCU_OFF(m) (int)(((m)>>16)&0xFF)
+
+/* set cu_width_log2 & cu_height_log2 to map */
+#define MCU_SET_LOGW(m, v) (m)=((m & 0xF0FFFFFF)|((v)&0x0F)<<24)
+#define MCU_SET_LOGH(m, v) (m)=((m & 0x0FFFFFFF)|((v)&0x0F)<<28)
+/* get cu_width_log2 & cu_height_log2 to map */
+#define MCU_GET_LOGW(m) (int)(((m)>>24)&0x0F)
+#define MCU_GET_LOGH(m) (int)(((m)>>28)&0x0F)
+
+#if BET_SPLIT_DECISION
+/* save to map_cu_mode*/
+#define MCU_SET_QT_DEPTH(m, v) (m)=((m & 0xFFFFFFF0)|((v)&0x0F)<<0)
+#define MCU_SET_BET_DEPTH(m, v) (m)=((m & 0xFFFFFF0F)|((v)&0x0F)<<4)
+#define MCU_GET_QT_DEPTH(m) (int)(((m)>>0)&0x0F)
+#define MCU_GET_BET_DEPTH(m) (int)(((m)>>4)&0x0F)
+#endif
+
+#if TB_SPLIT_EXT
+//set
+#define MCU_SET_TB_PART_LUMA(m,v) (m)=((m & 0xFFFFFF00)|((v)&0xFF)<<0 )
+//get
+#define MCU_GET_TB_PART_LUMA(m) (int)(((m)>>0 )&0xFF)
+#endif
+
+#if SBT
+//set
+#define MCU_SET_SBT_INFO(m,v) (m)=((m & 0xFFFF00FF)|((v)&0xFF)<<8 )
+//get
+#define MCU_GET_SBT_INFO(m) (int)(((m)>>8 )&0xFF)
+#endif
+
+#if USE_SP
+#define MSP_SET_SP_INFO(m) (m)=(m | 0x80)
+#define MSP_GET_SP_INFO(m) (int)(((m)>>7) & 1)
+#define MSP_CLR_SP_INFO(m) (m)=(m & 0x7F)
+#if EVS_UBVS_MODE
+#define MSP_SET_CS2_INFO(m) (m)=((m)|0x40)
+#define MSP_GET_CS2_INFO(m) (int)(((m)>>6) & 1)
+#define MSP_CLR_CS2_INFO(m) (m)=(m & 0xBF)
+#endif
+#endif
+
+typedef u32 SBAC_CTX_MODEL;
+#define NUM_POSITION_CTX 2
+#define NUM_SBAC_CTX_AFFINE_MVD_FLAG 2
+
+#if IIP
+#define NUM_IIP_CTX 1
+#endif
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SKIP_FLAG 4
+#else
+#define NUM_SBAC_CTX_SKIP_FLAG 3
+#endif
+#if USE_IBC
+#define NUM_SBAC_CTX_IBC_FLAG 3
+#endif
+#if USE_SP
+#define NUM_SOIF_CTX 1 ///< number of context models for SP or IBC flag coding
+#define NUM_GSF_CTX 1 ///< number of context models for SP flag coding
+#define NUM_SP_CDF_CTX 1 ///< number of context models for SP copy direction flag
+#define NUM_SP_IMF_CTX 1 ///< number of context models for SP is matched flag
+#if SP_CODE_TEXT_BUGFIX
+#define NUM_SP_STRLEN_CTX 4 ///< number of context models for SP matched length
+#else
+#define NUM_SP_STRLEN_CTX 3 ///< number of context models for SP matched length
+#endif
+#define NUM_SP_ABO_CTX 1 ///< number of context models for SP is above offset flag
+#define NUM_SP_OYZ_CTX 1 ///< number of context models for SP is offset Y Zero flag
+#define NUM_SP_OXZ_CTX 1 ///< number of context models for SP is offset X Zero flag
+#if !SP_CODE_TEXT_BUGFIX
+#define NUM_SP_SLF_CTX 1 ///< number of context models for SP whether using special length buffer flag
+#endif
+#define NUM_SP_NRF_CTX 1
+#define NUM_SP_NID_CTX (SP_RECENT_CANDS - 1)
+#define NUM_SP_PIMF_CTX 1 ///< number of context models for SP pixel is matched flag
+#if EVS_UBVS_MODE
+#define NUM_CS2F_CTX 1 ///< number of context models for CS2 flag coding
+#define NUM_SP_MODE_CTX 1
+#define NUM_SP_STRING_TYPE_CTX 1
+#define NUM_SP_STRING_SCAN_MODE_CTX 1
+#define NUM_SP_LOREF_MAX_LENGTH_CTX 4
+#define NUM_SP_SRB_FLAG_CTX 1
+#define NUM_SP_SRB_LOREFFLAG_CTX 1
+#define NUM_SP_SRB_TOPRUN_CTX 3
+#define NUM_SP_SRB_LEFTRUN_CTX 5
+#endif
+#endif
+#define NUM_SBAC_CTX_SKIP_IDX (MAX_SKIP_NUM - 1)
+
+#if ETMVP
+#define NUM_SBAC_CTX_ETMVP_IDX (MAX_ETMVP_NUM - 1)
+#define NUM_SBAC_CTX_ETMVP_FLAG 1
+#endif
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_DIRECT_FLAG 2
+#else
+#define NUM_SBAC_CTX_DIRECT_FLAG 1
+#endif
+#if INTERPF
+#define NUM_SBAC_CTX_INTERPF 2
+#endif
+#define NUM_SBAC_CTX_UMVE_BASE_IDX 1
+#define NUM_SBAC_CTX_UMVE_STEP_IDX 1
+#define NUM_SBAC_CTX_UMVE_DIR_IDX 2
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SPLIT_FLAG 4
+#else
+#define NUM_SBAC_CTX_SPLIT_FLAG 3
+#endif
+#define NUM_SBAC_CTX_SPLIT_MODE 3
+#define NUM_SBAC_CTX_BT_SPLIT_FLAG 9
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SPLIT_DIR 5
+#else
+#define NUM_SBAC_CTX_SPLIT_DIR 3
+#endif
+#define NUM_QT_CBF_CTX 3 /* number of context models for QT CBF */
+#if SEP_CONTEXT
+#define NUM_CTP_ZERO_FLAG_CTX 2 /* number of context models for ctp_zero_flag */
+#define NUM_PRED_MODE_CTX 6 /* number of context models for prediction mode */
+#else
+#define NUM_CTP_ZERO_FLAG_CTX 1 /* number of context models for ctp_zero_flag */
+#define NUM_PRED_MODE_CTX 5 /* number of context models for prediction mode */
+#endif
+#if MODE_CONS
+#define NUM_CONS_MODE_CTX 1 /* number of context models for constrained prediction mode */
+#endif
+#define NUM_TB_SPLIT_CTX 1
+#if SBT
+#define NUM_SBAC_CTX_SBT_INFO 7
+#endif
+#if CUDQP
+#define NUM_SBAC_CTX_CU_QP_DELTA_ABS 4
+#endif
+
+#define NUM_SBAC_CTX_DELTA_QP 4
+
+#if SEP_CONTEXT
+#define NUM_INTER_DIR_CTX 3 /* number of context models for inter prediction direction */
+#else
+#define NUM_INTER_DIR_CTX 2 /* number of context models for inter prediction direction */
+#endif
+#define NUM_REFI_CTX 3
+
+#define NUM_MVR_IDX_CTX (MAX_NUM_MVR - 1)
+#if IBC_ABVR
+#define NUM_BVR_IDX_CTX (MAX_NUM_BVR - 1)
+#endif
+#if IBC_BVP
+#define NUM_BVP_IDX_CTX (MAX_NUM_BVP - 1)
+#endif
+#if BVD_CODING
+#define NUM_BV_RES_CTX 8 /* number of context models for block vector difference */
+#endif
+#if BD_AFFINE_AMVR
+#define NUM_AFFINE_MVR_IDX_CTX (MAX_NUM_AFFINE_MVR - 1)
+#endif
+#if SIBC
+#define NUM_SIBC_IDX_CTX 2
+#endif
+
+#if EXT_AMVR_HMVP
+#define NUM_EXTEND_AMVR_FLAG 1
+#endif
+#define NUM_MV_RES_CTX 3 /* number of context models for motion vector difference */
+
+#if PMC && EPMC
+#define NUM_INTRA_DIR_CTX 14
+#elif PMC || EPMC
+#define NUM_INTRA_DIR_CTX 13
+#else
+#if EIPM
+#if TSCPM
+#if ENHANCE_TSPCM
+#define NUM_INTRA_DIR_CTX 12
+#else
+#define NUM_INTRA_DIR_CTX 11
+#endif
+#else
+#define NUM_INTRA_DIR_CTX 10
+#endif
+#else
+#if TSCPM
+#if ENHANCE_TSPCM
+#define NUM_INTRA_DIR_CTX 11
+#else
+#define NUM_INTRA_DIR_CTX 10
+#endif
+#else
+#define NUM_INTRA_DIR_CTX 9
+#endif
+#endif
+#endif
+
+#define NUM_SBAC_CTX_AFFINE_FLAG 1
+#define NUM_SBAC_CTX_AFFINE_MRG AFF_MAX_NUM_MRG - 1
+
+#if AWP
+#define NUM_SBAC_CTX_AWP_FLAG 1
+#define NUM_SBAC_CTX_AWP_IDX 2
+#endif
+
+#if SMVD
+#define NUM_SBAC_CTX_SMVD_FLAG 1
+#endif
+
+#if DT_SYNTAX
+#define NUM_SBAC_CTX_PART_SIZE 6
+#endif
+
+#define NUM_SAO_MERGE_FLAG_CTX 3
+#define NUM_SAO_MODE_CTX 1
+#define NUM_SAO_OFFSET_CTX 1
+
+#define NUM_ALF_COEFF_CTX 1
+#define NUM_ALF_LCU_CTX 1
+
+#if ESAO
+#define NUM_ESAO_LCU_CTX 1
+#define NUM_ESAO_OFFSET_CTX 1
+#define NUM_ESAO_UV_COUNT_CTX 1
+#endif
+
+#if CCSAO
+#define NUM_CCSAO_LCU_CTX 1
+#define NUM_CCSAO_OFFSET_CTX 1
+#endif
+
+#if SRCC
+/* Scan-Region based coefficient coding (SRCC) (START) */
+#define LOG2_CG_SIZE 4
+
+#define NUM_PREV_0VAL 5
+#define NUM_PREV_12VAL 5
+
+#define SCAN_REGION_GROUP 14
+
+#define NUM_CTX_SCANR_LUMA 25
+#define NUM_CTX_SCANR_CHROMA 3
+#define NUM_CTX_SCANR (NUM_CTX_SCANR_LUMA + NUM_CTX_SCANR_CHROMA)
+
+#define NUM_CTX_GT0_LUMA 51
+#define NUM_CTX_GT0_LUMA_TU 17
+
+#define NUM_CTX_GT0_CHROMA 9 /* number of context models for chroma gt0 flag */
+#define NUM_CTX_GT0 (NUM_CTX_GT0_LUMA + NUM_CTX_GT0_CHROMA) /* number of context models for gt0 flag */
+
+#define NUM_CTX_GT1_LUMA 17
+#define NUM_CTX_GT1_CHROMA 5
+#define NUM_CTX_GT1 (NUM_CTX_GT1_LUMA + NUM_CTX_GT1_CHROMA) /* number of context models for gt1/2 flag */
+
+/* Scan-Region based coefficient coding (SRCC) (END) */
+#endif
+
+#if ETS
+#define NUM_ETS_IDX_CTX 1
+#endif
+
+#if EST
+#define NUM_EST_IDX_CTX 1
+#endif
+
+#if ST_CHROMA
+#define NUM_ST_CHROMA_IDX_CTX 1
+#endif
+
+#define RANK_NUM 6
+#define NUM_SBAC_CTX_LEVEL (RANK_NUM * 4)
+#define NUM_SBAC_CTX_RUN (RANK_NUM * 4)
+
+#define NUM_SBAC_CTX_RUN_RDOQ (RANK_NUM * 4)
+
+#define NUM_SBAC_CTX_LAST1 RANK_NUM
+#define NUM_SBAC_CTX_LAST2 12
+
+#define NUM_SBAC_CTX_LAST 2
+
+/* context models for arithmetic coding */
+typedef struct _COM_SBAC_CTX
+{
+ SBAC_CTX_MODEL skip_flag [NUM_SBAC_CTX_SKIP_FLAG];
+#if USE_IBC
+ SBAC_CTX_MODEL ibc_flag [NUM_SBAC_CTX_IBC_FLAG];
+#endif
+#if USE_SP
+ SBAC_CTX_MODEL sp_or_ibc_flag [NUM_SOIF_CTX];
+ SBAC_CTX_MODEL sp_flag [NUM_GSF_CTX];
+ SBAC_CTX_MODEL sp_copy_direct_flag[NUM_SP_CDF_CTX];
+ SBAC_CTX_MODEL sp_is_matched_flag[NUM_SP_IMF_CTX];
+ SBAC_CTX_MODEL sp_string_length[NUM_SP_STRLEN_CTX];
+ SBAC_CTX_MODEL sp_above_offset [NUM_SP_ABO_CTX];
+ SBAC_CTX_MODEL sp_offset_y_zero[NUM_SP_OYZ_CTX];
+ SBAC_CTX_MODEL sp_offset_x_zero[NUM_SP_OXZ_CTX];
+#if !SP_CODE_TEXT_BUGFIX
+ SBAC_CTX_MODEL sp_special_len_flag[NUM_SP_SLF_CTX];
+#endif
+ SBAC_CTX_MODEL sp_n_recent_flag[NUM_SP_NRF_CTX];
+ SBAC_CTX_MODEL sp_n_index [NUM_SP_NID_CTX];
+#if SP_SLR
+ SBAC_CTX_MODEL sp_pixel_is_matched_flag[NUM_SP_PIMF_CTX];
+#endif
+#if EVS_UBVS_MODE
+ SBAC_CTX_MODEL sp_cs2_flag[NUM_CS2F_CTX];
+ SBAC_CTX_MODEL sp_mode_context[NUM_SP_MODE_CTX];
+ SBAC_CTX_MODEL sp_str_type_context[NUM_SP_STRING_TYPE_CTX];
+ SBAC_CTX_MODEL sp_str_scanmode_context[NUM_SP_STRING_SCAN_MODE_CTX];
+ SBAC_CTX_MODEL sp_lo_ref_maxlength_context[NUM_SP_LOREF_MAX_LENGTH_CTX];
+ //For SRB
+ SBAC_CTX_MODEL sp_evs_present_flag_context[NUM_SP_SRB_FLAG_CTX];
+ SBAC_CTX_MODEL sp_SRB_lo_ref_color_flag_context[NUM_SP_SRB_LOREFFLAG_CTX];
+ SBAC_CTX_MODEL sp_SRB_copy_toprun_context[NUM_SP_SRB_TOPRUN_CTX];
+#endif
+#endif
+ SBAC_CTX_MODEL skip_idx_ctx [NUM_SBAC_CTX_SKIP_IDX];
+ SBAC_CTX_MODEL direct_flag [NUM_SBAC_CTX_DIRECT_FLAG];
+#if INTERPF
+ SBAC_CTX_MODEL inter_filter_flag[NUM_SBAC_CTX_INTERPF];
+#endif
+#if BGC
+ SBAC_CTX_MODEL bgc_flag;
+ SBAC_CTX_MODEL bgc_idx;
+#endif
+#if AWP
+ SBAC_CTX_MODEL umve_awp_flag;
+#else
+ SBAC_CTX_MODEL umve_flag;
+#endif
+ SBAC_CTX_MODEL umve_base_idx [NUM_SBAC_CTX_UMVE_BASE_IDX];
+ SBAC_CTX_MODEL umve_step_idx [NUM_SBAC_CTX_UMVE_STEP_IDX];
+ SBAC_CTX_MODEL umve_dir_idx [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#if AFFINE_UMVE
+ SBAC_CTX_MODEL affine_umve_flag;
+ SBAC_CTX_MODEL affine_umve_step_idx [NUM_SBAC_CTX_UMVE_STEP_IDX];
+ SBAC_CTX_MODEL affine_umve_dir_idx [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#endif
+ SBAC_CTX_MODEL inter_dir [NUM_INTER_DIR_CTX];
+ SBAC_CTX_MODEL intra_dir [NUM_INTRA_DIR_CTX];
+ SBAC_CTX_MODEL pred_mode [NUM_PRED_MODE_CTX];
+#if MODE_CONS
+ SBAC_CTX_MODEL cons_mode [NUM_CONS_MODE_CTX];
+#endif
+#if IIP
+ SBAC_CTX_MODEL iip_flag [NUM_IIP_CTX];
+#endif
+ SBAC_CTX_MODEL ipf_flag [NUM_IPF_CTX];
+ SBAC_CTX_MODEL refi [NUM_REFI_CTX];
+ SBAC_CTX_MODEL mvr_idx [NUM_MVR_IDX_CTX];
+#if IBC_ABVR
+ SBAC_CTX_MODEL bvr_idx [NUM_BVR_IDX_CTX];
+#endif
+#if BD_AFFINE_AMVR
+ SBAC_CTX_MODEL affine_mvr_idx [NUM_AFFINE_MVR_IDX_CTX];
+#endif
+#if EXT_AMVR_HMVP
+ SBAC_CTX_MODEL mvp_from_hmvp_flag[NUM_EXTEND_AMVR_FLAG];
+#endif
+#if IBC_BVP
+ SBAC_CTX_MODEL cbvp_idx[NUM_BVP_IDX_CTX];
+#endif
+#if SIBC
+ SBAC_CTX_MODEL sibc_flag [NUM_SIBC_IDX_CTX];
+#endif
+#if BVD_CODING
+ SBAC_CTX_MODEL bvd [2][NUM_BV_RES_CTX];
+#endif
+ SBAC_CTX_MODEL mvd [2][NUM_MV_RES_CTX];
+ SBAC_CTX_MODEL ctp_zero_flag [NUM_CTP_ZERO_FLAG_CTX];
+ SBAC_CTX_MODEL cbf [NUM_QT_CBF_CTX];
+#if CUDQP
+ SBAC_CTX_MODEL cu_qp_delta_abs [NUM_SBAC_CTX_CU_QP_DELTA_ABS];
+#endif
+ SBAC_CTX_MODEL tb_split [NUM_TB_SPLIT_CTX];
+#if SBT
+ SBAC_CTX_MODEL sbt_info [NUM_SBAC_CTX_SBT_INFO];
+#endif
+#if SRCC
+ SBAC_CTX_MODEL cc_gt0 [NUM_CTX_GT0];
+ SBAC_CTX_MODEL cc_gt1 [NUM_CTX_GT1];
+ SBAC_CTX_MODEL cc_scanr_x [NUM_CTX_SCANR];
+ SBAC_CTX_MODEL cc_scanr_y [NUM_CTX_SCANR];
+#endif
+ SBAC_CTX_MODEL run [NUM_SBAC_CTX_RUN];
+ SBAC_CTX_MODEL run_rdoq [NUM_SBAC_CTX_RUN];
+ SBAC_CTX_MODEL last1 [NUM_SBAC_CTX_LAST1 * 2];
+ SBAC_CTX_MODEL last2 [NUM_SBAC_CTX_LAST2 * 2 - 2];
+ SBAC_CTX_MODEL level [NUM_SBAC_CTX_LEVEL];
+ SBAC_CTX_MODEL split_flag [NUM_SBAC_CTX_SPLIT_FLAG];
+ SBAC_CTX_MODEL bt_split_flag [NUM_SBAC_CTX_BT_SPLIT_FLAG];
+ SBAC_CTX_MODEL split_dir [NUM_SBAC_CTX_SPLIT_DIR];
+ SBAC_CTX_MODEL split_mode [NUM_SBAC_CTX_SPLIT_MODE];
+ SBAC_CTX_MODEL affine_flag [NUM_SBAC_CTX_AFFINE_FLAG];
+ SBAC_CTX_MODEL affine_mrg_idx [NUM_SBAC_CTX_AFFINE_MRG];
+#if ETMVP
+ SBAC_CTX_MODEL etmvp_flag[NUM_SBAC_CTX_ETMVP_FLAG];
+ SBAC_CTX_MODEL etmvp_idx[NUM_SBAC_CTX_ETMVP_IDX];
+#endif
+#if AWP
+ SBAC_CTX_MODEL awp_flag [NUM_SBAC_CTX_AWP_FLAG];
+ SBAC_CTX_MODEL awp_idx [NUM_SBAC_CTX_AWP_IDX];
+#endif
+#if AWP_MVR
+ SBAC_CTX_MODEL awp_mvr_flag;
+ SBAC_CTX_MODEL awp_mvr_step_idx[NUM_SBAC_CTX_UMVE_STEP_IDX];
+ SBAC_CTX_MODEL awp_mvr_dir_idx [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#endif
+#if SMVD
+ SBAC_CTX_MODEL smvd_flag [NUM_SBAC_CTX_SMVD_FLAG];
+#endif
+#if DT_SYNTAX
+ SBAC_CTX_MODEL part_size [NUM_SBAC_CTX_PART_SIZE];
+#endif
+#if ETS
+ SBAC_CTX_MODEL ets_flag [NUM_ETS_IDX_CTX];
+#endif
+#if EST
+ SBAC_CTX_MODEL est_flag [NUM_EST_IDX_CTX];
+#endif
+#if ST_CHROMA
+ SBAC_CTX_MODEL st_chroma_flag[NUM_ST_CHROMA_IDX_CTX];
+#endif
+
+ SBAC_CTX_MODEL sao_merge_flag [NUM_SAO_MERGE_FLAG_CTX];
+ SBAC_CTX_MODEL sao_mode [NUM_SAO_MODE_CTX];
+ SBAC_CTX_MODEL sao_offset [NUM_SAO_OFFSET_CTX];
+ SBAC_CTX_MODEL alf_lcu_enable [NUM_ALF_LCU_CTX];
+ SBAC_CTX_MODEL delta_qp [NUM_SBAC_CTX_DELTA_QP];
+#if ESAO
+ SBAC_CTX_MODEL esao_lcu_enable [NUM_ESAO_LCU_CTX];
+ SBAC_CTX_MODEL esao_offset [NUM_ESAO_OFFSET_CTX];
+ SBAC_CTX_MODEL esao_chroma_mode_flag[NUM_ESAO_UV_COUNT_CTX];
+#endif
+#if CCSAO
+ SBAC_CTX_MODEL ccsao_lcu_flag [NUM_CCSAO_LCU_CTX];
+ SBAC_CTX_MODEL ccsao_offset [NUM_CCSAO_OFFSET_CTX];
+#endif
+} COM_SBAC_CTX;
+
+#define COEF_SCAN_ZIGZAG 0
+#define COEF_SCAN_TYPE_NUM 1
+
+/* Maximum transform dynamic range (excluding sign bit) */
+#define MAX_TX_DYNAMIC_RANGE 15
+#if SRCC
+#define MAX_TX_VAL ((1 << MAX_TX_DYNAMIC_RANGE) - 1)
+#define MIN_TX_VAL (-(1 << MAX_TX_DYNAMIC_RANGE))
+#endif
+
+#define QUANT_SHIFT 14
+
+/* neighbor CUs
+ neighbor position:
+
+ D B C
+
+ A X,<G>
+
+ E <F>
+*/
+#define MAX_NEB 5
+#define NEB_A 0 /* left */
+#define NEB_B 1 /* up */
+#define NEB_C 2 /* up-right */
+#define NEB_D 3 /* up-left */
+#define NEB_E 4 /* low-left */
+
+#define NEB_F 5 /* co-located of low-right */
+#define NEB_G 6 /* co-located of X */
+#define NEB_X 7 /* center (current block) */
+#define NEB_H 8 /* right */
+#define NEB_I 9 /* low-right */
+#define MAX_NEB2 10
+
+/* SAO_AVS2(START) */
+typedef enum _SAO_MODE //mode
+{
+ SAO_MODE_OFF = 0,
+ SAO_MODE_MERGE,
+ SAO_MODE_NEW,
+ NUM_SAO_MODES
+} SAO_MODE;
+
+typedef enum _SAO_MODE_MERGE_TYPE
+{
+ SAO_MERGE_LEFT = 0,
+ SAO_MERGE_ABOVE,
+ NUM_SAO_MERGE_TYPES
+} SAO_MODE_MERGE_TYPE;
+
+typedef enum _SAO_MODE_NEW_TYPE //NEW: types
+{
+ SAO_TYPE_EO_0,
+ SAO_TYPE_EO_90,
+ SAO_TYPE_EO_135,
+ SAO_TYPE_EO_45,
+ SAO_TYPE_BO,
+ NUM_SAO_NEW_TYPES
+} SAO_MODE_NEW_TYPE;
+
+typedef enum _SAO_EO_CLASS // EO Groups, the assignments depended on how you implement the edgeType calculation
+{
+ SAO_CLASS_EO_FULL_VALLEY = 0,
+ SAO_CLASS_EO_HALF_VALLEY = 1,
+ SAO_CLASS_EO_PLAIN = 2,
+ SAO_CLASS_EO_HALF_PEAK = 3,
+ SAO_CLASS_EO_FULL_PEAK = 4,
+ SAO_CLASS_BO = 5,
+ NUM_SAO_EO_CLASSES = SAO_CLASS_BO,
+ NUM_SAO_OFFSET
+} SAO_EO_CLASS;
+
+typedef struct _SAO_STAT_DATA
+{
+ long long int diff[MAX_NUM_SAO_CLASSES];
+ int count[MAX_NUM_SAO_CLASSES];
+} SAO_STAT_DATA;
+
+typedef struct _SAO_BLK_PARAM
+{
+ int mode_idc; //NEW, MERGE, OFF
+ int type_idc; //NEW: EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, above
+ int start_band; //BO: starting band index
+ int start_band2;
+ int delta_band;
+ int offset[MAX_NUM_SAO_CLASSES];
+} SAO_BLK_PARAM;
+/* SAO_AVS2(END) */
+
+#if DBR
+typedef struct _DBR_PARAM
+{
+ int dbr_horizontal_enabled;
+ int thresh_horizontal_index;
+ int horizontal_offsets[6];
+ int dbr_vertical_enabled;
+ int thresh_vertical_index;
+ int vertical_offsets[6];
+} DBR_PARAM;
+#endif
+
+#if ESAO
+/* ESAO_AVS3(START) */
+typedef struct _ESAO_STAT_DATA
+{
+ long long diff[ESAO_LABEL_CLASSES_MAX];
+ int count[ESAO_LABEL_CLASSES_MAX];
+} ESAO_STAT_DATA;
+
+typedef struct _ESAO_BLK_PARAM
+{
+ int offset[ESAO_LABEL_CLASSES_MAX];
+ int *lcu_flag;
+}ESAO_BLK_PARAM;
+
+typedef struct _ESAO_FUNC_POINTER
+{
+ void (*esao_on_block_for_luma)(pel* p_dst, int i_dst, pel * p_src, int i_src, int i_block_w, int i_block_h, int bit_depth, int bo_value, const int *esao_offset, int lcu_available_left, int lcu_available_right,
+ int lcu_available_up, int lcu_available_down, int lcu_available_upleft, int lcu_available_upright, int lcu_available_leftdown, int lcu_available_rightdwon, int luma_type);
+ void (*esao_on_block_for_chroma)(pel * p_dst, int i_dst, pel * p_src, int i_src, int i_block_w, int i_block_h, int bo_value, int shift_value, int bit_depth, const int *esao_offset);
+}ESAO_FUNC_POINTER;
+/* ESAO_AVS3(END) */
+#endif
+
+#if CCSAO
+/* CCSAO_AVS3(START) */
+typedef struct
+{
+ long long diff [CCSAO_CLASS_NUM];
+ int count[CCSAO_CLASS_NUM];
+}CCSAO_STAT_DATA;
+
+#if CCSAO_ENHANCEMENT
+typedef struct
+{
+ long long diff [CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+ int count[CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+}CCSAO_REFINE_DATA;
+
+typedef struct
+{
+ int lcu_pos;
+ double lcu_cost;
+}CCSAO_LCU_COST;
+
+typedef struct
+{
+ BOOL en;
+ int set;
+ int cnt;
+}CCSAO_SET_CNT;
+
+typedef struct
+{
+ int set_num;
+ int type [CCSAO_SET_NUM];
+ int mode [CCSAO_SET_NUM];
+ int mode_c[CCSAO_SET_NUM];
+ int offset[CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+ int *lcu_flag;
+}CCSAO_BLK_PARAM;
+#else
+typedef struct
+{
+ int type;
+ int mode;
+ int offset[CCSAO_CLASS_NUM];
+ int *lcu_flag;
+}CCSAO_BLK_PARAM;
+#endif
+
+typedef struct
+{
+ void(*ccsao_on_block_for_chroma)(pel *p_dst, int i_dst, pel *p_src, int i_src,
+#if CCSAO_ENHANCEMENT
+ pel *p_src2, int i_src2,
+#endif
+ int lcu_width_c, int lcu_height_c, int bit_depth, int type, int band_num,
+#if CCSAO_ENHANCEMENT
+ int band_num_c,
+#endif
+ const int *ccsao_offset,
+ int lcu_available_left, int lcu_available_right, int lcu_available_up, int lcu_available_down, int lcu_available_upleft, int lcu_available_upright, int lcu_available_leftdown, int lcu_available_rightdwon);
+}CCSAO_FUNC_POINTER;
+/* CCSAO_AVS3(END) */
+#endif
+
+/* ALF_AVS2(START) */
+typedef struct _ALF_PARAM
+{
+ int alf_flag;
+ int num_coeff;
+ int filters_per_group;
+#if ALF_IMP
+ int dir_index;
+ int max_filter_num;
+#endif
+ int component_id;
+#ifdef AML
+ int32_t filter_pattern[NO_VAR_BINS];
+ int32_t coeff_multi[NO_VAR_BINS][ALF_MAX_NUM_COEF];
+#else
+ int *filter_pattern;
+ int **coeff_multi;
+#endif
+} ALF_PARAM;
+
+typedef struct _ALF_CORR_DATA
+{
+ double ***E_corr; //!< auto-correlation matrix
+ double **y_corr; //!< cross-correlation
+ double *pix_acc;
+ int component_id;
+} ALF_CORR_DATA;
+/* ALF_AVS2(END) */
+
+#ifdef AML
+typedef struct avs3_frame_s{
+#if 0
+ int32_t imgcoi_ref;
+ byte **referenceFrame[3];
+ int32_t **refbuf;
+ int32_t ** *mvbuf;
+ double saorate[NUM_SAO_COMPONENTS];
+ byte ** *ref;
+
+ int32_t imgtr_fwRefDistance;
+ int32_t refered_by_others;
+ int32_t is_output;
+#if M3480_TEMPORAL_SCALABLE
+ int32_t temporal_id; //temporal level setted in configure file
+#endif
+ byte **oneForthRefY;
+#if FIX_MAX_REF
+ int32_t ref_poc[MAXREF];
+#else
+ int32_t ref_poc[4];
+#endif
+#endif
+ int index;
+ int used;
+ u32 mmu_alloc_flag;
+ u32 lcu_size_log2;
+ u32 header_adr;
+ u32 header_dw_adr;
+ u32 mc_y_adr;
+ u32 mc_u_v_adr;
+ u32 mc_canvas_y;
+ u32 mc_canvas_u_v;
+ u32 mpred_mv_wr_start_addr;
+ u8 bg_flag;
+ u32 refered_by_others;
+ u32 is_output;
+ int vf_ref;
+ u8 slice_type;
+ int list0_num_refp;
+ int list0_ptr[MAX_NUM_REF_PICS];
+ int backend_ref;
+#ifdef NEW_FB_CODE
+ unsigned char back_done_mark;
+ //unsigned char flush_mark;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+ int list0_index[MAX_NUM_REF_PICS];
+ int list1_num_refp;
+ int list1_index[MAX_NUM_REF_PICS];
+ int width;
+ int height;
+ int depth;
+#endif
+#ifdef AML
+ int error_mark;
+ int32_t decoded_lcu;
+
+ unsigned long cma_alloc_addr;
+ int buf_size;
+ int BUF_index;
+ int lcu_total;
+ int comp_body_size;
+ uint32_t dw_y_adr;
+ uint32_t dw_u_v_adr;
+ unsigned long dw_header_adr;
+ int y_canvas_index;
+ int uv_canvas_index;
+ struct canvas_config_s canvas_config[2];
+ int double_write_mode;
+
+ u32 stream_offset;
+ u32 pts;
+ u64 pts64;
+ /* picture qos information*/
+ struct vframe_qos_s vqos;
+
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
+ char *cuva_data_buf;
+ int cuva_data_size;
+ bool in_dpb;
+ u64 time;
+ s32 poc;
+ u32 hw_front_decode_time;
+ struct vdec_info vinfo;
+ u32 stream_size; // For stream base mode
+#endif
+#ifdef OW_TRIPLE_WRITE
+ unsigned int tw_y_adr;
+ unsigned int tw_u_v_adr;
+
+ //int tw_y_canvas_index;
+ //int tw_uv_canvas_index;
+ struct canvas_config_s tw_canvas_config[2];
+
+ u32 triple_write_mode;
+#endif
+} avs3_frame_t;
+#endif
+/* picture store structure */
+typedef struct _COM_PIC
+{
+ /* Start address of Y component (except padding) */
+ pel *y;
+ /* Start address of U component (except padding) */
+ pel *u;
+ /* Start address of V component (except padding) */
+ pel *v;
+#if EVS_UBVS_MODE
+ /* Start address of U component format 444 (except padding) */
+ pel *u444;
+ /* Start address of V component format 444 (except padding) */
+ pel *v444;
+#endif
+ /* Stride of luma picture */
+ int stride_luma;
+ /* Stride of chroma picture */
+ int stride_chroma;
+ /* Width of luma picture */
+ int width_luma;
+ /* Height of luma picture */
+ int height_luma;
+ /* Width of chroma picture */
+ int width_chroma;
+ /* Height of chroma picture */
+ int height_chroma;
+ /* padding size of luma */
+ int padsize_luma;
+ /* padding size of chroma */
+ int padsize_chroma;
+ /* image buffer */
+ COM_IMGB *imgb;
+ /* decoding temporal reference of this picture */
+ int dtr;
+ /* presentation temporal reference of this picture */
+ int ptr;
+ int picture_output_delay;
+ /* 0: not used for reference buffer, reference picture type */
+ u8 is_ref;
+ /* needed for output? */
+ u8 need_for_out;
+ /* scalable layer id */
+ u8 temporal_id;
+ s16 (*map_mv)[REFP_NUM][MV_D];
+ s8 (*map_refi)[REFP_NUM];
+#if ETMVP || SUB_TMVP || AWP
+ u32 list_ptr[REFP_NUM][MAX_NUM_REF_PICS];
+#else
+ u32 list_ptr[MAX_NUM_REF_PICS];
+#endif
+#ifdef AML
+ avs3_frame_t buf_cfg;
+#endif
+} COM_PIC;
+
+#if LIBVC_ON
+#define MAX_NUM_COMPONENT 3
+#define MAX_NUM_LIBPIC 16
+#define MAX_CANDIDATE_PIC 256
+#define MAX_DIFFERENCE_OF_RLPIC_AND_LIBPIC 1.7e+308; ///< max. value of Double-type value
+
+typedef struct _PIC_HIST_FEATURE
+{
+ int num_component;
+ int num_of_hist_interval;
+ int length_of_interval;
+ int * list_hist_feature[MAX_NUM_COMPONENT];
+} PIC_HIST_FEATURE;
+
+// ====================================================================================================================
+// Information of libpic
+// ====================================================================================================================
+
+typedef struct _LibVCData
+{
+ int num_candidate_pic;
+ int list_poc_of_candidate_pic[MAX_CANDIDATE_PIC]; // for now, the candidate set contain only pictures from input sequence.
+ COM_IMGB * list_candidate_pic[MAX_CANDIDATE_PIC];
+ PIC_HIST_FEATURE list_hist_feature_of_candidate_pic[MAX_CANDIDATE_PIC];
+
+ int num_lib_pic;
+ int list_poc_of_libpic[MAX_NUM_LIBPIC];
+
+ COM_PIC * list_libpic_outside[MAX_NUM_LIBPIC];
+ int num_libpic_outside;
+ int list_library_index_outside[MAX_NUM_LIBPIC];
+
+ int num_RLpic;
+ int list_poc_of_RLpic[MAX_CANDIDATE_PIC];
+ int list_libidx_for_RLpic[MAX_CANDIDATE_PIC]; //the idx of library picture instead of poc of library picture in origin sequence is set as new poc.
+
+ int bits_dependencyFile;
+ int bits_libpic;
+
+ int library_picture_enable_flag;
+#if IPPPCRR
+#if LIB_PIC_UPDATE
+ int lib_pic_update;
+ int update;
+ int countRL;
+ int encode_skip;
+ int end_of_intra_period;
+#else
+ int first_pic_as_libpic;
+#endif
+#endif
+ int is_libpic_processing;
+ int is_libpic_prepared;
+#if CRR_ENC_OPT_CFG
+ int lib_in_l0, lib_in_l1, pb_ref_lib, rl_ref_lib, max_list_refnum;
+ int libpic_idx;
+#endif
+
+} LibVCData;
+#endif
+
+/*****************************************************************************
+ * picture buffer allocator
+ *****************************************************************************/
+typedef struct _PICBUF_ALLOCATOR
+{
+ /* width */
+ int width;
+ /* height */
+ int height;
+ /* pad size for luma */
+ int pad_l;
+ /* pad size for chroma */
+ int pad_c;
+ /* arbitrary data, if needs */
+ int ndata[4];
+ /* arbitrary address, if needs */
+ void *pdata[4];
+} PICBUF_ALLOCATOR;
+
+/*****************************************************************************
+ * picture manager for DPB in decoder and RPB in encoder
+ *****************************************************************************/
+typedef struct _COM_PM
+{
+ /* picture store (including reference and non-reference) */
+ COM_PIC *pic[MAX_PB_SIZE];
+ /* address of reference pictures */
+ COM_PIC *pic_ref[MAX_NUM_REF_PICS];
+ /* maximum reference picture count */
+ int max_num_ref_pics;
+ /* current count of available reference pictures in PB */
+ int cur_num_ref_pics;
+ /* number of reference pictures */
+ int num_refp[REFP_NUM];
+ /* next output POC */
+ int ptr_next_output;
+ /* POC increment */
+ int ptr_increase;
+ /* max number of picture buffer */
+ int max_pb_size;
+ /* current picture buffer size */
+ int cur_pb_size;
+ /* address of leased picture for current decoding/encoding buffer */
+ COM_PIC *pic_lease;
+ /* picture buffer allocator */
+ PICBUF_ALLOCATOR pa;
+#if LIBVC_ON
+ /* information for LibVC */
+ LibVCData *libvc_data;
+ int is_library_buffer_empty;
+ COM_PIC *pb_libpic; //buffer for libpic
+ int cur_libpb_size;
+ int pb_libpic_library_index;
+#endif
+/*AML*/
+ void *hw;
+ spinlock_t pm_lock;
+/**/
+} COM_PM;
+
+/* reference picture structure */
+typedef struct _COM_REFP
+{
+ /* address of reference picture */
+ COM_PIC *pic;
+ /* PTR of reference picture */
+ int ptr;
+ s16 (*map_mv)[REFP_NUM][MV_D];
+ s8 (*map_refi)[REFP_NUM];
+#if ETMVP || SUB_TMVP || AWP
+ u32 (*list_ptr)[MAX_NUM_REF_PICS];
+#else
+ u32 *list_ptr;
+#endif
+#if LIBVC_ON
+ int is_library_picture;
+#endif
+} COM_REFP;
+
+typedef struct _COM_MOTION
+{
+ s16 mv[REFP_NUM][MV_D];
+ s8 ref_idx[REFP_NUM];
+} COM_MOTION;
+
+/*****************************************************************************
+ * chunk header
+ *****************************************************************************/
+typedef struct _COM_CNKH
+{
+ /* version: 3bit */
+ int ver;
+ /* chunk type: 4bit */
+ int ctype;
+ /* broken link flag: 1bit(should be zero) */
+ int broken;
+} COM_CNKH;
+
+/*****************************************************************************
+ * sequence header
+ *****************************************************************************/
+typedef struct _COM_SQH
+{
+ u8 profile_id; /* 8 bits */
+ u8 level_id; /* 8 bits */
+ u8 progressive_sequence; /* 1 bit */
+ u8 field_coded_sequence; /* 1 bit */
+#if LIBVC_ON
+ u8 library_stream_flag; /* 1 bit */
+ u8 library_picture_enable_flag; /* 1 bit */
+ u8 duplicate_sequence_header_flag; /* 1 bit */
+#endif
+ u8 chroma_format; /* 2 bits */
+ u8 encoding_precision; /* 3 bits */
+ u8 output_reorder_delay; /* 5 bits */
+ u8 sample_precision; /* 3 bits */
+ u8 aspect_ratio; /* 4 bits */
+ u8 frame_rate_code; /* 4 bits */
+ u32 bit_rate_lower; /* 18 bits */
+ u32 bit_rate_upper; /* 18 bits */
+ u8 low_delay; /* 1 bit */
+ u8 temporal_id_enable_flag; /* 1 bit */
+ u32 bbv_buffer_size; /* 18 bits */
+ u8 max_dpb_size; /* 4 bits */
+ int horizontal_size; /* 14 bits */
+ int vertical_size; /* 14 bits */
+ u8 log2_max_cu_width_height; /* 3 bits */
+ u8 min_cu_size;
+ u8 max_part_ratio;
+ u8 max_split_times;
+ u8 min_qt_size;
+ u8 max_bt_size;
+ u8 max_eqt_size;
+ u8 max_dt_size;
+#if HLS_RPL
+ int rpl1_index_exist_flag;
+ int rpl1_same_as_rpl0_flag;
+ COM_RPL rpls_l0[MAX_NUM_RPLS];
+ COM_RPL rpls_l1[MAX_NUM_RPLS];
+ int rpls_l0_num;
+ int rpls_l1_num;
+ int num_ref_default_active_minus1[2];
+#endif
+#if IPCM
+ int ipcm_enable_flag;
+#endif
+ u8 amvr_enable_flag;
+#if IBC_ABVR
+ u8 abvr_enable_flag;
+#endif
+#if USE_SP
+ int sp_enable_flag;
+#if EVS_UBVS_MODE
+ int evs_ubvs_enable_flag;
+#endif
+#endif
+ int umve_enable_flag;
+#if UMVE_ENH
+ int umve_enh_enable_flag;
+#endif
+#if AWP
+ int awp_enable_flag;
+#endif
+#if AWP_MVR
+ int awp_mvr_enable_flag;
+#endif
+#if ETMVP
+ int etmvp_enable_flag;
+#endif
+#if SUB_TMVP
+ int sbtmvp_enable_flag;
+#endif
+#if MIPF
+ int mipf_enable_flag;
+#endif
+#if DBK_SCC
+ int loop_filter_type_enable_flag;
+#endif
+#if DBR
+ int dbr_enable_flag;
+#endif
+ int ipf_enable_flag;
+#if EXT_AMVR_HMVP
+ int emvr_enable_flag;
+#endif
+ u8 affine_enable_flag;
+#if ASP
+ u8 asp_enable_flag;
+#endif
+#if AFFINE_UMVE
+ u8 affine_umve_enable_flag;
+#endif
+#if SMVD
+ u8 smvd_enable_flag;
+#endif
+#if BIO
+ u8 bio_enable_flag;
+#endif
+#if BGC
+ u8 bgc_enable_flag;
+#endif
+#if DMVR
+ u8 dmvr_enable_flag;
+#endif
+#if INTERPF
+ u8 interpf_enable_flag;
+#endif
+#if MVAP
+ u8 mvap_enable_flag;
+ u8 num_of_mvap_cand;
+#endif
+#if DT_PARTITION
+ u8 dt_intra_enable_flag;
+#endif
+ u8 num_of_hmvp_cand;
+#if IBC_BVP
+ u8 num_of_hbvp_cand;
+#endif
+#if SIBC
+ u8 sibc_enable_flag;
+#endif
+#if TSCPM
+ u8 tscpm_enable_flag;
+#if ENHANCE_TSPCM
+ u8 enhance_tscpm_enable_flag;
+#endif
+#if PMC
+ u8 pmc_enable_flag;
+#endif
+#endif
+#if IPF_CHROMA
+ u8 chroma_ipf_enable_flag;
+#endif
+#if IIP
+ u8 iip_enable_flag;
+#endif
+#if FIMC
+ u8 fimc_enable_flag;
+#endif
+#if IST
+ u8 ist_enable_flag;
+#endif
+#if ISTS
+ u8 ists_enable_flag;
+#endif
+#if TS_INTER
+ u8 ts_inter_enable_flag;
+#endif
+#if EST
+ u8 est_enable_flag;
+#endif
+#if ST_CHROMA
+ u8 st_chroma_enable_flag;
+#endif
+#if SRCC
+ u8 srcc_enable_flag;
+#endif
+#if CABAC_MULTI_PROB
+ u8 mcabac_enable_flag;
+#endif
+#if EIPM
+ u8 eipm_enable_flag;
+#endif
+ u8 sample_adaptive_offset_enable_flag;
+#if ESAO
+ u8 esao_enable_flag;
+#endif
+#if CCSAO
+ u8 ccsao_enable_flag;
+#endif
+#if ALF_SHAPE || ALF_IMP
+ u8 adaptive_filter_shape_enable_flag;
+#endif
+ u8 adaptive_leveling_filter_enable_flag;
+ u8 secondary_transform_enable_flag;
+ u8 position_based_transform_enable_flag;
+#if SBT
+ u8 sbt_enable_flag;
+#endif
+
+ u8 wq_enable;
+ u8 seq_wq_mode;
+ u8 wq_4x4_matrix[16];
+ u8 wq_8x8_matrix[64];
+#if PATCH
+ u8 patch_stable;
+ u8 cross_patch_loop_filter;
+ u8 patch_ref_colocated;
+ u8 patch_uniform;
+ u8 patch_width_minus1;
+ u8 patch_height_minus1;
+ u8 patch_columns;
+ u8 patch_rows;
+ int column_width[64];
+ int row_height[32];
+#endif
+#if USE_IBC
+ u8 ibc_flag;
+#endif
+#if ESAO
+ u8 pic_esao_on[3];
+ u8 esao_adaptive_param[3];
+ u8 esao_lcu_enable[3];
+#endif
+} COM_SQH;
+
+/*****************************************************************************
+ * picture header
+ *****************************************************************************/
+typedef struct _COM_PIC_HEADER
+{
+ /* info from sqh */
+ u8 low_delay;
+ /* decoding temporal reference */
+#if HLS_RPL
+ s32 poc;
+ int rpl_l0_idx; //-1 means this slice does not use RPL candidate in SPS for RPL0
+ int rpl_l1_idx; //-1 means this slice does not use RPL candidate in SPS for RPL1
+ COM_RPL rpl_l0;
+ COM_RPL rpl_l1;
+ u8 num_ref_idx_active_override_flag;
+ u8 ref_pic_list_sps_flag[2];
+#endif
+ u32 dtr;
+ u8 slice_type;
+ u8 temporal_id;
+ u8 loop_filter_disable_flag;
+ u32 bbv_delay;
+ u16 bbv_check_times;
+
+#if DBK_SCC
+ u8 loop_fitler_type;
+#endif
+ u8 loop_filter_parameter_flag;
+ int alpha_c_offset;
+ int beta_offset;
+
+ u8 chroma_quant_param_disable_flag;
+ s8 chroma_quant_param_delta_cb;
+ s8 chroma_quant_param_delta_cr;
+
+ /*Flag and coeff for ALF*/
+ int tool_alf_on;
+#if ALF_SHAPE || ALF_IMP
+ int tool_alf_shape_on;
+#endif
+ int *pic_alf_on;
+ ALF_PARAM **alf_picture_param;
+#if DBR
+ DBR_PARAM ph_dbr_param;
+#endif
+
+ int fixed_picture_qp_flag;
+#if CUDQP
+ u8 cu_delta_qp_flag;
+ u8 cu_qp_group_size;
+ int cu_qp_group_area_size;
+#endif
+ int random_access_decodable_flag;
+ int time_code_flag;
+ int time_code;
+ int decode_order_index;
+ int picture_output_delay;
+ int progressive_frame;
+ int picture_structure;
+ int top_field_first;
+ int repeat_first_field;
+ int top_field_picture_flag;
+ int picture_qp;
+ int affine_subblock_size_idx;
+#if LIBVC_ON
+ int is_RLpic_flag; // only reference libpic
+ int library_picture_index;
+#endif
+ int pic_wq_enable;
+ int pic_wq_data_idx;
+ int wq_param;
+ int wq_model;
+ int wq_param_vector[6];
+ u8 wq_4x4_matrix[16];
+ u8 wq_8x8_matrix[64];
+#if USE_IBC
+ u8 ibc_flag;
+#endif
+#if USE_SP
+ u8 sp_pic_flag;
+#if EVS_UBVS_MODE
+ u8 evs_ubvs_pic_flag;
+#endif
+#endif
+#if FIMC
+ u8 fimc_pic_flag;
+#endif
+#if ISTS
+ u8 ph_ists_enable_flag;
+#endif
+#if TS_INTER
+ u8 ph_ts_inter_enable_flag;
+#endif
+#if AWP
+ u8 ph_awp_refine_flag;
+#endif
+#if AWP || FAST_LD
+ int ph_poc[REFP_NUM][MAX_NUM_ACTIVE_REF_FRAME];
+#endif
+#if ENC_ME_IMP
+ BOOL is_lowdelay;
+#endif
+#if FAST_LD
+ int l1idx_to_l0idx[MAX_NUM_ACTIVE_REF_FRAME];
+#endif
+#if UMVE_ENH
+ u8 umve_set_flag;
+#endif
+#if EPMC
+ u8 ph_epmc_model_flag;
+#endif
+#if ESAO
+ u8 pic_esao_on[N_C];
+ u8 esao_adaptive_param[N_C];
+ u8 esao_luma_type; //0:17 1 :9
+ u8 esao_lcu_enable[N_C]; //lcu mode control flag
+ int esao_chroma_band_length[2];
+ int esao_chroma_start_band[2];
+ int esao_chroma_band_flag[2];
+#if ESAO_PH_SYNTAX
+ ESAO_BLK_PARAM pic_esao_params[N_C];
+#endif
+#endif
+#if CCSAO
+ u8 pic_ccsao_on [N_C-1];
+ u8 ccsao_lcu_ctrl[N_C-1];
+#if CCSAO_ENHANCEMENT
+ u8 ccsao_set_num [N_C-1];
+ u8 ccsao_type [N_C-1][CCSAO_SET_NUM];
+ u8 ccsao_band_num [N_C-1][CCSAO_SET_NUM];
+ u8 ccsao_band_num_c[N_C-1][CCSAO_SET_NUM];
+#else
+ u8 ccsao_type [N_C-1];
+ u8 ccsao_band_num[N_C-1];
+#endif
+#if CCSAO_PH_SYNTAX
+ CCSAO_BLK_PARAM pic_ccsao_params[N_C-1];
+#endif
+#endif
+ int g_DOIPrev;
+ int g_CountDOICyCleTime;
+} COM_PIC_HEADER;
+
+typedef struct _COM_SH_EXT
+{
+ u8 slice_sao_enable[N_C];
+ u8 fixed_slice_qp_flag;
+ u8 slice_qp;
+} COM_SH_EXT;
+
+#if TB_SPLIT_EXT
+typedef struct _COM_PART_INFO
+{
+ u8 num_sub_part;
+ int sub_x[MAX_NUM_PB]; //sub part x, y, w and h
+ int sub_y[MAX_NUM_PB];
+ int sub_w[MAX_NUM_PB];
+ int sub_h[MAX_NUM_PB];
+ int sub_scup[MAX_NUM_PB];
+} COM_PART_INFO;
+#endif
+
+#if CUDQP
+typedef struct _COM_CU_QP_GROUP
+{
+ int num_delta_qp;
+ int cu_qp_group_x;
+ int cu_qp_group_y;
+ int pred_qp;
+ //encoder only
+ int target_qp_for_qp_group;
+ int qp_group_width;
+ int qp_group_height;
+} COM_CU_QP_GROUP;
+#endif
+
+typedef struct _COM_POS
+{
+ u8 a; // 1/4 position
+ u8 b; // 2/4 position
+ u8 c; // 3/4 position
+} COM_POS;
+
+typedef struct _COM_POS_INFO
+{
+ COM_POS x; // x dimension
+ COM_POS y; // y dimension
+} COM_POS_INFO;
+/*****************************************************************************
+ * user data types
+ *****************************************************************************/
+#define COM_UD_PIC_SIGNATURE 0x10
+#define COM_UD_END 0xFF
+
+#if USE_SP
+ /*****************************************************************************
+ * SP mode structure
+ *****************************************************************************/
+typedef struct _COM_SP_INFO
+{
+ u8 is_matched;
+ u16 length;
+ s16 offset_x;
+ s16 offset_y;
+#if SP_SLR
+ int match_dict[4];
+ pel pixel[4][N_C];
+#else
+ pel pixel[N_C];
+#endif
+#if !SP_CODE_TEXT_BUGFIX
+ u8 sp_length_type;
+#endif
+ u8 n_recent_flag;
+ s8 n_recent_idx;
+#if SP_SVP
+ s16 svp_x;
+ s16 svp_y;
+ s8 n_offset_num;
+#endif
+} COM_SP_INFO;
+#if EVS_UBVS_MODE
+typedef struct _COM_SP_PIX
+{
+ pel Y;
+ pel U;
+ pel V;
+}COM_SP_PIX;
+typedef struct _COM_SP_EVS_INFO
+{
+ u8 is_matched;
+ u16 length;
+ pel pixel[N_C];
+ u8 match_type;
+ u8 srb_index;
+ u16 srb_bits;
+ u16 srb_dist;
+ u8 esc_flag;
+ int pos;
+ s8 valid_flag;
+ u8 allcomp_adr_update_flag;
+}COM_SP_EVS_INFO;
+#endif
+#endif
+/*****************************************************************************
+ * for binary and triple tree structure
+ *****************************************************************************/
+typedef enum _SPLIT_MODE
+{
+ NO_SPLIT = 0,
+ SPLIT_BI_VER = 1,
+ SPLIT_BI_HOR = 2,
+#if EQT
+ SPLIT_EQT_VER = 3,
+ SPLIT_EQT_HOR = 4,
+ SPLIT_QUAD = 5,
+#else
+ SPLIT_QUAD = 3,
+#endif
+ NUM_SPLIT_MODE
+} SPLIT_MODE;
+
+typedef enum _SPLIT_DIR
+{
+ SPLIT_VER = 0,
+ SPLIT_HOR = 1,
+ SPLIT_QT = 2,
+} SPLIT_DIR;
+
+#if MODE_CONS
+typedef enum _CONS_PRED_MODE
+{
+ NO_MODE_CONS = 0,
+ ONLY_INTER = 1,
+ ONLY_INTRA = 2,
+} CONS_PRED_MODE;
+#endif
+
+#if CHROMA_NOT_SPLIT
+typedef enum _TREE_STATUS
+{
+ TREE_LC = 0,
+ TREE_L = 1,
+ TREE_C = 2,
+} TREE_STATUS;
+#endif
+
+typedef enum _CHANNEL_TYPE
+{
+ CHANNEL_LC = 0,
+ CHANNEL_L = 1,
+ CHANNEL_C = 2,
+#if PMC || EPMC
+ CHANNEL_U = 3,
+ CHANNEL_V = 4,
+#endif
+} CHANNEL_TYPE;
+
+#if TB_SPLIT_EXT
+typedef enum _PART_SIZE
+{
+ SIZE_2Nx2N, ///< symmetric partition, 2Nx2N
+ SIZE_2NxnU, ///< asymmetric partition, 2Nx( N/2) + 2Nx(3N/2)
+ SIZE_2NxnD, ///< asymmetric partition, 2Nx(3N/2) + 2Nx( N/2)
+ SIZE_nLx2N, ///< asymmetric partition, ( N/2)x2N + (3N/2)x2N
+ SIZE_nRx2N, ///< asymmetric partition, (3N/2)x2N + ( N/2)x2N
+ SIZE_NxN, ///< symmetric partition, NxN
+ SIZE_2NxhN, ///< symmetric partition, 2N x 0.5N
+ SIZE_hNx2N, ///< symmetric partition, 0.5N x 2N
+ NUM_PART_SIZE
+} PART_SIZE;
+#endif
+
+typedef enum _BLOCK_SHAPE
+{
+ NON_SQUARE_18,
+ NON_SQUARE_14,
+ NON_SQUARE_12,
+ SQUARE,
+ NON_SQUARE_21,
+ NON_SQUARE_41,
+ NON_SQUARE_81,
+ NUM_BLOCK_SHAPE,
+} BLOCK_SHAPE;
+
+typedef enum _CTX_NEV_IDX
+{
+ CNID_SKIP_FLAG,
+ CNID_PRED_MODE,
+ CNID_AFFN_FLAG,
+ NUM_CNID,
+} CTX_NEV_IDX;
+
+#if AWP
+typedef enum _AWP_ANGLE_RATIO
+{
+ AWP_ANGLE_1, // 1:1
+ AWP_ANGLE_2, // 1:2 2:1
+ AWP_ANGLE_4, // 1:4 4:1
+ AWP_ANGLE_8, // 1:8 8:1
+ AWP_ANGLE_16,
+ AWP_ANGLE_32,
+ AWP_ANGLE_64,
+ AWP_ANGLE_HOR,
+ AWP_ANGLE_VER
+} AWP_ANGLE_RATIO;
+#endif
+
+#if DMVR
+#define DMVR_PAD_LENGTH 2
+#define EXTRA_PIXELS_FOR_FILTER 7 // Maximum extraPixels required for final MC based on fiter size
+#define PAD_BUFFER_STRIDE ((MAX_CU_SIZE + EXTRA_PIXELS_FOR_FILTER + (DMVR_ITER_COUNT * 2)))
+static const int NTAPS_LUMA = 8; ///< Number of taps for luma
+static const int NTAPS_CHROMA = 4; ///< Number of taps for chroma
+#endif
+
+/*****************************************************************************
+* mode decision structure
+*****************************************************************************/
+typedef struct _COM_MODE
+{
+ /* CU position X in a frame in SCU unit */
+ int x_scu;
+ /* CU position Y in a frame in SCU unit */
+ int y_scu;
+
+ /* depth of current CU */
+ int cud;
+
+ /* width of current CU */
+ int cu_width;
+ /* height of current CU */
+ int cu_height;
+ /* log2 of cu_width */
+ int cu_width_log2;
+ /* log2 of cu_height */
+ int cu_height_log2;
+ /* position of CU */
+ int x_pos;
+ int y_pos;
+ /* CU position in current frame in SCU unit */
+ int scup;
+
+ int cu_mode;
+#if TB_SPLIT_EXT
+ //note: DT can apply to intra CU and only use normal amvp for inter CU (no skip, direct, amvr, affine, hmvp)
+ int pb_part;
+ int tb_part;
+ COM_PART_INFO pb_info;
+ COM_PART_INFO tb_info;
+#endif
+#if SBT
+ u8 sbt_info;
+ int sbt_hor_trans;
+ int sbt_ver_trans;
+#endif
+
+ pel rec[N_C][MAX_CU_DIM];
+ s16 coef[N_C][MAX_CU_DIM];
+ pel pred[N_C][MAX_CU_DIM];
+
+#if TB_SPLIT_EXT
+ int num_nz[MAX_NUM_TB][N_C];
+#else
+ int num_nz[N_C];
+#endif
+
+ /* reference indices */
+ s8 refi[REFP_NUM];
+
+ /* MVR indices */
+ u8 mvr_idx;
+#if INTERPF
+ u8 inter_filter_flag;
+#endif
+#if BGC
+ u8 bgc_flag;
+ u8 bgc_idx;
+#if UMVE_ENH
+ s8 bgc_flag_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM_SEC_SET * UMVE_BASE_NUM];
+ s8 bgc_idx_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM_SEC_SET * UMVE_BASE_NUM];
+#else
+ s8 bgc_flag_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM * UMVE_BASE_NUM];
+ s8 bgc_idx_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM * UMVE_BASE_NUM];
+#endif
+#endif
+ u8 umve_flag;
+ u8 umve_idx;
+ u8 skip_idx;
+#if EXT_AMVR_HMVP
+ u8 mvp_from_hmvp_flag;
+#endif
+#if IBC_BVP
+ u8 cbvp_idx;
+#if CBVP_LIST_SIMP
+ s8 cnt_hbvp_cands;
+#endif
+#endif
+
+#if SP_SVP
+ u8 svp_idx;
+#endif
+
+#if AFFINE_UMVE
+ u8 affine_umve_flag;
+ s8 affine_umve_idx[VER_NUM];
+ s8 best_affine_merge_index;
+#endif
+
+ /* mv difference */
+ s16 mvd[REFP_NUM][MV_D];
+ /* mv */
+ s16 mv[REFP_NUM][MV_D];
+
+ u8 affine_flag;
+ CPMV affine_mv[REFP_NUM][VER_NUM][MV_D];
+ s16 affine_mvd[REFP_NUM][VER_NUM][MV_D];
+
+#if AWP
+ /* awp flag*/
+ u8 awp_flag;
+ /* awp cand idx*/
+ u8 awp_idx0;
+ u8 awp_idx1;
+ /* awp mv & refidx*/
+ s16 awp_mv0[REFP_NUM][MV_D];
+ s16 awp_mv1[REFP_NUM][MV_D];
+ s8 awp_refi0[REFP_NUM];
+ s8 awp_refi1[REFP_NUM];
+#endif
+
+#if AWP_MVR
+ u8 awp_mvr_flag0;
+ u8 awp_mvr_idx0;
+ u8 awp_mvr_flag1;
+ u8 awp_mvr_idx1;
+#endif
+
+#if SMVD
+ u8 smvd_flag;
+#endif
+
+#if DMVR
+ pel dmvr_template[MAX_CU_DIM];
+ pel dmvr_ref_pred_interpolated[REFP_NUM][(MAX_CU_SIZE + (2*(DMVR_NEW_VERSION_ITER_COUNT + 1) * REF_PRED_EXTENTION_PEL_COUNT)) * (MAX_CU_SIZE + (2*(DMVR_NEW_VERSION_ITER_COUNT + 1) * REF_PRED_EXTENTION_PEL_COUNT))];
+ u8 dmvr_enable;
+ pel dmvr_padding_buf[2][N_C][PAD_BUFFER_STRIDE * PAD_BUFFER_STRIDE];
+#endif
+
+#if ETMVP
+ u8 etmvp_flag;
+#endif
+
+ /* intra prediction mode */
+#if TB_SPLIT_EXT
+ u8 mpm[MAX_NUM_PB][2];
+ s8 ipm[MAX_NUM_PB][2];
+#else
+ u8 mpm[2];
+ s8 ipm[2];
+#endif
+#if USE_IBC
+ // ibc flag for MODE_IBC
+ u8 ibc_flag;
+#endif
+#if IBC_ABVR
+ u8 bvr_idx;
+#endif
+#if SIBC
+ u8 sibc_flag;
+#endif
+#if IIP
+ u8 iip_flag;
+#endif
+ u8 ipf_flag;
+ /* intra transform type */
+ u8 slice_type;
+#if IST
+ u8 ist_tu_flag;
+#endif
+#if ISTS
+ u8 ph_ists_enable_flag;
+#endif
+#if TS_INTER
+ u8 ph_ts_inter_enable_flag;
+#endif
+#if AWP
+ u8 ph_awp_refine_flag;
+#endif
+#if EST
+ u8 est_flag;
+#endif
+#if ST_CHROMA
+ u8 st_chroma_flag;
+#endif
+#if USE_SP
+ u8 sp_flag;
+ u8 sp_copy_direction;
+ u16 sub_string_no;
+ COM_SP_INFO string_copy_info[SP_STRING_INFO_NO];
+ double cur_bst_rdcost;
+ u8 is_sp_pix_completed;
+#endif
+#if EVS_UBVS_MODE
+ u8 cs2_flag;
+ u8 evs_copy_direction;
+ int evs_sub_string_no;
+ COM_SP_EVS_INFO* evs_str_copy_info; //evs_str_copy_info[SP_STRING_INFO_NO];
+ int unpred_pix_num;
+ COM_SP_PIX* unpred_pix_info; //unpred_pix_info[SP_STRING_INFO_NO];
+ u8 equal_val_str_present_flag;
+ u8 unpredictable_pix_present_flag;
+ s16* p_SRB[N_C];
+ u8 pvbuf_size;
+ u8* pvbuf_reused_flag;
+ u8 all_comp_flag[MAX_SRB_SIZE];//1:LUMA AND CHROMA 0: ONLY LUMA
+ u8 all_comp_pre_flag[MAX_SRB_PRED_SIZE];
+ u16 temp_m_pvbuf[2][MAX_SRB_SIZE];
+ s16* p_SRB_prev[N_C];
+ u8 pvbuf_size_prev;
+ u16 m_pvbuf_prev[2][MAX_SRB_PRED_SIZE];
+ u16 m_pvbuf[2][MAX_SRB_SIZE];
+ u16 m_pvbuf_new[2][MAX_SRB_PRED_SIZE];
+ u8 m_dpb_idx[MAX_SRB_SIZE];
+ u8 m_dpb_idx_prev[MAX_SRB_PRED_SIZE];
+#endif
+} COM_MODE;
+
+/*****************************************************************************
+* map structure
+*****************************************************************************/
+typedef struct _COM_MAP
+{
+ /* SCU map for CU information */
+ u32 *map_scu;
+ /* LCU split information */
+ s8 (*map_split)[MAX_CU_DEPTH][NUM_BLOCK_SHAPE][MAX_CU_CNT_IN_LCU];
+ /* decoded motion vector for every blocks */
+ s16 (*map_mv)[REFP_NUM][MV_D];
+ /* reference frame indices */
+ s8 (*map_refi)[REFP_NUM];
+ /* intra prediction modes */
+ s8 *map_ipm;
+ u32 *map_cu_mode;
+#if TB_SPLIT_EXT
+ u32 *map_pb_tb_part;
+#endif
+ s8 *map_depth;
+ s8 *map_delta_qp;
+ s8 *map_patch_idx;
+#if USE_SP
+ u8 *map_usp;
+#endif
+#if PATCH
+ u32 *map_scu_temp;
+ u32 *map_cu_mode_temp;
+ s16 (*map_mv_temp)[REFP_NUM][MV_D];
+ s8 (*map_refi_temp)[REFP_NUM];
+#if USE_SP
+ u8 *map_usp_temp;
+#endif
+#endif
+} COM_MAP;
+
+/*****************************************************************************
+* common info
+*****************************************************************************/
+typedef struct _COM_INFO
+{
+ /* current chunk header */
+ COM_CNKH cnkh;
+
+ /* current picture header */
+ COM_PIC_HEADER pic_header;
+
+ /* current slice header */
+ COM_SH_EXT shext;
+
+ /* sequence header */
+ COM_SQH sqh;
+
+ /* decoding picture width */
+ int pic_width;
+ /* decoding picture height */
+ int pic_height;
+ /* maximum CU width and height */
+ int max_cuwh;
+ /* log2 of maximum CU width and height */
+ int log2_max_cuwh;
+
+ /* picture width in LCU unit */
+ int pic_width_in_lcu;
+ /* picture height in LCU unit */
+ int pic_height_in_lcu;
+
+ /* picture size in LCU unit (= w_lcu * h_lcu) */
+ int f_lcu;
+ /* picture width in SCU unit */
+ int pic_width_in_scu;
+ /* picture height in SCU unit */
+ int pic_height_in_scu;
+ /* picture size in SCU unit (= pic_width_in_scu * h_scu) */
+ int f_scu;
+
+ int bit_depth_internal;
+ int bit_depth_input;
+ int qp_offset_bit_depth;
+#if ASP
+ BOOL skip_me_asp;
+ BOOL skip_umve_asp;
+#endif
+#if BGC
+ pel *pred_tmp;
+#endif
+} COM_INFO;
+
+typedef enum _MSL_IDX
+{
+ MSL_SKIP, //skip
+ MSL_MERGE, //merge or direct
+ MSL_LIS0, //list 0
+ MSL_LIS1, //list 1
+ MSL_BI, //bi pred
+ NUM_MODE_SL,
+} MSL_IDX;
+/*****************************************************************************
+* patch info
+*****************************************************************************/
+#if PATCH
+typedef struct _PATCH_INFO
+{
+ int stable;
+ int cross_patch_loop_filter;
+ int ref_colocated;
+ int uniform;
+ int height;
+ int width;
+ int columns;
+ int rows;
+ int idx;
+ /*patch's location(up left) in pixel*/
+ int x_pel;
+ int y_pel;
+ /*all the cu in a patch are skip_mode*/
+ int skip_patch_flag;
+ /*pointer the width of each patch*/
+ int *width_in_lcu;
+ int *height_in_lcu;
+ /*count as the patch*/
+ int x_pat;
+ int y_pat;
+ /*define the boundary of a patch*/
+ int left_pel;
+ int right_pel;
+ int up_pel;
+ int down_pel;
+ /*patch_sao_enable_flag info of all patches*/
+ s8 *patch_sao_enable;
+} PATCH_INFO;
+#endif
+typedef enum _TRANS_TYPE
+{
+ DCT2,
+ DCT8,
+ DST7,
+ NUM_TRANS_TYPE
+} TRANS_TYPE;
+
+#if FIMC
+typedef struct _COM_CNTMPM
+{
+ u32 freqT [CNTMPM_TABLE_LENGTH]; // freqT [ mode ]
+ u8 modeT [2]; // modeT [ order]
+} COM_CNTMPM;
+#endif
+
+#if PMC || EPMC
+#define IS_RIGHT_CBF_U(cbf_u) ((cbf_u) > 0)
+#define V_QP_OFFSET 1
+#endif
+
+#if EPMC
+#define MOD_IDX 2 //2 is -2
+#define MOD2_IDX 1 //1 is -0.5
+#define TH_CBCR -0.10
+#endif
+
+#if IIP
+#define MAX_IIP_BLK 4096 //the number is included
+#define MIN_IIP_BLK 64 //the number is included
+#define STNUM 5 // anchor is 3
+#else
+#define STNUM 3 // anchor is 3
+#endif
+
+#if ASP
+#define ASP_SHIFT 3
+#define DMV_BUF_SIZE 8*8
+#endif
+#if 0
+#include "com_tbl.h"
+#include "com_util.h"
+#include "com_recon.h"
+#include "com_ipred.h"
+#include "com_tbl.h"
+#include "com_itdq.h"
+#include "com_picman.h"
+#include "com_mc.h"
+#include "com_img.h"
+#endif
+
+#endif /* _COM_DEF_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/com_picman.c b/drivers/frame_provider/decoder/avs3/com_picman.c
new file mode 100644
index 0000000..4da867a
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_picman.c
@@ -0,0 +1,1214 @@
+/* ====================================================================================================================
+
+ The copyright in this software is being made available under the License included below.
+ This software may be subject to other third party and contributor rights, including patent rights, and no such
+ rights are granted under this license.
+
+ Copyright (c) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+ Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+ Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted only for
+ the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+ promoting such standards. The following conditions are required to be met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* ====================================================================================================================
+*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/frame_sync/tsync.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+//#include "com_def.h"
+#include "avs3_global.h"
+
+#ifdef SIMULATION
+#ifdef SYSTEM_TEST
+#define printf st_printf
+#define printk st_printf
+#else
+#define printf io_printf
+#define printk io_printf
+#endif
+#endif
+
+/* macros for reference picture flag */
+#define IS_REF(pic) (((pic)->is_ref) != 0)
+#define SET_REF_UNMARK(pic) (((pic)->is_ref) = 0)
+#define SET_REF_MARK(pic) (((pic)->is_ref) = 1)
+
+#define PRINT_DPB(pm)\
+ printf("%s: current num_ref = %d, dpb_size = %d\n", __FUNCTION__, \
+ pm->cur_num_ref_pics, picman_get_num_allocated_pics(pm));
+
+static unsigned long com_picman_lock(COM_PM * pm)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&pm->pm_lock, flags);
+
+ return flags;
+}
+
+void com_picman_unlock(COM_PM * pm, unsigned long flags)
+{
+ spin_unlock_irqrestore(&pm->pm_lock, flags);
+}
+
+static int picman_get_num_allocated_pics(COM_PM * pm)
+{
+ int i, cnt = 0;
+ for (i = 0; i < pm->max_pb_size; i++) /* this is coding order */
+ {
+ if (pm->pic[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+static int picman_move_pic(COM_PM *pm, int from, int to)
+{
+ int i;
+ COM_PIC * pic;
+ int temp_cur_num_ref_pics = pm->cur_num_ref_pics;
+ BOOL found_empty_pos = 0;
+
+ pic = pm->pic[from];
+
+ for (i = from; i < temp_cur_num_ref_pics - 1; i++) {
+ pm->pic[i] = pm->pic[i + 1];// move the remaining ref pic to the front
+ }
+ pm->pic[temp_cur_num_ref_pics - 1] = NULL; // the new end fill with NULL.
+ temp_cur_num_ref_pics--;// update, since the ref-pic number decrease
+ for (i = to; i > temp_cur_num_ref_pics; i--) {
+ if (pm->pic[i] == NULL) {
+ pm->pic[i] = pic;// find the first NULL pos from end to front, and fill with the un-ref pic
+ found_empty_pos = 1;
+ break;
+ }
+ }
+
+ if (found_empty_pos != 1) {
+ pr_info("%s pic %p will be discarded\n", __func__, pic);
+ }
+ assert(found_empty_pos == 1);
+ return 0;
+}
+
+#if 0
+static void picman_flush_pb(COM_PM * pm)
+{
+ int i;
+ /* mark all frames unused */
+ for (i = 0; i < MAX_PB_SIZE; i++)
+ {
+ if (pm->pic[i]) SET_REF_UNMARK(pm->pic[i]);
+ }
+ pm->cur_num_ref_pics = 0;
+}
+#endif
+static void picman_update_pic_ref(COM_PM * pm)
+{
+ COM_PIC ** pic;
+ COM_PIC ** pic_ref;
+ COM_PIC * pic_t;
+ int i, j, cnt;
+ ulong flags;
+
+ flags = com_picman_lock(pm);
+
+ pic = pm->pic;
+ pic_ref = pm->pic_ref;
+ for (i = 0, j = 0; i < pm->max_pb_size; i++) {
+ if (pic[i] && IS_REF(pic[i])) {
+#ifdef BUFMGR_SANITY_CHECK
+ if (j < MAX_NUM_REF_PICS)
+ pic_ref[j++] = pic[i];
+ else {
+ if (avs3_get_debug_flag())
+ pr_info("%s ref pic num(%d) is more than the MAX_NUM_REF_PICS\n",
+ __func__, j);
+ }
+#else
+ pic_ref[j++] = pic[i];
+#endif
+ }
+ }
+ cnt = j;
+ while (j < MAX_NUM_REF_PICS)
+ pic_ref[j++] = NULL;
+ /* descending order sort based on PTR */
+ for (i = 0; i < cnt - 1; i++) {
+ for (j = i + 1; j < cnt; j++) {
+#ifdef BUFMGR_SANITY_CHECK
+ if (i >= MAX_NUM_REF_PICS || j >= MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("%s pm pic num(%d,%d) is more than the MAX_NUM_REF_PICS\n",
+ __func__, i, j);
+ return;
+ }
+#endif
+ if (pic_ref[i]->ptr < pic_ref[j]->ptr) {
+ pic_t = pic_ref[i];
+ pic_ref[i] = pic_ref[j];
+ pic_ref[j] = pic_t;
+ }
+ }
+ }
+
+ com_picman_unlock(pm, flags);
+}
+
+static COM_PIC * picman_remove_pic_from_pb(COM_PM * pm, int pos)
+{
+ int i;
+ COM_PIC * pic_rem;
+ ulong flags;
+
+ flags = com_picman_lock(pm);
+
+ pic_rem = pm->pic[pos];
+ printf("%s: pic %p pos %d\n", __func__, pic_rem, pos);
+ pm->pic[pos] = NULL;
+ /* fill empty pic buffer */
+ for (i = pos; i < pm->max_pb_size - 1; i++) {
+ pm->pic[i] = pm->pic[i + 1];
+ }
+ pm->pic[pm->max_pb_size - 1] = NULL;
+ pm->cur_pb_size--;
+
+ com_picman_unlock(pm, flags);
+
+ return pic_rem;
+}
+
+static void picman_set_pic_to_pb(COM_PM * pm, COM_PIC * pic,
+ COM_REFP(*refp)[REFP_NUM], int pos)
+{
+ int i;
+ printf("%s: pic %p pos %d\n", __func__, pic, pos);
+ for (i = 0; i < pm->num_refp[REFP_0]; i++) {
+#if ETMVP || SUB_TMVP || AWP
+ pic->list_ptr[REFP_0][i] = refp[i][REFP_0].ptr;
+#else
+ pic->list_ptr[i] = refp[i][REFP_0].ptr;
+#endif
+ }
+#if ETMVP || SUB_TMVP || AWP
+ for (i = 0; i < pm->num_refp[REFP_1]; i++) {
+ pic->list_ptr[REFP_1][i] = refp[i][REFP_1].ptr;
+ }
+#endif
+ if (pos >= 0) {
+ com_assert(pm->pic[pos] == NULL);
+ if (pm->pic[pos] != NULL) {
+ COM_PIC * pos_pic;
+ pos_pic = pm->pic[pos];
+
+ /* search empty pic buffer position */
+ for (i = (pm->max_pb_size - 1); i >= 0; i--)
+ {
+ if (pm->pic[i] == NULL)
+ {
+ pm->pic[i] = pos_pic;
+ break;
+ }
+ }
+
+ if (i < 0)
+ {
+ printf("pos pic will be discarded\n");
+ }
+ }
+ pm->pic[pos] = pic;
+ } else /* pos < 0 */
+ {
+ /* search empty pic buffer position */
+ for (i = (pm->max_pb_size - 1); i >= 0; i--) {
+ if (pm->pic[i] == NULL) {
+ pm->pic[i] = pic;
+ break;
+ }
+ }
+ if (i < 0) {
+ printf("i=%d\n", i);
+ com_assert(i >= 0);
+ }
+ }
+ pm->cur_pb_size++;
+}
+
+static int picman_get_empty_pic_from_list(COM_PM * pm)
+{
+ //COM_IMGB * imgb;
+ COM_PIC * pic;
+ int i;
+ for (i = 0; i < pm->max_pb_size; i++) {
+ pic = pm->pic[i];
+ if (pic != NULL && !IS_REF(pic) && pic->need_for_out == 0
+#ifdef AML
+ && pic->buf_cfg.vf_ref == 0
+ && pic->buf_cfg.backend_ref == 0
+ && pic->buf_cfg.in_dpb == 0
+#endif
+ ) {
+#ifdef ORI_CODE
+ imgb = pic->imgb;
+ com_assert(imgb != NULL);
+ /* check reference count */
+ if (1 == imgb->getref(imgb)) {
+ return i; /* this is empty buffer */
+ }
+#else
+ printf("%s: pm index %d pic index %d\n",
+ __func__, i, pic->buf_cfg.index);
+ return i;
+#endif
+ }
+ }
+ return -1;
+}
+
+void set_refp(COM_REFP * refp, COM_PIC * pic_ref)
+{
+ refp->pic = pic_ref;
+ refp->ptr = pic_ref->ptr;
+ refp->map_mv = pic_ref->map_mv;
+ refp->map_refi = pic_ref->map_refi;
+ refp->list_ptr = pic_ref->list_ptr;
+#if LIBVC_ON
+ refp->is_library_picture = 0;
+#endif
+}
+
+void copy_refp(COM_REFP * refp_dst, COM_REFP * refp_src)
+{
+ refp_dst->pic = refp_src->pic;
+ refp_dst->ptr = refp_src->ptr;
+ refp_dst->map_mv = refp_src->map_mv;
+ refp_dst->map_refi = refp_src->map_refi;
+ refp_dst->list_ptr = refp_src->list_ptr;
+#if LIBVC_ON
+ refp_dst->is_library_picture = refp_src->is_library_picture;
+#endif
+}
+
+int check_copy_refp(COM_REFP(*refp)[REFP_NUM], int cnt, int lidx, COM_REFP * refp_src)
+{
+ int i;
+ for (i = 0; i < cnt; i++) {
+#if LIBVC_ON
+ if (refp[i][lidx].ptr == refp_src->ptr && refp[i][lidx].is_library_picture == refp_src->is_library_picture)
+#else
+ if (refp[i][lidx].ptr == refp_src->ptr)
+#endif
+ {
+ return -1;
+ }
+ }
+ copy_refp(&refp[cnt][lidx], refp_src);
+ return COM_OK;
+}
+
+#if HLS_RPL //This is implementation of reference picture list construction based on RPL. This is meant to replace function int com_picman_refp_init(COM_PM *pm, int num_ref_pics_act, int slice_type, u32 ptr, u8 layer_id, int last_intra, COM_REFP(*refp)[REFP_NUM])
+int com_picman_refp_rpl_based_init(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM])
+{
+ //MX: IDR?
+ int i;
+ if ((pic_header->slice_type == SLICE_I) && (pic_header->poc == 0))
+ {
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+ return COM_OK;
+ }
+
+ picman_update_pic_ref(pm);
+
+#if LIBVC_ON
+ if (!pm->libvc_data->library_picture_enable_flag && pic_header->slice_type != SLICE_I)
+#endif
+ {
+ com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+ }
+
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+ refp[i][REFP_0].pic = refp[i][REFP_1].pic = NULL;
+ }
+
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+
+ //Do the L0 first
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++) {
+#if LIBVC_ON
+ if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l0.library_index_flag[i]) {
+ int ref_lib_index = pic_header->rpl_l0.ref_pics[i];
+ com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+
+ set_refp(&refp[i][REFP_0], pm->pb_libpic);
+ refp[i][REFP_0].ptr = pic_header->poc - 1;
+ refp[i][REFP_0].is_library_picture = 1;
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+ }
+ else
+#endif
+ {
+ int refPicPoc = pic_header->poc - pic_header->rpl_l0.ref_pics[i];
+ //Find the ref pic in the DPB
+ int j = 0;
+ int diff;
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+ j++;
+
+ //If the ref pic is found, set it to RPL0
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+
+ set_refp(&refp[i][REFP_0], pm->pic_ref[j]);
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+ //make sure delta doi of RPL0 correct,in case of last incomplete GOP
+ diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+ if (diff != pic_header->rpl_l0.ref_pics_ddoi[i]) {
+ pic_header->ref_pic_list_sps_flag[0] = 0;
+ pic_header->rpl_l0.ref_pics_ddoi[i] = diff;
+ }
+ } else {
+ printf("%s: The L0 Reference Picture(%d) is not find in dpb",
+ __func__, refPicPoc);
+ return COM_ERR; //The refence picture must be available in the DPB, if not found then there is problem
+ }
+ }
+ }
+
+ //update inactive ref ddoi in L0,in case of last incomplete GOP
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+#if LIBVC_ON
+ if (!pic_header->rpl_l0.library_index_flag[i] && pic_header->rpl_l0.ref_pics[i] > 0)
+#else
+ if (pic_header->rpl_l0.ref_pics[i] > 0)
+#endif
+ {
+ int refPicPoc = pic_header->poc - pic_header->rpl_l0.ref_pics[i];
+ //Find the ref pic in the DPB
+ int j = 0;
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+ j++;
+
+ //If the ref pic is found, set it to RPL0
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+ int diff = (pic_header->decode_order_index % DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+ if (diff != pic_header->rpl_l0.ref_pics_ddoi[i]) {
+ pic_header->ref_pic_list_sps_flag[0] = 0;
+ pic_header->rpl_l0.ref_pics_ddoi[i] = diff;
+ }
+ }
+ }
+ }
+ if (pic_header->slice_type == SLICE_P) return COM_OK;
+
+ //Do the L1 first
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++) {
+#if LIBVC_ON
+ if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l1.library_index_flag[i]) {
+ int ref_lib_index = pic_header->rpl_l1.ref_pics[i];
+ com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+
+ set_refp(&refp[i][REFP_1], pm->pb_libpic);
+ refp[i][REFP_1].ptr = pic_header->poc - 1;
+ refp[i][REFP_1].is_library_picture = 1;
+ pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+ } else
+#endif
+ {
+ int refPicPoc = pic_header->poc - pic_header->rpl_l1.ref_pics[i];
+ //Find the ref pic in the DPB
+ int j = 0;
+ int diff;
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+ j++;
+
+ //If the ref pic is found, set it to RPL1
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+ set_refp(&refp[i][REFP_1], pm->pic_ref[j]);
+ pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+ //make sure delta doi of RPL0 correct
+ diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+ if (diff != pic_header->rpl_l1.ref_pics_ddoi[i]) {
+ pic_header->ref_pic_list_sps_flag[1] = 0;
+ pic_header->rpl_l1.ref_pics_ddoi[i] = diff;
+ }
+ } else {
+ printf("%s: The L1 Reference Picture(%d) is not find in dpb",
+ __func__, refPicPoc);
+ return COM_ERR; //The refence picture must be available in the DPB, if not found then there is problem
+ }
+ }
+ }
+ //update inactive ref ddoi in L1
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+#if LIBVC_ON
+ if (!pic_header->rpl_l1.library_index_flag[i] && pic_header->rpl_l1.ref_pics[i] > 0)
+#else
+ if (pic_header->rpl_l1.ref_pics[i] > 0)
+#endif
+ {
+ int refPicPoc = pic_header->poc - pic_header->rpl_l1.ref_pics[i];
+ //Find the ref pic in the DPB
+ int j = 0;
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+ j++;
+
+ //If the ref pic is found, set it to RPL0
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+ int diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+ if (diff != pic_header->rpl_l1.ref_pics_ddoi[i]) {
+ pic_header->ref_pic_list_sps_flag[1] = 0;
+ pic_header->rpl_l1.ref_pics_ddoi[i] = diff;
+ }
+ }
+ }
+ }
+ return COM_OK; //RPL construction completed
+}
+
+int com_cleanup_useless_pic_buffer_in_pm( COM_PM *pm )
+{
+ //remove the pic if it is a unref pic, and has been output.
+ int i;
+ printf("%s\n", __func__);
+ for (i = 0; i < pm->max_pb_size; i++) {
+ if (pm->pic[i] != NULL)
+ printf("pm pic %p index %d\n", pm->pic[i], i);
+ if ( (pm->pic[i] != NULL) && (pm->pic[i]->need_for_out == 0)
+ && (pm->pic[i]->is_ref == 0)
+#ifdef AML
+ && (pm->pic[i]->buf_cfg.backend_ref == 0)
+ && (pm->pic[i]->buf_cfg.vf_ref == 0)
+#endif
+ ) {
+ com_pic_free(pm->hw, &pm->pa, pm->pic[i]);
+ pm->cur_pb_size--;
+ pm->pic[i] = NULL;
+ }
+ }
+ return COM_OK;
+}
+
+int com_picman_dpbpic_doi_minus_cycle_length( COM_PM *pm )
+{
+ COM_PIC * pic;
+ int i;
+ for (i = 0; i < pm->max_pb_size; i++) {
+ pic = pm->pic[i];
+ if ( pic != NULL )//MX: no matter whether is ref or unref(for output), need to minus 256.
+ {
+ pic->dtr = pic->dtr - DOI_CYCLE_LENGTH;
+ assert( pic->dtr >= (-256) );//MX:minus once at most.
+ }
+ }
+ return COM_OK;
+}
+
+//This is implementation of reference picture list construction based on RPL for decoder
+//in decoder, use DOI as pic reference instead of POC
+int com_picman_refp_rpl_based_init_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM])
+{
+ int i;
+ picman_update_pic_ref(pm);
+#ifdef BUFMGR_SANITY_CHECK
+ for (i = 0; i < pm->cur_num_ref_pics; i++) {
+ if (pm->pic_ref[i] == NULL) {
+ if (avs3_get_debug_flag())
+ pr_info("%s error, pm->cur_num_ref_pics = %d, pm->pic_ref[%d] is NULL\n",
+ __func__, pm->cur_num_ref_pics, i);
+ return COM_ERR;
+ }
+ }
+#endif
+#if LIBVC_ON
+ if (!pm->libvc_data->library_picture_enable_flag && pic_header->slice_type != SLICE_I)
+#endif
+ {
+ com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+ }
+
+ for (i = 0; i < MAX_NUM_REF_PICS; i++)
+ refp[i][REFP_0].pic = refp[i][REFP_1].pic = NULL;
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+
+ //Do the L0 first
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++) {
+#if LIBVC_ON
+ if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l0.library_index_flag[i]) {
+ int ref_lib_index;
+ ref_lib_index = pic_header->rpl_l0.ref_pics_ddoi[i];
+ com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+#ifdef BUFMGR_SANITY_CHECK
+ if (pm->pb_libpic == NULL) {
+ if (avs3_get_debug_flag())
+ pr_info("%s error, pm->pb_libpic is NULL\n", __func__);
+ return COM_ERR;
+ }
+#endif
+ set_refp(&refp[i][REFP_0], pm->pb_libpic);
+ refp[i][REFP_0].ptr = pic_header->poc - 1;
+ refp[i][REFP_0].is_library_picture = 1;
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+ } else
+#endif
+ {
+ int refPicDoi = pic_header->rpl_l0.ref_pics_doi[i];//MX: no need to fix the value in the range of 0~255. because DOI in the DPB can be a minus value, after minus 256.
+ //Find the ref pic in the DPB
+ int j = 0;
+ ulong flags;
+
+ flags = com_picman_lock(pm);
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr != refPicDoi)
+ j++;
+
+ //If the ref pic is found, set it to RPL0
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr == refPicDoi) {
+ set_refp(&refp[i][REFP_0], pm->pic_ref[j]);
+ pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+ } else {
+ com_picman_unlock(pm, flags);
+ printf("%s: The L0 Reference Picture(%d) is not find in dpb",
+ __func__, refPicDoi);
+ return COM_ERR; //The refence picture must be available in the DPB, if not found then there is problem
+ }
+
+ com_picman_unlock(pm, flags);
+ }
+ }
+
+ if (pic_header->slice_type == SLICE_P)
+ return COM_OK;
+
+ //Do the L1 first
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++) {
+#if LIBVC_ON
+ if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l1.library_index_flag[i]) {
+ int ref_lib_index = pic_header->rpl_l1.ref_pics_ddoi[i];
+ com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+#ifdef BUFMGR_SANITY_CHECK
+ if (pm->pb_libpic == NULL) {
+ if (avs3_get_debug_flag())
+ pr_info("%s error, pm->pb_libpic is NULL\n", __func__);
+ return COM_ERR;
+ }
+#endif
+ set_refp(&refp[i][REFP_1], pm->pb_libpic);
+ refp[i][REFP_1].ptr = pic_header->poc - 1;
+ refp[i][REFP_1].is_library_picture = 1;
+ pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+ } else
+#endif
+ {
+ int refPicDoi = pic_header->rpl_l1.ref_pics_doi[i];//MX: no need to fix the value in the range of 0~255. because DOI in the DPB can be a minus value, after minus 256.
+ //Find the ref pic in the DPB
+ int j = 0;
+#ifdef BUFMGR_SANITY_CHECK
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr != refPicDoi)
+#else
+ while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->dtr != refPicDoi)
+#endif
+ {
+ j++;
+ }
+
+ //If the ref pic is found, set it to RPL1
+#ifdef BUFMGR_SANITY_CHECK
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr == refPicDoi)
+#else
+ if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->dtr == refPicDoi)
+#endif
+ {
+ set_refp(&refp[i][REFP_1], pm->pic_ref[j]);
+ pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+ } else {
+ printf("%s: The L1 Reference Picture(%d) is not find in dpb",
+ __func__, refPicDoi);
+ return COM_ERR; //The refence picture must be available in the DPB, if not found then there is problem
+ }
+ }
+ }
+
+ return COM_OK; //RPL construction completed
+}
+#endif
+
+COM_PIC * com_picman_get_empty_pic(COM_PM * pm, int * err)
+{
+ int ret;
+ COM_PIC * pic = NULL;
+#if LIBVC_ON
+ if (pm->libvc_data->is_libpic_processing) {
+ /* no need to find empty picture buffer in list */
+ ret = -1;
+ } else
+#endif
+ {
+ /* try to find empty picture buffer in list */
+ ret = picman_get_empty_pic_from_list(pm);
+ }
+ if (ret >= 0) {
+ pic = picman_remove_pic_from_pb(pm, ret);
+ goto END;
+ }
+ /* else if available, allocate picture buffer */
+ pm->cur_pb_size = picman_get_num_allocated_pics(pm);
+ printf("cur_pb_size %d, cur_libpb_size %d, max_pb_size %d\n",
+ pm->cur_pb_size, pm->cur_libpb_size, pm->max_pb_size);
+#if LIBVC_ON
+ if (pm->cur_pb_size + pm->cur_libpb_size < pm->max_pb_size)
+#else
+ if (pm->cur_pb_size < pm->max_pb_size)
+#endif
+ {
+ /* create picture buffer */
+ pic = com_pic_alloc(pm->hw, &pm->pa, &ret);
+ com_assert_gv(pic != NULL, ret, COM_ERR_OUT_OF_MEMORY, ERR);
+ goto END;
+ }
+ com_assert_gv(0, ret, COM_ERR_UNKNOWN, ERR);
+END:
+ pm->pic_lease = pic;
+ if (err) *err = COM_OK;
+ return pic;
+ERR:
+ if (err) *err = ret;
+ if (pic) com_pic_free(pm->hw, &pm->pa, pic);
+ return NULL;
+}
+#if HLS_RPL
+/*This is the implementation of reference picture marking based on RPL*/
+int com_picman_refpic_marking(COM_PM *pm, COM_PIC_HEADER *pic_header)
+{
+ int i;
+ COM_PIC * pic;
+ int count_library_picture = 0;
+ int referenced_library_picture_index = -1;
+ int numberOfPicsToCheck;
+
+ picman_update_pic_ref(pm);
+#if LIBVC_ON
+ if (!pic_header->rpl_l0.reference_to_library_enable_flag && !pic_header->rpl_l1.reference_to_library_enable_flag && pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#else
+ if (pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#endif
+ com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+
+ numberOfPicsToCheck = pm->cur_num_ref_pics;
+ for (i = 0; i < numberOfPicsToCheck; i++) {
+ pic = pm->pic[i];
+ if (pm->pic[i] && IS_REF(pm->pic[i])) {
+ //If the pic in the DPB is a reference picture, check if this pic is included in RPL0
+ int isIncludedInRPL = 0;
+ int j = 0;
+ while (!isIncludedInRPL && j < pic_header->rpl_l0.ref_pic_num) {
+#if LIBVC_ON
+ if ((pic->ptr == (pic_header->poc - pic_header->rpl_l0.ref_pics[j])) && !pic_header->rpl_l0.library_index_flag[j]) //NOTE: we need to put POC also in COM_PIC
+#else
+ if (pic->ptr == (pic_header->poc - pic_header->rpl_l0.ref_pics[j])) //NOTE: we need to put POC also in COM_PIC
+#endif
+ {
+ isIncludedInRPL = 1;
+ }
+ j++;
+ }
+ //Check if the pic is included in RPL1. This while loop will be executed only if the ref pic is not included in RPL0
+ j = 0;
+ while (!isIncludedInRPL && j < pic_header->rpl_l1.ref_pic_num) {
+#if LIBVC_ON
+ if ((pic->ptr == (pic_header->poc - pic_header->rpl_l1.ref_pics[j])) && !pic_header->rpl_l1.library_index_flag[j]) //NOTE: we need to put POC also in COM_PIC
+#else
+ if (pic->ptr == (pic_header->poc - pic_header->rpl_l1.ref_pics[j]))
+#endif
+ {
+ isIncludedInRPL = 1;
+ }
+ j++;
+ }
+ //If the ref pic is not included in either RPL0 nor RPL1, then mark it as not used for reference. move it to the end of DPB.
+ if (!isIncludedInRPL) {
+ SET_REF_UNMARK(pic);
+ picman_move_pic(pm, i, pm->max_pb_size - 1);
+ pm->cur_num_ref_pics--;
+ i--; //We need to decrement i here because it will be increment by i++ at for loop. We want to keep the same i here because after the move, the current ref pic at i position is the i+1 position which we still need to check.
+ numberOfPicsToCheck--; //We also need to decrement this variable to avoid checking the moved ref picture twice.
+ }
+ }
+ }
+#if LIBVC_ON
+ // count the libpic in rpl
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+ if (pic_header->rpl_l0.library_index_flag[i]) {
+ if (count_library_picture == 0) {
+ referenced_library_picture_index = pic_header->rpl_l0.ref_pics[i];
+ count_library_picture++;
+ }
+
+ com_assert_rv(referenced_library_picture_index == pic_header->rpl_l0.ref_pics[i], COM_ERR_UNEXPECTED);
+ }
+ }
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_num; i++) {
+ if (pic_header->rpl_l1.library_index_flag[i]) {
+ if (count_library_picture == 0) {
+ referenced_library_picture_index = pic_header->rpl_l1.ref_pics[i];
+ count_library_picture++;
+ }
+
+ com_assert_rv(referenced_library_picture_index == pic_header->rpl_l1.ref_pics[i], COM_ERR_UNEXPECTED);
+ }
+ }
+
+ if (count_library_picture > 0) {
+ // move out lib pic
+ if (!pm->is_library_buffer_empty && (referenced_library_picture_index != pm->pb_libpic_library_index)) {
+ //com_picbuf_free(pm->libvc_data->pb_libpic);
+ pm->pb_libpic = NULL;
+ pm->cur_libpb_size--;
+ pm->pb_libpic_library_index = -1;
+ pm->is_library_buffer_empty = 1;
+ }
+ // move in lib pic from the buffer outside the decoder
+ if (pm->is_library_buffer_empty) {
+ //send out referenced_library_picture_index
+ int libpic_idx = -1;
+ int ii;
+ for (ii = 0; ii < pm->libvc_data->num_libpic_outside; ii++) {
+ if (referenced_library_picture_index == pm->libvc_data->list_library_index_outside[ii]) {
+ libpic_idx = ii;
+ break;
+ }
+ }
+ com_assert_rv(libpic_idx >= 0, COM_ERR_UNEXPECTED);
+
+ // move in lib pic from the buffer outside the decoder
+ pm->pb_libpic = pm->libvc_data->list_libpic_outside[libpic_idx];
+ pm->pb_libpic_library_index = referenced_library_picture_index;
+ pm->cur_libpb_size++;
+ pm->is_library_buffer_empty = 0;
+ }
+ }
+#endif
+ return COM_OK;
+}
+
+int com_construct_ref_list_doi( COM_PIC_HEADER *pic_header)
+{
+ int i;
+
+ if (pic_header == NULL)
+ return COM_ERR;
+
+ if ((pic_header->rpl_l0.ref_pic_num > MAX_NUM_REF_PICS) ||
+ (pic_header->rpl_l1.ref_pic_num > MAX_NUM_REF_PICS))
+ return COM_ERR;
+
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+ pic_header->rpl_l0.ref_pics_doi[i] = pic_header->decode_order_index%DOI_CYCLE_LENGTH - pic_header->rpl_l0.ref_pics_ddoi[i];
+ }
+ if (is_avs3_print_bufmgr_detail()) {
+ printf("rpl_l0.ref_pics_doi[%d]=%d, pic_header->rpl_l0.ref_pics_ddoi[%d]=%d\n",
+ i, pic_header->rpl_l0.ref_pics_doi[i], i, pic_header->rpl_l0.ref_pics_ddoi[i]);
+ }
+ for ( i = 0; i < pic_header->rpl_l1.ref_pic_num; i++ )
+ {
+ pic_header->rpl_l1.ref_pics_doi[i] = pic_header->decode_order_index%DOI_CYCLE_LENGTH - pic_header->rpl_l1.ref_pics_ddoi[i];
+ }
+ if (is_avs3_print_bufmgr_detail()) {
+ printf("rpl_l1.ref_pics_doi[%d]=%d, pic_header->rpl_l1.ref_pics_ddoi[%d]=%d\n",
+ i, pic_header->rpl_l1.ref_pics_doi[i], i, pic_header->rpl_l1.ref_pics_ddoi[i]);
+ }
+ return COM_OK;
+}
+
+/*This is the implementation of reference picture marking based on RPL for decoder */
+/*In decoder side, use DOI as pic reference instead of POI */
+int com_picman_refpic_marking_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header)
+{
+ int i;
+ COM_PIC * pic;
+ int numberOfPicsToCheck;
+ int count_library_picture = 0;
+ int referenced_library_picture_index = -1;
+
+ picman_update_pic_ref(pm);
+#if LIBVC_ON
+ if (!pic_header->rpl_l0.reference_to_library_enable_flag && !pic_header->rpl_l1.reference_to_library_enable_flag && pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#else
+ if (pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#endif
+ com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+
+ numberOfPicsToCheck = pm->cur_num_ref_pics;
+ for (i = 0; i < numberOfPicsToCheck; i++) {
+ pic = pm->pic[i];
+ if (pm->pic[i] && IS_REF(pm->pic[i])) {
+ //If the pic in the DPB is a reference picture, check if this pic is included in RPL0
+ int isIncludedInRPL = 0;
+ int j = 0;
+ while (!isIncludedInRPL && j < pic_header->rpl_l0.ref_pic_num) {
+#if LIBVC_ON
+ if (!pic_header->rpl_l0.library_index_flag[j] && pic->dtr == pic_header->rpl_l0.ref_pics_doi[j])
+#else
+ if ( pic->dtr == ((pic_header->decode_order_index - pic_header->rpl_l0.ref_pics_ddoi[j] + DOI_CYCLE_LENGTH) % DOI_CYCLE_LENGTH) ) //NOTE: we need to put POC also in COM_PIC
+#endif
+ {
+ isIncludedInRPL = 1;
+ }
+ j++;
+ }
+ //Check if the pic is included in RPL1. This while loop will be executed only if the ref pic is not included in RPL0
+ j = 0;
+ while (!isIncludedInRPL && j < pic_header->rpl_l1.ref_pic_num) {
+#if LIBVC_ON
+ if ( !pic_header->rpl_l1.library_index_flag[j] && pic->dtr == pic_header->rpl_l1.ref_pics_doi[j] )
+#else
+ if ( pic->dtr == ((pic_header->decode_order_index - pic_header->rpl_l1.ref_pics_ddoi[j] + DOI_CYCLE_LENGTH) % DOI_CYCLE_LENGTH) )
+#endif
+ {
+ isIncludedInRPL = 1;
+ }
+ j++;
+ }
+ //If the ref pic is not included in either RPL0 nor RPL1, then mark it as not used for reference. move it to the end of DPB.
+ if (!isIncludedInRPL) {
+ SET_REF_UNMARK(pic);
+ picman_move_pic(pm, i, pm->max_pb_size - 1);
+ pm->cur_num_ref_pics--;
+ i--; //We need to decrement i here because it will be increment by i++ at for loop. We want to keep the same i here because after the move, the current ref pic at i position is the i+1 position which we still need to check.
+ numberOfPicsToCheck--; //We also need to decrement this variable to avoid checking the moved ref picture twice.
+ }
+ }
+ }
+#if LIBVC_ON
+ // count the libpic in rpl
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+ if (pic_header->rpl_l0.library_index_flag[i]) {
+ if (count_library_picture == 0) {
+ referenced_library_picture_index = pic_header->rpl_l0.ref_pics_ddoi[i];
+ count_library_picture++;
+ }
+
+ com_assert_rv(referenced_library_picture_index == pic_header->rpl_l0.ref_pics_ddoi[i], COM_ERR_UNEXPECTED);
+ }
+ }
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_num; i++) {
+ if (pic_header->rpl_l1.library_index_flag[i]) {
+ if (count_library_picture == 0) {
+ referenced_library_picture_index = pic_header->rpl_l1.ref_pics_ddoi[i];
+ count_library_picture++;
+ }
+
+ com_assert_rv(referenced_library_picture_index == pic_header->rpl_l1.ref_pics_ddoi[i], COM_ERR_UNEXPECTED);
+ }
+ }
+
+ if (count_library_picture > 0) {
+ // move out lib pic
+ if (!pm->is_library_buffer_empty && (referenced_library_picture_index != pm->pb_libpic_library_index)) {
+ //com_picbuf_free(pm->libvc_data->pb_libpic);
+ pm->pb_libpic = NULL;
+ pm->cur_libpb_size--;
+ pm->pb_libpic_library_index = -1;
+ pm->is_library_buffer_empty = 1;
+ }
+ // move in lib pic from the buffer outside the decoder
+ if (pm->is_library_buffer_empty) {
+ //send out referenced_library_picture_index
+ int libpic_idx = -1;
+ int ii;
+ for (ii = 0; ii < pm->libvc_data->num_libpic_outside; ii++) {
+ if (referenced_library_picture_index == pm->libvc_data->list_library_index_outside[ii])
+ {
+ libpic_idx = ii;
+ break;
+ }
+ }
+ com_assert_rv(libpic_idx >= 0, COM_ERR_UNEXPECTED);
+
+ //move in the corresponding referenced library pic
+ pm->pb_libpic = pm->libvc_data->list_libpic_outside[libpic_idx];
+ pm->pb_libpic_library_index = referenced_library_picture_index;
+ pm->cur_libpb_size++;
+ pm->is_library_buffer_empty = 0;
+ }
+ }
+#endif
+ return COM_OK;
+}
+
+#endif
+
+#if LIBVC_ON
+int com_picman_put_libpic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM], COM_PIC_HEADER * pic_header)
+{
+ int i;
+ SET_REF_MARK(pic);
+ pic->temporal_id = temporal_id;
+ pic->ptr = ptr;
+ pic->dtr = dtr;
+ pic->need_for_out = (u8)need_for_output;
+
+ for (i = 0; i < pm->num_refp[REFP_0]; i++) {
+#if ETMVP || SUB_TMVP || AWP
+ pic->list_ptr[REFP_0][i] = refp[i][REFP_0].ptr;
+#else
+ pic->list_ptr[i] = refp[i][REFP_0].ptr;
+#endif
+ }
+#if ETMVP || SUB_TMVP || AWP
+ for (i = 0; i < pm->num_refp[REFP_1]; i++) {
+ pic->list_ptr[REFP_1][i] = refp[i][REFP_1].ptr;
+ }
+#endif
+
+ // move out
+ if (!pm->is_library_buffer_empty) {
+ //com_picbuf_free(pm->pb_libpic);
+ pm->pb_libpic = NULL;
+ pm->cur_libpb_size--;
+ pm->pb_libpic_library_index = -1;
+ pm->is_library_buffer_empty = 1;
+ }
+
+ // move in
+ pm->pb_libpic = pic;
+ pm->pb_libpic_library_index = pic_header->library_picture_index;
+ pm->cur_libpb_size++;
+ pm->is_library_buffer_empty = 0;
+
+ if (pm->pic_lease == pic) {
+ pm->pic_lease = NULL;
+ }
+
+ return COM_OK;
+}
+#endif
+
+int com_picman_put_pic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr,
+ u32 picture_output_delay, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM])
+{
+ /* manage RPB */
+ SET_REF_MARK(pic);
+ pic->temporal_id = temporal_id;
+ pic->ptr = ptr;
+ pic->dtr = dtr%DOI_CYCLE_LENGTH;//MX: range of 0~255
+ pic->picture_output_delay = picture_output_delay;
+ pic->need_for_out = (u8)need_for_output;
+ /* put picture into listed RPB */
+ if (IS_REF(pic)) {
+ picman_set_pic_to_pb(pm, pic, refp, pm->cur_num_ref_pics);
+ pm->cur_num_ref_pics++;
+#ifdef BUFMGR_SANITY_CHECK
+ if (pm->cur_num_ref_pics > MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("pm->cur_num_ref_pics (%d) is beyond limit, force it to %d\n",
+ pm->cur_num_ref_pics, MAX_NUM_REF_PICS);
+ pm->cur_num_ref_pics = MAX_NUM_REF_PICS;
+ }
+#endif
+ } else {
+ picman_set_pic_to_pb(pm, pic, refp, -1);
+ }
+ if (pm->pic_lease == pic) {
+ pm->pic_lease = NULL;
+ }
+ /*PRINT_DPB(pm);*/
+ return COM_OK;
+}
+#if LIBVC_ON
+int com_picman_out_libpic(COM_PIC * pic, int library_picture_index, COM_PM * pm)
+{
+ if (pic != NULL && pic->need_for_out)
+ {
+ //output to the buffer outside the decoder
+ int num_libpic_outside = pm->libvc_data->num_libpic_outside;
+ pm->libvc_data->list_libpic_outside[num_libpic_outside] = pic;
+ pm->libvc_data->list_library_index_outside[num_libpic_outside] = library_picture_index;
+ pm->libvc_data->num_libpic_outside++;
+ pic->need_for_out = 0;
+
+ return COM_OK;
+ } else {
+ return COM_ERR_UNEXPECTED;
+ }
+}
+#endif
+
+COM_PIC * com_picman_out_pic(COM_PM * pm, int * err, int cur_pic_doi, int state)
+{
+ COM_PIC ** ps;
+ int i, ret, any_need_for_out = 0;
+ BOOL exist_pic = 0;
+ int temp_smallest_poc = MAX_INT;
+ int temp_idx_for_smallest_poc = 0;
+ ps = pm->pic;
+
+ if (state != 1) {
+ for (i = 0; i < pm->max_pb_size; i++) {
+ if (ps[i] != NULL && ps[i]->need_for_out) {
+ any_need_for_out = 1;
+ if ((ps[i]->dtr + ps[i]->picture_output_delay <= cur_pic_doi)) {
+ exist_pic = 1;
+ if (temp_smallest_poc >= ps[i]->ptr)
+ {
+ temp_smallest_poc = ps[i]->ptr;
+ temp_idx_for_smallest_poc = i;
+ }
+ }
+ }
+ }
+ if (exist_pic) {
+ ps[temp_idx_for_smallest_poc]->need_for_out = 0;
+ if (err) *err = COM_OK;
+ return ps[temp_idx_for_smallest_poc];
+ }
+ } else {
+ //bumping state, bumping the pic in the DPB according to the POC number, from small to larger.
+ for (i = 0; i < pm->max_pb_size; i++) {
+ if (ps[i] != NULL && ps[i]->need_for_out) {
+ any_need_for_out = 1;
+ //Need to output the smallest poc
+ if ((ps[i]->ptr <= temp_smallest_poc)) {
+ exist_pic = 1;
+ temp_smallest_poc = ps[i]->ptr;
+ temp_idx_for_smallest_poc = i;
+ }
+ }
+ }
+ if (exist_pic) {
+ ps[temp_idx_for_smallest_poc]->need_for_out = 0;
+ if (err) *err = COM_OK;
+ return ps[temp_idx_for_smallest_poc];
+ }
+ }
+
+ if (any_need_for_out == 0) {
+ ret = COM_ERR_UNEXPECTED;
+ } else {
+ ret = COM_OK_FRM_DELAYED;
+ }
+ if (err) *err = ret;
+ return NULL;
+}
+
+int com_picman_deinit(COM_PM * pm)
+{
+ int i;
+ /* remove allocated picture and picture store buffer */
+ for (i = 0; i < pm->max_pb_size; i++) {
+ if (pm->pic[i]) {
+ com_pic_free(pm->hw, &pm->pa, pm->pic[i]);
+ pm->pic[i] = NULL;
+ }
+ }
+ if (pm->pic_lease) {
+ com_pic_free(pm->hw, &pm->pa, pm->pic_lease);
+ pm->pic_lease = NULL;
+ }
+
+ pm->cur_num_ref_pics = 0;
+
+#if LIBVC_ON
+ if (pm->pb_libpic) {
+ pm->pb_libpic = NULL;
+ }
+ pm->cur_libpb_size = 0;
+ pm->pb_libpic_library_index = -1;
+ pm->is_library_buffer_empty = 1;
+#endif
+ return COM_OK;
+}
+
+int com_picman_init(COM_PM * pm, int max_pb_size, int max_num_ref_pics, PICBUF_ALLOCATOR * pa)
+{
+ if (max_num_ref_pics > MAX_NUM_REF_PICS || max_pb_size > MAX_PB_SIZE) {
+ return COM_ERR_UNSUPPORTED;
+ }
+ spin_lock_init(&pm->pm_lock);
+ pm->max_num_ref_pics = max_num_ref_pics;
+ pm->max_pb_size = max_pb_size;
+ pm->ptr_increase = 1;
+ pm->pic_lease = NULL;
+ com_mcpy(&pm->pa, pa, sizeof(PICBUF_ALLOCATOR));
+#if LIBVC_ON
+ pm->pb_libpic = NULL;
+ pm->cur_libpb_size = 0;
+ pm->pb_libpic_library_index = -1;
+ pm->is_library_buffer_empty = 1;
+#endif
+ return COM_OK;
+}
+
+int com_picman_check_repeat_doi(COM_PM * pm, COM_PIC_HEADER * pic_header)
+{
+ COM_PIC * pic;
+ int i;
+ for (i = 0; i < pm->max_pb_size; i++) {
+ pic = pm->pic[i];
+ if (pic != NULL) {
+ assert(pic->dtr != pic_header->decode_order_index);//the DOI of current frame cannot be the same as the DOI of pic in DPB.
+ }
+ }
+ return COM_OK;
+}
+
+void com_picman_print_state(COM_PM * pm)
+{
+ COM_PIC * pic;
+ char tmpbuf[128];
+ int i, ii, j;
+ printf("pm->pic:\n");
+ for (i = 0; i < pm->max_pb_size; i++) {
+ pic = pm->pic[i];
+ if (pic != NULL) {
+ int pos = 0;
+ for (ii = 0; ii < 2; ii++) {
+ pos += sprintf(&tmpbuf[pos], "(");
+ for (j = 0; j < MAX_NUM_REF_PICS; j++)
+ pos += sprintf(&tmpbuf[pos], "%d ", pic->list_ptr[ii][j]);
+ pos += sprintf(&tmpbuf[pos], ")");
+ }
+
+ printf("%d: pic %p index %d dtr %d ptr %d is_ref %d need_for_out %d, backend_ref %d, vf_ref %d, output_delay %d, w/h(%d,%d) id %d, list_ptr %s\n",
+ i, pic, pic->buf_cfg.index, pic->dtr, pic->ptr, pic->is_ref,
+ pic->need_for_out, pic->buf_cfg.backend_ref, pic->buf_cfg.vf_ref,
+ pic->picture_output_delay,
+ pic->width_luma, pic->height_luma, pic->temporal_id,
+ tmpbuf);
+ }
+ }
+}
diff --git a/drivers/frame_provider/decoder/avs3/com_port.h b/drivers/frame_provider/decoder/avs3/com_port.h
new file mode 100644
index 0000000..a239d9c
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_port.h
@@ -0,0 +1,152 @@
+/* ====================================================================================================================
+
+ The copyright in this software is being made available under the License included below.
+ This software may be subject to other third party and contributor rights, including patent rights, and no such
+ rights are granted under this license.
+
+ Copyright (c) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+ Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+ Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted only for
+ the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+ promoting such standards. The following conditions are required to be met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_PORT_H_
+#define _COM_PORT_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+ * types
+ *****************************************************************************/
+typedef s16 pel; /* pixel type */
+typedef s32 double_pel; /* pixel type */
+
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+/*****************************************************************************
+ * limit constant
+ *****************************************************************************/
+#define COM_UINT16_MAX ((u16)0xFFFF)
+#define COM_UINT16_MIN ((u16)0x0)
+#define COM_INT16_MAX ((s16)0x7FFF)
+#define COM_INT16_MIN ((s16)0x8000)
+
+#define COM_UINT_MAX ((u32)0xFFFFFFFF)
+#define COM_UINT_MIN ((u32)0x0)
+#define COM_INT_MAX ((int)0x7FFFFFFF)
+#define COM_INT_MIN ((int)0x80000000)
+
+#define COM_UINT32_MAX ((u32)0xFFFFFFFF)
+#define COM_UINT32_MIN ((u32)0x0)
+#define COM_INT32_MAX ((s32)0x7FFFFFFF)
+#define COM_INT32_MIN ((s32)0x80000000)
+
+#define COM_UINT64_MAX ((u64)0xFFFFFFFFFFFFFFFFL)
+#define COM_UINT64_MIN ((u64)0x0L)
+#define COM_INT64_MAX ((s64)0x7FFFFFFFFFFFFFFFL)
+#define COM_INT64_MIN ((s64)0x8000000000000000L)
+
+#define COM_INT18_MAX ((s32)(131071))
+#define COM_INT18_MIN ((s32)(-131072))
+
+/*****************************************************************************
+ * memory operations
+ *****************************************************************************/
+#define com_malloc(size) malloc((size))
+#define com_malloc_fast(size) com_malloc((size))
+
+#define com_mfree(m) if (m) {free(m);}
+#define com_mfree_fast(m) if (m) {com_mfree(m);}
+
+#define com_mcpy(dst,src,size) memcpy((dst), (src), (size))
+#define com_mset(dst,v,size) memset((dst), (v), (size))
+#define com_mset_x64a(dst,v,size) memset((dst), (v), (size))
+#define com_mset_x128(dst,v,size) memset((dst), (v), (size))
+#define com_mcmp(dst,src,size) memcmp((dst), (src), (size))
+static __inline void com_mset_16b(s16 * dst, s16 v, int cnt)
+{
+ int i;
+ for (i=0; i<cnt; i++)
+ dst[i] = v;
+}
+
+/*****************************************************************************
+ * trace and assert
+ *****************************************************************************/
+#ifndef COM_TRACE
+#define COM_TRACE 0
+#endif
+
+/* print function */
+#if defined(LINUX)
+#define com_print(args...) printf(args)
+#else
+#define com_print(args,...) printf(args,__VA_ARGS__)
+#endif
+
+/* trace function */
+#if COM_TRACE
+#define com_trace com_print("[%s:%d] ", __FILE__, __LINE__); com_print
+#else
+#if defined(LINUX)
+#define com_trace(args...) {}
+#else
+#define com_trace(...) {}
+#endif
+#endif
+
+/* assert function */
+//#include <assert.h>
+#define com_assert(x) \
+ {if (!(x)) {assert(x);}}
+#define com_assert_r(x) \
+ {if (!(x)) {assert(x); return;}}
+#define com_assert_rv(x,r) \
+ {if (!(x)) {assert(x); return (r);}}
+#define com_assert_g(x,g) \
+ {if (!(x)) {assert(x); goto g;}}
+#define com_assert_gv(x,r,v,g) \
+ {if (!(x)) {assert(x); (r)=(v); goto g;}}
+
+#ifdef X86_SSE
+#if defined(WIN32) || defined(WIN64)
+#include <emmintrin.h>
+#include <xmmintrin.h>
+#include <tmmintrin.h>
+#include <smmintrin.h>
+#else
+//#include <x86intrin.h>
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COM_PORT_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/com_typedef.h b/drivers/frame_provider/decoder/avs3/com_typedef.h
new file mode 100644
index 0000000..459a0f7
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_typedef.h
@@ -0,0 +1,713 @@
+/* ====================================================================================================================
+
+ The copyright in this software is being made available under the License included below.
+ This software may be subject to other third party and contributor rights, including patent rights, and no such
+ rights are granted under this license.
+
+ Copyright (c) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+ Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+ Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted only for
+ the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+ promoting such standards. The following conditions are required to be met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_H_
+#define _COM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define HPM_VERSION "10.0"
+
+/* AVS3 phase-2 macros*/
+//intra
+#define EIPM 1 // M4993: extended intra prediction mode
+#define MIPF 1 // M5079: multiple intra prediction filter
+#define PMC 1 // M5158: Prediction from Multiple Cross-components
+#define IPF_CHROMA 1 // M5385 M5418: enable intrapf for chroma components
+#define IIP 1 // M5826: Improved Intra Prediction
+//inter
+#define DMVR 1 // M4813: decoder-side motion vector refinement
+#define BIO 1 // M4762: Bi-directional Optical Flow
+#define BGC 1 // M5398: Bi-directional Gradient Correction
+#define INTERPF 1 // M4812: inter prediction filtering
+#define MVAP 1 // M4926: motion vector angel prediction
+#define AFFINE_UMVE 1 // M5095: Enhanced Affine Skip/Direct Mode
+#define AWP 1 // M5142: angular weighted prediction & M5143: AWP list construction optimization
+#define ETMVP 1 // M5330(CE2-1.1):Enhanced temporal motion vector prediction
+#define UMVE_ENH 1 // M5379: enable the combination of interPF and UMVE modes; picture-level UMVE offset adaptation
+#define SUB_TMVP 1 // M5396(CE2-2.1) + M5397: NxN subblock TMVP
+#define ASP 1 // M5801 (CE2-3.2): affine secondary prediction
+//transform & quantization
+#define IST 1 // M4772: implicit selection of transforms for intra residual
+#define SBT 1 // M4876: sub-block transform for inter residual
+#define EST 1 // M5159: Enhanced Secondary Transform
+#define ST_CHROMA 1 // M5874: Secondary transform for intra chroma residual
+#define CUDQP 1 // M5877: cu-level qp adjustment
+//residual coding & CABAC
+#define SRCC 1 // M4763: scan region based coefficient coding
+#define CABAC_MULTI_PROB 1 // M4867 M5139: counter-based multi-probability CABAC
+//scc tools (off for class A/B/C in CTC, and enabled for scc seqs)
+#define USE_IBC 1 // M4859: intra block copy [cannot off now]
+#define FIMC 1 // M4972: frequency-based intra mode coding
+#if IST
+#define ISTS 1 // M5160: Implicit Selection of Transform Skip
+#endif
+#define USE_SP 1 // M5226: String Prediction
+#if ISTS
+#define TS_INTER 1 // M5601: Transform skip for inter-coded blocks
+#define ETS 1 // M5954: Extended Transform Skip
+#endif
+// in-loop filter tools
+#define ESAO 1 // M5374: Enhanced Sample Adaptive Offset
+#define DBR 1 // M5587: deblocking refinement
+#define ALF_SHAPE 1 // M5589: increased ALF coefficient
+#define ALF_IMP 1 // M5964: ALF improvements
+#define CCSAO 1 // M5800: Cross-component Sample Adaptive Offset
+#define DBK_SCC 1 // M5221 + M5869: improved deblock filter
+
+//detailed change on each new coding tool
+#if DBK_SCC
+#define DBK_OPT 1 // M5869(CE2-2.1): improve deblock filter
+#endif
+
+#if SBT
+#define ISBT 1 // M5952: Implicit signaling for SBT
+#endif
+
+#if IIP
+#define IIP_BUGFIX 1 // bug fix for iip codes, change the performance of HPM9.1
+#endif
+
+#if PMC
+#define EPMC 1 // M5659: extended PMC
+#endif
+
+#if AWP
+#define AWP_MVR 1 // M5380: angular weighted prediction with motion vector refinement
+#endif
+
+#if CUDQP
+#define CUDQP_QP_MAP 1 // generate 16x16 QP map based on texture variance
+#define CUDQP_PLATFORM_BUGFIX 1 // [Note]: can be cleaned up in next HPM version
+#define ONLY_ONE_DQP 1 // only one delta QP in one QG (useful as 0 for conformance test, since we support multiple QPs in one QG)
+#endif
+
+#if ESAO
+#define ESAO_PH_SYNTAX 1
+#endif
+
+#if CCSAO
+#define CCSAO_PH_SYNTAX 1
+#if CCSAO_PH_SYNTAX
+#define CCSAO_ENHANCEMENT 1 // M6051: alternative set and chroma BO for CCSAO
+#endif
+#endif
+
+#if USE_IBC
+#define IBC_REF_POS_CONS 1 // M4940: position constraint of reference block in IBC mode
+#define IBC_ABVR 1 // M5070: IBC adaptive block vector resolution
+#define IBC_BVP 1 // M5081: IBC block vector prediction
+#define CBVP_LIST_SIMP 1 // M5810: simplification of CBVP list construction
+#define SIBC 1 // M5976: symmetric intra block copy
+#define BVD_CODING 1 // M5961: modification of BVD coding
+#endif
+
+#if USE_SP
+#define SP_SVP 0 // M5613: SP string vector prediction
+#define SP_SLR 1 // M5631: control of SP string length resolution
+#define SP_CU_BUGFIX 1 // M5611: cu block string prediction Tree_L distortion miss shift right
+#define SP_CODE_TEXT_BUGFIX 1 // M5669: fix on the inconsistency between code and text for SP
+#define EVS_UBVS_MODE 1 // M5822: add evs_ubvs (equal value string and unit basic vector string) SP sub-mode
+#define SP_REF_OVERLAP 1 // M5994: allow the reference string above to overlap with current string
+#define SP_DEC_SV_CHECK 1 // M5864: check if string vector valid within search range
+#endif
+
+//code optimization
+#if EST
+#define EST_BUGFIX 1 // M5944:EST bugfix
+#endif
+
+#define ALF_DEC_OPT 1 // M5589: Remove unnecessary judgments in the filtering process
+#define INTER_ME_MVLIB 1 // M5527: improved EPZS motion estimation based on motion vector library
+#define ENC_ME_IMP 1 // M5806: gradient-based motion estimation and affine CPMV library
+#define ETMVP_FLAG_BUG_FIX 1 // M5886: add necessary condition for etmvp flag coding
+
+#define AFFINE_UMVE_OPT 1 //M5812: speedup for affine umve
+
+#define AWP_MVR_ENCODER_OPT 1 // M5871: improve AWP_MVR idx cost estimation
+
+#if USE_IBC && USE_SP
+#define SCC_CROSSINFO_UTILIZE 1 // M5605: SCC cross info utilize
+#endif
+
+#if USE_SP
+#define SP_BUGFIX 1 // M5679: SP encoder bugfix
+#define SP_ALIGN_SIGN_BUGFIX 1 // M5822: SP encoder bugfix
+#define SP_SV_ENCODE_BUGIFX 1 // M5934: SP encode bugfix
+#if SP_SLR
+#define SP_SLR_BUGFIX 1 // M5783: SP SLR bugfix
+#endif
+#define SP_FLAG_BUGFIX 1 // M5992: encoder bugfix related to SP flag
+#endif
+#define SCC_BUGFIX 1 // M5821: SCC encoder bugfix
+#define SCC_BUGFIX2 1 // M5882: SCC encoder bugfix
+#if SCC_BUGFIX2
+#define IBC_RDO_BUGFIX 1
+#define SP_RDO_BUGFIX 1
+#define CS_RDO_BUGFIX 1
+#endif
+
+#define REUSE_CU_SPLIT_OPT 1 // M5900: Adjust threshold for reusing cu results
+
+#define REFORMAT_HASH_RATIO 1 // fix issue 152: multiple calculation of hash ratio
+
+#define BITSTREAM_MERGE_BUGFIX 1 // M5867: bugfix for bitstream merge
+
+//high-level
+#define PHASE_2_PROFILE 1 //
+/*end of AVS phase-2 macros*/
+
+/* ------------------------BELOW HERE is related to AVS3 phase 1 -----------------------*/
+/*non-normative bugfix for AVS3 phase-1 after HPM4.0.1 (if any, add here) */
+
+/*end of non-normative bugfix */
+
+/*normative bugfix for AVS3 phase-1 after HPM4.0.1 (if any, add here) */
+
+/*end of normative bugfix */
+
+//high level syntax
+#define WRITE_MD5_IN_USER_DATA 1 // write per-frame MD5 into user_data after picture header
+#define REPEAT_SEQ_HEADER 1 // add sequence header before each I frame
+
+#define HLS_RPL 1
+#if HLS_RPL
+#define DOI_CYCLE_LENGTH 256 // the length of the DOI cycle.
+#endif
+
+#define PATCH 1
+#if PATCH
+#define PATCH_M4839 1
+#define PATCH_HEADER_PARAM_TEST 0 // different patches have different patch-header patch_sao_enable_flag parameters
+#endif
+
+//partition
+#define EQT 1
+//debug
+#define SPLIT_DEBUG 1 // some debug code to check the split
+#define PLATFORM_GENERAL_DEBUG 1 // some key check points at encoder for detecting potential bugs
+/* --------------------------- conformance test related, start -------------------------------------*/
+#define PRINT_SQH_PARAM_DEC 1
+#define FIXED_SPLIT 0 // fixed split pattern [must be OFF in formal test] <<<<<<<<<----------NOTE
+#if FIXED_SPLIT
+#define FS_ALL_COMBINATION 0 // test split combination of 6 depth
+#if FS_ALL_COMBINATION
+#define START_QT_DEPTH 0
+#define START_SPLIT_MODE 0 // 0: not constrain; 1~5: constrain 1 split at start qt depth
+#define VERIFY_SPLIT 0 // print target split combination for each CTU
+#define FS_SIMPLE_ORDER 1 // simple order of split modes (from smallest mode value to the largest)
+#endif
+#define FS_SAME_SIZE_PER_X_CTU 1 // constrained size changed per X CTUs
+#if FS_SAME_SIZE_PER_X_CTU
+#define FS_SAME_SIZE_X_VAL 1 // can be any value larger than 0
+#endif
+#endif
+/* --------------------------- conformance test related, end -------------------------------------*/
+
+//coding mode constraint for region of 64 pixels
+#define MODE_CONS 1 // [this macro cannot be off]
+//chroma no split for avoiding 2xN chroma blocks
+#define CHROMA_NOT_SPLIT 1 // [this macro cannot be off]
+
+//for DT and PBT
+#define TB_SPLIT_EXT 1 // extend the framework to support multiple luma prediction & transform blocks (support PBT and Intra DT) [this macro cannot be off]
+#if TB_SPLIT_EXT
+//fast algorithm (common)
+#define TR_SAVE_LOAD 1 // fast algorithm for PBT
+#define TR_EARLY_TERMINATE 1 // fast algorithm for PBT
+#endif
+#define DT_PARTITION 1 // [this macro cannot be off] (DT can be turn off ONLY by configure)
+#if DT_PARTITION
+#define DT_SYNTAX 1 // syntax change to support DT (must be 1)
+//DT_INTRA
+#define DT_INTRA_FAST_BY_RD 1 // fast algorithm: early skip based on RD cost comparison
+#define DT_SAVE_LOAD 1 // fast algorithm: save & load best part_size
+#endif
+#define PRINT_CU 0
+#define PRINT_CU_LEVEL_2 0
+#define PRINT_HMVP_FIFO 0
+#define PRINT_TRANSFORM_TABLE 0
+#define DEBUG_TEST_CHANGE_HORI_VERT_SIZE 0 //change horizontal_size and vertical_size to (8xN-1) in sqh coding
+#define PSNR_1020 0 //use 1020 as peak value for 10-bit picture in PSNR calculation (for comparing PSNR with HM and VTM)
+//**************** This part needs clean-up later (End)
+
+//intra
+#define TSCPM 1
+#if TSCPM
+#define ENHANCE_TSPCM 1
+#endif
+#define IPCM 1
+
+//inter
+#define BD_AFFINE_AMVR 1 // M4565 combine Affine and AMVR
+
+#define EXT_AMVR_HMVP 1
+
+#define SMVD 1 // Symmetric MVD mode
+
+#define INTER_CU_CONSTRAINT 1
+
+#define SEP_CONTEXT 1 // Separate context for useless bin
+
+//transform
+
+// filter
+#define DEBLOCK_M4647 1
+
+// others
+#define USE_RDOQ 1 // Use RDOQ
+#define RDO_DBK 1 // include DBK changes to luma samples into distortion
+#if RDO_DBK
+#define RDO_DBK_LUMA_ONLY 1 // M5315: DBK encoder speed up
+#endif
+
+#define AFFINE_MVF_VERIFY 0 // for debugging, clean up later
+
+#define CPMV_BIT_DEPTH 18
+#if CPMV_BIT_DEPTH == 18
+typedef int CPMV;
+#else
+typedef short CPMV;
+#endif
+#define COM_CPMV_MAX ((s32)((1<<(CPMV_BIT_DEPTH - 1)) - 1))
+#define COM_CPMV_MIN ((s32)(-(1<<(CPMV_BIT_DEPTH - 1))))
+
+#define LIBVC_ON 1 // use Library Picture
+#if LIBVC_ON
+#define IPPPCRR 1
+#if IPPPCRR
+#define PB_REF_LIB 1
+#define LIB_PIC_UPDATE 1 // M5422 adaptive library picture update
+#endif
+#define CRR_ENC_OPT_CFG 1 // M5533 CRR encoding optimization about configuration
+#endif
+#define EXTENSION_USER_DATA 1
+#if EXTENSION_USER_DATA
+#define CRR_EXTENSION_DATA 1 // M4822: cross random-access-point referencing extension
+#define HLS_12_6_7 0 // write sequence display extension data into bitstream
+#define HLS_12_8 0 // write CRR extension data into bitstream
+#endif
+
+#define WEIGHTED_SATD 1 // M5382: Improved SATD based cost calculation
+
+//fast algorithm
+#define ENC_ECU_DEPTH 4 // for early CU termination
+#define ENC_ECU_ADAPTIVE 1 // for early CU termination
+#define MULTI_REF_ME_STEP 1 // for ME speed-up
+#define FAST_LD 1 // M5557: fast me for lowdelay case
+#define BET_SPLIT_DECISION 1 // M5965: Test2, fast BET split decision based on QT split result
+
+//bbv
+#define BBV 1 // for Bitstream Buffer verifies
+#if BBV
+#define BBV_DELAY_MAX 0xFFFFFFFF
+#define BBV_CHECK_FRAMES_MAX 2000
+#define BBV_LIBVC 1 // whether the bbv is with libvc
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// //
+// SIMD Optimizations //
+// //
+////////////////////////////////////////////////////////////////////////////////
+#define X86_SSE 1
+#if X86_SSE
+#define SIMD_MC 1
+#define SIMD_SAD 1
+#define SIMD_SSD 1
+#define SIMD_DIFF 1
+#define SIMD_HAD_SAD 1
+#define SIMD_AFFINE 1
+#if ASP
+#define SIMD_ASP 1
+#endif // ASP
+#if ENC_ME_IMP
+#define SIMD_GRAD_ME 1
+#endif
+#else
+#define SIMD_MC 0
+#define SIMD_SAD 0
+#define SIMD_SSD 0
+#define SIMD_DIFF 0
+#define SIMD_HAD_SAD 0
+#define SIMD_AFFINE 0
+#if ASP
+#define SIMD_ASP 0
+#endif // ASP
+#if ENC_ME_IMP
+#define SIMD_GRAD_ME 0
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// Certain Tools Parameters //
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+#define INC_QT_DEPTH(qtd, smode) (smode == SPLIT_QUAD? (qtd + 1) : qtd)
+#define INC_BET_DEPTH(betd, smode) (smode != SPLIT_QUAD? (betd + 1) : betd)
+
+#if EQT
+#define MAX_SPLIT_NUM 6
+#define SPLIT_CHECK_NUM 6
+#else
+#define MAX_SPLIT_NUM 4
+#define SPLIT_CHECK_NUM 4
+#endif
+
+/*****************************************************************************
+ * return values and error code
+ *****************************************************************************/
+/* no more frames, but it is OK */
+#define COM_OK_NO_MORE_FRM (205)
+/* progress success, but output is not available temporarily */
+#define COM_OK_OUT_NOT_AVAILABLE (204)
+/* frame dimension (width or height) has been changed */
+#define COM_OK_DIM_CHANGED (203)
+/* decoding success, but output frame has been delayed */
+#define COM_OK_FRM_DELAYED (202)
+#if IPPPCRR&&LIB_PIC_UPDATE
+#define RL_UPDATE_TO_LIBPIC (2)
+#define COM_OK_SKIP (3)
+#endif
+#define COM_OK (0)
+#define END_OF_VIDEO_SEQUENCE (206)
+#define NOT_END_OF_VIDEO_SEQUENCE (207)
+
+#define COM_ERR (-1) /* generic error */
+#define COM_ERR_INVALID_ARGUMENT (-101)
+#define COM_ERR_OUT_OF_MEMORY (-102)
+#define COM_ERR_REACHED_MAX (-103)
+#define COM_ERR_UNSUPPORTED (-104)
+#define COM_ERR_UNEXPECTED (-105)
+#define COM_ERR_BAD_CRC (-130) /* not matched CRC value */
+
+#define COM_ERR_UNSUPPORTED_COLORSPACE (-201)
+#define COM_ERR_MALFORMED_BITSTREAM (-202)
+
+#define COM_ERR_UNKNOWN (-32767) /* unknown error */
+
+/* return value checking *****************************************************/
+#define COM_SUCCEEDED(ret) ((ret) >= 0)
+#define COM_FAILED(ret) ((ret) < 0)
+
+/* YUV planar ****************************************************************/
+#define COM_COLORSPACE_YUV400 300 /* Y 8bit */
+#define COM_COLORSPACE_YUV420 301 /* YUV420 8bit */
+#define COM_COLORSPACE_YUV422 302 /* YUV422 8bit narrow chroma*/
+#define COM_COLORSPACE_YUV444 303 /* YUV444 8bit */
+#define COM_COLORSPACE_YUV422N COM_COLORSPACE_YUV422
+#define COM_COLORSPACE_YUV422W 310 /* YUV422 8bit wide chroma */
+
+#define COM_COLORSPACE_YUV400A8 400 /* Y+alpha 8bit */
+#define COM_COLORSPACE_YUV420A8 401 /* YUV420+alpha 8bit */
+#define COM_COLORSPACE_YUV422A8 402 /* YUV422+alpha 8bit narrow chroma*/
+#define COM_COLORSPACE_YUV444A8 403 /* YUV444+alpha 8bit */
+#define COM_COLORSPACE_YUV422NA8 COM_COLORSPACE_YUV422A8
+#define COM_COLORSPACE_YUV422WA8 414 /* YUV422+alpha 8bit wide chroma*/
+
+/* RGB pack ******************************************************************/
+
+/* RGB pack 8bit */
+#define COM_COLORSPACE_RGB888 2200
+#define COM_COLORSPACE_BGR888 2201
+
+#define COM_COLORSPACE_RGBA8888 2220
+#define COM_COLORSPACE_BGRA8888 2221
+#define COM_COLORSPACE_ARGB8888 2222
+#define COM_COLORSPACE_ABGR8888 2223
+
+/*****************************************************************************
+ * config types for decoder
+ *****************************************************************************/
+#define DEC_CFG_SET_USE_PIC_SIGNATURE (301)
+
+/*****************************************************************************
+ * chunk type
+ *****************************************************************************/
+#define COM_CT_UNKNOWN (0)
+#define COM_CT_PICTURE (1) /* picture header */
+#define COM_CT_SQH (2) /* sequence header */
+#define COM_CT_SLICE (3) /* slice header */
+#define COM_CT_SIGN (6) /* picture signature */
+#define COM_CT_SEQ_END (7)
+
+/*****************************************************************************
+ * slice type
+ *****************************************************************************/
+#define COM_ST_UNKNOWN (0)
+#define COM_ST_I (1)
+#define COM_ST_P (2)
+#define COM_ST_B (3)
+
+/*****************************************************************************
+ * software version
+ *****************************************************************************/
+#define COM_VER_1 (1)
+
+/*****************************************************************************
+ * type and macro for media time
+ *****************************************************************************/
+/* media time in 100-nanosec unit */
+typedef long long COM_MTIME;
+
+/*****************************************************************************
+ * image buffer format
+ *****************************************************************************
+ baddr
+ +---------------------------------------------------+ ---
+ | | ^
+ | | | |
+ | a v | |
+ | --- +-----------------------------------+ --- | |
+ | ^ | (x, y) | y | |
+ | | | +---------------------------+ + --- | |
+ | | | | | | ^ | |
+ | | | | | | | | |
+ | | | | | | | | |
+ | | | | | | | | |
+ | | | | | |
+ | ah | | | | h | e
+ | | | | | |
+ | | | | | | | | |
+ | | | | | | | | |
+ | | | | | | v | |
+ | | | +---------------------------+ | --- | |
+ | v | | | |
+ | --- +---+-------------------------------+ | |
+ | ->| x |<----------- w ----------->| | |
+ | |<--------------- aw -------------->| | |
+ | | v
+ +---------------------------------------------------+ ---
+
+ |<---------------------- stride-------------------->|
+
+ *****************************************************************************/
+
+#define COM_IMGB_MAX_PLANE (4)
+
+typedef struct _COM_IMGB COM_IMGB;
+struct _COM_IMGB
+{
+ int cs; /* color space */
+ int np; /* number of plane */
+ int horizontal_size;
+ int vertical_size;
+ /* width (in unit of pixel) */
+ int width[COM_IMGB_MAX_PLANE];
+ /* height (in unit of pixel) */
+ int height[COM_IMGB_MAX_PLANE];
+ /* buffer stride (in unit of byte) */
+ int stride[COM_IMGB_MAX_PLANE];
+ /* address of each plane */
+ void * addr_plane[COM_IMGB_MAX_PLANE];
+
+ /* time-stamps */
+ COM_MTIME ts[4];
+
+ /* aligned width (in unit of pixel) */
+ int width_aligned[COM_IMGB_MAX_PLANE];
+ /* aligned height (in unit of pixel) */
+ int height_aligned[COM_IMGB_MAX_PLANE];
+
+ /* left padding size (in unit of pixel) */
+ int pad_left[COM_IMGB_MAX_PLANE];
+ /* right padding size (in unit of pixel) */
+ int pad_right[COM_IMGB_MAX_PLANE];
+ /* up padding size (in unit of pixel) */
+ int pad_up[COM_IMGB_MAX_PLANE];
+ /* bottom padding size (in unit of pixel) */
+ int pad_down[COM_IMGB_MAX_PLANE];
+
+ /* address of actual allocated buffer */
+ void * buf_addr[COM_IMGB_MAX_PLANE];
+ /* actual allocated buffer size */
+ int buf_size[COM_IMGB_MAX_PLANE];
+
+ /* life cycle management */
+ int refcnt;
+ int (*addref)(COM_IMGB * imgb);
+ int (*getref)(COM_IMGB * imgb);
+ int (*release)(COM_IMGB * imgb);
+};
+
+/*****************************************************************************
+ * Bitstream buffer
+ *****************************************************************************/
+typedef struct _COM_BITB
+{
+ /* user space address indicating buffer */
+ void * addr;
+ void * addr2;
+ /* physical address indicating buffer, if any */
+ void * pddr;
+ /* byte size of buffer memory */
+ int bsize;
+ /* byte size of bitstream in buffer */
+ int ssize;
+ /* bitstream has an error? */
+ int err;
+ /* arbitrary data, if needs */
+ int ndata[4];
+ /* arbitrary address, if needs */
+ void * pdata[4];
+ /* time-stamps */
+ COM_MTIME ts[4];
+
+} COM_BITB;
+
+/*****************************************************************************
+ * description for creating of decoder
+ *****************************************************************************/
+typedef struct _DEC_CDSC
+{
+ int __na; /* nothing */
+} DEC_CDSC;
+
+/*****************************************************************************
+ * status after decoder operation
+ *****************************************************************************/
+typedef struct _DEC_STAT
+{
+ /* byte size of decoded bitstream (read size of bitstream) */
+ int read;
+ /* chunk type */
+ int ctype;
+ /* slice type */
+ int stype;
+ /* frame number monotonically increased whenever decoding a frame.
+ note that it has negative value if the decoded data is not frame */
+ int fnum;
+ /* picture order count */
+ int poc;
+ /* number of reference pictures */
+ int refpic_num[2];
+ /* list of reference pictures */
+ int refpic[2][16];
+#if LIBVC_ON
+ /* is only ref libpic */
+ int is_RLpic_flag;
+#if IPPPCRR
+ int reflib[2][16];
+#endif
+#endif
+ /* for printing sqh parameter */
+#if PRINT_SQH_PARAM_DEC
+ /* framework param */
+#if PHASE_2_PROFILE
+ int profile_id;
+#endif
+ int internal_bit_depth;
+ /* tools */
+ int intra_tools;
+ int inter_tools;
+ int trans_tools;
+ int filte_tools;
+ int scc_tools;
+#endif
+} DEC_STAT;
+
+/*****************************************************************************
+ * status after encoder operation
+ *****************************************************************************/
+typedef struct _ENC_STAT
+{
+ /* encoded bitstream byte size */
+ int write;
+ /* picture number increased whenever encoding a frame */
+ unsigned long fnum;
+ /* chunk type */
+ int ctype;
+ /* slice type */
+ int stype;
+ /* quantization parameter used for encoding */
+ int qp;
+ /* picture order count */
+ int poc;
+ /* number of reference pictures */
+ int refpic_num[2];
+ /* list of reference pictures */
+ int refpic[2][16];
+#if LIBVC_ON
+ /* is only ref libpic */
+ int is_RLpic_flag;
+#if IPPPCRR
+ int reflib[2][16];
+#endif
+#endif
+} ENC_STAT;
+
+#define MAX_NUM_REF_PICS 17
+#define MAX_NUM_ACTIVE_REF_FRAME 4
+#define MAX_NUM_RPLS 32
+
+//extern int g_CountDOICyCleTime; // number to count the DOI cycle time.
+//extern int g_DOIPrev; // the doi of previous frm.
+
+#if HLS_RPL
+/* rpl structure */
+typedef struct _COM_RPL
+{
+ int slice_type;
+ int poc;
+ int tid;
+ int ref_pic_num;
+ int ref_pic_active_num;
+ int ref_pics[MAX_NUM_REF_PICS];
+ int ref_pics_ddoi[MAX_NUM_REF_PICS];
+ int ref_pics_doi[MAX_NUM_REF_PICS];//ref pic list, doi info
+#if LIBVC_ON
+ int reference_to_library_enable_flag;
+ int library_index_flag[MAX_NUM_REF_PICS];
+#endif
+} COM_RPL;
+#endif
+/*****************************************************************************
+ * API for decoder only
+ *****************************************************************************/
+/* instance identifier for decoder */
+typedef void * DEC;
+
+DEC dec_create(DEC_CDSC * cdsc, int * err);
+void dec_delete(DEC id);
+int dec_decode(DEC id, COM_BITB * bitb, DEC_STAT * stat);
+int dec_config(DEC id, int cfg, void * buf, int * size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COM_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/dec_eco.c b/drivers/frame_provider/decoder/avs3/dec_eco.c
new file mode 100644
index 0000000..9bb32a3
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/dec_eco.c
@@ -0,0 +1,1674 @@
+/* ====================================================================================================================
+
+ The copyright in this software is being made available under the License included below.
+ This software may be subject to other third party and contributor rights, including patent rights, and no such
+ rights are granted under this license.
+
+ Copyright (c) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+ Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+ Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted only for
+ the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+ promoting such standards. The following conditions are required to be met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+* ====================================================================================================================
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/frame_sync/tsync.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "avs3_global.h"
+//#define param_proc(mark, index, val) val
+int aml_print_header_info;
+
+#define AML
+#if HLS_RPL
+#if LIBVC_ON
+int dec_eco_rlp(union param_u *param, COM_RPL * rpl, COM_SQH * sqh)
+#else
+int dec_eco_rlp(union param_u *param, COM_RPL * rpl)
+#endif
+{
+#ifndef AML
+#if LIBVC_ON
+ int ddoi_base = 0;
+ int i;
+
+ rpl->reference_to_library_enable_flag = 0;
+ if (sqh->library_picture_enable_flag)
+ {
+ rpl->reference_to_library_enable_flag = param->p.rpl_reference_to_library_enable_flag;
+ if (aml_print_header_info) printf(" * 18-bits reference_to_library_enable_flag : %d\n", rpl->reference_to_library_enable_flag);
+ }
+ else {
+ if (aml_print_header_info) printf(" * set reference_to_library_enable_flag : %d\n", rpl->reference_to_library_enable_flag);
+ }
+#endif
+
+ rpl->ref_pic_num = (u32)param->p.rpl_ref_pic_num;
+ if (aml_print_header_info) printf(" * UE ref_pic_num : %d\n", rpl->ref_pic_num);
+ //note, here we store DOI of each ref pic instead of delta DOI
+ if (rpl->ref_pic_num > 0)
+ {
+#if LIBVC_ON
+ rpl->library_index_flag[0] = 0;
+ if (sqh->library_picture_enable_flag && rpl->reference_to_library_enable_flag)
+ {
+ rpl->library_index_flag[0] = param->p.rpl_library_index_flag[0];
+ if (aml_print_header_info) printf(" * 1-bit library_index_flag[0] : %d\n", rpl->library_index_flag[0]);
+ }
+ else {
+ if (aml_print_header_info) printf(" * set library_index_flag[0] : %d\n", rpl->library_index_flag[0]);
+ }
+ if (sqh->library_picture_enable_flag && rpl->library_index_flag[0])
+ {
+ rpl->ref_pics_ddoi[0] = (u32)param->p.rpl_ref_pics_ddoi[0];
+ if (aml_print_header_info) printf(" * UE ref_pics_ddoi[0] : %d\n", rpl->ref_pics_ddoi[0]);
+ }
+ else
+#endif
+ {
+#ifdef ORI_CODE
+ rpl->ref_pics_ddoi[0] = (u32)com_bsr_read_ue(bs);
+ if (aml_print_header_info) printf(" * UE abs_doi[0] : %d\n", rpl->ref_pics_ddoi[0]);
+ if (rpl->ref_pics_ddoi[0] != 0) rpl->ref_pics_ddoi[0] *= 1 - ((u32)com_bsr_read1(bs) << 1);
+ if (aml_print_header_info) printf(" * 1-bit sign_doi[0] : %d --> ref_pics_ddoi[0] : %d\n", (rpl->ref_pics_ddoi[0] < 0), rpl->ref_pics_ddoi[0]);
+#if LIBVC_ON
+ ddoi_base = rpl->ref_pics_ddoi[0];
+#endif
+#endif
+ rpl->ref_pics_ddoi[0] = param->p.rpl_ref_pics_ddoi[0];
+ }
+
+ }
+#ifdef BUFMGR_SANITY_CHECK
+ for (i = 1; i < rpl->ref_pic_num && i < MAX_NUM_REF_PICS; ++i)
+#else
+ for (i = 1; i < rpl->ref_pic_num; ++i)
+#endif
+ {
+#if LIBVC_ON
+ rpl->library_index_flag[i] = 0;
+ if (sqh->library_picture_enable_flag && rpl->reference_to_library_enable_flag)
+ {
+ rpl->library_index_flag[i] = param->p.rpl_library_index_flag[i];
+ if (aml_print_header_info) printf(" * 1-bit library_index_flag[%d] : %d\n", i, rpl->library_index_flag[i]);
+ }
+ else {
+ if (aml_print_header_info) printf(" * set library_index_flag[%d] : %d\n", i, rpl->library_index_flag[i]);
+ }
+#ifdef ORI_CODE
+ if (sqh->library_picture_enable_flag && rpl->library_index_flag[i])
+ {
+ rpl->ref_pics_ddoi[i] = (u32)com_bsr_read_ue(bs);
+ if (aml_print_header_info) printf(" * UE ref_pics_ddoi[%d] : %d\n", i, rpl->ref_pics_ddoi[i]);
+ }
+ else
+ {
+ int deltaRefPic = (u32)com_bsr_read_ue(bs);
+ if (aml_print_header_info) printf(" * UE abs_delta_doi[%d] : %d\n", i, deltaRefPic);
+ if (deltaRefPic != 0) deltaRefPic *= 1 - ((u32)com_bsr_read1(bs) << 1);
+ if (aml_print_header_info) printf(" * 1-bit sign_delta_doi[%d] : %d --> deltaRefPic : %d\n", i, (deltaRefPic < 0), deltaRefPic);
+#if LIBVC_ON
+ rpl->ref_pics_ddoi[i] = ddoi_base + deltaRefPic;
+ if (aml_print_header_info) printf(" - ref_pics_ddoi[%d] : %d\n", i, rpl->ref_pics_ddoi[i]);
+ ddoi_base = rpl->ref_pics_ddoi[i];
+#else
+ rpl->ref_pics_ddoi[i] = rpl->ref_pics_ddoi[i - 1] + deltaRefPic;
+#endif
+ }
+#endif
+/*ORI_CODE*/
+#endif
+ rpl->ref_pics_ddoi[i] = param->p.rpl_ref_pics_ddoi[i];
+
+ }
+/*!AML*/
+#endif
+ return COM_OK;
+}
+#endif
+
+int dec_eco_sqh(union param_u *param, COM_SQH * sqh)
+{
+ int i, j;
+ int max_cuwh;
+#ifdef ORI_CODE
+ //video_sequence_start_code
+ unsigned int ret = com_bsr_read(bs, 24);
+ assert(ret == 1);
+ unsigned int start_code;
+ start_code = com_bsr_read(bs, 8);
+ assert(start_code == 0xB0);
+#endif
+ sqh->profile_id = (u8)param->p.sqh_profile_id;
+ if (aml_print_header_info) {
+ printf(" * 8-bits profile_id : 0x%02x ", sqh->profile_id);
+ if (sqh->profile_id == 0x00) printf(" -- Forbidden Profile\n");
+ else if (sqh->profile_id == 0x20) printf(" -- Main Profile\n");
+ else if (sqh->profile_id == 0x22) printf(" -- Main-10bit Profile\n");
+ else printf(" -- Reserved Profile\n");
+ }
+#if PHASE_2_PROFILE
+ if (sqh->profile_id != 0x22 && sqh->profile_id != 0x20
+ && sqh->profile_id != 0x32 && sqh->profile_id != 0x30
+ )
+ {
+ printf("unknown profile id: 0x%x\n", sqh->profile_id);
+ assert(0);
+ }
+#endif
+ sqh->level_id = (u8)param->p.sqh_level_id;
+ if (aml_print_header_info) {
+ printf(" * 8-bits level_id : 0x%02x ", sqh->level_id);
+ if (sqh->level_id == 0x10) printf(" -- Level 2.0.15\n");
+ else if (sqh->level_id == 0x12) printf(" -- Level 2.0.30\n");
+ else if (sqh->level_id == 0x14) printf(" -- Level 2.0.60\n");
+ else if (sqh->level_id == 0x20) printf(" -- Level 4.0.30\n");
+ else if (sqh->level_id == 0x22) printf(" -- Level 4.0.60\n");
+ else if (sqh->level_id == 0x40) printf(" -- Level 6.0.30\n");
+ else if (sqh->level_id == 0x42) printf(" -- Level 6.2.30\n");
+ else if (sqh->level_id == 0x44) printf(" -- Level 6.0.60\n");
+ else if (sqh->level_id == 0x46) printf(" -- Level 6.2.60\n");
+ else if (sqh->level_id == 0x48) printf(" -- Level 6.0.120\n");
+ else if (sqh->level_id == 0x4a) printf(" -- Level 6.2.120\n");
+ else if (sqh->level_id == 0x50) printf(" -- Level 8.0.30\n");
+ else if (sqh->level_id == 0x52) printf(" -- Level 8.2.30\n");
+ else if (sqh->level_id == 0x54) printf(" -- Level 8.0.60\n");
+ else if (sqh->level_id == 0x56) printf(" -- Level 8.2.60\n");
+ else if (sqh->level_id == 0x58) printf(" -- Level 8.0.120\n");
+ else if (sqh->level_id == 0x5a) printf(" -- Level 8.2.120\n");
+ else if (sqh->level_id == 0x60) printf(" -- Level 10.0.30\n");
+ else if (sqh->level_id == 0x62) printf(" -- Level 10.2.30\n");
+ else if (sqh->level_id == 0x64) printf(" -- Level 10.0.60\n");
+ else if (sqh->level_id == 0x66) printf(" -- Level 10.2.60\n");
+ else if (sqh->level_id == 0x68) printf(" -- Level 10.0.120\n");
+ else if (sqh->level_id == 0x6a) printf(" -- Level 10.2.120\n");
+ else printf(" -- Reserved Level\n");
+ }
+ sqh->progressive_sequence = (u8)param->p.sqh_progressive_sequence;
+ if (aml_print_header_info) printf(" * 1-bit progressive_sequence : %d\n", sqh->progressive_sequence);
+ assert(sqh->progressive_sequence == 1);
+ sqh->field_coded_sequence = (u8)param->p.sqh_field_coded_sequence;
+ if (aml_print_header_info) printf(" * 1-bit field_coded_sequence : %d\n", sqh->field_coded_sequence);
+#if LIBVC_ON
+ sqh->library_stream_flag = (u8)param->p.sqh_library_stream_flag;
+ if (aml_print_header_info) {
+ printf(" * 1-bit library_stream_flag : %d\n", sqh->library_stream_flag);
+ }
+ sqh->library_picture_enable_flag = 0;
+ //sqh->duplicate_sequence_header_flag = 0;
+ if (!sqh->library_stream_flag)
+ {
+ sqh->library_picture_enable_flag = (u8)param->p.sqh_library_picture_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit library_picture_enable_flag : %d\n", sqh->library_picture_enable_flag);
+ if (sqh->library_picture_enable_flag)
+ {
+ //sqh->duplicate_sequence_header_flag = (u8)param->p.sqh_duplicate_sequence_header_flag;
+ if (aml_print_header_info) printf(" * 1-bit duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+ }
+ else {
+ if (aml_print_header_info) printf(" - set duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+ }
+ }
+ else {
+ if (aml_print_header_info) printf(" - set library_picture_enable_flag : %d\n", sqh->library_picture_enable_flag);
+ if (aml_print_header_info) printf(" - set duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+ }
+#endif
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ sqh->horizontal_size = param->p.sqh_horizontal_size;
+ if (aml_print_header_info) printf(" * 14-bits horizontal_size : %d\n", sqh->horizontal_size);
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ sqh->vertical_size = param->p.sqh_vertical_size;
+ if (aml_print_header_info) printf(" * 14-bits vertical_size : %d\n", sqh->vertical_size);
+ if (aml_print_header_info) printf(" - pic_frame_size : %d x %d\n", sqh->horizontal_size, sqh->vertical_size);
+ //sqh->chroma_format = (u8)param->p.sqh_chroma_format;
+ if (aml_print_header_info) {
+ printf(" * 2-bits chroma_format : %d ", sqh->chroma_format);
+ if (sqh->chroma_format == 1) printf(" -- 4:2:0\n");
+ // else if (sqh->chroma_format == 2) printf(" -- 4:2:2\n");
+ else printf(" -- Reserved chroma_format\n");
+ }
+ sqh->sample_precision = (u8)param->p.sqh_sample_precision;
+ if (aml_print_header_info) printf(" * 3-bits sample_precision : %d -- %d bits\n", sqh->sample_precision, sqh->sample_precision*2+6);
+
+#if PHASE_2_PROFILE
+ if (sqh->profile_id == 0x22 || sqh->profile_id == 0x32)
+#else
+ if (sqh->profile_id == 0x22)
+#endif
+ {
+ sqh->encoding_precision = (u8)param->p.sqh_encoding_precision;
+ if (aml_print_header_info) printf(" * 3-bits encoding_precision : %d -- %d-bits\n", sqh->encoding_precision, sqh->encoding_precision*2+6);
+ //assert(sqh->encoding_precision == 2);
+ }
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ sqh->aspect_ratio = (u8)param->p.sqh_aspect_ratio;
+ if (aml_print_header_info) {
+ printf(" * 4-bits aspect_ratio : %d ", sqh->aspect_ratio);
+ if (sqh->aspect_ratio == 1) printf(" -- SAR = 1.0\n");
+ else if (sqh->aspect_ratio == 2) printf(" -- DAR = 4:3\n");
+ else if (sqh->aspect_ratio == 3) printf(" -- DAR = 16:9\n");
+ else if (sqh->aspect_ratio == 4) printf(" -- DAR = 2.21:1\n");
+ else printf(" -- Reserved aspect_ratio_information\n");
+ }
+
+ sqh->frame_rate_code = (u8)param->p.sqh_frame_rate_code;
+ if (aml_print_header_info) {
+ printf(" * 4-bits frame_rate_code : %d ", sqh->frame_rate_code);
+ if (sqh->frame_rate_code == 1) printf(" -- 23.976 fps\n");
+ else if (sqh->frame_rate_code == 2) printf(" -- 24 fps\n");
+ else if (sqh->frame_rate_code == 3) printf(" -- 25 fps\n");
+ else if (sqh->frame_rate_code == 4) printf(" -- 29.97 fps\n");
+ else if (sqh->frame_rate_code == 5) printf(" -- 30 fps\n");
+ else if (sqh->frame_rate_code == 6) printf(" -- 50 fps\n");
+ else if (sqh->frame_rate_code == 7) printf(" -- 59.94 fps\n");
+ else if (sqh->frame_rate_code == 8) printf(" -- 60 fps\n");
+ else if (sqh->frame_rate_code == 9) printf(" -- 100 fps\n");
+ else if (sqh->frame_rate_code == 10) printf(" -- 120 fps\n");
+ else if (sqh->frame_rate_code == 11) printf(" -- 200 fps\n");
+ else if (sqh->frame_rate_code == 12) printf(" -- 240 fps\n");
+ else if (sqh->frame_rate_code == 13) printf(" -- 300 fps\n");
+ else printf(" -- Reserved frame_rate_code\n");
+ }
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ //sqh->bit_rate_lower = param->p.sqh_bit_rate_lower;
+ if (aml_print_header_info) printf(" * 18-bits bit_rate_lower : %d\n", sqh->bit_rate_lower);
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ //sqh->bit_rate_upper = param->p.sqh_bit_rate_upper;
+ if (aml_print_header_info) printf(" * 12-bits bit_rate_upper : %d\n", sqh->bit_rate_upper);
+ printf(" - BitRate = %d kbit/s \n", ((sqh->bit_rate_upper << 18) + sqh->bit_rate_lower) * 400 / 1024);
+ sqh->low_delay = (u8)param->p.sqh_low_delay;
+
+ sqh->temporal_id_enable_flag = (u8)param->p.sqh_temporal_id_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit temporal_id_enable_flag : %d\n", sqh->temporal_id_enable_flag);
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ //sqh->bbv_buffer_size = param->p.sqh_bbv_buffer_size;
+ if (aml_print_header_info) printf(" * 18-bits bbv_buffer_size : %d\n", sqh->bbv_buffer_size);
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ sqh->max_dpb_size = param->p.sqh_max_dpb_size;
+ if (aml_print_header_info) printf(" * 4-bits max_dpb_size_minus1 : %d --> max_dpb_size : %d\n", sqh->max_dpb_size-1, sqh->max_dpb_size);
+
+#if HLS_RPL
+ if (aml_print_header_info) printf("--BEGIN HLS_RPL--------------------------------------------\n");
+ //sqh->rpl1_index_exist_flag = (u32)param->p.sqh_rpl1_index_exist_flag;
+ if (aml_print_header_info) printf(" * 1-bit rpl1_index_exist_flag : %d\n", sqh->rpl1_index_exist_flag);
+ //sqh->rpl1_same_as_rpl0_flag = (u32)param->p.sqh_rpl1_same_as_rpl0_flag;
+ if (aml_print_header_info) printf(" * 1-bit rpl1_same_as_rpl0_flag : %d\n", sqh->rpl1_same_as_rpl0_flag);
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ //sqh->rpls_l0_num = (u32)param->p.sqh_rpls_l0_num;
+ if (aml_print_header_info) printf(" * UE rpls_l0_num : %d\n", sqh->rpls_l0_num);
+ for (i = 0; i < sqh->rpls_l0_num; ++i)
+ {
+#if LIBVC_ON
+ if (aml_print_header_info) printf(" ## dec_eco_rlp_l0[%d] ##\n", i);
+ dec_eco_rlp(param, &sqh->rpls_l0[i], sqh);
+#else
+ dec_eco_rlp(param, &sqh->rpls_l0[i]);
+#endif
+ }
+
+ if (!sqh->rpl1_same_as_rpl0_flag)
+ {
+ //sqh->rpls_l1_num = (u32)param->p.sqh_rpls_l1_num;
+ if (aml_print_header_info) printf(" * UE rpls_l1_num : %d\n", sqh->rpls_l1_num);
+ for (i = 0; i < sqh->rpls_l1_num; ++i)
+ {
+#if LIBVC_ON
+ if (aml_print_header_info) printf(" ## dec_eco_rlp_l1[%d] ##\n", i);
+ dec_eco_rlp(param, &sqh->rpls_l1[i], sqh);
+#else
+ dec_eco_rlp(param, &sqh->rpls_l1[i]);
+#endif
+ }
+ }
+ else
+ {
+ //Basically copy everything from sqh->rpls_l0 to sqh->rpls_l1
+ //MX: LIBVC is not harmonization yet.
+ //sqh->rpls_l1_num = sqh->rpls_l0_num;
+ for (i = 0; i < sqh->rpls_l1_num; i++)
+ {
+#if LIBVC_ON
+ sqh->rpls_l1[i].reference_to_library_enable_flag = sqh->rpls_l0[i].reference_to_library_enable_flag;
+#endif
+ sqh->rpls_l1[i].ref_pic_num = sqh->rpls_l0[i].ref_pic_num;
+ for (j = 0; j < sqh->rpls_l1[i].ref_pic_num; j++)
+ {
+#if LIBVC_ON
+ sqh->rpls_l1[i].library_index_flag[j] = sqh->rpls_l0[i].library_index_flag[j];
+#endif
+ sqh->rpls_l1[i].ref_pics_ddoi[j] = sqh->rpls_l0[i].ref_pics_ddoi[j];
+ }
+ }
+ }
+ sqh->num_ref_default_active_minus1[0] = (u32)param->p.sqh_num_ref_default_active_minus1[0];
+ if (aml_print_header_info) printf("-----------------------------------------------------------\n");
+ if (aml_print_header_info) printf(" * UE num_ref_default_active_minus1[0] : %d\n", sqh->num_ref_default_active_minus1[0]);
+ sqh->num_ref_default_active_minus1[1] = (u32)param->p.sqh_num_ref_default_active_minus1[1];
+ if (aml_print_header_info) printf(" * UE num_ref_default_active_minus1[1] : %d\n", sqh->num_ref_default_active_minus1[1]);
+ if (aml_print_header_info) printf("--END HLS_RPL----------------------------------------------\n");
+#endif
+
+#ifdef ORI_CODE
+ if (aml_print_header_info) {
+ int temp_size_read;
+ temp_size_read = com_bsr_read(bs, 3); // log2_lcu_size_minus2
+ sqh->log2_max_cu_width_height = param->p.sqh_log2_max_cu_width_height;
+ printf(" * 3-bits log2_lcu_size_minus2 : %d --> lcu_size : %d x %d\n", temp_size_read, (1<< sqh->log2_max_cu_width_height), (1<< sqh->log2_max_cu_width_height));
+ temp_size_read = com_bsr_read(bs, 2); // log2_min_cu_size_minus2
+ //sqh->min_cu_size = param->p.sqh_min_cu_size;
+ printf(" * 2-bits log2_min_cu_size_minus2 : %d --> min_cu_size : %d\n", temp_size_read, sqh->min_cu_size);
+ temp_size_read = com_bsr_read(bs, 2); // log2_max_part_ratio_minus2
+ //sqh->max_part_ratio = param->p.sqh_max_part_ratio;
+ printf(" * 2-bits log2_max_part_ratio_minus2 : %d --> max_part_ratio : %d\n", temp_size_read, sqh->max_part_ratio);
+ temp_size_read = com_bsr_read(bs, 3); // max_split_times_minus6
+ //sqh->max_split_times = param->p.sqh_max_split_times;
+ printf(" * 3-bits max_split_times_minus6 : %d --> max_split_times : %d\n", temp_size_read, sqh->max_split_times);
+ temp_size_read = com_bsr_read(bs, 3); // log2_min_qt_size_minus2
+ //sqh->min_qt_size = param->p.sqh_min_qt_size;
+ printf(" * 3-bits log2_min_qt_size_minus2 : %d --> min_qt_size : %d\n", temp_size_read, sqh->min_qt_size);
+ temp_size_read = com_bsr_read(bs, 3); // log2_max_bt_size_minus2
+ //sqh->max_bt_size = param->p.sqh_max_bt_size;
+ printf(" * 3-bits log2_max_bt_size_minus2 : %d --> max_bt_size : %d\n", temp_size_read, sqh->max_bt_size);
+ temp_size_read = com_bsr_read(bs, 2); // log2_max_eqt_size_minus3
+ //sqh->max_eqt_size = param->p.sqh_max_eqt_size;
+ printf(" * 2-bits log2_max_eqt_size_minus3 : %d --> max_eqt_size : %d\n", temp_size_read, sqh->max_eqt_size);
+ }
+ else
+#endif
+ {
+ sqh->log2_max_cu_width_height = param->p.sqh_log2_max_cu_width_height;
+ //sqh->min_cu_size = param->p.sqh_min_cu_size;
+ //sqh->max_part_ratio = param->p.sqh_max_part_ratio;
+ //sqh->max_split_times = param->p.sqh_max_split_times;
+ //sqh->min_qt_size = param->p.sqh_min_qt_size;
+ //sqh->max_bt_size = param->p.sqh_max_bt_size;
+ //sqh->max_eqt_size = param->p.sqh_max_eqt_size;
+ }
+
+#ifndef ORI_CODE
+ sqh->adaptive_leveling_filter_enable_flag = (u8)param->p.sqh_adaptive_leveling_filter_enable_flag;
+ sqh->num_of_hmvp_cand = (u8)param->p.sqh_num_of_hmvp_cand;
+ printf("sqh->num_of_hmvp_cand=%d\n", sqh->num_of_hmvp_cand);
+#if ALF_SHAPE || ALF_IMP
+ if (sqh->profile_id == 0x30 || sqh->profile_id == 0x32)
+ {
+ if (sqh->adaptive_leveling_filter_enable_flag)
+ {
+ sqh->adaptive_filter_shape_enable_flag = (u8)param->p.sqh_adaptive_filter_shape_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+ }
+ else
+ {
+ sqh->adaptive_filter_shape_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+ }
+ } else {
+ sqh->adaptive_filter_shape_enable_flag = 0;
+ }
+#endif
+#else
+ assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+ //verify parameters allowed in Profile
+ assert(sqh->log2_max_cu_width_height >= 5 && sqh->log2_max_cu_width_height <= 7);
+ assert(sqh->min_cu_size == 4);
+ assert(sqh->max_part_ratio == 8);
+ assert(sqh->max_split_times == 6);
+ assert(sqh->min_qt_size == 4 || sqh->min_qt_size == 8 || sqh->min_qt_size == 16 || sqh->min_qt_size == 32 || sqh->min_qt_size == 64 || sqh->min_qt_size == 128);
+ assert(sqh->max_bt_size == 64 || sqh->max_bt_size == 128);
+ assert(sqh->max_eqt_size == 8 || sqh->max_eqt_size == 16 || sqh->max_eqt_size == 32 || sqh->max_eqt_size == 64);
+
+ //sqh->wq_enable = (u8)param->p.sqh_wq_enable;
+ if (aml_print_header_info) printf(" * 1-bit wq_enable : %d\n", sqh->wq_enable);
+ if (sqh->wq_enable)
+ {
+ sqh->seq_wq_mode = param->p.sqh_seq_wq_mode;
+ if (aml_print_header_info) printf(" * 1-bit seq_wq_mode : %d\n", sqh->seq_wq_mode);
+ if (sqh->seq_wq_mode)
+ {
+ read_wq_matrix(bs, sqh->wq_4x4_matrix, sqh->wq_8x8_matrix); //weight_quant_matrix( )
+ }
+ else
+ {
+ memcpy(sqh->wq_4x4_matrix, tab_WqMDefault4x4, sizeof(tab_WqMDefault4x4));
+ memcpy(sqh->wq_8x8_matrix, tab_WqMDefault8x8, sizeof(tab_WqMDefault8x8));
+ }
+ }
+ //sqh->secondary_transform_enable_flag = (u8)param->p.sqh_secondary_transform_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit secondary_transform_enable_flag : %d\n", sqh->secondary_transform_enable_flag);
+ //sqh->sample_adaptive_offset_enable_flag = (u8)param->p.sqh_sample_adaptive_offset_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit sample_adaptive_offset_enable_flag : %d\n", sqh->sample_adaptive_offset_enable_flag);
+ sqh->adaptive_leveling_filter_enable_flag = (u8)param->p.sqh_adaptive_leveling_filter_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit adaptive_leveling_filter_enable_flag : %d\n", sqh->adaptive_leveling_filter_enable_flag);
+ //sqh->affine_enable_flag = (u8)param->p.sqh_affine_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit affine_enable_flag : %d\n", sqh->affine_enable_flag);
+#if SMVD
+ //sqh->smvd_enable_flag = (u8)param->p.sqh_smvd_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit smvd_enable_flag : %d\n", sqh->smvd_enable_flag);
+#endif
+#if IPCM
+ //sqh->ipcm_enable_flag = param->p.sqh_ipcm_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit ipcm_enable_flag : %d\n", sqh->ipcm_enable_flag);
+ assert(sqh->sample_precision == 1 || sqh->sample_precision == 2);
+#endif
+ //sqh->amvr_enable_flag = (u8)param->p.sqh_amvr_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit amvr_enable_flag : %d\n", sqh->amvr_enable_flag);
+ sqh->num_of_hmvp_cand = (u8)param->p.sqh_num_of_hmvp_cand;
+ if (aml_print_header_info) printf(" * 4-bits num_of_hmvp_cand : %d\n", sqh->num_of_hmvp_cand);
+ //sqh->umve_enable_flag = (u8)param->p.sqh_umve_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit umve_enable_flag : %d\n", sqh->umve_enable_flag);
+#if EXT_AMVR_HMVP
+ if (sqh->amvr_enable_flag && sqh->num_of_hmvp_cand)
+ {
+ //sqh->emvr_enable_flag = (u8)param->p.sqh_emvr_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit emvr_enable_flag : %d\n", sqh->emvr_enable_flag);
+ }
+ else
+ {
+ //sqh->emvr_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set emvr_enable_flag : %d\n", sqh->emvr_enable_flag);
+ }
+#endif
+ //sqh->ipf_enable_flag = (u8)param->p.sqh_ipf_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit ipf_enable_flag : %d\n", sqh->ipf_enable_flag);
+#if TSCPM
+ //sqh->tscpm_enable_flag = (u8)param->p.sqh_tscpm_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit tscpm_enable_flag : %d\n", sqh->tscpm_enable_flag);
+#endif
+ //assert(com_bsr_read1(bs) == 1); //marker_bit
+ if (aml_print_header_info) printf(" * 1-bit marker_bit : %d\n", 1);
+#if DT_PARTITION
+ //sqh->dt_intra_enable_flag = (u8)param->p.sqh_dt_intra_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit dt_intra_enable_flag : %d\n", sqh->dt_intra_enable_flag);
+ if (sqh->dt_intra_enable_flag)
+ {
+ //u32 log2_max_dt_size_minus4 = com_bsr_read(bs, 2);
+ //assert(log2_max_dt_size_minus4 <= 2);
+ //sqh->max_dt_size = param->p.sqh_max_dt_size;
+ if (aml_print_header_info) printf(" * 2-bits log2_max_dt_size_minus4 : %d --> max_dt_size : %d\n", log2_max_dt_size_minus4, sqh->max_dt_size);
+ }
+#endif
+ //sqh->position_based_transform_enable_flag = (u8)param->p.sqh_position_based_transform_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit position_based_transform_enable_flag : %d\n", sqh->position_based_transform_enable_flag);
+
+#if PHASE_2_PROFILE
+ if (sqh->profile_id == 0x30 || sqh->profile_id == 0x32)
+ {
+#endif
+ // begin of phase-2 sqh
+#if ESAO
+ sqh->esao_enable_flag = (u8)param->p.sqh_esao_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit esao_enable_flag : %d\n", sqh->esao_enable_flag);
+#endif
+#if CCSAO
+ sqh->ccsao_enable_flag = (u8)param->p.sqh_ccsao_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit ccsao_enable_flag : %d\n", sqh->ccsao_enable_flag);
+#endif
+#if ALF_SHAPE || ALF_IMP
+ if (sqh->adaptive_leveling_filter_enable_flag)
+ {
+ sqh->adaptive_filter_shape_enable_flag = (u8)param->p.sqh_adaptive_filter_shape_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+ }
+ else
+ {
+ sqh->adaptive_filter_shape_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+ }
+#endif
+#if UMVE_ENH
+ if (sqh->umve_enable_flag)
+ {
+ sqh->umve_enh_enable_flag = (u8)param->p.sqh_umve_enh_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit umve_enh_enable_flag : %d\n", sqh->umve_enh_enable_flag);
+ }
+#endif
+#if AWP
+ sqh->awp_enable_flag = (u8)param->p.sqh_awp_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit awp_enable_flag : %d\n", sqh->awp_enable_flag);
+#endif
+#if AWP_MVR
+ if (sqh->awp_enable_flag)
+ {
+ sqh->awp_mvr_enable_flag = (u8)param->p.sqh_awp_mvr_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit awp_mvr_enable_flag : %d\n", sqh->awp_mvr_enable_flag);
+ }
+ else
+ {
+ sqh->awp_mvr_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set awp_mvr_enable_flag : %d\n", sqh->awp_mvr_enable_flag);
+ }
+#endif
+#if BIO
+ sqh->bio_enable_flag = (u8)param->p.sqh_bio_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit bio_enable_flag : %d\n", sqh->bio_enable_flag);
+#endif
+#if BGC
+ sqh->bgc_enable_flag = (u8)param->p.sqh_bgc_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit bgc_enable_flag : %d\n", sqh->bgc_enable_flag);
+#endif
+#if DMVR
+ sqh->dmvr_enable_flag = (u8)param->p.sqh_dmvr_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit dmvr_enable_flag : %d\n", sqh->dmvr_enable_flag);
+#endif
+#if INTERPF
+ sqh->interpf_enable_flag = (u8)param->p.sqh_interpf_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit interpf_enable_flag : %d\n", sqh->interpf_enable_flag);
+#endif
+#if IBC_ABVR
+ sqh->abvr_enable_flag = (u8)param->p.sqh_abvr_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit abvr_enable_flag : %d\n", sqh->abvr_enable_flag);
+#endif
+#if USE_SP
+ sqh->sp_enable_flag = (u8)param->p.sqh_sp_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit sp_enable_flag : %d\n", sqh->sp_enable_flag);
+#if EVS_UBVS_MODE
+ if (sqh->sp_enable_flag)
+ {
+ sqh->evs_ubvs_enable_flag = (u8)param->p.sqh_evs_ubvs_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit evs_ubvs_enable_flag : %d\n", sqh->evs_ubvs_enable_flag);
+ }
+ else
+ {
+ sqh->evs_ubvs_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set evs_ubvs_enable_flag : %d\n", sqh->evs_ubvs_enable_flag);
+ }
+#endif
+#endif
+#if IBC_BVP
+ sqh->num_of_hbvp_cand = (u8)param->p.sqh_num_of_hbvp_cand;
+ if (aml_print_header_info) printf(" * 4-bits num_of_hbvp_cand : %d\n", sqh->num_of_hbvp_cand);
+#endif
+#if ASP
+ if (sqh->affine_enable_flag)
+ {
+ sqh->asp_enable_flag = (u8)param->p.sqh_asp_enable_flag;
+ if (aml_print_header_info) printf(" * 1-bit asp_enable_flag : %d\n", sqh->asp_enable_flag);
+ }
+ else
+ {
+ sqh->asp_enable_flag = 0;
+ if (aml_print_header_info) printf(" - set asp_enable_flag : %d\n", sqh->asp_enable_flag);
+ }
+#endif
+#if AFFINE_UMVE
+ if (sqh->affine_enable_flag && sqh->umve_enable_flag)
+ {
+ sqh->affine_umve_enable_flag = (u8)param->p.sqh_affine_umve_enable_flag;
+ }
+ else
+ {
+ sqh->affine_umve_enable_flag = 0;
+ }
+#endif
+#if MIPF
+ sqh->mipf_enable_flag = (u8)param->p.sqh_mipf_enable_flag;
+#endif
+#if TSCPM && ENHANCE_TSPCM
+ if (sqh->tscpm_enable_flag)
+ {
+ sqh->enhance_tscpm_enable_flag = (u8)param->p.sqh_enhance_tscpm_enable_flag;
+ }
+ else
+ {
+ sqh->enhance_tscpm_enable_flag = 0;
+ }
+#endif
+#if IPF_CHROMA
+ if (sqh->ipf_enable_flag)
+ {
+ sqh->chroma_ipf_enable_flag = (u8)param->p.sqh_chroma_ipf_enable_flag;
+ }
+ else
+ {
+ sqh->chroma_ipf_enable_flag = 0;
+ }
+#endif
+#if IIP
+ sqh->iip_enable_flag = (u8)param->p.sqh_iip_enable_flag;
+#endif
+#if PMC
+ sqh->pmc_enable_flag = (u8)param->p.sqh_pmc_enable_flag;
+#endif
+#if FIMC
+ sqh->fimc_enable_flag = (u8)param->p.sqh_fimc_enable_flag;
+#endif
+#if USE_IBC
+ sqh->ibc_flag = (u8)param->p.sqh_ibc_flag;
+#endif
+#if SIBC
+ if (sqh->ibc_flag)
+ {
+ sqh->sibc_enable_flag = (u8)param->p.sqh_sibc_enable_flag;
+ }
+ else
+ {
+ sqh->sibc_enable_flag = 0;
+ }
+#endif
+#if SBT
+ sqh->sbt_enable_flag = (u8)param->p.sqh_sbt_enable_flag;
+#endif
+#if IST
+ sqh->ist_enable_flag = (u8)param->p.sqh_ist_enable_flag;
+#endif
+#if ISTS
+ sqh->ists_enable_flag = (u8)param->p.sqh_ists_enable_flag;
+#endif
+#if TS_INTER
+ sqh->ts_inter_enable_flag = (u8)param->p.sqh_ts_inter_enable_flag;
+#endif
+#if EST
+ if (sqh->secondary_transform_enable_flag)
+ {
+ sqh->est_enable_flag = (u8)param->p.sqh_est_enable_flag;
+ }
+#endif
+#if ST_CHROMA
+ if (sqh->secondary_transform_enable_flag)
+ {
+ sqh->st_chroma_enable_flag = (u8)param->p.sqh_st_chroma_enable_flag;
+ }
+ else
+ {
+ sqh->st_chroma_enable_flag = 0;
+ }
+#endif
+#if SRCC
+ sqh->srcc_enable_flag = (u8)param->p.sqh_srcc_enable_flag;
+#endif
+#if CABAC_MULTI_PROB
+ sqh->mcabac_enable_flag = (u8)param->p.sqh_mcabac_enable_flag;
+#endif
+#if EIPM
+ sqh->eipm_enable_flag = (u8)param->p.sqh_eipm_enable_flag;
+#endif
+#if ETMVP
+ sqh->etmvp_enable_flag = (u8)param->p.sqh_etmvp_enable_flag;
+#endif
+#if SUB_TMVP
+ sqh->sbtmvp_enable_flag = (u8)param->p.sqh_sbtmvp_enable_flag;
+#endif
+#if MVAP
+ sqh->mvap_enable_flag = (u8)param->p.sqh_mvap_enable_flag;
+ sqh->num_of_mvap_cand = sqh->mvap_enable_flag ? ALLOWED_MVAP_NUM : 0;
+#endif
+#if DBK_SCC
+ sqh->loop_filter_type_enable_flag = (u8)param->p.sqh_loop_filter_type_enable_flag;
+#endif
+#if DBR
+ sqh->dbr_enable_flag = (u8)param->p.sqh_dbr_enable_flag;
+#endif
+ // end of phase-2 sqh
+#if PHASE_2_PROFILE
+ }
+ else
+ {
+#if ESAO
+ sqh->esao_enable_flag = 0;
+#endif
+#if CCSAO
+ sqh->ccsao_enable_flag = 0;
+#endif
+#if ALF_SHAPE || ALF_IMP
+ sqh->adaptive_filter_shape_enable_flag = 0;
+#endif
+#if UMVE_ENH
+ sqh->umve_enh_enable_flag = 0;
+#endif
+#if AWP
+ sqh->awp_enable_flag = 0;
+#endif
+#if AWP_MVR
+ sqh->awp_mvr_enable_flag = 0;
+#endif
+#if BIO
+ sqh->bio_enable_flag = 0;
+#endif
+#if BGC
+ sqh->bgc_enable_flag = 0;
+#endif
+#if DMVR
+ sqh->dmvr_enable_flag = 0;
+#endif
+#if INTERPF
+ sqh->interpf_enable_flag = 0;
+#endif
+#if IBC_ABVR
+ sqh->abvr_enable_flag = 0;
+#endif
+#if USE_SP
+ sqh->sp_enable_flag = 0;
+#if EVS_UBVS_MODE
+ sqh->evs_ubvs_enable_flag = 0;
+#endif
+#endif
+#if IBC_BVP
+ sqh->num_of_hbvp_cand = 0;
+#endif
+#if ASP
+ sqh->asp_enable_flag = 0;
+#endif
+#if AFFINE_UMVE
+ sqh->affine_umve_enable_flag = 0;
+#endif
+#if MIPF
+ sqh->mipf_enable_flag = 0;
+#endif
+#if TSCPM && ENHANCE_TSPCM
+ sqh->enhance_tscpm_enable_flag = 0;
+#endif
+#if IPF_CHROMA
+ sqh->chroma_ipf_enable_flag = 0;
+#endif
+#if IIP
+ sqh->iip_enable_flag = 0;
+#endif
+#if PMC
+ sqh->pmc_enable_flag = 0;
+#endif
+#if FIMC
+ sqh->fimc_enable_flag = 0;
+#endif
+#if USE_IBC
+ sqh->ibc_flag = 0;
+#endif
+#if SIBC
+ sqh->sibc_enable_flag = 0;
+#endif
+#if SBT
+ sqh->sbt_enable_flag = 0;
+#endif
+#if IST
+ sqh->ist_enable_flag = 0;
+#endif
+#if ISTS
+ sqh->ists_enable_flag = 0;
+#endif
+#if TS_INTER
+ sqh->ts_inter_enable_flag = 0;
+#endif
+#if EST
+ sqh->est_enable_flag = 0;
+#endif
+#if ST_CHROMA
+ sqh->st_chroma_enable_flag = 0;
+#endif
+#if SRCC
+ sqh->srcc_enable_flag = 0;
+#endif
+#if CABAC_MULTI_PROB
+ sqh->mcabac_enable_flag = 0;
+#endif
+#if EIPM
+ sqh->eipm_enable_flag = 0;
+#endif
+#if ETMVP
+ sqh->etmvp_enable_flag = 0;
+#endif
+#if SUB_TMVP
+ sqh->sbtmvp_enable_flag = 0;
+#endif
+#if MVAP
+ sqh->mvap_enable_flag = 0;
+ sqh->num_of_mvap_cand = 0;
+#endif
+#if DBK_SCC
+ sqh->loop_filter_type_enable_flag = 0;
+#endif
+#if DBR
+ sqh->dbr_enable_flag = 0;
+#endif
+ }
+#endif // end of PHASE_2_PROFILE
+/*ORI_CODE*/
+#endif
+ if (sqh->low_delay == 0)
+ {
+ sqh->output_reorder_delay = (u8)param->p.sqh_output_reorder_delay;
+ if (aml_print_header_info) printf(" * 5-bits output_reorder_delay : %d\n", sqh->output_reorder_delay);
+ }
+ else
+ {
+ sqh->output_reorder_delay = 0;
+ if (aml_print_header_info) printf(" - set output_reorder_delay : %d\n", sqh->output_reorder_delay);
+ }
+#ifdef ORI_CODE
+#if PATCH
+ sqh->cross_patch_loop_filter = (u8)param->p.sqh_cross_patch_loop_filter;
+ if (aml_print_header_info) printf(" * 1-bit cross_patch_loop_filter : %d\n", sqh->cross_patch_loop_filter);
+ //sqh->patch_ref_colocated = (u8)param->p.sqh_patch_ref_colocated;
+ if (aml_print_header_info) printf(" * 1-bit patch_ref_colocated : %d\n", sqh->patch_ref_colocated);
+ //sqh->patch_stable = (u8)param->p.sqh_patch_stable;
+ if (aml_print_header_info) printf(" * 1-bit patch_stable : %d\n", sqh->patch_stable);
+ if (sqh->patch_stable)
+ {
+ //sqh->patch_uniform = (u8)param->p.sqh_patch_uniform;
+ if (aml_print_header_info) printf(" * 1-bit patch_uniform : %d\n", sqh->patch_uniform);
+ if (sqh->patch_uniform)
+ {
+ assert(com_bsr_read1(bs) == 1); //marker_bit
+ //sqh->patch_width_minus1 = (u8)param->p.sqh_patch_width_minus1;
+ if (aml_print_header_info) printf(" * UE patch_width_minus1 : %d\n", sqh->patch_width_minus1);
+ //sqh->patch_height_minus1 = (u8)param->p.sqh_patch_height_minus1;
+ if (aml_print_header_info) printf(" * UE patch_height_minus1 : %d\n", sqh->patch_height_minus1);
+ }
+ }
+#endif
+ com_bsr_read(bs, 2); //reserved_bits r(2)
+ if (aml_print_header_info) printf(" * 2-bits reserved_bits dropped\n");
+
+ //next_start_code()
+ assert(com_bsr_read1(bs)==1); // stuffing_bit '1'
+ while (!COM_BSR_IS_BYTE_ALIGN(bs))
+ {
+ assert(com_bsr_read1(bs) == 0); // stuffing_bit '0'
+ }
+ while (com_bsr_next(bs, 24) != 0x1)
+ {
+ assert(com_bsr_read(bs, 8) == 0); // stuffing_byte '00000000'
+ };
+#endif
+ /* check values */
+ max_cuwh = 1 << sqh->log2_max_cu_width_height;
+ if (max_cuwh < MIN_CU_SIZE || max_cuwh > MAX_CU_SIZE)
+ {
+ printf("max_cuwh %d, MIN_CU_SIZE %d, MAX_CU_SIZE %d\n",
+ max_cuwh, MIN_CU_SIZE, MAX_CU_SIZE);
+ return COM_ERR_MALFORMED_BITSTREAM;
+ }
+ printf("%s return\n", __func__);
+ return COM_OK;
+}
+
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code)
+{
+ int i, ii;
+#ifdef ORI_CODE
+ unsigned int ret = com_bsr_read(bs, 24);
+ assert(ret == 1);
+ unsigned int start_code = com_bsr_read(bs, 8);
+#endif
+ if (start_code == 0xB3)
+ {
+ pic_header->slice_type = SLICE_I;
+ }
+ assert(start_code == 0xB6 || start_code == 0xB3);
+ if (start_code != 0xB3)//MX: not SLICE_I
+ {
+ pic_header->random_access_decodable_flag = param->p.pic_header_random_access_decodable_flag;
+ }
+ //pic_header->bbv_delay = com_bsr_read(bs, 8) << 24 | com_bsr_read(bs, 8) << 16 | com_bsr_read(bs, 8) << 8 | com_bsr_read(bs, 8);
+ //pic_header->bbv_delay = (u32)param->p.pic_header_bbv_delay;
+ if (start_code == 0xB6)
+ {
+ //picture_coding_type
+ //u8 val = (u8)com_bsr_read(bs, 2);
+ //assert(val == 1 || val == 2);
+ pic_header->slice_type = (u8)param->p.pic_header_slice_type;
+ }
+ if (pic_header->slice_type == SLICE_I)
+ {
+ //pic_header->time_code_flag = param->p.pic_header_time_code_flag;
+ if (pic_header->time_code_flag == 1)
+ {
+ //pic_header->time_code = param->p.pic_header_time_code;
+ }
+ }
+
+ pic_header->decode_order_index = param->p.pic_header_decode_order_index;
+
+#if LIBVC_ON
+ pic_header->library_picture_index = -1;
+ if (pic_header->slice_type == SLICE_I)
+ {
+ if (sqh->library_stream_flag)
+ {
+ pic_header->library_picture_index = param->p.pic_header_library_picture_index;
+ }
+ }
+#endif
+
+ if (sqh->temporal_id_enable_flag == 1)
+ {
+ //pic_header->temporal_id = (u8)param->p.pic_header_temporal_id;
+ }
+ if (sqh->low_delay == 0)
+ {
+ pic_header->picture_output_delay = param->p.pic_header_picture_output_delay;
+ pic_header->bbv_check_times = 0;
+ }
+ else
+ {
+ pic_header->picture_output_delay = 0;
+ //pic_header->bbv_check_times = param->p.pic_header_bbv_check_times;
+ }
+
+ //the field information below is not used by decoder -- start
+ pic_header->progressive_frame = param->p.pic_header_progressive_frame;
+ assert(pic_header->progressive_frame == 1);
+ if (pic_header->progressive_frame == 0)
+ {
+ //pic_header->picture_structure = param->p.pic_header_picture_structure;
+ }
+ else
+ {
+ //pic_header->picture_structure = 1;
+ }
+ pic_header->top_field_first = param->p.pic_header_top_field_first;
+ pic_header->repeat_first_field = param->p.pic_header_repeat_first_field;
+ if (sqh->field_coded_sequence == 1)
+ {
+ pic_header->top_field_picture_flag = param->p.pic_header_top_field_picture_flag;
+ //com_bsr_read1(bs); // reserved_bits r(1)
+ }
+ // -- end
+
+#if LIBVC_ON
+ if (!sqh->library_stream_flag)
+ {
+#endif
+ if (pic_header->decode_order_index < pic_header->g_DOIPrev)
+ {
+ *need_minus_256 = 1;
+ pic_header->g_CountDOICyCleTime++; // initialized the number .
+ }
+ pic_header->g_DOIPrev = pic_header->decode_order_index;
+ pic_header->dtr = pic_header->decode_order_index + (DOI_CYCLE_LENGTH*pic_header->g_CountDOICyCleTime) + pic_header->picture_output_delay - sqh->output_reorder_delay;//MX: in the decoder, the only usage of g_CountDOICyCleTime is to derive the POC/POC. here is the dtr
+#if LIBVC_ON
+ }
+ else
+ {
+ pic_header->dtr = pic_header->decode_order_index + (DOI_CYCLE_LENGTH*pic_header->g_CountDOICyCleTime) + pic_header->picture_output_delay - sqh->output_reorder_delay;
+ }
+#endif
+
+ //initialization
+ pic_header->rpl_l0_idx = pic_header->rpl_l1_idx = -1;
+ pic_header->ref_pic_list_sps_flag[0] = pic_header->ref_pic_list_sps_flag[1] = 0;
+ pic_header->rpl_l0.ref_pic_num = 0;
+ pic_header->rpl_l1.ref_pic_num = 0;
+ pic_header->rpl_l0.ref_pic_active_num = 0;
+ pic_header->rpl_l1.ref_pic_active_num = 0;
+ for (i = 0; i < MAX_NUM_REF_PICS; i++)
+ {
+ pic_header->rpl_l0.ref_pics[i] = 0;
+ pic_header->rpl_l1.ref_pics[i] = 0;
+ pic_header->rpl_l0.ref_pics_ddoi[i] = 0;
+ pic_header->rpl_l1.ref_pics_ddoi[i] = 0;
+ pic_header->rpl_l0.ref_pics_doi[i] = 0;
+ pic_header->rpl_l1.ref_pics_doi[i] = 0;
+#if LIBVC_ON
+ pic_header->rpl_l0.library_index_flag[i] = 0;
+ pic_header->rpl_l1.library_index_flag[i] = 0;
+#endif
+ }
+
+#if HLS_RPL
+ //TBD(@Chernyak) if (!IDR) condition to be added here
+ pic_header->poc = pic_header->dtr;
+ //pic_header->poc = com_bsr_read_ue(bs); = param_proc???("", -1, );
+ // L0 candidates signaling
+ pic_header->ref_pic_list_sps_flag[0] = param->p.pic_header_ref_pic_list_sps_flag[0];
+ if (pic_header->ref_pic_list_sps_flag[0])
+ {
+ if (sqh->rpls_l0_num)
+ {
+ if (sqh->rpls_l0_num > 1)
+ {
+ pic_header->rpl_l0_idx = param->p.pic_header_rpl_l0_idx;
+ }
+ else//if sps only have 1 RPL, no need to signal the idx
+ {
+ pic_header->rpl_l0_idx = 0;
+ }
+#ifdef BUFMGR_SANITY_CHECK
+ if ((pic_header->rpl_l1_idx >= 0) &&
+ (pic_header->rpl_l1_idx < MAX_NUM_RPLS))
+#endif
+ memcpy(&pic_header->rpl_l0, &sqh->rpls_l0[pic_header->rpl_l0_idx], sizeof(pic_header->rpl_l0));
+ pic_header->rpl_l0.poc = pic_header->poc;
+ }
+ }
+ else
+ {
+#if LIBVC_ON
+ dec_eco_rlp(param, &pic_header->rpl_l0, sqh);
+#else
+ dec_eco_rlp(param, &pic_header->rpl_l0);
+#endif
+ pic_header->rpl_l0.poc = pic_header->poc;
+ }
+
+ //L1 candidates signaling
+ pic_header->ref_pic_list_sps_flag[1] = param->p.pic_header_ref_pic_list_sps_flag[1];
+ if (pic_header->ref_pic_list_sps_flag[1])
+ {
+ if (sqh->rpls_l1_num > 1 && sqh->rpl1_index_exist_flag)
+ {
+ pic_header->rpl_l1_idx = param->p.pic_header_rpl_l1_idx;
+ }
+ else if (!sqh->rpl1_index_exist_flag)
+ {
+ pic_header->rpl_l1_idx = pic_header->rpl_l0_idx;
+ }
+ else//if sps only have 1 RPL, no need to signal the idx
+ {
+ assert(sqh->rpls_l1_num == 1);
+ pic_header->rpl_l1_idx = 0;
+ }
+#ifdef BUFMGR_SANITY_CHECK
+ if ((pic_header->rpl_l1_idx >= 0) &&
+ (pic_header->rpl_l1_idx < MAX_NUM_RPLS))
+#endif
+ memcpy(&pic_header->rpl_l1, &sqh->rpls_l1[pic_header->rpl_l1_idx], sizeof(pic_header->rpl_l1));
+ pic_header->rpl_l1.poc = pic_header->poc;
+ }
+ else
+ {
+#if LIBVC_ON
+ dec_eco_rlp(param, &pic_header->rpl_l1, sqh);
+#else
+ dec_eco_rlp(param, &pic_header->rpl_l1);
+#endif
+ pic_header->rpl_l1.poc = pic_header->poc;
+ }
+#ifdef AML
+ pic_header->rpl_l0.ref_pic_num = param->p.pic_header_rpl_l0_ref_pic_num;
+ for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+ pic_header->rpl_l0.ref_pics_ddoi[ii] = param->p.pic_header_rpl_l0_ref_pics_ddoi[ii];
+ }
+ pic_header->rpl_l1.ref_pic_num = param->p.pic_header_rpl_l1_ref_pic_num;
+ for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+ pic_header->rpl_l1.ref_pics_ddoi[ii] = param->p.pic_header_rpl_l1_ref_pics_ddoi[ii];
+ }
+
+ pic_header->rpl_l0.reference_to_library_enable_flag = param->p.pic_header_rpl_l0_reference_to_library_enable_flag;
+ for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+ pic_header->rpl_l0.library_index_flag[ii] = param->p.pic_header_rpl_l0_library_index_flag[ii];
+ }
+ pic_header->rpl_l1.reference_to_library_enable_flag = param->p.pic_header_rpl_l1_reference_to_library_enable_flag;
+ for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+ pic_header->rpl_l1.library_index_flag[ii] = param->p.pic_header_rpl_l1_library_index_flag[ii];
+ }
+
+#endif
+
+ if (pic_header->slice_type != SLICE_I)
+ {
+ pic_header->num_ref_idx_active_override_flag = param->p.pic_header_num_ref_idx_active_override_flag;
+ if (pic_header->num_ref_idx_active_override_flag)
+ {
+ pic_header->rpl_l0.ref_pic_active_num = (u32)param->p.pic_header_rpl_l0_ref_pic_active_num;
+#ifdef BUFMGR_SANITY_CHECK
+ if (pic_header->rpl_l0.ref_pic_active_num > MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("<1>pic_header->rpl_l0.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+ pic_header->rpl_l0.ref_pic_active_num, MAX_NUM_REF_PICS);
+ pic_header->rpl_l0.ref_pic_active_num = MAX_NUM_REF_PICS;
+ }
+#endif
+ if (pic_header->slice_type == SLICE_P)
+ {
+ pic_header->rpl_l1.ref_pic_active_num = 0;
+ }
+ else if (pic_header->slice_type == SLICE_B)
+ {
+ pic_header->rpl_l1.ref_pic_active_num = (u32)param->p.pic_header_rpl_l1_ref_pic_active_num;
+#ifdef BUFMGR_SANITY_CHECK
+ if (pic_header->rpl_l1.ref_pic_active_num > MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("<2>pic_header->rpl_l1.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+ pic_header->rpl_l1.ref_pic_active_num, MAX_NUM_REF_PICS);
+ pic_header->rpl_l1.ref_pic_active_num = MAX_NUM_REF_PICS;
+ }
+#endif
+ }
+ }
+ else
+ {
+ //Hendry -- @Roman: we need to signal the num_ref_idx_default_active_minus1[ i ]. This syntax element is in the PPS in the spec document
+ pic_header->rpl_l0.ref_pic_active_num = sqh->num_ref_default_active_minus1[0]+1;
+#ifdef BUFMGR_SANITY_CHECK
+ if (pic_header->rpl_l0.ref_pic_active_num > MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("<3>pic_header->rpl_l0.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+ pic_header->rpl_l0.ref_pic_active_num, MAX_NUM_REF_PICS);
+ pic_header->rpl_l0.ref_pic_active_num = MAX_NUM_REF_PICS;
+ }
+#endif
+ if (pic_header->slice_type == SLICE_P)
+ {
+ pic_header->rpl_l1.ref_pic_active_num = 0;
+ }
+ else
+ {
+ pic_header->rpl_l1.ref_pic_active_num = sqh->num_ref_default_active_minus1[1] + 1;
+#ifdef BUFMGR_SANITY_CHECK
+ if (pic_header->rpl_l1.ref_pic_active_num > MAX_NUM_REF_PICS) {
+ if (avs3_get_debug_flag())
+ pr_info("<4>pic_header->rpl_l1.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+ pic_header->rpl_l1.ref_pic_active_num, MAX_NUM_REF_PICS);
+ pic_header->rpl_l1.ref_pic_active_num = MAX_NUM_REF_PICS;
+ }
+#endif
+ }
+ }
+ }
+ if (pic_header->slice_type == SLICE_I)
+ {
+ pic_header->rpl_l0.ref_pic_active_num = 0;
+ pic_header->rpl_l1.ref_pic_active_num = 0;
+ }
+#if LIBVC_ON
+ pic_header->is_RLpic_flag = 0;
+ if (pic_header->slice_type != SLICE_I)
+ {
+ int only_ref_libpic_flag = 1;
+#ifdef BUFMGR_SANITY_CHECK
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num && i < MAX_NUM_REF_PICS; i++)
+#else
+ for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++)
+#endif
+ {
+ if (!pic_header->rpl_l0.library_index_flag[i])
+ {
+ only_ref_libpic_flag = 0;
+ break;
+ }
+ }
+ if (only_ref_libpic_flag)
+ {
+#ifdef BUFMGR_SANITY_CHECK
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num && i < MAX_NUM_REF_PICS; i++)
+#else
+ for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++)
+#endif
+ {
+ if (!pic_header->rpl_l1.library_index_flag[i])
+ {
+ only_ref_libpic_flag = 0;
+ break;
+ }
+ }
+ }
+ pic_header->is_RLpic_flag = only_ref_libpic_flag;
+ }
+#endif
+#endif
+
+#ifdef ORI_CODE
+
+ //pic_header->fixed_picture_qp_flag = param->p.pic_header_fixed_picture_qp_flag;
+ //pic_header->picture_qp = param->p.pic_header_picture_qp;
+#if CUDQP && PHASE_2_PROFILE
+ pic_header->cu_delta_qp_flag = pic_header->cu_qp_group_size = pic_header->cu_qp_group_area_size = 0;
+ if (!pic_header->fixed_picture_qp_flag && (sqh->profile_id == 0x32 || sqh->profile_id == 0x30))
+ {
+ pic_header->cu_delta_qp_flag = param->p.pic_header_cu_delta_qp_flag;
+ if (pic_header->cu_delta_qp_flag)
+ {
+ pic_header->cu_qp_group_size = param->p.pic_header_cu_qp_group_size;
+ pic_header->cu_qp_group_area_size = pic_header->cu_qp_group_size * pic_header->cu_qp_group_size;
+ }
+ }
+#endif
+#if CABAC_MULTI_PROB
+ if (pic_header->slice_type == SLICE_I)
+ {
+ mCabac_ws = MCABAC_SHIFT_I;
+ mCabac_offset = (1 << (mCabac_ws - 1));
+ counter_thr1 = 0;
+ counter_thr2 = COUNTER_THR_I;
+ }
+ else if (pic_header->slice_type == SLICE_B)
+ {
+ mCabac_ws = MCABAC_SHIFT_B;
+ mCabac_offset = (1 << (mCabac_ws - 1));
+ counter_thr1 = 3;
+ counter_thr2 = COUNTER_THR_B;
+ }
+ else
+ {
+ mCabac_ws = MCABAC_SHIFT_P;
+ mCabac_offset = (1 << (mCabac_ws - 1));
+ counter_thr1 = 3;
+ counter_thr2 = COUNTER_THR_P;
+ }
+ if (sqh->mcabac_enable_flag)
+ {
+ g_compatible_back = 0;
+ }
+ else
+ {
+ g_compatible_back = 1;
+ }
+#endif
+ //the reserved_bits only appears in inter_picture_header, so add the non-I-slice check
+ if ( pic_header->slice_type != SLICE_I && !(pic_header->slice_type == SLICE_B && pic_header->picture_structure == 1) )
+ {
+ com_bsr_read1( bs ); // reserved_bits r(1)
+ }
+ dec_eco_DB_param(bs, pic_header
+#if DBK_SCC || DBR
+ , sqh
+#endif
+ );
+
+ //pic_header->chroma_quant_param_disable_flag = (u8)param->p.pic_header_chroma_quant_param_disable_flag;
+ if (pic_header->chroma_quant_param_disable_flag == 0)
+ {
+ pic_header->chroma_quant_param_delta_cb = (u8)com_bsr_read_se(bs);
+ pic_header->chroma_quant_param_delta_cr = (u8)com_bsr_read_se(bs);
+ }
+ else
+ {
+ pic_header->chroma_quant_param_delta_cb = pic_header->chroma_quant_param_delta_cr = 0;
+ }
+
+ if (sqh->wq_enable)
+ {
+ pic_header->pic_wq_enable = param->p.pic_header_pic_wq_enable;
+ if (pic_header->pic_wq_enable)
+ {
+ pic_header->pic_wq_data_idx = param->p.pic_header_pic_wq_data_idx;
+ if (pic_header->pic_wq_data_idx == 0)
+ {
+ memcpy(pic_header->wq_4x4_matrix, sqh->wq_4x4_matrix, sizeof(sqh->wq_4x4_matrix));
+ memcpy(pic_header->wq_8x8_matrix, sqh->wq_8x8_matrix, sizeof(sqh->wq_8x8_matrix));
+ }
+ else if (pic_header->pic_wq_data_idx == 1)
+ {
+ int delta, i;
+ com_bsr_read1( bs ); //reserved_bits r(1)
+ pic_header->wq_param = param->p.pic_header_wq_param;
+ pic_header->wq_model = param->p.pic_header_wq_model;
+ if (pic_header->wq_param == 0)
+ {
+ memcpy(pic_header->wq_param_vector, tab_wq_param_default[1], sizeof(pic_header->wq_param_vector));
+ }
+ else if (pic_header->wq_param == 1)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ delta = com_bsr_read_se(bs);
+ pic_header->wq_param_vector[i] = delta + tab_wq_param_default[0][i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ {
+ delta = com_bsr_read_se(bs);
+ pic_header->wq_param_vector[i] = delta + tab_wq_param_default[1][i];
+ }
+ }
+ set_pic_wq_matrix_by_param(pic_header->wq_param_vector, pic_header->wq_model, pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+ }
+ else
+ {
+ read_wq_matrix(bs, pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+ }
+ }
+ else
+ {
+ init_pic_wq_matrix(pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+ }
+ }
+ else
+ {
+ pic_header->pic_wq_enable = 0;
+ init_pic_wq_matrix(pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+ }
+#if ESAO
+ if (sqh->esao_enable_flag)
+ {
+#if ESAO_PH_SYNTAX
+ dec_eco_esao_param(bs, pic_header);
+#else
+ dec_eco_esao_pic_header(bs, pic_header);
+#endif
+ }
+ else
+ {
+ memset(pic_header->pic_esao_on, 0, N_C * sizeof(int));
+ }
+#endif
+#if CCSAO
+ if (sqh->ccsao_enable_flag)
+ {
+ dec_eco_ccsao_pic_header(bs, pic_header);
+#if CCSAO_PH_SYNTAX
+ dec_eco_ccsao_param(pic_header, bs);
+#endif
+ }
+ else
+ {
+ memset(pic_header->pic_ccsao_on, 0, (N_C-1) * sizeof(int));
+ }
+#endif
+/*ORI_CODE*/
+#endif
+ if (pic_header->tool_alf_on)
+ {
+ /* decode ALF flag and ALF coeff */
+#if ALF_SHAPE
+ int num_coef = (sqh->adaptive_filter_shape_enable_flag) ? ALF_MAX_NUM_COEF_SHAPE2 : ALF_MAX_NUM_COEF;
+#endif
+
+#if ALF_IMP
+ int max_filter_num = (sqh->adaptive_filter_shape_enable_flag) ? NO_VAR_BINS:NO_VAR_BINS_16;
+#endif
+
+ dec_eco_alf_param(param, pic_header
+#if ALF_SHAPE
+ , num_coef
+#endif
+#if ALF_IMP
+ ,max_filter_num
+#endif
+ );
+ }
+ else
+ {
+ memset( pic_header->pic_alf_on, 0, N_C * sizeof( int ) );
+ }
+#ifdef ORI_CODE
+ if (pic_header->slice_type != SLICE_I && sqh->affine_enable_flag)
+ {
+ //pic_header->affine_subblock_size_idx = param->p.pic_header_affine_subblock_size_idx;
+ }
+#if USE_IBC
+#if PHASE_2_PROFILE
+ if (sqh->ibc_flag)
+ {
+#endif
+ pic_header->ibc_flag = (u8)param->p.pic_header_ibc_flag;
+#if PHASE_2_PROFILE
+ }
+ else
+ {
+ pic_header->ibc_flag = 0;
+ }
+#endif
+#endif
+#if USE_SP
+#if PHASE_2_PROFILE
+ if (sqh->sp_enable_flag)
+ {
+#endif
+ pic_header->sp_pic_flag = (u8)param->p.pic_header_sp_pic_flag;
+#if PHASE_2_PROFILE
+ }
+ else
+ {
+ pic_header->sp_pic_flag = 0;
+ }
+#endif
+#if EVS_UBVS_MODE
+ pic_header->evs_ubvs_pic_flag = sqh->evs_ubvs_enable_flag;
+#endif
+#endif
+#if FIMC
+#if PHASE_2_PROFILE
+ if (sqh->fimc_enable_flag)
+ {
+#endif
+ pic_header->fimc_pic_flag = (u8)param->p.pic_header_fimc_pic_flag;
+#if PHASE_2_PROFILE
+ }
+ else
+ {
+ pic_header->fimc_pic_flag = 0;
+ }
+#endif
+#endif
+#if ISTS
+ if (sqh->ists_enable_flag)
+ {
+ pic_header->ph_ists_enable_flag = (u8)param->p.pic_header_ph_ists_enable_flag;
+ }
+#if PHASE_2_PROFILE
+ else
+ {
+ pic_header->ph_ists_enable_flag = 0;
+ }
+#endif
+#endif
+#if TS_INTER
+ if (sqh->ts_inter_enable_flag && pic_header->slice_type != SLICE_I)
+ {
+ pic_header->ph_ts_inter_enable_flag = (u8)param->p.pic_header_ph_ts_inter_enable_flag;
+ }
+#if PHASE_2_PROFILE
+ else
+ {
+ pic_header->ph_ts_inter_enable_flag = 0;
+ }
+#endif
+#endif
+#if AWP
+ if (sqh->awp_enable_flag)
+ {
+ pic_header->ph_awp_refine_flag = (u8)param->p.pic_header_ph_awp_refine_flag;
+ }
+#if PHASE_2_PROFILE
+ else
+ {
+ pic_header->ph_awp_refine_flag = 0;
+ }
+#endif
+#endif
+#if UMVE_ENH
+ if (sqh->umve_enh_enable_flag && pic_header->slice_type != SLICE_I)
+ {
+ pic_header->umve_set_flag = (u8)param->p.pic_header_umve_set_flag;
+ }
+ else
+ {
+ pic_header->umve_set_flag = 0;
+ }
+#endif
+#if EPMC
+ if (sqh->pmc_enable_flag)
+ {
+ pic_header->ph_epmc_model_flag = (u8)param->p.pic_header_ph_epmc_model_flag;
+
+ }
+ else
+ {
+ pic_header->ph_epmc_model_flag = 0;
+ }
+#endif
+ /* byte align */
+
+ ret = com_bsr_read1(bs);
+ assert(ret == 1);
+ while (!COM_BSR_IS_BYTE_ALIGN(bs))
+ {
+ assert(com_bsr_read1(bs) == 0);
+ }
+ while (com_bsr_next(bs, 24) != 0x1)
+ {
+ assert(com_bsr_read(bs, 8) == 0);
+ }
+/*ORI_CODE*/
+#endif
+ return COM_OK;
+}
+
+int dec_eco_patch_header(union param_u *param, COM_SQH *sqh, COM_PIC_HEADER * ph, COM_SH_EXT * sh,PATCH_INFO *patch)
+{
+ return COM_OK;
+}
+
+int dec_eco_alf_param(union param_u *rpm_param, COM_PIC_HEADER *sh
+#if ALF_SHAPE
+ , int num_coef
+#endif
+#if ALF_IMP
+ , int max_filter_num
+#endif
+)
+{
+ ALF_PARAM **alf_picture_param = sh->alf_picture_param;
+ int *pic_alf_on = sh->pic_alf_on;
+ int compIdx;
+ if (alf_picture_param == NULL) {
+ pr_err("%s, alf_picture_param null\n", __func__);
+ return COM_ERR;
+ }
+
+#if ALF_SHAPE
+ alf_picture_param[Y_C]->num_coeff = num_coef;
+ alf_picture_param[U_C]->num_coeff = num_coef;
+ alf_picture_param[V_C]->num_coeff = num_coef;
+#endif
+#if ALF_IMP
+ alf_picture_param[Y_C]->max_filter_num = max_filter_num;
+ alf_picture_param[U_C]->max_filter_num = 1;
+ alf_picture_param[V_C]->max_filter_num = 1;
+#endif
+ pic_alf_on[Y_C] = rpm_param->alf.picture_alf_enable_Y;
+ pic_alf_on[U_C] = rpm_param->alf.picture_alf_enable_Cb;
+ pic_alf_on[V_C] = rpm_param->alf.picture_alf_enable_Cr;
+
+ alf_picture_param[Y_C]->alf_flag = pic_alf_on[Y_C];
+ alf_picture_param[U_C]->alf_flag = pic_alf_on[U_C];
+ alf_picture_param[V_C]->alf_flag = pic_alf_on[V_C];
+ if (pic_alf_on[Y_C] || pic_alf_on[U_C] || pic_alf_on[V_C])
+ {
+ for (compIdx = 0; compIdx < N_C; compIdx++)
+ {
+ if (pic_alf_on[compIdx])
+ {
+ dec_eco_alf_coeff(rpm_param, alf_picture_param[compIdx]);
+ }
+ }
+ }
+ return COM_OK;
+}
+
+int dec_eco_alf_coeff(union param_u *rpm_param, ALF_PARAM *alf_param)
+{
+ int pos;
+ int f = 0, symbol, pre_symbole;
+ int32_t region_distance_idx = 0;
+#if ALF_SHAPE
+ const int num_coeff = alf_param->num_coeff;
+#else
+ const int num_coeff = (int)ALF_MAX_NUM_COEF;
+#endif
+
+ if (num_coeff > ALF_MAX_NUM_COEF)
+ return COM_ERR;
+
+ switch (alf_param->component_id)
+ {
+ case U_C:
+ case V_C:
+ for (pos = 0; pos < num_coeff; pos++)
+ {
+ if (alf_param->component_id == U_C)
+ alf_param->coeff_multi[0][pos] = (int16_t)rpm_param->alf.alf_cb_coeffmulti[pos];
+ else
+ alf_param->coeff_multi[0][pos] = (int16_t)rpm_param->alf.alf_cr_coeffmulti[pos];
+ }
+ break;
+ case Y_C:
+ alf_param->filters_per_group = rpm_param->alf.alf_filters_num_m_1;
+ alf_param->filters_per_group = alf_param->filters_per_group + 1;
+#if ALF_IMP
+ if (alf_param->max_filter_num == NO_VAR_BINS)
+ {
+ alf_param->dir_index = rpm_param->alf.dir_index;
+ }
+ else
+ {
+ assert(alf_param->max_filter_num == NO_VAR_BINS_16);
+ }
+#endif
+ memset(alf_param->filter_pattern, 0, NO_VAR_BINS * sizeof(int));
+ pre_symbole = 0;
+ symbol = 0;
+ for (f = 0; f < alf_param->filters_per_group; f++)
+ {
+ if (f > 0)
+ {
+#if ALF_IMP
+ if (alf_param->filters_per_group != alf_param->max_filter_num)
+#else
+ if (alf_param->filters_per_group != NO_VAR_BINS)
+#endif
+ {
+ symbol = rpm_param->alf.region_distance[region_distance_idx++];
+ }
+ else
+ {
+ symbol = 1;
+ }
+ alf_param->filter_pattern[symbol + pre_symbole] = 1;
+ pre_symbole = symbol + pre_symbole;
+ }
+ for (pos = 0; pos < num_coeff; pos++)
+ {
+ alf_param->coeff_multi[f][pos] = (int16_t)rpm_param->alf.alf_y_coeffmulti[f][pos]; //com_bsr_read_se(bs);
+ }
+ }
+ break;
+ default:
+ printf("Not a legal component ID\n");
+ assert(0);
+ //exit(-1);
+ return -1;
+ }
+ return COM_OK;
+}
diff --git a/drivers/frame_provider/decoder/avs3/vavs3.c b/drivers/frame_provider/decoder/avs3/vavs3.c
new file mode 100644
index 0000000..9a674bc
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/vavs3.c
@@ -0,0 +1,11203 @@
+ /*
+ * drivers/amlogic/amports/avs3.c
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/frame_sync/tsync.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+#include <linux/slab.h>
+//#include <linux/amlogic/tee.h>
+#include <uapi/linux/tee.h>
+#include <linux/sched/clock.h>
+#include "../../../stream_input/amports/amports_priv.h"
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "avs3_global.h"
+#include "../../../common/media_utils/media_utils.h"
+//#define TMP_DEBUG
+
+//#define USE_FRONT_ISR_HANDLE_FOR_BACK
+
+#define FOR_S5
+#define PXP_DEBUG
+#define USE_SIM_BUFSPEC
+
+//#define DEBUG_CMD
+
+#define MEM_NAME "codec_avs3"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+
+#include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include "../utils/config_parser.h"
+#include "../utils/firmware.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../utils/vdec_feature.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "../utils/vdec_profile.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+#define DYN_CACHE
+#define I_ONLY_SUPPORT
+#define MIX_STREAM_SUPPORT
+//#define CONSTRAIN_MAX_BUF_NUM
+
+#define CO_MV_COMPRESS
+
+#include "vavs3.h"
+#define HEVC_SHIFT_LENGTH_PROTECT 0x313a
+#define HEVC_MPRED_CTRL4 0x324c
+#define HEVC_DBLK_CFGD 0x350d
+#define HEVC_CM_HEADER_START_ADDR 0x3628
+#define HEVC_DBLK_CFGB 0x350b
+#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
+#define HEVC_SAO_MMU_VH1_ADDR 0x363b
+#define HEVC_SAO_MMU_VH0_ADDR 0x363a
+
+#define HEVC_CM_BODY_LENGTH2 0x3663
+#define HEVC_CM_HEADER_OFFSET2 0x3664
+#define HEVC_CM_HEADER_LENGTH2 0x3665
+
+#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
+
+#define HEVC_CM_HEADER_START_ADDR 0x3628
+#define HEVC_CM_HEADER_START_ADDR2 0x364a
+#define HEVC_SAO_MMU_VH1_ADDR 0x363b
+#define HEVC_SAO_MMU_VH0_ADDR 0x363a
+#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
+#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
+
+#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
+#define HEVC_SAO_MMU_STATUS2 0x3650
+#define HEVC_DW_VH0_ADDDR 0x365e
+#define HEVC_DW_VH1_ADDDR 0x365f
+
+#define HEVC_SAO_CTRL9 0x362d
+
+/*
+ * AVS3_DEC_STATUS define
+*/
+/*internal*/
+#define AVS3_DEC_IDLE 0
+#define AVS3_SEQUENCE 1
+#define AVS3_I_PICTURE 2
+#define AVS3_PB_PICTURE 3
+#define AVS3_DISCARD_STARTCODE 4
+#define AVS3_DISCARD_NAL 4
+
+#define AVS3_SLICE_DECODING 6
+
+#define SWAP_IN_CMD 0x10
+#define SWAP_OUT_CMD 0x11
+#define SWAP_OUTIN_CMD 0x12
+#define SWAP_DONE 0x13
+#define SWAP_POST_INIT 0x14
+
+/*head*/
+#define AVS3_HEAD_SEQ_READY 0x21
+#define AVS3_HEAD_PIC_I_READY 0x22
+#define AVS3_HEAD_PIC_PB_READY 0x23
+#define AVS3_HEAD_SEQ_END_READY 0x24
+#define AVS3_STARTCODE_SEARCH_DONE 0x25
+
+/*pic done*/
+#define HEVC_DECPIC_DATA_DONE 0x30
+#define HEVC_DECPIC_DATA_ERROR 0x31
+#define HEVC_NAL_DECODE_DONE 0x32
+#define AVS3_DECODE_BUFEMPTY 0x33
+#define AVS3_DECODE_TIMEOUT 0x34
+#define AVS3_DECODE_OVER_SIZE 0x35
+#define AVS3_EOS 0x36
+
+/*cmd*/
+#define AVS3_10B_DISCARD_NAL 0xf0
+#define AVS3_SEARCH_NEW_PIC 0xf1
+#define AVS3_ACTION_ERROR 0xfe
+#define HEVC_ACTION_ERROR 0xfe
+#define AVS3_ACTION_DONE 0xff
+/*AVS3_DEC_STATUS end*/
+
+//???
+#define HEVC_BE_DECODE_DATA 0xa0
+#define HEVC_BE_DECODE_DATA_DONE 0xb0
+#define HEVC_BE_DECODE_TIMEOUT 0xc0
+/*AVS3_BE_DEC_STATUS end*/
+
+#define VF_POOL_SIZE 32
+
+#undef pr_info
+#define pr_info printk
+
+#define DECODE_MODE_SINGLE (0 | (0x80 << 24))
+#define DECODE_MODE_MULTI_STREAMBASE (1 | (0x80 << 24))
+#define DECODE_MODE_MULTI_FRAMEBASE (2 | (0x80 << 24))
+
+#define VP9_TRIGGER_FRAME_DONE 0x100
+#define VP9_TRIGGER_FRAME_ENABLE 0x200
+
+/*#define MV_MEM_UNIT 0x240*/
+#define MV_MEM_UNIT 0x200
+/*---------------------------------------------------
+ Include "parser_cmd.h"
+---------------------------------------------------*/
+#define PARSER_CMD_SKIP_CFG_0 0x0000090b
+
+#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
+
+#define PARSER_CMD_SKIP_CFG_2 0x001b1910
+
+#define PARSER_CMD_NUMBER 37
+
+static unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
+0x0401,
+0x8401,
+0x0800,
+0x0402,
+0x9002,
+0x1423,
+0x8CC3,
+0x1423,
+0x8804,
+0x9825,
+0x0800,
+0x04FE,
+0x8406,
+0x8411,
+0x1800,
+0x8408,
+0x8409,
+0x8C2A,
+0x9C2B,
+0x1C00,
+0x840F,
+0x8407,
+0x8000,
+0x8408,
+0x2000,
+0xA800,
+0x8410,
+0x04DE,
+0x840C,
+0x840D,
+0xAC00,
+0xA000,
+0x08C0,
+0x08E0,
+0xA40E,
+0xFC00,
+0x7C00
+};
+
+static int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+};
+
+static int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+};
+/*#define HEVC_PIC_STRUCT_SUPPORT*/
+/* to remove, fix build error */
+
+/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/
+
+#define MULTI_INSTANCE_SUPPORT
+/* #define ERROR_HANDLE_DEBUG */
+
+#ifndef STAT_KTHREAD
+#define STAT_KTHREAD 0x40
+#endif
+
+#ifdef MULTI_INSTANCE_SUPPORT
+#define MAX_DECODE_INSTANCE_NUM 12
+#define MULTI_DRIVER_NAME "ammvdec_avs3"
+
+#define lock_buffer(dec, flags) \
+ spin_lock_irqsave(&dec->buffer_lock, flags)
+
+#define unlock_buffer(dec, flags) \
+ spin_unlock_irqrestore(&dec->buffer_lock, flags)
+
+#define lock_front_back(dec, flags) \
+ spin_lock_irqsave(&dec->front_back_lock, flags)
+
+#define unlock_front_back(dec, flags) \
+ spin_unlock_irqrestore(&dec->front_back_lock, flags)
+
+u32 debug_mask = 0xffffffff;
+#define get_dbg_flag(dec) ((debug_mask & (1 << dec->index)) ? debug : 0)
+
+static unsigned int max_decode_instance_num
+ = MAX_DECODE_INSTANCE_NUM;
+static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
+static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
+static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
+#ifdef NEW_FB_CODE
+static unsigned int max_process_time_back[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count_back[MAX_DECODE_INSTANCE_NUM];
+#endif
+static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
+static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
+
+static u32 decode_timeout_val = 200;
+
+static u32 over_decoder_shiftbytes = 0x80;
+#endif
+
+static int start_decode_buf_level = 0x8000;
+
+static u32 work_buf_size;
+
+static u32 mv_buf_margin;
+static int pre_decode_buf_level = 0x1000;
+static u32 again_threshold;
+
+/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
+/* double_write_mode:
+ * 0, no double write;
+ * 1, 1:1 ratio;
+ * 2, (1/4):(1/4) ratio;
+ * 3, (1/4):(1/4) ratio, with both compressed frame included
+ * 4, (1/2):(1/2) ratio;
+ * 8, (1/8):(1/8) ratio;
+ * 0x10, double write only
+ * 0x100, if > 1080p,use mode 4,else use mode 1;
+ * 0x200, if > 1080p,use mode 2,else use mode 1;
+ * 0x300, if > 720p, use mode 4, else use mode 1;
+ * 0x10000, double write p010 enable
+ */
+static u32 double_write_mode;
+
+/* triple_write_mode:
+ * 0, no triple write;
+ * 1, 1:1 ratio;
+ * 2, (1/4):(1/4) ratio;
+ * 3, (1/4):(1/4) ratio, with both compressed frame included
+ * 4, (1/2):(1/2) ratio;
+ * 5, (1/2):(1/2) ratio, with both compressed frame included
+ * 8, (1/8):(1/8) ratio
+ * 0x10000, triple write p010 enable
+ */
+static u32 triple_write_mode;
+
+static u32 without_display_mode;
+
+static u32 trace_debug_mode = 7;
+static u32 paral_alloc_buffer_mode = 1;
+
+static u32 mv_buf_dynamic_alloc;
+
+#define DRIVER_NAME "amvdec_avs3"
+#define DRIVER_HEADER_NAME "amvdec_avs3_header"
+
+#define PUT_INTERVAL (HZ/100)
+#define ERROR_SYSTEM_RESET_COUNT 200
+
+#define PTS_NORMAL 0
+#define PTS_NONE_REF_USE_DURATION 1
+
+#define PTS_MODE_SWITCHING_THRESHOLD 3
+#define PTS_MODE_SWITCHING_RECOVERY_THRESHOLD 3
+
+#define DUR2PTS(x) ((x)*90/96)
+
+struct AVS3Decoder_s;
+static int vavs3_vf_states(struct vframe_states *states, void *);
+static struct vframe_s *vavs3_vf_peek(void *);
+static struct vframe_s *vavs3_vf_get(void *);
+static void vavs3_vf_put(struct vframe_s *, void *);
+static int vavs3_event_cb(int type, void *data, void *private_data);
+static void set_vframe(struct AVS3Decoder_s *dec,
+ struct vframe_s *vf, struct avs3_frame_s *pic, u8 dummy);
+
+static int vavs3_stop(struct AVS3Decoder_s *dec);
+static s32 vavs3_init(struct vdec_s *vdec);
+static void vavs3_prot_init(struct AVS3Decoder_s *dec);
+static int vavs3_local_init(struct AVS3Decoder_s *dec);
+static void vavs3_put_timer_func(struct timer_list *timer);
+static void dump_data(struct AVS3Decoder_s *dec, int size);
+static unsigned char get_data_check_sum
+ (struct AVS3Decoder_s *dec, int size);
+static struct avs3_frame_s *get_pic_by_index(
+ struct AVS3Decoder_s *dec, int index);
+void pic_backend_ref_operation(struct AVS3Decoder_s *dec, avs3_frame_t *pic, bool add_flag);
+static int avs3_hw_ctx_restore(struct AVS3Decoder_s *dec);
+static void dump_or_fill_phy_buffer(struct AVS3Decoder_s *dec, u32 phy_adr, u32 size, char *file, u8 flag, char *mark);
+static void d_dump(struct AVS3Decoder_s *dec, unsigned int phy_adr, int size,
+ struct file *fp, loff_t *wr_off, u32 * total_check_sum, u8 print_flag);
+
+#ifdef NEW_FB_CODE
+static unsigned int decode_timeout_val_back = 200;
+static unsigned int fast_timer_check_count = 3;
+
+static unsigned int efficiency_mode = 1;
+
+static void avs3_work_back(struct work_struct *work);
+static void avs3_timeout_work_back(struct work_struct *work);
+static void avs3_work_back_implement(struct AVS3Decoder_s *dec,
+ struct vdec_s *vdec, int from);
+#endif
+
+static const char vavs3_dec_id[] = "vavs3-dev";
+
+#define PROVIDER_NAME "decoder.avs3"
+#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs3"
+
+static const struct vframe_operations_s vavs3_vf_provider = {
+ .peek = vavs3_vf_peek,
+ .get = vavs3_vf_get,
+ .put = vavs3_vf_put,
+ .event_cb = vavs3_event_cb,
+ .vf_states = vavs3_vf_states,
+};
+
+static struct vframe_provider_s vavs3_vf_prov;
+
+static u32 bit_depth_luma;
+static u32 bit_depth_chroma;
+static u32 frame_width;
+static u32 frame_height;
+static u32 video_signal_type;
+static u32 pts_unstable;
+static u32 on_no_keyframe_skiped;
+
+static u32 force_video_signal_type;
+static u32 enable_force_video_signal_type;
+#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
+#define HDR_CUVA_MASK 0x40000000
+
+static const char * const video_format_names[] = {
+ "component", "PAL", "NTSC", "SECAM",
+ "MAC", "unspecified", "Reserved", "Reserved"
+};
+
+static inline int div_r32(int64_t m, int n)
+{
+/*
+return (int)(m/n)
+*/
+#ifndef CONFIG_ARM64
+ int64_t qu = 0;
+ qu = div_s64(m, n);
+ return (int)qu;
+#else
+ return (int)(m/n);
+#endif
+}
+
+enum vpx_bit_depth_t {
+ AVS3_BITS_8 = 8, /**< 8 bits */
+ AVS3_BITS_10 = 10, /**< 10 bits */
+ AVS3_BITS_12 = 12, /**< 12 bits */
+};
+
+enum trace_debug_t {
+ TRACE_BASIC = 1,
+ TRACE_BUFFER = 2,
+ TRACE_PERFORMANCE_DETAIL = 4,
+};
+
+enum alloc_buffer_status_t {
+ BUFFER_INIT = 0,
+ BUFFER_ALLOCATING = 1,
+ BUFFER_ALLOCATE_DONE = 2,
+};
+
+/*USE_BUF_BLOCK*/
+struct BUF_s {
+ int index;
+ unsigned int alloc_flag;
+ /*buffer */
+ unsigned int cma_page_count;
+ unsigned long alloc_addr;
+ unsigned long start_adr;
+ unsigned int size;
+
+ unsigned int free_start_adr;
+} /*BUF_t */;
+
+struct MVBUF_s {
+ unsigned long start_adr;
+ unsigned int size;
+ int used_flag;
+} /*MVBUF_t */;
+
+ /* #undef BUFMGR_ONLY to enable hardware configuration */
+
+/*#define TEST_WR_PTR_INC*/
+#define WR_PTR_INC_NUM 128
+
+#define SIMULATION
+#define DOS_PROJECT
+#undef MEMORY_MAP_IN_REAL_CHIP
+
+/*#undef DOS_PROJECT*/
+/*#define MEMORY_MAP_IN_REAL_CHIP*/
+
+/*#define BUFFER_MGR_ONLY*/
+/*#define CONFIG_HEVC_CLK_FORCED_ON*/
+/*#define ENABLE_SWAP_TEST*/
+
+#ifdef AVS3_10B_NV21
+#define MEM_MAP_MODE 2 /* 0:linear 1:32x32 2:64x32*/
+#else
+#define MEM_MAP_MODE 0 /* 0:linear 1:32x32 2:64x32*/
+#endif
+
+#ifdef AVS3_10B_NV21
+#else
+#define LOSLESS_COMPRESS_MODE
+#endif
+
+#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
+#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+//#define UCODE_LOG_BUF_SIZE (16 * 1024)
+#define UCODE_LOG_BUF_SIZE (1024 * 1024)
+#endif
+
+#ifdef DEBUG_CMD
+static u32 debug_cmd_wait_count;
+static u32 debug_cmd_wait_type;
+#endif
+
+/* bit 0, disable backend
+ bit 1, start frontend only after last backend done (not pipeline front-back)
+ bit 2, do not loop buffer (use with bit[1] of 1)
+ bit 3, fill loop buffer 0 before starting front decoding
+ ##
+ bit[31:28],1: dump loop buffer at frontend data done for specific frame to file
+ bit[27:16], frame num
+ bit[31:28],2: dump frame count of frames to file
+ bit[27:16], frame count
+ bit[31:28],3: dump every frame and print checksum
+ bit[31:28] 8: dump loop buffer to file in dump_state()
+*/
+static u32 fbdebug_flag;
+
+static u32 debug;
+
+static u32 debug_again;
+
+u32 avs3_get_debug_flag(void)
+{
+ return debug;
+}
+
+bool is_avs3_print_param(void)
+{
+ bool ret = false;
+ if (debug & AVS3_DBG_PRINT_PARAM)
+ ret = true;
+ return ret;
+}
+
+inline bool is_avs3_print_bufmgr_detail(void)
+{
+ bool ret = false;
+ if (debug & AVS3_DBG_BUFMGR_DETAIL)
+ ret = true;
+ return ret;
+}
+static bool is_reset;
+/*for debug*/
+static u32 force_bufspec;
+/*
+ udebug_flag:
+ bit 0, enable ucode print
+ bit 1, enable ucode detail print
+ bit [31:16] not 0, pos to dump lmem
+ bit 2, pop bits to lmem
+ bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
+*/
+static u32 udebug_flag;
+/*
+ when udebug_flag[1:0] is not 0
+ udebug_pause_pos not 0,
+ pause position
+*/
+static u32 udebug_pause_pos;
+/*
+ when udebug_flag[1:0] is not 0
+ and udebug_pause_pos is not 0,
+ pause only when DEBUG_REG2 is equal to this val
+*/
+static u32 udebug_pause_val;
+
+static u32 udebug_pause_decode_idx;
+
+static u32 force_disp_pic_index;
+
+static u32 dump_phy_adr;
+static u32 dump_phy_size;
+
+#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
+static u32 cuva_buf_size = 512;
+
+#define DEBUG_REG
+#ifdef DEBUG_REG
+static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
+{
+ if (debug & AVS3_DBG_REG) {
+ unsigned adr_conv = dos_reg_compat_convert(adr);
+ pr_info("%s(%x, %x)\n", __func__, adr_conv, val);
+ }
+ if (adr != 0)
+ WRITE_VREG(adr, val);
+
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ if (adr == HEVC_ASSIST_SCRATCH_0) // && val == AVS3_ACTION_DONE)
+ pr_info("!!write HEVC_ASSIST_SCRATCH_0 %x\n", val);
+ }
+}
+
+#undef WRITE_VREG
+#define WRITE_VREG WRITE_VREG_DBG2
+#endif
+
+#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
+#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
+#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
+
+#define INVALID_IDX -1 /* Invalid buffer index.*/
+
+#define FRAME_BUFFERS (MAX_PB_SIZE)
+#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
+
+#define FRAME_CONTEXTS_LOG2 2
+#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
+/*buffer + header buffer + workspace*/
+
+#ifdef NEW_FB_CODE
+#define BMMU_IFBUF_SCALELUT_ID (0)
+#define BMMU_IFBUF_VCPU_IMEM_ID (BMMU_IFBUF_SCALELUT_ID + 1)
+#define BMMU_IFBUF_SYS_IMEM_ID (BMMU_IFBUF_VCPU_IMEM_ID + 1)
+#define BMMU_IFBUF_LMEM0_ID (BMMU_IFBUF_SYS_IMEM_ID + 1)
+#define BMMU_IFBUF_LMEM1_ID (BMMU_IFBUF_LMEM0_ID + 1)
+#define BMMU_IFBUF_PARSER_SAO0_ID (BMMU_IFBUF_LMEM1_ID + 1)
+#define BMMU_IFBUF_PARSER_SAO1_ID (BMMU_IFBUF_PARSER_SAO0_ID + 1)
+#define BMMU_IFBUFF_MPRED_IMP0_ID (BMMU_IFBUF_PARSER_SAO1_ID + 1)
+#define BMMU_IFBUFF_MPRED_IMP1_ID (BMMU_IFBUFF_MPRED_IMP0_ID + 1)
+#define FB_LOOP_BUF_COUNT (BMMU_IFBUFF_MPRED_IMP1_ID + 1)
+#else
+#define FB_LOOP_BUF_COUNT 0
+#endif
+
+#define MV_USE_FIXED_BUF
+#ifdef MV_USE_FIXED_BUF
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1)
+#else
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + ((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define MV_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
+//#define DW_HEADER_BUFFER_IDX(n) ((FRAME_BUFFERS * 3) + n+1)
+#endif
+
+#define CO_MV_BUF_SIZE_1080P 0x3fc00
+#define CO_MV_BUF_SIZE_4K 0x120000
+#define CO_MV_BUF_SIZE_8K 0x480000
+/*
+static void set_canvas(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic);
+int avs3_prepare_display_buf(struct AVS3Decoder_s *dec,
+ int pos);
+*/
+
+#ifdef NEW_FB_CODE
+static u32 fb_ifbuf_num = 3;
+/*
+ 0: single core mode
+ 1: front_back_mode
+ 2: front_back_test_mode
+*/
+static u32 front_back_mode = 1;
+#endif
+
+struct BuffInfo_s {
+ u32 max_width;
+ u32 max_height;
+ u32 start_adr;
+ u32 end_adr;
+ struct buff_s ipp;
+#ifdef NEW_FRONT_BACK_CODE
+ struct buff_s ipp1;
+#endif
+ struct buff_s sao_abv;
+ struct buff_s sao_vb;
+ struct buff_s short_term_rps;
+ struct buff_s rcs;
+ struct buff_s sps;
+ struct buff_s pps;
+ struct buff_s sbac_top;
+ struct buff_s sao_up;
+ struct buff_s swap_buf;
+ struct buff_s swap_buf2;
+ struct buff_s scalelut;
+ struct buff_s dblk_para;
+ struct buff_s dblk_data;
+ struct buff_s dblk_data2;
+#ifdef AVS3_10B_MMU
+ struct buff_s mmu_vbh;
+ struct buff_s cm_header;
+#endif
+#ifdef AVS3_10B_MMU_DW
+ struct buff_s mmu_vbh_dw;
+ struct buff_s cm_header_dw;
+#endif
+ struct buff_s mpred_above;
+#ifdef MV_USE_FIXED_BUF
+ struct buff_s mpred_mv;
+#endif
+ struct buff_s rpm;
+ struct buff_s lmem;
+};
+
+#define DEC_RESULT_NONE 0
+#define DEC_RESULT_DONE 1
+#define DEC_RESULT_AGAIN 2
+#define DEC_RESULT_CONFIG_PARAM 3
+#define DEC_RESULT_ERROR 4
+#define DEC_INIT_PICLIST 5
+#define DEC_UNINIT_PICLIST 6
+#define DEC_RESULT_GET_DATA 7
+#define DEC_RESULT_GET_DATA_RETRY 8
+#define DEC_RESULT_EOS 9
+#define DEC_RESULT_FORCE_EXIT 10
+#define DEC_RESULT_WAIT_BUFFER 11
+#define DEC_RESULT_TIMEOUT 12
+
+#ifdef NEW_FB_CODE
+#define DEC_BACK_RESULT_NONE 0
+#define DEC_BACK_RESULT_DONE 1
+#define DEC_BACK_RESULT_TIMEOUT 2
+#define DEC_BACK_RESULT_FORCE_EXIT 10
+#endif
+
+static void avs3_work(struct work_struct *work);
+struct loop_filter_info_n;
+struct loopfilter;
+struct segmentation;
+
+struct AVS3Decoder_s {
+ int pic_list_init_flag;
+ int pic_list_wait_alloc_done_flag;
+ unsigned char index;
+ spinlock_t front_back_lock;
+ spinlock_t buffer_lock;
+ struct device *cma_dev;
+ struct platform_device *platform_dev;
+ void (*vdec_cb)(struct vdec_s *, void *, int);
+ void *vdec_cb_arg;
+ struct vframe_chunk_s *chunk;
+ int dec_result;
+ struct work_struct work;
+ u32 start_shift_bytes;
+
+ struct BuffInfo_s work_space_buf_store;
+ unsigned long buf_start;
+ u32 buf_size;
+ u32 cma_alloc_count;
+ unsigned long cma_alloc_addr;
+ uint8_t eos;
+ unsigned long int start_process_time;
+ unsigned last_lcu_idx;
+ int decode_timeout_count;
+ unsigned timeout_num;
+
+ int double_write_mode;
+
+ unsigned char m_ins_flag;
+ char *provider_name;
+ int frame_count;
+ u32 stat;
+ struct timer_list timer;
+ u32 frame_dur;
+ u32 frame_ar;
+ u32 vavs3_ratio;
+ int fatal_error;
+ uint8_t init_flag;
+ uint8_t first_sc_checked;
+ uint8_t process_busy;
+#define PROC_STATE_INIT 0
+#define PROC_STATE_HEAD_DONE 1
+#define PROC_STATE_DECODING 2
+#define PROC_STATE_HEAD_AGAIN 3
+#define PROC_STATE_DECODE_AGAIN 4
+#define PROC_STATE_TEST1 5
+ uint8_t process_state;
+ u32 ucode_pause_pos;
+
+ int show_frame_num;
+#ifndef AVS3_10B_MMU
+ struct buff_s mc_buf_spec;
+#endif
+ struct dec_sysinfo vavs3_amstream_dec_info;
+ void *rpm_addr;
+ void *lmem_addr;
+ dma_addr_t rpm_phy_addr;
+ dma_addr_t lmem_phy_addr;
+ unsigned short *lmem_ptr;
+ unsigned short *debug_ptr;
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+ void *ucode_log_addr;
+ dma_addr_t ucode_log_phy_addr;
+#endif
+
+#ifdef AVS3_10B_MMU
+ bool mmu_enable;
+
+ u32 cuva_size;
+ void *cuva_addr;
+ dma_addr_t cuva_phy_addr;
+
+ void *frame_mmu_map_addr;
+ dma_addr_t frame_mmu_map_phy_addr;
+#endif
+#ifdef AVS3_10B_MMU_DW
+ bool dw_mmu_enable;
+ void *dw_mmu_box;
+ void *dw_frame_mmu_map_addr;
+ dma_addr_t dw_frame_mmu_map_phy_addr;
+#endif
+ unsigned int use_cma_flag;
+
+ DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
+ struct vframe_s vfpool[VF_POOL_SIZE];
+ u32 vf_pre_count;
+ u32 vf_get_count;
+ u32 vf_put_count;
+ int buf_num;
+ unsigned int losless_comp_body_size;
+
+ u32 video_signal_type;
+ u32 video_ori_signal_type;
+
+ int pts_mode;
+ int last_lookup_pts;
+ int last_pts;
+ u64 last_lookup_pts_us64;
+ u64 last_pts_us64;
+ u64 shift_byte_count;
+ u32 shift_byte_count_lo;
+ u32 shift_byte_count_hi;
+ int pts_mode_switching_count;
+ int pts_mode_recovery_count;
+
+ bool get_frame_dur;
+ u32 saved_resolution;
+
+ /**/
+ int refresh_frame_flags;
+ uint8_t hold_ref_buf;
+ struct BuffInfo_s *work_space_buf;
+#ifndef AVS3_10B_MMU
+ struct buff_s *mc_buf;
+#endif
+ unsigned int frame_width;
+ unsigned int frame_height;
+
+ unsigned short *rpm_ptr;
+ int init_pic_w;
+ int init_pic_h;
+
+ int slice_type;
+
+ int decode_idx;
+ int slice_idx;
+ uint8_t wait_buf;
+ uint8_t error_flag;
+ unsigned int bufmgr_error_count;
+
+ /* bit 0, for decoding; bit 1, for displaying */
+ uint8_t ignore_bufmgr_error;
+ uint8_t skip_PB_before_I;
+ int PB_skip_mode;
+ int PB_skip_count_after_decoding;
+ /*hw*/
+
+ /**/
+ struct vdec_info *gvs;
+
+ unsigned int dec_status;
+ u32 last_put_idx;
+ int new_frame_displayed;
+ void *mmu_box;
+ void *bmmu_box;
+ struct vframe_master_display_colour_s vf_dp;
+ struct firmware_s *fw;
+#ifdef AVS3_10B_MMU
+ int cur_fb_idx_mmu;
+#endif
+ struct avs3_decoder avs3_dec;
+ int32_t m_filterCoeffSym[16][9];
+ int32_t m_varIndTab[NO_VAR_BINS];
+
+ struct vframe_s vframe_dummy;
+ /* start_decoding_flag,
+ bit 0, SEQ ready
+ bit 1, I ready
+ */
+ unsigned char start_decoding_flag;
+ uint32_t mpred_abv_start_addr;
+ uint32_t mpred_abv_start_addr_bak;
+ u8 next_again_flag;
+ u32 pre_parser_wr_ptr;
+ int need_cache_size;
+ u64 sc_start_time;
+#ifdef I_ONLY_SUPPORT
+ u32 i_only;
+#endif
+ int frameinfo_enable;
+ u32 dynamic_buf_margin;
+ int sidebind_type;
+ int sidebind_channel_id;
+ u32 endian;
+ dma_addr_t rdma_phy_adr;
+ unsigned *rdma_adr;
+ int hdr_flag;
+
+ ulong rpm_mem_handle;
+ ulong lmem_phy_handle;
+ ulong frame_mmu_map_handle;
+ ulong frame_mmu_map_handle_1;
+ ulong frame_dw_mmu_map_handle;
+ ulong frame_dw_mmu_map_handle_1;
+ ulong ucode_log_handle;
+ ulong rdma_mem_handle;
+ ulong cuva_handle;
+#ifdef NEW_FB_CODE
+ u32 front_back_mode;
+ int fb_ifbuf_num;
+ //int pic_wr_count;
+ //int pic_rd_count;
+ //struct PIC_s *decoded_PIC[MAX_REF_PIC_NUM];
+ //u32 flush_count;
+
+ /*init_fb_bufstate() for linux APIs*/
+ struct work_struct work_back;
+ struct work_struct timeout_work_back;
+
+ void *frame_mmu_map_addr_1;
+ dma_addr_t frame_mmu_map_phy_addr_1;
+ void *mmu_box_1;
+
+ void *dw_mmu_box_1;
+ void *dw_frame_mmu_map_addr_1;
+ dma_addr_t dw_frame_mmu_map_phy_addr_1;
+
+ void *mmu_box_fb;
+ void *fb_buf_mmu0_addr;
+ void *fb_buf_mmu1_addr;
+ /**/
+ void (*vdec_back_cb)(struct vdec_s *, void *, int);
+ void *vdec_back_cb_arg;
+ struct firmware_s *fw_back;
+ struct timer_list timer_back;
+ unsigned long int start_process_time_back;
+ unsigned int decode_timeout_count_back;
+ unsigned int timeout_num_back;
+
+ int dec_back_result;
+ u32 dec_status_back;
+ struct mutex fb_mutex;
+ u32 mmu_fb_4k_number;
+#endif
+ uint32_t ASSIST_MBOX0_IRQ_REG;
+ uint32_t ASSIST_MBOX0_CLR_REG;
+ uint32_t ASSIST_MBOX0_MASK;
+ uint32_t backend_ASSIST_MBOX0_IRQ_REG;
+ uint32_t backend_ASSIST_MBOX0_CLR_REG;
+ uint32_t backend_ASSIST_MBOX0_MASK;
+
+ unsigned char print_buf[1024*16+16];
+ int print_buf_len;
+ struct trace_decoder_name trace;
+ int has_i_frame;
+ struct mutex slice_header_lock;
+#ifdef OW_TRIPLE_WRITE
+ int triple_write_mode;
+#endif
+ u32 last_monitor_data;
+};
+
+static int compute_losless_comp_body_size(
+ struct AVS3Decoder_s *dec, int width, int height,
+ uint8_t is_bit_depth_10);
+
+static int avs3_mmu_page_num(struct AVS3Decoder_s *dec,
+ int pic_width, int pic_height, int is_bit_depth_10);
+
+static void avs3_work_implement(struct AVS3Decoder_s *dec);
+
+
+#undef pr_info
+#define pr_info printk
+int avs3_debug(struct AVS3Decoder_s *dec,
+ int flag, const char *fmt, ...)
+{
+#define HEVC_PRINT_BUF 512
+ unsigned char buf[HEVC_PRINT_BUF];
+ int len = 0;
+ if (dec && dec->print_buf_len>0) {
+ dec->print_buf_len = 0;
+ pr_info("%s", dec->print_buf);
+ }
+ if (dec == NULL ||
+ (flag == 0) ||
+ ((debug_mask &
+ (1 << dec->index))
+ && (debug & flag))) {
+ va_list args;
+
+ va_start(args, fmt);
+ if (dec)
+ len = sprintf(buf, "[%d]", dec->index);
+
+#ifdef DEBUG_AMRISC
+ if (dec && dec->front_back_mode == 1)
+ len += sprintf(buf+len, "<%x,%x,%x>", READ_VREG(HEVC_ASSIST_SCRATCH_0), READ_VREG(HEVC_MPC_E), READ_VREG(HEVC_MPC_E_DBE));
+ else
+ len += sprintf(buf+len, "<%x,%x>", READ_VREG(HEVC_ASSIST_SCRATCH_0), READ_VREG(HEVC_MPC_E));
+#endif
+ vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+ //pr_debug("%s", buf);
+ pr_info("%s", buf);
+ va_end(args);
+ }
+ return 0;
+}
+
+static void avs3_print_flush(struct AVS3Decoder_s *dec)
+{
+ if (dec->print_buf_len>0) {
+ dec->print_buf_len = 0;
+ pr_info("%s", dec->print_buf);
+ }
+}
+
+static int avs3_print_cont(struct AVS3Decoder_s *dec,
+ int flag, const char *fmt, ...)
+{
+ //unsigned char buf[HEVC_PRINT_BUF];
+ //int len = 0;
+ if (dec == NULL ||
+ (flag == 0) ||
+ ((debug_mask &
+ (1 << dec->index))
+ && (debug & flag))) {
+ va_list args;
+
+ va_start(args, fmt);
+#if 0
+ vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+ pr_info("%s", buf);
+#else
+ if (dec->print_buf_len<1024*16)
+ dec->print_buf_len += vsnprintf(dec->print_buf+dec->print_buf_len,
+ 1024*16-dec->print_buf_len, fmt, args);
+ else
+ pr_info("print_buf is full\n");
+#endif
+ va_end(args);
+ }
+ return 0;
+}
+
+#define PROB_SIZE (496 * 2 * 4)
+#define PROB_BUF_SIZE (0x5000)
+#define COUNT_BUF_SIZE (0x300 * 4 * 4)
+/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/
+#define MAX_FRAME_4K_NUM 0x1200
+#define MAX_FRAME_8K_NUM 0x4800
+#define MAX_SIZE_4K (4096 * 2304)
+#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
+#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
+
+/*
+error handling
+*/
+/*error_handle_policy:
+bit 0: search seq again if buffer mgr error occur
+ (buffer mgr error count need big than
+ re_search_seq_threshold)
+bit 1: 1: display from I picture; 0: display from any correct pic;
+bit 2: 1: not output error frame; 0: output error frame;
+bit 3: 1: same poc insert dpb; 0: same poc don't insert dpb;
+
+*/
+
+static u32 error_handle_policy = 5;
+
+int avs3_get_error_policy(void)
+{
+ return error_handle_policy;
+}
+
+static int get_frame_mmu_map_size(void)
+{
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ return (MAX_FRAME_8K_NUM * 4);
+
+ return (MAX_FRAME_4K_NUM * 4);
+}
+
+static int get_compress_header_size(struct AVS3Decoder_s *dec)
+{
+ int32_t pic_width = dec->avs3_dec.img.width;
+ int32_t pic_height = dec->avs3_dec.img.height;
+
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ (IS_8K_SIZE(pic_width, pic_height)))
+ return MMU_COMPRESS_HEADER_SIZE_8K;
+ else if (IS_4K_SIZE(pic_width, pic_height))
+ return MMU_COMPRESS_HEADER_SIZE_4K;
+ return MMU_COMPRESS_HEADER_SIZE_1080P;
+}
+
+static void reset_process_time(struct AVS3Decoder_s *dec)
+{
+ if (dec->start_process_time) {
+ //unsigned process_time =
+ // 1000 * (jiffies - dec->start_process_time) / HZ;
+ dec->start_process_time = 0;
+ //if (process_time > max_process_time[dec->index])
+ // max_process_time[dec->index] = process_time;
+ }
+}
+
+static void start_process_time(struct AVS3Decoder_s *dec)
+{
+ dec->start_process_time = jiffies;
+ if ((dec->start_process_time != 0) &&
+ !(error_handle_policy & 0x4) &&
+ (decode_timeout_val > 0)) {
+ dec->decode_timeout_count = fast_timer_check_count;
+ } else
+ dec->decode_timeout_count = 0;
+ dec->last_lcu_idx = 0;
+}
+
+static void update_decoded_pic(struct AVS3Decoder_s *dec);
+
+static void timeout_process(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *cur_pic = avs3_dec->cur_pic;
+ dec->timeout_num++;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ amhevc_stop_f();
+ } else
+#endif
+ amhevc_stop();
+ avs3_print(dec,
+ 0, "%s decoder timeout\n", __func__);
+ if (cur_pic)
+ cur_pic->error_mark = 1;
+ dec->dec_result = DEC_RESULT_DONE;
+ update_decoded_pic(dec);
+ reset_process_time(dec);
+ vdec_schedule_work(&dec->work);
+}
+
+#ifdef NEW_FB_CODE
+static void reset_process_time_back(struct AVS3Decoder_s *dec)
+{
+ if (dec->start_process_time_back) {
+ unsigned int process_time =
+ 1000 * (jiffies - dec->start_process_time_back) / HZ;
+ dec->start_process_time_back = 0;
+ if (process_time > max_process_time_back[dec->index])
+ max_process_time_back[dec->index] = process_time;
+ }
+}
+
+static void start_process_time_back(struct AVS3Decoder_s *dec)
+{
+ dec->start_process_time_back = jiffies;
+ dec->decode_timeout_count_back = fast_timer_check_count;
+}
+
+/*
+static void restart_process_time_back(struct AVS3Decoder_s *dec)
+{
+ dec->start_process_time_back = jiffies;
+ dec->decode_timeout_count_back = 2;
+}
+*/
+static void timeout_process_back(struct AVS3Decoder_s *dec)
+{
+ /*
+ * In this very timeout point,the vh265_work arrives,
+ * or in some cases the system become slow, then come
+ * this second timeout. In both cases we return.
+ */
+ if (work_pending(&dec->work_back) ||
+ work_busy(&dec->work_back) ||
+ work_busy(&dec->timeout_work_back) ||
+ work_pending(&dec->timeout_work_back)) {
+ pr_err("%s avs3[%d] work back pending, do nothing.\n",__func__, dec->index);
+ return;
+ }
+
+ /* disable irq before handle timeout */
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 0);
+
+ avs3_print(dec,
+ 0, "%s decoder timeout\n", __func__);
+ dec->timeout_num_back++;
+ reset_process_time_back(dec);
+
+ if (work_pending(&dec->work_back))
+ return;
+ dec->dec_back_result = DEC_BACK_RESULT_TIMEOUT;
+ vdec_schedule_work(&dec->timeout_work_back);
+}
+#endif
+
+static inline void decoder_trace(char *name, int value, int flag)
+{
+ if (trace_debug_mode & flag)
+ ATRACE_COUNTER(name, value);
+}
+
+static u32 get_valid_double_write_mode(struct AVS3Decoder_s *dec)
+{
+ u32 dw_mode;
+
+ dw_mode = (dec->m_ins_flag &&
+ ((double_write_mode & 0x80000000) == 0)) ?
+ dec->double_write_mode :
+ (double_write_mode & 0x7fffffff);
+ if (dw_mode & 0x20) {
+ if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
+ && ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3))
+ dw_mode = 0;
+ }
+
+ return dw_mode;
+}
+
+static int get_double_write_mode(struct AVS3Decoder_s *dec)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(dec) & 0xffff;
+ int w = dec->avs3_dec.img.width;
+ int h = dec->avs3_dec.img.height;
+ u32 dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 720)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ dw = valid_dw_mode;
+ break;
+ }
+ return dw;
+}
+
+#ifdef OW_TRIPLE_WRITE
+static int get_triple_write_mode(struct AVS3Decoder_s *dec)
+{
+ int tw = ((triple_write_mode & 0x80000000) == 0) ?
+ dec->triple_write_mode : (triple_write_mode & 0x7fffffff);
+
+ return (tw & 0xffff);
+}
+#endif
+
+#ifdef P010_ENABLE
+static __inline__ bool is_dw_p010(struct AVS3Decoder_s *dec)
+{
+ int a = (double_write_mode & 0x80000000) ? (double_write_mode & 0x10000) : 0;
+
+ return ((dec->double_write_mode & 0x10000) || a);
+}
+
+static __inline__ bool is_tw_p010(struct AVS3Decoder_s *dec)
+{
+ int a = (triple_write_mode & 0x80000000) ? (triple_write_mode & 0x10000) : 0;
+
+ return ((dec->triple_write_mode & 0x10000) || a);
+}
+
+#else
+static __inline__ bool is_dw_p010(struct AVS3Decoder_s *dec)
+{
+ return 0;
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+ return 0;
+}
+#endif
+
+/* for double write buf alloc */
+static int get_double_write_mode_init(struct AVS3Decoder_s *dec)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(dec);
+ u32 dw;
+ int w = dec->init_pic_w;
+ int h = dec->init_pic_h;
+
+ dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 720)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ dw = valid_dw_mode;
+ break;
+ }
+ return dw;
+}
+
+//#define MAX_4K_NUM 0x1200
+#ifdef AVS3_10B_MMU
+int avs3_alloc_mmu(
+ struct AVS3Decoder_s *dec,
+ int cur_buf_idx,
+ int pic_width,
+ int pic_height,
+ unsigned short bit_depth,
+ unsigned int *mmu_index_adr)
+{
+ int cur_mmu_4k_number;
+ int bit_depth_10 = (bit_depth == AVS3_BITS_10);
+ int ret;
+
+ cur_mmu_4k_number = avs3_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+ if (cur_mmu_4k_number < 0) {
+ pr_err("%s: cur_mmu_4k_number 0x%x is error width %d height %d\n",
+ __func__, cur_mmu_4k_number, pic_width, pic_height);
+ return -1;
+ }
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+ __func__, cur_buf_idx, cur_mmu_4k_number);
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+ ret = decoder_mmu_box_alloc_idx(
+ dec->mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+
+ return ret;
+}
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+int avs3_alloc_dw_mmu(
+ struct AVS3Decoder_s *dec,
+ int cur_buf_idx,
+ int pic_width,
+ int pic_height,
+ unsigned short bit_depth,
+ unsigned int *mmu_index_adr)
+{
+ int cur_mmu_4k_number;
+ int bit_depth_10 = (bit_depth == AVS3_BITS_10);
+ int ret;
+
+ cur_mmu_4k_number = avs3_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+ if (cur_mmu_4k_number < 0) {
+ return -1;
+ }
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+ __func__, cur_buf_idx, cur_mmu_4k_number);
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+ ret = decoder_mmu_box_alloc_idx(
+ dec->dw_mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+
+ return ret;
+}
+#endif
+
+static int get_free_buf_count(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int ii;
+ int count = 0;
+ for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+ if (avs3_dec->pic_pool[ii].buf_cfg.used == 0)
+ count++;
+ }
+ return count;
+}
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+static int get_vf_ref_only_buf_count(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int ii;
+ int count = 0;
+ for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+ if (avs3_dec->pic_pool[ii].buf_cfg.used > 0 &&
+ avs3_dec->pic_pool[ii].buf_cfg.vf_ref > 0 &&
+#ifdef NEW_FRONT_BACK_CODE
+ avs3_dec->pic_pool[ii].buf_cfg.backend_ref == 0 && /*?? why need it in case0763,
+ used is supposed to be 1 if backend_ref is not 0*/
+#endif
+ avs3_dec->pic_pool[ii].is_ref == 0 &&
+ avs3_dec->pic_pool[ii].need_for_out == 0
+ ) {
+ count++;
+ }
+ }
+ return count;
+}
+
+static int get_used_buf_count(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int ii;
+ int count = 0;
+ for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+ if (avs3_dec->pic_pool[ii].buf_cfg.used > 0)
+ count++;
+ }
+ return count;
+}
+#endif
+int avs3_dec_init(struct AVS3Decoder_s *dec, struct BuffInfo_s *buf_spec_i,
+ struct buff_s *mc_buf_i) {
+
+ dec->frame_count = 0;
+#ifdef AVS3_10B_MMU
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+#endif
+
+ /* private init */
+ dec->work_space_buf = buf_spec_i;
+#ifndef AVS3_10B_MMU
+ dec->mc_buf = mc_buf_i;
+#endif
+ dec->rpm_addr = NULL;
+ dec->lmem_addr = NULL;
+
+ dec->use_cma_flag = 0;
+ dec->decode_idx = 0;
+ dec->slice_idx = 0;
+ /*int m_uiMaxCUWidth = 1<<7;*/
+ /*int m_uiMaxCUHeight = 1<<7;*/
+ dec->wait_buf = 0;
+ dec->error_flag = 0;
+ dec->skip_PB_before_I = 0;
+
+ dec->pts_mode = PTS_NORMAL;
+ dec->last_pts = 0;
+ dec->last_lookup_pts = 0;
+ dec->last_pts_us64 = 0;
+ dec->last_lookup_pts_us64 = 0;
+ dec->shift_byte_count = 0;
+ dec->shift_byte_count_lo = 0;
+ dec->shift_byte_count_hi = 0;
+ dec->pts_mode_switching_count = 0;
+ dec->pts_mode_recovery_count = 0;
+
+ dec->buf_num = 0;
+ dec->has_i_frame = 0;
+ dec->bufmgr_error_count = 0;
+#ifdef NEW_FB_CODE
+ dec->start_process_time_back = 0;
+ dec->decode_timeout_count_back = 0;
+ dec->timeout_num_back = 0;
+ dec->decode_timeout_count_back = 0;
+#endif
+ return 0;
+}
+
+#define HEVC_CM_BODY_START_ADDR 0x3626
+#define HEVC_CM_BODY_LENGTH 0x3627
+#define HEVC_CM_HEADER_LENGTH 0x3629
+#define HEVC_CM_HEADER_OFFSET 0x362b
+
+#define LOSLESS_COMPRESS_MODE
+
+/*#define DECOMP_HEADR_SURGENT*/
+
+static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
+static u32 enable_mem_saving = 1;
+static u32 force_w_h;
+
+static u32 force_fps;
+
+const u32 avs3_version = 201602101;
+static u32 radr;
+static u32 rval;
+static u32 pop_shorts;
+ /*dbg_cmd[3:0]:
+ 2, dump phy address of (dbg_cmd[31:4]<<4)
+ */
+static u32 dbg_cmd;
+static u32 dbg_skip_decode_index;
+/*
+ * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
+ * bit 8~23, for HEVC_SAO_CTRL1 endian config
+ */
+static u32 endian;
+#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
+#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
+#define HEVC_CONFIG_P010_LE (0x77007)
+
+#ifdef ERROR_HANDLE_DEBUG
+static u32 dbg_nal_skip_flag;
+ /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
+static u32 dbg_nal_skip_count;
+#endif
+/*for debug*/
+static u32 decode_pic_begin;
+static uint slice_parse_begin;
+static u32 step;
+#ifdef MIX_STREAM_SUPPORT
+static u32 buf_alloc_width = 4096;
+static u32 buf_alloc_height = 2304;
+
+static u32 dynamic_buf_num_margin;
+#else
+static u32 buf_alloc_width;
+static u32 buf_alloc_height;
+static u32 dynamic_buf_num_margin = 7;
+#endif
+#ifdef CONSTRAIN_MAX_BUF_NUM
+static u32 run_ready_max_vf_only_num;
+static u32 run_ready_display_q_num;
+ /*0: not check
+ 0xff: avs3_dec.ref_maxbuffer
+ */
+static u32 run_ready_max_buf_num = 0xff;
+#endif
+static u32 buf_alloc_depth = 10;
+static u32 buf_alloc_size;
+
+/*
+bit[0]: 0,
+ bit[1]: 0, always release cma buffer when stop
+ bit[1]: 1, never release cma buffer when stop
+bit[0]: 1, when stop, release cma buffer if blackout is 1;
+do not release cma buffer is blackout is not 1
+
+bit[2]: 0, when start decoding, check current displayed buffer
+ (only for buffer decoded by vp9) if blackout is 0
+ 1, do not check current displayed buffer
+
+bit[3]: 1, if blackout is not 1, do not release current
+ displayed cma buffer always.
+*/
+/* set to 1 for fast play;
+ set to 8 for other case of "keep last frame"
+*/
+static u32 buffer_mode = 1;
+/* buffer_mode_dbg: debug only*/
+static u32 buffer_mode_dbg = 0xffff0000;
+/**/
+
+/*
+bit 0, 1: only display I picture;
+bit 1, 1: only decode I picture;
+*/
+static u32 i_only_flag;
+
+static u32 max_decoding_time;
+
+/*
+re_search_seq_threshold:
+ bit 7~0: buffer mgr error research seq count
+ bit 15~8: frame count threshold
+*/
+static u32 re_search_seq_threshold = 0x800; /*0x8;*/
+/*static u32 parser_sei_enable = 1;*/
+
+static u32 max_buf_num = (MAX_NUM_REF_PICS);
+
+static u32 run_ready_min_buf_num = 1;
+
+static DEFINE_MUTEX(vavs3_mutex);
+
+#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
+#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
+#define AVS3_ALF_SWAP_BUFFER HEVC_ASSIST_SCRATCH_2
+#define HEVC_RCS_BUFFER HEVC_ASSIST_SCRATCH_3
+//#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
+//#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
+#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
+#ifdef AVS3_10B_MMU
+#define AVS3_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
+#else
+#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
+#endif
+#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
+/*
+#define VP9_PROB_SWAP_BUFFER HEVC_ASSIST_SCRATCH_9
+#define VP9_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
+#define VP9_SEG_MAP_BUFFER HEVC_ASSIST_SCRATCH_B
+*/
+//#define AVS3_CUVA_ADR HEVC_ASSIST_SCRATCH_A
+//#define AVS3_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_B
+/*same as simulation*/
+#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_A
+#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_B
+/**/
+
+#define AVS3_SBAC_TOP_BUFFER HEVC_ASSIST_SCRATCH_C
+#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
+#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
+#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
+
+#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_9
+#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
+#define HEVC_EFFICIENCY_MODE HEVC_ASSIST_SCRATCH_L
+/*!!!*/
+#define AVS3_CUVA_ADR HEVC_ASSIST_SCRATCH_M
+#define AVS3_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_N
+#define HEVC_DECODE_PIC_BEGIN HEVC_ASSIST_SCRATCH_M
+#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
+#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+#define HEVC_DBG_LOG_ADR HEVC_ASSIST_SCRATCH_5
+#ifdef DEBUG_CMD
+#define HEVC_D_ADR HEVC_ASSIST_SCRATCH_4
+#endif
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE HEVC_ASSIST_SCRATCH_Z
+#define HEVC_EFFICIENCY_MODE_BACK HEVC_ASSIST_SCRATCH_10
+#endif
+/*
+ucode parser/search control
+bit 0: 0, header auto parse; 1, header manual parse
+bit 1: 0, auto skip for noneseamless stream; 1, no skip
+bit [3:2]: valid when bit1 == 0;
+0, auto skip nal before first vps/sps/pps/idr;
+1, auto skip nal before first vps/sps/pps
+2, auto skip nal before first vps/sps/pps,
+ and not decode until the first I slice (with slice address of 0)
+
+3, auto skip before first I slice (nal_type >=16 && nal_type <= 21)
+bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
+bit [16]: for NAL_UNIT_EOS when bit0 is 0:
+ 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
+bit [17]: for NAL_SEI when bit0 is 0:
+ 0, do not parse SEI in ucode; 1, parse SEI in ucode
+bit [31:20]: used by ucode for debug purpose
+*/
+#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
+ /*DECODE_MODE: set before start decoder
+ bit 7~0: decode mode
+ bit 23~16: start_decoding_flag
+ bit [0] - SEQ_ready
+ bit [2:1] - I Picture Count
+ bit 31~24: chip feature
+ */
+#define DECODE_MODE HEVC_ASSIST_SCRATCH_J
+#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
+ /*read only*/
+#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE HEVC_ASSIST_SCRATCH_Z
+
+#define EE_ASSIST_MBOX0_IRQ_REG 0x3f70
+#define EE_ASSIST_MBOX0_CLR_REG 0x3f71
+#define EE_ASSIST_MBOX0_MASK 0x3f72
+#endif
+
+#define RPM_BUF_SIZE (0x600 * 2)
+#define LMEM_BUF_SIZE (0x600 * 2)
+
+ /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
+#define VBH_BUF_SIZE_1080P 0x3000
+#define VBH_BUF_SIZE_4K 0x5000
+#define VBH_BUF_SIZE_8K 0xa000
+#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
+ /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
+ HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
+#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
+#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
+#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
+#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
+
+/* necessary 4K page size align for t7/t3 decoder and after */
+#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
+
+#define WORK_BUF_SPEC_NUM 6
+static struct BuffInfo_s amvavs3_workbuff_spec[WORK_BUF_SPEC_NUM] = {
+ {
+ /* 8M bytes */
+ .max_width = 1920,
+ .max_height = 1088,
+ .ipp = {
+ /* IPP work space calculation :
+ 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+ .buf_size = 0x1e00,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x1e00,
+ },
+#endif
+ .sao_abv = {
+ .buf_size = 0,
+ },
+ .sao_vb = {
+ .buf_size = 0,
+ },
+ .short_term_rps = {
+ /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800) */
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
+ total 0x0400 bytes */
+ .buf_size = 0x400,
+ },
+ .sps = {
+ /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes*/
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
+ total 0x2000 bytes*/
+ .buf_size = 0x2000,
+ },
+ .sbac_top = {
+ // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+ .buf_size = 0x2000,
+ },
+ .sao_up = {
+ /* SAO UP STORE AREA - Max 640(10240/16) LCU,
+ each has 16 bytes total 0x2800 bytes */
+ .buf_size = 0,
+ },
+ .swap_buf = {
+ /* 256cyclex64bit = 2K bytes 0x800
+ (only 144 cycles valid) */
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+ .scalelut = {
+ /* support up to 32 SCALELUT 1024x32 =
+ 32Kbytes (0x8000) */
+ .buf_size = 0,
+ },
+ .dblk_para = {
+ /* DBLK -> Max 256(4096/16) LCU,
+ each para 1024bytes(total:0x40000),
+ data 1024bytes(total:0x40000)*/
+ .buf_size = 0x3d00, //0x3c80,
+ },
+ .dblk_data = {
+ .buf_size = 0x62800,
+ },
+ .dblk_data2 = {
+ .buf_size = 0x62800,
+ },
+#ifdef AVS3_10B_MMU
+ .mmu_vbh = {
+ .buf_size = VBH_BUF_SIZE_1080P, /*2*16*(more than 2304)/4, 4K*/
+ },
+#if 0
+ .cm_header = {
+ /*add one for keeper.*/
+ .buf_size = MMU_COMPRESS_HEADER_SIZE *
+ (FRAME_BUFFERS + 1),
+ /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
+ },
+#endif
+#endif
+#ifdef AVS3_10B_MMU_DW
+ .mmu_vbh_dw = {
+ .buf_size = DW_VBH_BUF_SIZE_1080P, //2*16*2304/4, 4K
+ },
+#if 0
+ .cm_header_dw = {
+ .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+ },
+#endif
+#endif
+ .mpred_above = {
+ .buf_size = 0x1e00, /* 2 * size of hevc*/
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {/* 1080p, 0x40000 per buffer */
+ .buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x600 * 2,
+ }
+ },
+ {
+ .max_width = 4096,
+ .max_height = 2304,
+ .ipp = {
+ /* IPP work space calculation :
+ 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+ .buf_size = 0x4000,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000,
+ },
+#endif
+ .sao_abv = {
+ .buf_size = 0,
+ },
+ .sao_vb = {
+ .buf_size = 0,
+ },
+ .short_term_rps = {
+ /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800) */
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+ total 0x0400 bytes */
+ // RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+ .buf_size = 0x1000,
+ },
+ .sps = {
+ /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes */
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
+ total 0x2000 bytes */
+ .buf_size = 0x2000,
+ },
+ .sbac_top = {
+ // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+ .buf_size = 0x2000,
+ },
+ .sao_up = {
+ /* SAO UP STORE AREA - Max 640(10240/16) LCU,
+ each has 16 bytes total 0x2800 bytes */
+ .buf_size = 0,
+ },
+ .swap_buf = {
+ /* 256cyclex64bit = 2K bytes 0x800
+ (only 144 cycles valid) */
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+ .scalelut = {
+ /* support up to 32 SCALELUT 1024x32 = 32Kbytes
+ (0x8000) */
+ .buf_size = 0,
+ },
+ .dblk_para = { .buf_size = 0x40000, },
+ .dblk_data = { .buf_size = 0x80000, },
+ .dblk_data2 = { .buf_size = 0x80000, },
+#ifdef AVS3_10B_MMU
+ .mmu_vbh = {
+ .buf_size = VBH_BUF_SIZE_4K,/*2*16*(more than 2304)/4, 4K*/
+ },
+#if 0
+ .cm_header = {
+ /*add one for keeper.*/
+ .buf_size = MMU_COMPRESS_HEADER_SIZE *
+ (FRAME_BUFFERS + 1),
+ /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
+ },
+#endif
+#endif
+#ifdef AVS3_10B_MMU_DW
+ .mmu_vbh_dw = {
+ .buf_size = DW_VBH_BUF_SIZE_4K, //2*16*2304/4, 4K
+ },
+#if 0
+ .cm_header_dw = {
+ .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+ },
+#endif
+#endif
+ .mpred_above = {
+ .buf_size = 0x8000, /* 2 * size of hevc*/
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {
+ /* .buf_size = 0x100000*16,
+ //4k2k , 0x100000 per buffer */
+ /* 4096x2304 , 0x120000 per buffer */
+ .buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x600 * 2,
+ }
+ },
+ {
+ .max_width = 4096 * 2,
+ .max_height = 2304 * 2,
+ .ipp = {
+ /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
+ round to 16k*/
+ .buf_size = 0x4000 * 2,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000 * 2,
+ },
+#endif
+#ifdef USE_SIM_BUFSPEC
+ .sao_abv = {
+ .buf_size = 0x30000*2,
+ },
+ .sao_vb = {
+ .buf_size = 0x30000*2,
+ },
+
+#else
+ .sao_abv = {
+ .buf_size = 0,
+ },
+ .sao_vb = {
+ .buf_size = 0,
+ },
+#endif
+ .short_term_rps = {
+ /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800)*/
+ .buf_size = 0x800,
+ },
+ .rcs = {
+ /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+ total 0x0400 bytes*/
+ // RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+ .buf_size = 0x1000,
+ },
+ .sps = {
+ /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes*/
+ .buf_size = 0x800,
+ },
+ .pps = {
+ /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
+ 0x2000 bytes*/
+ .buf_size = 0x2000,
+ },
+ .sbac_top = {
+ // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+ .buf_size = 0x2000 * 2,
+ },
+#ifdef USE_SIM_BUFSPEC
+ .sao_up = {
+ // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .buf_size = 0x2800*2,
+ },
+#else
+ .sao_up = {
+ /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
+ total 0x2800 bytes*/
+ .buf_size = 0,
+ },
+#endif
+ .swap_buf = {
+ /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
+ .buf_size = 0x800,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800,
+ },
+#ifdef USE_SIM_BUFSPEC
+ .scalelut = {
+ // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .buf_size = 0x8000*2,
+ },
+#else
+ .scalelut = {
+ /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
+ .buf_size = 0,
+ },
+#endif
+ .dblk_para = { .buf_size = 0x40000*2, },
+ .dblk_data = { .buf_size = 0x80000*2, },
+ .dblk_data2 = { .buf_size = 0x80000*2, },
+#ifdef AVS3_10B_MMU
+ .mmu_vbh = {
+ .buf_size = VBH_BUF_SIZE_8K, /*2*16*2304/4, 4K*/
+ },
+#if 0
+ .cm_header = {
+ /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
+ .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
+ },
+#endif
+#endif
+#ifdef AVS3_10B_MMU_DW
+ .mmu_vbh_dw = {
+ .buf_size = DW_VBH_BUF_SIZE_8K, //2*16*2304/4, 4K
+ },
+#if 0
+ .cm_header_dw = {
+ .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+ },
+#endif
+#endif
+ .mpred_above = {
+ .buf_size = 0x8000*2,
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {
+ /*4k2k , 0x100000 per buffer*/
+ .buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x600 * 2,
+ }
+ },
+
+ //large buf size for debugging only
+ {
+ .max_width = 4096 * 2,
+ .max_height = 2304 * 2,
+ .ipp = {
+ /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
+ round to 16k*/
+ .buf_size = 0x4000 * 4,
+ },
+#ifdef NEW_FRONT_BACK_CODE
+ .ipp1 = {
+ // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+ .buf_size = 0x4000 * 4,
+ },
+#endif
+#ifdef USE_SIM_BUFSPEC
+ .sao_abv = {
+ .buf_size = 0x30000*4,
+ },
+ .sao_vb = {
+ .buf_size = 0x30000*4,
+ },
+#else
+ .sao_abv = {
+ .buf_size = 0,
+ },
+ .sao_vb = {
+ .buf_size = 0,
+ },
+#endif
+ .short_term_rps = {
+ /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+ total 64x16x2 = 2048 bytes (0x800)*/
+ .buf_size = 0x800*4
+ },
+ .rcs = {
+ /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+ total 0x0400 bytes*/
+ // RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+ .buf_size = 0x1000*4,
+ },
+ .sps = {
+ /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+ total 0x0800 bytes*/
+ .buf_size = 0x800*4,
+ },
+ .pps = {
+ /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
+ 0x2000 bytes*/
+ .buf_size = 0x2000*2,
+ },
+ .sbac_top = {
+ // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+ .buf_size = 0x2000 * 4,
+ },
+#ifdef USE_SIM_BUFSPEC
+ .sao_up = {
+ // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+ .buf_size = 0x2800*4,
+ },
+#else
+ .sao_up = {
+ /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
+ total 0x2800 bytes*/
+ .buf_size = 0,
+ },
+#endif
+ .swap_buf = {
+ /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
+ .buf_size = 0x800*4,
+ },
+ .swap_buf2 = {
+ .buf_size = 0x800*4,
+ },
+#ifdef USE_SIM_BUFSPEC
+ .scalelut = {
+ // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+ .buf_size = 0x8000*2,
+ },
+#else
+ .scalelut = {
+ /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
+ .buf_size = 0,
+ },
+#endif
+ .dblk_para = { .buf_size = 0x40000*4, },
+ .dblk_data = { .buf_size = 0x80000*4, },
+ .dblk_data2 = { .buf_size = 0x80000*4, },
+#ifdef AVS3_10B_MMU
+ .mmu_vbh = {
+ .buf_size = VBH_BUF_SIZE_8K*2, /*2*16*2304/4, 4K*/
+ },
+#if 0
+ .cm_header = {
+ /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
+ .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
+ },
+#endif
+#endif
+#ifdef AVS3_10B_MMU_DW
+ .mmu_vbh_dw = {
+ .buf_size = DW_VBH_BUF_SIZE_8K*2, //2*16*2304/4, 4K
+ },
+#if 0
+ .cm_header_dw = {
+ .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+ },
+#endif
+#endif
+ .mpred_above = {
+ .buf_size = 0x8000*4,
+ },
+#ifdef MV_USE_FIXED_BUF
+ .mpred_mv = {
+ /*4k2k , 0x100000 per buffer*/
+ .buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS,
+ },
+#endif
+ .rpm = {
+ .buf_size = RPM_BUF_SIZE,
+ },
+ .lmem = {
+ .buf_size = 0x600 * 2,
+ }
+ }
+
+};
+
+#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
+#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
+
+static u32 get_mv_mem_unit(int lcu_size_log2)
+{
+ u32 mv_mem_unit;
+ //lcu_size_log2 == 6 ? 0x200 : lcu_size_log2 == 5 ? 0x80 : 0x20; //avs2
+ //mv_mem_unit = lcu_size_log2 == 7 ? 256 : lcu_size_log2 == 6 ? 64 : 16;
+ mv_mem_unit = lcu_size_log2 == 7 ? 512 : lcu_size_log2 == 6 ? 128 : 32;
+ return mv_mem_unit;
+}
+
+#ifndef MV_USE_FIXED_BUF
+
+static uint32_t get_mv_buf_size(struct AVS3Decoder_s *dec, int width, int height) {
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ uint32_t size;
+ if (mv_buf_dynamic_alloc == 1) {
+ int mv_mem_unit =
+ get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+ int32_t pic_width = avs3_dec->img.width;
+ int32_t pic_height = avs3_dec->img.height;
+ int32_t lcu_size = 1<<avs3_dec->lcu_size_log2;
+ int32_t pic_width_lcu = ( pic_width %lcu_size ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+ int32_t pic_height_lcu = ( pic_height %lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+ int32_t lcu_total =pic_width_lcu*pic_height_lcu;
+ int new_size = lcu_total * mv_mem_unit;
+ size = (new_size + 0xffff) & (~0xffff);
+
+ } else {
+ if (IS_8K_SIZE(width, height))
+ size = CO_MV_BUF_SIZE_8K;
+ else if (IS_4K_SIZE(width, height))
+ size = CO_MV_BUF_SIZE_4K;
+ else
+ size = CO_MV_BUF_SIZE_1080P;
+ }
+ return size;
+}
+#endif
+
+static void config_hevc_irq_num(struct AVS3Decoder_s *dec)
+{
+#ifdef NEW_FB_CODE
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ dec->ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = EE_ASSIST_MBOX0_MASK;
+ dec->backend_ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->backend_ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->backend_ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+ } else {
+ dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+ dec->backend_ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+ dec->backend_ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+ dec->backend_ASSIST_MBOX0_MASK = EE_ASSIST_MBOX0_MASK;
+ }
+#else
+ dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+ dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+ dec->ASSIST_MBOX0_MASK = HEVC_ASSIST_MBOX0_MASK;
+#endif
+}
+
+#ifdef NEW_FB_CODE
+#include "avs3_fb_hw.c"
+
+void pic_backend_ref_operation(struct AVS3Decoder_s *dec, avs3_frame_t *pic, bool add_flag)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_frame_t *ref_pic = NULL;
+ int i = 0;
+
+ mutex_lock(&dec->fb_mutex);
+ if (add_flag) {
+ pic->backend_ref = 1;
+ pic->back_done_mark = 0;
+ } else {
+ pic->backend_ref--;
+ if (pic->backend_ref < 0) {
+ pic->backend_ref = 0;
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:pic(%px) backend_ref error\n",
+ __func__, pic);
+ }
+ pic->back_done_mark = 1;
+ }
+
+ for (i = 0; i < pic->list0_num_refp; i++) {
+ ref_pic = &avs3_dec->pic_pool[pic->list0_index[i]].buf_cfg;
+ if (add_flag) {
+ ref_pic->backend_ref++;
+ } else {
+ ref_pic->backend_ref--;
+ if (ref_pic->backend_ref < 0) {
+ ref_pic->backend_ref = 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 ref_pic %d backend_ref error\n",
+ __func__, pic->list0_index[i]);
+ }
+ }
+ }
+
+ for (i = 0; i < pic->list1_num_refp; i++) {
+ ref_pic = &avs3_dec->pic_pool[pic->list1_index[i]].buf_cfg;
+ if (add_flag) {
+ ref_pic->backend_ref++;
+ } else {
+ ref_pic->backend_ref--;
+ if (ref_pic->backend_ref < 0) {
+ ref_pic->backend_ref = 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 ref_pic %d backend_ref error\n",
+ __func__, pic->list1_index[i]);
+ }
+ }
+ }
+
+ mutex_unlock(&dec->fb_mutex);
+}
+
+/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+static int front_decpic_done_update(struct AVS3Decoder_s *dec, uint8_t reset_flag)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+ int j;
+ if (debug & AVS3_DBG_PRINT_PIC_LIST) {
+ print_pic_pool(avs3_dec, "before inc backend_ref");
+
+ avs3_print_cont(dec, 0, "pic_cfg index %d, list0 index ", cur_pic->index);
+ for (j = 0; j < cur_pic->list0_num_refp; j++)
+ avs3_print_cont(dec, 0, "%d ", cur_pic->list0_index[j]);
+ avs3_print_cont(dec, 0, "list1 index ");
+ for (j = 0; j < cur_pic->list1_num_refp; j++)
+ avs3_print_cont(dec, 0, "%d ", cur_pic->list1_index[j]);
+ avs3_print_cont(dec, 0, "\n");
+ }
+
+ pic_backend_ref_operation(dec, cur_pic, 1);
+
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "after inc backend_ref");
+
+ if (dec->front_back_mode == 1) {
+ if (fbdebug_flag & 0x70000000) {
+ u8 cmd = (fbdebug_flag >> 28) & 0x7;
+ u32 dump_c = (fbdebug_flag >> 16) & 0xfff;
+ if ((cmd == 3) ||
+ (cmd == 1 && dump_c == avs3_dec->frontend_decoded_count) ||
+ (cmd == 2 && avs3_dec->frontend_decoded_count < dump_c))
+ dump_loop_buffer(dec, avs3_dec->frontend_decoded_count, cmd ==1 || cmd == 2);
+ }
+
+ if (fbdebug_flag & 0x4) {
+ copy_loopbufs_ptr(&avs3_dec->fr, &avs3_dec->init_fr);
+ print_loopbufs_ptr(dec, "fr", &avs3_dec->fr);
+ } else {
+ copy_loopbufs_ptr(&avs3_dec->p_fr, &avs3_dec->fr);
+ read_bufstate_front(avs3_dec);
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "update fr from loop buf register\n");
+
+ print_loopbufs_ptr2(dec, "fr", &avs3_dec->p_fr, &avs3_dec->fr);
+ }
+
+ WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 1);
+
+ //WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_DEC_IDLE);
+ } else {
+ if (reset_flag) /*not multi pictures in one packe*/
+ amhevc_stop();
+ }
+
+ avs3_dec->frontend_decoded_count++;
+ avs3_dec->next_be_decode_pic[avs3_dec->fb_wr_pos] = avs3_dec->cur_pic;
+
+ mutex_lock(&dec->fb_mutex);
+ avs3_dec->fb_wr_pos++;
+ if (avs3_dec->fb_wr_pos >= dec->fb_ifbuf_num)
+ avs3_dec->fb_wr_pos = 0;
+
+ if (avs3_dec->fb_wr_pos == avs3_dec->fb_rd_pos)
+ avs3_dec->wait_working_buf = 1;
+
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+ avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, avs3_dec->wait_working_buf);
+
+ mutex_unlock(&dec->fb_mutex);
+
+ return 0;
+}
+
+#endif
+
+/*Losless compression body buffer size 4K per 64x32 (jt)*/
+static int compute_losless_comp_body_size(struct AVS3Decoder_s *dec,
+ int width, int height,
+ uint8_t is_bit_depth_10)
+{
+ int width_x64;
+ int height_x32;
+ int bsize;
+ width_x64 = width + 63;
+ width_x64 >>= 6;
+ height_x32 = height + 31;
+ height_x32 >>= 5;
+ bsize = (is_bit_depth_10 ? 4096 : 3200)
+ * width_x64 * height_x32;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s(%d,%d,%d)=>%d\n",
+ __func__, width, height,
+ is_bit_depth_10, bsize);
+
+ return bsize;
+}
+
+static int avs3_mmu_page_num(struct AVS3Decoder_s *dec,
+ int pic_width, int pic_height, int is_bit_depth_10)
+{
+ int picture_size;
+ int cur_mmu_4k_number, max_frame_num;
+
+ picture_size =
+ compute_losless_comp_body_size(dec, pic_width, pic_height, is_bit_depth_10);
+ cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ max_frame_num = MAX_FRAME_8K_NUM;
+ else
+ max_frame_num = MAX_FRAME_4K_NUM;
+
+ if (cur_mmu_4k_number > max_frame_num) {
+ avs3_print(dec, 0, "over max !! 0x%x width %d height %d\n",
+ max_frame_num, pic_width, pic_height);
+ return -1;
+ }
+ return cur_mmu_4k_number;
+}
+
+/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
+static int compute_losless_comp_header_size(struct AVS3Decoder_s *dec,
+ int width, int height)
+{
+ int width_x128;
+ int height_x64;
+ int hsize;
+ width_x128 = width + 127;
+ width_x128 >>= 7;
+ height_x64 = height + 63;
+ height_x64 >>= 6;
+
+ hsize = 32 * width_x128 * height_x64;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s(%d,%d)=>%d\n",
+ __func__, width, height,
+ hsize);
+
+ return hsize;
+}
+
+static void init_buff_spec(struct AVS3Decoder_s *dec,
+ struct BuffInfo_s *buf_spec)
+{
+ void *mem_start_virt;
+ buf_spec->ipp.buf_start =
+ WORKBUF_ALIGN(buf_spec->start_adr);
+#ifdef NEW_FRONT_BACK_CODE
+ buf_spec->ipp1.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+ buf_spec->sao_abv.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp1.buf_start + buf_spec->ipp1.buf_size);
+#else
+ buf_spec->sao_abv.buf_start =
+ WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+#endif
+ buf_spec->sao_vb.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+ buf_spec->short_term_rps.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+ buf_spec->rcs.buf_start =
+ WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+ buf_spec->sps.buf_start =
+ WORKBUF_ALIGN(buf_spec->rcs.buf_start + buf_spec->rcs.buf_size);
+ buf_spec->pps.buf_start =
+ WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+ buf_spec->sbac_top.buf_start =
+ WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+ buf_spec->sao_up.buf_start =
+ WORKBUF_ALIGN(buf_spec->sbac_top.buf_start + buf_spec->sbac_top.buf_size);
+ buf_spec->swap_buf.buf_start =
+ WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+ buf_spec->swap_buf2.buf_start =
+ WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+ buf_spec->scalelut.buf_start =
+ WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+ buf_spec->dblk_para.buf_start =
+ WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+ buf_spec->dblk_data.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+ buf_spec->dblk_data2.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+#ifdef AVS3_10B_MMU
+ buf_spec->mmu_vbh.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ #ifdef AVS3_10B_MMU_DW
+ buf_spec->mmu_vbh_dw.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
+ #else
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ #endif
+#else /* AVS3_10B_MMU */
+ #ifdef AVS3_10B_MMU_DW
+ buf_spec->mmu_vbh_dw.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
+ #else
+ buf_spec->mpred_above.buf_start =
+ WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+ #endif
+#endif /* AVS3_10B_MMU */
+#ifdef MV_USE_FIXED_BUF
+ buf_spec->mpred_mv.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->rpm.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+#else
+ buf_spec->rpm.buf_start =
+ WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+#endif
+ buf_spec->lmem.buf_start =
+ WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->end_adr =
+ WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+
+ if (dec) {
+ mem_start_virt =
+ codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
+ if (mem_start_virt) {
+ memset(mem_start_virt, 0, buf_spec->dblk_para.buf_size);
+ codec_mm_dma_flush(mem_start_virt,
+ buf_spec->dblk_para.buf_size,
+ DMA_TO_DEVICE);
+ } else {
+ /*not virt for tvp playing,
+ may need clear on ucode.*/
+ pr_err("mem_start_virt failed\n");
+ }
+ if (debug) {
+ pr_info("%s workspace (%x %x) size = %x\n", __func__,
+ buf_spec->start_adr, buf_spec->end_adr,
+ buf_spec->end_adr - buf_spec->start_adr);
+ }
+ if (debug) {
+ pr_info("ipp.buf_start :%x\n",
+ buf_spec->ipp.buf_start);
+#ifdef NEW_FRONT_BACK_CODE
+ pr_info("ipp1.buf_start :%x\n",
+ buf_spec->ipp1.buf_start);
+#endif
+ pr_info("sao_abv.buf_start :%x\n",
+ buf_spec->sao_abv.buf_start);
+ pr_info("sao_vb.buf_start :%x\n",
+ buf_spec->sao_vb.buf_start);
+ pr_info("short_term_rps.buf_start :%x\n",
+ buf_spec->short_term_rps.buf_start);
+ pr_info("rcs.buf_start :%x\n",
+ buf_spec->rcs.buf_start);
+ pr_info("sps.buf_start :%x\n",
+ buf_spec->sps.buf_start);
+ pr_info("pps.buf_start :%x\n",
+ buf_spec->pps.buf_start);
+ pr_info("sao_up.buf_start :%x\n",
+ buf_spec->sao_up.buf_start);
+ pr_info("swap_buf.buf_start :%x\n",
+ buf_spec->swap_buf.buf_start);
+ pr_info("swap_buf2.buf_start :%x\n",
+ buf_spec->swap_buf2.buf_start);
+ pr_info("scalelut.buf_start :%x\n",
+ buf_spec->scalelut.buf_start);
+ pr_info("dblk_para.buf_start :%x\n",
+ buf_spec->dblk_para.buf_start);
+ pr_info("dblk_data.buf_start :%x\n",
+ buf_spec->dblk_data.buf_start);
+ pr_info("dblk_data2.buf_start :%x\n",
+ buf_spec->dblk_data2.buf_start);
+ #ifdef AVS3_10B_MMU
+ pr_info("mmu_vbh.buf_start :%x\n",
+ buf_spec->mmu_vbh.buf_start);
+ #endif
+ #ifdef AVS3_10B_MMU_DW
+ pr_info("mmu_vbh_dw.buf_start :%x\n",
+ buf_spec->mmu_vbh_dw.buf_start);
+ #endif
+ pr_info("mpred_above.buf_start :%x\n",
+ buf_spec->mpred_above.buf_start);
+#ifdef MV_USE_FIXED_BUF
+ pr_info("mpred_mv.buf_start :%x\n",
+ buf_spec->mpred_mv.buf_start);
+#endif
+ if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+ pr_info("rpm.buf_start :%x\n",
+ buf_spec->rpm.buf_start);
+ }
+ }
+ }
+
+}
+
+static void uninit_mmu_buffers(struct AVS3Decoder_s *dec)
+{
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+ decoder_mmu_box_free(dec->dw_mmu_box);
+ dec->dw_mmu_box = NULL;
+ }
+#endif
+ decoder_mmu_box_free(dec->mmu_box);
+ dec->mmu_box = NULL;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (dec->mmu_box_1)
+ decoder_mmu_box_free(dec->mmu_box_1);
+ dec->mmu_box_1 = NULL;
+ if (dec->dw_mmu_enable && dec->dw_mmu_box_1) {
+ decoder_mmu_box_free(dec->dw_mmu_box_1);
+ dec->dw_mmu_box_1 = NULL;
+ }
+ }
+ if (dec->front_back_mode) {
+ uninit_fb_bufstate(dec);
+ }
+#endif
+ if (dec->bmmu_box)
+ decoder_bmmu_box_free(dec->bmmu_box);
+ dec->bmmu_box = NULL;
+}
+
+static u32 calc_buffer_u_v_h_size(u32 w, u32 h, u32 ratio, u32 lcu_size)
+{
+ int pic_width_dw = w / ratio;
+ int pic_height_dw = h / ratio;
+
+ int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
+ (pic_width_dw / lcu_size + 1) : (pic_width_dw / lcu_size);
+ int pic_height_lcu_dw = (pic_height_dw % lcu_size) ?
+ (pic_height_dw / lcu_size + 1) : (pic_height_dw / lcu_size);
+
+ int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
+ int mc_buffer_size_u_v = (lcu_total_dw * lcu_size * lcu_size) >> 1; // div 2
+
+ return ((mc_buffer_size_u_v + 0xffff) >> 16);
+}
+
+static int config_pic(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic, int32_t lcu_size_log2)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ int ret = -1;
+ int i;
+ /* to do: init_pic_w, init_pic_h*/
+#if 0
+ int pic_width = dec->init_pic_w;
+ int pic_height = dec->init_pic_h;
+#else
+ //simulation
+ int32_t pic_width = dec->avs3_dec.img.width;
+ int32_t pic_height = dec->avs3_dec.img.height;
+#endif
+ /*struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;*/
+ int32_t lcu_size = 1 << dec->avs3_dec.lcu_size_log2;
+ int32_t pic_width_lcu = ( pic_width %lcu_size ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+ int32_t pic_height_lcu = ( pic_height %lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+ int32_t lcu_total =pic_width_lcu*pic_height_lcu;
+
+ u32 y_adr = 0;
+ int buf_size = 0;
+ int losless_comp_body_size = compute_losless_comp_body_size(
+ dec, pic_width,
+ pic_height, buf_alloc_depth == 10);
+
+ //int mc_buffer_size_u_v = 0;
+ int mc_buffer_size_u_v_h = 0;
+ int dw_uv_size;
+ int dw_mode = get_double_write_mode_init(dec);
+#ifdef OW_TRIPLE_WRITE
+ int tw_mode = get_triple_write_mode(dec);
+#endif
+
+ if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+ pic_height, get_double_write_ratio(dw_mode & 0xf), lcu_size);
+
+ /*64k alignment*/
+ buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
+ buf_size = ((buf_size + 0xffff) >> 16) << 16;
+#ifdef P010_ENABLE
+ if (is_dw_p010(dec)) { //double size mem for p010 mode
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ }
+#endif
+ }
+#ifdef OW_TRIPLE_WRITE
+ if (tw_mode) {
+ mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+ pic_height, get_double_write_ratio(tw_mode), lcu_size);
+
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ if (is_tw_p010(dec)) {
+ buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+ }
+ }
+#endif
+
+ if (dec->mmu_enable) {
+ pic->header_adr = decoder_bmmu_box_get_phy_addr(
+ dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
+
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ pic->dw_header_adr = pic->header_adr
+ + get_compress_header_size(dec);
+ }
+#endif
+ }
+
+ i = pic->index;
+
+ /*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
+ dec->mc_buf->buf_end)
+ y_adr = dec->mc_buf->buf_start + i * buf_size;
+ else {*/
+ if (buf_size > 0 && pic->cma_alloc_addr == 0) {
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ VF_BUFFER_IDX(i),
+ buf_size, DRIVER_NAME,
+ &pic->cma_alloc_addr);
+ if (ret < 0) {
+ avs3_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
+ VF_BUFFER_IDX(i),
+ buf_size
+ );
+ return ret;
+ }
+
+ if (pic->cma_alloc_addr) {
+ y_adr = pic->cma_alloc_addr;
+ if (!vdec_secure(vdec))
+ codec_mm_memset(y_adr, 0, buf_size);
+
+ if (vdec->vdata == NULL ||
+ atomic_read(&vdec->vdata->use_flag) == 0) {
+ vdec->vdata = vdec_data_get();
+ }
+
+ if (vdec->vdata != NULL) {
+ int index = 0;
+ struct vdec_data_buf_s data_buf;
+ data_buf.alloc_policy = ALLOC_AUX_BUF;
+ data_buf.aux_buf_size = dec->cuva_size;
+
+ index = vdec_data_get_index((ulong)vdec->vdata, &data_buf);
+ if (index >= 0) {
+ pic->cuva_data_buf = vdec->vdata->data[index].aux_data_buf;
+ vdec_data_buffer_count_increase((ulong)vdec->vdata, index, i);
+ INIT_LIST_HEAD(&vdec->vdata->release_callback[i].node);
+ decoder_bmmu_box_add_callback_func(dec->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->vdata->release_callback[i]);
+ } else {
+ avs3_print(dec, 0, "vdec data is full\n");
+ }
+ }
+ } else {
+ avs3_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
+ VF_BUFFER_IDX(i),
+ buf_size
+ );
+ return -1;
+ }
+ }
+
+ /*ensure get_pic_by_POC()
+ not get the buffer not decoded*/
+ dw_uv_size = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+
+ pic->BUF_index = i;
+ pic->lcu_total = lcu_total;
+
+ pic->comp_body_size = losless_comp_body_size;
+ pic->buf_size = buf_size;
+ pic->mc_canvas_y = pic->index;
+ pic->mc_canvas_u_v = pic->index;
+ if (dw_mode) {
+ pic->dw_y_adr = y_adr;
+ pic->dw_u_v_adr = pic->dw_y_adr + (dw_uv_size << 1);
+
+ pic->mc_y_adr = pic->dw_y_adr;
+ pic->mc_u_v_adr = pic->dw_u_v_adr;
+ }
+ if (tw_mode) {
+ if (dw_mode) {
+ pic->tw_y_adr = pic->dw_u_v_adr + dw_uv_size; //base dw buf addr
+ } else {
+ pic->tw_y_adr = y_adr; //base no dw buf addr
+ }
+ pic->tw_u_v_adr = pic->tw_y_adr + (mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1));
+ }
+
+#ifdef MV_USE_FIXED_BUF
+ pic->mpred_mv_wr_start_addr =
+ dec->work_space_buf->mpred_mv.buf_start +
+ pic->index * (dec->work_space_buf->mpred_mv.buf_size / FRAME_BUFFERS);
+ if (pic->mpred_mv_wr_start_addr >
+ (dec->work_space_buf->mpred_mv.buf_start
+ + dec->work_space_buf->mpred_mv.buf_size)) {
+ avs3_print(dec, 0, "err: fixed mv buf out of size, 0x0%x\n",
+ pic->mpred_mv_wr_start_addr);
+ pic->mpred_mv_wr_start_addr =
+ dec->work_space_buf->mpred_mv.buf_start;
+ }
+#endif
+ if (debug & AVS3_DBG_BUFMGR) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s index %d, head_size 0x%08x, MMU header_adr 0x%08x, dw_header_adr 0x%08x; ",
+ __func__, pic->index, get_compress_header_size(dec),
+ pic->header_adr, pic->dw_header_adr);
+
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+ "dw_y_adr 0x%08x, dw_u_v_adr 0x%08x, ",
+ pic->dw_y_adr,
+ pic->dw_u_v_adr);
+
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+ "comp_body_size %x comp_buf_size %x ;",
+ pic->comp_body_size,
+ pic->buf_size);
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+ "mpred_mv_wr_start_adr %d ",
+ pic->mpred_mv_wr_start_addr);
+
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+ "tw y_addr %x, uv_addr %x\n", pic->tw_y_adr, pic->tw_u_v_adr);
+ avs3_print_flush(dec);
+ }
+
+ ret = 0;
+ return ret;
+}
+
+static void init_pic_list(struct AVS3Decoder_s *dec,
+ int32_t lcu_size_log2)
+{
+ int i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic;
+#ifdef AVS3_10B_MMU
+ if (dec->mmu_enable) {
+ for (i = 0; i < avs3_dec->max_pb_size; i++) {
+ unsigned long buf_addr;
+ u32 header_size = get_compress_header_size(dec);
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable)
+ header_size <<= 1;
+#endif
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ HEADER_BUFFER_IDX(i), header_size,
+ DRIVER_HEADER_NAME,
+ &buf_addr) < 0) {
+ avs3_print(dec, 0,
+ "%s malloc compress header failed %d\n",
+ DRIVER_HEADER_NAME, i);
+ dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+ return;
+ }
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(buf_addr, 0, header_size);
+ }
+ }
+#endif
+ dec->frame_height = avs3_dec->img.height;
+ dec->frame_width = avs3_dec->img.width;
+
+ for (i = 0; i < avs3_dec->max_pb_size; i++) {
+ pic = &avs3_dec->pic_pool[i].buf_cfg;
+ pic->index = i;
+ pic->BUF_index = -1;
+ //pic->mv_buf_index = -1;
+ if (config_pic(dec, pic, lcu_size_log2) < 0) {
+ //if (debug)
+ avs3_print(dec, 0,
+ "Config_pic %d fail\n",
+ pic->index);
+ pic->index = -1;
+ break;
+ }
+ pic->width = avs3_dec->img.width;
+ pic->height = avs3_dec->img.height;
+ }
+ for (; i < avs3_dec->max_pb_size; i++) {
+ pic = &avs3_dec->pic_pool[i].buf_cfg;
+ pic->index = -1;
+ pic->BUF_index = -1;
+ //pic->mv_buf_index = -1;
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s ok, max_pb_size = %d\n",
+ __func__, avs3_dec->max_pb_size);
+ dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATE_DONE;
+}
+
+static void init_pic_list_hw(struct AVS3Decoder_s *dec)
+{
+ int i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic;
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
+#if 0
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (0x1 << 2));
+
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (0x1 << 2));
+#endif
+#endif
+ for (i = 0; i < avs3_dec->max_pb_size; i++) {
+ pic = &avs3_dec->pic_pool[i].buf_cfg;
+ if (pic->index < 0)
+ break;
+#ifdef AVS3_10B_MMU
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->header_adr
+ | (pic->mc_canvas_y << 8)|0x1);*/
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+
+#ifdef DUAL_CORE_64
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2)
+ WRITE_VREG(HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+ else
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ (0x1 << 1) | (pic->index << 8));
+#endif
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_y_adr
+ | (pic->mc_canvas_y << 8) | 0x1);*/
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+ pic->mc_u_v_adr
+ | (pic->mc_canvas_u_v << 8)| 0x1);*/
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+#ifdef DUAL_CORE_64
+#ifdef AVS3_10B_MMU
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->header_adr >> 5);
+#else
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+ pic->mc_u_v_adr >> 5);
+#endif
+/*DUAL_CORE_64*/
+#endif
+ }
+ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+ 0x1);
+#endif
+ /*Zero out canvas registers in IPP -- avoid simulation X*/
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+ (0 << 8) | (0 << 1) | 1);
+ for (i = 0; i < 32; i++) {
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+ WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+ }
+}
+
+#ifdef DEBUG_CMD
+#if 0
+static void d_fill_zero(struct AVS3Decoder_s *hw, unsigned int phyadr, int size)
+{
+ WRITE_VREG(HEVC_DBG_LOG_ADR, phyadr);
+ WRITE_VREG(DEBUG_REG1,
+ 0x20000000 | size);
+ debug_cmd_wait_count = 0;
+ debug_cmd_wait_type = 1;
+ while ((READ_VREG(DEBUG_REG1) & 0x1) == 0
+ && debug_cmd_wait_count < 0x7fffffff) {
+ debug_cmd_wait_count++;
+ }
+
+ WRITE_VREG(DEBUG_REG1, 0);
+ debug_cmd_wait_type = 0;
+}
+#endif
+#if 0
+static void d_dump(struct AVS3Decoder_s *hw, unsigned int phyadr, int size,
+ struct file *fp, loff_t *wr_off)
+{
+
+ int jj;
+ unsigned char *data = (unsigned char *)
+ (hw->ucode_log_addr);
+ WRITE_VREG(HEVC_DBG_LOG_ADR, hw->ucode_log_phy_addr);
+
+ WRITE_VREG(HEVC_D_ADR, phyadr);
+ WRITE_VREG(DEBUG_REG1,
+ 0x10000000 | size);
+
+ debug_cmd_wait_count = 0;
+ debug_cmd_wait_type = 3;
+ while ((READ_VREG(DEBUG_REG1) & 0x1) == 0
+ && debug_cmd_wait_count < 0x7fffffff) {
+ debug_cmd_wait_count++;
+ }
+
+ if (fp) {
+ vfs_write(fp, data,
+ size, wr_off);
+
+ } else {
+ for (jj = 0; jj < size; jj++) {
+ if ((jj & 0xf) == 0)
+ avs3_print(hw, 0,
+ "%06x:", jj);
+ avs3_print_cont(hw, 0,
+ "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ avs3_print_cont(hw, 0,
+ "\n");
+ }
+ avs3_print(hw, 0, "\n");
+ }
+
+ WRITE_VREG(DEBUG_REG1, 0);
+ debug_cmd_wait_type = 0;
+
+}
+
+static void mv_buffer_fill_zero(struct AVS3Decoder_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config)
+{
+ pr_info("fill dummy data pic index %d colocate addresses %x size %x\n",
+ pic_config->index, pic_config->mpred_mv_wr_start_addr,
+ hw->m_mv_BUF[pic_config->mv_buf_index].size);
+ d_fill_zero(hw, pic_config->mpred_mv_wr_start_addr,
+ hw->m_mv_BUF[pic_config->mv_buf_index].size);
+}
+
+static void dump_mv_buffer(struct AVS3Decoder_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config)
+{
+
+ unsigned int adr, size;
+ unsigned int adr_end = pic_config->mpred_mv_wr_start_addr +
+ hw->m_mv_BUF[pic_config->mv_buf_index].size;
+ mm_segment_t old_fs;
+ loff_t off = 0;
+ int mode = O_CREAT | O_WRONLY | O_TRUNC;
+ char file[64];
+ struct file *fp;
+ sprintf(&file[0], "/data/tmp/colocate%d", hw->frame_count-1);
+ fp = filp_open(file, mode, 0666);
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ for (adr = pic_config->mpred_mv_wr_start_addr;
+ adr < adr_end;
+ adr += UCODE_LOG_BUF_SIZE) {
+ size = UCODE_LOG_BUF_SIZE;
+ if (size > (adr_end - adr))
+ size = adr_end - adr;
+ pr_info("dump pic index %d colocate addresses %x size %x\n",
+ pic_config->index, adr, size);
+ d_dump(hw, adr, size, fp, &off);
+ }
+ set_fs(old_fs);
+ vfs_fsync(fp, 0);
+
+ filp_close(fp, current->files);
+}
+#endif
+#endif
+
+static int config_mc_buffer(struct AVS3Decoder_s *dec)
+{
+ int32_t i;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ //avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+ avs3_frame_t *pic;
+ //uint32_t rdata32;
+ //uint32_t rdata32_2;
+ //if (avs3_dec->img.type == I_IMG)
+ // return 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "Entered config_mc_buffer....\n");
+ if (avs3_dec->f_bg != NULL) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+ avs3_dec->f_bg->mc_canvas_y, avs3_dec->f_bg->mc_canvas_u_v);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (7 << 8) | (0<<1) | 1); // L0:BG
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (15 << 8) | (0<<1) | 1); // L0:BG
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ //WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (23 << 8) | (0<<1) | 1); // L1:BG
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (31 << 8) | (0<<1) | 1); // L1:BG
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+ }
+ if (avs3_dec->slice_type == SLICE_I)
+ return 0;
+ if (avs3_dec->slice_type == SLICE_P || avs3_dec->slice_type == SLICE_B) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for REF_0, img type %d\n", avs3_dec->slice_type);
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_0]; i++) {
+ pic = &avs3_dec->ctx.refp[i][REFP_0].pic->buf_cfg;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark) {
+ avs3_dec->ctx.pic->buf_cfg.error_mark = 1;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 refid %d pic error\n", __func__, i);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "L0 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ }
+ if (avs3_dec->slice_type == SLICE_B) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "config_mc_buffer for REF_1\n");
+
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ pic = &avs3_dec->ctx.refp[i][REFP_1].pic->buf_cfg;
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+ (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+ if (pic->error_mark) {
+ avs3_dec->ctx.pic->buf_cfg.error_mark = 1;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 refid %d pic error\n", __func__, i);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "L1 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+ }
+ }
+ return 0;
+}
+#if 0
+static void mcrcc_get_hitrate(void)
+{
+ u32 tmp;
+ u32 raw_mcr_cnt;
+ u32 hit_mcr_cnt;
+ u32 byp_mcr_cnt_nchoutwin;
+ u32 byp_mcr_cnt_nchcanv;
+ int hitrate;
+
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("[cache_util.c] Entered mcrcc_get_hitrate...\n");
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
+ raw_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
+ hit_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
+ byp_mcr_cnt_nchoutwin = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
+ byp_mcr_cnt_nchcanv = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+
+ if (debug & AVS3_DBG_CACHE) {
+ pr_info("raw_mcr_cnt_total: %d\n",raw_mcr_cnt);
+ pr_info("hit_mcr_cnt_total: %d\n",hit_mcr_cnt);
+ pr_info("byp_mcr_cnt_nchoutwin_total: %d\n",byp_mcr_cnt_nchoutwin);
+ pr_info("byp_mcr_cnt_nchcanv_total: %d\n",byp_mcr_cnt_nchcanv);
+ }
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
+ tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("miss_mcr_0_cnt_total: %d\n", tmp);
+
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
+ tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("miss_mcr_1_cnt_total: %d\n", tmp);
+
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
+ tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("hit_mcr_0_cnt_total: %d\n",tmp);
+
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
+ tmp= READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("hit_mcr_1_cnt_total: %d\n",tmp);
+
+ if (raw_mcr_cnt != 0) {
+ hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("MCRCC_HIT_RATE : %d\n", hitrate);
+ hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)
+ /raw_mcr_cnt) * 100;
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("MCRCC_BYP_RATE : %d\n", hitrate);
+ } else if (debug & AVS3_DBG_CACHE) {
+ pr_info("MCRCC_HIT_RATE : na\n");
+ pr_info("MCRCC_BYP_RATE : na\n");
+ }
+ return;
+}
+
+static void decomp_get_hitrate(void)
+{
+ u32 raw_mcr_cnt;
+ u32 hit_mcr_cnt;
+ int hitrate;
+
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("[cache_util.c] Entered decomp_get_hitrate...\n");
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
+ raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
+ hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+
+ if (debug & AVS3_DBG_CACHE) {
+ pr_info("hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+ pr_info("hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+ }
+ if (raw_mcr_cnt != 0) {
+ hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+ } else {
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("DECOMP_HCACHE_HIT_RATE : na\n");
+ }
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
+ raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
+ hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+
+ if (debug & AVS3_DBG_CACHE) {
+ pr_info("dcache_raw_cnt_total: %d\n", raw_mcr_cnt);
+ pr_info("dcache_hit_cnt_total: %d\n", hit_mcr_cnt);
+ }
+ if (raw_mcr_cnt != 0) {
+ hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+ } else if (debug & AVS3_DBG_CACHE) {
+ pr_info("DECOMP_DCACHE_HIT_RATE : na\n");
+ }
+return;
+}
+
+static void decomp_get_comprate(void)
+{
+ u32 raw_ucomp_cnt;
+ u32 fast_comp_cnt;
+ u32 slow_comp_cnt;
+ int comprate;
+
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("[cache_util.c] Entered decomp_get_comprate...\n");
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
+ fast_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
+ slow_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
+ raw_ucomp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
+ if (debug & AVS3_DBG_CACHE) {
+ pr_info("decomp_fast_comp_total: %d\n", fast_comp_cnt);
+ pr_info("decomp_slow_comp_total: %d\n", slow_comp_cnt);
+ pr_info("decomp_raw_uncomp_total: %d\n", raw_ucomp_cnt);
+ }
+
+ if (raw_ucomp_cnt != 0) {
+ comprate = ((fast_comp_cnt + slow_comp_cnt)
+ / raw_ucomp_cnt) * 100;
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("DECOMP_COMP_RATIO : %d\n", comprate);
+ } else if (debug & AVS3_DBG_CACHE) {
+ pr_info("DECOMP_COMP_RATIO : na\n");
+ }
+ return;
+}
+#endif
+
+static void config_mcrcc_axi_hw(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ uint32_t rdata32;
+ uint32_t rdata32_2;
+
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+ if (avs3_dec->slice_type == SLICE_I) {
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+ return;
+ }
+
+#if 0
+ mcrcc_get_hitrate();
+ decomp_get_hitrate();
+ decomp_get_comprate();
+#endif
+ if ((avs3_dec->slice_type == SLICE_B) || (avs3_dec->slice_type == SLICE_P)) {
+ // Programme canvas0
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+ rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | ( rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
+
+ // Programme canvas1
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (1<<1) | 0);
+ rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32_2 = rdata32_2 & 0xffff;
+ rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ if ( rdata32 == rdata32_2 ) {
+ rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32_2 = rdata32_2 & 0xffff;
+ rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+ }
+ WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32_2);
+ } else { // P-PIC
+ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+ rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | ( rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
+
+ // Programme canvas1
+ rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+ rdata32 = rdata32 & 0xffff;
+ rdata32 = rdata32 | ( rdata32 << 16);
+ WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
+ }
+
+ WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+ return;
+}
+
+static void config_mpred_hw(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int32_t i;
+ uint32_t data32;
+ avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+ avs3_frame_t *col_pic;
+ //COM_PIC *colPic;
+
+ //int32_t AMVP_MAX_NUM_CANDS_MEM=3;
+ //int32_t AMVP_MAX_NUM_CANDS=2;
+ //int32_t NUM_CHROMA_MODE=5;
+ //int32_t DM_CHROMA_IDX=36;
+ int32_t above_ptr_ctrl =0;
+ //int32_t buffer_linear =1;
+ //int32_t cu_size_log2 =3;
+ int32_t mpred_mv_rd_start_addr ;
+ //int32_t mpred_curr_lcu_x;
+ //int32_t mpred_curr_lcu_y;
+ //int32_t mpred_above_buf_start ;
+ //int32_t mpred_mv_rd_ptr ;
+ //int32_t mpred_mv_rd_ptr_p1 ;
+ int32_t mpred_mv_rd_end_addr;
+ int32_t MV_MEM_UNIT_l;
+ //int32_t mpred_mv_wr_ptr ;
+
+ int32_t above_en;
+ int32_t mv_wr_en;
+ int32_t mv_rd_en;
+ int32_t col_isIntra;
+ int32_t col_ptr;
+
+ if (avs3_dec->slice_type == SLICE_P) {
+ col_pic = &avs3_dec->ctx.refp[0][REFP_0].pic->buf_cfg;
+ }
+ else if (avs3_dec->slice_type == SLICE_B) {
+ col_pic = &avs3_dec->ctx.refp[0][REFP_1].pic->buf_cfg;
+ }
+ else {
+ col_pic = cur_pic;
+ }
+
+ //if (dec->slice_type!=2)
+ if (avs3_dec->slice_type != SLICE_I)
+ {
+ above_en=1;
+ mv_wr_en=1;
+ if (col_pic->slice_type != SLICE_I)
+ mv_rd_en=1;
+ else
+ mv_rd_en=0;
+ col_isIntra=0;
+ }
+ else
+ {
+ above_en=1;
+ mv_wr_en=1;
+ mv_rd_en=0;
+ col_isIntra=0;
+ }
+
+ mpred_mv_rd_start_addr=col_pic->mpred_mv_wr_start_addr;
+ /*data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
+ mpred_curr_lcu_x =data32 & 0xffff;
+ mpred_curr_lcu_y =(data32>>16) & 0xffff;*/
+
+ MV_MEM_UNIT_l=get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+ mpred_mv_rd_end_addr=mpred_mv_rd_start_addr + ((avs3_dec->lcu_x_num*avs3_dec->lcu_y_num)*MV_MEM_UNIT_l);
+
+ //mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "cur pic index %d slicetype %d col pic index %d slicetype %d\n",
+ cur_pic->index, cur_pic->slice_type,
+ col_pic->index, col_pic->slice_type);
+
+ WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR, cur_pic->mpred_mv_wr_start_addr);
+ WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, col_pic->mpred_mv_wr_start_addr);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[MPRED CO_MV] write 0x%x read 0x%x\n", cur_pic->mpred_mv_wr_start_addr, col_pic->mpred_mv_wr_start_addr);
+ /*
+ data32 =
+ ((avs3_dec->bk_img_is_top_field) << 13) |
+ ((avs3_dec->hd.background_picture_enable & 1) << 12) |
+ ((avs3_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+ ((avs3_dec->hd.b_pmvr_enabled & 1) << 6) |
+ ((avs3_dec->img.is_top_field & 1) << 5) |
+ ((avs3_dec->img.is_field_sequence & 1) << 4) |
+ ((avs3_dec->img.typeb & 7) << 1) |
+ (avs3_dec->hd.background_reference_enable & 0x1);
+ printk("HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n", data32, avs3_dec->hd.curr_RPS.num_of_ref);
+ WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+ */
+#if 1
+ /*
+ data32 = ((dec->lcu_x_num - dec->tile_width_lcu)*MV_MEM_UNIT);
+ WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);
+ WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);
+ */
+ data32 = READ_VREG(HEVC_MPRED_CTRL0);
+ data32 &= (~(0x3 | (0xf << 8) | (0xf << 16)));
+ data32 = (
+ avs3_dec->slice_type |
+ /*dec->new_pic<<2 |
+ dec->new_tile<<3|
+ dec->isNextSliceSegment<<4|
+ dec->TMVPFlag<<5|
+ dec->LDCFlag<<6|
+ dec->ColFromL0Flag<<7|
+ */
+ above_ptr_ctrl<<8 |
+ above_en<<9|
+ mv_wr_en<<10|
+ mv_rd_en<<11|
+ avs3_dec->lcu_size_log2<<16
+ /*|cu_size_log2<<20*/
+ );
+ WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "P_HEVC_MPRED_CTRL0=0x%x\n",
+ READ_VREG(HEVC_MPRED_CTRL0));
+
+ data32 = READ_VREG(HEVC_MPRED_CTRL1);
+ data32 &= (~0xf);
+ data32 |= avs3_dec->ctx.info.sqh.num_of_hmvp_cand;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "write P_HEVC_MPRED_CTRL1=0x%x, avs3_dec->ctx.info.sqh.num_of_hmvp_cand=%d\n",
+ data32, avs3_dec->ctx.info.sqh.num_of_hmvp_cand);
+ WRITE_VREG(HEVC_MPRED_CTRL1,data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "P_HEVC_MPRED_CTRL1=0x%x\n",
+ READ_VREG(HEVC_MPRED_CTRL1));
+
+ data32 = (
+ avs3_dec->img.width|
+ avs3_dec->img.height<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+ data32 = (
+ (avs3_dec->lcu_x_num-1) |
+ (avs3_dec->lcu_y_num-1)<<16
+ );
+ WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU,data32);
+
+ /*data32 = (
+ dec->tile_start_lcu_x |
+ dec->tile_start_lcu_y<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_START,data32);
+ data32 = (
+ dec->tile_width_lcu |
+ dec->tile_height_lcu<<16
+ );
+ WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU,data32);
+ */
+ data32 = (
+ avs3_dec->ctx.dpm.num_refp[REFP_0] |
+ avs3_dec->ctx.dpm.num_refp[REFP_1]<<8|
+ 0
+ //col_RefNum_L0<<16|
+ //col_RefNum_L1<<24
+ );
+ WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+ data32=0;
+ for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_0];i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+ data32=0;
+ for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_1];i++)data32=data32|(1<<i);
+ WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+
+ WRITE_VREG(HEVC_MPRED_CUR_POC, avs3_dec->ctx.ptr & 0xffff);
+ if (avs3_dec->slice_type == SLICE_P) {
+ col_ptr = avs3_dec->ctx.refp[0][REFP_0].ptr;
+ //colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+ }
+ else if (avs3_dec->slice_type == SLICE_B) {
+ col_ptr = avs3_dec->ctx.refp[0][REFP_1].ptr;
+ //colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+ }
+ else {
+ col_ptr = avs3_dec->ctx.pic->ptr;
+ //colPic = avs3_dec->ctx.pic;
+ }
+ WRITE_VREG(HEVC_MPRED_COL_POC, col_ptr & 0xffff);
+ //below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> Ref_POC_xx_L1 in pair write order!!!
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "P_HEVC_MPRED_CUR_POC=0x%x, P_HEVC_MPRED_COL_POC=0x%x\n",
+ READ_VREG(HEVC_MPRED_CUR_POC), READ_VREG(HEVC_MPRED_COL_POC));
+
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+ data32 = 0;
+ if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+ if (i < cur_pic->list0_num_refp) {
+ data32 |= cur_pic->list0_ptr[i] & 0xffff;
+ }
+ if (i < col_pic->list0_num_refp) {
+ data32 |= ((col_pic->list0_ptr[i] & 0xffff) << 16);
+ }
+ }
+ WRITE_VREG(HEVC_MPRED_L0_REF_POC_ADR[i], data32);
+ }
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+ if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+ if (i < cur_pic->list0_num_refp) {
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[%d] ", cur_pic->list0_ptr[i]);
+ }
+ if (i < col_pic->list0_num_refp) {
+ avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "<%d> ", col_pic->list0_ptr[i]);
+ }
+ }
+ if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "P_HEVC_MPRED_L0_REF=0x%x (readback 0x%x)\n", i,
+ data32, READ_VREG(HEVC_MPRED_L0_REF_POC_ADR[i]));
+ }
+ }
+ }
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ WRITE_VREG(HEVC_MPRED_L1_REF_POC_ADR[i], avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff);
+ }
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "P_HEVC_MPRED_L1_REF%02d_POC=0x%x (readback 0x%x)\n", i, avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff, READ_VREG(HEVC_MPRED_L1_REF_POC_ADR[i]));
+ }
+ }
+
+#if 0
+ if (dec->new_pic)
+ {
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,mpred_above_buf_start);
+ WRITE_VREG(HEVC_MPRED_MV_WPTR,mpred_mv_wr_ptr);
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_start_addr);
+ }
+ else if (!dec->isNextSliceSegment)
+ {
+ //WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1);
+ WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+ }
+#endif
+ WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dblk_hw(struct AVS3Decoder_s *dec)
+{
+ /*
+ * Picture level de-block parameter configuration here
+ */
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ union param_u *rpm_param = &avs3_dec->param;
+ uint32_t data32;
+ DEC_CTX * ctx = &avs3_dec->ctx;
+ int32_t alpha_c_offset = rpm_param->p.pic_header_alpha_c_offset;
+ int32_t beta_offset = rpm_param->p.pic_header_beta_offset;
+
+ alpha_c_offset = (alpha_c_offset >=16) ? 15 : ((alpha_c_offset < -16) ? -16 : alpha_c_offset);
+ beta_offset = (beta_offset >=16) ? 15 : ((beta_offset < -16) ? -16 : beta_offset);
+
+ data32 = READ_VREG(HEVC_DBLK_CFG1);
+ data32 = (((data32>>20)&0xfff)<<20) |
+ (((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)<<16) | // [16 +: 4]: {luma_bd[1:0],chroma_bd[1:0]}
+ (((data32>>2)&0x3fff)<<2) |
+ (((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)<<0);// [ 0 +: 2]: lcu_size
+ WRITE_VREG(HEVC_DBLK_CFG1, data32);
+
+ data32 = (avs3_dec->img.height<<16) | avs3_dec->img.width;
+ WRITE_VREG(HEVC_DBLK_CFG2, data32);
+
+ data32 = ((rpm_param->p.sqh_cross_patch_loop_filter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+ ((rpm_param->p.pic_header_loop_filter_disable_flag & 0x1)<<26) | // [26 +: 1]: loop_filter_disable
+ ((alpha_c_offset&0x1f) <<17) | // [17 +: 5]: alpha_c_offset (-8~8)
+ ((beta_offset&0x1f) <<12) | // [12 +: 5]: beta_offset (-8~8)
+ ((rpm_param->p.pic_header_chroma_quant_param_delta_cb&0x3f)<<6) | // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+ ((rpm_param->p.pic_header_chroma_quant_param_delta_cr&0x3f)<<0); // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+ WRITE_VREG(HEVC_DBLK_CFG9, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d,%d),log2_lcuSize(%d)\n",
+ rpm_param->p.sqh_cross_patch_loop_filter,rpm_param->p.pic_header_loop_filter_disable_flag,
+ ctx->info.bit_depth_input,ctx->info.bit_depth_internal,ctx->info.log2_max_cuwh);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: alphaCOffset(%d crop to %d),betaOffset(%d crop to %d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+ rpm_param->p.pic_header_alpha_c_offset, alpha_c_offset,rpm_param->p.pic_header_beta_offset, beta_offset,
+ rpm_param->p.pic_header_chroma_quant_param_delta_cb,rpm_param->p.pic_header_chroma_quant_param_delta_cr);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgDBLK: .done.\n");
+
+}
+
+static void config_dw(struct AVS3Decoder_s *dec, struct avs3_frame_s *pic,
+ u32 mc_buffer_size_u_v_h)
+{
+
+ int dw_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+ int tw_mode = get_triple_write_mode(dec);
+#endif
+ uint32_t data32;
+
+ if ((dw_mode & 0x10) == 0) {
+ WRITE_VREG(HEVC_SAO_CTRL26, 0);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 &= (~(0xff << 16));
+ if (((dw_mode & 0xf) == 8) ||
+ ((dw_mode & 0xf) == 9)) {
+ data32 |= (0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
+ } else {
+ if ((dw_mode & 0xf) == 2 ||
+ (dw_mode & 0xf) == 3)
+ data32 |= (0xff<<16);
+ else if ((dw_mode & 0xf) == 4 ||
+ (dw_mode & 0xf) == 5)
+ data32 |= (0x33<<16);
+
+ /*if (dec->mem_saving_mode == 1)
+ data32 |= (1 << 9);
+ else*/
+ data32 &= ~(1 << 9);
+ /*if (workaround_enable & 1)
+ data32 |= (1 << 7);*/
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+ }
+
+ /* m8baby test1902 */
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+ data32 |= (MEM_MAP_MODE << 12);
+ data32 &= (~0xff0);
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable == 0)
+ data32 |= ((dec->endian >> 8) & 0xfff); /* endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf) */
+#else
+ data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+
+ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+ if (dw_mode == 0)
+ data32 |= 0x2; /*disable double write*/
+ else if (dw_mode & 0x10)
+ data32 |= 0x1; /*disable cm*/
+
+ data32 &= (~(3 << 14));
+ data32 |= (2 << 14);
+ /*
+ * [31:24] ar_fifo1_axi_thred
+ * [23:16] ar_fifo0_axi_thred
+ * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
+ * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ * [11:08] axi_lendian_C
+ * [07:04] axi_lendian_Y
+ * [3] reserved
+ * [2] clk_forceon
+ * [1] dw_disable:disable double write output
+ * [0] cm_disable:disable compress output
+ */
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+ data32 = READ_VREG(HEVC_DBLK_CFGB);
+ data32 &= (~0x300); /*[8]:first write enable (compress)
+ [9]:double write enable (uncompress)*/
+ if (dw_mode == 0)
+ data32 |= (0x1 << 8); /*enable first write*/
+ else if (dw_mode == 0x10)
+ data32 |= (0x1 << 9); /*double write only*/
+ else
+ data32 |= ((0x1 << 8) | (0x1 << 9));
+ WRITE_VREG(HEVC_DBLK_CFGB, data32);
+
+ if (dw_mode & 0x10) {
+ /* [23:22] dw_v1_ctrl
+ *[21:20] dw_v0_ctrl
+ *[19:18] dw_h1_ctrl
+ *[17:16] dw_h0_ctrl
+ */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ /*set them all 0 for H265_NV21 (no down-scale)*/
+ data32 &= ~(0xff << 16);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+
+#ifdef P010_ENABLE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+ data32 = READ_VREG(HEVC_SAO_CTRL3);
+ if (is_dw_p010(dec)) {
+ data32 |= (1 << 1); /* enable double write p010 */
+ } else {
+ data32 &= ~(1 << 1);
+ }
+ WRITE_VREG(HEVC_SAO_CTRL3, data32);
+ }
+#endif
+#ifdef OW_TRIPLE_WRITE
+ if (tw_mode) {
+ data32 = READ_VREG(HEVC_SAO_CTRL31);
+ data32 &= ~0xfff;
+ if ((tw_mode == 2) || (tw_mode == 3)) {
+ data32 |= ((0xf << 6) | 0xf); //1:4
+ } else if ((tw_mode == 4) || (tw_mode == 5)) {
+ data32 |= ((0x3 << 6) | 0x3); //1:2
+ } else if ((tw_mode == 8) || (tw_mode == 9)) {
+ data32 |= ((0x3f << 6) | 0x3f);
+ }
+ WRITE_VREG(HEVC_SAO_CTRL31, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL32);
+ data32 &= (~0xfff); /* clr endian, blkmod and align */
+ data32 |= ((dec->endian >> 12) & 0xff);
+ data32 |= ((mem_map_mode & 0x3) << 8);
+ /* Linear_LineAlignment 00:16byte 01:32byte 10:64byte */
+ data32 |= (2 << 10);
+ WRITE_VREG(HEVC_SAO_CTRL32, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL3);
+ data32 |= (1 << 2); /* enable triple write */
+#ifdef P010_ENABLE
+ if (is_tw_p010(dec)) {
+ data32 |= (1 << 3); /* enable triple write p010 */
+ } else {
+ data32 &= ~(1 << 3);
+ }
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL3, data32);
+
+ if (debug & AVS3_DBG_REG) {
+ avs3_print(dec, 0, "%s, HEVC_SAO_CTRL3 %x, HEVC_SAO_CTRL31 %x, HEVC_SAO_CTRL32 %x\n",
+ __func__, READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL31), READ_VREG(HEVC_SAO_CTRL32));
+ }
+ }
+#endif
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+ data32 = pic->mc_y_adr;
+ if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_VREG(HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ if ((dw_mode & 0x10) == 0)
+ WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32);
+#ifdef OW_TRIPLE_WRITE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+ if (tw_mode) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR3, pic->tw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR3, pic->tw_u_v_adr);
+ } else {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR3, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR3, 0xffffffff);
+ }
+ }
+#endif
+
+ if (dec->mmu_enable)
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ }
+#endif
+#else
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+ WRITE_VREG(HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+ WRITE_VREG(HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+ data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec) + 1);
+ WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
+
+ data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+ WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
+
+ if (tw_mode) {
+ data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1);
+ WRITE_VREG(HEVC_SAO_Y_LENGTH3, data32);
+ data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec));
+ WRITE_VREG(HEVC_SAO_C_LENGTH3, data32);
+
+ if (debug & AVS3_DBG_REG) {
+ avs3_print(dec, 0, "triple write SAO_Y_ADDR3 %x, SAO_Y_LENGTH3 %x, SAO_C_ADDR3 %x, SAO_C_LENGTH3 %x\n",
+ READ_VREG(HEVC_SAO_Y_START_ADDR3), READ_VREG(HEVC_SAO_Y_LENGTH3),
+ READ_VREG(HEVC_SAO_C_START_ADDR3), READ_VREG(HEVC_SAO_C_LENGTH3));
+ }
+ }
+}
+
+static void config_sao_hw(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_frame_t *pic = avs3_dec->cur_pic;
+ //union param_u* params = &avs3_dec->param;
+ uint32_t data32;
+ int32_t pic_width = avs3_dec->img.width;
+ int32_t pic_height = avs3_dec->img.height;
+ int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+ int32_t lcu_size = 1<<lcu_size_log2;
+ int32_t pic_width_lcu = ( pic_width % lcu_size ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+ int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+ int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+ int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+ int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+ config_dw(dec, pic, mc_buffer_size_u_v_h);
+ data32 = READ_VREG(HEVC_SAO_CTRL0);
+ data32 &= (~0xf);
+ data32 |= avs3_dec->lcu_size_log2;
+ WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+ if ((get_double_write_mode(dec) & 0x10) == 0)
+ WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+ if ((get_double_write_mode(dec) & 0x20) == 0) {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+ WRITE_VREG(HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+ WRITE_VREG(HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+ } else {
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
+ }
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
+ }
+
+ //WRITE_VREG(HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+ //WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+#ifdef AVS3_10B_MMU
+ //WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS3_10B_MMU_DW
+ //if (dec->dw_mmu_enable) {
+ // WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+ //}
+#endif
+
+#else
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+ data32 = (mc_buffer_size_u_v_h<<16)<<1;
+ WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+
+ //WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+ data32 = (mc_buffer_size_u_v_h<<16);
+ WRITE_VREG(HEVC_SAO_C_LENGTH ,data32);
+ //WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+ //WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+
+#ifdef AVS3_10B_NV21
+ data32 = READ_VREG(HEVC_SAO_CTRL1);
+ data32 &= (~0x3000);
+ data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ data32 &= (~0x3);
+ data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
+ WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+ data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
+ data32 &= ~(0xff << 16); // set them all 0 for H265_NV21 (no down-scale)
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+ data32 &= (~0x30);
+ data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
+ WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+#ifndef AVS3_10B_NV21
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+ WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+ }
+#endif
+#endif
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgSAO .done.\n");
+}
+
+static void config_alf_hw(struct AVS3Decoder_s *dec)
+{
+ /*
+ * Picture level ALF parameter configuration here
+ */
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ uint32_t data32;
+ int32_t i,j;
+ int32_t m_filters_per_group;
+#ifdef USE_FORCED_ALF_PARAM
+ ALFParam forced_alf_cr;
+ forced_alf_cr.alf_flag = 1;
+ forced_alf_cr.num_coeff = 9;
+ forced_alf_cr.filters_per_group = 1;
+ forced_alf_cr.component_id = 2;
+ forced_alf_cr.coeff_multi[0][0] = -3;
+ forced_alf_cr.coeff_multi[0][1] = -3;
+ forced_alf_cr.coeff_multi[0][2] = 4;
+ forced_alf_cr.coeff_multi[0][3] = 7;
+ forced_alf_cr.coeff_multi[0][4] = 6;
+ forced_alf_cr.coeff_multi[0][5] = -1;
+ forced_alf_cr.coeff_multi[0][6] = 3;
+ forced_alf_cr.coeff_multi[0][7] = 6;
+ forced_alf_cr.coeff_multi[0][8] = 0;
+#endif
+
+ ALFParam *m_alfPictureParam_y = &avs3_dec->m_alfPictureParam[0];
+ ALFParam *m_alfPictureParam_cb = &avs3_dec->m_alfPictureParam[1];
+#ifdef USE_FORCED_ALF_PARAM
+ ALFParam *m_alfPictureParam_cr = &forced_alf_cr; // &avs3_dec->m_alfPictureParam[2];
+#else
+ ALFParam *m_alfPictureParam_cr = &avs3_dec->m_alfPictureParam[2];
+#endif
+
+ printf("[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filter_pattern[0]=0x%x,[15]=0x%x\n",
+ m_alfPictureParam_y->component_id,
+ m_alfPictureParam_y->alf_flag,
+ m_alfPictureParam_y->filters_per_group,
+ m_alfPictureParam_y->filter_pattern[0],m_alfPictureParam_y->filter_pattern[15]);
+ printf("[t]alfy,num_coeff(%d),coeff_multi[0][0]=0x%x,[0][1]=0x%x,[1][0]=0x%x,[1][1]=0x%x\n",
+ m_alfPictureParam_y->num_coeff,
+ m_alfPictureParam_y->coeff_multi[0][0],
+ m_alfPictureParam_y->coeff_multi[0][1],
+ m_alfPictureParam_y->coeff_multi[1][0],
+ m_alfPictureParam_y->coeff_multi[1][1]);
+
+ // Cr
+ for (i=0;i<16;i++) dec->m_varIndTab[i] = 0;
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 2, m_alfPictureParam_cr);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cr(%d), alf_cr_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cr->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Cb
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 1, m_alfPictureParam_cb);
+ data32 = ((dec->m_filterCoeffSym[0][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[0][4]>>4) & 0x7 ) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_cb(%d), alf_cb_coef(%d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_cb->alf_flag,
+ dec->m_filterCoeffSym[0][0],dec->m_filterCoeffSym[0][1],dec->m_filterCoeffSym[0][2],
+ dec->m_filterCoeffSym[0][3],dec->m_filterCoeffSym[0][4],dec->m_filterCoeffSym[0][5],
+ dec->m_filterCoeffSym[0][6],dec->m_filterCoeffSym[0][7],dec->m_filterCoeffSym[0][8]);
+
+ // Y
+ for (j=0;j<16;j++) for (i=0;i<9;i++) dec->m_filterCoeffSym[j][i] = 0;
+ reconstructCoefInfo(dec, 0, m_alfPictureParam_y);
+ data32 = ((dec->m_varIndTab[7] & 0xf) << 28) | ((dec->m_varIndTab[6] & 0xf) << 24) |
+ ((dec->m_varIndTab[5] & 0xf) << 20) | ((dec->m_varIndTab[4] & 0xf) << 16) |
+ ((dec->m_varIndTab[3] & 0xf) << 12) | ((dec->m_varIndTab[2] & 0xf) << 8) |
+ ((dec->m_varIndTab[1] & 0xf) << 4) | ((dec->m_varIndTab[0] & 0xf) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 = ((dec->m_varIndTab[15] & 0xf) << 28) | ((dec->m_varIndTab[14] & 0xf) << 24) |
+ ((dec->m_varIndTab[13] & 0xf) << 20) | ((dec->m_varIndTab[12] & 0xf) << 16) |
+ ((dec->m_varIndTab[11] & 0xf) << 12) | ((dec->m_varIndTab[10] & 0xf) << 8) |
+ ((dec->m_varIndTab[ 9] & 0xf) << 4) | ((dec->m_varIndTab[ 8] & 0xf) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] pic_alf_on_y(%d), alf_y_tab(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)\n", m_alfPictureParam_y->alf_flag,
+ dec->m_varIndTab[ 0],dec->m_varIndTab[ 1],dec->m_varIndTab[ 2],dec->m_varIndTab[ 3],
+ dec->m_varIndTab[ 4],dec->m_varIndTab[ 5],dec->m_varIndTab[ 6],dec->m_varIndTab[ 7],
+ dec->m_varIndTab[ 8],dec->m_varIndTab[ 9],dec->m_varIndTab[10],dec->m_varIndTab[11],
+ dec->m_varIndTab[12],dec->m_varIndTab[13],dec->m_varIndTab[14],dec->m_varIndTab[15]);
+
+ m_filters_per_group = (m_alfPictureParam_y->alf_flag == 0) ? 1 : m_alfPictureParam_y->filters_per_group;
+ for (i=0;i<m_filters_per_group;i++) {
+ data32 = ((dec->m_filterCoeffSym[i][4] & 0xf ) << 28) |
+ ((dec->m_filterCoeffSym[i][3] & 0x7f) << 21) |
+ ((dec->m_filterCoeffSym[i][2] & 0x7f) << 14) |
+ ((dec->m_filterCoeffSym[i][1] & 0x7f) << 7) |
+ ((dec->m_filterCoeffSym[i][0] & 0x7f) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ data32 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+ ((dec->m_filterCoeffSym[i][8] & 0x7f) << 24) |
+ ((dec->m_filterCoeffSym[i][7] & 0x7f) << 17) |
+ ((dec->m_filterCoeffSym[i][6] & 0x7f) << 10) |
+ ((dec->m_filterCoeffSym[i][5] & 0x7f) << 3) |
+ (((dec->m_filterCoeffSym[i][4]>>4) & 0x7 ) << 0);
+ WRITE_VREG(HEVC_DBLK_CFGD, data32);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] alf_y_coef[%d](%d %d %d %d %d %d %d %d %d)\n",i,dec->m_filterCoeffSym[i][0],dec->m_filterCoeffSym[i][1],dec->m_filterCoeffSym[i][2],
+ dec->m_filterCoeffSym[i][3],dec->m_filterCoeffSym[i][4],dec->m_filterCoeffSym[i][5],
+ dec->m_filterCoeffSym[i][6],dec->m_filterCoeffSym[i][7],dec->m_filterCoeffSym[i][8]);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "[c] cfgALF .done.\n");
+}
+
+static u32 init_cuva_size;
+
+static int cuva_data_is_available(struct AVS3Decoder_s *dec, u32 reg_val)
+{
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s:reg_val: %u \n",
+ __func__, reg_val);
+ if (reg_val != 0 && reg_val != init_cuva_size)
+ return 1;
+ else
+ return 0;
+}
+
+void config_cuva_buf(struct AVS3Decoder_s *dec)
+{
+ WRITE_VREG(AVS3_CUVA_ADR, dec->cuva_phy_addr);
+ init_cuva_size = (dec->cuva_size >> 4) << 16;
+ WRITE_VREG(AVS3_CUVA_DATA_SIZE, init_cuva_size);
+}
+
+static void set_cuva_data(struct AVS3Decoder_s *dec)
+{
+ int i;
+ unsigned short *cuva_adr;
+ unsigned int size_reg_val =
+ READ_VREG(AVS3_CUVA_DATA_SIZE);
+ unsigned int cuva_count = 0;
+ int cuva_size = 0;
+ struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+ if (pic == NULL || 0 == cuva_data_is_available(dec, size_reg_val)) {
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "%s:pic 0x%p or data not available\n",
+ __func__, pic);
+ return;
+ }
+
+ cuva_adr = (unsigned short *)dec->cuva_addr;
+ cuva_count = ((size_reg_val >> 16) << 4) >> 1;
+ cuva_size = dec->cuva_size;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
+ __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
+ if (cuva_size > 0 && cuva_count > 0) {
+ if (pic->cuva_data_buf) {
+ unsigned char *p = pic->cuva_data_buf;
+ int len = 0;
+
+ for (i = 0; i < cuva_count; i += 4) {
+ int j;
+
+ for (j = 0; j < 4; j++) {
+ unsigned short aa = cuva_adr[i + 3 - j];
+ *p = aa & 0xff;
+ p++;
+ len++;
+ }
+ }
+ if (len > 0) {
+ pic->cuva_data_size = len;
+ }
+
+ if (pic->cuva_data_buf[0] == 0x26
+ && pic->cuva_data_buf[1] == 0x00
+ && pic->cuva_data_buf[2] == 0x04
+ && pic->cuva_data_buf[3] == 0x00
+ && pic->cuva_data_buf[4] == 0x05) {
+ dec->hdr_flag |= HDR_CUVA_MASK;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "cuva stream: (size %d)\n", pic->cuva_data_size);
+ } else {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ " other hdr stream (size %d)\n", pic->cuva_data_size);
+ }
+
+ if (get_dbg_flag(dec) & AVS3_DBG_HDR_INFO) {
+ for (i = 0; i < pic->cuva_data_size; i++) {
+ pr_info("%02x ", pic->cuva_data_buf[i]);
+ if (((i + 1) & 0xf) == 0)
+ pr_info("\n");
+ }
+ pr_info("\n");
+ }
+
+ } else {
+ avs3_print(dec, 0, "cuva_data_buf NULL\n");
+ }
+ }
+}
+
+static void release_cuva_data(struct avs3_frame_s *pic)
+{
+ pic->cuva_data_size = 0;
+}
+
+static void avs3_config_work_space_hw(struct AVS3Decoder_s *dec)
+{
+ DEC_CTX * ctx = &dec->avs3_dec.ctx;
+ struct BuffInfo_s *buf_spec = dec->work_space_buf;
+ u32 width = dec->avs3_dec.img.width ? dec->avs3_dec.img.width : dec->init_pic_w;
+ u32 height = dec->avs3_dec.img.height ? dec->avs3_dec.img.height : dec->init_pic_h;
+ u8 is_bit_depth_10 = (ctx->info.bit_depth_internal == 8) ? 0 : 1;
+
+#ifdef LOSLESS_COMPRESS_MODE
+ int losless_comp_header_size = compute_losless_comp_header_size(
+ dec, width, height);
+ int losless_comp_body_size = compute_losless_comp_body_size(
+ dec, width, height, is_bit_depth_10);
+#endif
+#ifdef AVS3_10B_MMU
+ unsigned int data32;
+#endif
+ if (debug && dec->init_flag == 0)
+ avs3_print(dec, 0,
+ "%s %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
+ __func__,
+ buf_spec->ipp.buf_start,
+ buf_spec->start_adr,
+ buf_spec->short_term_rps.buf_start,
+ buf_spec->rcs.buf_start,
+ buf_spec->sps.buf_start,
+ buf_spec->pps.buf_start,
+ buf_spec->sao_up.buf_start,
+ buf_spec->swap_buf.buf_start,
+ buf_spec->swap_buf2.buf_start,
+ buf_spec->scalelut.buf_start,
+ buf_spec->dblk_para.buf_start,
+ buf_spec->dblk_data.buf_start,
+ buf_spec->dblk_data2.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start);
+ if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0)
+ WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+ WRITE_VREG(AVS3_ALF_SWAP_BUFFER, buf_spec->short_term_rps.buf_start);
+ WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
+ //WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
+ //WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
+ WRITE_VREG(AVS3_SBAC_TOP_BUFFER, buf_spec->sbac_top.buf_start);
+ //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+#ifdef AVS3_10B_MMU
+ WRITE_VREG(AVS3_MMU_MAP_BUFFER, dec->frame_mmu_map_phy_addr);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
+#endif
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
+ WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
+ }
+#endif
+ WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
+ WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
+#ifndef FOR_S5
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
+ WRITE_VREG(HEVC_DBLK_CFG3, 0x404010); //default value
+ else
+ WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); // make left storage 2 x 4k]
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "HEVC_DBLK_CFG3 = %x\n", READ_VREG(HEVC_DBLK_CFG3));
+ }
+#endif
+ /* cfg_p_addr */
+ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
+ /* cfg_d_addr */
+ WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
+
+ WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
+
+#ifdef LOSLESS_COMPRESS_MODE
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+#if 1
+ data32 &= ~(1<<9);
+#else
+ if (params->p.bit_depth != 0x00)
+ data32 &= ~(1<<9);
+ else
+ data32 |= (1<<9);
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+#ifdef AVS3_10B_MMU
+ /*bit[4] : paged_mem_mode*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0);
+#else
+ /* bit[3] smem mode*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3));
+
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
+#endif
+ /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));*/
+ /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
+/*8-bit mode */
+ WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
+#else
+#ifdef P010_ENABLE
+ if (get_double_write_mode(dec) & 0x10) {
+ if (is_dw_p010(dec)) {
+ /* Enable P010 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+ (0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+ } else {
+ /* Enable NV21 reference read mode for MC */
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+ }
+ }
+#endif
+#endif
+
+#ifdef AVS3_10B_MMU
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start
+ + VBH_BUF_SIZE(buf_spec));
+ /*data32 = READ_VREG(HEVC_SAO_CTRL9);*/
+ /*data32 |= 0x1;*/
+ /*WRITE_VREG(HEVC_SAO_CTRL9, data32);*/
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<10);
+#if 0
+ if (debug & AVS3_DBG_FORCE_UNCOMPRESS)
+ data32 |= 0x80;
+#endif
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ u32 data_tmp;
+ data_tmp = READ_VREG(HEVC_SAO_CTRL9);
+ data_tmp |= (1<<10);
+ WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
+
+ WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size);
+ WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size);
+
+ WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
+ WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec));
+
+ /* use HEVC_CM_HEADER_START_ADDR */
+ data32 = READ_VREG(HEVC_SAO_CTRL5);
+ data32 |= (1<<15);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
+ }
+#endif
+
+ WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+
+#ifdef CO_MV_COMPRESS
+ //if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1 << 1);
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+ //}
+#endif
+ data32 = READ_VREG(HEVC_MPRED_CTRL4);
+ data32 |= (1<<26); //enable AVS3 mode
+ WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+}
+
+static void decomp_perfcount_reset(void)
+{
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("[cache_util.c] Entered decomp_perfcount_reset...\n");
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
+ return;
+}
+
+static void mcrcc_perfcount_reset(void)
+{
+ if (debug & AVS3_DBG_CACHE)
+ pr_info("[cache_util.c] Entered mcrcc_perfcount_reset...\n");
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
+ WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
+ return;
+}
+
+#ifdef TMP_DEBUG
+
+static void avs2_init_decoder_hw(struct AVS3Decoder_s *dec)
+{
+ unsigned int data32;
+ unsigned int decode_mode;
+ int i;
+
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+ /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+ data32 &= ~(7 << 29);
+ data32 |= (3 << 29);
+
+ data32 = data32 |
+ (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
+ (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
+ (1 << 7) |/*dec_done_int_cpu_enable*/
+ (1 << 4) |/*startcode_found_int_cpu_enable*/
+ (0 << 3) |/*startcode_found_int_amrisc_enable*/
+ (1 << 0); /*parser_int_enable*/
+
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STATUS);
+ data32 = data32 |
+ (0 << 1) |/*emulation_check_off VP9
+ do not have emulation*/
+ (1 << 0);/*startcode_check_on*/
+
+ WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+ WRITE_VREG(HEVC_SHIFT_CONTROL,
+ (6 << 20) | /* emu_push_bits (6-bits for AVS2)*/
+ (0 << 19) | /* emu_3_enable, maybe turned on in microcode*/
+ (0 << 18) | /* emu_2_enable, maybe turned on in microcode*/
+ (0 << 17) | /* emu_1_enable, maybe turned on in microcode*/
+ (0 << 16) | /* emu_0_enable, maybe turned on in microcode*/
+ (0 << 14) | /*disable_start_code_protect*/
+ (3 << 6) | /* sft_valid_wr_position*/
+ (2 << 4) | /* emulate_code_length_sub_1*/
+ (2 << 1) | /* start_code_length_sub_1*/
+ (1 << 0)); /* stream_shift_enable*/
+
+ WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
+ (0 << 30) | /*data_protect_fill_00_enable*/
+ (1 << 29)); /*data_protect_fill_ff_enable*/
+
+ WRITE_VREG(HEVC_CABAC_CONTROL, (1 << 0));/*cabac_enable*/
+
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0));/* hevc_parser_core_clk_en*/
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
+
+ /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/
+ if (is_rdma_enable())
+ rdma_back_end_work(dec->rdma_phy_adr, RDMA_SIZE);
+ else {
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+ }
+
+#ifdef ENABLE_SWAP_TEST
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+#endif
+ if (!dec->m_ins_flag)
+ decode_mode = DECODE_MODE_SINGLE;
+ else if (vdec_frame_based(hw_to_vdec(dec)))
+ decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
+ else
+ decode_mode = DECODE_MODE_MULTI_STREAMBASE;
+ dec->start_decoding_flag = 3;
+ decode_mode |= (dec->start_decoding_flag << 16);
+
+ WRITE_VREG(DECODE_MODE, decode_mode);
+ WRITE_VREG(HEVC_DECODE_SIZE, 0);
+ WRITE_VREG(HEVC_DECODE_COUNT, 0);
+#ifdef DYN_CACHE
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+ }
+#endif
+
+ /*Send parser_cmd*/
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
+ for (i = 0; i < PARSER_CMD_NUMBER; i++)
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
+
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ (1 << 9) | /* parser_alf_if_en*/
+ /* (1 << 8) |*/ /*sao_sw_pred_enable*/
+ (1 << 5) | /*parser_sao_if_en*/
+ (1 << 2) | /*parser_mpred_if_en*/
+ (1 << 0) /*parser_scaler_if_en*/
+ );
+
+#ifdef MULTI_INSTANCE_SUPPORT
+ WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+ WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+ for (i = 0; i < 8; i++)
+ data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
+
+ WRITE_VREG(DOS_SW_RESET3, (1<<18)); /* reset mpred */
+ WRITE_VREG(DOS_SW_RESET3, 0);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+#endif
+
+ return;
+}
+
+#else
+static
+#endif
+void avs3_init_decoder_hw(struct AVS3Decoder_s *dec)
+{
+ unsigned int data32;
+ unsigned int decode_mode;
+ int i;
+ /*if (debug & AVS3_DBG_BUFMGR_MORE)
+ pr_info("%s\n", __func__);*/
+ data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+#if 1
+ /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+ data32 &= ~(7 << 29);
+ data32 |= (3 << 29);
+#endif
+ data32 = data32 |
+ (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
+ (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
+ (1 << 7) |/*dec_done_int_cpu_enable*/
+ (1 << 4) |/*startcode_found_int_cpu_enable*/
+ (0 << 3) |/*startcode_found_int_amrisc_enable*/
+ (1 << 0) /*parser_int_enable*/
+ ;
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
+
+ data32 = READ_VREG(HEVC_SHIFT_STATUS);
+ data32 = data32 |
+ (0 << 1) |/*emulation_check_off VP9
+ do not have emulation*/
+ (1 << 0)/*startcode_check_on*/
+ ;
+ WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+ WRITE_VREG(HEVC_SHIFT_CONTROL,
+ (6 << 20) | /* emu_push_bits (6-bits for AVS3)*/
+ (0 << 19) | /* emu_3_enable, maybe turned on in microcode*/
+ (0 << 18) | /* emu_2_enable, maybe turned on in microcode*/
+ (0 << 17) | /* emu_1_enable, maybe turned on in microcode*/
+ (0 << 16) | /* emu_0_enable, maybe turned on in microcode*/
+ (0 << 14) | /*disable_start_code_protect*/
+ (3 << 6) | /* sft_valid_wr_position*/
+ (2 << 4) | /* emulate_code_length_sub_1*/
+ (2 << 1) | /* start_code_length_sub_1*/
+ (1 << 0) /* stream_shift_enable*/
+ );
+
+ WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
+ (0 << 30) | /*data_protect_fill_00_enable*/
+ (1 << 29) /*data_protect_fill_ff_enable*/
+ );
+ WRITE_VREG(HEVC_CABAC_CONTROL,
+ (1 << 0)/*cabac_enable*/
+ );
+
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
+ (1 << 0)/* hevc_parser_core_clk_en*/
+ );
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
+
+ /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/
+ if (is_rdma_enable())
+ rdma_back_end_work(dec->rdma_phy_adr, RDMA_SIZE);
+ else {
+ if ((debug & AVS3_DBG_DISABLE_IQIT_SCALELUT_INIT) == 0) {
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+ }
+ }
+
+#ifdef ENABLE_SWAP_TEST
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+#else
+ WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+#endif
+ if (!dec->m_ins_flag)
+ decode_mode = DECODE_MODE_SINGLE;
+ else if (vdec_frame_based(hw_to_vdec(dec)))
+ decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
+ else
+ decode_mode = DECODE_MODE_MULTI_STREAMBASE;
+ if (dec->avs3_dec.bufmgr_error_flag &&
+ (error_handle_policy & 0x1)) {
+ dec->bufmgr_error_count++;
+ dec->avs3_dec.bufmgr_error_flag = 0;
+ if (dec->bufmgr_error_count >
+ (re_search_seq_threshold & 0xff)
+ && dec->frame_count >
+ ((re_search_seq_threshold >> 8) & 0xff)) {
+ //struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ dec->start_decoding_flag = 0;
+ //avs3_dec->hd.vec_flag = 1;
+ dec->skip_PB_before_I = 1;
+ avs3_print(dec, 0,
+ "!!Bufmgr error, search seq again (0x%x %d %d)\n",
+ error_handle_policy,
+ dec->frame_count,
+ dec->bufmgr_error_count);
+ dec->bufmgr_error_count = 0;
+ }
+ }
+#ifdef FOR_S5
+ /*to do..*/
+ dec->start_decoding_flag = 3;
+#endif
+ decode_mode |= (dec->start_decoding_flag << 16);
+ WRITE_VREG(DECODE_MODE, decode_mode);
+ WRITE_VREG(HEVC_DECODE_SIZE, 0);
+ WRITE_VREG(HEVC_DECODE_COUNT, 0);
+#ifdef DYN_CACHE
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+ WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc}
+ }
+#endif
+ /*Send parser_cmd*/
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
+ for (i = 0; i < PARSER_CMD_NUMBER; i++)
+ WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
+ WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
+
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ (1 << 9) | /* parser_alf_if_en*/
+ /* (1 << 8) |*/ /*sao_sw_pred_enable*/
+ (1 << 5) | /*parser_sao_if_en*/
+ (1 << 2) | /*parser_mpred_if_en*/
+ (1 << 0) /*parser_scaler_if_en*/
+ );
+
+#if 0 //def MULTI_INSTANCE_SUPPORT
+ WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+ WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+ for (i = 0; i < 8; i++)
+ data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
+
+ WRITE_VREG(DOS_SW_RESET3, (1<<18)); /* reset mpred */
+ WRITE_VREG(DOS_SW_RESET3, 0);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+ WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
+#endif
+ /*End of Multi-instance*/
+ /*Changed to Start MPRED in microcode*/
+ /*
+ pr_info("[test.c] Start MPRED\n");
+ WRITE_VREG(HEVC_MPRED_INT_STATUS,
+ (1<<31)
+ );
+ */
+
+ /*AVS3 default seq_wq_matrix config*/
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "Config AVS3 default seq_wq_matrix ...\n");
+ /*4x4*/
+ /* default seq_wq_matrix_4x4 begin address*/
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64);
+ for (i = 0; i < 16; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ /*8x8*/
+ /*default seq_wq_matrix_8x8 begin address*/
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);
+ for (i = 0; i < 64; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (0 << 1) | /*enable ipp*/
+ (1 << 0) /*software reset ipp and mpp*/
+ );
+ WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+ (1 << 1) | /*enable ipp*/
+ (0 << 0) /*software reset ipp and mpp*/
+ );
+#if 0
+/*AVS3_10B_NV21*/
+ /*Enable NV21 reference read mode for MC*/
+ WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+#endif
+ /* Init dblk*/
+ data32 = READ_VREG(HEVC_DBLK_CFGB);
+ data32 |= (5 << 0);
+ /* [3:0] cfg_video_type -> AVS3*/
+#ifndef FOR_S5
+ data32 &= (~0x300); /*[8]:first write enable (compress)
+ [9]:double write enable (uncompress)*/
+ if (get_double_write_mode(dec) == 0)
+ data32 |= (0x1 << 8); /*enable first write*/
+ else if (get_double_write_mode(dec) == 0x10)
+ data32 |= (0x1 << 9); /*double write only*/
+ else
+ data32 |= ((0x1 << 8) | (0x1 << 9));
+#endif
+ WRITE_VREG(HEVC_DBLK_CFGB, data32);
+
+ WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); /* [0] rst_sync*/
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "Bitstream level Init for DBLK .Done.\n");
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ mcrcc_perfcount_reset();
+ decomp_perfcount_reset();
+ }
+
+ return;
+}
+
+#ifdef CONFIG_HEVC_CLK_FORCED_ON
+static void config_avs3_clk_forced_on(void)
+{
+ unsigned int rdata32;
+ /*IQIT*/
+ rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
+ WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
+
+ /* DBLK*/
+ rdata32 = READ_VREG(HEVC_DBLK_CFG0);
+ WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
+
+ /* SAO*/
+ rdata32 = READ_VREG(HEVC_SAO_CTRL1);
+ WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
+
+ /*MPRED*/
+ rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
+ WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
+
+ /* PARSER*/
+ rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
+ WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
+ WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
+ WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
+ rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
+ WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+ WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
+ rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
+ WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+ rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1));
+
+ /*IPP*/
+ rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
+ WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
+
+ /* MCRCC*/
+ rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
+ WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
+}
+#endif
+
+static struct AVS3Decoder_s gAVS3Decoder;
+
+static void avs3_local_uninit(struct AVS3Decoder_s *dec)
+{
+ dec->rpm_ptr = NULL;
+ dec->lmem_ptr = NULL;
+ if (dec->rpm_addr) {
+ decoder_dma_free_coherent(dec->rpm_mem_handle,
+ RPM_BUF_SIZE, dec->rpm_addr,
+ dec->rpm_phy_addr);
+ dec->rpm_addr = NULL;
+ }
+
+ if (dec->cuva_addr) {
+ decoder_dma_free_coherent(dec->cuva_handle,
+ dec->cuva_size, dec->cuva_addr,
+ dec->cuva_phy_addr);
+ dec->cuva_addr = NULL;
+ }
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+ if (dec->ucode_log_addr) {
+ decoder_dma_free_coherent(dec->ucode_log_handle,
+ UCODE_LOG_BUF_SIZE, dec->ucode_log_addr,
+ dec->ucode_log_phy_addr);
+ dec->ucode_log_addr = NULL;
+ }
+#endif
+ if (dec->lmem_addr) {
+ if (dec->lmem_phy_addr)
+ decoder_dma_free_coherent(dec->lmem_phy_handle,
+ LMEM_BUF_SIZE, dec->lmem_addr,
+ dec->lmem_phy_addr);
+ dec->lmem_addr = NULL;
+ }
+
+#ifdef AVS3_10B_MMU
+ if (dec->frame_mmu_map_addr) {
+ if (dec->frame_mmu_map_phy_addr)
+ decoder_dma_free_coherent(dec->frame_mmu_map_handle,
+ get_frame_mmu_map_size(), dec->frame_mmu_map_addr,
+ dec->frame_mmu_map_phy_addr);
+ dec->frame_mmu_map_addr = NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (dec->frame_mmu_map_phy_addr_1)
+ decoder_dma_free_coherent(dec->frame_mmu_map_handle_1,
+ get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+ dec->frame_mmu_map_phy_addr_1);
+
+ dec->frame_mmu_map_addr_1 = NULL;
+ }
+#endif
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_frame_mmu_map_addr) {
+ if (dec->dw_frame_mmu_map_phy_addr)
+ decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
+ get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr,
+ dec->dw_frame_mmu_map_phy_addr);
+ dec->dw_frame_mmu_map_addr = NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && dec->dw_frame_mmu_map_addr_1) {
+ if (dec->dw_frame_mmu_map_phy_addr_1)
+ decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle_1,
+ get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr_1,
+ dec->dw_frame_mmu_map_phy_addr_1);
+
+ dec->dw_frame_mmu_map_addr_1 = NULL;
+ }
+#endif
+#endif
+
+ if (dec->gvs)
+ vfree(dec->gvs);
+ dec->gvs = NULL;
+}
+
+static int avs3_local_init(struct AVS3Decoder_s *dec)
+{
+ int ret = -1;
+ /*int losless_comp_header_size, losless_comp_body_size;*/
+
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct BuffInfo_s *cur_buf_info = NULL;
+ unsigned bufspec_index = 0;
+ cur_buf_info = &dec->work_space_buf_store;
+ if (force_bufspec) {
+ bufspec_index = force_bufspec & 0xf;
+ pr_info("force buffer spec %d\n", force_bufspec & 0xf);
+ } else {
+ if (vdec_is_support_4k()) {
+ bufspec_index = 2; /* 8k */
+ } else
+ bufspec_index = 0;/* 1080p */
+ }
+ pr_info("buffer spec %d\n", bufspec_index);
+ memcpy(cur_buf_info, &amvavs3_workbuff_spec[bufspec_index],
+ sizeof(struct BuffInfo_s));
+
+ cur_buf_info->start_adr = dec->buf_start;
+#ifndef AVS3_10B_MMU
+ dec->mc_buf_spec.buf_end = dec->buf_start + dec->buf_size;
+#endif
+
+ init_buff_spec(dec, cur_buf_info);
+
+ avs3_bufmgr_init(&dec->avs3_dec);
+ //init_avs3_decoder(&dec->avs3_dec);
+
+#ifdef AVS3_10B_MMU
+ avs3_dec_init(dec, cur_buf_info, NULL);
+#else
+ dec->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff)
+ & (~0xffff);
+ dec->mc_buf_spec.buf_size = (dec->mc_buf_spec.buf_end
+ - dec->mc_buf_spec.buf_start);
+ if (debug) {
+ pr_err("dec->mc_buf_spec.buf_start %x-%x\n",
+ dec->mc_buf_spec.buf_start,
+ dec->mc_buf_spec.buf_start +
+ dec->mc_buf_spec.buf_size);
+ }
+ avs3_dec_init(dec, cur_buf_info, &dec->mc_buf_spec);
+#endif
+ if ((buf_alloc_width & buf_alloc_height) == 0) {
+ if (!vdec_is_support_4k()
+ && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
+ buf_alloc_width = 1920;
+ buf_alloc_height = 1088;
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ buf_alloc_width = 3840;
+ buf_alloc_height = 2160;
+ }
+ }
+
+ dec->init_pic_w = buf_alloc_width ? buf_alloc_width :
+ (dec->vavs3_amstream_dec_info.width ?
+ dec->vavs3_amstream_dec_info.width :
+ dec->work_space_buf->max_width);
+ dec->init_pic_h = buf_alloc_height ? buf_alloc_height :
+ (dec->vavs3_amstream_dec_info.height ?
+ dec->vavs3_amstream_dec_info.height :
+ dec->work_space_buf->max_height);
+
+ pr_info(
+ "init_pic_w %d init_pic_h %d\n", dec->init_pic_w, dec->init_pic_h);
+
+#ifndef AVS3_10B_MMU
+ init_buf_list(dec);
+#else
+ dec->avs3_dec.max_pb_size = max_buf_num + dec->dynamic_buf_margin;
+ if (dec->avs3_dec.max_pb_size > MAX_PB_SIZE)
+ dec->avs3_dec.max_pb_size = MAX_PB_SIZE;
+#endif
+ //dec->avs3_dec.ref_maxbuffer = MAX_PB_SIZE; //dec->used_buf_num - 1;
+ /*init_pic_list(dec);*/
+
+ pts_unstable = ((unsigned long)(dec->vavs3_amstream_dec_info.param)
+ & 0x40) >> 6;
+
+ if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+ dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
+ RPM_BUF_SIZE,
+ &dec->rpm_phy_addr, "AVS3_RPM_BUF");
+ if (dec->rpm_addr == NULL) {
+ pr_err("%s: failed to alloc rpm buffer\n", __func__);
+ return -1;
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "rpm_phy_addr %x\n", (u32) dec->rpm_phy_addr);
+ dec->rpm_ptr = dec->rpm_addr;
+ }
+
+ if (cuva_buf_size > 0) {
+ dec->cuva_size = AUX_BUF_ALIGN(cuva_buf_size);
+
+ dec->cuva_addr = decoder_dma_alloc_coherent(&dec->cuva_handle,
+ dec->cuva_size, &dec->cuva_phy_addr, "AVS3_CUVA_BUF");
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s, cuva_size = %d cuva_phy_addr %x dec->cuva_addr = %px\n",
+ __func__, dec->cuva_size, (u32)dec->cuva_phy_addr, dec->cuva_addr);
+ if (dec->cuva_addr == NULL) {
+ pr_err("%s: failed to alloc cuva buffer\n", __func__);
+ return -1;
+ }
+ }
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+ //if (udebug_flag & 0x8) {
+ dec->ucode_log_addr = decoder_dma_alloc_coherent(&dec->ucode_log_handle,
+ UCODE_LOG_BUF_SIZE, &dec->ucode_log_phy_addr, "AVS3_UCODE_LOG_BUF");
+ if (dec->ucode_log_addr == NULL) {
+ dec->ucode_log_phy_addr = 0;
+ }
+ pr_info("%s: alloc ucode log buffer %p\n",
+ __func__, dec->ucode_log_addr);
+ //}
+#endif
+ dec->lmem_addr = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
+ LMEM_BUF_SIZE,
+ &dec->lmem_phy_addr, "AVS3_LMEM_BUF");
+ if (dec->lmem_addr == NULL) {
+ pr_err("%s: failed to alloc lmem buffer\n", __func__);
+ return -1;
+ } else
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s, lmem_phy_addr %x\n",
+ __func__, (u32)dec->lmem_phy_addr);
+ dec->lmem_ptr = dec->lmem_addr;
+
+#ifdef AVS3_10B_MMU
+ if (dec->mmu_enable) {
+ dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
+ get_frame_mmu_map_size(),
+ &dec->frame_mmu_map_phy_addr, "AVS3_MMU_BUF");
+ if (dec->frame_mmu_map_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->frame_mmu_map_addr, 0, get_frame_mmu_map_size());
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && dec->frame_mmu_map_addr_1 == NULL) {
+ dec->frame_mmu_map_addr_1 =
+ decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle_1,
+ get_frame_mmu_map_size(),
+ &dec->frame_mmu_map_phy_addr_1, "AVS3_MMU_1_BUF");
+ if (dec->frame_mmu_map_addr_1 == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+ }
+#endif
+ }
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
+ get_frame_mmu_map_size(),
+ &dec->dw_frame_mmu_map_phy_addr, "AVS3_DWMMU_BUF");
+ if (dec->dw_frame_mmu_map_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->dw_frame_mmu_map_addr, 0, get_frame_mmu_map_size());
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->dw_frame_mmu_map_addr_1 =
+ decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle_1,
+ get_frame_mmu_map_size(),
+ &dec->dw_frame_mmu_map_phy_addr_1, "AVS3_DWMMU_1_BUF");
+ if (dec->dw_frame_mmu_map_addr_1 == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(dec->dw_frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+ }
+#endif
+ }
+#endif
+#ifdef NEW_FB_CODE
+ avs3_dec->wait_working_buf = 0;
+ avs3_dec->front_pause_flag = 0; /*multi pictures in one packe*/
+ if (dec->front_back_mode) {
+ avs3_dec->frontend_decoded_count = 0;
+ avs3_dec->backend_decoded_count = 0;
+ avs3_dec->fb_wr_pos = 0;
+ avs3_dec->fb_rd_pos = 0;
+ init_fb_bufstate(dec);
+ if (fbdebug_flag & 0x4) {
+ copy_loopbufs_ptr(&avs3_dec->init_fr, &avs3_dec->fr);
+ }
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "copy loopbuf fr to next_bk[fb_wr_pos=%d]\n",avs3_dec->fb_wr_pos);
+ copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+ }
+#endif
+ ret = 0;
+ return ret;
+}
+
+/********************************************
+ * Mailbox command
+ ********************************************/
+#define CMD_FINISHED 0
+#define CMD_ALLOC_VIEW 1
+#define CMD_FRAME_DISPLAY 3
+#define CMD_DEBUG 10
+
+#define DECODE_BUFFER_NUM_MAX 32
+#define DISPLAY_BUFFER_NUM 6
+
+#define video_domain_addr(adr) (adr&0x7fffffff)
+#define DECODER_WORK_SPACE_SIZE 0x800000
+
+#define spec2canvas(x) \
+ (((x)->uv_canvas_index << 16) | \
+ ((x)->uv_canvas_index << 8) | \
+ ((x)->y_canvas_index << 0))
+
+static void set_canvas(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic)
+{
+ int canvas_w = ALIGN(pic->width, 64)/4;
+ int canvas_h = ALIGN(pic->height, 32)/4;
+ int blkmode = mem_map_mode;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ /*CANVAS_BLKMODE_64X32*/
+ if (pic->double_write_mode) {
+ canvas_w = pic->width /
+ get_double_write_ratio(pic->double_write_mode);
+ canvas_h = pic->height /
+ get_double_write_ratio(pic->double_write_mode);
+ /*sao_crtl1 aligned with 64*/
+ canvas_w = ALIGN(canvas_w, 64);
+ canvas_h = ALIGN(canvas_h, 32);
+
+ if (vdec->parallel_dec == 1) {
+ if (pic->y_canvas_index == -1)
+ pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->uv_canvas_index == -1)
+ pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->y_canvas_index = 128 + pic->index * 2;
+ pic->uv_canvas_index = 128 + pic->index * 2 + 1;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->dw_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index,
+ pic->dw_u_v_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+#ifdef MULTI_INSTANCE_SUPPORT
+ pic->canvas_config[0].phy_addr = pic->dw_y_adr;
+ pic->canvas_config[0].width = canvas_w;
+ pic->canvas_config[0].height = canvas_h;
+ pic->canvas_config[0].block_mode = blkmode;
+ pic->canvas_config[0].endian = 7;
+ pic->canvas_config[0].bit_depth = is_dw_p010(dec);
+
+ pic->canvas_config[1].phy_addr = pic->dw_u_v_adr;
+ pic->canvas_config[1].width = canvas_w;
+ pic->canvas_config[1].height = canvas_h;
+ pic->canvas_config[1].block_mode = blkmode;
+ pic->canvas_config[1].endian = 7;
+ pic->canvas_config[1].bit_depth = is_dw_p010(dec);
+
+ decoder_trace(dec->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr, TRACE_BUFFER);
+#endif
+ } else {
+ #ifndef AVS3_10B_MMU
+ if (vdec->parallel_dec == 1) {
+ if (pic->y_canvas_index == -1)
+ pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->uv_canvas_index == -1)
+ pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->y_canvas_index = 128 + pic->index;
+ pic->uv_canvas_index = 128 + pic->index;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->mc_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index,
+ pic->mc_u_v_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+
+ decoder_trace(dec->trace.set_canvas0_addr, spec2canvas(pic), TRACE_BUFFER);
+ #endif
+ }
+
+#ifdef OW_TRIPLE_WRITE
+ if (pic->triple_write_mode) {
+ canvas_w = pic->width /
+ get_double_write_ratio(pic->triple_write_mode & 0xf); //same ratio with double write
+ canvas_h = pic->height /
+ get_double_write_ratio(pic->triple_write_mode & 0xf);
+
+ canvas_w = ALIGN(canvas_w, 64);
+ canvas_h = ALIGN(canvas_h, 32);
+
+#if 0
+ if (vdec->parallel_dec == 1) {
+ if (pic->tw_y_canvas_index == -1)
+ pic->tw_y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ if (pic->tw_uv_canvas_index == -1)
+ pic->tw_uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+ } else {
+ pic->tw_y_canvas_index = 128 + pic->index * 2;
+ pic->tw_uv_canvas_index = 128 + pic->index * 2 + 1;
+ }
+
+ config_cav_lut_ex(pic->y_canvas_index,
+ pic->dw_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+ config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
+ canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+#endif
+ pic->tw_canvas_config[0].phy_addr = pic->tw_y_adr;
+ pic->tw_canvas_config[0].width = canvas_w;
+ pic->tw_canvas_config[0].height = canvas_h;
+ pic->tw_canvas_config[0].block_mode = blkmode;
+ pic->tw_canvas_config[0].endian = 7;
+ pic->tw_canvas_config[0].bit_depth = is_tw_p010(dec);
+
+ pic->tw_canvas_config[1].phy_addr = pic->tw_u_v_adr;
+ pic->tw_canvas_config[1].width = canvas_w;
+ pic->tw_canvas_config[1].height = canvas_h;
+ pic->tw_canvas_config[1].block_mode = blkmode;
+ pic->tw_canvas_config[1].endian = 7;
+ pic->tw_canvas_config[1].bit_depth = is_tw_p010(dec);
+ }
+#endif
+}
+
+static void set_frame_info(struct AVS3Decoder_s *dec, struct vframe_s *vf)
+{
+ unsigned int ar = 0;
+ unsigned int pixel_ratio = 0;;
+
+ vf->duration = dec->frame_dur;
+ vf->duration_pulldown = 0;
+ vf->flag = 0;
+ vf->prop.master_display_colour = dec->vf_dp;
+ if (dec->hdr_flag & HDR_CUVA_MASK)
+ dec->video_signal_type |= 1 << 31;
+ vf->signal_type = dec->video_signal_type;
+
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "signal_type 0x%x \n",
+ vf->signal_type);
+
+ pixel_ratio = dec->vavs3_amstream_dec_info.ratio;
+
+ if (dec->vavs3_ratio == 0) {
+ /* always stretch to 16:9 */
+ vf->ratio_control |= (0x90 <<
+ DISP_RATIO_ASPECT_RATIO_BIT);
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ } else {
+ switch (pixel_ratio) {
+ case 1:
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ ar = (vf->height * dec->vavs3_ratio) / vf->width;
+ break;
+ case 2:
+ vf->sar_width = 4;
+ vf->sar_height = 3;
+ ar = (vf->height * 3 * dec->vavs3_ratio) / (vf->width * 4);
+ break;
+ case 3:
+ vf->sar_width = 16;
+ vf->sar_height = 9;
+ ar = (vf->height * 9 * dec->vavs3_ratio) / (vf->width * 16);
+ break;
+ case 4:
+ vf->sar_width = 221;
+ vf->sar_height = 100;
+ ar = (vf->height * 100 * dec->vavs3_ratio) / (vf->width *
+ 221);
+ break;
+ default:
+ vf->sar_width = 1;
+ vf->sar_height = 1;
+ ar = (vf->height * dec->vavs3_ratio) / vf->width;
+ break;
+ }
+ }
+
+ ar = min_t(u32, ar, DISP_RATIO_ASPECT_RATIO_MAX);
+ vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
+
+ vf->sidebind_type = dec->sidebind_type;
+ vf->sidebind_channel_id = dec->sidebind_channel_id;
+ vf->codec_vfmt = VFORMAT_AVS3;
+
+ return;
+}
+
+static int vavs3_vf_states(struct vframe_states *states, void *op_arg)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+
+ states->vf_pool_size = VF_POOL_SIZE;
+ states->buf_free_num = kfifo_len(&dec->newframe_q);
+ states->buf_avail_num = kfifo_len(&dec->display_q);
+
+ if (step == 2)
+ states->buf_avail_num = 0;
+ return 0;
+}
+
+static struct vframe_s *vavs3_vf_peek(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+ if (step == 2)
+ return NULL;
+
+ if (force_disp_pic_index & 0x100) {
+ if (force_disp_pic_index & 0x200)
+ return NULL;
+ return &dec->vframe_dummy;
+ }
+
+ if (kfifo_len(&dec->display_q) > VF_POOL_SIZE) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "kfifo len:%d invalid, peek error\n",
+ kfifo_len(&dec->display_q));
+ return NULL;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ struct vframe_s *vf_tmp;
+ if (kfifo_peek(&dec->display_q, &vf_tmp) && vf_tmp) {
+ uint8_t index = vf_tmp->index & 0xff;
+ struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+ if ((pic == NULL) || (!pic->back_done_mark)) {
+ return NULL;
+ }
+ } else
+ return NULL;
+ }
+#endif
+
+ if (kfifo_peek(&dec->display_q, &vf)) {
+ return vf;
+ }
+
+ return NULL;
+}
+
+static struct avs3_frame_s *get_pic_by_index(
+ struct AVS3Decoder_s *dec, int index)
+{
+ struct avs3_frame_s *pic = NULL;
+
+ if ((index >= 0) && (index < dec->avs3_dec.max_pb_size))
+ pic = &dec->avs3_dec.pic_pool[index].buf_cfg;
+ return pic;
+}
+
+static void update_vf_memhandle(struct AVS3Decoder_s *dec,
+ struct vframe_s *vf, struct avs3_frame_s *pic)
+{
+ vf->mem_handle = NULL;
+ vf->mem_handle_1 = NULL;
+ vf->mem_head_handle = NULL;
+ vf->mem_dw_handle = NULL;
+
+#ifdef AVS3_10B_MMU
+ if (vf->type & VIDTYPE_SCATTER) {
+#ifdef AVS3_10B_MMU_DW
+ if (pic->double_write_mode & 0x20) {
+ vf->mem_handle =
+ decoder_mmu_box_get_mem_handle(
+ dec->dw_mmu_box, pic->index);
+ if (dec->front_back_mode)
+ vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->dw_mmu_box_1, pic->index);
+ vf->mem_head_handle =
+ decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->BUF_index));
+ vf->mem_dw_handle = NULL;
+ } else
+#endif
+ {
+ vf->mem_handle = decoder_mmu_box_get_mem_handle(
+ dec->mmu_box,
+ pic->index);
+ if (dec->front_back_mode)
+ vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->mmu_box_1, pic->index);
+ vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->index));
+ if (dec->double_write_mode == 3)
+ vf->mem_dw_handle =
+ decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->BUF_index));
+ else
+ vf->mem_dw_handle = NULL;
+ }
+ } else {
+ vf->mem_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->index));
+ vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->index));
+ }
+#else
+ vf->mem_handle = decoder_bmmu_box_get_mem_handle(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->index));
+#endif
+}
+
+static void fill_frame_info(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic, unsigned int framesize, unsigned int pts);
+
+static struct vframe_s *vavs3_vf_get(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+ unsigned long flags = 0;
+
+ if (step == 2)
+ return NULL;
+ else if (step == 1)
+ step = 2;
+
+ if (force_disp_pic_index & 0x100) {
+ int idx = force_disp_pic_index & 0xff;
+ struct avs3_frame_s *pic = get_pic_by_index(dec, idx);
+
+ if (pic == NULL)
+ return NULL;
+ if (force_disp_pic_index & 0x200)
+ return NULL;
+
+ vf = &dec->vframe_dummy;
+
+ set_vframe(dec, vf, pic, 1);
+
+ force_disp_pic_index |= 0x200;
+ return vf;
+ }
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (kfifo_peek(&dec->display_q, &vf) && vf) {
+ uint8_t index = vf->index & 0xff;
+ struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+ if ((pic == NULL) || (!pic->back_done_mark)) {
+ return NULL;
+ }
+ } else
+ return NULL;
+ }
+#endif
+
+ lock_buffer(dec, flags);
+ if (kfifo_get(&dec->display_q, &vf)) {
+ uint8_t index = vf->index & 0xff;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ decoder_trace(dec->trace.vf_get_name, (long)vf, TRACE_BUFFER);
+ decoder_trace(dec->trace.disp_q_name, kfifo_len(&dec->display_q), TRACE_BUFFER);
+#ifdef MULTI_INSTANCE_SUPPORT
+ decoder_trace(dec->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr, TRACE_BUFFER);
+#else
+ decoder_trace(dec->trace.get_canvas0_addr, vf->canvas0Addr, TRACE_BUFFER);
+#endif
+
+ if (index < dec->avs3_dec.max_pb_size) {
+ struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+ if (pic == NULL &&
+ (debug & AVS3_DBG_PIC_LEAK)) {
+ int i;
+ avs3_print(dec, 0,
+ "%s error index 0x%x pic not exist\n",
+ __func__, index);
+ print_pic_pool(&dec->avs3_dec, "");
+ for (i = 0; i < 10; i++) {
+ pic = get_pic_by_index(dec, index);
+ pr_info("pic = %p\n", pic);
+ }
+
+ if (debug & AVS3_DBG_PIC_LEAK)
+ debug |= AVS3_DBG_PIC_LEAK_WAIT;
+ unlock_buffer(dec, flags);
+ return NULL;
+ }
+
+ vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+ vf->vf_ud_param.ud_param.buf_len = 0;
+ vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+ vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+ vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+ vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS3 << 3);
+ vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+ if (vf->pts)
+ vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+ vf->omx_index = dec->vf_get_count;
+ dec->vf_get_count++;
+ if (pic) {
+ if (dec->front_back_mode == 1) {
+ update_vf_memhandle(dec, vf, pic);
+ decoder_do_frame_check(hw_to_vdec(dec), vf);
+ }
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s vf %p pic %p index 0x%x getcount %d type 0x%x w/h/depth %d/%d/0x%x, compHeadAddr 0x%08x, pts %d, %lld\n",
+ __func__, vf, pic, index,
+ //pic->imgtr_fwRefDistance_bak,
+ dec->vf_get_count,
+ vf->type,
+ vf->width, vf->height,
+ vf->bitdepth,
+ vf->compHeadAddr,
+ vf->pts,
+ vf->pts_us64);
+ }
+
+ if (pic && (!(pic->error_mark) || !(error_handle_policy & 0x4))) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ fill_frame_info(dec, pic, 0, vf->pts);
+ vdec_fill_vdec_frame(vdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+ }
+#endif
+ unlock_buffer(dec, flags);
+ return vf;
+ }
+
+ dec->vf_get_count--;
+ dec->vf_pre_count--;
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s:get error pic from fifo\n", __func__);
+ unlock_buffer(dec, flags);
+ vavs3_vf_put(vf, dec);
+ return NULL;
+ }
+ }
+ unlock_buffer(dec, flags);
+ return NULL;
+}
+
+static void vavs3_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+ struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
+ uint8_t index;
+ unsigned long flags = 0;
+
+ if (vf == (&dec->vframe_dummy))
+ return;
+
+ if (!vf)
+ return;
+
+ decoder_trace(dec->trace.vf_put_name, (long)vf, TRACE_BUFFER);
+#ifdef MULTI_INSTANCE_SUPPORT
+ decoder_trace(dec->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr, TRACE_BUFFER);
+#else
+ decoder_trace(dec->trace.put_canvas0_addr, vf->canvas0Addr, TRACE_BUFFER);
+#endif
+
+ lock_buffer(dec, flags);
+ index = vf->index & 0xff;
+ kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+ decoder_trace(dec->trace.new_q_name, kfifo_len(&dec->newframe_q), TRACE_BUFFER);
+
+ if (index < dec->avs3_dec.max_pb_size) {
+ struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+ if (pic && pic->vf_ref > 0) {
+ pic->vf_ref--;
+ } else {
+ if (pic)
+ avs3_print(dec, 0,
+ "%s, error pic (index %d) vf_ref is %d\n",
+ __func__, index, pic->vf_ref);
+ else
+ avs3_print(dec, 0,
+ "%s, error pic (index %d) is NULL\n",
+ __func__, index);
+ }
+
+ if (pic && (!(pic->error_mark) || !(error_handle_policy & 0x4)))
+ dec->vf_put_count++;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s vf %p pic %p index 0x%x putcount %d\n",
+ __func__, vf, pic, vf->index & 0xff, dec->vf_put_count);
+
+ if (dec->wait_buf)
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ dec->last_put_idx = index;
+ dec->new_frame_displayed++;
+ }
+ unlock_buffer(dec, flags);
+
+#ifdef MULTI_INSTANCE_SUPPORT
+ vdec_up(vdec);
+#endif
+}
+
+static int vavs3_event_cb(int type, void *data, void *private_data)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)private_data;
+
+ if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
+ struct provider_state_req_s *req =
+ (struct provider_state_req_s *)data;
+ if (req->req_type == REQ_STATE_SECURE)
+ req->req_result[0] = vdec_secure(hw_to_vdec(dec));
+ else
+ req->req_result[0] = 0xffffffff;
+ } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
+ struct provider_aux_req_s *req =
+ (struct provider_aux_req_s *)data;
+ unsigned char index;
+ unsigned long flags;
+ struct avs3_frame_s *pic;
+
+ if (!req->vf) {
+ req->aux_size = dec->vf_put_count;
+ return 0;
+ }
+ lock_buffer(dec, flags);
+ index = req->vf->index & 0xff;
+ req->aux_buf = NULL;
+ req->aux_size = 0;
+ req->format = VFORMAT_AVS3;
+ if (index < dec->avs3_dec.max_pb_size) {
+ pic = get_pic_by_index(dec, index);
+ req->aux_buf = pic->cuva_data_buf;
+ req->aux_size = pic->cuva_data_size;
+ }
+ unlock_buffer(dec, flags);
+
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s pic 0x%p index %d =>size %d\n",
+ __func__, pic, index, req->aux_size);
+ }
+
+ return 0;
+}
+
+/*
+static struct avs3_frame_s *get_disp_pic(struct AVS3Decoder_s *dec)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic = NULL;
+ int32_t j;
+ int32_t pre_disp_count_min = 0x7fffffff;
+ for (j = 0; j < avs3_dec->ref_maxbuffer; j++) {
+ if (avs3_dec->fref[j]->to_prepare_disp &&
+ avs3_dec->fref[j]->to_prepare_disp <
+ pre_disp_count_min) {
+ pre_disp_count_min =
+ avs3_dec->fref[j]->to_prepare_disp;
+ pic = avs3_dec->fref[j];
+ }
+ }
+ if (pic)
+ pic->to_prepare_disp = 0;
+
+ return pic;
+
+}
+*/
+
+static void fill_frame_info(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic, unsigned int framesize, unsigned int pts)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (pic->slice_type == SLICE_I)
+ pic->vqos.type = 1;
+ else if (pic->slice_type == SLICE_P)
+ pic->vqos.type = 2;
+ else if (pic->slice_type == SLICE_B)
+ pic->vqos.type = 3;
+
+ if (input_frame_based(hw_to_vdec(dec)))
+ pic->vqos.size = pic->frame_size;
+ else {
+ if (!((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP))
+ && vdec_stream_based(vdec))
+ pic->vqos.size = pic->stream_size;
+ else if (framesize == 0)
+ pic->vqos.size = pic->stream_size;
+ else
+ pic->vqos.size = framesize;
+ }
+
+ if (pic->error_mark)
+ pic->vqos.decode_buffer = 3;
+ else
+ pic->vqos.decode_buffer = 0;
+
+ pic->vqos.num++;
+ pic->vqos.pts = pts;
+
+ if (get_dbg_flag(dec) & AVS3_DBG_QOS_INFO) {
+ avs3_print(dec, 0, "slice:%d, poc:%d, size %d, decode_buffer %d, time %dus\n",
+ pic->vqos.type, pic->poc, pic->vqos.size, pic->vqos.decode_buffer, pic->hw_decode_time);
+ avs3_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_mv,
+ pic->vqos.avg_mv,
+ pic->vqos.min_mv);
+
+ avs3_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_qp,
+ pic->vqos.avg_qp,
+ pic->vqos.min_qp);
+
+ avs3_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
+ pic->vqos.max_skip,
+ pic->vqos.avg_skip,
+ pic->vqos.min_skip);
+ }
+
+ return ;
+}
+
+static void set_vframe(struct AVS3Decoder_s *dec,
+ struct vframe_s *vf, struct avs3_frame_s *pic, u8 dummy)
+{
+ u32 stream_offset = pic->stream_offset;
+ unsigned int frame_size = 0;
+ int pts_discontinue;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ ulong flags = 0;
+
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s index = %d\r\n",
+ __func__, pic->index);
+
+#ifdef OW_TRIPLE_WRITE
+ if ((pic->triple_write_mode) ||
+ (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0))
+#else
+ if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0)
+#endif
+ set_canvas(dec, pic);
+
+ display_frame_count[dec->index]++;
+
+ if (!dummy) {
+#ifdef MULTI_INSTANCE_SUPPORT
+ if (vdec_frame_based(vdec)) {
+ vf->pts = pic->pts;
+ vf->pts_us64 = pic->pts64;
+ } else {
+#endif
+ if (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
+ /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
+ stream_offset, &vf->pts, 0) != 0) { */
+ if (pts_lookup_offset_us64
+ (PTS_TYPE_VIDEO, stream_offset,
+ &vf->pts, &frame_size, 0,
+ &vf->pts_us64) != 0) {
+#ifdef DEBUG_PTS
+ dec->pts_missed++;
+#endif
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+ }
+#ifdef DEBUG_PTS
+ else
+ dec->pts_hit++;
+#endif
+ if (pts_unstable)
+ dec->pts_mode = PTS_NONE_REF_USE_DURATION;
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode != 1)
+#endif
+ fill_frame_info(dec, pic, frame_size, vf->pts);
+
+ if ((dec->pts_mode == PTS_NORMAL) && (vf->pts != 0)
+ && dec->get_frame_dur) {
+ int pts_diff = (int)vf->pts - dec->last_lookup_pts;
+
+ if (pts_diff < 0) {
+ dec->pts_mode_switching_count++;
+ dec->pts_mode_recovery_count = 0;
+
+ if (dec->pts_mode_switching_count >=
+ PTS_MODE_SWITCHING_THRESHOLD) {
+ dec->pts_mode =
+ PTS_NONE_REF_USE_DURATION;
+ pr_info
+ ("HEVC: switch to n_d mode.\n");
+ }
+
+ } else {
+ int p = PTS_MODE_SWITCHING_RECOVERY_THRESHOLD;
+ dec->pts_mode_recovery_count++;
+ if (dec->pts_mode_recovery_count > p) {
+ dec->pts_mode_switching_count = 0;
+ dec->pts_mode_recovery_count = 0;
+ }
+ }
+ }
+
+ pts_discontinue =
+ (abs(dec->last_pts - vf->pts) >=
+ tsync_vpts_discontinuity_margin());
+
+ if (vf->pts != 0)
+ dec->last_lookup_pts = vf->pts;
+
+ if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
+ && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
+ !first_pts_checkin_complete(PTS_TYPE_AUDIO))))
+ vf->pts = dec->last_pts + DUR2PTS(dec->frame_dur);
+ dec->last_pts = vf->pts;
+
+ if (vf->pts_us64 != 0)
+ dec->last_lookup_pts_us64 = vf->pts_us64;
+
+ if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
+ && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
+ !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) {
+ vf->pts_us64 =
+ dec->last_pts_us64 +
+ (DUR2PTS(dec->frame_dur) * 100 / 9);
+ }
+
+ dec->last_pts_us64 = vf->pts_us64;
+ }
+
+ vf->index = 0xff00 | pic->index;
+
+ if (pic->double_write_mode & 0x10) {
+ /* double write only */
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = 0;
+ } else {
+#ifdef AVS3_10B_MMU
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = pic->header_adr;
+#ifdef AVS3_10B_MMU_DW
+ vf->dwBodyAddr = 0;
+ vf->dwHeadAddr = 0;
+ if (pic->double_write_mode & 0x20) {
+ u32 mode = pic->double_write_mode & 0xf;
+ if (mode == 5 || mode == 3)
+ vf->dwHeadAddr = pic->dw_header_adr;
+ else if ((mode == 1 || mode == 2 || mode == 4)
+ && ((debug & AVS3_DBG_OUT_PTS) == 0)) {
+ vf->compHeadAddr = pic->dw_header_adr;
+ pr_info("Use dw mmu for display\n");
+ }
+ }
+#endif
+
+#else
+ vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+ vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
+#endif
+ }
+ if (pic->double_write_mode &&
+ ((pic->double_write_mode & 0x20) == 0)) {
+ vf->type = VIDTYPE_PROGRESSIVE |
+ VIDTYPE_VIU_FIELD;
+ vf->type |= VIDTYPE_VIU_NV21;
+ if (pic->double_write_mode == 3) {
+ vf->type |= VIDTYPE_COMPRESS;
+#ifdef AVS3_10B_MMU
+ vf->type |= VIDTYPE_SCATTER;
+#endif
+ }
+#ifdef MULTI_INSTANCE_SUPPORT
+ if (dec->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+ vf->canvas0_config[0] =
+ pic->canvas_config[0];
+ vf->canvas0_config[1] =
+ pic->canvas_config[1];
+
+ vf->canvas1_config[0] =
+ pic->canvas_config[0];
+ vf->canvas1_config[1] =
+ pic->canvas_config[1];
+
+ } else
+#endif
+ vf->canvas0Addr = vf->canvas1Addr =
+ spec2canvas(pic);
+ } else {
+ vf->canvas0Addr = vf->canvas1Addr = 0;
+ vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
+#ifdef AVS3_10B_MMU
+ vf->type |= VIDTYPE_SCATTER;
+#endif
+ }
+
+ switch (pic->depth) {
+ case AVS3_BITS_8:
+ vf->bitdepth = BITDEPTH_Y8 |
+ BITDEPTH_U8 | BITDEPTH_V8;
+ break;
+ case AVS3_BITS_10:
+ case AVS3_BITS_12:
+ vf->bitdepth = BITDEPTH_Y10 |
+ BITDEPTH_U10 | BITDEPTH_V10;
+ break;
+ default:
+ vf->bitdepth = BITDEPTH_Y10 |
+ BITDEPTH_U10 | BITDEPTH_V10;
+ break;
+ }
+ if ((vf->type & VIDTYPE_COMPRESS) == 0)
+ vf->bitdepth =
+ BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
+ if (pic->depth == AVS3_BITS_8)
+ vf->bitdepth |= BITDEPTH_SAVING_MODE;
+
+ set_frame_info(dec, vf);
+ /* if ((vf->width!=pic->width)|
+ (vf->height!=pic->height)) */
+ /* pr_info("aaa: %d/%d, %d/%d\n",
+ vf->width,vf->height, pic->width,
+ pic->height); */
+ vf->width = pic->width /
+ get_double_write_ratio(pic->double_write_mode);
+ vf->height = pic->height /
+ get_double_write_ratio(pic->double_write_mode);
+ if (force_w_h != 0) {
+ vf->width = (force_w_h >> 16) & 0xffff;
+ vf->height = force_w_h & 0xffff;
+ }
+ if ((pic->double_write_mode & 0x20) &&
+ ((pic->double_write_mode & 0xf) == 2 ||
+ (pic->double_write_mode & 0xf) == 4)) {
+ vf->compWidth = pic->width /
+ get_double_write_ratio(
+ pic->double_write_mode & 0xf);
+ vf->compHeight = pic->height /
+ get_double_write_ratio(
+ pic->double_write_mode & 0xf);
+ } else {
+ vf->compWidth = pic->width;
+ vf->compHeight = pic->height;
+ }
+
+#ifdef OW_TRIPLE_WRITE
+ if (!pic->double_write_mode && pic->triple_write_mode) {
+ vf->type |= VIDTYPE_VIU_NV21; //nv12 flag
+ vf->canvas0_config[0] = pic->tw_canvas_config[0];
+ vf->canvas0_config[1] = pic->tw_canvas_config[1];
+ vf->canvas1_config[0] = pic->tw_canvas_config[0];
+ vf->canvas1_config[1] = pic->tw_canvas_config[1];
+ vf->width = pic->width /
+ get_double_write_ratio(pic->triple_write_mode & 0xf); //tw same ratio defined with dw
+ vf->height = pic->height /
+ get_double_write_ratio(pic->triple_write_mode & 0xf);
+ avs3_print(dec, 0, "output triple write w %d, h %d, bitdepth %s\n",
+ vf->width, vf->height, vf->canvas0_config[0].bit_depth?"10":"8");
+ }
+#endif
+
+ if (force_fps & 0x100) {
+ u32 rate = force_fps & 0xff;
+ if (rate)
+ vf->duration = 96000/rate;
+ else
+ vf->duration = 0;
+ }
+
+ if (dec->front_back_mode != 1)
+ update_vf_memhandle(dec, vf, pic);
+
+ if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+ /* offset for tsplayer pts lookup */
+ u64 frame_type = 0;
+ if (pic->slice_type == SLICE_I)
+ frame_type = KEYFRAME_FLAG;
+ else if (pic->slice_type == SLICE_P)
+ frame_type = PFRAME_FLAG;
+ else if (pic->slice_type == SLICE_B)
+ frame_type = BFRAME_FLAG;
+ vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
+ vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ /* lookup by decoder */
+ checkout_pts_offset pts_info;
+ u64 frame_type = 0;
+ if (pic->slice_type == SLICE_I)
+ frame_type = KEYFRAME_FLAG;
+ else if (pic->slice_type == SLICE_P)
+ frame_type = PFRAME_FLAG;
+ else if (pic->slice_type == SLICE_B)
+ frame_type = BFRAME_FLAG;
+ pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+ | pic->stream_offset;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+ avs3_print(dec, AVS3_DBG_OUT_PTS,
+ "avs3 dec out pts: vf->pts=%d, vf->pts_us64 = %lld slice_type %d, duration %d\n",
+ vf->pts, vf->pts_us64, pic->slice_type, vf->duration);
+
+ lock_buffer(dec, flags);
+ if (!dummy) {
+ pic->vf_ref = 1;
+ }
+ dec->vf_pre_count++;
+ unlock_buffer(dec, flags);
+}
+
+static inline void dec_update_gvs(struct AVS3Decoder_s *dec)
+{
+ if (dec->gvs->frame_height != dec->frame_height) {
+ dec->gvs->frame_width = dec->frame_width;
+ dec->gvs->frame_height = dec->frame_height;
+ }
+ /*if (dec->gvs->frame_dur != dec->frame_dur) {
+ dec->gvs->frame_dur = dec->frame_dur;
+ if (dec->frame_dur != 0)
+ dec->gvs->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+ 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
+ else
+ dec->gvs->frame_rate = -1;
+ }*/
+ dec->gvs->status = dec->stat | dec->fatal_error;
+}
+
+static int avs3_prepare_display_buf(struct AVS3Decoder_s *dec)
+{
+#ifndef NO_DISPLAY
+ struct vframe_s *vf = NULL;
+ /*unsigned short slice_type;*/
+ struct avs3_frame_s *pic;
+ struct vdec_s *pvdec = hw_to_vdec(dec);
+
+ while (1) {
+ COM_PIC *com_pic = dec_pull_frm(&dec->avs3_dec.ctx, 0);
+
+ if (com_pic == NULL)
+ break;
+ pic = &com_pic->buf_cfg;
+ if (force_disp_pic_index & 0x100) {
+ /*recycle directly*/
+ continue;
+ }
+
+ if (pic->error_mark && (error_handle_policy & 0x4)) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s: error pic, skip\n", __func__);
+ continue;
+ }
+
+ if (dec->start_decoding_flag != 0) {
+ if (dec->skip_PB_before_I &&
+ pic->slice_type != I_IMG) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "!!!slice type %d (not I) skip\n",
+ 0, pic->slice_type);
+ continue;
+ }
+ dec->skip_PB_before_I = 0;
+ }
+
+ if (kfifo_get(&dec->newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return -1;
+ }
+
+ if (vf) {
+ set_vframe(dec, vf, pic, 0);
+ if (dec->front_back_mode != 1)
+ decoder_do_frame_check(pvdec, vf);
+ vdec_vframe_ready(pvdec, vf);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "%s: pic %p stream_offset 0x%x\n",
+ __func__, com_pic, pic->stream_offset);
+
+ kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
+ decoder_trace(dec->trace.pts_name, vf->pts, TRACE_BUFFER);
+ decoder_trace(dec->trace.new_q_name, kfifo_len(&dec->newframe_q), TRACE_BUFFER);
+ decoder_trace(dec->trace.disp_q_name, kfifo_len(&dec->display_q), TRACE_BUFFER);
+
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 0) {
+#endif
+ dec_update_gvs(dec);
+ /*count info*/
+ vdec_count_info(dec->gvs, 2, pic->stream_offset);
+
+ dec->gvs->bit_depth_luma = pic->depth;
+ dec->gvs->bit_depth_chroma = pic->depth;
+ dec->gvs->double_write_mode = pic->double_write_mode;
+ vdec_fill_vdec_frame(pvdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#ifdef NEW_FB_CODE
+ }
+#endif
+
+ pvdec->vdec_fps_detec(pvdec->id);
+ if (without_display_mode == 0) {
+ if (dec->front_back_mode != 1)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ } else
+ vavs3_vf_put(vavs3_vf_get(dec), dec);
+ }
+ }
+/*!NO_DISPLAY*/
+#endif
+ return 0;
+}
+
+static void get_rpm_param(union param_u *params)
+{
+ int i;
+ unsigned int data32;
+ if (debug & AVS3_DBG_BUFMGR)
+ pr_info("enter %s\r\n", __func__);
+ for (i = 0; i < (RPM_END - RPM_BEGIN); i++) {
+ do {
+ data32 = READ_VREG(RPM_CMD_REG);
+ /*pr_info("%x\n", data32);*/
+ } while ((data32 & 0x10000) == 0);
+ params->l.data[i] = data32&0xffff;
+ /*pr_info("%x\n", data32);*/
+ WRITE_VREG(RPM_CMD_REG, 0);
+ }
+ if (debug & AVS3_DBG_BUFMGR)
+ pr_info("leave %s\r\n", __func__);
+}
+static void debug_buffer_mgr_more(struct AVS3Decoder_s *dec)
+{
+ int i;
+ if (!(debug & AVS3_DBG_BUFMGR_MORE))
+ return;
+
+ avs3_print(dec, 0, "avs3_param: (%d)\n", dec->avs3_dec.img.number);
+ for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
+ avs3_print_cont(dec, 0, "%04x ", dec->avs3_dec.param.l.data[i]);
+ if (((i + 1) & 0xf) == 0) {
+ avs3_print_cont(dec, 0, "\n");
+ avs3_print_flush(dec);
+ }
+ }
+ avs3_print(dec, 0, "\n");
+}
+
+#ifdef AVS3_10B_MMU
+static void avs3_recycle_mmu_buf_tail(struct AVS3Decoder_s *dec)
+{
+ if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+ u32 used_4k_num =
+ (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
+ if (dec->m_ins_flag)
+ hevc_mmu_dma_check(hw_to_vdec(dec));
+ decoder_mmu_box_free_idx_tail(dec->mmu_box,
+ dec->cur_fb_idx_mmu, used_4k_num);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_free_idx_tail index=%d used_4k_num %d\n",
+ __func__, dec->cur_fb_idx_mmu, used_4k_num);
+
+ if (dec->dw_mmu_enable) {
+ used_4k_num = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s DW decoder_mmu_box_free_idx_tail index=%d used_4k_num %d\n",
+ __func__, dec->cur_fb_idx_mmu, used_4k_num);
+
+ decoder_mmu_box_free_idx_tail(
+ dec->dw_mmu_box,
+ dec->cur_fb_idx_mmu,
+ used_4k_num);
+ }
+
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+ }
+}
+
+static void avs3_recycle_mmu_buf(struct AVS3Decoder_s *dec)
+{
+ if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+ decoder_mmu_box_free_idx(dec->mmu_box,
+ dec->cur_fb_idx_mmu);
+
+ if (dec->front_back_mode)
+ decoder_mmu_box_free_idx(dec->mmu_box_1,
+ dec->cur_fb_idx_mmu);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_free_idx index=%d\n",
+ __func__, dec->cur_fb_idx_mmu);
+
+ if (dec->dw_mmu_enable) {
+ decoder_mmu_box_free_idx(dec->dw_mmu_box,
+ dec->cur_fb_idx_mmu);
+
+ if (dec->front_back_mode)
+ decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+ dec->cur_fb_idx_mmu);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s DW decoder_mmu_box_free_idx index=%d\n",
+ __func__, dec->cur_fb_idx_mmu);
+ }
+ dec->cur_fb_idx_mmu = INVALID_IDX;
+ }
+}
+#endif
+
+static void dec_again_process(struct AVS3Decoder_s *dec)
+{
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ dec->dec_result = DEC_RESULT_AGAIN;
+ if (dec->process_state ==
+ PROC_STATE_DECODING) {
+ dec->process_state =
+ PROC_STATE_DECODE_AGAIN;
+ } else if (dec->process_state ==
+ PROC_STATE_HEAD_DONE) {
+ dec->process_state =
+ PROC_STATE_HEAD_AGAIN;
+ }
+ dec->next_again_flag = 1;
+
+ vdec_schedule_work(&dec->work);
+}
+/*
+static uint32_t log2i(uint32_t val)
+{
+ uint32_t ret = -1;
+ while (val != 0) {
+ val >>= 1;
+ ret++;
+ }
+ return ret;
+}
+*/
+static void check_pic_error(struct AVS3Decoder_s *dec,
+ struct avs3_frame_s *pic)
+{
+#ifndef PXP_DEBUG
+ if (dec->front_back_mode == 3 ||
+ (debug & AVS3_DBG_DIS_LOC_ERROR_PROC))
+ return;
+
+ if (pic->decoded_lcu != dec->avs3_dec.lcu_total) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "%s error pic(index %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index,
+ pic->decoded_lcu, dec->avs3_dec.lcu_total);
+ pic->error_mark = 1;
+ } else {
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s pic(index %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index,
+ pic->decoded_lcu, dec->avs3_dec.lcu_total);
+
+ }
+#endif
+}
+static void update_decoded_pic(struct AVS3Decoder_s *dec)
+{
+ struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+ if (pic) {
+ dec->avs3_dec.cur_pic->decoded_lcu =
+ (READ_VREG(HEVC_PARSER_LCU_START)
+ & 0xffffff) + 1;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s pic(index %d) decoded lcu %d (total %d)\n",
+ __func__, pic->index,
+ pic->decoded_lcu, dec->avs3_dec.lcu_total);
+ }
+}
+/* +[SE] [BUG][BUG-171463][chuanqi.wang]: get frame rate by video sequeue*/
+static int get_frame_rate(union param_u *params, struct AVS3Decoder_s *dec)
+{
+ int tmp = 0;
+
+ switch (params->p.sqh_frame_rate_code) {
+ case 1:
+ case 2:
+ tmp = 24;
+ break;
+ case 3:
+ tmp = 25;
+ break;
+ case 4:
+ case 5:
+ tmp = 30;
+ break;
+ case 6:
+ tmp = 50;
+ break;
+ case 7:
+ case 8:
+ tmp = 60;
+ break;
+ case 9:
+ tmp = 100;
+ break;
+ case 10:
+ tmp = 120;
+ break;
+ default:
+ tmp = 25;
+ break;
+ }
+
+ if (!params->p.sqh_progressive_sequence)
+ tmp = tmp / 2;
+ dec->frame_dur = div_u64(96000ULL, tmp);
+ dec->get_frame_dur = true;
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS, "avs3 frame_dur:%d,progressive:%d\n",
+ dec->frame_dur, params->p.sqh_progressive_sequence);
+ return 0;
+}
+
+#define HEVC_MV_INFO 0x310d
+#define HEVC_QP_INFO 0x3137
+#define HEVC_SKIP_INFO 0x3136
+
+static void get_qos_info(struct AVS3Decoder_s *dec, struct vframe_qos_s* vqos, int pic_number, int core_num)
+{
+ uint32_t blk88_y_count;
+ uint32_t blk88_c_count;
+ uint32_t blk22_mv_count;
+ uint32_t rdata32;
+ int32_t mv_hi;
+ int32_t mv_lo;
+ uint32_t rdata32_l;
+ uint32_t mvx_L0_hi;
+ uint32_t mvy_L0_hi;
+ uint32_t mvx_L1_hi;
+ uint32_t mvy_L1_hi;
+ int64_t value;
+ uint64_t temp_value;
+ uint64_t ctrl_reg = HEVC_PIC_QUALITY_CTRL;
+ uint64_t data_reg = HEVC_PIC_QUALITY_DATA;
+
+ if (core_num == 1) {
+ ctrl_reg = HEVC_PIC_QUALITY_CTRL_DBE1;
+ data_reg = HEVC_PIC_QUALITY_DATA_DBE1;
+ }
+
+ /* set rd_idx to 0 */
+ WRITE_VREG(ctrl_reg, 0);
+
+ blk88_y_count = READ_VREG(data_reg);
+ if (blk88_y_count == 0) {
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] NO Data yet.\n",
+ pic_number);
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* qp_y_sum */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] Y QP AVG:%d (%d/%d)\n",
+ pic_number, rdata32/blk88_y_count, rdata32, blk88_y_count);
+ vqos->avg_qp = rdata32 * 10 / blk88_y_count;
+
+ /* intra_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] Y intra rate:%d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+
+ /* skipped_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] Y skipped rate:%d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+ vqos->avg_skip = rdata32 * 1000 / blk88_y_count;
+
+ /* coeff_non_zero_y_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] Y ZERO_Coeff rate:%d%c (%d)\n",
+ pic_number, (100 - rdata32 * 100 / blk88_y_count), '%', rdata32);
+
+ /* blk66_c_count */
+ blk88_c_count = READ_VREG(data_reg);
+ if (blk88_c_count == 0) {
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] NO Data yet.\n",
+ pic_number);
+
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* qp_c_sum */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] C QP AVG:%d (%d/%d)\n",
+ pic_number, rdata32 / blk88_c_count, rdata32, blk88_c_count);
+
+ /* intra_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] C intra rate:%d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_c_count, '%', rdata32);
+
+ /* skipped_cu_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] C skipped rate:%d%c (%d)\n",
+ pic_number, rdata32 * 100 / blk88_c_count, '%', rdata32);
+
+ /* coeff_non_zero_c_count */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] C ZERO_Coeff rate:%d%c (%d)\n",
+ pic_number, (100 - rdata32 * 100 / blk88_c_count), '%', rdata32);
+
+ /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
+ 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
+ rdata32 = READ_VREG(data_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] Y QP min:%d max:%d\n",
+ pic_number, (rdata32 >> 0) & 0xff, (rdata32 >> 8) & 0xff);
+
+ vqos->min_qp = (rdata32 >> 0) & 0xff;
+ vqos->max_qp = (rdata32 >> 8) & 0xff;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] C QP min:%d max:%d\n",
+ pic_number, (rdata32 >> 16) & 0xff, (rdata32 >> 24) & 0xff);
+
+ /* blk22_mv_count */
+ blk22_mv_count = READ_VREG(data_reg);
+ if (blk22_mv_count == 0) {
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] NO MV Data yet.\n",
+ pic_number);
+
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+ return;
+ }
+
+ /* mvy_L1_count[39:32], mvx_L1_count[39:32],
+ mvy_L0_count[39:32], mvx_L0_count[39:32] */
+ rdata32 = READ_VREG(data_reg);
+
+ /* should all be 0x00 or 0xff */
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MV AVG High Bits:0x%X\n",
+ pic_number, rdata32);
+
+ mvx_L0_hi = ((rdata32 >> 0) & 0xff);
+ mvy_L0_hi = ((rdata32 >> 8) & 0xff);
+ mvx_L1_hi = ((rdata32 >> 16) & 0xff);
+ mvy_L1_hi = ((rdata32 >> 24) & 0xff);
+
+ /* mvx_L0_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvx_L0_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+
+ if (mvx_L0_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+ value = div_s64(value * 10, blk22_mv_count);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L0 AVG:%d (%lld/%d)\n",
+ pic_number, div_s64(value, 10), div_s64(value, 10), blk22_mv_count);
+
+ vqos->avg_mv = value;
+
+ /* mvy_L0_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvy_L0_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+
+ if (mvy_L0_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L0 AVG:%d (%lld/%d)\n",
+ pic_number, rdata32_l / blk22_mv_count, value, blk22_mv_count);
+
+ /* mvx_L1_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvx_L1_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+ if (mvx_L1_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L1 AVG:%d (%lld/%d)\n",
+ pic_number, rdata32_l / blk22_mv_count, value, blk22_mv_count);
+
+ /* mvy_L1_count[31:0] */
+ rdata32_l = READ_VREG(data_reg);
+ temp_value = mvy_L1_hi;
+ temp_value = (temp_value << 32) | rdata32_l;
+ if (mvy_L1_hi & 0x80)
+ value = 0xFFFFFFF000000000 | temp_value;
+ else
+ value = temp_value;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L1 AVG:%d (%lld/%d)\n",
+ pic_number, rdata32_l/blk22_mv_count, value, blk22_mv_count);
+
+ /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+ vqos->max_mv = mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+ vqos->min_mv = mv_lo;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L0 MAX:%d MIN:%d\n",
+ pic_number, mv_hi, mv_lo);
+
+ /* {mvy_L0_max, mvy_L0_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L0 MAX:%d MIN:%d\n",
+ pic_number, mv_hi, mv_lo);
+
+ /* {mvx_L1_max, mvx_L1_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVX_L1 MAX:%d MIN:%d\n",
+ pic_number, mv_hi, mv_lo);
+
+ /* {mvy_L1_max, mvy_L1_min} */
+ rdata32 = READ_VREG(data_reg);
+ mv_hi = (rdata32 >> 16) & 0xffff;
+ if (mv_hi & 0x8000)
+ mv_hi = 0x8000 - mv_hi;
+
+ mv_lo = (rdata32 >> 0) & 0xffff;
+ if (mv_lo & 0x8000)
+ mv_lo = 0x8000 - mv_lo;
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] MVY_L1 MAX:%d MIN:%d\n",
+ pic_number, mv_hi, mv_lo);
+
+ rdata32 = READ_VREG(ctrl_reg);
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "[Picture %d Quality] After Read:VDEC_PIC_QUALITY_CTRL: 0x%x\n",
+ pic_number, rdata32);
+
+ /* reset all counts */
+ WRITE_VREG(ctrl_reg, (1 << 8));
+
+}
+
+/* only when we decoded one field or one frame,
+we can call this function to get qos info*/
+static void get_picture_qos_info(struct AVS3Decoder_s *dec, bool back_flag)
+{
+ struct avs3_frame_s *picture = NULL;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct vframe_qos_s vqos_0, vqos_1;
+
+ if (back_flag) {
+#ifdef NEW_FB_CODE
+ picture = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+#endif
+ } else {
+ picture = dec->avs3_dec.cur_pic;
+ }
+
+ if (!picture) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decode picture is none exist\n");
+ return;
+ }
+
+ if (vdec->mvfrm) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode != 0) {
+ if (back_flag) {
+ picture->hw_decode_time =
+ local_clock() - vdec->hw_back_decode_start;
+ if (picture->hw_decode_time < picture->hw_front_decode_time)
+ picture->hw_decode_time = picture->hw_front_decode_time;
+
+ } else {
+ picture->hw_front_decode_time =
+ local_clock() - vdec->hw_front_decode_start;
+ return ;
+ }
+ } else
+#endif
+ picture->hw_decode_time =
+ local_clock() - vdec->mvfrm->hw_decode_start;
+ }
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO, "slice_type:%d, poc:%d hw_decode_time:%d\n",
+ picture->slice_type, picture->poc, picture->hw_decode_time);
+
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
+ unsigned char a[3];
+ unsigned char i, j, t;
+ unsigned long data;
+
+ data = READ_VREG(HEVC_MV_INFO);
+ if (picture->slice_type == SLICE_I)
+ data = 0;
+ a[0] = data & 0xff;
+ a[1] = (data >> 8) & 0xff;
+ a[2] = (data >> 16) & 0xff;
+
+ for (i = 0; i < 3; i++) {
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ }
+ picture->vqos.max_mv = a[2];
+ picture->vqos.avg_mv = a[1];
+ picture->vqos.min_mv = a[0];
+ avs3_print(dec, AVS3_DBG_QOS_INFO, "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+
+ data = READ_VREG(HEVC_QP_INFO);
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++)
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ picture->vqos.max_qp = a[2];
+ picture->vqos.avg_qp = a[1];
+ picture->vqos.min_qp = a[0];
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO, "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+
+ data = READ_VREG(HEVC_SKIP_INFO);
+ a[0] = data & 0x1f;
+ a[1] = (data >> 8) & 0x3f;
+ a[2] = (data >> 16) & 0x7f;
+
+ for (i = 0; i < 3; i++)
+ for (j = i+1; j < 3; j++) {
+ if (a[j] < a[i]) {
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ } else if (a[j] == a[i]) {
+ a[i]++;
+ t = a[j];
+ a[j] = a[i];
+ a[i] = t;
+ }
+ }
+ picture->vqos.max_skip = a[2];
+ picture->vqos.avg_skip = a[1];
+ picture->vqos.min_skip = a[0];
+
+ avs3_print(dec, AVS3_DBG_QOS_INFO,
+ "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ data, a[0], a[1], a[2]);
+ } else {
+ picture->vqos.max_mv = 0;
+ picture->vqos.avg_mv = 0;
+ picture->vqos.min_mv = 0;
+
+ picture->vqos.max_skip = 0;
+ picture->vqos.avg_skip = 0;
+ picture->vqos.min_skip = 0;
+
+ picture->vqos.max_qp = 0;
+ picture->vqos.avg_qp = 0;
+ picture->vqos.min_qp = 0;
+
+ get_qos_info(dec, &vqos_0, picture->poc, 0);
+
+ if (back_flag) {
+#ifdef NEW_FB_CODE
+ get_qos_info(dec, &vqos_1, picture->poc, 1);
+
+ vqos_0.max_mv = max(vqos_0.max_mv, vqos_1.max_mv);
+ vqos_0.min_mv = min(vqos_0.min_mv, vqos_1.min_mv);
+ vqos_0.max_qp = max(vqos_0.max_qp, vqos_1.max_qp);
+ vqos_0.min_qp = min(vqos_0.min_qp, vqos_1.min_qp);
+
+ vqos_0.avg_qp = (vqos_0.avg_qp + vqos_1.avg_qp) / 20;
+ vqos_0.avg_skip = (vqos_0.avg_skip + vqos_1.avg_skip) / 20;
+ vqos_0.avg_mv = (vqos_0.avg_mv + vqos_1.avg_mv) / 20;
+#endif
+ } else {
+ vqos_0.avg_qp = vqos_0.avg_qp / 10;
+ vqos_0.avg_skip = vqos_0.avg_skip / 10;
+ vqos_0.avg_mv = vqos_0.avg_mv / 10;
+ }
+
+ picture->vqos = vqos_0;
+ }
+}
+
+#ifdef NEW_FB_CODE
+irqreturn_t avs3_back_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_PIC_DONE);
+ dec->dec_status_back = READ_VREG(HEVC_DEC_STATUS_DBE);
+ if (dec->dec_status_back == HEVC_BE_DECODE_DATA_DONE) {
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC_BACK);
+ }
+
+ /*BackEnd_Handle()*/
+ if (dec->front_back_mode != 1) {
+ avs3_print(dec, AVS3_DBG_IRQ_EVENT,
+ "[BE] %s\n", __func__);
+ if (dec->front_back_mode == 3)
+ dec->dec_status_back = HEVC_BE_DECODE_DATA_DONE;
+ return IRQ_WAKE_THREAD;
+ }
+
+#if 0
+ if (debug & AVS3_DBG_IRQ_EVENT)
+ avs3_print(dec, 0,
+ "[BE] avs3 back isr dec_status_back = 0x%x\n",
+ dec->dec_status_back
+ );
+ if (READ_VREG(DEBUG_REG1_DBE)) {
+ pr_info("[BE] dbg%x: %x, HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n", READ_VREG(DEBUG_REG1_DBE),
+ READ_VREG(DEBUG_REG2_DBE),
+ READ_VREG(HEVC_SAO_CRC),
+ READ_VREG(HEVC_SAO_CRC_DBE1)
+ );
+ WRITE_VREG(DEBUG_REG1_DBE, 0);
+ }
+#else
+ if (READ_VREG(DEBUG_REG1_DBE)) {
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+ return IRQ_HANDLED;
+#else
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+ return IRQ_WAKE_THREAD;
+#endif
+ }
+#endif
+ if (dec->dec_status_back == AVS3_DEC_IDLE) {
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+ return IRQ_HANDLED;
+ }
+ /**/
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+ return IRQ_HANDLED;
+#else
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+ reset_process_time_back(dec);
+ return IRQ_WAKE_THREAD;
+#endif
+}
+
+irqreturn_t vavs3_back_isr_thread_fn(struct AVS3Decoder_s *dec)
+{
+ unsigned int dec_status = dec->dec_status_back;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ int j;
+ //unsigned long flags;
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
+
+ if (debug & AVS3_DBG_IRQ_EVENT)
+ avs3_print(dec, 0,
+ "[BE] avs3 back isr dec_status_back = 0x%x\n",
+ dec->dec_status_back);
+ if (READ_VREG(DEBUG_REG1_DBE)) {
+ avs3_print(dec, 0, "[BE] dbg%x: %x\n",
+ READ_VREG(DEBUG_REG1_DBE), READ_VREG(DEBUG_REG2_DBE));
+ WRITE_VREG(DEBUG_REG1_DBE, 0);
+ }
+
+ /*simulation code: if (READ_VREG(HEVC_DEC_STATUS_DBE)==HEVC_BE_DECODE_DATA_DONE)*/
+ if (dec_status == HEVC_BE_DECODE_DATA_DONE || dec->front_back_mode == 2) {
+ struct avs3_frame_s *pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+
+ get_picture_qos_info(dec, true);
+
+ dec_update_gvs(dec);
+ /*count info*/
+ vdec_count_info(dec->gvs, 2, pic->stream_offset);
+ dec->gvs->bit_depth_luma = pic->depth;
+ dec->gvs->bit_depth_chroma = pic->depth;
+ dec->gvs->double_write_mode = pic->double_write_mode;
+
+ reset_process_time_back(dec);
+ vdec->back_pic_done = true;
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "BackEnd data done %d, fb_rd_pos %d, pic index %d, poc %d HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+ avs3_dec->backend_decoded_count, avs3_dec->fb_rd_pos, pic->index, pic->poc,
+ READ_VREG(HEVC_SAO_CRC), READ_VREG(HEVC_SAO_CRC_DBE1));
+
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ avs3_print(dec, 0,
+ "CM_BODY_START_ADDR 0x%x CM_HEADER_START_ADDR 0x%x SAO_Y_START_ADDR 0x%x SAO_Y_LENGTH 0x%x\n",
+ READ_VREG(HEVC_CM_BODY_START_ADDR), READ_VREG(HEVC_CM_HEADER_START_ADDR),
+ READ_VREG(HEVC_SAO_Y_START_ADDR), READ_VREG(HEVC_SAO_Y_LENGTH));
+
+ avs3_print(dec, 0,
+ "SAO_C_START_ADDR 0x%x SAO_C_LENGTH 0x%x SAO_Y_WPTR 0x%x SAO_C_WPTR 0x%x\n",
+ READ_VREG(HEVC_SAO_C_START_ADDR), READ_VREG(HEVC_SAO_C_LENGTH),
+ READ_VREG(HEVC_SAO_Y_WPTR), READ_VREG(HEVC_SAO_C_WPTR));
+
+ avs3_print(dec, 0,
+ "SAO_CTRL0 0x%x SAO_CTRL1 0x%x SAO_CTRL2 0x%x SAO_CTRL3 0x%x SAO_CTRL4 0x%x SAO_CTRL5 0x%x\n",
+ READ_VREG(HEVC_SAO_CTRL0), READ_VREG(HEVC_SAO_CTRL1), READ_VREG(HEVC_SAO_CTRL2),
+ READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL4), READ_VREG(HEVC_SAO_CTRL5));
+
+ avs3_print(dec, 0,
+ "CM_BODY_START_ADDR_DBE1 0x%x CM_HEADER_START_ADDR_DBE1 0x%x SAO_Y_START_ADDR_DBE1 0x%x SAO_Y_LENGTH_DBE1 0x%x\n",
+ READ_VREG(HEVC_CM_BODY_START_ADDR_DBE1), READ_VREG(HEVC_CM_HEADER_START_ADDR_DBE1),
+ READ_VREG(HEVC_SAO_Y_START_ADDR_DBE1), READ_VREG(HEVC_SAO_Y_LENGTH_DBE1));
+
+ avs3_print(dec, 0,
+ "SAO_C_START_ADDR_DBE1 0x%x SAO_C_LENGTH_DBE1 0x%x SAO_Y_WPTR_DBE1 0x%x SAO_C_WPTR_DBE1 0x%x\n",
+ READ_VREG(HEVC_SAO_C_START_ADDR_DBE1), READ_VREG(HEVC_SAO_C_LENGTH_DBE1),
+ READ_VREG(HEVC_SAO_Y_WPTR_DBE1), READ_VREG(HEVC_SAO_C_WPTR_DBE1));
+
+ avs3_print(dec, 0,
+ "SAO_CTRL0_DBE1 0x%x SAO_CTRL1_DBE1 0x%x SAO_CTRL2_DBE1 0x%x SAO_CTRL3_DBE1 0x%x SAO_CTRL4_DBE1 0x%x SAO_CTRL5_DBE1 0x%x\n",
+ READ_VREG(HEVC_SAO_CTRL0_DBE1), READ_VREG(HEVC_SAO_CTRL1_DBE1), READ_VREG(HEVC_SAO_CTRL2_DBE1),
+ READ_VREG(HEVC_SAO_CTRL3_DBE1), READ_VREG(HEVC_SAO_CTRL4_DBE1), READ_VREG(HEVC_SAO_CTRL5_DBE1));
+ }
+
+ if (fbdebug_flag & 0x70000000) {
+ u8 cmd = (fbdebug_flag >> 28) & 0x7;
+ u32 dump_c = (fbdebug_flag >> 16) & 0xfff;
+ if ((cmd == 3) ||
+ (cmd == 1 && dump_c == avs3_dec->backend_decoded_count) ||
+ (cmd == 2 && avs3_dec->backend_decoded_count < dump_c))
+ //10000, make log different from dump_loop_buffer after FrontEnd data done.
+ dump_loop_buffer(dec, 10000 + avs3_dec->backend_decoded_count, cmd ==1 || cmd == 2);
+ }
+
+ if (dec->front_back_mode == 1) {
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "MMU0 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0));
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "MMU1 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1));
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS3_DEC_IDLE);
+ WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 2);
+ }
+ if (debug & AVS3_DBG_PRINT_PIC_LIST) {
+ print_pic_pool(avs3_dec, "before dec backend_ref");
+ avs3_print_cont(dec, 0, "pic_cfg index %d, list0 index: ", pic->index);
+ for (j = 0; j < pic->list0_num_refp; j++)
+ avs3_print_cont(dec, 0, "%d ", pic->list0_index[j]);
+ avs3_print_cont(dec, 0, "list1 index: ");
+ for (j = 0; j < pic->list1_num_refp; j++)
+ avs3_print_cont(dec, 0, "%d ", pic->list1_index[j]);
+ avs3_print_cont(dec, 0, "\n");
+ }
+
+#if 0
+#ifdef AVS3_10B_MMU
+ release_unused_4k(&avs3_mmumgr_0, pic->index);
+ release_unused_4k(&avs3_mmumgr_1, pic->index);
+#endif
+#ifdef AVS3_10B_MMU_DW
+ release_unused_4k(&avs3_mmumgr_dw0, pic->index); // new dual
+ release_unused_4k(&avs3_mmumgr_dw1, pic->index); // new dual
+#endif
+#else
+ if ((dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3
+ ) && (debug & AVS3_DBG_NOT_RECYCLE_MMU_TAIL) == 0) {
+ /*if (dec->is_used_v4l) {
+ // to do
+ } else {*/
+ unsigned used_4k_num0;
+ unsigned used_4k_num1;
+ used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+ if (dec->front_back_mode == 3)
+ used_4k_num1 = used_4k_num0;
+ else
+ used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS_DBE1) >> 16;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decoder_mmu_box_free_idx_tail index=%d, core0 %d core1 %d\n",
+ __func__, pic->index,
+ used_4k_num0, used_4k_num1);
+ decoder_mmu_box_free_idx_tail(
+ dec->mmu_box,
+ pic->index,
+ used_4k_num0);
+ decoder_mmu_box_free_idx_tail(
+ dec->mmu_box_1,
+ pic->index,
+ used_4k_num1);
+ if (dec->dw_mmu_enable) {
+ used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+ if (dec->front_back_mode == 3)
+ used_4k_num1 = used_4k_num0;
+ else
+ used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS2_DBE1) >> 16;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s DW decoder_mmu_box_free_idx_tail index=%d, core0 %d core1 %d\n",
+ __func__, pic->index,
+ used_4k_num0, used_4k_num1);
+ decoder_mmu_box_free_idx_tail(
+ dec->dw_mmu_box,
+ pic->index,
+ used_4k_num0);
+ decoder_mmu_box_free_idx_tail(
+ dec->dw_mmu_box_1,
+ pic->index,
+ used_4k_num1);
+ }
+ }
+#endif
+
+ if (without_display_mode == 0) {
+ struct vframe_s *vf = NULL;
+ if (kfifo_peek(&dec->display_q, &vf) && vf) {
+ uint8_t index = vf->index & 0xff;
+ struct avs3_frame_s *peek_pic = get_pic_by_index(dec, index);
+
+ if (peek_pic == pic)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ }
+ } else
+ vavs3_vf_put(vavs3_vf_get(dec), dec);
+
+ pic_backend_ref_operation(dec, pic, 0);
+
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "after dec backend_ref");
+
+ if (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3)
+ release_free_mmu_buffers(dec);
+
+ dec->dec_back_result = DEC_BACK_RESULT_DONE;
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_THREAD_EDN);
+ if (avs3_dec->front_pause_flag) {
+ /*multi pictures in one packe*/
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG,
+ 0x1);
+ }
+ avs3_work_back_implement(dec, vdec, 0);
+ }
+ //unlock_front_back(dec, flags);
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t avs3_back_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ irqreturn_t ret;
+ //unsigned long flags;
+ //lock_front_back(dec, flags);
+ ret = vavs3_back_isr_thread_fn(dec);
+ //unlock_front_back(dec, flags);
+ return ret;
+}
+
+#endif
+
+static void handle_ucode_dbg(struct AVS3Decoder_s *dec, uint debug_tag)
+{
+
+ int i;
+ if (debug_tag & 0x10000) {
+ dma_sync_single_for_cpu(
+ amports_get_dma_device(),
+ dec->lmem_phy_addr,
+ LMEM_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
+ pr_info("LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
+ for (i = 0; i < 0x400; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ",
+ dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == dec->decode_idx) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_HREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ dec->ucode_pause_pos = udebug_pause_pos;
+ } else if (debug_tag & 0x20000)
+ dec->ucode_pause_pos = 0xffffffff;
+ if (dec->ucode_pause_pos)
+ reset_process_time(dec);
+ else
+ WRITE_VREG(DEBUG_REG1, 0);
+ } else if (debug_tag != 0) {
+ pr_info(
+ "dbg%x: %x lcu %x stream crc %x, shiftbytes 0x%x decbytes 0x%x\n", READ_HREG(DEBUG_REG1),
+ READ_HREG(DEBUG_REG2),
+ READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
+ dec->start_shift_bytes);
+ if ((debug & AVS3_DBG_SAO_CRC) &&
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5)) {
+ unsigned old_crc = READ_VREG(HEVC_SAO_CRC);
+ int count = 0;
+ while (1) {
+ unsigned crc;
+ crc = READ_VREG(HEVC_SAO_CRC);
+ if (crc == old_crc) {
+ pr_info("stable HEVC_SAO_CRC = %x, count=%d\n", crc, count);
+ break;
+ }
+ count++;
+ old_crc = crc;
+ if (count > 100) {
+ pr_info("read HEVC_SAO_CRC = %x\n", crc);
+ count = 0;
+ }
+ }
+ }
+
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == dec->decode_idx) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_HREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ dec->ucode_pause_pos = udebug_pause_pos;
+ }
+ if (dec->ucode_pause_pos)
+ reset_process_time(dec);
+ else
+ WRITE_VREG(DEBUG_REG1, 0);
+ /*if (dec->dec_status) {
+ return IRQ_WAKE_THREAD;
+ } else*/ {
+ //dec->process_busy = 0;
+ }
+ }
+}
+
+static irqreturn_t vavs3_isr_thread_fn(int irq, void *data)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)data;
+ DEC_CTX *ctx = &dec->avs3_dec.ctx;
+ unsigned int dec_status = dec->dec_status;
+ int i, ret;
+ int32_t start_code = 0;
+#ifdef NEW_FB_CODE
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+#endif
+ unsigned char avs3_bi_mid_ptr;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+#if 0
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s decode_status 0x%x process_state %d lcu 0x%x\n",
+ __func__, dec_status, dec->process_state,
+ READ_VREG(HEVC_PARSER_LCU_START));
+#else
+ if (debug & AVS3_DBG_IRQ_EVENT) {
+ if (dec->front_back_mode != 1)
+ avs3_print(dec, 0,
+ "avs3 isr dec status = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x)\n",
+ dec_status, READ_HREG(DEBUG_REG1), READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR)
+ );
+ else
+ avs3_print(dec, 0,
+ "avs3 isr dec status = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) [BE] pc %x psr %x DEC_STATUS %x\n",
+ dec_status, READ_HREG(DEBUG_REG1), READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ READ_VREG(HEVC_MPC_E_DBE),
+ READ_VREG(HEVC_MPSR_DBE),
+ READ_VREG(HEVC_DEC_STATUS_DBE)
+ );
+ }
+
+ if (udebug_flag) {
+ uint debug_tag = READ_HREG(DEBUG_REG1);
+
+ if (debug_tag != 0) {
+ handle_ucode_dbg(dec, debug_tag);
+ //dec->process_busy = 0;
+ //return IRQ_HANDLED;
+ }
+ }
+
+#endif
+
+ if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+ (dec_status == AVS3_HEAD_PIC_PB_READY)) {
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START, TRACE_BASIC);
+ } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START, TRACE_BASIC);
+ }
+
+#ifndef G12A_BRINGUP_DEBUG
+ if (dec->eos) {
+ goto irq_handled_exit;
+ }
+#endif
+ dec->wait_buf = 0;
+ if (dec_status == AVS3_DECODE_BUFEMPTY) {
+ if (dec->m_ins_flag) {
+ if (!vdec_frame_based(hw_to_vdec(dec)))
+ dec_again_process(dec);
+ else {
+ dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ amhevc_stop_f();
+ } else
+#endif
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
+ }
+ goto irq_handled_exit;
+ } else if ((dec_status == HEVC_DECPIC_DATA_DONE) ||
+ (dec_status == HEVC_DECPIC_DATA_ERROR)) {
+ struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+ u32 shiftbytes = 0;
+
+ if (pic != NULL)
+ pic->poc = ctx->info.pic_header.dtr;
+ mutex_lock(&dec->slice_header_lock);
+ mutex_unlock(&dec->slice_header_lock);
+ if (dec_status == HEVC_DECPIC_DATA_DONE)
+ vdec->front_pic_done = true;
+
+ if (pic && (vdec_stream_based(hw_to_vdec(dec)))
+ && (dec_status == HEVC_DECPIC_DATA_DONE))
+ pic->stream_size = vdec_get_stream_size(hw_to_vdec(dec));
+
+ WRITE_VREG(HEVC_PARSER_DEBUG_IDX, 0xb);
+ shiftbytes = READ_VREG(HEVC_PARSER_DEBUG_DAT) & 0xffff;
+ if ((shiftbytes > over_decoder_shiftbytes) && (pic != NULL)) {
+ pic->error_mark = 1;
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS, "%s: over decoder(0x%x),set pic error\n",
+ __func__, shiftbytes);
+ }
+
+ if (dec->front_back_mode == 0) {
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "HEVC_DECPIC_DATA_DONE: decode_idx %d stream crc %x shiftcnt=0x%x, HEVC_SAO_CRC %x HEVC_SAO_MMU_STATUS %x\n",
+ dec->frame_count,
+ READ_VREG(HEVC_STREAM_CRC),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_SAO_CRC),
+ READ_VREG(HEVC_SAO_MMU_STATUS));
+
+ if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+ pr_info("HEVC_CM_BODY_START_ADDR = %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR));
+ pr_info("HEVC_CM_HEADER_START_ADDR = %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR));
+ pr_info("HEVC_SAO_Y_START_ADDR = %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR));
+ pr_info("HEVC_SAO_Y_LENGTH = %x\n", READ_VREG(HEVC_SAO_Y_LENGTH));
+ pr_info("HEVC_SAO_C_START_ADDR = %x\n", READ_VREG(HEVC_SAO_C_START_ADDR));
+ pr_info("HEVC_SAO_C_LENGTH = %x\n", READ_VREG(HEVC_SAO_C_LENGTH));
+ pr_info("HEVC_SAO_Y_WPTR = %x\n", READ_VREG(HEVC_SAO_Y_WPTR));
+ pr_info("HEVC_SAO_C_WPTR = %x\n", READ_VREG(HEVC_SAO_C_WPTR));
+
+ pr_info("HEVC_SAO_CTRL0 = %x\n", READ_VREG(HEVC_SAO_CTRL0));
+ pr_info("HEVC_SAO_CTRL1 = %x\n", READ_VREG(HEVC_SAO_CTRL1));
+ pr_info("HEVC_SAO_CTRL2 = %x\n", READ_VREG(HEVC_SAO_CTRL2));
+ pr_info("HEVC_SAO_CTRL3 = %x\n", READ_VREG(HEVC_SAO_CTRL3));
+ pr_info("HEVC_SAO_CTRL4 = %x\n", READ_VREG(HEVC_SAO_CTRL4));
+ pr_info("HEVC_SAO_CTRL5 = %x\n", READ_VREG(HEVC_SAO_CTRL5));
+
+ }
+ if ((debug & AVS3_DBG_NOT_RECYCLE_MMU_TAIL) == 0)
+ avs3_recycle_mmu_buf_tail(dec);
+ } else {
+ if (pic != NULL)
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "FrontEnd data done %d, fb_rd_pos %d, pic index %d, poc %d stream crc %x shiftbyte %x, shiftstatus 0x%x\n",
+ avs3_dec->frontend_decoded_count, avs3_dec->fb_rd_pos, pic->index, pic->poc,
+ READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT), READ_VREG(HEVC_SHIFT_STATUS));
+ else
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "FrontEnd data done %d, fb_rd_pos %d, stream crc %x shiftbyte %x\n",
+ avs3_dec->frontend_decoded_count, avs3_dec->fb_rd_pos,
+ READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ }
+
+ dec->start_decoding_flag |= 0x3;
+ if (dec->m_ins_flag) {
+ if (dec_status == HEVC_DECPIC_DATA_ERROR &&
+ (pic != NULL)) {
+ pic->error_mark = 1;
+ }
+
+ set_cuva_data(dec);
+ update_decoded_pic(dec);
+ check_pic_error(dec, pic);
+ get_picture_qos_info(dec, false);
+ dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ /*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+ if (pic != NULL)
+ front_decpic_done_update(dec, 1); /*not multi pictures in one packe*/
+ } else
+#endif
+ amhevc_stop();
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_EDN, TRACE_BASIC);
+ avs3_work_implement(dec);
+ }
+
+ goto irq_handled_exit;
+ }
+#if 0
+ if (dec_status == AVS3_EOS) {
+ if (dec->m_ins_flag)
+ reset_process_time(dec);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "AVS3_EOS, flush buffer\r\n");
+
+ avs3_post_process(&dec->avs3_dec);
+ avs3_prepare_display_buf(dec);
+
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "send AVS3_10B_DISCARD_NAL\r\n");
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_10B_DISCARD_NAL);
+ if (dec->m_ins_flag) {
+ update_decoded_pic(dec);
+ dec->dec_result = DEC_RESULT_DONE;
+ amhevc_stop();
+ vdec_schedule_work(&dec->work);
+ }
+ goto irq_handled_exit;
+ } else
+#endif
+ if (dec_status == AVS3_DECODE_OVER_SIZE) {
+ avs3_print(dec, 0,
+ "avs3 decode oversize !!\n");
+ debug |= (AVS3_DBG_DIS_LOC_ERROR_PROC |
+ AVS3_DBG_DIS_SYS_ERROR_PROC);
+ dec->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
+ goto irq_handled_exit;
+ }
+
+ if (dec_status == AVS3_HEAD_SEQ_READY)
+ start_code = SEQUENCE_HEADER_CODE;
+ else if (dec_status == AVS3_HEAD_PIC_I_READY)
+ start_code = I_PICTURE_START_CODE;
+ else if (dec_status == AVS3_HEAD_PIC_PB_READY)
+ start_code = PB_PICTURE_START_CODE;
+ else if (dec_status == AVS3_HEAD_SEQ_END_READY)
+ start_code = SEQUENCE_END_CODE;
+ else if (dec_status == AVS3_STARTCODE_SEARCH_DONE)
+ /*VIDEO_EDIT_CODE*/
+ start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
+ else
+ goto irq_handled_exit_and_start_timer;
+
+ if (dec->process_state ==
+ PROC_STATE_HEAD_AGAIN
+ ) {
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)) {
+ avs3_print(dec, 0,
+ "PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n",
+ start_code);
+ goto irq_handled_exit_and_start_timer;
+ } else {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "PROC_STATE_HEAD_AGAIN, start_code 0x%x\r\n",
+ start_code);
+ dec->process_state = PROC_STATE_HEAD_DONE;
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ goto irq_handled_exit_and_start_timer;
+ }
+ } else if (dec->process_state ==
+ PROC_STATE_DECODE_AGAIN) {
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "PROC_STATE_DECODE_AGAIN=> decode_slice, start_code 0x%x\r\n",
+ start_code);
+ if ((dec->front_back_mode == 1) && (dec->pic_list_init_flag == 0) && (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATE_DONE)) {
+ dec->pic_list_init_flag = 1;
+ goto alloc_buffer_done;
+ }
+ else
+ goto decode_slice;
+ } else {
+ avs3_print(dec, 0,
+ "PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
+ start_code);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ goto irq_handled_exit_and_start_timer;
+ }
+ }
+
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)
+ || (start_code == SEQUENCE_END_CODE)
+ || (start_code == VIDEO_EDIT_CODE)) {
+
+ if (dec->avs3_dec.cur_pic != NULL) {
+#ifndef NEW_FB_CODE
+ int32_t ii;
+#endif
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "before post process");
+
+ ret = avs3_bufmgr_post_process(avs3_dec);
+
+ if (ret == 2) {
+ avs3_print(dec, AVS3_DBG_BUFMGR, "avs3 same poc %d\n",
+ avs3_dec->ctx.ptr);
+ pic_backend_ref_operation(dec, dec->avs3_dec.cur_pic, 0);
+ }
+
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(&dec->avs3_dec, "after post_process");
+
+ if ((dec->front_back_mode != 1) || !efficiency_mode)
+ avs3_prepare_display_buf(dec);
+ dec->avs3_dec.cur_pic = NULL;
+#ifdef NEW_FB_CODE
+ //release_free_mmu_buffers(dec);
+#else
+#endif
+ }
+ }
+
+ if ((dec_status == AVS3_HEAD_PIC_I_READY)
+ || (dec_status == AVS3_HEAD_PIC_PB_READY)) {
+
+ if (debug & AVS3_DBG_SEND_PARAM_WITH_REG) {
+ get_rpm_param(
+ &dec->avs3_dec.param);
+ } else {
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START, TRACE_BASIC);
+ for (i = 0; i < (RPM_VALID_END - RPM_BEGIN); i += 4) {
+ int ii;
+ for (ii = 0; ii < 4; ii++)
+ dec->avs3_dec.param.l.data[i + ii] =
+ dec->rpm_ptr[i + 3 - ii];
+ }
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END, TRACE_BASIC);
+ }
+#if 0 //def SANITY_CHECK
+ if (dec->avs3_dec.param.p.num_of_ref_cur >
+ dec->avs3_dec.ref_maxbuffer) {
+ pr_info("Warning: Wrong num_of_ref_cur %d, force to %d\n",
+ dec->avs3_dec.param.p.num_of_ref_cur,
+ dec->avs3_dec.ref_maxbuffer);
+ dec->avs3_dec.param.p.num_of_ref_cur =
+ dec->avs3_dec.ref_maxbuffer;
+ }
+#endif
+
+ debug_buffer_mgr_more(dec);
+ get_frame_rate(&dec->avs3_dec.param, dec);
+
+ if (dec->avs3_dec.param.p.video_signal_type & (1<<14)) {
+ union param_u *pPara;
+
+ avs3_print(dec, AVS3_DBG_HDR_INFO, "avs3 HDR meta data present\n");
+ pPara = &dec->avs3_dec.param;
+
+ /*clean this flag*/
+ pPara->p.video_signal_type &= ~(1<<14);
+
+ dec->vf_dp.present_flag = 1;
+
+ dec->vf_dp.white_point[0]
+ = pPara->p.white_point_x;
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "white_point[0]:0x%x\n",
+ dec->vf_dp.white_point[0]);
+
+ dec->vf_dp.white_point[1]
+ = pPara->p.white_point_y;
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "white_point[1]:0x%x\n",
+ dec->vf_dp.white_point[1]);
+
+ for (i = 0; i < 3; i++) {
+ dec->vf_dp.primaries[i][0]
+ = pPara->p.display_primaries_x[i];
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "primaries[%d][0]:0x%x\n",
+ i,
+ dec->vf_dp.primaries[i][0]);
+ }
+
+ for (i = 0; i < 3; i++) {
+ dec->vf_dp.primaries[i][1]
+ = pPara->p.display_primaries_y[i];
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "primaries[%d][1]:0x%x\n",
+ i,
+ dec->vf_dp.primaries[i][1]);
+ }
+
+ dec->vf_dp.luminance[0]
+ = pPara->p.max_display_mastering_luminance;
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "luminance[0]:0x%x\n",
+ dec->vf_dp.luminance[0]);
+
+ dec->vf_dp.luminance[1]
+ = pPara->p.min_display_mastering_luminance;
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "luminance[1]:0x%x\n",
+ dec->vf_dp.luminance[1]);
+
+ dec->vf_dp.content_light_level.present_flag
+ = 1;
+ dec->vf_dp.content_light_level.max_content
+ = pPara->p.max_content_light_level;
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "max_content:0x%x\n",
+ dec->vf_dp.content_light_level.max_content);
+
+ dec->vf_dp.content_light_level.max_pic_average
+ = pPara->p.max_picture_average_light_level;
+
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "max_pic_average:0x%x\n",
+ dec->vf_dp.content_light_level.max_pic_average);
+ }
+ if (dec->video_ori_signal_type !=
+ ((dec->avs3_dec.param.p.video_signal_type << 16)
+ | dec->avs3_dec.param.p.color_description)) {
+ u32 v = dec->avs3_dec.param.p.video_signal_type;
+ u32 c = dec->avs3_dec.param.p.color_description;
+ u32 convert_c = c;
+
+ if (v & 0x2000) {
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "video_signal_type present:\n");
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ " %s %s\n",
+ video_format_names[(v >> 10) & 7],
+ ((v >> 9) & 1) ?
+ "full_range" : "limited");
+ if (v & 0x100) {
+ u32 transfer;
+ u32 maxtrix;
+
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "color_description present:\n");
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "color_primarie = %d\n",
+ v & 0xff);
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "transfer_characteristic = %d\n",
+ (c >> 8) & 0xff);
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ " matrix_coefficient = %d\n",
+ c & 0xff);
+
+ transfer = (c >> 8) & 0xFF;
+ if (transfer >= 15)
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "unsupport transfer_characteristic\n");
+ else if (transfer == 14)
+ transfer = 18; /* HLG */
+ else if (transfer == 13)
+ transfer = 32;
+ else if (transfer == 12)
+ transfer = 16;
+ else if (transfer == 11)
+ transfer = 15;
+
+ maxtrix = c & 0xFF;
+ if (maxtrix >= 10)
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ "unsupport matrix_coefficient\n");
+ else if (maxtrix == 9)
+ maxtrix = 10;
+ else if (maxtrix == 8)
+ maxtrix = 9;
+
+ convert_c = (transfer << 8) | (maxtrix);
+
+ avs3_print(dec, AVS3_DBG_HDR_INFO,
+ " convered c:0x%x\n",
+ convert_c);
+ }
+ }
+
+ if (enable_force_video_signal_type)
+ dec->video_signal_type
+ = force_video_signal_type;
+ else {
+ dec->video_signal_type
+ = (v << 16) | convert_c;
+
+ dec->video_ori_signal_type
+ = (v << 16) | c;
+ }
+
+ video_signal_type = dec->video_signal_type;
+ }
+ }
+
+#if 0
+ if ((debug_again & 0x4) &&
+ dec->process_state ==
+ PROC_STATE_INIT) {
+ if (start_code == PB_PICTURE_START_CODE) {
+ dec->process_state = PROC_STATE_TEST1;
+ dec_again_process(dec);
+ goto irq_handled_exit;
+ }
+ }
+#endif
+
+ if (start_code == SEQUENCE_HEADER_CODE) {
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ " ## SEQUENCE_HEADER_CODE ##\n");
+ dec->avs3_dec.seq_change_flag = 1;
+ dec->avs3_dec.init_hw_flag = 0;
+ }
+
+ if (dec->has_i_frame == 0 &&
+ start_code == PB_PICTURE_START_CODE) {
+ dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+ else
+#endif
+ amhevc_stop();
+ avs3_print(dec, 0, "no i frame!!\n");
+ vdec_schedule_work(&dec->work);
+ goto irq_handled_exit;
+ }
+
+ mutex_lock(&dec->slice_header_lock);
+ if (start_code == SEQUENCE_END_CODE) {
+ avs3_bufmgr_process(&dec->avs3_dec, SEQUENCE_END_CODE);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ } else if (start_code == SEQUENCE_HEADER_CODE ||
+ start_code == VIDEO_EDIT_CODE) {
+ /*if (dec->m_ins_flag &&
+ vdec_frame_based(hw_to_vdec(dec)))
+ dec->start_decoding_flag |= 0x1;*/
+ dec->process_state = PROC_STATE_HEAD_DONE;
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ } else if (start_code == I_PICTURE_START_CODE ||
+ start_code == PB_PICTURE_START_CODE) {
+ avs3_frame_t *cur_pic;
+ ret = 0;
+#ifdef NEW_FB_CODE
+ if (dec->m_ins_flag) {
+ u32 width = avs3_dec->param.p.sqh_horizontal_size;
+ u32 height = avs3_dec->param.p.sqh_vertical_size;
+ u8 bit_depth = (u8)avs3_dec->param.p.sqh_encoding_precision;
+ int cur_mmu_fb_4k_number = 0;
+
+ width = ((width + MINI_SIZE - 1) >> MINI_SIZE_LOG2) << MINI_SIZE_LOG2;
+ height = ((height + MINI_SIZE - 1) >> MINI_SIZE_LOG2) << MINI_SIZE_LOG2;
+ bit_depth = (bit_depth == 2) ? 10 : 8;
+ cur_mmu_fb_4k_number = dec->fb_ifbuf_num * avs3_mmu_page_num(dec,
+ width, height, (bit_depth == 10));
+
+ if ((dec->front_back_mode == 1) &&
+ (start_code == I_PICTURE_START_CODE) &&
+ (dec->mmu_fb_4k_number < cur_mmu_fb_4k_number) &&
+ (cur_mmu_fb_4k_number > 0)) {
+ amhevc_stop_f();
+ avs3_print(dec, AVS3_DBG_BUFMGR, "need realloc mmu fb\n");
+ uninit_mmu_fb_bufstate(dec);
+ init_mmu_fb_bufstate(dec, cur_mmu_fb_4k_number);
+ dec_again_process(dec);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+ }
+#endif
+
+ avs3_print(dec, AVS3_DBG_BUFMGR, "========== Picture %d\n", avs3_dec->decode_id++);
+ //avs3_dec->ins_offset = 0; //move to init_pic_list_hw_fb
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "before bufmgr process");
+ if (is_avs3_print_param()) {
+ print_param(&avs3_dec->param);
+ print_alf_param(&avs3_dec->param);
+ }
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, 9, TRACE_BASIC);
+
+ if (avs3_dec->seq_change_flag) {
+ avs3_bufmgr_process(avs3_dec, SEQUENCE_HEADER_CODE);
+ avs3_dec->seq_change_flag = 0;
+ }
+ ret = avs3_bufmgr_process(avs3_dec, start_code);
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "after bufmgr process");
+
+
+ if ((ret == 0) && (avs3_dec->cur_pic != NULL)) {
+ cur_pic = avs3_dec->cur_pic;
+#ifdef NEW_FRONT_BACK_CODE
+ cur_pic->width = avs3_dec->img.width;
+ cur_pic->height = avs3_dec->img.height;
+ cur_pic->depth = avs3_dec->input.sample_bit_depth;
+#endif
+
+ if (!dec->m_ins_flag)
+ dec->slice_idx++;
+ else
+ release_cuva_data(cur_pic);
+ }
+
+#if 0
+ if (avs3_dec->init_hw_flag == 0) {
+ //from simulation
+ init_pic_list_hw(avs3_dec, buf_spec, mc_buf_spec);
+ avs3_dec->init_hw_flag = 1;
+ }
+#else
+ if ((dec->pic_list_init_flag == 0) && (ctx->init_flag != 0)) {
+ int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+
+ if ((dec->front_back_mode == 1) && (paral_alloc_buffer_mode & 1)) {
+ if ((dec->pic_list_wait_alloc_done_flag == BUFFER_INIT)) {
+ dec->dec_result = DEC_RESULT_WAIT_BUFFER;
+ avs3_print(dec, AVS3_DBG_BUFMGR, "alloc buffer\n");
+ vdec_schedule_work(&dec->work);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+ } else
+ init_pic_list(dec, lcu_size_log2);
+
+#ifdef NEW_FB_CODE
+ if ((dec->front_back_mode == 1) ||
+ (dec->front_back_mode == 3))
+ init_pic_list_hw_fb(dec);
+ else
+#endif
+ init_pic_list_hw(dec);
+#endif
+ dec->pic_list_init_flag = 1;
+ }
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, 10, TRACE_BASIC);
+alloc_buffer_done:
+
+#ifdef I_ONLY_SUPPORT
+ if ((start_code == PB_PICTURE_START_CODE) &&
+ (dec->i_only & 0x2))
+ ret = -2;
+#endif
+
+ if (ret == 0) {
+#ifdef AVS3_10B_MMU
+ if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ ) {
+#if 0
+//DDD
+ if (cur_pic->index == -1) {
+ pr_info("dec->avs3_dec.ctx.pic %p\n", dec->avs3_dec.ctx.pic);
+ print_pic_pool(avs3_dec, "error");
+ }
+#endif
+ ret = avs3_alloc_mmu(dec,
+ cur_pic->index,
+ cur_pic->width,
+ cur_pic->height,
+ cur_pic->depth,
+ dec->frame_mmu_map_addr);
+ if (ret >= 0) {
+ dec->cur_fb_idx_mmu =
+ cur_pic->index;
+ cur_pic->mmu_alloc_flag = 1;
+ } else
+ pr_err("can't alloc need mmu1,idx %d ret =%d\n",
+ cur_pic->index,
+ ret);
+ }
+#endif
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable
+#ifdef NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ ) {
+ ret = avs3_alloc_dw_mmu(dec,
+ cur_pic->index,
+ cur_pic->width,
+ cur_pic->height,
+ cur_pic->depth,
+ dec->dw_frame_mmu_map_addr);
+ if (ret >= 0) {
+ dec->cur_fb_idx_mmu =
+ cur_pic->index;
+ cur_pic->mmu_alloc_flag = 1;
+ } else
+ pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
+ dec->avs3_dec.cur_pic->index,
+ ret);
+ }
+#endif
+ }
+
+#ifndef MV_USE_FIXED_BUF
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+
+ if (ret == 0 && cur_pic->
+ mpred_mv_wr_start_addr == 0
+#if 0 //def NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ ) {
+ unsigned long buf_addr;
+ unsigned mv_buf_size = get_mv_buf_size(
+ dec,
+ cur_pic->width,
+ cur_pic->height);
+ int i = cur_pic->index;
+ /*if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ mv_buf_size = 0x120000 * 4;*/
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ MV_BUFFER_IDX(i),
+ mv_buf_size,
+ DRIVER_NAME,
+ &buf_addr) < 0) {
+ ret = -1;
+ } else {
+ cur_pic->mpred_mv_wr_start_addr = buf_addr;
+ if (!vdec_secure(hw_to_vdec(dec)))
+ codec_mm_memset(cur_pic->mpred_mv_wr_start_addr,
+ 0, mv_buf_size);
+ }
+ }
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+#endif
+ if (ret) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "avs3_bufmgr_process=> %d, AVS3_10B_DISCARD_NAL\r\n",
+ ret);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_10B_DISCARD_NAL);
+ #ifdef AVS3_10B_MMU
+ if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+ && (dec->front_back_mode != 1)
+#endif
+ )
+ avs3_recycle_mmu_buf(dec);
+ #endif
+ if (dec->m_ins_flag) {
+ int slice_type = 0;
+
+#ifdef NEW_FB_CODE
+ mutex_lock(&dec->fb_mutex);
+#endif
+ if (avs3_dec->cur_pic != NULL) {
+ slice_type = avs3_dec->cur_pic->slice_type;
+ } else {
+ slice_type = dec->avs3_dec.param.p.pic_header_slice_type;
+ }
+
+ dec->gvs->frame_count++;
+ dec->gvs->drop_frame_count++;
+ dec->gvs->error_frame_count++;
+
+ if (slice_type == SLICE_I) {
+ dec->gvs->i_lost_frames++;
+ dec->gvs->i_concealed_frames++;
+ dec->gvs->i_decoded_frames++;
+ } else if (slice_type == SLICE_P) {
+ dec->gvs->p_lost_frames++;
+ dec->gvs->p_concealed_frames++;
+ dec->gvs->p_decoded_frames++;
+ } else if (slice_type == SLICE_B) {
+ dec->gvs->b_lost_frames++;
+ dec->gvs->b_concealed_frames++;
+ dec->gvs->b_decoded_frames++;
+ }
+
+#ifdef NEW_FB_CODE
+ mutex_unlock(&dec->fb_mutex);
+#endif
+
+ dec->dec_result = DEC_RESULT_ERROR;
+
+ vdec_schedule_work(&dec->work);
+ }
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ } else {
+ if (avs3_dec->cur_pic != NULL) {
+ dec->gvs->frame_count++;
+ if (avs3_dec->cur_pic->slice_type == SLICE_I) {
+ dec->gvs->i_decoded_frames++;
+ } else if (avs3_dec->cur_pic->slice_type == SLICE_P) {
+ dec->gvs->p_decoded_frames++;
+ } else if (avs3_dec->cur_pic->slice_type == SLICE_B) {
+ dec->gvs->b_decoded_frames++;
+ }
+ }
+
+ dec->avs3_dec.cur_pic->stream_offset =
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+ /*
+ struct PIC_BUFFER_CONFIG_s *cur_pic
+ = &cm->cur_frame->buf;
+ cur_pic->decode_idx = dec->frame_count;
+ */
+ if (!dec->m_ins_flag) {
+ dec->frame_count++;
+ decode_frame_count[dec->index]
+ = dec->frame_count;
+ }
+ /*MULTI_INSTANCE_SUPPORT*/
+ if (dec->chunk) {
+ dec->avs3_dec.cur_pic->pts =
+ dec->chunk->pts;
+ dec->avs3_dec.cur_pic->pts64 =
+ dec->chunk->pts64;
+ }
+ if (vdec->mvfrm)
+ dec->avs3_dec.cur_pic->frame_size = vdec->mvfrm->frame_size;
+decode_slice:
+ dec->avs3_dec.cur_pic->double_write_mode
+ = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+ dec->avs3_dec.cur_pic->triple_write_mode
+ = get_triple_write_mode(dec);
+#endif
+
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START, TRACE_BASIC);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+ if (!efficiency_mode) {
+ config_mc_buffer_fb(dec);
+ config_mcrcc_axi_hw_fb(dec);
+ }
+
+ config_mpred_hw_fb(dec);
+
+ if (!efficiency_mode) {
+ config_dblk_hw_fb(dec);
+ config_sao_hw_fb(dec);
+ config_alf_hw_fb(dec);
+ }
+ } else {
+#endif
+ config_mc_buffer(dec);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 0)
+#endif
+ config_mcrcc_axi_hw(dec);
+ config_mpred_hw(dec);
+ config_dblk_hw(dec);
+ config_sao_hw(dec);
+ config_alf_hw(dec);
+#ifdef NEW_FB_CODE
+ }
+#endif
+ decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END, TRACE_BASIC);
+
+ // HEVC_PARSER_HEADER_INFO :
+ // bit[30] -- avs3_bi_mid_ptr // (ctx->ptr - ctx->refp[0][REFP_0].ptr == ctx->refp[0][REFP_1].ptr - ctx->ptr)
+ // bit[21:16] -- ctx->dpm.num_refp[REFP_1]
+ // bit[15:10] -- ctx->dpm.num_refp[REFP_0]
+ avs3_bi_mid_ptr = (ctx->ptr - ctx->refp[0][REFP_0].ptr == ctx->refp[0][REFP_1].ptr - ctx->ptr);
+ WRITE_VREG(HEVC_PARSER_HEADER_INFO, (ctx->dpm.num_refp[REFP_0]<<10) | (ctx->dpm.num_refp[REFP_1]<<16) | (avs3_bi_mid_ptr<<30));
+
+#ifdef BUFMGR_ONLY
+ WRITE_VREG(NAL_SEARCH_CTL, 0x1);
+#else
+ WRITE_VREG(NAL_SEARCH_CTL, 0);
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+ if ((!efficiency_mode) && (dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3)) {
+
+ WRITE_BACK_RET(avs3_dec);
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "write system instruction, ins_offset = %d, addr = 0x%x\n",
+ avs3_dec->ins_offset, avs3_dec->fr.sys_imem_ptr);
+
+ avs3_dec->sys_imem_ptr = avs3_dec->fr.sys_imem_ptr;
+ avs3_dec->sys_imem_ptr_v = avs3_dec->fr.sys_imem_ptr_v;
+
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset > 512) {
+ avs3_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs3_dec->ins_offset);
+ avs3_dec->ins_offset = 512;
+ } else if (avs3_dec->ins_offset < 256) {
+ avs3_dec->ins_offset = 256;
+ WRITE_BACK_RET(avs3_dec);
+ }
+
+ memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+ avs3_dec->sys_imem_ptr_v,
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+ avs3_dec->sys_imem_ptr += 2 * FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs3_dec->sys_imem_ptr_v += 2 * FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+ if (avs3_dec->ins_offset > 256) {
+ avs3_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs3_dec->ins_offset);
+ avs3_dec->ins_offset = 256;
+ }
+
+ memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+ avs3_dec->sys_imem_ptr_v,
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+ avs3_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs3_dec->sys_imem_ptr_v +=FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+ if (avs3_dec->sys_imem_ptr >= avs3_dec->fb_buf_sys_imem.buf_end) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "sys_imem_ptr is 0x%x, wrap around\n", avs3_dec->sys_imem_ptr);
+ avs3_dec->sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+ avs3_dec->sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr;
+ }
+ if (dec->front_back_mode == 1) {
+ //WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+ //imem_count++;
+ WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+ }
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ } else {
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ }
+#endif
+
+ //WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ //pr_info("!!write AVS3_ACTION_DONE %d\n", __LINE__);
+
+ if ((debug_again & 0x2) &&
+ dec->process_state ==
+ PROC_STATE_INIT) {
+ dec->process_state = PROC_STATE_DECODING;
+ dec_again_process(dec);
+ mutex_unlock(&dec->slice_header_lock);
+ goto irq_handled_exit;
+ }
+
+ dec->process_state = PROC_STATE_DECODING;
+
+ }
+ if (start_code == I_PICTURE_START_CODE)
+ dec->has_i_frame = 1;
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC);
+ }
+
+ if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+ (dec_status == AVS3_HEAD_PIC_PB_READY)) {
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END, TRACE_PERFORMANCE_DETAIL);
+ }
+ if (efficiency_mode && (dec->front_back_mode == 1)) {
+ if (dec->pic_list_init_flag) {
+#ifdef NEW_FB_CODE
+ if ((dec->front_back_mode == 1) ||
+ (dec->front_back_mode == 3))
+ init_pic_list_hw_fb(dec);
+ else
+#endif
+ init_pic_list_hw(dec);
+ }
+
+ if ((dec->front_back_mode == 1 || dec->front_back_mode == 3) &&
+ (start_code == I_PICTURE_START_CODE ||
+ start_code == PB_PICTURE_START_CODE)) {
+
+ int32_t g_WqMDefault4x4[16] = {
+ 64, 64, 64, 68,
+ 64, 64, 68, 72,
+ 64, 68, 76, 80,
+ 72, 76, 84, 96
+ };
+
+ int32_t g_WqMDefault8x8[64] = {
+ 64, 64, 64, 64, 68, 68, 72, 76,
+ 64, 64, 64, 68, 72, 76, 84, 92,
+ 64, 64, 68, 72, 76, 80, 88, 100,
+ 64, 68, 72, 80, 84, 92, 100, 112,
+ 68, 72, 80, 84, 92, 104, 112, 128,
+ 76, 80, 84, 92, 104, 116, 132, 152,
+ 96, 100, 104, 116, 124, 140, 164, 188,
+ 104, 108, 116, 128, 152, 172, 192, 216
+ };
+ config_mc_buffer_fb(dec);
+ config_mcrcc_axi_hw_fb(dec);
+ config_dblk_hw_fb(dec);
+ config_sao_hw_fb(dec);
+ config_alf_hw_fb(dec);
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+ for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+ for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+ // 4x4
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+ for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+ // 8x8
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+ for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+ WRITE_BACK_RET(avs3_dec);
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "write system instruction, ins_offset = %d, addr = 0x%x\n",
+ avs3_dec->ins_offset, avs3_dec->fr.sys_imem_ptr);
+
+ avs3_dec->sys_imem_ptr = avs3_dec->fr.sys_imem_ptr;
+ avs3_dec->sys_imem_ptr_v = avs3_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+ if (avs3_dec->ins_offset > 512) {
+ avs3_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs3_dec->ins_offset);
+ avs3_dec->ins_offset = 512;
+ } else if (avs3_dec->ins_offset < 256) {
+ avs3_dec->ins_offset = 256;
+ WRITE_BACK_RET(avs3_dec);
+ }
+ memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+ avs3_dec->sys_imem_ptr_v,
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+
+ avs3_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs3_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+ if (avs3_dec->ins_offset > 256) {
+ avs3_print(dec, 0,
+ "!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs3_dec->ins_offset);
+ avs3_dec->ins_offset = 256;
+ }
+ memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+ //copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+ avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+ "cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+ avs3_dec->sys_imem_ptr_v,
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+ ((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+ avs3_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+ avs3_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+ if (avs3_dec->sys_imem_ptr >= avs3_dec->fb_buf_sys_imem.buf_end) {
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "sys_imem_ptr is 0x%x, wrap around\n", avs3_dec->sys_imem_ptr);
+ avs3_dec->sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+ avs3_dec->sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr;
+ }
+ if (dec->front_back_mode == 1) {
+ //WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+ //WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+ //imem_count++;
+ WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+ }
+ }
+
+ if ((start_code == I_PICTURE_START_CODE)
+ || (start_code == PB_PICTURE_START_CODE)
+ || (start_code == SEQUENCE_END_CODE)
+ || (start_code == VIDEO_EDIT_CODE)) {
+ avs3_prepare_display_buf(dec);
+ }
+ }
+ mutex_unlock(&dec->slice_header_lock);
+
+irq_handled_exit_and_start_timer:
+ if (dec->m_ins_flag)
+ start_process_time(dec);
+
+irq_handled_exit:
+
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t vavs3_isr(int irq, void *data)
+{
+ //int i;
+ unsigned int dec_status;
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)data;
+ uint debug_tag = 0;
+#if 0
+ if ((debug & AVS3_DBG_BE_SIMULATE_IRQ)
+ &&(READ_VREG(DEBUG_REG1_DBE) ||
+ READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ }
+#endif
+
+ dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
+ if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC);
+ }
+
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+ (dec_status == AVS3_HEAD_PIC_PB_READY)) {
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_HEAD_DONE, TRACE_PERFORMANCE_DETAIL);
+ } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_PIC_DONE, TRACE_PERFORMANCE_DETAIL);
+ }
+
+
+ if (!dec)
+ return IRQ_HANDLED;
+ if (dec->init_flag == 0)
+ return IRQ_HANDLED;
+ if (dec->process_busy)/*on process.*/
+ return IRQ_HANDLED;
+ dec->dec_status = dec_status;
+ dec->process_busy = 1;
+#if 0
+ if (debug & AVS3_DBG_IRQ_EVENT) {
+ if (dec->front_back_mode != 1)
+ avs3_print(dec, 0,
+ "avs3 isr dec status = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_SAO_CRC %x\n",
+ dec_status, READ_HREG(DEBUG_REG1), READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+ READ_VREG(HEVC_SAO_CRC) : 0
+ );
+ else {
+ avs3_print(dec, 0,
+ "avs3 isr dec status = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) [BE] pc %x psr %x DEC_STATUS %x shiftstatus 0x%x\n",
+ dec_status, READ_HREG(DEBUG_REG1), READ_VREG(HEVC_PARSER_LCU_START),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ READ_VREG(HEVC_MPC_E_DBE),
+ READ_VREG(HEVC_MPSR_DBE),
+ READ_VREG(HEVC_DEC_STATUS_DBE),
+ READ_VREG(HEVC_SHIFT_STATUS)
+ );
+ }
+ }
+#endif
+
+ if (udebug_flag)
+ debug_tag = READ_HREG(DEBUG_REG1);
+ if (debug_tag != 0) {
+#if 0
+ handle_ucode_dbg(dec, debug_tag);
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+#else
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_END, TRACE_BASIC);
+ return IRQ_WAKE_THREAD;
+#endif
+ }
+
+ if (!dec->m_ins_flag) {
+ if (dec->error_flag == 1) {
+ dec->error_flag = 2;
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ } else if (dec->error_flag == 3) {
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ }
+
+ if ((dec->pic_list_init_flag) &&
+ get_free_buf_count(dec) <= 0) {
+ /*
+ if (dec->wait_buf == 0)
+ pr_info("set wait_buf to 1\r\n");
+ */
+ dec->wait_buf = 1;
+ dec->process_busy = 0;
+ if (debug & AVS3_DBG_IRQ_EVENT)
+ avs3_print(dec, 0, "wait_buf\n");
+ return IRQ_HANDLED;
+ } else if (force_disp_pic_index) {
+ dec->process_busy = 0;
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (dec->m_ins_flag)
+ reset_process_time(dec);
+
+ decoder_trace(dec->trace.decode_time_name, DECODER_ISR_END, TRACE_BASIC);
+ return IRQ_WAKE_THREAD;
+}
+
+#ifdef NEW_FB_CODE
+static void avs3_check_timer_back_func(struct timer_list *timer)
+{
+ struct AVS3Decoder_s *dec = container_of(timer,
+ struct AVS3Decoder_s, timer_back);
+
+ if (dec->init_flag == 0) {
+ if (dec->stat & STAT_TIMER_BACK_ARM) {
+ mod_timer(&dec->timer_back, jiffies + PUT_INTERVAL);
+ }
+ return;
+ }
+
+ if (
+ (decode_timeout_val_back > 0) &&
+ (dec->start_process_time_back > 0) &&
+ ((1000 * (jiffies - dec->start_process_time_back) / HZ)
+ > decode_timeout_val_back)
+ ) {
+ if (dec->decode_timeout_count_back > 0)
+ dec->decode_timeout_count_back--;
+ if (dec->decode_timeout_count_back == 0)
+ timeout_process_back(dec);
+ }
+
+#if 0
+ if (debug & AVS3_DBG_BE_SIMULATE_IRQ) {
+ //struct vdec_s *vdec = hw_to_vdec(dec);
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ //if (avs3_back_irq_cb(vdec, 0) == IRQ_WAKE_THREAD)
+ // avs3_back_threaded_irq_cb(vdec, 0);
+ }
+#endif
+ if ((dec->start_process_time_back > 0) &&
+ (dec->decode_timeout_count_back != 0) &&
+ !(error_handle_policy & 0x4) &&
+ (decode_timeout_val_back > 0)) {
+ int current_monitor_data = 0;
+
+ WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (READ_VREG(HEVC_PATH_MONITOR_CTRL) & 0xfffffe0f) | 0x91);
+ current_monitor_data = READ_VREG(HEVC_PATH_MONITOR_DATA);
+ if (dec->last_monitor_data == current_monitor_data) {
+ if (dec->decode_timeout_count_back > 0)
+ dec->decode_timeout_count_back--;
+ if (dec->decode_timeout_count_back == 0) {
+ timeout_process_back(dec);
+ }
+ } else {
+ dec->decode_timeout_count_back = fast_timer_check_count;
+ }
+ dec->last_monitor_data = current_monitor_data;
+ mod_timer(timer, jiffies + 1);
+ } else
+ mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+#endif
+
+static void vavs3_put_timer_func(struct timer_list *timer)
+{
+ struct AVS3Decoder_s *dec = container_of(timer,
+ struct AVS3Decoder_s, timer);
+ //uint8_t empty_flag;
+ //unsigned int buf_level;
+
+ //enum receiver_start_e state = RECEIVER_INACTIVE;
+ if (dec->init_flag == 0) {
+ if (dec->stat & STAT_TIMER_ARM) {
+ timer->expires = jiffies + PUT_INTERVAL;
+ add_timer(&dec->timer);
+ }
+ return;
+ }
+ if (dec->m_ins_flag == 0) {
+#ifndef PXP_DEBUG
+ if (vf_get_receiver(dec->provider_name)) {
+ state =
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE,
+ NULL);
+ if ((state == RECEIVER_STATE_NULL)
+ || (state == RECEIVER_STATE_NONE))
+ state = RECEIVER_INACTIVE;
+ } else
+ state = RECEIVER_INACTIVE;
+
+ empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
+ /* error watchdog */
+ if (empty_flag == 0) {
+ /* decoder has input */
+ if ((debug & AVS3_DBG_DIS_LOC_ERROR_PROC) == 0) {
+
+ buf_level = READ_VREG(HEVC_STREAM_LEVEL);
+ /* receiver has no buffer to recycle */
+ if ((state == RECEIVER_INACTIVE) &&
+ (kfifo_is_empty(&dec->display_q) &&
+ buf_level > 0x200)
+ ) {
+ WRITE_VREG
+ (dec->ASSIST_MBOX0_IRQ_REG,
+ 0x1);
+ }
+ }
+
+ if ((debug & AVS3_DBG_DIS_SYS_ERROR_PROC) == 0) {
+ /* receiver has no buffer to recycle */
+ /*if ((state == RECEIVER_INACTIVE) &&
+ (kfifo_is_empty(&dec->display_q))) {
+ pr_info("avs3 something error,need reset\n");
+ }*/
+ }
+ }
+#endif
+ } else {
+ if (
+ (decode_timeout_val > 0) &&
+ (dec->start_process_time > 0) &&
+ ((1000 * (jiffies - dec->start_process_time) / HZ)
+ > decode_timeout_val)
+ ) {
+ int current_lcu_idx =
+ READ_VREG(HEVC_PARSER_LCU_START)
+ & 0xffffff;
+ if (dec->last_lcu_idx == current_lcu_idx) {
+ if (dec->decode_timeout_count > 0)
+ dec->decode_timeout_count--;
+ if (dec->decode_timeout_count == 0) {
+ if (input_frame_based(
+ hw_to_vdec(dec)) ||
+ (READ_VREG(HEVC_STREAM_LEVEL) > 0x200))
+ timeout_process(dec);
+ else {
+ avs3_print(dec, 0,
+ "timeout & empty, again\n");
+ dec_again_process(dec);
+ }
+ }
+ } else {
+ start_process_time(dec);
+ dec->last_lcu_idx = current_lcu_idx;
+ }
+ }
+ }
+ if ((dec->ucode_pause_pos != 0) &&
+ (dec->ucode_pause_pos != 0xffffffff) &&
+ udebug_pause_pos != dec->ucode_pause_pos) {
+ dec->ucode_pause_pos = 0;
+ WRITE_VREG(DEBUG_REG1, 0);
+ }
+ if (debug & AVS3_DBG_DUMP_DATA) {
+ debug &= ~AVS3_DBG_DUMP_DATA;
+ avs3_print(dec, 0,
+ "%s: chunk size 0x%x off 0x%x sum 0x%x\n",
+ __func__,
+ dec->chunk->size,
+ dec->chunk->offset,
+ get_data_check_sum(dec, dec->chunk->size)
+ );
+ dump_data(dec, dec->chunk->size);
+ }
+ if (debug & AVS3_DBG_DUMP_PIC_LIST) {
+ print_pic_pool(&dec->avs3_dec, "");
+ debug &= ~AVS3_DBG_DUMP_PIC_LIST;
+ }
+ if (debug & AVS3_DBG_TRIG_SLICE_SEGMENT_PROC) {
+ WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+ debug &= ~AVS3_DBG_TRIG_SLICE_SEGMENT_PROC;
+ }
+ if (debug & AVS3_DBG_DUMP_RPM_BUF) {
+ int i;
+
+ pr_info("RPM:\n");
+ for (i = 0; i < RPM_BUF_SIZE; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ",
+ dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+ debug &= ~AVS3_DBG_DUMP_RPM_BUF;
+ }
+ if (debug & AVS3_DBG_DUMP_LMEM_BUF) {
+ int i;
+
+ pr_info("LMEM:\n");
+ for (i = 0; i < LMEM_BUF_SIZE; i += 4) {
+ int ii;
+ if ((i & 0xf) == 0)
+ pr_info("%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ pr_info("%04x ",
+ dec->lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ pr_info("\n");
+ }
+ debug &= ~AVS3_DBG_DUMP_LMEM_BUF;
+ }
+ /*if (debug & AVS3_DBG_HW_RESET) {
+ }*/
+
+ if (radr != 0) {
+ if (rval != 0) {
+ WRITE_VREG(radr, rval);
+ pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
+ } else
+ pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
+ rval = 0;
+ radr = 0;
+ }
+ if (pop_shorts != 0) {
+ int i;
+ u32 sum = 0;
+ pr_info("pop stream 0x%x shorts\r\n", pop_shorts);
+ for (i = 0; i < pop_shorts; i++) {
+ u32 data =
+ (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
+ WRITE_VREG(HEVC_SHIFT_COMMAND,
+ (1<<7)|16);
+ if ((i & 0xf) == 0)
+ pr_info("%04x:", i);
+ pr_info("%04x ", data);
+ if (((i + 1) & 0xf) == 0)
+ pr_info("\r\n");
+ sum += data;
+ }
+ pr_info("\r\nsum = %x\r\n", sum);
+ pop_shorts = 0;
+ }
+ if (dbg_cmd != 0) {
+ if (dbg_cmd == 1) {
+ u32 disp_laddr;
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
+ get_double_write_mode(dec) == 0) {
+ disp_laddr =
+ READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
+ } else {
+ struct canvas_s cur_canvas;
+ canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
+ & 0xff), &cur_canvas);
+ disp_laddr = cur_canvas.addr;
+ }
+ pr_info("current displayed buffer address %x\r\n",
+ disp_laddr);
+ }
+#ifdef DEBUG_CMD
+ else if ((dbg_cmd & 0xf) == 2) {
+ d_dump(dec, dbg_cmd & (~0xf), 128, NULL, NULL);
+ }
+#endif
+ dbg_cmd = 0;
+ }
+ /*don't changed at start.*/
+ if (dec->get_frame_dur && dec->show_frame_num > 60 &&
+ dec->frame_dur > 0 && dec->saved_resolution !=
+ frame_width * frame_height *
+ (96000 / dec->frame_dur)) {
+ int fps = 96000 / dec->frame_dur;
+ if (hevc_source_changed(VFORMAT_AVS3,
+ frame_width, frame_height, fps) > 0)
+ dec->saved_resolution = frame_width *
+ frame_height * fps;
+ }
+
+ if ((dec->start_process_time != 0) &&
+ !(error_handle_policy & 0x4) &&
+ (decode_timeout_val > 0)) {
+ int current_lcu_idx =
+ READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff;
+
+ if (dec->last_lcu_idx == current_lcu_idx) {
+ if (dec->decode_timeout_count > 0)
+ dec->decode_timeout_count--;
+ if (dec->decode_timeout_count == 0) {
+ timeout_process(dec);
+ }
+ } else {
+ dec->decode_timeout_count = fast_timer_check_count;
+ dec->last_lcu_idx = current_lcu_idx;
+ }
+
+ mod_timer(timer, jiffies + 1);
+ } else
+ mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+
+int vavs3_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+
+ if (!dec)
+ return -1;
+
+ vstatus->frame_width = dec->frame_width;
+ vstatus->frame_height = dec->frame_height;
+
+ if (dec->frame_dur != 0)
+ vstatus->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
+ 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
+ else
+ vstatus->frame_rate = -1;
+ vstatus->error_count = 0;
+ vstatus->status = dec->stat | dec->fatal_error;
+ vstatus->frame_dur = dec->frame_dur;
+ vstatus->bit_rate = dec->gvs->bit_rate;
+ vstatus->frame_data = dec->gvs->frame_data;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->frame_count = dec->gvs->frame_count;
+ vstatus->error_frame_count = dec->gvs->error_frame_count;
+ vstatus->drop_frame_count = dec->gvs->drop_frame_count;
+ vstatus->i_decoded_frames = dec->gvs->i_decoded_frames;
+ vstatus->i_lost_frames = dec->gvs->i_lost_frames;
+ vstatus->i_concealed_frames = dec->gvs->i_concealed_frames;
+ vstatus->p_decoded_frames = dec->gvs->p_decoded_frames;
+ vstatus->p_lost_frames = dec->gvs->p_lost_frames;
+ vstatus->p_concealed_frames = dec->gvs->p_concealed_frames;
+ vstatus->b_decoded_frames = dec->gvs->b_decoded_frames;
+ vstatus->b_lost_frames = dec->gvs->b_lost_frames;
+ vstatus->b_concealed_frames = dec->gvs->b_concealed_frames;
+ vstatus->total_data = dec->gvs->total_data;
+ vstatus->samp_cnt = dec->gvs->samp_cnt;
+ vstatus->offset = dec->gvs->offset;
+ snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
+ "%s", DRIVER_NAME);
+ return 0;
+}
+
+int vavs3_set_isreset(struct vdec_s *vdec, int isreset)
+{
+#ifndef PXP_DEBUG
+ is_reset = isreset;
+#endif
+ return 0;
+}
+
+static void vavs3_prot_init(struct AVS3Decoder_s *dec)
+{
+ unsigned int data32;
+
+ avs3_config_work_space_hw(dec);
+ if (dec->pic_list_init_flag)
+ init_pic_list_hw(dec);
+#ifdef TMP_DEBUG
+ avs2_init_decoder_hw(dec);
+#else
+ avs3_init_decoder_hw(dec);
+#endif
+#if 1
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%s\n", __func__);
+#if 0
+ data32 = READ_VREG(HEVC_STREAM_CONTROL);
+ data32 = data32 |
+ (1 << 0)/*stream_fetch_enable*/
+ ;
+ WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+#if 0
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x00000100) {
+ pr_info("avs3 prot init error %d\n", __LINE__);
+ return;
+ }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x00000300) {
+ pr_info("avs3 prot init error %d\n", __LINE__);
+ return;
+ }
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
+ data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+ if (data32 != 0x12345678) {
+ pr_info("avs3 prot init error %d\n", __LINE__);
+ return;
+ }
+ data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+ if (data32 != 0x9abcdef0) {
+ pr_info("avs3 prot init error %d\n", __LINE__);
+ return;
+ }
+#endif
+ WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+ WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
+
+// Set MCR fetch priorities
+ data32 = 0x1 | (0x1 << 2) | (0x1 <<3) | (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
+ WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
+
+#endif
+
+ WRITE_VREG(HEVC_WAIT_FLAG, 1);
+
+ /* WRITE_VREG(HEVC_MPSR, 1); */
+
+ /* clear mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+ /* disable PSCALE for hardware sharing */
+#ifndef FOR_S5
+ WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+#endif
+
+ WRITE_VREG(DEBUG_REG1, 0x0);
+ /*check vps/sps/pps/i-slice in ucode*/
+ WRITE_VREG(NAL_SEARCH_CTL, 0x8);
+
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+ WRITE_VREG(HEVC_DBG_LOG_ADR, dec->ucode_log_phy_addr);
+#endif
+ config_cuva_buf(dec);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+ WRITE_VREG(HEVC_SAO_CRC, 0);
+ if (dec->front_back_mode == 1)
+ WRITE_VREG(HEVC_SAO_CRC_DBE1, 0);
+ }
+
+}
+
+#ifdef I_ONLY_SUPPORT
+static int vavs3_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ if (i_only_flag & 0x100)
+ return 0;
+ if (trickmode == TRICKMODE_I || trickmode == TRICKMODE_I_HEVC)
+ dec->i_only = 0x3;
+ else if (trickmode == TRICKMODE_NONE)
+ dec->i_only = 0x0;
+ return 0;
+}
+#endif
+
+static int vavs3_local_init(struct AVS3Decoder_s *dec)
+{
+ int i;
+ int ret;
+ int width, height;
+
+ dec->vavs3_ratio = dec->vavs3_amstream_dec_info.ratio;
+
+ dec->gvs = vzalloc(sizeof(struct vdec_info));
+ if (NULL == dec->gvs) {
+ avs3_print(dec, 0,
+ "the struct of vdec status malloc failed.\n");
+ return -1;
+ }
+#ifdef DEBUG_PTS
+ dec->pts_missed = 0;
+ dec->pts_hit = 0;
+#endif
+ dec->new_frame_displayed = 0;
+ dec->last_put_idx = -1;
+ dec->saved_resolution = 0;
+ dec->get_frame_dur = false;
+ on_no_keyframe_skiped = 0;
+ width = dec->vavs3_amstream_dec_info.width;
+ height = dec->vavs3_amstream_dec_info.height;
+ dec->frame_dur =
+ (dec->vavs3_amstream_dec_info.rate ==
+ 0) ? 3600 : dec->vavs3_amstream_dec_info.rate;
+ if (width && height)
+ dec->frame_ar = height * 0x100 / width;
+/*
+TODO:FOR VERSION
+*/
+ avs3_print(dec, AVS3_DBG_BUFMGR,
+ "avs3: ver (%d,%d) decinfo: %dx%d rate=%d\n", avs3_version,
+ 0, width, height, dec->frame_dur);
+
+ if (dec->frame_dur == 0)
+ dec->frame_dur = 96000 / 24;
+#ifdef I_ONLY_SUPPORT
+ if (i_only_flag & 0x100)
+ dec->i_only = i_only_flag & 0xff;
+ else if ((unsigned long) dec->vavs3_amstream_dec_info.param
+ & 0x08)
+ dec->i_only = 0x7;
+ else
+ dec->i_only = 0x0;
+#endif
+ INIT_KFIFO(dec->display_q);
+ INIT_KFIFO(dec->newframe_q);
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ const struct vframe_s *vf = &dec->vfpool[i];
+ dec->vfpool[i].index = -1;
+ kfifo_put(&dec->newframe_q, vf);
+ }
+
+ ret = avs3_local_init(dec);
+
+ return ret;
+}
+
+static s32 vavs3_init(struct vdec_s *vdec)
+{
+ int ret = -1, size = -1;
+ int fw_size = 0x1000 * 16;
+ struct firmware_s *fw = NULL;
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)vdec->private;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+#ifdef NEW_FB_CODE
+ struct firmware_s *fw_back = NULL;
+#endif
+
+ avs3_dec->start_time = div64_u64(local_clock(), 1000);
+ timer_setup(&dec->timer, vavs3_put_timer_func, 0);
+#ifdef NEW_FB_CODE
+ timer_setup(&dec->timer_back, avs3_check_timer_back_func, 0);
+ dec->stat |= STAT_TIMER_BACK_INIT;
+#endif
+
+ dec->stat |= STAT_TIMER_INIT;
+ if (vavs3_local_init(dec) < 0)
+ return -EBUSY;
+
+ vdec_set_vframe_comm(vdec, DRIVER_NAME);
+
+ fw = vmalloc(sizeof(struct firmware_s) + fw_size);
+ if (IS_ERR_OR_NULL(fw))
+ return -ENOMEM;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+ fw_back = vzalloc(sizeof(struct firmware_s) + fw_size);
+ if (IS_ERR_OR_NULL(fw_back))
+ return -ENOMEM;
+
+ size = get_firmware_data(VIDEO_DEC_AVS3_FRONT, fw->data);
+
+ fw_back->len = get_firmware_data(VIDEO_DEC_AVS3_BACK, fw_back->data);
+ if (fw_back->len < 0) {
+ pr_err("get back firmware fail.\n");
+ vfree(fw_back);
+ return -1;
+ }
+ } else
+#endif
+ size = get_firmware_data(VIDEO_DEC_AVS3, fw->data);
+ if (size < 0) {
+ pr_err("get firmware fail.\n");
+ vfree(fw);
+ return -1;
+ }
+
+ fw->len = fw_size;
+
+ if (dec->m_ins_flag) {
+ dec->timer.expires = jiffies + PUT_INTERVAL;
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->timer_back.expires = jiffies + PUT_INTERVAL;
+ dec->fw_back = fw_back;
+ }
+#endif
+ /*add_timer(&dec->timer);
+
+ dec->stat |= STAT_TIMER_ARM;
+ dec->stat |= STAT_ISR_REG;*/
+
+ INIT_WORK(&dec->work, avs3_work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ INIT_WORK(&dec->work_back, avs3_work_back);
+ INIT_WORK(&dec->timeout_work_back, avs3_timeout_work_back);
+ mutex_init(&dec->fb_mutex);
+ }
+#endif
+ dec->fw = fw;
+
+ return 0;
+ }
+
+ amhevc_enable();
+
+ ret = amhevc_loadmc_ex(VFORMAT_AVS3, NULL, fw->data);
+ if (ret < 0) {
+ amhevc_disable();
+ vfree(fw);
+ pr_err("AVS3: the %s fw loading failed, err: %x\n",
+ fw_tee_enabled() ? "TEE" : "local", ret);
+ return -EBUSY;
+ }
+
+ vfree(fw);
+
+ dec->stat |= STAT_MC_LOAD;
+
+ /* enable AMRISC side protocol */
+ vavs3_prot_init(dec);
+
+ if (vdec_request_threaded_irq(VDEC_IRQ_0,
+ vavs3_isr,
+ vavs3_isr_thread_fn,
+ IRQF_ONESHOT,/*run thread on this irq disabled*/
+ "vavs3-irq", (void *)dec)) {
+ pr_info("vavs3 irq register error.\n");
+ amhevc_disable();
+ return -ENOENT;
+ }
+ dec->stat |= STAT_ISR_REG;
+
+ dec->provider_name = PROVIDER_NAME;
+ vf_provider_init(&vavs3_vf_prov, PROVIDER_NAME,
+ &vavs3_vf_provider, dec);
+ vf_reg_provider(&vavs3_vf_prov);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
+ if (dec->frame_dur != 0) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)
+ ((unsigned long)dec->frame_dur));
+ }
+ dec->stat |= STAT_VF_HOOK;
+
+ dec->timer.expires = jiffies + PUT_INTERVAL;
+ add_timer(&dec->timer);
+ dec->stat |= STAT_TIMER_ARM;
+
+ /* dec->stat |= STAT_KTHREAD; */
+ dec->process_busy = 0;
+ avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+ "%d, vavs3_init, RP=0x%x\n",
+ __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
+ return 0;
+}
+
+static int vmavs3_stop(struct AVS3Decoder_s *dec)
+{
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+#endif
+ if (dec->stat & STAT_VF_HOOK) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT,
+ NULL);
+
+ vf_unreg_provider(&vavs3_vf_prov);
+ dec->stat &= ~STAT_VF_HOOK;
+ }
+ avs3_local_uninit(dec);
+ reset_process_time(dec);
+ cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ cancel_work_sync(&dec->work_back);
+ vfree(dec->fw_back);
+ dec->fw_back = NULL;
+ }
+#endif
+ uninit_mmu_buffers(dec);
+ if (dec->fw) {
+ vfree(dec->fw);
+ dec->fw = NULL;
+ }
+
+ return 0;
+}
+
+static int vavs3_stop(struct AVS3Decoder_s *dec)
+{
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ if (dec->stat & STAT_VDEC_RUN) {
+ amhevc_stop();
+ dec->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (dec->stat & STAT_ISR_REG) {
+ if (!dec->m_ins_flag)
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 0);
+ vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+ dec->stat &= ~STAT_ISR_REG;
+ }
+
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+#endif
+
+ if (dec->stat & STAT_VF_HOOK) {
+ if (!is_reset)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT,
+ NULL);
+
+ vf_unreg_provider(&vavs3_vf_prov);
+ dec->stat &= ~STAT_VF_HOOK;
+ }
+ avs3_local_uninit(dec);
+
+ if (dec->m_ins_flag) {
+ cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ cancel_work_sync(&dec->work_back);
+ vfree(dec->fw_back);
+ dec->fw_back = NULL;
+ }
+#endif
+ } else
+ amhevc_disable();
+ uninit_mmu_buffers(dec);
+
+ return 0;
+}
+
+static int amvdec_avs3_mmu_init(struct AVS3Decoder_s *dec)
+{
+ int tvp_flag = vdec_secure(hw_to_vdec(dec)) ?
+ CODEC_MM_FLAGS_TVP : 0;
+ int buf_size = 48;
+
+ dec->need_cache_size = buf_size * SZ_1M;
+ dec->sc_start_time = get_jiffies_64();
+#ifdef AVS3_10B_MMU
+ if (dec->mmu_enable) {
+ dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->mmu_box) {
+ pr_err("avs3 alloc mmu box failed!!\n");
+ return -1;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->mmu_box_1) {
+ pr_err("avs3 alloc mmu box1 failed!!\n");
+ return -1;
+ }
+ }
+ }
+#endif
+#ifdef AVS3_10B_MMU_DW
+ if (dec->dw_mmu_enable) {
+ dec->dw_mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->dw_mmu_box) {
+ pr_err("avs3 alloc dw mmu box failed!!\n");
+ dec->dw_mmu_enable = 0;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ dec->dw_mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->dw_mmu_box_1) {
+ pr_err("avs3 alloc dw mmu box1 failed!!\n");
+ dec->dw_mmu_enable = 0;
+ }
+ }
+#endif
+ }
+#endif
+ dec->bmmu_box = decoder_bmmu_box_alloc_box(
+ DRIVER_NAME,
+ dec->index,
+ MAX_BMMU_BUFFER_NUM,
+ 4 + PAGE_SHIFT,
+ CODEC_MM_FLAGS_CMA_CLEAR |
+ CODEC_MM_FLAGS_FOR_VDECODER |
+ tvp_flag,
+ BMMU_ALLOC_FLAGS_WAITCLEAR);
+ if (!dec->bmmu_box) {
+ pr_err("avs3 alloc bmmu box failed!!\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int amvdec_avs3_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ /*struct BUF_s BUF[MAX_BUF_NUM];*/
+ struct AVS3Decoder_s *dec = &gAVS3Decoder;
+ int ret;
+ pr_info("%s\n", __func__);
+
+ dec = vzalloc(sizeof(struct AVS3Decoder_s));
+ if (!dec)
+ return -ENOMEM;
+
+ pdata->private = dec;
+ platform_set_drvdata(pdev, pdata);
+
+ mutex_lock(&vavs3_mutex);
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ dec->eos = 0;
+ dec->start_process_time = 0;
+ dec->timeout_num = 0;
+ dec->fatal_error = 0;
+ dec->show_frame_num = 0;
+ if (pdata == NULL) {
+ avs3_print(dec, 0,
+ "\namvdec_avs3 memory resource undefined.\n");
+ mutex_unlock(&vavs3_mutex);
+ return -EFAULT;
+ }
+ dec->m_ins_flag = 0;
+ dec->platform_dev = pdev;
+ platform_set_drvdata(pdev, pdata);
+
+#ifdef NEW_FB_CODE
+ dec->front_back_mode = 0;
+#endif
+ config_hevc_irq_num(dec);
+
+#ifdef AVS3_10B_MMU_DW
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
+ dec->dw_mmu_enable =
+ (get_double_write_mode(dec) & 0x20) ? 1 : 0;
+ } else {
+ dec->dw_mmu_enable = 0;
+ }
+#endif
+ if (amvdec_avs3_mmu_init(dec) < 0) {
+ mutex_unlock(&vavs3_mutex);
+ pr_err("avs3 alloc bmmu box failed!!\n");
+ return -1;
+ }
+
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+ work_buf_size, DRIVER_NAME, &pdata->mem_start);
+ if (ret < 0) {
+ uninit_mmu_buffers(dec);
+ mutex_unlock(&vavs3_mutex);
+ return ret;
+ }
+ dec->buf_size = work_buf_size;
+
+ dec->buf_start = pdata->mem_start;
+
+ if (debug) {
+ avs3_print(dec, 0,
+ "===AVS3 decoder mem resource 0x%lx size 0x%x\n",
+ pdata->mem_start, dec->buf_size);
+ }
+
+ if (pdata->sys_info) {
+ dec->vavs3_amstream_dec_info = *pdata->sys_info;
+ dec->frame_width = dec->vavs3_amstream_dec_info.width;
+ dec->frame_height = dec->vavs3_amstream_dec_info.height;
+ } else {
+ dec->vavs3_amstream_dec_info.width = 0;
+ dec->vavs3_amstream_dec_info.height = 0;
+ dec->vavs3_amstream_dec_info.rate = 30;
+ }
+ dec->cma_dev = pdata->cma_dev;
+
+ dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
+ if (is_support_vdec_canvas())
+ dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+ if (endian)
+ dec->endian = endian;
+
+ pdata->private = dec;
+ pdata->dec_status = vavs3_dec_status;
+ /*pdata->set_isreset = vavs3_set_isreset;*/
+ is_reset = 0;
+ if (vavs3_init(pdata) < 0) {
+ pr_info("\namvdec_avs3 init failed.\n");
+ avs3_local_uninit(dec);
+ uninit_mmu_buffers(dec);
+ pdata->dec_status = NULL;
+ mutex_unlock(&vavs3_mutex);
+ return -ENODEV;
+ }
+ /*set the max clk for smooth playing...*/
+ hevc_source_changed(VFORMAT_AVS3,
+ 4096, 2048, 60);
+ mutex_unlock(&vavs3_mutex);
+
+ return 0;
+}
+
+static int amvdec_avs3_remove(struct platform_device *pdev)
+{
+ struct AVS3Decoder_s *dec = &gAVS3Decoder;
+ if (debug)
+ pr_info("amvdec_avs3_remove\n");
+
+ mutex_lock(&vavs3_mutex);
+
+ vavs3_stop(dec);
+
+ hevc_source_changed(VFORMAT_AVS3, 0, 0, 0);
+
+#ifdef DEBUG_PTS
+ pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+ dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+
+ mutex_unlock(&vavs3_mutex);
+
+ return 0;
+}
+
+/****************************************/
+
+static struct platform_driver amvdec_avs3_driver = {
+ .probe = amvdec_avs3_probe,
+ .remove = amvdec_avs3_remove,
+#ifdef CONFIG_PM
+ .suspend = amhevc_suspend,
+ .resume = amhevc_resume,
+#endif
+ .driver = {
+ .name = DRIVER_NAME,
+ }
+};
+static struct codec_profile_t amvdec_avs3_profile = {
+ .name = "avs3",
+ .profile = ""
+};
+
+static struct codec_profile_t amvdec_avs3_profile_mult;
+static unsigned char get_data_check_sum
+ (struct AVS3Decoder_s *dec, int size)
+{
+ int jj;
+ int sum = 0;
+ u8 *data = NULL;
+
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ for (jj = 0; jj < size; jj++)
+ sum += data[jj];
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ return sum;
+}
+
+static void dump_data(struct AVS3Decoder_s *dec, int size)
+{
+ int jj;
+ u8 *data = NULL;
+ int padding_size = dec->chunk->offset &
+ (VDEC_FIFO_ALIGN - 1);
+
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ avs3_print(dec, 0, "padding: ");
+ for (jj = padding_size; jj > 0; jj--)
+ avs3_print_cont(dec,
+ 0,
+ "%02x ", *(data - jj));
+ avs3_print_cont(dec, 0, "data adr %p\n",
+ data);
+
+ for (jj = 0; jj < size; jj++) {
+ if ((jj & 0xf) == 0)
+ avs3_print(dec,
+ 0,
+ "%06x:", jj);
+ avs3_print_cont(dec,
+ 0,
+ "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ avs3_print(dec,
+ 0,
+ "\n");
+ }
+ avs3_print(dec,
+ 0,
+ "\n");
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+}
+
+void wait_shift_byte_search_done(struct AVS3Decoder_s *dec)
+{
+ u32 shift_byte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+ int count = 0;
+ do {
+ usleep_range(1000, 1010);
+ if (shift_byte == READ_VREG(HEVC_SHIFT_BYTE_COUNT))
+ break;
+ if (count > 200) {
+ avs3_print(dec,
+ 0, "%s timeout count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n",
+ __func__, count, shift_byte, READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ break;
+ } else
+ shift_byte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+ count++;
+ } while (1);
+ pr_err("count %d, shift_byte 0x%x\n", count, shift_byte);
+}
+void wait_hevc_search_done(struct AVS3Decoder_s *dec)
+{
+ int count = 0;
+ WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+ while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+ usleep_range(100, 101);
+ count++;
+ if (count > 100) {
+ avs3_print(dec, 0, "%s timeout\n", __func__);
+ break;
+ }
+ }
+}
+
+static int avs3_wait_alloc_buf(void *args)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)args;
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ init_pic_list(dec, dec->avs3_dec.lcu_size_log2);
+
+ vdec_up(vdec);
+
+ return 0;
+}
+
+static void avs3_work_implement(struct AVS3Decoder_s *dec)
+{
+ struct vdec_s *vdec = hw_to_vdec(dec);
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+ /*if (dec->dec_result == DEC_RESULT_DONE)
+ decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_START, TRACE_BASIC);
+ else if (dec->dec_result == DEC_RESULT_AGAIN)
+ decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_AGAIN, TRACE_BASIC);*/
+
+ /* finished decoding one frame or error,
+ * notify vdec core to switch context
+ */
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "%s dec_result %d %x %x %x\n",
+ __func__,
+ dec->dec_result,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR));
+
+ if (((dec->dec_result == DEC_RESULT_GET_DATA) ||
+ (dec->dec_result == DEC_RESULT_GET_DATA_RETRY))
+ && (hw_to_vdec(dec)->next_status !=
+ VDEC_STATUS_DISCONNECTED)) {
+ if (!vdec_has_more_input(vdec)) {
+ dec->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+
+ if (dec->dec_result == DEC_RESULT_GET_DATA) {
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s DEC_RESULT_GET_DATA %x %x %x\n",
+ __func__,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR));
+ vdec_vframe_dirty(vdec, dec->chunk);
+ vdec_clean_input(vdec);
+ }
+
+ if (get_free_buf_count(dec) >=
+ run_ready_min_buf_num) {
+ int r;
+ int decode_size;
+ r = vdec_prepare_input(vdec, &dec->chunk);
+ if (r < 0) {
+ dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
+
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL,
+ "amvdec_avs3: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ dec->dec_result = DEC_RESULT_NONE;
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s: chunk size 0x%x sum 0x%x\n",
+ __func__, r,
+ (debug & PRINT_FLAG_VDEC_STATUS) ?
+ get_data_check_sum(dec, r) : 0
+ );
+ if (debug & PRINT_FLAG_VDEC_DATA)
+ dump_data(dec, dec->chunk->size);
+
+ decode_size = dec->chunk->size +
+ (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+
+ WRITE_VREG(HEVC_DECODE_SIZE,
+ READ_VREG(HEVC_DECODE_SIZE) + decode_size);
+
+ vdec_enable_input(vdec);
+
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+
+ start_process_time(dec);
+
+ } else{
+ dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
+
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "amvdec_avs3: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ }
+ return;
+ } else if ((dec->dec_result == DEC_RESULT_DONE) ||
+ (dec->dec_result == DEC_RESULT_ERROR)) {
+ struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+ /* if (!dec->ctx_valid)
+ dec->ctx_valid = 1; */
+ dec->slice_idx++;
+ dec->frame_count++;
+ dec->process_state = PROC_STATE_INIT;
+ decode_frame_count[dec->index] = dec->frame_count;
+
+ if ((pic != NULL) && (pic->error_mark) &&
+ (dec->dec_result == DEC_RESULT_DONE)) {
+#ifdef NEW_FB_CODE
+ mutex_lock(&dec->fb_mutex);
+#endif
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_concealed_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_concealed_frames++;
+ }
+
+ if (pic->backend_ref == 0) {
+ dec->gvs->drop_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_lost_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_lost_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_lost_frames++;
+ }
+ }
+#ifdef NEW_FB_CODE
+ mutex_unlock(&dec->fb_mutex);
+#endif
+ }
+
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s (===> %d) dec_result %d %x %x %x stream crc %x shiftbytes 0x%x decbytes 0x%x\n",
+ __func__,
+ dec->frame_count,
+ dec->dec_result,
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ READ_VREG(HEVC_STREAM_CRC),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
+ dec->start_shift_bytes
+ );
+ vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+ } else if (dec->dec_result == DEC_RESULT_AGAIN) {
+ /*
+ stream base: stream buf empty or timeout
+ frame base: vdec_prepare_input fail
+ */
+ if (!vdec_has_more_input(vdec)) {
+ dec->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ } else if (dec->dec_result == DEC_RESULT_EOS) {
+ DEC_CTX *avs3_ctx = &avs3_dec->ctx;
+ avs3_print(dec, 0,
+ "%s: end of stream\n",
+ __func__);
+ dec->eos = 1;
+ if (dec->avs3_dec.cur_pic != NULL) {
+ avs3_bufmgr_post_process(&dec->avs3_dec);
+ }
+
+ //output all pic;
+ avs3_ctx->info.pic_header.decode_order_index =
+ avs3_ctx->info.pic_header.decode_order_index + DOI_CYCLE_LENGTH;
+ avs3_prepare_display_buf(dec);
+ vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+ } else if (dec->dec_result == DEC_RESULT_FORCE_EXIT) {
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s: force exit\n",
+ __func__);
+ if (dec->stat & STAT_VDEC_RUN) {
+ amhevc_stop();
+ dec->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (dec->stat & STAT_ISR_REG) {
+ if (!dec->m_ins_flag)
+ WRITE_VREG(dec->ASSIST_MBOX0_MASK, 0);
+ vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+ dec->stat &= ~STAT_ISR_REG;
+ }
+ } else if (dec->dec_result == DEC_RESULT_WAIT_BUFFER) {
+ pr_err("DEC_RESULT_WAIT_BUFFER in\n");
+ vdec_post_task(avs3_wait_alloc_buf, dec);
+ dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATING;
+ dec->process_state =
+ PROC_STATE_DECODE_AGAIN;
+ }
+
+#ifdef NEW_FRONT_BACK_CODE
+ if (!vdec->front_pic_done && (dec->front_back_mode == 1)) {
+ fb_hw_status_clear(true);
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s, clear front, status 0x%x, status_back 0x%x\n",
+ __func__, dec->dec_status, dec->dec_status_back);
+ }
+#endif
+
+ if (dec->front_back_mode == 1)
+ amhevc_stop_f();
+
+ if (dec->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&dec->timer);
+ dec->stat &= ~STAT_TIMER_ARM;
+ }
+
+ wait_hevc_search_done(dec);
+
+ if (dec->dec_result == DEC_RESULT_DONE)
+ decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_END, TRACE_PERFORMANCE_DETAIL);
+
+ if (get_dbg_flag(dec) & AVS3_DBG_QOS_INFO) {
+ avs3_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+ __func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+ avs3_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+ avs3_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+ avs3_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+ dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+ }
+
+ /* mark itself has all HW resource released and input released */
+ if (vdec->parallel_dec ==1)
+ vdec_core_finish_run(vdec, CORE_MASK_HEVC);
+ else
+ vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+
+ if (dec->vdec_cb)
+ dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg, CORE_MASK_HEVC);
+}
+
+static void avs3_work(struct work_struct *work)
+{
+ struct AVS3Decoder_s *dec = container_of(work,
+ struct AVS3Decoder_s, work);
+
+ avs3_work_implement(dec);
+}
+
+#ifdef NEW_FB_CODE
+static void avs3_work_back_implement(struct AVS3Decoder_s *dec,
+ struct vdec_s *vdec, int from)
+{
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "[BE] %s result %d\n", __func__, dec->dec_back_result);
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_WORKER_START);
+
+ if (dec->dec_back_result == DEC_BACK_RESULT_TIMEOUT) {
+ avs3_frame_t* pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+
+ mutex_lock(&dec->fb_mutex);
+ if (pic->error_mark == 0) {
+ dec->gvs->error_frame_count++;
+ if (pic->slice_type == SLICE_I) {
+ dec->gvs->i_concealed_frames++;
+ } else if (pic->slice_type == SLICE_P) {
+ dec->gvs->p_concealed_frames++;
+ } else if (pic->slice_type == SLICE_B) {
+ dec->gvs->b_concealed_frames++;
+ }
+ }
+ mutex_lock(&dec->fb_mutex);
+ pic->error_mark = 1; /* set error mark for timeout pic */
+ pic_backend_ref_operation(dec, pic, 0);
+ if (debug & AVS3_DBG_PRINT_PIC_LIST)
+ print_pic_pool(avs3_dec, "after dec backend_ref");
+
+ if (without_display_mode == 0) {
+ struct vframe_s *vf = NULL;
+ if (kfifo_peek(&dec->display_q, &vf) && vf) {
+ uint8_t index = vf->index & 0xff;
+ struct avs3_frame_s *peek_pic = get_pic_by_index(dec, index);
+ if (peek_pic == pic)
+ vf_notify_receiver(dec->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ }
+ } else
+ vavs3_vf_put(vavs3_vf_get(dec), dec);
+
+ if ((dec->front_back_mode == 1 ||
+ dec->front_back_mode == 3) && (error_handle_policy & 0x4))
+
+ release_free_mmu_buffers(dec);
+ }
+
+ avs3_dec->backend_decoded_count++;
+
+ mutex_lock(&dec->fb_mutex);
+ avs3_dec->fb_rd_pos++;
+ if (avs3_dec->fb_rd_pos >= dec->fb_ifbuf_num)
+ avs3_dec->fb_rd_pos = 0;
+
+ avs3_dec->wait_working_buf = 0;
+ mutex_unlock(&dec->fb_mutex);
+
+ WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS3_DEC_IDLE);
+ if (dec->front_back_mode == 1)
+ amhevc_stop_b();
+
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "fb_wr_pos %d, set next fb_rd_pos %d, set wait_working_buf %d\n",
+ avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, avs3_dec->wait_working_buf);
+
+ if (!vdec->back_pic_done && (dec->front_back_mode == 1)) {
+ fb_hw_status_clear(false);
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "%s, clear back, status 0x%x, status_back 0x%x\n",
+ __func__, dec->dec_status, dec->dec_status_back);
+ }
+
+ if (dec->stat & STAT_TIMER_BACK_ARM) {
+ del_timer_sync(&dec->timer_back);
+ dec->stat &= ~STAT_TIMER_BACK_ARM;
+ }
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_WORKER_END);
+
+ vdec_core_finish_run(vdec, CORE_MASK_HEVC_BACK);
+
+ if (dec->vdec_back_cb)
+ dec->vdec_back_cb(hw_to_vdec(dec), dec->vdec_back_cb_arg, CORE_MASK_HEVC_BACK);
+
+}
+
+static void avs3_work_back(struct work_struct *work)
+{
+ struct AVS3Decoder_s *dec = container_of(work,
+ struct AVS3Decoder_s, work_back);
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ avs3_work_back_implement(dec, vdec, 0);
+
+}
+
+static void avs3_timeout_work_back(struct work_struct *work)
+{
+ struct AVS3Decoder_s *dec = container_of(work,
+ struct AVS3Decoder_s, timeout_work_back);
+ struct vdec_s *vdec = hw_to_vdec(dec);
+
+ if (work_pending(&dec->work_back))
+ return;
+ avs3_work_back_implement(dec, vdec, 1);
+}
+#endif
+
+static int avs3_hw_ctx_restore(struct AVS3Decoder_s *dec)
+{
+ /* new to do ... */
+ vavs3_prot_init(dec);
+ return 0;
+}
+
+#ifdef NEW_FB_CODE
+ /*run_ready_back*/
+static unsigned long check_input_data(struct vdec_s *vdec, unsigned long mask)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+ if (fbdebug_flag & 0x1)
+ return 0;
+
+ if (((avs3_dec->fb_wr_pos != avs3_dec->fb_rd_pos) || avs3_dec->wait_working_buf) &&
+ (dec->front_back_mode))
+ return mask;
+ else
+ return 0;
+}
+#endif
+
+static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ int tvp = vdec_secure(hw_to_vdec(dec)) ?
+ CODEC_MM_FLAGS_TVP : 0;
+ unsigned long ret = 0;
+ unsigned int run_ready_case = 0;
+#if 0
+ if ((debug & AVS3_DBG_BE_SIMULATE_IRQ)
+ &&(READ_VREG(DEBUG_REG1_DBE) ||
+ READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+ pr_info("Simulate BE irq\n");
+ WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+ }
+#endif
+ if (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATING)
+ return 0;
+
+ if ((fbdebug_flag & 0x2) &&
+ dec->front_back_mode &&
+ (dec->avs3_dec.cur_pic != NULL) &&
+ (dec->avs3_dec.cur_pic->back_done_mark == 0) &&
+ dec->next_again_flag == 0) {
+ run_ready_case = 1;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+ return 0;
+ }
+
+ if (debug & AVS3_DBG_PIC_LEAK_WAIT) {
+ run_ready_case = 2;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+ return ret;
+ }
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode && avs3_dec->wait_working_buf) {
+ run_ready_case = 3;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+ return 0xffffffff;
+ }
+#endif
+
+ if (dec->eos) {
+ run_ready_case = 4;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+ return ret;
+ }
+ if (!dec->first_sc_checked) {
+ int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp);
+#ifdef NEW_FB_CODE
+/* to do:
+ for dec->mmu_box_1
+*/
+#endif
+ dec->first_sc_checked = 1;
+ avs3_print(dec, 0, "vavs3 cached=%d need_size=%d speed= %d ms\n",
+ size, (dec->need_cache_size >> PAGE_SHIFT),
+ (int)(get_jiffies_64() - dec->sc_start_time) * 1000/HZ);
+ }
+
+ if (dec->next_again_flag &&
+ (!vdec_frame_based(vdec))) {
+ u32 parser_wr_ptr =
+ STBUF_READ(&vdec->vbuf, get_wp);
+ if (parser_wr_ptr >= dec->pre_parser_wr_ptr &&
+ (parser_wr_ptr - dec->pre_parser_wr_ptr) <
+ again_threshold) {
+ int r = vdec_sync_input(vdec);
+ run_ready_case = 5;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d buf lelvel:%x\n", __func__, run_ready_case, r);
+ return 0;
+ }
+ }
+/*
+ if (vdec_stream_based(vdec) && (dec->pic_list_init_flag == 0)
+ && pre_decode_buf_level != 0) {
+ u32 rp, wp, level;
+
+ rp = STBUF_READ(&vdec->vbuf, get_rp);
+ wp = STBUF_READ(&vdec->vbuf, get_wp);
+ if (wp < rp)
+ level = vdec->input.size + wp - rp;
+ else
+ level = wp - rp;
+
+ if (level < pre_decode_buf_level)
+ return 0;
+ }
+*/
+
+ if ((dec->pic_list_init_flag == 0) ||
+ get_free_buf_count(dec) >=
+ run_ready_min_buf_num)
+ ret = 1;
+ else {
+ avs3_cleanup_useless_pic_buffer_in_pm(avs3_dec);
+ if (get_free_buf_count(dec) >= run_ready_min_buf_num)
+ ret = 1;
+ else
+ run_ready_case = 0;
+ }
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+ if (dec->pic_list_init_flag) {
+ if (run_ready_max_vf_only_num > 0 &&
+ get_vf_ref_only_buf_count(dec) >=
+ run_ready_max_vf_only_num
+ ) {
+ run_ready_case = 10;
+ ret = 0;
+ }
+ if (run_ready_display_q_num > 0 &&
+ kfifo_len(&dec->display_q) >=
+ run_ready_display_q_num) {
+ run_ready_case = 11;
+ ret = 0;
+ }
+
+ /*if (run_ready_max_buf_num == 0xff &&
+ get_used_buf_count(dec) >=
+ dec->avs3_dec.ref_maxbuffer) {
+ run_ready_case = 12;
+ ret = 0;
+ } else*/ if (run_ready_max_buf_num &&
+ get_used_buf_count(dec) >=
+ run_ready_max_buf_num) {
+ run_ready_case = 13;
+ ret = 0;
+ }
+ }
+#endif
+ if (ret)
+ not_run_ready[dec->index] = 0;
+ else {
+ not_run_ready[dec->index]++;
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+ }
+
+ if (vdec->parallel_dec == 1)
+#ifdef NEW_FB_CODE
+ return ret ? mask : mask & ~(CORE_MASK_HEVC);
+#else
+ return ret ? CORE_MASK_HEVC : 0;
+#endif
+ else
+ return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
+}
+
+#ifdef NEW_FB_CODE
+static void run_back(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ int loadr = 0;
+ int ret = 0;
+
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_LOADING_FW_START);
+
+ if (vdec->mc_back_loaded || dec->front_back_mode != 1) {
+ /*firmware have load before,
+ and not changes to another.
+ ignore reload.
+ */
+ } else {
+ loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS3, vdec,
+ "avs3_back", dec->fw_back->data);
+
+ if (loadr < 0) {
+ amhevc_disable();
+ avs3_print(dec, 0, "AVS3: the %s back fw loading failed, err: %x\n",
+ fw_tee_enabled() ? "TEE" : "local", loadr);
+ dec->dec_back_result = DEC_BACK_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&dec->work_back);
+ return;
+ }
+
+ //vdec->mc_back_loaded = 1;
+ vdec->mc_back_type = VFORMAT_AVS3;
+ }
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_LOADING_FW_END);
+
+ ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_ALLOC_MMU_START);
+
+ run_count_back[dec->index]++;
+ dec->vdec_back_cb_arg = arg;
+ dec->vdec_back_cb = callback;
+ vdec->back_pic_done = false;
+ //pr_err("run h265_HEVC_back_test\n");
+ //vdec_post_task(h265_HEVC_back_test, hevc);
+
+ ret = BackEnd_StartDecoding(dec);
+
+ if (ret == 1) {
+ dec->dec_back_result = DEC_BACK_RESULT_DONE;
+ vdec_schedule_work(&dec->timeout_work_back);
+ } else {
+ mod_timer(&dec->timer_back, jiffies);
+ dec->stat |= STAT_TIMER_BACK_ARM;
+ start_process_time_back(dec);
+ }
+}
+
+#if 0
+static void start_front_end_multi_pic_decoding(struct AVS3Decoder_s *dec)
+{ /*multi pictures in one packe*/
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ printk("Start FrontEnd Decoding %d\n", avs3_dec->frontend_decoded_count);
+ printk("copy loopbuf to next_bk[%d]\n",avs3_dec->fb_wr_pos);
+ copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+
+ if (dec->front_back_mode == 1)
+ config_bufstate_front_hw(avs3_dec);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+}
+#endif
+#endif
+
+static void run(struct vdec_s *vdec, unsigned long mask,
+ void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ int r;
+
+#ifdef NEW_FB_CODE
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ /*simulation code: if (dec_status == AVS3_DEC_IDLE)*/
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s(mask = 0x%lx)\n", __func__, mask);
+ if (dec->front_back_mode == 0 || (mask & CORE_MASK_HEVC)) {
+#endif
+ if (debug & PRINT_FLAG_VDEC_STATUS)
+ WRITE_VREG(HEVC_STREAM_CRC, 0);
+ run_count[dec->index]++;
+ dec->vdec_cb_arg = arg;
+ dec->vdec_cb = callback;
+ vdec->front_pic_done = false;
+
+ decoder_trace(dec->trace.decode_time_name, DECODER_RUN_START, TRACE_PERFORMANCE_DETAIL);
+ /* dec->chunk = vdec_prepare_input(vdec); */
+#ifdef NEW_FRONT_BACK_CODE
+ /*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+ if (dec->front_back_mode) {
+ avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+ "Start FrontEnd Decoding %d\n", avs3_dec->frontend_decoded_count);
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "copy loopbuf fr to next_bk[fb_wr_pos=%d]\n",avs3_dec->fb_wr_pos);
+ copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+
+ if (dec->front_back_mode == 1)
+ amhevc_reset_f();
+ else
+ hevc_reset_core(vdec);
+ } else
+#endif
+ {
+ hevc_reset_core(vdec);
+ }
+ if (vdec_stream_based(vdec)) {
+ dec->pre_parser_wr_ptr =
+ STBUF_READ(&vdec->vbuf, get_wp);
+ dec->next_again_flag = 0;
+ }
+
+ r = vdec_prepare_input(vdec, &dec->chunk);
+
+ if (r < 0) {
+ input_empty[dec->index]++;
+
+ dec->dec_result = DEC_RESULT_AGAIN;
+
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "ammvdec_avs3: Insufficient data\n");
+
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+
+ input_empty[dec->index] = 0;
+ dec->dec_result = DEC_RESULT_NONE;
+
+ if (debug)
+ dec->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+
+ if (debug & PRINT_FLAG_VDEC_STATUS) {
+ int ii;
+ avs3_print(dec, 0,
+ "%s (%d): size 0x%x (0x%x 0x%x) sum 0x%x (%x %x %x %x %x) bytes 0x%x",
+ __func__,
+ dec->frame_count, r,
+ dec->chunk ? dec->chunk->size : 0,
+ dec->chunk ? dec->chunk->offset : 0,
+ dec->chunk ? ((vdec_frame_based(vdec) &&
+ (debug & PRINT_FLAG_VDEC_STATUS)) ?
+ get_data_check_sum(dec, r) : 0) : 0,
+ READ_VREG(HEVC_STREAM_START_ADDR),
+ READ_VREG(HEVC_STREAM_END_ADDR),
+ READ_VREG(HEVC_STREAM_LEVEL),
+ READ_VREG(HEVC_STREAM_WR_PTR),
+ READ_VREG(HEVC_STREAM_RD_PTR),
+ dec->start_shift_bytes);
+ if (vdec_frame_based(vdec) && dec->chunk) {
+ u8 *data = NULL;
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, 8);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+
+ avs3_print_cont(dec, 0, "data adr %p:",
+ data);
+ for (ii = 0; ii < 8; ii++)
+ avs3_print_cont(dec, 0, "%02x ",
+ data[ii]);
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ }
+ avs3_print_cont(dec, 0, "\r\n");
+ }
+
+ decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START, TRACE_BASIC);
+ if (vdec->mc_loaded) {
+ /*firmware have load before,
+ and not changes to another.
+ ignore reload.
+ */
+ } else {
+#ifdef NEW_FB_CODE
+ int loadr = 0;
+ if (dec->front_back_mode == 1 || dec->front_back_mode == 3)
+ loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS3, vdec,
+ "avs3_front", dec->fw->data);
+ else
+#endif
+ if (amhevc_loadmc_ex(VFORMAT_AVS3, "avs3_mmu", dec->fw->data) < 0) {
+ vdec->mc_loaded = 0;
+ amhevc_disable();
+ avs3_print(dec, 0,
+ "%s: Error amvdec_loadmc avs3_mmu fail \n", __func__);
+ dec->dec_result = DEC_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ //vdec->mc_loaded = 1;
+ vdec->mc_type = VFORMAT_AVS3;
+ }
+ decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END, TRACE_BASIC);
+
+ decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START, TRACE_BASIC);
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode) {
+ if (efficiency_mode)
+ WRITE_VREG(HEVC_EFFICIENCY_MODE, 1 << 1);
+ else
+ WRITE_VREG(HEVC_EFFICIENCY_MODE, 0 << 1);
+
+ avs3_hw_init(dec, 1, 0);
+ //config_decode_mode(dec);
+ if (dec->front_back_mode == 1) {
+ config_bufstate_front_hw(avs3_dec);
+ if ((fbdebug_flag & 0x8) && (avs3_dec->frontend_decoded_count == 0))
+ loop_buffer_fill_zero(dec);
+ }
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+ } else
+#endif
+ if (avs3_hw_ctx_restore(dec) < 0) {
+ vdec_schedule_work(&dec->work);
+ return;
+ }
+ decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END, TRACE_BASIC);
+
+ if (vdec_frame_based(vdec))
+ WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
+
+ vdec_enable_input(vdec);
+
+ //WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_SEARCH_NEW_PIC);
+
+ if (vdec_frame_based(vdec) && dec->chunk) {
+ if (debug & PRINT_FLAG_VDEC_DATA)
+ dump_data(dec, dec->chunk->size);
+
+ r = dec->chunk->size +
+ (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
+ if (vdec->mvfrm)
+ vdec->mvfrm->frame_size = dec->chunk->size;
+ }
+
+ WRITE_VREG(HEVC_DECODE_SIZE, r);
+ WRITE_VREG(HEVC_DECODE_COUNT, dec->slice_idx);
+ dec->init_flag = 1;
+
+ /*
+ avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+ "%s: start hevc (%x %x %x)\n",
+ __func__,
+ READ_VREG(HEVC_DEC_STATUS_REG),
+ READ_VREG(HEVC_MPC_E),
+ READ_VREG(HEVC_MPSR));
+ */
+ start_process_time(dec);
+ mod_timer(&dec->timer, jiffies);
+ dec->stat |= STAT_TIMER_ARM;
+ dec->stat |= STAT_ISR_REG;
+ if (vdec->mvfrm)
+ vdec->mvfrm->hw_decode_start = local_clock();
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode == 1) {
+ vdec->hw_front_decode_start = local_clock();
+ amhevc_start_f();
+ } else
+#endif
+ amhevc_start();
+ dec->stat |= STAT_VDEC_RUN;
+ decoder_trace(dec->trace.decode_time_name, DECODER_RUN_END, TRACE_PERFORMANCE_DETAIL);
+#ifdef NEW_FB_CODE
+ }
+ if (dec->front_back_mode &&
+ (mask & CORE_MASK_HEVC_BACK)) {
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_RUN_START);
+ run_back(vdec, callback, arg);
+ ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_RUN_END);
+ }
+#endif
+}
+
+static void reset(struct vdec_s *vdec)
+{
+
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+
+ avs3_print(dec,
+ PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
+
+}
+
+static irqreturn_t avs3_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ return vavs3_isr(0, dec);
+}
+
+static irqreturn_t avs3_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+ irqreturn_t ret;
+ //unsigned long flags;
+ //lock_front_back(dec, flags);
+ ret = vavs3_isr_thread_fn(0, dec);
+ //unlock_front_back(dec, flags);
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+ if ((dec->dec_status_back != AVS3_DEC_IDLE) ||
+ READ_VREG(DEBUG_REG1_DBE)) {
+ ret = vavs3_back_isr_thread_fn(dec);
+ }
+#endif
+ return ret;
+}
+
+static void avs3_dump_state(struct vdec_s *vdec)
+{
+ struct AVS3Decoder_s *dec =
+ (struct AVS3Decoder_s *)vdec->private;
+
+ if (radr != 0) {
+ if (rval != 0) {
+ WRITE_VREG(radr, rval);
+ pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
+ } else
+ pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
+ rval = 0;
+ radr = 0;
+ return;
+ }
+
+ avs3_print(dec, 0, "====== %s\n", __func__);
+ avs3_print(dec, 0,
+ "width/height (%d/%d), max_pb_size %d\n",
+ dec->avs3_dec.img.width,
+ dec->avs3_dec.img.height,
+ dec->avs3_dec.max_pb_size
+ );
+
+ avs3_print(dec, 0,
+ "front_back_mode (%d), is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
+ dec->front_back_mode,
+ input_frame_based(vdec),
+ dec->eos,
+ dec->dec_result,
+ decode_frame_count[dec->index],
+ display_frame_count[dec->index],
+ run_count[dec->index],
+ not_run_ready[dec->index],
+ input_empty[dec->index]
+ );
+
+ if (vf_get_receiver(vdec->vf_provider_name)) {
+ enum receiver_start_e state =
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE,
+ NULL);
+ avs3_print(dec, 0,
+ "\nreceiver(%s) state %d\n",
+ vdec->vf_provider_name,
+ state);
+ }
+
+ avs3_print(dec, 0,
+ "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
+ __func__,
+ kfifo_len(&dec->newframe_q),
+ VF_POOL_SIZE,
+ kfifo_len(&dec->display_q),
+ VF_POOL_SIZE,
+ dec->vf_pre_count,
+ dec->vf_get_count,
+ dec->vf_put_count,
+ get_free_buf_count(dec),
+ run_ready_min_buf_num
+ );
+
+ print_pic_pool(&dec->avs3_dec, "");
+
+ avs3_print(dec, 0,
+ "HEVC_DEC_STATUS_REG=0x%x\n",
+ READ_VREG(HEVC_DEC_STATUS_REG));
+ avs3_print(dec, 0,
+ "HEVC_MPC_E=0x%x\n",
+ READ_VREG(HEVC_MPC_E));
+ avs3_print(dec, 0,
+ "DECODE_MODE=0x%x\n",
+ READ_VREG(DECODE_MODE));
+ avs3_print(dec, 0,
+ "NAL_SEARCH_CTL=0x%x\n",
+ READ_VREG(NAL_SEARCH_CTL));
+ avs3_print(dec, 0,
+ "HEVC_PARSER_LCU_START=0x%x\n",
+ READ_VREG(HEVC_PARSER_LCU_START));
+ avs3_print(dec, 0,
+ "HEVC_DECODE_SIZE=0x%x\n",
+ READ_VREG(HEVC_DECODE_SIZE));
+ avs3_print(dec, 0,
+ "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
+ READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+ avs3_print(dec, 0,
+ "HEVC_STREAM_START_ADDR=0x%x\n",
+ READ_VREG(HEVC_STREAM_START_ADDR));
+ avs3_print(dec, 0,
+ "HEVC_STREAM_END_ADDR=0x%x\n",
+ READ_VREG(HEVC_STREAM_END_ADDR));
+ avs3_print(dec, 0,
+ "HEVC_STREAM_LEVEL=0x%x\n",
+ READ_VREG(HEVC_STREAM_LEVEL));
+ avs3_print(dec, 0,
+ "HEVC_STREAM_WR_PTR=0x%x\n",
+ READ_VREG(HEVC_STREAM_WR_PTR));
+ avs3_print(dec, 0,
+ "HEVC_STREAM_RD_PTR=0x%x\n",
+ READ_VREG(HEVC_STREAM_RD_PTR));
+ avs3_print(dec, 0,
+ "PARSER_VIDEO_RP=0x%x\n",
+ STBUF_READ(&vdec->vbuf, get_rp));
+ avs3_print(dec, 0,
+ "PARSER_VIDEO_WP=0x%x\n",
+ STBUF_READ(&vdec->vbuf, get_wp));
+
+ if (input_frame_based(vdec) &&
+ (debug & PRINT_FLAG_VDEC_DATA)
+ ) {
+ int jj;
+ if (dec->chunk && dec->chunk->block &&
+ dec->chunk->size > 0) {
+ u8 *data = NULL;
+ if (!dec->chunk->block->is_mapped)
+ data = codec_mm_vmap(dec->chunk->block->start +
+ dec->chunk->offset, dec->chunk->size);
+ else
+ data = ((u8 *)dec->chunk->block->start_virt) +
+ dec->chunk->offset;
+ avs3_print(dec, 0,
+ "frame data size 0x%x\n",
+ dec->chunk->size);
+ for (jj = 0; jj < dec->chunk->size; jj++) {
+ if ((jj & 0xf) == 0)
+ avs3_print(dec, 0,
+ "%06x:", jj);
+ avs3_print_cont(dec, 0,
+ "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ avs3_print_cont(dec, 0,
+ "\n");
+ }
+
+ if (!dec->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ }
+ }
+
+ if (dec->front_back_mode == 1) {
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ avs3_print(dec, 0,
+ "[BE] dec_back_result 0x%x, frontend_decoded_count %d, backend_decoded_count %d, fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+ dec->dec_back_result,
+ avs3_dec->frontend_decoded_count,
+ avs3_dec->backend_decoded_count,
+ avs3_dec->fb_wr_pos,
+ avs3_dec->fb_rd_pos,
+ avs3_dec->wait_working_buf
+ );
+
+ avs3_print(dec, 0,
+ "[BE] HEVC_DEC_STATUS_DBE=0x%x\n",
+ READ_VREG(HEVC_DEC_STATUS_DBE));
+ avs3_print(dec, 0,
+ "[BE] HEVC_MPC_E_DBE=0x%x\n",
+ READ_VREG(HEVC_MPC_E_DBE));
+ avs3_print(dec, 0,
+ "[BE] HEVC_MPSR_DBE=0x%x\n",
+ READ_VREG(HEVC_MPSR_DBE));
+ avs3_print(dec, 0,
+ "[BE] DEBUG_REG1_DBE=0x%x\n",
+ READ_VREG(DEBUG_REG1_DBE));
+ avs3_print(dec, 0,
+ "[BE] DEBUG_REG2_DBE=0x%x\n",
+ READ_VREG(DEBUG_REG2_DBE));
+ print_loopbufs_adr_size(dec);
+ print_loopbufs_ptr(dec, "fr", &avs3_dec->fr);
+ print_loopbufs_ptr(dec, "bk", &avs3_dec->bk);
+ }
+
+ if (dump_phy_adr != 0 && dump_phy_size != 0) {
+ dump_or_fill_phy_buffer(dec, dump_phy_adr, dump_phy_size, NULL, 2, NULL);
+ }
+ if (fbdebug_flag & 0x80000000) {
+ dump_loop_buffer(dec, -1, 1);
+ fbdebug_flag &= ~0x80000000;
+ }
+}
+
+static void d_dump(struct AVS3Decoder_s *dec, unsigned int phy_adr, int size,
+ struct file *fp, loff_t *wr_off, u32 * total_check_sum, u8 print_flag)
+{
+ u8 *vaddr;
+ u32 check_sum = 0;
+ vaddr = codec_mm_vmap(phy_adr, size);
+ if (vaddr) {
+ int i;
+ if (total_check_sum == NULL) {
+ for (i = 0; i < size; i++)
+ vaddr[i] = 0;
+ codec_mm_dma_flush(vaddr, size, DMA_TO_DEVICE);
+ } else {
+ codec_mm_dma_flush(vaddr, size, DMA_FROM_DEVICE);
+ if (fp) {
+ media_write(fp, vaddr, size, wr_off);
+ for (i = 0; i < size; i++)
+ check_sum += vaddr[i];
+ *total_check_sum += check_sum;
+ } else {
+ for (i = 0; i < size; i++) {
+ if (print_flag) {
+ if ((i & 0xf) == 0)
+ avs3_print_cont(dec, 0, "%08x: ", phy_adr+i);
+ avs3_print_cont(dec, 0, "%02x ", vaddr[i]);
+ }
+ check_sum += vaddr[i];
+ if (print_flag) {
+ if (((i + 1) & 0xf) == 0)
+ avs3_print_flush(dec); //avs3_print(dec, 0, "\n");
+ }
+ }
+ *total_check_sum += check_sum;
+ if (print_flag)
+ avs3_print(dec, 0, "check_sum %08x, %08x\n", *total_check_sum, check_sum);
+ }
+ }
+ codec_mm_unmap_phyaddr(vaddr);
+ } else {
+ pr_info("%s codec_mm_vmap fail\n", __func__);
+ }
+}
+
+static void dump_or_fill_phy_buffer(struct AVS3Decoder_s *dec, u32 dump_phy_adr, u32 dump_phy_size, char *file, u8 flag, char *mark)
+{
+ /*
+ flag: 1, fill zero
+ flag: 2, print data
+ */
+ loff_t off = 0;
+ int mode = O_CREAT | O_WRONLY | O_TRUNC;
+ struct file *fp = NULL;
+
+ int dump_size = 1024;
+ int remain_size = dump_phy_size;
+ u32 phy_adr = dump_phy_adr;
+ u32 total_check_sum = 0;
+
+ if (file) {
+ fp = media_open(file, mode, 0666);
+ }
+ while (remain_size > 0) {
+ if (flag == 1)
+ d_dump(dec, phy_adr, dump_size, NULL, NULL, NULL, 0);
+ else
+ d_dump(dec, phy_adr, dump_size, fp, &off, &total_check_sum, flag == 2);
+
+ remain_size -= dump_size;
+ phy_adr += dump_size;
+ if (remain_size < dump_size)
+ dump_size = remain_size;
+ //msleep(20);
+ }
+ if (fp) {
+ media_close(fp, current->files);
+ }
+ if (flag == 1)
+ avs3_print(dec, 0, "fill phy mem %s %x (size %x):\n", mark?mark:"", dump_phy_adr, dump_phy_size);
+ else
+ avs3_print(dec, 0, "dump phy mem %s %x (size %x) check_sum %x %s\n", mark?mark:"", dump_phy_adr, dump_phy_size, total_check_sum, file? file:"");
+}
+
+static int ammvdec_avs3_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ int ret;
+ int config_val;
+ int i;
+ struct vframe_content_light_level_s content_light_level;
+ struct vframe_master_display_colour_s vf_dp;
+ /*struct BUF_s BUF[MAX_BUF_NUM];*/
+ struct AVS3Decoder_s *dec = NULL;
+ static struct vframe_operations_s vf_tmp_ops;
+
+ pr_info("%s\n", __func__);
+
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+ pr_info("%s, chip id %d is not support avs3\n",
+ __func__, get_cpu_major_id());
+ return -1;
+ }
+ if (pdata == NULL) {
+ pr_info("\nammvdec_avs3 memory resource undefined.\n");
+ return -EFAULT;
+ }
+ /*dec = (struct AVS3Decoder_s *)devm_kzalloc(&pdev->dev,
+ sizeof(struct AVS3Decoder_s), GFP_KERNEL);*/
+ memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
+ dec = vzalloc(sizeof(struct AVS3Decoder_s));
+ if (dec == NULL) {
+ pr_info("\nammvdec_avs3 device data allocation failed\n");
+ return -ENOMEM;
+ }
+ /*
+ //move to other place after pic_pool is initialized
+ if (pdata->parallel_dec == 1) {
+ int i;
+ for (i = 0; i < MAX_PB_SIZE; i++) {
+ dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index = -1;
+ dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index = -1;
+ }
+ }
+ */
+ pdata->private = dec;
+ pdata->dec_status = vavs3_dec_status;
+#ifdef I_ONLY_SUPPORT
+ pdata->set_trickmode = vavs3_set_trickmode;
+#endif
+ pdata->run_ready = run_ready;
+ pdata->run = run;
+ dec->avs3_dec.max_pb_size = MAX_PB_SIZE; //will reconfig later
+#ifdef NEW_FB_CODE
+ if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) {
+ dec->front_back_mode = front_back_mode;
+ } else {
+ dec->front_back_mode = 0;
+ }
+ dec->fb_ifbuf_num = fb_ifbuf_num;
+ if (dec->fb_ifbuf_num > MAX_FB_IFBUF_NUM)
+ dec->fb_ifbuf_num = MAX_FB_IFBUF_NUM;
+ pdata->check_input_data = NULL;
+ if (dec->front_back_mode) {
+ pdata->check_input_data = check_input_data;
+ pdata->reset = NULL;
+ pdata->back_irq_handler = avs3_back_irq_cb;
+ pdata->back_threaded_irq_handler = avs3_back_threaded_irq_cb;
+ } else
+#endif
+ pdata->reset = reset;
+ pdata->irq_handler = avs3_irq_cb;
+ pdata->threaded_irq_handler = avs3_threaded_irq_cb;
+ pdata->dump_state = avs3_dump_state;
+
+ /*
+ * memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ * memset(dec, 0, sizeof(struct AVS3Decoder_s));
+ * memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ */
+
+ dec->index = pdev->id;
+ dec->m_ins_flag = 1;
+
+ config_hevc_irq_num(dec);
+
+ if (is_rdma_enable()) {
+ dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle, RDMA_SIZE, &dec->rdma_phy_adr, "AVS3_RDMA_BUF");
+ for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
+ dec->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
+ dec->rdma_adr[i * 4 + 1] = i;
+ dec->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
+ dec->rdma_adr[i * 4 + 3] = 0;
+ if (i == SCALELUT_DATA_WRITE_NUM - 1) {
+ dec->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
+ }
+ }
+ }
+
+ snprintf(dec->trace.vdec_name, sizeof(dec->trace.vdec_name),
+ "avs3-%d", dec->index);
+ snprintf(dec->trace.pts_name, sizeof(dec->trace.pts_name),
+ "%s-pts", dec->trace.vdec_name);
+ snprintf(dec->trace.vf_get_name, sizeof(dec->trace.vf_get_name),
+ "%s-vf_get", dec->trace.vdec_name);
+ snprintf(dec->trace.vf_put_name, sizeof(dec->trace.vf_put_name),
+ "%s-vf_put", dec->trace.vdec_name);
+ snprintf(dec->trace.set_canvas0_addr, sizeof(dec->trace.set_canvas0_addr),
+ "%s-set_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.get_canvas0_addr, sizeof(dec->trace.get_canvas0_addr),
+ "%s-get_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.put_canvas0_addr, sizeof(dec->trace.put_canvas0_addr),
+ "%s-put_canvas0_addr", dec->trace.vdec_name);
+ snprintf(dec->trace.new_q_name, sizeof(dec->trace.new_q_name),
+ "%s-newframe_q", dec->trace.vdec_name);
+ snprintf(dec->trace.disp_q_name, sizeof(dec->trace.disp_q_name),
+ "%s-dispframe_q", dec->trace.vdec_name);
+ snprintf(dec->trace.decode_time_name, sizeof(dec->trace.decode_time_name),
+ "decoder_time%d", pdev->id);
+ snprintf(dec->trace.decode_run_time_name, sizeof(dec->trace.decode_run_time_name),
+ "decoder_run_time%d", pdev->id);
+ snprintf(dec->trace.decode_header_memory_time_name, sizeof(dec->trace.decode_header_memory_time_name),
+ "decoder_header_time%d", pdev->id);
+ snprintf(dec->trace.decode_work_time_name, sizeof(dec->trace.decode_work_time_name),
+ "decoder_work_time%d", pdev->id);
+ snprintf(dec->trace.decode_back_time_name, sizeof(dec->trace.decode_back_time_name),
+ "decoder_back_time%d", pdev->id);
+ snprintf(dec->trace.decode_back_run_time_name, sizeof(dec->trace.decode_back_run_time_name),
+ "decoder_back_run_time%d", pdev->id);
+ snprintf(dec->trace.decode_back_work_time_name, sizeof(dec->trace.decode_back_work_time_name),
+ "decoder_back_work_time%d", pdev->id);
+
+ if (pdata->use_vfm_path) {
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ VFM_DEC_PROVIDER_NAME);
+ dec->frameinfo_enable = 1;
+ } else
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+
+ memcpy(&vf_tmp_ops, &vavs3_vf_provider, sizeof(struct vframe_operations_s));
+ if (without_display_mode == 1) {
+ vf_tmp_ops.get = NULL;
+ }
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vf_tmp_ops, dec);
+
+ dec->provider_name = pdata->vf_provider_name;
+ platform_set_drvdata(pdev, pdata);
+
+ dec->platform_dev = pdev;
+ dec->video_signal_type = 0;
+ dec->video_ori_signal_type = 0;
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX)
+ dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
+
+ if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
+ /*use ptr config for double_write_mode, etc*/
+ avs3_print(dec, 0, "pdata->config=%s\n", pdata->config);
+ if (get_config_int(pdata->config, "avs3_double_write_mode",
+ &config_val) == 0)
+ dec->double_write_mode = config_val;
+ else
+ dec->double_write_mode = double_write_mode;
+
+#ifdef OW_TRIPLE_WRITE
+ if (get_config_int(pdata->config, "avs3_triple_write_mode",
+ &config_val) == 0)
+ dec->triple_write_mode = config_val;
+ else
+ dec->triple_write_mode = triple_write_mode;
+#endif
+
+ if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
+ &config_val) == 0)
+ dec->dynamic_buf_margin = config_val;
+ else
+ dec->dynamic_buf_margin = 0;
+
+ if (get_config_int(pdata->config, "sidebind_type",
+ &config_val) == 0)
+ dec->sidebind_type = config_val;
+
+ if (get_config_int(pdata->config, "sidebind_channel_id",
+ &config_val) == 0)
+ dec->sidebind_channel_id = config_val;
+
+ if (get_config_int(pdata->config, "HDRStaticInfo",
+ &vf_dp.present_flag) == 0
+ && vf_dp.present_flag == 1) {
+ get_config_int(pdata->config, "mG.x",
+ &vf_dp.primaries[0][0]);
+ get_config_int(pdata->config, "mG.y",
+ &vf_dp.primaries[0][1]);
+ get_config_int(pdata->config, "mB.x",
+ &vf_dp.primaries[1][0]);
+ get_config_int(pdata->config, "mB.y",
+ &vf_dp.primaries[1][1]);
+ get_config_int(pdata->config, "mR.x",
+ &vf_dp.primaries[2][0]);
+ get_config_int(pdata->config, "mR.y",
+ &vf_dp.primaries[2][1]);
+ get_config_int(pdata->config, "mW.x",
+ &vf_dp.white_point[0]);
+ get_config_int(pdata->config, "mW.y",
+ &vf_dp.white_point[1]);
+ get_config_int(pdata->config, "mMaxDL",
+ &vf_dp.luminance[0]);
+ get_config_int(pdata->config, "mMinDL",
+ &vf_dp.luminance[1]);
+ vf_dp.content_light_level.present_flag = 1;
+ get_config_int(pdata->config, "mMaxCLL",
+ &content_light_level.max_content);
+ get_config_int(pdata->config, "mMaxFALL",
+ &content_light_level.max_pic_average);
+ vf_dp.content_light_level = content_light_level;
+ dec->video_signal_type = (1 << 29)
+ | (5 << 26) /* unspecified */
+ | (0 << 25) /* limit */
+ | (1 << 24) /* color available */
+ | (9 << 16) /* 2020 */
+ | (16 << 8) /* 2084 */
+ | (9 << 0); /* 2020 */
+ }
+ dec->vf_dp = vf_dp;
+ } else {
+ /*dec->vavs3_amstream_dec_info.width = 0;
+ dec->vavs3_amstream_dec_info.height = 0;
+ dec->vavs3_amstream_dec_info.rate = 30;*/
+ dec->double_write_mode = double_write_mode;
+ dec->dynamic_buf_margin = dynamic_buf_num_margin;
+ }
+ video_signal_type = dec->video_signal_type;
+
+ if (double_write_mode) {
+ dec->double_write_mode = get_double_write_mode(dec);
+ }
+
+ if ((dec->double_write_mode & 0x10) == 0)
+ dec->mmu_enable = 1;
+
+#ifdef AVS3_10B_MMU_DW
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
+ dec->dw_mmu_enable =
+ (get_double_write_mode(dec) & 0x20) ? 1 : 0;
+ } else {
+ dec->dw_mmu_enable = 0;
+ }
+#endif
+#ifdef OW_TRIPLE_WRITE
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3X) {
+ if ((dec->triple_write_mode) || (triple_write_mode) ||
+ (dec->double_write_mode & 0x10000) || (double_write_mode & 0x10000)) {
+ double_write_mode &= ~(1 <<16);
+ dec->double_write_mode &= ~(1 <<16);
+ triple_write_mode = 0;
+ dec->triple_write_mode = 0;
+ pr_err("%s warn: unsupport triple write or p010 mode, force disabled\n", __func__);
+ }
+ }
+#endif
+
+ if (amvdec_avs3_mmu_init(dec) < 0) {
+ pr_err("avs3 alloc bmmu box failed!!\n");
+ /* devm_kfree(&pdev->dev, (void *)dec); */
+ vfree((void *)dec);
+ return -1;
+ }
+ dec->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE;
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+ dec->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
+ &dec->cma_alloc_addr);
+ if (ret < 0) {
+ uninit_mmu_buffers(dec);
+ /* devm_kfree(&pdev->dev, (void *)dec); */
+ vfree((void *)dec);
+ return ret;
+ }
+ if (!vdec_secure(pdata))
+ codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
+ dec->buf_start = dec->cma_alloc_addr;
+ dec->buf_size = work_buf_size;
+
+ dec->init_flag = 0;
+ dec->first_sc_checked = 0;
+ dec->fatal_error = 0;
+ dec->show_frame_num = 0;
+
+ if (debug) {
+ pr_info("===AVS3 decoder mem resource 0x%lx size 0x%x\n",
+ dec->buf_start,
+ dec->buf_size);
+ }
+
+ if (pdata->sys_info) {
+ dec->vavs3_amstream_dec_info = *pdata->sys_info;
+ dec->frame_width = dec->vavs3_amstream_dec_info.width;
+ dec->frame_height = dec->vavs3_amstream_dec_info.height;
+ } else {
+ dec->vavs3_amstream_dec_info.width = 0;
+ dec->vavs3_amstream_dec_info.height = 0;
+ dec->vavs3_amstream_dec_info.rate = 30;
+ }
+
+ dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
+ if (is_support_vdec_canvas())
+ dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+ if (is_dw_p010(dec) || is_tw_p010(dec))
+ dec->endian = HEVC_CONFIG_P010_LE;
+ if (endian)
+ dec->endian = endian;
+
+ dec->cma_dev = pdata->cma_dev;
+ if (vavs3_init(pdata) < 0) {
+ pr_info("\namvdec_avs3 init failed.\n");
+ avs3_local_uninit(dec);
+ uninit_mmu_buffers(dec);
+ /* devm_kfree(&pdev->dev, (void *)dec); */
+ vfree((void *)dec);
+ pdata->dec_status = NULL;
+ return -ENODEV;
+ }
+ if (pdata->parallel_dec == 1) {
+ //run only after pic_pool initialzied in vavs3_init()
+ int i;
+ for (i = 0; i < MAX_PB_SIZE; i++) {
+ dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index = -1;
+ dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index = -1;
+ }
+ }
+ spin_lock_init(&dec->buffer_lock);
+ spin_lock_init(&dec->front_back_lock);
+ mutex_init(&dec->slice_header_lock);
+ vdec_set_prepare_level(pdata, start_decode_buf_level);
+ hevc_source_changed(VFORMAT_AVS3,
+ 4096, 2048, 60);
+ if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode)
+ vdec_core_request(pdata, CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+ else
+#endif
+ vdec_core_request(pdata, CORE_MASK_HEVC);
+ } else {
+ vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
+ | CORE_MASK_COMBINE);
+ }
+
+ return 0;
+}
+
+static int ammvdec_avs3_remove(struct platform_device *pdev)
+{
+ struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)
+ (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+ struct avs3_frame_s *pic;
+ int i;
+
+ if (debug)
+ pr_info("amvdec_avs3_remove\n");
+
+ vmavs3_stop(dec);
+
+ if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+ if (dec->front_back_mode)
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+ else
+#endif
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
+ } else
+ vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
+
+ vdec_set_status(hw_to_vdec(dec), VDEC_STATUS_DISCONNECTED);
+ if (pdata->parallel_dec == 1) {
+ for (i = 0; i < MAX_PB_SIZE; i++) {
+ pdata->free_canvas_ex(dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index, pdata->id);
+ pdata->free_canvas_ex(dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index, pdata->id);
+ }
+ }
+
+ for (i = 0; i < avs3_dec->max_pb_size; i++) {
+ pic = &avs3_dec->pic_pool[i].buf_cfg;
+ if (pic->used < 0)
+ continue;
+
+ release_cuva_data(pic);
+ }
+
+#ifdef DEBUG_PTS
+ pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+ dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+ if (is_rdma_enable())
+ decoder_dma_free_coherent(dec->rdma_mem_handle, RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
+ /* devm_kfree(&pdev->dev, (void *)dec); */
+ vfree((void *)dec);
+ return 0;
+}
+
+static struct platform_driver ammvdec_avs3_driver = {
+ .probe = ammvdec_avs3_probe,
+ .remove = ammvdec_avs3_remove,
+#ifdef CONFIG_PM
+ .suspend = amvdec_suspend,
+ .resume = amvdec_resume,
+#endif
+ .driver = {
+ .name = MULTI_DRIVER_NAME,
+ }
+};
+#endif
+//#ifndef FOR_S5
+static struct mconfig avs3_configs[] = {
+ MC_PU32("bit_depth_luma", &bit_depth_luma),
+ MC_PU32("bit_depth_chroma", &bit_depth_chroma),
+ MC_PU32("frame_width", &frame_width),
+ MC_PU32("frame_height", &frame_height),
+ MC_PU32("debug", &debug),
+ MC_PU32("radr", &radr),
+ MC_PU32("rval", &rval),
+ MC_PU32("pop_shorts", &pop_shorts),
+ MC_PU32("dbg_cmd", &dbg_cmd),
+ MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
+ MC_PU32("endian", &endian),
+ MC_PU32("step", &step),
+ MC_PU32("udebug_flag", &udebug_flag),
+ MC_PU32("decode_pic_begin", &decode_pic_begin),
+ MC_PU32("slice_parse_begin", &slice_parse_begin),
+ MC_PU32("i_only_flag", &i_only_flag),
+ MC_PU32("error_handle_policy", &error_handle_policy),
+ MC_PU32("buf_alloc_width", &buf_alloc_width),
+ MC_PU32("buf_alloc_height", &buf_alloc_height),
+ MC_PU32("buf_alloc_depth", &buf_alloc_depth),
+ MC_PU32("buf_alloc_size", &buf_alloc_size),
+ MC_PU32("buffer_mode", &buffer_mode),
+ MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
+ MC_PU32("max_buf_num", &max_buf_num),
+ MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
+ MC_PU32("mem_map_mode", &mem_map_mode),
+ MC_PU32("double_write_mode", &double_write_mode),
+ MC_PU32("enable_mem_saving", &enable_mem_saving),
+ MC_PU32("force_w_h", &force_w_h),
+ MC_PU32("force_fps", &force_fps),
+ MC_PU32("max_decoding_time", &max_decoding_time),
+ MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped),
+ MC_PU32("start_decode_buf_level", &start_decode_buf_level),
+ MC_PU32("decode_timeout_val", &decode_timeout_val),
+};
+static struct mconfig_node avs3_node;
+//#endif
+static int __init amvdec_avs3_driver_init_module(void)
+{
+
+#ifdef AVS3_10B_MMU
+ struct BuffInfo_s *p_buf_info;
+ unsigned int bufspec_index = 0;
+ if (force_bufspec) {
+ bufspec_index = force_bufspec & 0xf;
+ pr_info("force buffer spec %d\n", force_bufspec & 0xf);
+ } else {
+ if (vdec_is_support_4k()) {
+ bufspec_index = 2; /* 8k */
+ } else
+ bufspec_index = 0;/* 1080p */
+ }
+ p_buf_info = &amvavs3_workbuff_spec[bufspec_index];
+ pr_info("%s bufspec_index = %d\n", __func__, bufspec_index);
+ init_buff_spec(NULL, p_buf_info);
+ work_buf_size =
+ (p_buf_info->end_adr - p_buf_info->start_adr
+ + 0xffff) & (~0xffff);
+
+#endif
+ pr_debug("amvdec_avs3 module init\n");
+
+#ifdef ERROR_HANDLE_DEBUG
+ dbg_nal_skip_flag = 0;
+ dbg_nal_skip_count = 0;
+#endif
+ udebug_flag = 0;
+ decode_pic_begin = 0;
+ slice_parse_begin = 0;
+ step = 0;
+ buf_alloc_size = 0;
+ if (platform_driver_register(&ammvdec_avs3_driver))
+ pr_err("failed to register ammvdec_avs3 driver\n");
+
+ if (platform_driver_register(&amvdec_avs3_driver)) {
+ pr_err("failed to register amvdec_avs3 driver\n");
+ return -ENODEV;
+ }
+ if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
+ (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
+ amvdec_avs3_profile.name = "avs3_unsupport";
+ } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+ if (vdec_is_support_4k())
+ amvdec_avs3_profile.profile =
+ "4k, 10bit, dwrite, compressed";
+ else
+ amvdec_avs3_profile.profile =
+ "10bit, dwrite, compressed";
+ } else {
+ /* cpu id larger than sm1 support 8k */
+ amvdec_avs3_profile.profile =
+ "8k, 10bit, dwrite, compressed";
+ }
+
+ vcodec_profile_register(&amvdec_avs3_profile);
+ amvdec_avs3_profile_mult = amvdec_avs3_profile;
+ amvdec_avs3_profile_mult.name = "mavs3";
+ vcodec_profile_register(&amvdec_avs3_profile_mult);
+
+ INIT_REG_NODE_CONFIGS("media.decoder", &avs3_node,
+ "avs3", avs3_configs, CONFIG_FOR_RW);
+ vcodec_feature_register(VFORMAT_AVS3, 0);
+ return 0;
+}
+
+static void __exit amvdec_avs3_driver_remove_module(void)
+{
+ pr_debug("amvdec_avs3 module remove.\n");
+ platform_driver_unregister(&ammvdec_avs3_driver);
+ platform_driver_unregister(&amvdec_avs3_driver);
+}
+
+/****************************************/
+
+module_param(bit_depth_luma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs3 bit_depth_luma\n");
+
+module_param(bit_depth_chroma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_avs3 bit_depth_chroma\n");
+
+module_param(frame_width, uint, 0664);
+MODULE_PARM_DESC(frame_width, "\n amvdec_avs3 frame_width\n");
+
+module_param(frame_height, uint, 0664);
+MODULE_PARM_DESC(frame_height, "\n amvdec_avs3 frame_height\n");
+
+module_param(debug, uint, 0664);
+MODULE_PARM_DESC(debug, "\n amvdec_avs3 debug\n");
+
+module_param(debug_again, uint, 0664);
+MODULE_PARM_DESC(debug_again, "\n amvdec_avs3 debug_again\n");
+
+module_param(radr, uint, 0664);
+MODULE_PARM_DESC(radr, "\nradr\n");
+
+module_param(rval, uint, 0664);
+MODULE_PARM_DESC(rval, "\nrval\n");
+
+module_param(pop_shorts, uint, 0664);
+MODULE_PARM_DESC(pop_shorts, "\nrval\n");
+
+module_param(dbg_cmd, uint, 0664);
+MODULE_PARM_DESC(dbg_cmd, "\ndbg_cmd\n");
+
+module_param(dbg_skip_decode_index, uint, 0664);
+MODULE_PARM_DESC(dbg_skip_decode_index, "\ndbg_skip_decode_index\n");
+
+module_param(endian, uint, 0664);
+MODULE_PARM_DESC(endian, "\nrval\n");
+
+module_param(step, uint, 0664);
+MODULE_PARM_DESC(step, "\n amvdec_avs3 step\n");
+
+module_param(decode_pic_begin, uint, 0664);
+MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_avs3 decode_pic_begin\n");
+
+module_param(slice_parse_begin, uint, 0664);
+MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_avs3 slice_parse_begin\n");
+
+module_param(i_only_flag, uint, 0664);
+MODULE_PARM_DESC(i_only_flag, "\n amvdec_avs3 i_only_flag\n");
+
+module_param(error_handle_policy, uint, 0664);
+MODULE_PARM_DESC(error_handle_policy, "\n amvdec_avs3 error_handle_policy\n");
+
+module_param(re_search_seq_threshold, uint, 0664);
+MODULE_PARM_DESC(re_search_seq_threshold, "\n amvdec_avs3 re_search_seq_threshold\n");
+
+module_param(buf_alloc_width, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
+
+module_param(buf_alloc_height, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
+
+module_param(buf_alloc_depth, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
+
+module_param(buf_alloc_size, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
+
+module_param(over_decoder_shiftbytes, uint, 0664);
+MODULE_PARM_DESC(over_decoder_shiftbytes, "\n over_decoder_shiftbytes\n");
+
+module_param(buffer_mode, uint, 0664);
+MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
+
+module_param(buffer_mode_dbg, uint, 0664);
+MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
+/*USE_BUF_BLOCK*/
+module_param(max_buf_num, uint, 0664);
+MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
+
+module_param(dynamic_buf_num_margin, uint, 0664);
+MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+module_param(run_ready_max_vf_only_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_max_vf_only_num, "\n run_ready_max_vf_only_num\n");
+
+module_param(run_ready_display_q_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_display_q_num, "\n run_ready_display_q_num\n");
+
+module_param(run_ready_max_buf_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_max_buf_num, "\n run_ready_max_buf_num\n");
+#endif
+
+module_param(mv_buf_margin, uint, 0664);
+MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n");
+
+module_param(run_ready_min_buf_num, uint, 0664);
+MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
+
+/**/
+
+module_param(mem_map_mode, uint, 0664);
+MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
+
+module_param(double_write_mode, uint, 0664);
+MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
+
+#ifdef OW_TRIPLE_WRITE
+module_param(triple_write_mode, uint, 0664);
+MODULE_PARM_DESC(triple_write_mode, "\n triple_write_mode\n");
+#endif
+
+module_param(enable_mem_saving, uint, 0664);
+MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
+
+module_param(force_w_h, uint, 0664);
+MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
+
+module_param(force_fps, uint, 0664);
+MODULE_PARM_DESC(force_fps, "\n force_fps\n");
+
+module_param(max_decoding_time, uint, 0664);
+MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
+
+module_param(on_no_keyframe_skiped, uint, 0664);
+MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
+
+module_param(start_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(start_decode_buf_level,
+ "\n avs3 start_decode_buf_level\n");
+
+module_param(decode_timeout_val, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val,
+ "\n avs3 decode_timeout_val\n");
+
+module_param_array(decode_frame_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(display_frame_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(max_process_time, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(run_count, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(input_empty, uint,
+ &max_decode_instance_num, 0664);
+
+module_param_array(not_run_ready, uint,
+ &max_decode_instance_num, 0664);
+
+module_param(video_signal_type, uint, 0664);
+MODULE_PARM_DESC(video_signal_type, "\n amvdec_avs3 video_signal_type\n");
+
+module_param(force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(force_video_signal_type, "\n amvdec_avs3 force_video_signal_type\n");
+
+module_param(enable_force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs3 enable_force_video_signal_type\n");
+
+module_param(force_bufspec, uint, 0664);
+MODULE_PARM_DESC(force_bufspec, "\n amvdec_avs3 force_bufspec\n");
+
+module_param(fbdebug_flag, uint, 0664);
+MODULE_PARM_DESC(fbdebug_flag, "\n amvdec_avs3 fbdebug_flag\n");
+
+module_param(udebug_flag, uint, 0664);
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs3 udebug_flag\n");
+
+module_param(udebug_pause_pos, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
+
+module_param(udebug_pause_val, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
+
+module_param(udebug_pause_decode_idx, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
+
+module_param(dump_phy_adr, uint, 0664);
+MODULE_PARM_DESC(dump_phy_adr, "\n dump_phy_adr\n");
+
+module_param(dump_phy_size, uint, 0664);
+MODULE_PARM_DESC(dump_phy_size, "\n dump_phy_size\n");
+
+#ifdef DEBUG_CMD
+module_param(debug_cmd_wait_type, uint, 0664);
+MODULE_PARM_DESC(debug_cmd_wait_type, "\n debug_cmd_wait_type\n");
+
+module_param(debug_cmd_wait_count, uint, 0664);
+MODULE_PARM_DESC(debug_cmd_wait_count, "\n debug_cmd_wait_count\n");
+#endif
+
+module_param(pre_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(pre_decode_buf_level,
+ "\n amvdec_avs3 pre_decode_buf_level\n");
+
+module_param(again_threshold, uint, 0664);
+MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
+
+module_param(force_disp_pic_index, int, 0664);
+MODULE_PARM_DESC(force_disp_pic_index,
+ "\n amvdec_avs3 force_disp_pic_index\n");
+
+module_param(without_display_mode, uint, 0664);
+MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
+
+module_param(mv_buf_dynamic_alloc, uint, 0664);
+MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
+
+#ifdef NEW_FB_CODE
+module_param(front_back_mode, uint, 0664);
+MODULE_PARM_DESC(front_back_mode, "\n amvdec_avs3 front_back_mode\n");
+
+module_param(fb_ifbuf_num, uint, 0664);
+MODULE_PARM_DESC(fb_ifbuf_num, "\n amvdec_avs3 fb_ifbuf_num\n");
+
+module_param(decode_timeout_val_back, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val_back,
+ "\n amvdec_avs3 decode_timeout_val_back\n");
+
+module_param(fast_timer_check_count, uint, 0664);
+MODULE_PARM_DESC(fast_timer_check_count,
+ "\n amvdec_avs3 fast_timer_check_count\n");
+
+module_param_array(max_process_time_back, uint,
+ &max_decode_instance_num, 0664);
+#endif
+
+module_param(trace_debug_mode, uint, 0664);
+MODULE_PARM_DESC(trace_debug_mode, "\n trace_debug_mode\n");
+
+module_param(paral_alloc_buffer_mode, uint, 0664);
+MODULE_PARM_DESC(paral_alloc_buffer_mode, "\n paral_alloc_buffer_mode\n");
+
+#ifdef NEW_FB_CODE
+
+module_param(efficiency_mode, uint, 0664);
+MODULE_PARM_DESC(efficiency_mode, "\n efficiency_mode\n");
+
+#endif
+
+module_init(amvdec_avs3_driver_init_module);
+module_exit(amvdec_avs3_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC avs3 Video Decoder Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/h264/vh264.h b/drivers/frame_provider/decoder/avs3/vavs3.h
similarity index 61%
copy from drivers/frame_provider/decoder/h264/vh264.h
copy to drivers/frame_provider/decoder/avs3/vavs3.h
index 6c8e4ad..f00c08f 100644
--- a/drivers/frame_provider/decoder/h264/vh264.h
+++ b/drivers/frame_provider/decoder/avs3/vavs3.h
@@ -1,7 +1,7 @@
/*
- * drivers/amlogic/media/frame_provider/decoder/h264/vh264.h
+ * drivers/amlogic/amports/vavs3.h
*
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,15 +13,14 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
- */
+*/
-#ifndef VH264_H
-#define VH264_H
+#ifndef VAVS3_H
+#define VAVS3_H
-extern int query_video_status(int type, int *value);
+#define AVS3_10B_MMU
+#define AVS3_10B_MMU_DW
-/* extern s32 vh264_init(void); */
-
-extern s32 vh264_release(void);
-
-#endif /* VMPEG4_H */
+void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
+unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
+#endif
diff --git a/drivers/frame_provider/decoder/avs_multi/Makefile b/drivers/frame_provider/decoder/avs_multi/Makefile
index 638cec0..0a90f15 100644
--- a/drivers/frame_provider/decoder/avs_multi/Makefile
+++ b/drivers/frame_provider/decoder/avs_multi/Makefile
@@ -1,2 +1,7 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs.o
-amvdec_mavs-objs += avs_multi.o
+MODULE_NAME = amvdec_mavs
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += avs_multi.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
index 7dd20bb..0ba2183 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -1,7 +1,5 @@
/*
- * drivers/amlogic/amports/vavs.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,6 +11,11 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
*/
#include <linux/kernel.h>
#include <linux/types.h>
@@ -29,30 +32,26 @@
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../stream_input/amports/streambuf_reg.h"
-#include "../utils/amvdec.h"
#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/dma-mapping.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/slab.h>
-#include "avs_multi.h"
#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/tee.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../stream_input/amports/streambuf_reg.h"
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
#include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include <linux/amlogic/tee.h>
#include "../utils/vdec_feature.h"
+#include "../utils/amvdec.h"
+#include "avs_multi.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
#define DEBUG_MULTI_FLAG 0
-/*
-#define DEBUG_WITH_SINGLE_MODE
-#define DEBUG_MULTI_WITH_AUTOMODE
-#define DEBUG_MULTI_FRAME_INS
-*/
-
#define USE_DYNAMIC_BUF_NUM
@@ -66,9 +65,7 @@
#define ENABLE_USER_DATA
-#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
#define NV21
-#endif
#define USE_AVS_SEQ_INFO
#define HANDLE_AVS_IRQ
@@ -82,7 +79,6 @@
#define LMEM_BUF_SIZE (0x500 * 2)
-/* #define ORI_BUFFER_START_ADDR 0x81000000 */
#define ORI_BUFFER_START_ADDR 0x80000000
#define INTERLACE_FLAG 0x80
@@ -90,8 +86,7 @@
/* protocol registers */
#define AVS_PIC_RATIO AV_SCRATCH_0
-#define AVS_PIC_WIDTH AV_SCRATCH_1
-#define AVS_PIC_HEIGHT AV_SCRATCH_2
+#define AVS_PIC_INFO AV_SCRATCH_1
#define AVS_FRAME_RATE AV_SCRATCH_3
/*#define AVS_ERROR_COUNT AV_SCRATCH_6*/
@@ -116,6 +111,7 @@
#define DECODE_STATUS_DECODE_BUF_EMPTY 0x2
#define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3
#define DECODE_STATUS_SKIP_PIC_DONE 0x4
+#define DECODE_STATUS_INFO 0x5
#define DECODE_SEARCH_HEAD 0xff
#define DECODE_STOP_POS AV_SCRATCH_J
@@ -127,12 +123,7 @@
#define VF_POOL_SIZE 64
#define PUT_INTERVAL (HZ/100)
-#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
#define INT_AMVENCODER INT_DOS_MAILBOX_1
-#else
-/* #define AMVENC_DEV_VERSION "AML-MT" */
-#define INT_AMVENCODER INT_MAILBOX_1A
-#endif
#ifdef USE_DYNAMIC_BUF_NUM
static unsigned int buf_spec_reg[] = {
@@ -150,14 +141,12 @@
#define DEBUG_REG1 AV_SCRATCH_E
#define DEBUG_REG2 AV_SCRATCH_D
-
static void check_timer_func(struct timer_list *timer);
static void vavs_work(struct work_struct *work);
#define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001
static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE;
-
#define VPP_VD1_POSTBLEND (1 << 10)
static int debug;
@@ -168,14 +157,14 @@
udebug_flag:
bit 0, enable ucode print
bit 1, enable ucode more print
- bit 3, enable ucdode detail print
+ bit 3, enable ucode detail print
bit [31:16] not 0, pos to dump lmem
bit 2, pop bits to lmem
bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
avs only:
bit [8], disable empty muitl-instance handling
- bit [9], enable writting of VC1_CONTROL_REG in ucode
+ bit [9], enable writing of VC1_CONTROL_REG in ucode
*/
static u32 udebug_flag;
/*
@@ -236,7 +225,6 @@
static int disable_longcabac_trans = 1;
static int pre_decode_buf_level = 0x800;
-
static struct vframe_s *vavs_vf_peek(void *);
static struct vframe_s *vavs_vf_get(void *);
static void vavs_vf_put(struct vframe_s *, void *);
@@ -256,9 +244,7 @@
.event_cb = vavs_event_cb,
.vf_states = vavs_vf_states,
};
-/*
-static void *mm_blk_handle;
-*/
+
static struct vframe_provider_s vavs_vf_prov;
#define VF_BUF_NUM_MAX 16
@@ -287,44 +273,11 @@
static int canvas_num = 3;
#endif
-#if 0
-static struct vframe_s vfpool[VF_POOL_SIZE];
-/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
-static struct vframe_s *cur_vfpool;
-static unsigned char recover_flag;
-static s32 vfbuf_use[VF_BUF_NUM_MAX];
-static u32 saved_resolution;
-static u32 frame_width, frame_height, frame_dur, frame_prog;
-static struct timer_list recycle_timer;
-static u32 stat;
-#endif
static u32 buf_size = 32 * 1024 * 1024;
-#if 0
-static u32 buf_offset;
-static u32 avi_flag;
-static u32 vavs_ratio;
-static u32 pic_type;
-#endif
+
static u32 pts_by_offset = 1;
-#if 0
-static u32 total_frame;
-static u32 next_pts;
-static unsigned char throw_pb_flag;
-#ifdef DEBUG_PTS
-static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
-#endif
-#endif
static u32 radr, rval;
static u32 dbg_cmd;
-#if 0
-static struct dec_sysinfo vavs_amstream_dec_info;
-static struct vdec_info *gvs;
-static u32 fr_hint_status;
-static struct work_struct notify_work;
-static struct work_struct set_clk_work;
-static bool is_reset;
-#endif
-/*static struct vdec_s *vdec;*/
#ifdef AVSP_LONG_CABAC
static struct work_struct long_cabac_wd_work;
@@ -333,19 +286,11 @@
void *bitstream_read_tmp;
dma_addr_t bitstream_read_tmp_phy;
+ulong bitstream_read_handle;
void *avsp_heap_adr;
static uint long_cabac_busy;
#endif
-#if 0
-#ifdef ENABLE_USER_DATA
-static void *user_data_buffer;
-static dma_addr_t user_data_buffer_phys;
-#endif
-static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
-#endif
static inline u32 index2canvas(u32 index)
{
const u32 canvas_tab[VF_BUF_NUM_MAX] = {
@@ -397,6 +342,25 @@
unsigned short decode_pic_count;
};
+struct pic_info_t {
+ u32 buffer_info;
+ u32 index;
+ u32 offset;
+ u32 width;
+ u32 height;
+ u32 pts;
+ u64 pts64;
+ bool pts_valid;
+ ulong v4l_ref_buf_addr;
+ u32 hw_decode_time;
+ u32 frame_size; // For frame base mode
+ u64 timestamp;
+ u32 picture_type;
+ unsigned short decode_pic_count;
+ u32 repeat_cnt;
+ u32 error_flag;
+};
+
struct vdec_avs_hw_s {
spinlock_t lock;
unsigned char m_ins_flag;
@@ -448,7 +412,6 @@
/*debug*/
u32 ucode_pause_pos;
- /**/
u32 decode_pic_count;
u8 reset_decode_flag;
u32 display_frame_count;
@@ -532,7 +495,7 @@
struct work_struct notify_work;
atomic_t error_handler_run;
struct work_struct fatal_error_wd_work;
- void (*vdec_cb)(struct vdec_s *, void *);
+ void (*vdec_cb)(struct vdec_s *, void *, int);
void *vdec_cb_arg;
/* for error handling */
u32 run_count;
@@ -554,6 +517,14 @@
char pts_name[32];
char new_q_name[32];
char disp_q_name[32];
+ s32 ref_use[DECODE_BUFFER_NUM_MAX];
+ s32 buf_use[DECODE_BUFFER_NUM_MAX];
+ u32 decoding_index;
+ struct pic_info_t pics[DECODE_BUFFER_NUM_MAX];
+ ulong user_data_handle;
+ ulong lmem_phy_handle;
+ bool process_busy;
+ bool run_flag;
};
static void reset_process_time(struct vdec_avs_hw_s *hw);
@@ -594,7 +565,6 @@
#define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000
#define DEBUG_PIC_DONE_WHEN_UCODE_PAUSE 0x40000
-
#undef DEBUG_REG
#ifdef DEBUG_REG
static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
@@ -610,7 +580,7 @@
#endif
#undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
static int debug_print(struct vdec_avs_hw_s *hw,
int flag, const char *fmt, ...)
{
@@ -626,7 +596,6 @@
(1 << index))
&& (debug & flag))) {
va_list args;
-
va_start(args, fmt);
if (hw)
len = sprintf(buf, "[%d]", index);
@@ -660,6 +629,60 @@
return 0;
}
+static bool is_enough_free_buffer(struct vdec_avs_hw_s *hw)
+{
+ int i;
+
+ for (i = 0; i < hw->vf_buf_num_used; i++) {
+ if ((hw->vfbuf_use[i] == 0) && (hw->ref_use[i] == 0) &&
+ (hw->buf_use[i] == 0))
+ break;
+ }
+
+ return (i == hw->vf_buf_num_used) ? false : true;
+}
+
+static int find_free_buffer(struct vdec_avs_hw_s *hw)
+{
+ int i;
+
+ for (i = 0; i < hw->vf_buf_num_used; i++) {
+ if ((hw->vfbuf_use[i] == 0) &&
+ (hw->ref_use[i] == 0) &&
+ (hw->buf_use[i] == 0))
+ break;
+ }
+
+ return i;
+}
+
+int update_reference(struct vdec_avs_hw_s *hw,
+ int index)
+{
+ hw->ref_use[index]++;
+ if (hw->refs[1] == -1) {
+ hw->refs[1] = index;
+ /*
+ * first pic need output to show
+ * usecnt do not decrease.
+ */
+ } else if (hw->refs[0] == -1) {
+ hw->refs[0] = hw->refs[1];
+ hw->refs[1] = index;
+ /* second pic do not output */
+ index = hw->vf_buf_num_used;
+ } else {
+ hw->ref_use[hw->refs[0]]--; //old ref0 unused
+ hw->refs[0] = hw->refs[1];
+ hw->refs[1] = index;
+ index = hw->refs[0];
+ }
+ debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+ "hw->refs[0] = %d, hw->refs[1] = %d\n", hw->refs[0], hw->refs[1]);
+ return index;
+}
+
+
static void avs_pts_check_in(struct vdec_avs_hw_s *hw,
unsigned short decode_pic_count, struct vframe_chunk_s *chunk)
{
@@ -751,11 +774,10 @@
} else
#endif
{
- vf->width = READ_VREG(AVS_PIC_WIDTH);
- vf->height = READ_VREG(AVS_PIC_HEIGHT);
+ vf->width = READ_VREG(AVS_PIC_INFO) & 0x3fff;
+ vf->height = (READ_VREG(AVS_PIC_INFO) >> 14) & 0x3fff;
hw->frame_width = vf->width;
hw->frame_height = vf->height;
- /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/
}
#ifndef USE_AVS_SEQ_INFO
@@ -765,7 +787,6 @@
#endif
{
*duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf];
- /* pr_info("%s: duration = %d\n", __func__, *duration); */
hw->frame_dur = *duration;
schedule_work(&hw->notify_work);
}
@@ -810,19 +831,15 @@
ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
- /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */
vf->flag = 0;
buf_of_vf(vf)->detached = 0;
+ vf->codec_vfmt = VFORMAT_AVS;
}
#ifdef ENABLE_USER_DATA
-/*static struct work_struct userdata_push_work;*/
-/*
-#define DUMP_LAST_REPORTED_USER_DATA
-*/
static void userdata_push_process(struct vdec_avs_hw_s *hw)
{
unsigned int user_data_flags;
@@ -864,8 +881,7 @@
pdata += 8;
}
} else {
- wp_start = user_data_wp +
- USER_DATA_SIZE - user_data_len;
+ wp_start = user_data_wp + USER_DATA_SIZE - user_data_len;
pdata = (unsigned char *)hw->user_data_buffer;
pdata += wp_start;
@@ -891,20 +907,10 @@
}
#endif
-/*
- pr_info("pocinfo 0x%x, poc %d, wp 0x%x, len %d\n",
- READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M),
- user_data_wp, user_data_length);
-*/
user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L);
user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M);
WRITE_VREG(AV_SCRATCH_N, 0);
-/*
- wakeup_userdata_poll(user_data_poc, user_data_wp,
- (unsigned long)hw->user_data_buffer,
- USER_DATA_SIZE, user_data_length);
-*/
}
static void userdata_push_do_work(struct work_struct *work)
@@ -963,16 +969,8 @@
return IRQ_WAKE_THREAD;
}
-/*
- *static int run_flag = 1;
- *static int step_flag;
- */
+
static int error_recovery_mode; /*0: blocky 1: mosaic*/
-/*
- *static uint error_watchdog_threshold=10;
- *static uint error_watchdog_count;
- *static uint error_watchdog_buf_threshold = 0x4000000;
- */
static struct vframe_s *vavs_vf_peek(void *op_arg)
{
@@ -987,7 +985,7 @@
if (kfifo_len(&hw->display_q) > VF_POOL_SIZE) {
debug_print(hw, PRINT_FLAG_RUN_FLOW,
- "kfifo len:%d invaild, peek error\n",
+ "kfifo len:%d invalid, peek error\n",
kfifo_len(&hw->display_q));
return NULL;
}
@@ -1008,7 +1006,6 @@
}
return NULL;
-
}
static struct vframe_s *vavs_vf_get(void *op_arg)
@@ -1017,6 +1014,7 @@
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)op_arg;
unsigned long flags;
+ struct vdec_s *vdec = hw_to_vdec(hw);
if (hw->recover_flag)
return NULL;
@@ -1049,6 +1047,18 @@
buf_of_vf(vf)->detached);
}
spin_unlock_irqrestore(&lock, flags);
+
+ vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+ vf->vf_ud_param.ud_param.buf_len = 0;
+ vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+ vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+ vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+ vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS << 3);
+ vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+ if (vf->pts)
+ vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
return vf;
}
spin_unlock_irqrestore(&lock, flags);
@@ -1061,6 +1071,8 @@
int i;
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)op_arg;
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ unsigned long flags;
if (vf) {
hw->put_num++;
@@ -1076,6 +1088,7 @@
if (hw->recover_flag)
return;
+ spin_lock_irqsave(&lock, flags);
for (i = 0; i < VF_POOL_SIZE; i++) {
if (vf == &hw->vfpool[i].vf)
break;
@@ -1083,7 +1096,9 @@
if (i < VF_POOL_SIZE)
kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf);
+ spin_unlock_irqrestore(&lock, flags);
+ vdec_up(vdec);
}
static int vavs_event_cb(int type, void *data, void *private_data)
@@ -1106,8 +1121,7 @@
{
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)vdec->private;
- /*if (!(hw->stat & STAT_VDEC_RUN))
- return -1;*/
+
if (!hw)
return -1;
@@ -1148,7 +1162,7 @@
static int vavs_set_isreset(struct vdec_s *vdec, int isreset)
{
struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
+ (struct vdec_avs_hw_s *)vdec->private;
hw->is_reset = isreset;
return 0;
@@ -1194,6 +1208,28 @@
decbuf_size = 0x300000;
}
+ for (i = 0; i < hw->vf_buf_num_used; i++) {
+ unsigned canvas;
+ if (vdec->parallel_dec == 1) {
+ unsigned tmp;
+ if (canvas_u(hw->canvas_spec[i]) == 0xff) {
+ tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ hw->canvas_spec[i] &= ~(0xffff << 8);
+ hw->canvas_spec[i] |= tmp << 8;
+ hw->canvas_spec[i] |= tmp << 16;
+ }
+ if (canvas_y(hw->canvas_spec[i]) == 0xff) {
+ tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ hw->canvas_spec[i] &= ~0xff;
+ hw->canvas_spec[i] |= tmp;
+ }
+ canvas = hw->canvas_spec[i];
+ } else {
+ canvas = vdec->get_canvas(i, 2);
+ hw->canvas_spec[i] = canvas;
+ }
+ }
+
#ifdef AVSP_LONG_CABAC
need_alloc_buf_num = hw->vf_buf_num_used + 2;
#else
@@ -1226,83 +1262,64 @@
continue;
}
#endif
- if (hw->m_ins_flag) {
- unsigned canvas;
+ if (i < hw->vf_buf_num_used) {
+ if (hw->m_ins_flag) {
- if (vdec->parallel_dec == 1) {
- unsigned tmp;
- if (canvas_u(hw->canvas_spec[i]) == 0xff) {
- tmp =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~(0xffff << 8);
- hw->canvas_spec[i] |= tmp << 8;
- hw->canvas_spec[i] |= tmp << 16;
- }
- if (canvas_y(hw->canvas_spec[i]) == 0xff) {
- tmp =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~0xff;
- hw->canvas_spec[i] |= tmp;
- }
- canvas = hw->canvas_spec[i];
+ hw->canvas_config[i][0].phy_addr =
+ buf_start;
+ hw->canvas_config[i][0].width =
+ canvas_width;
+ hw->canvas_config[i][0].height =
+ canvas_height;
+ hw->canvas_config[i][0].block_mode =
+ vdec->canvas_mode;
+ hw->canvas_config[i][0].endian = 0;
+
+ hw->canvas_config[i][1].phy_addr =
+ buf_start + decbuf_y_size;
+ hw->canvas_config[i][1].width =
+ canvas_width;
+ hw->canvas_config[i][1].height =
+ canvas_height / 2;
+ hw->canvas_config[i][1].block_mode =
+ vdec->canvas_mode;
+ hw->canvas_config[i][1].endian = 0;
} else {
- canvas = vdec->get_canvas(i, 2);
- hw->canvas_spec[i] = canvas;
- }
-
- hw->canvas_config[i][0].phy_addr =
- buf_start;
- hw->canvas_config[i][0].width =
- canvas_width;
- hw->canvas_config[i][0].height =
- canvas_height;
- hw->canvas_config[i][0].block_mode =
- CANVAS_BLKMODE_32X32;
-
- hw->canvas_config[i][1].phy_addr =
- buf_start + decbuf_y_size;
- hw->canvas_config[i][1].width =
- canvas_width;
- hw->canvas_config[i][1].height =
- canvas_height / 2;
- hw->canvas_config[i][1].block_mode =
- CANVAS_BLKMODE_32X32;
-
- } else {
#ifdef NV21
- config_cav_lut_ex(canvas_base + canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_base + canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ canvas_config(canvas_base + canvas_num * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_base + canvas_num * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
#else
- config_cav_lut_ex(canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width / 2,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 2,
- buf_start +
- decbuf_y_size + decbuf_uv_size,
- canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ canvas_config(canvas_num * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width / 2,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 2,
+ buf_start +
+ decbuf_y_size + decbuf_uv_size,
+ canvas_width / 2, canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
#endif
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "canvas config %d, addr %p\n", i,
- (void *)buf_start);
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "canvas config %d, addr %p\n", i,
+ (void *)buf_start);
+ }
}
}
return 0;
@@ -1422,14 +1439,12 @@
hw->reg_scratch_1 = READ_VREG(AV_SCRATCH_1);
hw->reg_scratch_2 = READ_VREG(AV_SCRATCH_2);
hw->reg_scratch_3 = READ_VREG(AV_SCRATCH_3);
- hw->reg_scratch_4 = READ_VREG(AV_SCRATCH_4);
hw->reg_scratch_5 = READ_VREG(AV_SCRATCH_5);
hw->reg_scratch_6 = READ_VREG(AV_SCRATCH_6);
hw->reg_scratch_7 = READ_VREG(AV_SCRATCH_7);
hw->reg_scratch_8 = READ_VREG(AV_SCRATCH_8);
hw->reg_scratch_9 = READ_VREG(AV_SCRATCH_9);
hw->reg_scratch_A = READ_VREG(AV_SCRATCH_A);
- hw->reg_scratch_B = READ_VREG(AV_SCRATCH_B);
hw->reg_scratch_C = READ_VREG(AV_SCRATCH_C);
hw->reg_scratch_D = READ_VREG(AV_SCRATCH_D);
hw->reg_scratch_E = READ_VREG(AV_SCRATCH_E);
@@ -1451,6 +1466,10 @@
hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR);
hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR);
+ debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+ "%s ANC0_CANVAS_ADDR = 0x%x, ANC1_CANVAS_ADDR = 0x%x, ANC2_CANVAS_ADDR = 0x%x\n",
+ __func__, READ_VREG(ANC0_CANVAS_ADDR), READ_VREG(ANC1_CANVAS_ADDR), READ_VREG(ANC2_CANVAS_ADDR));
+
hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE);
hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG);
@@ -1484,14 +1503,12 @@
WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1);
WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2);
WRITE_VREG(AV_SCRATCH_3, hw->reg_scratch_3);
- WRITE_VREG(AV_SCRATCH_4, hw->reg_scratch_4);
WRITE_VREG(AV_SCRATCH_5, hw->reg_scratch_5);
WRITE_VREG(AV_SCRATCH_6, hw->reg_scratch_6);
WRITE_VREG(AV_SCRATCH_7, hw->reg_scratch_7);
WRITE_VREG(AV_SCRATCH_8, hw->reg_scratch_8);
WRITE_VREG(AV_SCRATCH_9, hw->reg_scratch_9);
WRITE_VREG(AV_SCRATCH_A, hw->reg_scratch_A);
- WRITE_VREG(AV_SCRATCH_B, hw->reg_scratch_B);
WRITE_VREG(AV_SCRATCH_C, hw->reg_scratch_C);
WRITE_VREG(AV_SCRATCH_D, hw->reg_scratch_D);
WRITE_VREG(AV_SCRATCH_E, hw->reg_scratch_E);
@@ -1504,17 +1521,34 @@
WRITE_VREG(VIFF_BIT_CNT, hw->reg_viff_bit_cnt);
WRITE_VREG(REC_CANVAS_ADDR, hw->reg_canvas_addr);
- WRITE_VREG(DBKR_CANVAS_ADDR, hw->reg_dbkr_canvas_addr);
- WRITE_VREG(DBKW_CANVAS_ADDR, hw->reg_dbkw_canvas_addr);
- WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr);
- WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr);
- WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr);
- WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr);
- WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr);
- WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr);
+ WRITE_VREG(DBKR_CANVAS_ADDR, hw->reg_dbkr_canvas_addr);
+ WRITE_VREG(DBKW_CANVAS_ADDR, hw->reg_dbkw_canvas_addr);
+ WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr);
+ WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr);
+ WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr);
+ WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr);
+ WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr);
+ WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr);
+ if (hw->refs[1] == -1)
+ WRITE_VREG(ANC0_CANVAS_ADDR, 0xffffffff);
+ else
+ WRITE_VREG(ANC0_CANVAS_ADDR, hw->canvas_spec[hw->refs[1]]);
+
+ if (hw->refs[0] == -1) {
+ if (hw->refs[1] == -1)
+ WRITE_VREG(ANC1_CANVAS_ADDR, 0xffffffff);
+ else
+ WRITE_VREG(ANC1_CANVAS_ADDR, hw->canvas_spec[hw->refs[1]]);
+ }
+ else
+ WRITE_VREG(ANC1_CANVAS_ADDR, hw->canvas_spec[hw->refs[0]]);
+
+ debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+ "%s ANC0_CANVAS_ADDR = 0x%x, ANC1_CANVAS_ADDR = 0x%x, ANC2_CANVAS_ADDR = 0x%x\n",
+ __func__, READ_VREG(ANC0_CANVAS_ADDR), READ_VREG(ANC1_CANVAS_ADDR), READ_VREG(ANC2_CANVAS_ADDR));
+ WRITE_VREG(MCRCC_CTL1, 0xff1);
WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type);
-
WRITE_VREG(VC1_CONTROL_REG, hw->vc1_control_reg);
WRITE_VREG(AVS_CO_MB_WR_ADDR, hw->avs_co_mb_wr_addr);
WRITE_VREG(SLICE_START_BYTE_01, hw->slice_start_byte_01);
@@ -1543,7 +1577,7 @@
#if DEBUG_MULTI_FLAG > 0
if (hw->decode_pic_count == 0) {
#endif
-#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+
WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
WRITE_VREG(DOS_SW_RESET0, 0);
@@ -1555,15 +1589,6 @@
WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
WRITE_VREG(DOS_SW_RESET0, 0);
-#else
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
- READ_RESET_REG(RESET0_REGISTER);
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
-
- WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
-#endif
#if DEBUG_MULTI_FLAG > 0
}
#endif
@@ -1574,6 +1599,16 @@
/*************************************************************/
if (hw->m_ins_flag) {
int i;
+ u32 index = -1;
+ index = find_free_buffer(hw);
+ if (index < 0)
+ return -1;
+ hw->decoding_index = index;
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "hw->decoding_index = %d\n",
+ hw->decoding_index);
+ WRITE_VREG(AV_SCRATCH_4, index);
+ WRITE_VREG(AV_SCRATCH_B, 0);
if (hw->decode_pic_count == 0) {
r = vavs_canvas_init(hw);
#ifndef USE_DYNAMIC_BUF_NUM
@@ -1600,21 +1635,24 @@
vavs_restore_regs(hw);
for (i = 0; i < hw->vf_buf_num_used; i++) {
- config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
- hw->canvas_config[i][0].phy_addr,
- hw->canvas_config[i][0].width,
- hw->canvas_config[i][0].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][0].block_mode,
- 0, VDEC_1);
+ if (hw->canvas_config[i][0].phy_addr &&
+ hw->canvas_config[i][1].phy_addr) {
+ config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
+ hw->canvas_config[i][0].phy_addr,
+ hw->canvas_config[i][0].width,
+ hw->canvas_config[i][0].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][0].block_mode,
+ 0, VDEC_1);
- config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
- hw->canvas_config[i][1].phy_addr,
- hw->canvas_config[i][1].width,
- hw->canvas_config[i][1].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][1].block_mode,
- 0, VDEC_1);
+ config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
+ hw->canvas_config[i][1].phy_addr,
+ hw->canvas_config[i][1].width,
+ hw->canvas_config[i][1].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][1].block_mode,
+ 0, VDEC_1);
+ }
}
} else {
r = vavs_canvas_init(hw);
@@ -1629,31 +1667,18 @@
for (ii = 0; ii < 4; ii++) {
WRITE_VREG(AV_SCRATCH_0 + ii,
(canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 1)
- << 16)
- );
+ ((canvas_base + canvas_num * ii + 1) << 8) |
+ ((canvas_base + canvas_num * ii + 1) << 16));
}
#else
- for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) {
- WRITE_VREG(buf_spec_reg[ii >> 1],
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 2)
- << 16) |
- ((canvas_base + canvas_num * ii + 3)
- << 24)
- );
- }
+ for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) {
+ WRITE_VREG(buf_spec_reg[ii >> 1],
+ (canvas_base + canvas_num * ii) |
+ ((canvas_base + canvas_num * ii + 1) << 8) |
+ ((canvas_base + canvas_num * ii + 2) << 16) |
+ ((canvas_base + canvas_num * ii + 3) << 24));
+ }
#endif
- /*
- *WRITE_VREG(AV_SCRATCH_0, 0x010100);
- *WRITE_VREG(AV_SCRATCH_1, 0x040403);
- *WRITE_VREG(AV_SCRATCH_2, 0x070706);
- *WRITE_VREG(AV_SCRATCH_3, 0x0a0a09);
- */
}
#else
/* index v << 16 | u << 8 | y */
@@ -1696,15 +1721,10 @@
#endif
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-#ifdef PIC_DC_NEED_CLEAR
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
if (hw->m_ins_flag && start_decoding_delay > 0)
msleep(start_decoding_delay);
- //pr_info("+++++++++++++++++++++++++++++++\n");
- //pr_info("+++++++++++++++++++++++++++++++\n");
- //pr_info("+++++++++++++++++++++++++++++++\n");
#ifdef AVSP_LONG_CABAC
if (firmware_sel == 0) {
WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
@@ -1776,6 +1796,9 @@
INIT_KFIFO(hw->recycle_q);
INIT_KFIFO(hw->newframe_q);
+ hw->refs[0] = -1;
+ hw->refs[1] = -1;
+
for (i = 0; i < VF_POOL_SIZE; i++) {
const struct vframe_s *vf = &hw->vfpool[i].vf;
@@ -1787,8 +1810,6 @@
for (i = 0; i < hw->vf_buf_num_used; i++)
hw->vfbuf_use[i] = 0;
- /*cur_vfpool = vfpool;*/
-
if (hw->recover_flag == 1)
return;
@@ -1804,7 +1825,8 @@
MAX_BMMU_BUFFER_NUM,
4 + PAGE_SHIFT,
CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER);
+ CODEC_MM_FLAGS_FOR_VDECODER,
+ BMMU_ALLOC_FLAGS_WAITCLEAR);
if (hw->mm_blk_handle == NULL)
pr_info("Error, decoder_bmmu_box_alloc_box fail\n");
@@ -1813,9 +1835,7 @@
static int vavs_vf_states(struct vframe_states *states, void *op_arg)
{
unsigned long flags;
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)op_arg;
-
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)op_arg;
spin_lock_irqsave(&lock, flags);
states->vf_pool_size = VF_POOL_SIZE;
@@ -1856,26 +1876,10 @@
amvdec_start();
hw->recover_flag = 0;
-#if 0
- error_watchdog_count = 0;
-
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
-#endif
-
-
mutex_unlock(&vavs_mutex);
}
-#if 0
-static struct work_struct fatal_error_wd_work;
-static struct work_struct notify_work;
-static atomic_t error_handler_run = ATOMIC_INIT(0);
-#endif
static void vavs_fatal_error_handler(struct work_struct *work)
{
struct vdec_avs_hw_s *hw =
@@ -1925,11 +1929,10 @@
hw->saved_resolution = hw->frame_width * hw->frame_height * fps;
if (firmware_sel == 0 &&
(debug & AVS_DEBUG_USE_FULL_SPEED)) {
- vdec_source_changed(VFORMAT_AVS,
- 4096, 2048, 60);
+ vdec_source_changed(VFORMAT_AVS, 4096, 2048, 60);
} else {
vdec_source_changed(VFORMAT_AVS,
- hw->frame_width, hw->frame_height, fps);
+ hw->frame_width, hw->frame_height, fps);
}
}
@@ -1956,25 +1959,6 @@
#endif
if (READ_VREG(AVS_SOS_COUNT)) {
if (!error_recovery_mode) {
-#if 0
- if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) {
- mutex_lock(&vavs_mutex);
- pr_info("vavs fatal error reset !\n");
- amvdec_stop();
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vavs_ppmgr_reset();
-#else
- vf_light_unreg_provider(&vavs_vf_prov);
- vavs_local_init();
- vf_reg_provider(&vavs_vf_prov);
-#endif
- vavs_recover();
- amvdec_start();
- mutex_unlock(&vavs_mutex);
- } else {
- vavs_local_reset();
- }
-#else
if (!atomic_read(&hw->error_handler_run)) {
atomic_set(&hw->error_handler_run, 1);
pr_info("AVS_SOS_COUNT = %d\n",
@@ -1987,30 +1971,9 @@
READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
schedule_work(&hw->fatal_error_wd_work);
}
-#endif
}
}
-#if 0
- if (long_cabac_busy == 0 &&
- error_watchdog_threshold > 0 &&
- kfifo_len(&hw->display_q) == 0 &&
- READ_VREG(VLD_MEM_VIFIFO_LEVEL) >
- error_watchdog_buf_threshold) {
- pr_info("newq %d dispq %d recyq %d\r\n",
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q));
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- error_watchdog_count++;
- if (error_watchdog_count >= error_watchdog_threshold)
- vavs_local_reset();
- } else
- error_watchdog_count = 0;
-#endif
+
if (radr != 0) {
if (rval != 0) {
WRITE_VREG(radr, rval);
@@ -2059,14 +2022,7 @@
{
int status = 0;
struct vdec_avs_hw_s *hw = gw;
-#ifdef PERFORMANCE_DEBUG
- pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q)
- );
-#endif
+
mutex_lock(&vavs_mutex);
long_cabac_busy = 1;
while (READ_VREG(LONG_CABAC_REQ)) {
@@ -2077,14 +2033,7 @@
}
long_cabac_busy = 0;
mutex_unlock(&vavs_mutex);
-#ifdef PERFORMANCE_DEBUG
- pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q)
- );
-#endif
+
if (status < 0) {
pr_info("transcoding error, local reset\r\n");
vavs_local_reset(hw);
@@ -2096,56 +2045,31 @@
#ifdef AVSP_LONG_CABAC
static void init_avsp_long_cabac_buf(void)
{
-#if 0
- es_write_addr_phy = (unsigned long)codec_mm_alloc_for_dma(
- "vavs",
- PAGE_ALIGN(MAX_CODED_FRAME_SIZE)/PAGE_SIZE,
- 0, CODEC_MM_FLAGS_DMA_CPU);
- es_write_addr_virt = codec_mm_phys_to_virt(es_write_addr_phy);
-
-#elif 0
- es_write_addr_virt =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- MAX_CODED_FRAME_SIZE, &es_write_addr_phy,
- GFP_KERNEL);
-#else
- /*es_write_addr_virt = kmalloc(MAX_CODED_FRAME_SIZE, GFP_KERNEL);
- * es_write_addr_virt = (void *)__get_free_pages(GFP_KERNEL,
- * get_order(MAX_CODED_FRAME_SIZE));
- */
es_write_addr_virt = &es_write_addr[0];
if (es_write_addr_virt == NULL) {
- pr_err("%s: failed to alloc es_write_addr_virt buffer\n",
- __func__);
+ pr_err("%s: failed to alloc es_write_addr_virt buffer\n", __func__);
return;
}
es_write_addr_phy = dma_map_single(amports_get_dma_device(),
es_write_addr_virt,
MAX_CODED_FRAME_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(amports_get_dma_device(),
- es_write_addr_phy)) {
- pr_err("%s: failed to map es_write_addr_virt buffer\n",
- __func__);
- /*kfree(es_write_addr_virt);*/
+ if (dma_mapping_error(amports_get_dma_device(), es_write_addr_phy)) {
+ pr_err("%s: failed to map es_write_addr_virt buffer\n", __func__);
es_write_addr_virt = NULL;
return;
}
-#endif
-
#ifdef BITSTREAM_READ_TMP_NO_CACHE
bitstream_read_tmp =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
+ (void *)decoder_dma_alloc_coherent(&bitstream_read_handle,
SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy,
- GFP_KERNEL);
+ "AVS_BITSTREAM_BUF");
#else
bitstream_read_tmp = kmalloc(SVA_STREAM_BUF_SIZE, GFP_KERNEL);
- /*bitstream_read_tmp = (void *)__get_free_pages(GFP_KERNEL,
- *get_order(MAX_CODED_FRAME_SIZE));
- */
+
if (bitstream_read_tmp == NULL) {
pr_err("%s: failed to alloc bitstream_read_tmp buffer\n",
__func__);
@@ -2172,23 +2096,12 @@
int ret, size = -1;
struct firmware_s *fw;
u32 fw_size = 0x1000 * 16;
- /*char *buf = vmalloc(0x1000 * 16);
- if (IS_ERR_OR_NULL(buf))
- return -ENOMEM;
- */
fw = vmalloc(sizeof(struct firmware_s) + fw_size);
if (IS_ERR_OR_NULL(fw))
return -ENOMEM;
pr_info("vavs_init\n");
- //init_timer(&hw->recycle_timer);
-
- //hw->stat |= STAT_TIMER_INIT;
-
- //amvdec_enable();
-
- //vdec_enable_DMC(NULL);
vavs_local_init(hw);
@@ -2217,13 +2130,8 @@
if (hw->m_ins_flag) {
timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (ulong) hw;
- //hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
-
- //add_timer(&hw->check_timer);
hw->stat |= STAT_TIMER_ARM;
INIT_WORK(&hw->work, vavs_work);
@@ -2241,17 +2149,13 @@
if (ret < 0) {
amvdec_disable();
- /*vfree(buf);*/
pr_err("AVS: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
+ fw_tee_enabled() ? "TEE" : "local", ret);
return -EBUSY;
}
- /*vfree(buf);*/
-
hw->stat |= STAT_MC_LOAD;
-
/* enable AMRISC side protocol */
ret = vavs_prot_init(hw);
if (ret < 0)
@@ -2370,9 +2274,9 @@
#ifdef ENABLE_USER_DATA
if (NULL == hw->user_data_buffer) {
hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
+ decoder_dma_alloc_coherent(&hw->user_data_handle,
USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
+ &hw->user_data_buffer_phys, "AVS_AUX_BUF");
if (!hw->user_data_buffer) {
pr_info("%s: Can not allocate hw->user_data_buffer\n",
__func__);
@@ -2450,7 +2354,7 @@
#ifdef BITSTREAM_READ_TMP_NO_CACHE
if (bitstream_read_tmp) {
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(bitstream_read_handle,
SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
bitstream_read_tmp_phy);
bitstream_read_tmp = NULL;
@@ -2477,8 +2381,8 @@
#ifdef ENABLE_USER_DATA
if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
+ decoder_dma_free_coherent(
+ hw->user_data_handle,
USER_DATA_SIZE,
hw->user_data_buffer,
hw->user_data_buffer_phys);
@@ -2530,7 +2434,6 @@
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)vdec->private;
int ret = 1;
- unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1;
#ifdef DEBUG_MULTI_FRAME_INS
if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] &&
run_count[1] < max_run_count[1])
@@ -2557,16 +2460,15 @@
if (level < pre_decode_buf_level) {
hw->not_run_ready++;
- return 0;
+ return PRE_LEVEL_NOT_ENOUGH;
}
}
- if (hw->reset_decode_flag == 0 &&
- hw->again_flag == 0 &&
- (hw->buf_status & buf_busy_mask) == buf_busy_mask) {
- recycle_frames(hw);
- if (hw->buf_recycle_status == 0)
- ret = 0;
+ recycle_frames(hw);
+
+ if (!is_enough_free_buffer(hw)) {
+ hw->buffer_not_ready++;
+ return 0;
}
if (again_threshold > 0 &&
@@ -2580,7 +2482,7 @@
again_threshold) {
int r = vdec_sync_input(vdec);
debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "%s buf lelvel:%x\n", __func__, r);
+ "%s buf level:%x\n", __func__, r);
ret = 0;
}
}
@@ -2620,6 +2522,7 @@
msleep(delay);
#endif
vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ hw->chunk = NULL;
} else if (hw->dec_result == DEC_RESULT_AGAIN
&& (hw_to_vdec(hw)->next_status !=
VDEC_STATUS_DISCONNECTED)) {
@@ -2648,6 +2551,7 @@
READ_VREG(VLD_MEM_VIFIFO_WP),
READ_VREG(VLD_MEM_VIFIFO_RP));
vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ hw->chunk = NULL;
vdec_clean_input(hw_to_vdec(hw));
return;
} else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
@@ -2669,6 +2573,7 @@
}
hw->eos = 1;
vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ hw->chunk = NULL;
vdec_clean_input(hw_to_vdec(hw));
}
if (hw->stat & STAT_VDEC_RUN) {
@@ -2692,7 +2597,7 @@
vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
if (hw->vdec_cb) {
- hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
+ hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg, CORE_MASK_VDEC_1);
debug_print(hw, 0x80000,
"%s:\n", __func__);
}
@@ -2730,6 +2635,12 @@
hw->vfbuf_use[vf->index] = 0;
}
}
+ for (i = 0; i < VF_BUF_NUM_MAX; i++) {
+ hw->ref_use[i] = 0;
+ hw->buf_use[i] = 0;
+ }
+ hw->refs[0] = -1;
+ hw->refs[1] = -1;
if (error_handle_policy & 0x2) {
while (!kfifo_is_empty(&hw->display_q)) {
if (kfifo_get(&hw->display_q, &vf)) {
@@ -2834,6 +2745,7 @@
if ((vf->index < hw->vf_buf_num_used) &&
(buf_of_vf(vf)->detached == 0) &&
(--hw->vfbuf_use[vf->index] == 0)) {
+ hw->buf_use[vf->index] --;
hw->buf_recycle_status |= (1 << vf->index);
debug_print(hw, PRINT_FLAG_DECODING,
"%s for vf index of %d => buf_recycle_status 0x%x\n",
@@ -2936,7 +2848,7 @@
hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
}
- if (READ_VREG(AVS_SOS_COUNT)) {
+ if (!atomic_read(&hw->error_handler_run) && !work_busy(&hw->work) && READ_VREG(AVS_SOS_COUNT)) {
if (!error_recovery_mode) {
amvdec_stop();
if (error_handle_policy & 0x1) {
@@ -2958,6 +2870,7 @@
__func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL),
READ_VREG(AVS_SOS_COUNT));
reset_process_time(hw);
+ atomic_set(&hw->error_handler_run, 1);
vdec_schedule_work(&hw->work);
}
}
@@ -3010,13 +2923,16 @@
}
static void run(struct vdec_s *vdec, unsigned long mask,
-void (*callback)(struct vdec_s *, void *),
+void (*callback)(struct vdec_s *, void *, int),
void *arg)
{
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)vdec->private;
int save_reg;
int size, ret;
+ int i;
+
+ hw->run_flag = 1;
if (!hw->vdec_pg_enable_flag) {
hw->vdec_pg_enable_flag = 1;
amvdec_enable();
@@ -3059,6 +2975,7 @@
hw->input_empty++;
hw->dec_result = DEC_RESULT_AGAIN;
vdec_schedule_work(&hw->work);
+ hw->run_flag = 0;
return;
}
} else {
@@ -3066,6 +2983,7 @@
hw->input_empty++;
hw->dec_result = DEC_RESULT_AGAIN;
vdec_schedule_work(&hw->work);
+ hw->run_flag = 0;
return;
}
}
@@ -3152,24 +3070,38 @@
hw->fw->data, hw->fw->len);
if (ret < 0) {
pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
- hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
+ hw->fw->name, fw_tee_enabled() ? "TEE" : "local", ret);
hw->dec_result = DEC_RESULT_FORCE_EXIT;
vdec_schedule_work(&hw->work);
+ hw->run_flag = 0;
return;
}
vdec->mc_loaded = 1;
vdec->mc_type = VFORMAT_AVS;
}
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "vfbuf_use:\n");
+ for (i = 0; i < hw->vf_buf_num_used; i++)
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: vf_buf_use %d\n",
+ i, hw->vfbuf_use[i]);
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "ref_use:\n");
+ for (i = 0; i < hw->vf_buf_num_used; i++)
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: ref_use %d\n",
+ i, hw->ref_use[i]);
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "buf_use:\n");
+ for (i = 0; i < hw->vf_buf_num_used; i++)
+ debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: buf_use %d\n",
+ i, hw->buf_use[i]);
if (avs_hw_ctx_restore(hw) < 0) {
hw->dec_result = DEC_RESULT_ERROR;
debug_print(hw, PRINT_FLAG_ERROR,
"ammvdec_avs: error HW context restore\n");
vdec_schedule_work(&hw->work);
+ hw->run_flag = 0;
return;
}
/*
- This configureation of VC1_CONTROL_REG will
+ This configuration of VC1_CONTROL_REG will
pop bits (even no data in the stream buffer) if input is enabled,
so it can only be configured before vdec_enable_input() is called.
So move this code from ucode to here
@@ -3222,86 +3154,454 @@
hw->stat |= STAT_VDEC_RUN;
hw->stat |= STAT_TIMER_ARM;
-
+ atomic_set(&hw->error_handler_run, 0);
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
+ hw->run_flag = 0;
}
static void reset(struct vdec_s *vdec)
{
}
+static int prepare_display_buf(struct vdec_avs_hw_s *hw,
+ struct pic_info_t *pic)
+{
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ struct vframe_s *vf = NULL;
+ u32 reg = pic->buffer_info;
+ bool force_interlaced_frame = false;
+ u32 picture_type = pic->picture_type;
+ u32 repeat_count = pic->repeat_cnt;
+ unsigned int pts = pic->pts;
+ unsigned int pts_valid = pic->pts_valid;
+ unsigned int offset = pic->offset;
+ u64 pts_us64 = pic->pts64;
+ u32 buffer_index = pic->index;
+ u32 dur;
+ unsigned short decode_pic_count = pic->decode_pic_count;
+
+ if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
+ && hw->frame_width == 1920 && hw->frame_height == 1080) {
+ force_interlaced_frame = true;
+ }
+
+ if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */
+ hw->throw_pb_flag = 0;
+
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "interlace, picture type %d\n",
+ picture_type);
+
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info
+ ("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ hw->pic_type = 2;
+ if ((picture_type == I_PICTURE) && pts_valid) {
+ vf->pts = pts;
+ vf->pts_us64 = pts_us64;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* hw->next_pts = pts +
+ * (hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1)*15/16;
+ */
+ hw->next_pts =
+ pts +
+ (dur * repeat_count >> 1) *
+ 15 / 16;
+ } else
+ hw->next_pts = 0;
+ } else {
+ vf->pts = hw->next_pts;
+ if (vf->pts == 0) {
+ vf->pts_us64 = 0;
+ }
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1;
+ */
+ vf->duration = dur * repeat_count >> 1;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate >> 1;
+ */
+ vf->duration = dur >> 1;
+ hw->next_pts = 0;
+ }
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ if (force_interlaced_frame) {
+ vf->type = VIDTYPE_INTERLACE_TOP;
+ }else{
+ vf->type =
+ (reg & TOP_FIELD_FIRST_FLAG)
+ ? VIDTYPE_INTERLACE_TOP
+ : VIDTYPE_INTERLACE_BOTTOM;
+ }
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "buffer_index %d, canvas addr %x\n",
+ buffer_index, vf->canvas0Addr);
+ vf->pts = (pts_valid)?pts:0;
+ //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+
+ if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
+ set_vframe_pts(hw, decode_pic_count, vf);
+
+ if (vdec_stream_based(vdec) && (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+ vf->pts_us64 =
+ (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+ vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ checkout_pts_offset pts_info;
+ pts_info.offset = (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+
+ debug_print(hw, PRINT_FLAG_PTS,
+ "interlace1 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
+ if (hw->pics[buffer_index].error_flag) {
+ vavs_vf_put(vf, hw);
+ } else {
+ vdec_vframe_ready(vdec, vf);
+ kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ avs_vf_notify_receiver(hw, PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ if (force_interlaced_frame)
+ vf->pts = 0;
+ else
+ vf->pts = hw->next_pts;
+
+ if (vf->pts == 0) {
+ vf->pts_us64 = 0;
+ }
+
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration = hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1;
+ */
+ vf->duration = dur * repeat_count >> 1;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration = hw->vavs_amstream_dec_info.rate
+ * >> 1;
+ */
+ vf->duration = dur >> 1;
+ hw->next_pts = 0;
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ if (force_interlaced_frame) {
+ vf->type = VIDTYPE_INTERLACE_BOTTOM;
+ } else {
+ vf->type =
+ (reg & TOP_FIELD_FIRST_FLAG) ?
+ VIDTYPE_INTERLACE_BOTTOM :
+ VIDTYPE_INTERLACE_TOP;
+ }
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+ vf->pts_us64 = 0;
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+
+ if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
+ set_vframe_pts(hw, decode_pic_count, vf);
+
+ if (vdec_stream_based(vdec) && (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+ vf->pts_us64 = (u64)-1;
+ vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ checkout_pts_offset pts_info;
+ pts_info.offset = -1;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+ debug_print(hw, PRINT_FLAG_PTS,
+ "interlace2 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
+
+ if (hw->pics[buffer_index].error_flag) {
+ vavs_vf_put(vf, hw);
+ } else {
+ vdec_vframe_ready(vdec, vf);
+ kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ avs_vf_notify_receiver(hw, PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+ hw->total_frame++;
+ } else { /* progressive */
+ hw->throw_pb_flag = 0;
+
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "progressive picture type %d\n",
+ picture_type);
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info
+ ("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ hw->pic_type = 1;
+
+ if ((picture_type == I_PICTURE) && pts_valid) {
+ vf->pts = pts;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* hw->next_pts = pts +
+ * (hw->vavs_amstream_dec_info.rate *
+ * repeat_count)*15/16;
+ */
+ hw->next_pts =
+ pts +
+ (dur * repeat_count) * 15 / 16;
+ } else
+ hw->next_pts = 0;
+ } else {
+ vf->pts = hw->next_pts;
+ if (vf->pts == 0) {
+ vf->pts_us64 = 0;
+ }
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate *
+ * repeat_count;
+ */
+ vf->duration = dur * repeat_count;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate;
+ */
+ vf->duration = dur;
+ hw->next_pts = 0;
+ }
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+
+ vf->pts = (pts_valid)?pts:0;
+ //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "buffer_index %d, canvas addr %x\n",
+ buffer_index, vf->canvas0Addr);
+ debug_print(hw, PRINT_FLAG_PTS,
+ "progressive vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+
+ if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
+ set_vframe_pts(hw, decode_pic_count, vf);
+
+ if (vdec_stream_based(vdec) && (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+ vf->pts_us64 =
+ (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+ vf->pts = 0;
+ } else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+ checkout_pts_offset pts_info;
+ pts_info.offset = (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+ if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+ vf->pts = pts_info.pts;
+ vf->pts_us64 = pts_info.pts_64;
+ } else {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ }
+
+ if (hw->pics[buffer_index].error_flag) {
+ vavs_vf_put(vf, hw);
+ } else {
+ decoder_do_frame_check(hw_to_vdec(hw), vf);
+ vdec_vframe_ready(vdec, vf);
+ kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
+ ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
+ avs_vf_notify_receiver(hw, PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+
+ hw->total_frame++;
+ }
+
+ /*count info*/
+ vdec_count_info(hw->gvs, 0, offset);
+ if (offset) {
+ if (picture_type == I_PICTURE) {
+ hw->gvs->i_decoded_frames++;
+ } else if (picture_type == P_PICTURE) {
+ hw->gvs->p_decoded_frames++;
+ } else if (picture_type == B_PICTURE) {
+ hw->gvs->b_decoded_frames++;
+ }
+ }
+ avs_update_gvs(hw);
+ vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0);
+ return 0;
+}
+
+static void check_ref_error(struct vdec_avs_hw_s *hw, int index)
+{
+ struct pic_info_t *pic = NULL;
+ int i = 0;
+
+ pic = &hw->pics[index];
+ if ((pic->picture_type) == B_PICTURE) {
+ if ((hw->refs[0] < 0) || (hw->refs[0] >= hw->vf_buf_num_used) ||
+ (hw->refs[1] < 0) || (hw->refs[1] >= hw->vf_buf_num_used)) {
+ pic->error_flag = 1;
+ debug_print(hw, 0,
+ "avs: ref pic not exist, set cur pic error\n");
+ return ;
+ }
+ for (i = 0; i < 2; i++) {
+ if (hw->pics[hw->refs[i]].error_flag) {
+ pic->error_flag = 1;
+ debug_print(hw, 0,
+ "avs: L%d ref error, set index %d error_mark\n", i, index);
+ return ;
+ }
+ }
+ }
+
+ if ((pic->picture_type) == P_PICTURE) {
+ if ((hw->refs[1] < 0) || (hw->refs[1] >= hw->vf_buf_num_used)) {
+ pic->error_flag = 1;
+ debug_print(hw, 0,
+ "avs: ref pic not exist, set cur pic error\n");
+ return ;
+ } else if (hw->pics[hw->refs[1]].error_flag) {
+ pic->error_flag = 1;
+ debug_print(hw, 0,
+ "avs: L0 ref error, set index %d error_mark\n", index);
+ }
+ }
+}
+
+
static irqreturn_t vmavs_isr_thread_fn(struct vdec_s *vdec, int irq)
{
struct vdec_avs_hw_s *hw =
(struct vdec_avs_hw_s *)vdec->private;
u32 reg;
- struct vframe_s *vf = NULL;
- u32 dur;
- u32 repeat_count;
u32 picture_type;
u32 buffer_index;
u32 frame_size;
- bool force_interlaced_frame = false;
- unsigned int pts, pts_valid = 0, offset = 0;
+ unsigned int pts, offset = 0;
u64 pts_us64;
u32 debug_tag;
u32 buffer_status_debug;
- //struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id;
- /*if (debug & AVS_DEBUG_UCODE) {
- if (READ_VREG(AV_SCRATCH_E) != 0) {
- pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E),
- READ_VREG(AV_SCRATCH_D));
- WRITE_VREG(AV_SCRATCH_E, 0);
- }
- }*/
-
- debug_print(hw, PRINT_FLAG_RUN_FLOW, "READ_VREG(AVS_BUFFEROUT) 0x%x, READ_VREG(DECODE_STATUS) 0x%x READ_VREG(AV_SCRATCH_N) 0x%x, READ_VREG(DEBUG_REG1) 0x%x\n",
- READ_VREG(AVS_BUFFEROUT),READ_VREG(DECODE_STATUS), READ_VREG(AV_SCRATCH_N), READ_VREG(DEBUG_REG1));
+ debug_print(hw, PRINT_FLAG_RUN_FLOW, "READ_VREG(AVS_BUFFEROUT) 0x%x, READ_VREG(DECODE_STATUS) 0x%x READ_VREG(AV_SCRATCH_N) 0x%x, READ_VREG(DEBUG_REG1) 0x%x, READ_VREG(AV_SCRATCH_2) 0x%x\n",
+ READ_VREG(AVS_BUFFEROUT),READ_VREG(DECODE_STATUS), READ_VREG(AV_SCRATCH_N), READ_VREG(DEBUG_REG1), READ_VREG(AV_SCRATCH_2));
debug_tag = READ_VREG(DEBUG_REG1);
buffer_status_debug = debug_tag >> 16;
debug_tag &= 0xffff;
- /* if (debug_tag & 0x10000) {
- int i;
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->lmem_phy_addr,
- LMEM_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- debug_print(hw, 0,
- "LMEM<tag %x>:\n", debug_tag);
-
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- unsigned short *lmem_ptr = hw->lmem_addr;
- if ((i & 0xf) == 0)
- debug_print_cont(hw, 0, "%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- debug_print_cont(hw, 0, "%04x ",
- lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- debug_print_cont(hw, 0, "\n");
- }
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hw->decode_pic_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_VREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- else if (debug_tag & 0x20000)
- hw->ucode_pause_pos = 0xffffffff;
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_VREG(DEBUG_REG1, 0);
- } else*/ if (debug_tag != 0) {
+ if (debug_tag != 0) {
debug_print(hw, 1,
"dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n",
debug_tag,
@@ -3354,14 +3654,17 @@
READ_VREG(DECODE_STATUS),
buffer_status_debug);
}
+ reg = READ_VREG(DECODE_STATUS); // need find a null register pyx
+ if (reg == DECODE_STATUS_INFO) {
+ WRITE_VREG(DECODE_STATUS, 0);
+ debug_print(hw, PRINT_FLAG_DECODING, "READ_VREG(AVS_PIC_INFO) = 0x%x\n", READ_VREG(AVS_PIC_INFO));
+ return IRQ_HANDLED;
+ }
#ifdef AVSP_LONG_CABAC
if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) {
-#ifdef PERFORMANCE_DEBUG
- pr_info("%s:schedule long_cabac_wd_work\r\n", __func__);
-#endif
pr_info("schedule long_cabac_wd_work and requested from %d\n",
- (READ_VREG(LONG_CABAC_REQ) >> 8)&0xFF);
+ (READ_VREG(LONG_CABAC_REQ) >> 8) & 0xFF);
schedule_work(&long_cabac_wd_work);
}
#endif
@@ -3376,17 +3679,28 @@
= READ_VREG(DECODE_PIC_COUNT);
debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n",
reg, decode_pic_count);
+ hw->pics[hw->decoding_index].offset = READ_VREG(AVS_OFFSET_REG);
+ hw->pics[hw->decoding_index].repeat_cnt = READ_VREG(AVS_REPEAT_COUNT);
+ hw->pics[hw->decoding_index].buffer_info = reg;
+ hw->pics[hw->decoding_index].index = hw->decoding_index;
+ hw->pics[hw->decoding_index].decode_pic_count = decode_pic_count;
+ hw->pics[hw->decoding_index].error_flag = 0;
if (pts_by_offset) {
offset = READ_VREG(AVS_OFFSET_REG);
debug_print(hw, PRINT_FLAG_DECODING, "AVS OFFSET=%x\n", offset);
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
+ if (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
&frame_size, 0, &pts_us64) == 0) {
- pts_valid = 1;
+ hw->pics[hw->decoding_index].pts_valid = 1;
+ hw->pics[hw->decoding_index].pts = pts;
+ hw->pics[hw->decoding_index].pts64 = pts_us64;
#ifdef DEBUG_PTS
hw->pts_hit++;
#endif
} else {
+ hw->pics[hw->decoding_index].pts_valid = 0;
+ hw->pics[hw->decoding_index].pts = 0;
+ hw->pics[hw->decoding_index].pts64 = 0;
#ifdef DEBUG_PTS
hw->pts_missed++;
#endif
@@ -3394,365 +3708,66 @@
}
}
- repeat_count = READ_VREG(AVS_REPEAT_COUNT);
#ifdef USE_DYNAMIC_BUF_NUM
- buffer_index =
- ((reg & 0x7) +
- (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
+ buffer_index = ((reg & 0x7) + (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
#else
if (firmware_sel == 0)
- buffer_index =
- ((reg & 0x7) +
+ buffer_index = ((reg & 0x7) +
(((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
else
- buffer_index =
- ((reg & 0x7) - 1) & 3;
+ buffer_index = ((reg & 0x7) - 1) & 3;
#endif
picture_type = (reg >> 3) & 7;
+ hw->pics[hw->decoding_index].picture_type = picture_type;
#ifdef DEBUG_PTS
if (picture_type == I_PICTURE) {
- /* pr_info("I offset 0x%x, pts_valid %d\n",
- * offset, pts_valid);
- */
- if (!pts_valid)
+ if (!hw->pics[hw->decoding_index].pts_valid)
hw->pts_i_missed++;
else
hw->pts_i_hit++;
}
#endif
- if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
- && hw->frame_width == 1920 && hw->frame_height == 1080) {
- force_interlaced_frame = true;
- }
-
if (hw->throw_pb_flag && picture_type != I_PICTURE) {
-
debug_print(hw, PRINT_FLAG_DECODING,
"%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for throwing picture with type of %d\n",
__func__,
- ~(1 << buffer_index), picture_type);
+ ~(1 << hw->decoding_index), picture_type);
- WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index));
- } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */
- hw->throw_pb_flag = 0;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "interlace, picture type %d\n",
- picture_type);
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
+ WRITE_VREG(AVS_BUFFERIN, ~(1 << hw->decoding_index));
+ hw->buf_use[hw->decoding_index]--;
+ } else {
+ u32 decode_status = READ_VREG(DECODE_STATUS) & 0xff;
+ if (vdec_frame_based(vdec) && (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
+ decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY)) {
+ hw->pics[hw->decoding_index].error_flag = 1;
}
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- hw->pic_type = 2;
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- vf->pts_us64 = pts_us64;
- if ((repeat_count > 1) && hw->avi_flag) {
- /* hw->next_pts = pts +
- * (hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1)*15/16;
- */
- hw->next_pts =
- pts +
- (dur * repeat_count >> 1) *
- 15 / 16;
- } else
- hw->next_pts = 0;
+ check_ref_error(hw, hw->decoding_index);
+
+ if ((picture_type == I_PICTURE) ||
+ (picture_type == P_PICTURE)) {
+ buffer_index = update_reference(hw, hw->decoding_index);
} else {
- vf->pts = hw->next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate >> 1;
- */
- vf->duration = dur >> 1;
- hw->next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_TOP;
- }else{
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG)
- ? VIDTYPE_INTERLACE_TOP
- : VIDTYPE_INTERLACE_BOTTOM;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr);
- vf->pts = (pts_valid)?pts:0;
- //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
- vf->pts = 0;
+ /* drop b frame before reference pic ready */
+ if (hw->refs[0] == -1)
+ buffer_index = hw->vf_buf_num_used;
}
- debug_print(hw, PRINT_FLAG_PTS,
- "interlace1 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->pts);
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- if (force_interlaced_frame)
- vf->pts = 0;
- else
- vf->pts = hw->next_pts;
-
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
-
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration = hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
+ if (buffer_index < hw->vf_buf_num_used) {
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "avs: show num %d, type %d, index %d, offset %x\n",
+ decode_pic_count, picture_type, buffer_index, offset);
+ prepare_display_buf(hw, &hw->pics[buffer_index]);
} else {
- /* vf->duration = hw->vavs_amstream_dec_info.rate
- * >> 1;
- */
- vf->duration = dur >> 1;
- hw->next_pts = 0;
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_BOTTOM;
- } else {
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG) ?
- VIDTYPE_INTERLACE_BOTTOM :
- VIDTYPE_INTERLACE_TOP;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
- vf->pts_us64 = 0;
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- debug_print(hw, PRINT_FLAG_PTS,
- "interlace2 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->pts);
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- hw->total_frame++;
- } else { /* progressive */
- hw->throw_pb_flag = 0;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "progressive picture type %d\n",
- picture_type);
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- hw->pic_type = 1;
-
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- if ((repeat_count > 1) && hw->avi_flag) {
- /* hw->next_pts = pts +
- * (hw->vavs_amstream_dec_info.rate *
- * repeat_count)*15/16;
- */
- hw->next_pts =
- pts +
- (dur * repeat_count) * 15 / 16;
- } else
- hw->next_pts = 0;
- } else {
- vf->pts = hw->next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate *
- * repeat_count;
- */
- vf->duration = dur * repeat_count;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate;
- */
- vf->duration = dur;
- hw->next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
-
- vf->pts = (pts_valid)?pts:0;
- //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr);
- debug_print(hw, PRINT_FLAG_PTS,
- "progressive vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
- vf->pts = 0;
- }
- decoder_do_frame_check(hw_to_vdec(hw), vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->pts);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- hw->total_frame++;
- }
-
- /*count info*/
- vdec_count_info(hw->gvs, 0, offset);
- if (offset) {
- if (picture_type == I_PICTURE) {
- hw->gvs->i_decoded_frames++;
- } else if (picture_type == P_PICTURE) {
- hw->gvs->p_decoded_frames++;
- } else if (picture_type == B_PICTURE) {
- hw->gvs->b_decoded_frames++;
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "avs: drop pic num %d, type %d, index %d, offset %x\n",
+ decode_pic_count, picture_type, buffer_index, offset);
}
}
- avs_update_gvs(hw);
- vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0);
-
- /* pr_info("PicType = %d, PTS = 0x%x\n",
- * picture_type, vf->pts);
- */
WRITE_VREG(AVS_BUFFEROUT, 0);
}
//WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
if (hw->m_ins_flag) {
u32 status_reg = READ_VREG(DECODE_STATUS);
u32 decode_status = status_reg & 0xff;
@@ -3786,15 +3801,19 @@
amvdec_stop();
#endif
vavs_save_regs(hw);
+ if (reg) {
+ hw->buf_use[hw->decoding_index]++;
+ }
+
debug_print(hw, PRINT_FLAG_DECODING,
- "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n",
+ "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x, AV_SCRATCH_B=0x%x\n",
__func__,
(decode_status == DECODE_STATUS_PIC_DONE) ?
"DECODE_STATUS_PIC_DONE" : "DECODE_STATUS_SKIP_PIC_DONE",
status_reg, decode_status,
hw->buf_status,
hw->dec_result, hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
+ READ_VREG(VIFF_BIT_CNT), READ_VREG(AV_SCRATCH_B));
vdec_schedule_work(&hw->work);
return IRQ_HANDLED;
} else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
@@ -3816,16 +3835,19 @@
hw->decode_pic_count++;
}
vavs_save_regs(hw);
+ if (reg) {
+ hw->buf_use[hw->decoding_index]++;
+ }
} else
hw->dec_result = DEC_RESULT_AGAIN;
debug_print(hw, PRINT_FLAG_DECODING,
- "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x, hw->decode_status_skip_pic_done_flag = %d, hw->decode_decode_cont_start_code = 0x%x\n",
+ "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x, hw->decode_status_skip_pic_done_flag = %d, hw->decode_decode_cont_start_code = 0x%x, AV_SCRATCH_B=0x%x\n",
__func__, status_reg, decode_status,
hw->buf_status,
hw->reg_scratch_8,
hw->dec_result, hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT), hw->decode_status_skip_pic_done_flag, hw->decode_decode_cont_start_code);
+ READ_VREG(VIFF_BIT_CNT), hw->decode_status_skip_pic_done_flag, hw->decode_decode_cont_start_code, READ_VREG(AV_SCRATCH_B));
vdec_schedule_work(&hw->work);
return IRQ_HANDLED;
}
@@ -3865,7 +3887,10 @@
);
debug_print(hw, 0,
- "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
+ "is_framebase(%d), decode_status 0x%x, buf_status 0x%x,"
+ "buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x,"
+ "dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d"
+ "input_empty %d fun_flag %d\n",
vdec_frame_based(vdec),
READ_VREG(DECODE_STATUS) & 0xff,
hw->buf_status,
@@ -3878,11 +3903,12 @@
hw->display_frame_count,
hw->run_count,
hw->not_run_ready,
- hw->input_empty
+ hw->input_empty,
+ hw->run_flag
);
if (vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
+ enum receiver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
NULL);
@@ -3912,6 +3938,14 @@
for (i = 0; i < hw->vf_buf_num_used; i++)
debug_print(hw, 0, "%d: vf_buf_use %d\n",
i, hw->vfbuf_use[i]);
+ debug_print(hw, 0, "ref_use:\n");
+ for (i = 0; i < hw->vf_buf_num_used; i++)
+ debug_print(hw, 0, "%d: ref_use %d\n",
+ i, hw->ref_use[i]);
+ debug_print(hw, 0, "buf_use:\n");
+ for (i = 0; i < hw->vf_buf_num_used; i++)
+ debug_print(hw, 0, "%d: buf_use %d\n",
+ i, hw->buf_use[i]);
debug_print(hw, 0,
"DECODE_STATUS=0x%x\n",
@@ -4009,6 +4043,7 @@
}
/*atomic_set(&hw->error_handler_run, 0);*/
hw->m_ins_flag = 1;
+ hw->run_flag = 0;
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
firmware_sel = 1;
@@ -4056,9 +4091,9 @@
#ifdef ENABLE_USER_DATA
if (NULL == hw->user_data_buffer) {
hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
+ decoder_dma_alloc_coherent(&hw->user_data_handle,
USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
+ &hw->user_data_buffer_phys, "AVS_AUX_BUF");
if (!hw->user_data_buffer) {
pr_info("%s: Can not allocate hw->user_data_buffer\n",
__func__);
@@ -4084,8 +4119,8 @@
return -1;
}*/
/*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/
- hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL);
+ hw->lmem_addr = (dma_addr_t)decoder_dma_alloc_coherent(&hw->lmem_phy_handle,
+ LMEM_BUF_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, "AVS_LMEM_BUF");
if (hw->lmem_addr == 0) {
pr_err("%s: failed to alloc lmem buffer\n", __func__);
r = -1;
@@ -4143,12 +4178,12 @@
return 0;
error4:
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(hw->lmem_phy_handle,
LMEM_BUF_SIZE, (void *)hw->lmem_addr,
hw->lmem_phy_addr);
error3:
- dma_free_coherent(
- amports_get_dma_device(),
+ decoder_dma_free_coherent(
+ hw->user_data_handle,
USER_DATA_SIZE,
hw->user_data_buffer,
hw->user_data_buffer_phys);
@@ -4192,8 +4227,12 @@
cancel_work_sync(&hw->notify_work);
if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
+ void *bmmu_box_tmp = hw->mm_blk_handle;
hw->mm_blk_handle = NULL;
+ if (hw->run_flag)
+ usleep_range(1000, 2000);
+ decoder_bmmu_box_free(bmmu_box_tmp);
+ bmmu_box_tmp = NULL;
}
if (vdec->parallel_dec == 1)
vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
@@ -4209,8 +4248,8 @@
}
#ifdef ENABLE_USER_DATA
if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
+ decoder_dma_free_coherent(
+ hw->user_data_handle,
USER_DATA_SIZE,
hw->user_data_buffer,
hw->user_data_buffer_phys);
@@ -4225,7 +4264,7 @@
hw->lmem_addr = NULL;
}*/
if (hw->lmem_addr) {
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(hw->lmem_phy_handle,
LMEM_BUF_SIZE, (void *)hw->lmem_addr,
hw->lmem_phy_addr);
hw->lmem_addr = 0;
@@ -4512,7 +4551,7 @@
amvdec_disable();
/*vfree(buf);*/
pr_err("AVS: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
+ fw_tee_enabled() ? "TEE" : "local", ret);
}
pr_info("%s, %d\n", __func__, __LINE__);
@@ -4622,9 +4661,9 @@
#ifdef ENABLE_USER_DATA
if (NULL == hw->user_data_buffer) {
hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
+ decoder_dma_alloc_coherent(&hw->user_data_handle,
USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
+ &hw->user_data_buffer_phys, "AVS_AUX_BUF");
if (!hw->user_data_buffer) {
pr_info("%s: Can not allocate hw->user_data_buffer\n",
__func__);
@@ -4756,7 +4795,7 @@
#ifdef BITSTREAM_READ_TMP_NO_CACHE
if (bitstream_read_tmp) {
- dma_free_coherent(amports_get_dma_device(),
+ decoder_dma_free_coherent(bitstream_read_handle,
SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
bitstream_read_tmp_phy);
bitstream_read_tmp = NULL;
@@ -4783,8 +4822,8 @@
#ifdef ENABLE_USER_DATA
if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
+ decoder_dma_free_coherent(
+ hw->user_data_handle,
USER_DATA_SIZE,
hw->user_data_buffer,
hw->user_data_buffer_phys);
@@ -4975,7 +5014,7 @@
MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs udebug_flag\n");
module_param(udebug_pause_pos, uint, 0664);
MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.h b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
index 8922b40..ca89e2c 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.h
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
@@ -1,22 +1,22 @@
/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Description:
+ */
#ifndef AVS_H_
#define AVS_H_
diff --git a/drivers/frame_provider/decoder/h264/Makefile b/drivers/frame_provider/decoder/h264/Makefile
deleted file mode 100644
index b7c85ee..0000000
--- a/drivers/frame_provider/decoder/h264/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264) += amvdec_h264.o
-amvdec_h264-objs += vh264.o
-
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC) += amvdec_h264mvc.o
-amvdec_h264mvc-objs += vh264_mvc.o
-
diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c
deleted file mode 100644
index 55f0581..0000000
--- a/drivers/frame_provider/decoder/h264/vh264.c
+++ /dev/null
@@ -1,4509 +0,0 @@
-/*
- * drivers/amlogic/media/frame_provider/decoder/h264/vh264.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/tsync.h>
-#include <linux/workqueue.h>
-#include <linux/dma-mapping.h>
-#include <linux/atomic.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/canvas/canvas.h>
-#include "../utils/vdec.h"
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../utils/amvdec.h"
-#include "vh264.h"
-#include "../../../stream_input/amports/streambuf.h"
-#include <linux/delay.h>
-#include <linux/amlogic/media/video_sink/video.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/amlogic/media/ge2d/ge2d.h>
-#include "../utils/decoder_mmu_box.h"
-#include "../utils/decoder_bmmu_box.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include <linux/uaccess.h>
-
-#define DRIVER_NAME "amvdec_h264"
-#define MODULE_NAME "amvdec_h264"
-#define MEM_NAME "codec_264"
-#define HANDLE_H264_IRQ
-
-#if 0
-/* currently, only iptv supports this function*/
-#define SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
-#endif
-
-/* #define DEBUG_PTS */
-#if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */
-#define DROP_B_FRAME_FOR_1080P_50_60FPS
-#endif
-#define RATE_MEASURE_NUM 8
-#define RATE_CORRECTION_THRESHOLD 5
-#define RATE_24_FPS 4004 /* 23.97 */
-#define RATE_25_FPS 3840 /* 25 */
-#define DUR2PTS(x) ((x)*90/96)
-#define PTS2DUR(x) ((x)*96/90)
-#define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96)
-#define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2
-#define VDEC_CLOCK_ADJUST_FRAME 30
-
-static inline bool close_to(int a, int b, int m)
-{
- return (abs(a - b) < m) ? true : false;
-}
-
-static DEFINE_MUTEX(vh264_mutex);
-#define DEF_BUF_START_ADDR 0x1000000
-#define V_BUF_ADDR_OFFSET_NEW (0x1ee000)
-#define V_BUF_ADDR_OFFSET (0x13e000)
-
-#define PIC_SINGLE_FRAME 0
-#define PIC_TOP_BOT_TOP 1
-#define PIC_BOT_TOP_BOT 2
-#define PIC_DOUBLE_FRAME 3
-#define PIC_TRIPLE_FRAME 4
-#define PIC_TOP_BOT 5
-#define PIC_BOT_TOP 6
-#define PIC_INVALID 7
-
-#define EXTEND_SAR 0xff
-
-#define VF_POOL_SIZE 64
-#define VF_BUF_NUM 24
-#define WORKSPACE_BUF_NUM 2
-#define PUT_INTERVAL (HZ/100)
-#define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL)
-
-#define SWITCHING_STATE_OFF 0
-#define SWITCHING_STATE_ON_CMD3 1
-#define SWITCHING_STATE_ON_CMD1 2
-#define SWITCHING_STATE_ON_CMD1_PENDING 3
-
-
-#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001
-#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002
-#define DEC_CONTROL_FLAG_DISABLE_FAST_POC 0x0004
-
-#define INCPTR(p) ptr_atomic_wrap_inc(&p)
-
-#define SLICE_TYPE_I 2
-#define SLICE_TYPE_P 5
-#define SLICE_TYPE_B 6
-
-struct buffer_spec_s {
- unsigned int y_addr;
- unsigned int u_addr;
- unsigned int v_addr;
-
- int y_canvas_index;
- int u_canvas_index;
- int v_canvas_index;
-
- unsigned int y_canvas_width;
- unsigned int u_canvas_width;
- unsigned int v_canvas_width;
-
- unsigned int y_canvas_height;
- unsigned int u_canvas_height;
- unsigned int v_canvas_height;
-
- unsigned long phy_addr;
- int alloc_count;
-};
-
-#define spec2canvas(x) \
- (((x)->v_canvas_index << 16) | \
- ((x)->u_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-static struct vframe_s *vh264_vf_peek(void *);
-static struct vframe_s *vh264_vf_get(void *);
-static void vh264_vf_put(struct vframe_s *, void *);
-static int vh264_vf_states(struct vframe_states *states, void *);
-static int vh264_event_cb(int type, void *data, void *private_data);
-
-static void vh264_prot_init(void);
-static int vh264_local_init(void);
-static void vh264_put_timer_func(struct timer_list *timer);
-static void stream_switching_done(void);
-
-static const char vh264_dec_id[] = "vh264-dev";
-
-#define PROVIDER_NAME "decoder.h264"
-
-static const struct vframe_operations_s vh264_vf_provider_ops = {
- .peek = vh264_vf_peek,
- .get = vh264_vf_get,
- .put = vh264_vf_put,
- .event_cb = vh264_event_cb,
- .vf_states = vh264_vf_states,
-};
-
-static struct vframe_provider_s vh264_vf_prov;
-/*TODO irq*/
-#if 1
-static u32 frame_width, frame_height, frame_dur, frame_prog, frame_packing_type,
- last_duration;
-static u32 saved_resolution;
-static u32 last_mb_width, last_mb_height;
-#else
-static u32 frame_buffer_size;
-static u32 frame_width, frame_height, frame_dur, frame_prog, last_duration;
-static u32 last_mb_width, last_mb_height;
-static u32 frame_packing_type;
-#endif
-static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(delay_display_q, struct vframe_s *, VF_POOL_SIZE);
-
-static struct vframe_s vfpool[VF_POOL_SIZE];
-static s32 vfbuf_use[VF_BUF_NUM];
-static struct buffer_spec_s buffer_spec[VF_BUF_NUM];
-static struct buffer_spec_s fense_buffer_spec[2];
-/* disp buf + keep buf+ fense buf + workspace */
-
-#define MAX_BLK_BUFFERS (VF_BUF_NUM + 2 + WORKSPACE_BUF_NUM)
-#define VF_BUFFER_IDX(n) (WORKSPACE_BUF_NUM + n)
-#define FENSE_BUFFER_IDX(n) (WORKSPACE_BUF_NUM + VF_BUF_NUM + n)
-
-#define USER_DATA_RUND_SIZE (USER_DATA_SIZE + 4096)
-static struct vframe_s fense_vf[2];
-
-static struct timer_list recycle_timer;
-static u32 stat;
-static s32 buf_offset;
-static u32 pts_outside;
-static u32 sync_outside;
-static u32 dec_control;
-static u32 vh264_ratio;
-static u32 vh264_rotation;
-static u32 use_idr_framerate;
-static u32 high_bandwidth;
-
-static u32 seq_info;
-static u32 timing_info_present_flag;
-static u32 fixed_frame_rate_flag;
-static u32 fixed_frame_rate_check_count;
-static u32 aspect_ratio_info;
-static u32 num_units_in_tick;
-static u32 time_scale;
-static u32 h264_ar;
-static u32 decoder_debug_flag;
-static u32 dpb_size_adj = 6;
-static u32 fr_hint_status;
-
-#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS
-static u32 last_interlaced;
-#endif
-static bool is_4k;
-static unsigned char h264_first_pts_ready;
-static bool h264_first_valid_pts_ready;
-static u32 h264pts1, h264pts2;
-static u32 h264_pts_count, duration_from_pts_done, duration_on_correcting;
-static u32 vh264_error_count;
-static u32 vh264_no_disp_count;
-static u32 fatal_error_flag;
-static u32 fatal_error_reset;
-static u32 max_refer_buf = 1;
-static u32 decoder_force_reset;
-static unsigned int no_idr_error_count;
-static unsigned int no_idr_error_max = 60;
-static unsigned int canvas_mode;
-
-#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
-/* 0~128*/
-static u32 bad_block_scale;
-#endif
-static u32 enable_userdata_debug;
-
-static unsigned int enable_switch_fense = 1;
-#define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k)
-static struct vframe_qos_s s_vframe_qos;
-static int frame_count;
-
-#if 0
-static u32 vh264_no_disp_wd_count;
-#endif
-static u32 vh264_running;
-static s32 vh264_stream_switching_state;
-static s32 vh264_eos;
-static struct vframe_s *p_last_vf;
-static s32 iponly_early_mode;
-static void *mm_blk_handle;
-static int tvp_flag;
-static bool is_reset;
-
-/*TODO irq*/
-#if 1
-static u32 last_pts, last_pts_remainder;
-#else
-static u32 last_pts;
-#endif
-static bool check_pts_discontinue;
-static u32 wait_buffer_counter;
-static u32 video_signal_from_vui;
-
-static uint error_recovery_mode;
-static uint error_recovery_mode_in = 3;
-static uint error_recovery_mode_use = 3;
-
-static uint mb_total = 0, mb_width = 0, mb_height;
-static uint saved_idc_level;
-#define UCODE_IP_ONLY 2
-#define UCODE_IP_ONLY_PARAM 1
-static uint ucode_type;
-
-#ifdef DEBUG_PTS
-static unsigned long pts_missed, pts_hit;
-#endif
-static uint debugfirmware;
-
-static atomic_t vh264_active = ATOMIC_INIT(0);
-static int vh264_reset;
-static struct work_struct error_wd_work;
-static struct work_struct stream_switching_work;
-static struct work_struct set_parameter_work;
-static struct work_struct notify_work;
-static struct work_struct set_clk_work;
-static struct work_struct userdata_push_work;
-
-struct h264_qos_data_node_t {
- struct list_head list;
-
- uint32_t b_offset;
- int poc;
- /* picture qos infomation*/
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
-};
-
-/*qos data records list waiting for match with picture that be display*/
-static struct list_head picture_qos_list;
-/*free qos data records list*/
-static struct list_head free_qos_nodes_list;
-#define MAX_FREE_QOS_NODES 64
-static struct h264_qos_data_node_t free_nodes[MAX_FREE_QOS_NODES];
-static struct work_struct qos_work;
-static struct dec_sysinfo vh264_amstream_dec_info;
-static dma_addr_t mc_dma_handle;
-static void *mc_cpu_addr;
-static u32 first_offset;
-static u32 first_pts;
-static u32 first_frame_size;
-static u64 first_pts64;
-static bool first_pts_cached;
-static void *sei_data_buffer;
-static dma_addr_t sei_data_buffer_phys;
-static int clk_adj_frame_count;
-
-#define MC_OFFSET_HEADER 0x0000
-#define MC_OFFSET_DATA 0x1000
-#define MC_OFFSET_MMCO 0x2000
-#define MC_OFFSET_LIST 0x3000
-#define MC_OFFSET_SLICE 0x4000
-
-#define MC_TOTAL_SIZE (20*SZ_1K)
-#define MC_SWAP_SIZE (4*SZ_1K)
-
-#define MODE_ERROR 0
-#define MODE_FULL 1
-
-static DEFINE_SPINLOCK(lock);
-static DEFINE_SPINLOCK(prepare_lock);
-static DEFINE_SPINLOCK(recycle_lock);
-
-static bool block_display_q;
-static int vh264_stop(int mode);
-static s32 vh264_init(void);
-
-
-#define DFS_HIGH_THEASHOLD 3
-
-static bool pts_discontinue;
-
-static struct ge2d_context_s *ge2d_videoh264_context;
-
-static struct vdec_info *gvs;
-
-static struct vdec_s *vdec_h264;
-
-static int ge2d_videoh264task_init(void)
-{
- if (ge2d_videoh264_context == NULL)
- ge2d_videoh264_context = create_ge2d_work_queue();
-
- if (ge2d_videoh264_context == NULL) {
- pr_info("create_ge2d_work_queue video task failed\n");
- return -1;
- }
- return 0;
-}
-
-static int ge2d_videoh264task_release(void)
-{
- if (ge2d_videoh264_context) {
- destroy_ge2d_work_queue(ge2d_videoh264_context);
- ge2d_videoh264_context = NULL;
- }
- return 0;
-}
-
-static int ge2d_canvas_dup(struct canvas_s *srcy, struct canvas_s *srcu,
- struct canvas_s *des, int format, u32 srcindex,
- u32 desindex)
-{
-
- struct config_para_ex_s ge2d_config;
- /* pr_info("[%s]h264 ADDR srcy[0x%lx] srcu[0x%lx] des[0x%lx]\n",
- * __func__, srcy->addr, srcu->addr, des->addr);
- */
- memset(&ge2d_config, 0, sizeof(struct config_para_ex_s));
-
- ge2d_config.alu_const_color = 0;
- ge2d_config.bitmask_en = 0;
- ge2d_config.src1_gb_alpha = 0;
-
- ge2d_config.src_planes[0].addr = srcy->addr;
- ge2d_config.src_planes[0].w = srcy->width;
- ge2d_config.src_planes[0].h = srcy->height;
-
- ge2d_config.src_planes[1].addr = srcu->addr;
- ge2d_config.src_planes[1].w = srcu->width;
- ge2d_config.src_planes[1].h = srcu->height;
-
- ge2d_config.dst_planes[0].addr = des->addr;
- ge2d_config.dst_planes[0].w = des->width;
- ge2d_config.dst_planes[0].h = des->height;
-
- ge2d_config.src_para.canvas_index = srcindex;
- ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.src_para.format = format;
- ge2d_config.src_para.fill_color_en = 0;
- ge2d_config.src_para.fill_mode = 0;
- ge2d_config.src_para.color = 0;
- ge2d_config.src_para.top = 0;
- ge2d_config.src_para.left = 0;
- ge2d_config.src_para.width = srcy->width;
- ge2d_config.src_para.height = srcy->height;
-
- ge2d_config.dst_para.canvas_index = desindex;
- ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.dst_para.format = format;
- ge2d_config.dst_para.fill_color_en = 0;
- ge2d_config.dst_para.fill_mode = 0;
- ge2d_config.dst_para.color = 0;
- ge2d_config.dst_para.top = 0;
- ge2d_config.dst_para.left = 0;
- ge2d_config.dst_para.width = srcy->width;
- ge2d_config.dst_para.height = srcy->height;
-
- if (ge2d_context_config_ex(ge2d_videoh264_context, &ge2d_config) < 0) {
- pr_info("ge2d_context_config_ex failed\n");
- return -1;
- }
-
- stretchblt_noalpha(ge2d_videoh264_context, 0, 0, srcy->width,
- srcy->height, 0, 0, srcy->width, srcy->height);
-
- return 0;
-}
-
-static inline int fifo_level(void)
-{
- return VF_POOL_SIZE - kfifo_len(&newframe_q);
-}
-
-
-void spec_set_canvas(struct buffer_spec_s *spec,
- unsigned int width, unsigned int height)
-{
- int endian;
-
- endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
- config_cav_lut_ex(spec->y_canvas_index,
- spec->y_addr,
- width, height,
- CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
-
- config_cav_lut_ex(spec->u_canvas_index,
- spec->u_addr,
- width, height / 2,
- CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
-
-}
-
-static void vh264_notify_work(struct work_struct *work)
-{
- pr_info("frame duration changed %d\n", frame_dur);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)frame_dur));
-
- return;
-}
-
-static void prepare_display_q(void)
-{
- unsigned long flags;
- int count;
-
- spin_lock_irqsave(&prepare_lock, flags);
-
- if (block_display_q) {
- spin_unlock_irqrestore(&prepare_lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&prepare_lock, flags);
-
- count = (int)VF_POOL_SIZE -
- kfifo_len(&delay_display_q) -
- kfifo_len(&display_q) -
- kfifo_len(&recycle_q) -
- kfifo_len(&newframe_q);
-
- if ((vh264_stream_switching_state != SWITCHING_STATE_OFF)
- || !EN_SWITCH_FENCE())
- count = 0;
- else
- count = (count < 2) ? 0 : 2;
-
- while (kfifo_len(&delay_display_q) > count) {
- struct vframe_s *vf;
-
- if (kfifo_get(&delay_display_q, &vf)) {
- kfifo_put(&display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);