Project import generated by Copybara. GitOrigin-RevId: a13be63c5ff99e1fd1c223991f26f4265e6fef3e
diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 7481eee..6640ff9 --- a/Makefile +++ b/Makefile
@@ -1,6 +1,3 @@ -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -MEDIA_MODULE_PATH := $(dir $(mkfile_path)) -VERSION_CONTROL_CFLAGS := $(shell ${MEDIA_MODULE_PATH}/version_control.sh) CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \ CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \ @@ -18,25 +15,21 @@ CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \ 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_ENHANCEMENT_DOLBYVISION=y \ - CONFIG_AMLOGIC_MEDIA_GE2D=y \ - CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \ - CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m + CONFIG_AMLOGIC_MEDIA_VENC_H264=m \ + CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \ + CONFIG_AMLOGIC_MEDIA_VENC_H265=m + EXTRA_INCLUDE := -I$(KERNEL_SRC)/$(M)/drivers/include CONFIGS_BUILD := -Wno-parentheses-equality -Wno-pointer-bool-conversion \ -Wno-unused-const-variable -Wno-typedef-redefinition \ - -Wno-logical-not-parentheses -Wno-sometimes-uninitialized \ - -Wno-frame-larger-than= + -Wno-logical-not-parentheses -Wno-sometimes-uninitialized -KBUILD_CFLAGS_MODULE += $(GKI_EXT_MODULE_PREDEFINE) 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) + $(MAKE) -C $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE)" $(CONFIGS) all: modules
diff --git a/Media.mk b/Media.mk index 58db63b..68b0778 100644 --- a/Media.mk +++ b/Media.mk
@@ -18,13 +18,13 @@ CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \ CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \ CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \ CONFIG_AMLOGIC_MEDIA_VENC_H264=m \ + CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \ CONFIG_AMLOGIC_MEDIA_VENC_H265=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_FRAME_WARN=4096 define copy-media-modules $(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\ @@ -63,10 +63,11 @@ $(shell cp $(MEDIA_DRIVERS)/* $(MEDIA_MODULES) -rfa) define media-modules - PATH=$(KERNEL_TOOLPATHS):$$PATH \ - $(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) $(KERNEL_ARGS) $(CONFIGS) \ - "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error" modules; \ - find $(MEDIA_MODULES) -name "*.ko" | PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH xargs -i cp {} $(MODS_OUT) + PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \ + $(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) ARCH=$(KERNEL_ARCH) \ + CROSS_COMPILE=$(PREFIX_CROSS_COMPILE) $(CONFIGS) \ + EXTRA_CFLAGS+=-I$(INCLUDE) modules; + sh $(TOP)/device/amlogic/common/copy_modules.sh $(MEDIA_MODULES) $(MODS_OUT) endef else @@ -90,10 +91,18 @@ $(shell mkdir $(MODS_OUT) -p) endif +ifeq ($(KERNEL_A32_SUPPORT), true) +TOOLS := /opt/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- +else +TOOLS := /opt/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- +endif + + modules: - CCACHE_NODIRECT="true" PATH=$(KERNEL_TOOLPATHS):$$PATH \ - $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) $(KERNEL_ARGS) $(CONFIGS) \ - EXTRA_CFLAGS+=-I$(INCLUDE) -j64 + CCACHE_NODIRECT="true" PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \ + $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) \ + CROSS_COMPILE=$(TOOLS) $(CONFIGS) \ + EXTRA_CFLAGS+=-I$(INCLUDE) -j64 copy-modules: @echo "start copying media modules." @@ -102,9 +111,8 @@ all: modules copy-modules - clean: - PATH=$(KERNEL_TOOLPATHS):$$PATH \ - $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) $(KERNEL_ARGS) clean + PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \ + $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) clean endif
diff --git a/VERSION b/VERSION deleted file mode 100644 index 4b1504d..0000000 --- a/VERSION +++ /dev/null
@@ -1,76 +0,0 @@ -Major_V=5 -Minor_V=3 -BaseChangeId=Ifc17e92ef9c9e211b8f01ebae1e97c5855fea084 - - -#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. -#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 -# -#V4.0.0 Release Notes -#upgrade Kernel version to 4.19 -#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 -#new firmware management -#mjpeg/mpeg12/mpeg2 multi-instance decoder support -#h264 4k afbc support -#AVS2 decoder support -#vdec double write support -#add av1 decoder support -#add decoder QOS info report -#upgrade TA ucode to 0.2 version -# -#V2.0.0 Release Notes -#upgrade Kernel version to 3.14 -#Introduce codec_mm memory managment -#add afbc scatter memory support -#add vp9 decoder support -#add 264/265/vp9 multi-instance decoder support -# -#V1.0.0 Release Notes -#based kernel to 3.10 -#add H264 4K decoder support -#add H265 video decoder support -#H265 decoder support afbc output
diff --git a/build_media.sh b/build_media.sh new file mode 100755 index 0000000..63eaf1a --- /dev/null +++ b/build_media.sh
@@ -0,0 +1,105 @@ +#!/bin/bash +# Builds the media driver and updates the workspace path with output files + +exec_name=$0 + +cpu_num=$(grep -c processor /proc/cpuinfo) + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +CROSS_COMPILE=$DIR/../prebuilt/toolchain/aarch64/bin/aarch64-cros-linux-gnu- +KERNEL_ARCH=arm64 +KDIR=$DIR/../kernel +INCLUDE=$DIR/drivers/include +MEDIA_MODULES=$DIR/drivers +CONFIGS="CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4_MULTI=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_VC1=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_H264=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_H265=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_VP9=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \ + CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \ + CONFIG_AMLOGIC_MEDIA_VENC_H264=m \ + CONFIG_AMLOGIC_MEDIA_VENC_H265=m \ + CONFIG_FRAME_WARN=4096" + +set -o errtrace +trap 'echo Fatal error: script ${exec_name} aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR + +function usage(){ + echo "Usage: ${exec_name} <product> [workspace path]" + echo "supported products: sabrina" + echo "Note: if [workspace path] is not set, it still builds" +} + +if (( $# < 1 )) +then + usage + exit 2 +fi + +readonly product=$1 +readonly workspace_path=$2 + +pushd $DIR + + +make -C $KDIR M=$MEDIA_MODULES ARCH=$KERNEL_ARCH \ +CROSS_COMPILE=$CROSS_COMPILE $CONFIGS \ +EXTRA_CFLAGS+=-I$INCLUDE modules -j64 + +case $product in + sabrina*) + ;; + *) + echo "unknown product: $product" + exit 1 +esac + +popd + +if [ ! -z $workspace_path ]; then + media_out_dir=${workspace_path}/device/google/${product}-kernel/lib/modules + mkdir -p ${media_out_dir} + + for ko in aml_hardware_dmx.ko \ + amvdec_avs2.ko \ + amvdec_avs.ko \ + amvdec_h264.ko \ + amvdec_h264mvc.ko \ + amvdec_h265.ko \ + amvdec_mh264.ko \ + amvdec_mjpeg.ko \ + amvdec_mmjpeg.ko \ + amvdec_mmpeg12.ko \ + amvdec_mmpeg4.ko \ + amvdec_mpeg12.ko \ + amvdec_mpeg4.ko \ + amvdec_real.ko \ + amvdec_vc1.ko \ + amvdec_vp9.ko \ + decoder_common.ko \ + encoder.ko \ + firmware.ko \ + media_clock.ko \ + stream_input.ko \ + vpu.ko \ + amvdec_ports.ko \ + video_framerate_adapter.ko \ + media_sync.ko + do + find $MEDIA_MODULES -name $ko | xargs -i cp {} $media_out_dir + done + media_fw_out_dir=${workspace_path}/device/google/${product}-kernel/lib/firmware/video/ + mkdir -p $media_fw_out_dir + cp -r firmware/* $media_fw_out_dir +fi
diff --git a/drivers/Makefile b/drivers/Makefile index e96ba44..3e487db 100644 --- a/drivers/Makefile +++ b/drivers/Makefile
@@ -3,6 +3,6 @@ obj-y += frame_sink/ obj-y += stream_input/ obj-y += amvdec_ports/ +obj-y += fake_video_out/ 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..6395adf 100644 --- a/drivers/amvdec_ports/Makefile +++ b/drivers/amvdec_ports/Makefile
@@ -3,10 +3,8 @@ 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 += aml_vcodec_vfm.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
diff --git a/drivers/amvdec_ports/aml_task_chain.c b/drivers/amvdec_ports/aml_task_chain.c deleted file mode 100644 index 8dfe014..0000000 --- a/drivers/amvdec_ports/aml_task_chain.c +++ /dev/null
@@ -1,365 +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/list.h> -#include <linux/spinlock.h> - -#include "aml_vcodec_drv.h" -#include "aml_task_chain.h" - -#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2 -#include <trace/events/meson_atrace.h> - -struct task_item_name_s { - enum task_type_e type; - const u8 *name; -}; - -static const struct task_item_name_s iname[] = { - {TASK_TYPE_DEC, "dec"}, - {TASK_TYPE_VPP, "vpp"}, - {TASK_TYPE_V4L_SINK, "v4l-sink"}, - {TASK_TYPE_GE2D, "ge2d"}, - {TASK_TYPE_MAX, "unknown"}, -}; - -static const u8 *type_to_name(enum task_type_e type) -{ - const u8 *name = "unknown"; - int i, size = ARRAY_SIZE(iname); - - for (i = 0; i < size; i++) { - if (type == iname[i].type) - name = iname[i].name; - } - - return name; -} - -static struct task_item_s *find_task_item(struct task_chain_s *task, - enum task_type_e type) -{ - struct task_item_s *item = NULL; - ulong flags; - - spin_lock_irqsave(&task->slock, flags); - - if (!list_empty(&task->list_item)) { - struct task_item_s *p; - - list_for_each_entry(p, &task->list_item, node) { - if (p->ops->type == type) { - item = p; - break; - } - } - } - - if (item) - kref_get(&item->ref); - - spin_unlock_irqrestore(&task->slock, flags); - - return item; -} - -static void task_item_release(struct kref *kref); - -static void task_item_vframe_push(struct task_item_s *item, struct vframe_s *vframe) -{ - int i = 0; - - for (i = 0 ; i < 3; i++) { - if (item->vframe[i] == NULL) { - item->vframe[i] = vframe; - break; - } - } -} - -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; - break; - } - } - - return vframe; -} - -static struct task_item_s *task_item_get(struct task_chain_s *task, - enum task_type_e type) -{ - 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; -} - -static int task_item_put(struct task_item_s *item) -{ - return kref_put(&item->ref, task_item_release); -} - -static void 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 task_item_s *item = NULL; - struct task_item_s *item2 = NULL; - struct vframe_s *vf = NULL; - - 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->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); - - 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, - type, task->map[0][type]); - - task->direction = TASK_DIR_SUBMIT; - task_item_put(item2); - } - task_item_put(item); - } -} - -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 task_item_s *item = NULL; - struct task_item_s *item2 = NULL; - - item = task_item_get(task, type); - if (item) { - item->is_active = false; - - item2 = task_item_get(task, task->map[1][type]); - if (item2) { - struct vframe_s *vf = NULL; - - item2->is_active = true; - - vf = task_item_vframe_pop(item2); - 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, - type, task->map[1][type]); - - task->direction = TASK_DIR_RECYCLE; - task_item_put(item2); - } - task_item_put(item); - } -} - -void task_chain_show(struct task_chain_s *task) -{ - struct task_item_s *item = NULL; - char buf[128] = {0}; - char *pbuf = buf; - ulong flags; - - if (!task || !task->ctx) - return; - - spin_lock_irqsave(&task->slock, flags); - - if (!list_empty(&task->list_item)) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)task->obj; - - list_for_each_entry(item, &task->list_item, node) { - pbuf += sprintf(pbuf, "%s(%d)", - item->name, item->is_active); - if (item->node.next != &task->list_item) { - if (task->direction == TASK_DIR_SUBMIT) - pbuf += sprintf(pbuf, " ==> "); - else - pbuf += sprintf(pbuf, " <== "); - } - } - v4l_dbg(task->ctx, V4L_DEBUG_CODEC_PRINFO, - "vb:%2d, phy:%lx %s\n", - task->id, fb->m.mem[0].addr, buf); - } - - spin_unlock_irqrestore(&task->slock, flags); -} -EXPORT_SYMBOL(task_chain_show); - -static void task_chain_destroy(struct kref *kref) -{ - struct task_chain_s *task; - - task = container_of(kref, struct task_chain_s, ref); - - task->cur_type = TASK_TYPE_MAX; - memset(task->map, 0, sizeof(task->map)); - - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d task chain destroyed.\n", task, task->id); - - kfree(task); -} - -static void task_item_release(struct kref *kref) -{ - struct task_item_s *item; - - item = container_of(kref, struct task_item_s, ref); - list_del(&item->node); - - v4l_dbg(item->task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d task item:(%px,%d) released.\n", - item->task, item->task->id, item, item->ops->type); - - kref_put(&item->task->ref, task_chain_destroy); - - kfree(item); -} - -void task_chain_clean(struct task_chain_s *task) -{ - struct task_item_s *item, *tmp; - - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d task chain clean.\n", task, task->id); - - if (!list_empty(&task->list_item)) { - list_for_each_entry_safe(item, tmp, &task->list_item, node) - kref_put(&item->ref, task_item_release); - } -} -EXPORT_SYMBOL(task_chain_clean); - -void task_chain_release(struct task_chain_s *task) -{ - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d task chain release.\n", task, task->id); - - kref_put(&task->ref, task_chain_destroy); -} -EXPORT_SYMBOL(task_chain_release); - -void task_order_attach(struct task_chain_s *task, - struct task_ops_s *ops, - void *caller) -{ - struct task_item_s *item; - - item = kzalloc(sizeof(struct task_item_s), GFP_ATOMIC); - if (!item) { - v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR, - "TSK(%px):%d alloc item fail.\n", task, task->id); - return; - } - - item->task = task; - item->ops = ops; - item->caller = caller; - item->name = type_to_name(ops->type); - kref_init(&item->ref); - - task->map[0][ops->type] = task->cur_type; - task->map[1][task->cur_type] = ops->type; - task->cur_type = ops->type; - kref_get(&task->ref); - - list_add(&item->node, &task->list_item); - - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d attach item:(%px,%d).\n", - task, task->id, item, ops->type); -} -EXPORT_SYMBOL(task_order_attach); - -void task_chain_update_object(struct task_chain_s *task, void *obj) -{ - /* - * Note: have to invoke this funtion - * if the task object has been changed. - */ - task->obj = obj; - - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d update task obj:%px.\n", - task, task->id, obj); -} -EXPORT_SYMBOL(task_chain_update_object); - -int task_chain_init(struct task_chain_s **task_out, - void *v4l_ctx, - void *obj, - int vb_idx) -{ - struct task_chain_s *task; - - task = kzalloc(sizeof(struct task_chain_s), GFP_ATOMIC); - if (!task) { - v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR, - "TSK(%px):%d alloc task fail.\n", task, task->id); - return -ENOMEM; - } - - task->id = vb_idx; - task->obj = obj; - task->ctx = v4l_ctx; - kref_init(&task->ref); - spin_lock_init(&task->slock); - INIT_LIST_HEAD(&task->list_item); - - task->attach = task_order_attach; - task->submit = task_buffer_submit; - task->recycle = task_buffer_recycle; - - *task_out = task; - - v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN, - "TSK(%px):%d task chain creat success.\n", task, task->id); - return 0; -} -EXPORT_SYMBOL(task_chain_init); -
diff --git a/drivers/amvdec_ports/aml_task_chain.h b/drivers/amvdec_ports/aml_task_chain.h deleted file mode 100644 index fdbe2fb..0000000 --- a/drivers/amvdec_ports/aml_task_chain.h +++ /dev/null
@@ -1,125 +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 AML_TASK_CHAIN_H -#define AML_TASK_CHAIN_H - -#include <linux/amlogic/media/vfm/vframe.h> - -enum task_type_e { - TASK_TYPE_DEC, - TASK_TYPE_VPP, - TASK_TYPE_V4L_SINK, - TASK_TYPE_GE2D, - TASK_TYPE_MAX -}; - -enum task_dir_e { - TASK_DIR_SUBMIT, - TASK_DIR_RECYCLE, - TASK_DIR_MAX -}; - -struct task_chain_s; - -/* - * struct task_ops_s - interface of the task item. - * @type : type of task ops involves dec, vpp, v4l sink etc. - * @get_vframe : get the video frame from caller's fifo. - * @put_vframe : put the video frame to caller's fifo. - * @fill_buffer : submit the buffer into next process module. - */ -struct task_ops_s { - enum task_type_e type; - 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); -}; - -/* - * struct task_item_s - items of the task chain. - * @node : list node of the specific task item. - * @ref : reference count of item be used by others. - * @name : name of task item, map with task type. - * @is_active : indicate this item whether is active. - * @vframe[3] : store the vframes that get from caller. - * @task : the context of the task chain. - * @caller : it's the handle, meght it's dec, vpp or v4l-sink etc. - * @ops : sets of interface which attach from task item. - */ -struct task_item_s { - struct list_head node; - struct kref ref; - const u8 *name; - bool is_active; - void *vframe[3]; - struct task_chain_s *task; - void *caller; - struct task_ops_s *ops; -}; - -/* - * struct task_chain_s - the manager struct of the task chain. - * @list_item : all task items be attached are store in the list. - * @node : will register to the task chain pool. - * @ref : reference count of task chain be used by others. - * @slock : used for list item write and read safely. - * @id : it's vb index to be a mark used for task chain. - * @ctx : the context of the v4l driver. - * @obj : the object managed by task chain. - * @direction : direction incluse 2 flows submit & recycle. - * @cur_type : the latest item type before a new item be attached. - * @map : the map store the pipeline information. - * @attach : attach a new item to task chain. - * @submit : submit the finish item to next item module. - * @recycle : if item's date was consumed will be recycled to item. - */ -struct task_chain_s { - struct list_head list_item; - struct list_head node; - struct kref ref; - spinlock_t slock; - int id; - void *ctx; - void *obj; - enum task_dir_e direction; - enum task_type_e cur_type; - 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); - void (*recycle) (struct task_chain_s *, enum task_type_e); -}; - - -int task_chain_init(struct task_chain_s **task_out, - void *v4l_ctx, - void *obj, - int vb_idx); -void task_order_attach(struct task_chain_s *task, - struct task_ops_s *ops, - 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); -void task_chain_update_object(struct task_chain_s *task, void *obj); - -#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..95ee48a 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.c +++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -56,11 +56,17 @@ //#define DATA_DEBUG extern int dump_output_frame; -extern u32 dump_output_start_position; extern void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle); +static int def_4k_vstreambuf_sizeM = + (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20); +static int def_vstreambuf_sizeM = + (DEFAULT_VIDEO_BUFFER_SIZE >> 20); static int slow_input = 0; +static int use_bufferlevelx10000 = 10000; +static unsigned int amstream_buf_num = BUF_MAX_NUM; + static struct stream_buf_s bufs[BUF_MAX_NUM] = { { .reg_base = VLD_MEM_VIFIFO_REG_BASE, @@ -167,6 +173,60 @@ return 0; } +static int reset_canuse_buferlevel(int levelx10000) +{ + int i; + struct stream_buf_s *p = NULL; + + if (levelx10000 >= 0 && levelx10000 <= 10000) + use_bufferlevelx10000 = levelx10000; + else + use_bufferlevelx10000 = 10000; + for (i = 0; i < amstream_buf_num; i++) { + p = &bufs[i]; + p->canusebuf_size = ((p->buf_size / 1024) * + use_bufferlevelx10000 / 10000) * 1024; + p->canusebuf_size += 1023; + p->canusebuf_size &= ~1023; + + if (p->canusebuf_size > p->buf_size) + p->canusebuf_size = p->buf_size; + } + + return 0; +} + +static void change_vbufsize(struct vdec_s *vdec, + struct stream_buf_s *pvbuf) +{ + if (pvbuf->buf_start != 0) { + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "streambuf is alloced before\n"); + return; + } + + if (vdec->port->is_4k) { + pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M; + + if (vdec->port_flag & PORT_FLAG_DRM) + pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP; + + if ((pvbuf->buf_size > 30 * SZ_1M) + && (codec_mm_get_total_size() < 220 * SZ_1M)) { + /*if less than 250M, used 20M for 4K & 265*/ + pvbuf->buf_size = pvbuf->buf_size >> 1; + } + } else if (pvbuf->buf_size > def_vstreambuf_sizeM * SZ_1M) { + if (vdec->port_flag & PORT_FLAG_DRM) + pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP; + } else { + pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M; + if (vdec->port_flag & PORT_FLAG_DRM) + pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP; + } + + reset_canuse_buferlevel(10000); +} + static void user_buffer_init(void) { struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA]; @@ -177,14 +237,41 @@ pubuf->buf_rp = 0; } -static void video_component_release(struct stream_port_s *port) +static void video_component_release(struct stream_port_s *port, +struct stream_buf_s *pbuf, int release_num) { struct aml_vdec_adapt *ada_ctx = container_of(port, struct aml_vdec_adapt, port); struct vdec_s *vdec = ada_ctx->vdec; - vdec_release(vdec); + struct vdec_s *slave = NULL; + switch (release_num) { + default: + case 0: + case 4: { + if ((port->type & PORT_TYPE_FRAME) == 0) + esparser_release(pbuf); + } + + case 3: { + if (vdec->slave) + slave = vdec->slave; + vdec_release(vdec); + + if (slave) + vdec_release(slave); + vdec = NULL; + } + + case 2: { + if ((port->type & PORT_TYPE_FRAME) == 0) + stbuf_release(pbuf); + } + + case 1: + ; + } } static int video_component_init(struct stream_port_s *port, @@ -204,21 +291,69 @@ || port->vformat == VFORMAT_H264_4K2K) { port->is_4k = true; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX - && (port->vformat == VFORMAT_H264)) + && port->vformat == VFORMAT_H264) vdec_poweron(VDEC_HEVC); } else port->is_4k = false; - if (port->type & PORT_TYPE_FRAME || - (port->type & PORT_TYPE_ES)) { - ret = vdec_init(vdec, port->is_4k, true); + if (port->type & PORT_TYPE_FRAME) { + ret = vdec_init(vdec, port->is_4k); if (ret < 0) { v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n"); - video_component_release(port); + video_component_release(port, pbuf, 2); + return ret; + } + + return 0; + } + + change_vbufsize(vdec, pbuf); + + if (has_hevc_vdec()) { + if (port->type & PORT_TYPE_MPTS) { + if (pbuf->type == BUF_TYPE_HEVC) + vdec_poweroff(VDEC_1); + else + vdec_poweroff(VDEC_HEVC); + } + } + + ret = stbuf_init(pbuf, vdec); + if (ret < 0) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n"); + return ret; + } + + /* todo: set path based on port flag */ + ret = vdec_init(vdec, port->is_4k); + if (ret < 0) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n"); + video_component_release(port, pbuf, 2); + return ret; + } + + if (vdec_dual(vdec)) { + ret = vdec_init(vdec->slave, port->is_4k); + if (ret < 0) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n"); + video_component_release(port, pbuf, 2); return ret; } } + if (port->type & PORT_TYPE_ES) { + ret = esparser_init(pbuf, vdec); + if (ret < 0) { + video_component_release(port, pbuf, 3); + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n"); + return ret; + } + } + + pbuf->flag |= BUF_FLAG_IN_USE; + + vdec_connect(vdec); + return 0; } @@ -227,8 +362,8 @@ struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO]; if (has_hevc_vdec()) { - if (port->vformat == VFORMAT_HEVC || - port->vformat == VFORMAT_VP9) + if (port->vformat == VFORMAT_HEVC + || port->vformat == VFORMAT_VP9) pvbuf = &bufs[BUF_TYPE_HEVC]; } @@ -241,7 +376,7 @@ psparser_release(); if (port->type & PORT_TYPE_VIDEO) - video_component_release(port); + video_component_release(port, pvbuf, 0); port->pcr_inited = 0; port->flag = 0; @@ -256,6 +391,7 @@ vdec->port = &ada_ctx->port; vdec->format = ada_ctx->video_type; vdec->sys_info_store = ada_ctx->dec_prop; + vdec->vf_receiver_name = ada_ctx->recv_name; /* binding v4l2 ctx to vdec. */ vdec->private = ada_ctx->ctx; @@ -289,6 +425,7 @@ vdec->frame_base_video_path = aml_set_vfm_path; vdec->port->flag = vdec->port_flag; + ada_ctx->vfm_path = vdec->frame_base_video_path; vdec->config_len = ada_ctx->config.length > PAGE_SIZE ? PAGE_SIZE : ada_ctx->config.length; @@ -308,7 +445,6 @@ if (IS_ERR_OR_NULL(vdec)) return -1; - vdec->disable_vfm = true; set_vdec_properity(vdec, ada_ctx); /* init hw and gate*/ @@ -325,8 +461,8 @@ && (vdec->port_flag & PORT_FLAG_VFORMAT)) { vdec->port->is_4k = false; if (has_hevc_vdec()) { - if (vdec->port->vformat == VFORMAT_HEVC || - vdec->port->vformat == VFORMAT_VP9) + if (vdec->port->vformat == VFORMAT_HEVC + || vdec->port->vformat == VFORMAT_VP9) pvbuf = &bufs[BUF_TYPE_HEVC]; } @@ -390,11 +526,9 @@ if (!IS_ERR(fp)) { kernel_write(fp, data, size, 0); filp_close(fp, NULL); - } else { - pr_info("Dump ES fail, should check RW permission, size:%x\n", size); } -} +} int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx, const char *buf, unsigned int count) { @@ -445,11 +579,11 @@ { struct vdec_s *vdec = ada_ctx->vdec; - return (vdec->input.have_frame_num > 60) ? true : false; + return (vdec->input.have_frame_num > 600) ? true : false; } int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, - const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr) + const char *buf, unsigned int count, u64 timestamp) { int ret = -1; struct vdec_s *vdec = ada_ctx->vdec; @@ -457,9 +591,6 @@ /* set timestamp */ vdec_set_timestamp(vdec, timestamp); - /* set metadata */ - vdec_set_metadata(vdec, meta_ptr); - ret = vdec_write_vframe(vdec, buf, count); if (slow_input) { @@ -468,12 +599,9 @@ msleep(30); } - if (dump_output_frame > 0 && - (!dump_output_start_position || - (dump_output_start_position == crc32_le(0, buf, count)))) { + if (dump_output_frame > 0) { dump("/data/es.data", buf, count); dump_output_frame--; - dump_output_start_position = 0; } v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, @@ -530,14 +658,23 @@ int ret = 0; if (vdec) { - if (ada_ctx->ctx->v4l_resolution_change) - *mode = V4L_RESET_MODE_LIGHT; - else + if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed) vdec_set_eos(vdec, false); - + if (*mode == V4L_RESET_MODE_NORMAL && + vdec->input.have_frame_num == 0) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "no input reset mode: %d\n", *mode); + *mode = V4L_RESET_MODE_LIGHT; + } + if (ada_ctx->ctx->param_sets_from_ucode && + *mode == V4L_RESET_MODE_NORMAL && + ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) { + v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, + "resolution_changed reset mode: %d\n", *mode); + *mode = V4L_RESET_MODE_LIGHT; + } v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO, - "reset mode: %d, es frames buffering: %d\n", - *mode, vdec_frame_number(ada_ctx)); + "reset mode: %d\n", *mode); ret = vdec_v4l2_reset(vdec, *mode); *mode = V4L_RESET_MODE_NORMAL; @@ -572,11 +709,6 @@ return -1; } -int vdec_get_instance_num(void) -{ - return vdec_get_core_nr(); -} - void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len) { struct vdec_s *vdec = ada_ctx->vdec; @@ -584,8 +716,3 @@ vdec->config_len = len > PAGE_SIZE ? PAGE_SIZE : len; memcpy(vdec->config, data, vdec->config_len); } - -void vdec_set_duration(s32 duration) -{ - vdec_frame_rate_uevent(duration); -}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h index c8641ce..b86cbff 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.h +++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -27,12 +27,13 @@ #include "aml_vcodec_drv.h" struct aml_vdec_adapt { - int format; + enum vformat_e format; void *vsi; int32_t failure; uint32_t inst_addr; unsigned int signaled; struct aml_vcodec_ctx *ctx; + struct platform_device *dev; wait_queue_head_t wq; struct file *filp; struct vdec_s *vdec; @@ -40,7 +41,8 @@ struct dec_sysinfo dec_prop; struct v4l2_config_parm config; int video_type; - char *frm_name; + char *recv_name; + int vfm_path; }; int video_decoder_init(struct aml_vdec_adapt *ada_ctx); @@ -51,7 +53,7 @@ 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); + const char *buf, unsigned int count, u64 timestamp); void vdec_vframe_input_free(void *priv, u32 handle); @@ -71,9 +73,5 @@ int vdec_frame_number(struct aml_vdec_adapt *ada_ctx); -int vdec_get_instance_num(void); - -void vdec_set_duration(s32 duration); - #endif /* VDEC_ADAPT_H */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index 2bbfb6e..afebb7a 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -20,41 +20,27 @@ #include <media/v4l2-event.h> #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> -#include <media/videobuf2-dma-sg.h> - -#include <linux/delay.h> -#include <linux/atomic.h> -#include <linux/crc32.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/amlogic/meson_uvm_core.h> -#include <linux/scatterlist.h> -#include <linux/sched/clock.h> -#include <linux/highmem.h> -#include <uapi/linux/sched/types.h> #include "aml_vcodec_drv.h" #include "aml_vcodec_dec.h" +//#include "aml_vcodec_intr.h" #include "aml_vcodec_util.h" #include "vdec_drv_if.h" +#include <linux/delay.h> +#include <linux/atomic.h> +#include <linux/crc32.h> #include "aml_vcodec_adapt.h" -#include "aml_vcodec_vpp.h" -#include "aml_vcodec_ge2d.h" +#include <linux/spinlock.h> +#include "aml_vcodec_vfm.h" #include "../frame_provider/decoder/utils/decoder_bmmu_box.h" #include "../frame_provider/decoder/utils/decoder_mmu_box.h" -#include "../common/chips/decoder_cpu_ver_info.h" -#include "utils/common.h" -#include "../frame_provider/decoder/utils/vdec_sync.h" - #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2 #include <trace/events/meson_atrace.h> - -#define OUT_FMT_IDX (0) //default h264 -#define CAP_FMT_IDX (9) //capture nv21 -#define CAP_FMT_I420_IDX (12) //use for mjpeg +#define OUT_FMT_IDX 0 //default h264 +#define CAP_FMT_IDX 8 //capture nv21 #define AML_VDEC_MIN_W 64U #define AML_VDEC_MIN_H 64U @@ -63,12 +49,8 @@ #define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100) #define AML_V4L2_SET_DRMMODE (V4L2_CID_USER_AMLOGIC_BASE + 0) -#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 WORK_ITEMS_MAX (32) -#define MAX_DI_INSTANCE (2) //#define USEC_PER_SEC 1000000 @@ -80,89 +62,70 @@ static struct aml_video_fmt aml_video_formats[] = { { - .name = "H.264", .fourcc = V4L2_PIX_FMT_H264, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "H.265", .fourcc = V4L2_PIX_FMT_HEVC, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "VP9", .fourcc = V4L2_PIX_FMT_VP9, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "MPEG1", .fourcc = V4L2_PIX_FMT_MPEG1, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "MPEG2", .fourcc = V4L2_PIX_FMT_MPEG2, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "MPEG4", .fourcc = V4L2_PIX_FMT_MPEG4, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "MJPEG", .fourcc = V4L2_PIX_FMT_MJPEG, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "AV1", .fourcc = V4L2_PIX_FMT_AV1, .type = AML_FMT_DEC, .num_planes = 1, }, { - .name = "NV21", .fourcc = V4L2_PIX_FMT_NV21, .type = AML_FMT_FRAME, .num_planes = 1, }, { - .name = "NV21M", .fourcc = V4L2_PIX_FMT_NV21M, .type = AML_FMT_FRAME, .num_planes = 2, }, { - .name = "NV12", .fourcc = V4L2_PIX_FMT_NV12, .type = AML_FMT_FRAME, .num_planes = 1, }, { - .name = "NV12M", .fourcc = V4L2_PIX_FMT_NV12M, .type = AML_FMT_FRAME, .num_planes = 2, }, { - .name = "YUV420", .fourcc = V4L2_PIX_FMT_YUV420, .type = AML_FMT_FRAME, .num_planes = 1, }, - { - .name = "YUV420M", - .fourcc = V4L2_PIX_FMT_YUV420M, - .type = AML_FMT_FRAME, - .num_planes = 2, - }, }; static const struct aml_codec_framesizes aml_vdec_framesizes[] = { @@ -202,11 +165,6 @@ 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_NV21, .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, @@ -226,44 +184,16 @@ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, }, - { - .fourcc = V4L2_PIX_FMT_YUV420, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, - }, - { - .fourcc = V4L2_PIX_FMT_YUV420M, - .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2, - AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2}, - }, }; #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes) #define NUM_FORMATS ARRAY_SIZE(aml_video_formats) extern bool multiplanar; -extern int dump_capture_frame; -extern int bypass_vpp; -extern int bypass_ge2d; -extern bool support_format_I420; -extern bool support_mjpeg; -extern int bypass_progressive; -extern int force_enable_nr; -extern int force_enable_di_local_buffer; -extern int max_di_instance; -extern int bypass_nr_flag; +extern bool dump_capture_frame; 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); -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, - struct v4l2_pix_format *pix, - struct aml_q_data *q_data, - u32 type); static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx) { @@ -279,23 +209,6 @@ spin_unlock_irqrestore(&ctx->slock, flags); } -static ulong dmabuf_contiguous_size(struct sg_table *sgt) -{ - struct scatterlist *s; - dma_addr_t expected = sg_dma_address(sgt->sgl); - ulong size = 0; - u32 i; - - for_each_sg(sgt->sgl, s, sgt->nents, i) { - if (sg_dma_address(s) != expected) - break; - expected = sg_dma_address(s) + sg_dma_len(s); - size += sg_dma_len(s); - } - - return size; -} - static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f) { struct aml_video_fmt *fmt; @@ -323,6 +236,16 @@ { struct v4l2_event event = {0}; + if (ctx->receive_cmd_stop && + changes != V4L2_EVENT_SRC_CH_RESOLUTION && + changes != V4L2_EVENT_SEND_EOS) { + ctx->state = AML_STATE_ABORT; + ATRACE_COUNTER("v4l2_state", ctx->state); + changes = V4L2_EVENT_REQUEST_EXIT; + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); + } + switch (changes) { case V4L2_EVENT_SRC_CH_RESOLUTION: case V4L2_EVENT_SRC_CH_HDRINFO: @@ -354,176 +277,11 @@ aml_decoder_flush(ctx->ada_ctx); } -/* 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 - * stream size is under 2K. - * For DV, need application to notify V4L2 driver to enforce the color space - * conversion. Plan to do it through a system node. - * Do not connect VPP in other cases. - */ -static bool vpp_needed(struct aml_vcodec_ctx *ctx, u32* mode) +static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) { - int width = ctx->picinfo.coded_width; - int height = ctx->picinfo.coded_height; - int size = 1920 * 1088; + unsigned int dpbsize = 0; + int ret; - if (bypass_vpp) - return false; - - if (!ctx->vpp_cfg.enable_nr && - (ctx->picinfo.field == V4L2_FIELD_NONE)) { - return false; - } - - if (!ctx->vpp_cfg.enable_nr && - (ctx->output_pix_fmt == V4L2_PIX_FMT_HEVC)) { - if (is_over_size(width, height, size)) { - return false; - } - } - - if ((ctx->output_pix_fmt == V4L2_PIX_FMT_H264) && - (ctx->picinfo.field != V4L2_FIELD_NONE)) { - if (is_over_size(width, height, size)) { - return false; - } - } - - if (ctx->vpp_cfg.enable_nr) { - if (ctx->vpp_cfg.enable_local_buf) - *mode = VPP_MODE_NOISE_REDUC_LOCAL; - else - *mode = VPP_MODE_NOISE_REDUC; - } else { - if (ctx->vpp_cfg.enable_local_buf) - *mode = VPP_MODE_DI_LOCAL; - else - *mode = VPP_MODE_DI; - } - -#if 0//enable later - if (ctx->colorspace != V4L2_COLORSPACE_DEFAULT && - !is_over_size(width, height, size)) { - if (ctx->vpp_cfg.enable_local_buf) - *mode = VPP_MODE_COLOR_CONV_LOCAL; - else - *mode = VPP_MODE_COLOR_CONV; - } -#endif - - return true; -} - -static bool ge2d_needed(struct aml_vcodec_ctx *ctx, u32* mode) -{ - bool enable_fence = (ctx->config.parm.dec.cfg.low_latency_mode & 2) ? 1 : 0; - - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) && enable_fence) { - return false; - } - - if (bypass_ge2d) - return false; - - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_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)) { - return false; - } - } else if (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) { - return false; - } - - if (ctx->picinfo.field != V4L2_FIELD_NONE) { - 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; - - return true; -} - -static u32 v4l_buf_size_decision(struct aml_vcodec_ctx *ctx) -{ - u32 mode, total_size; - struct vdec_pic_info *picinfo = &ctx->picinfo; - struct aml_vpp_cfg_infos *vpp = &ctx->vpp_cfg; - struct aml_ge2d_cfg_infos *ge2d = &ctx->ge2d_cfg; - - if (vpp_needed(ctx, &mode)) { - vpp->mode = mode; - vpp->fmt = ctx->cap_pix_fmt; - vpp->is_drm = ctx->is_drm_mode; - vpp->buf_size = aml_v4l2_vpp_get_buf_num(vpp->mode) - + picinfo->vpp_margin; - - if (picinfo->field == V4L2_FIELD_NONE) { - vpp->is_prog = true; - vpp->buf_size = 0; - } else { - vpp->is_prog = false; - /* for between with dec & vpp. */ - picinfo->dpb_margin = 2; - } - - if (vpp->is_prog && - !vpp->enable_local_buf && - bypass_progressive) { - vpp->is_bypass_p = true; - } - ctx->vpp_is_need = true; - } else { - vpp->buf_size = 0; - ctx->vpp_is_need = false; - } - - if (ge2d_needed(ctx, &mode)) { - ge2d->mode = mode; - ge2d->buf_size = 4 + picinfo->dpb_margin; - ctx->ge2d_is_need = true; - picinfo->dpb_margin = 2; - } else { - ge2d->buf_size = 0; - ctx->ge2d_is_need = false; - } - - ctx->dpb_size = picinfo->dpb_frames + picinfo->dpb_margin; - ctx->vpp_size = vpp->buf_size; - ctx->ge2d_size = ge2d->buf_size; - - total_size = ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size; - - if (total_size > V4L_CAP_BUFF_MAX) { - if (ctx->ge2d_size) { - ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->ge2d_size - ctx->vpp_size; - } else if (ctx->vpp_size) { - ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->vpp_size; - } else { - ctx->dpb_size = V4L_CAP_BUFF_MAX; - } - picinfo->dpb_margin = ctx->dpb_size - picinfo->dpb_frames; - total_size = V4L_CAP_BUFF_MAX; - } - vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, picinfo); - - return total_size; -} - -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)) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Cannot get param : GET_PARAM_PICTURE_INFO ERR\n"); @@ -551,277 +309,287 @@ ctx->last_decoded_picinfo.coded_width, ctx->last_decoded_picinfo.coded_width); + ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); + if (dpbsize == 0) + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Incorrect dpb size, ret=%d\n", ret); + + /* update picture information */ + ctx->dpb_size = dpbsize; ctx->picinfo = ctx->last_decoded_picinfo; +} - if (ctx->vpp_is_need) - ctx->vpp_cfg.is_vpp_reset = true; +static bool aml_check_inst_quit(struct aml_vcodec_dev *dev, + struct aml_vcodec_ctx * inst, u32 id) +{ + struct aml_vcodec_ctx *ctx = NULL; + bool ret = true; - v4l_buf_size_decision(ctx); + if (dev == NULL) + return false; - 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, - ctx->picinfo.dpb_margin, - CTX_BUF_TOTAL(ctx)); + mutex_lock(&dev->dev_mutex); + + if (list_empty(&dev->ctx_list)) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "v4l inst list is empty.\n"); + ret = true; + goto out; + } + + list_for_each_entry(ctx, &dev->ctx_list, list) { + if ((ctx == inst) && (ctx->id == id)) { + ret = ctx->receive_cmd_stop ? true : false; + goto out; + } + } +out: + mutex_unlock(&dev->dev_mutex); + + return ret; } void vdec_frame_buffer_release(void *data) { struct file_private_data *priv_data = (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_vcodec_dev *dev = (struct aml_vcodec_dev *) priv_data->vb_handle; - struct uvm_hook_mod_info *uvm = NULL; + struct aml_vcodec_ctx *inst = (struct aml_vcodec_ctx *) + priv_data->v4l_dec_ctx; + u32 id = priv_data->v4l_inst_id; - if (ctx && ctx->uvm_proxy) { - uvm = &ctx->uvm_proxy[vb->internal_index]; - uvm->free(uvm->arg); + if (aml_check_inst_quit(dev, inst, id)) { + struct vframe_s *vf = &priv_data->vf; + + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, + "[%d]: vf idx: %d, bmmu idx: %d, bmmu_box: %lx\n", + id, vf->index, vf->mm_box.bmmu_idx, + (ulong) vf->mm_box.bmmu_box); + + v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR, + "[%d]: vf idx: %d, mmu_idx: %d, mmu_box: %lx\n", + id, vf->index, vf->mm_box.mmu_idx, + (ulong) vf->mm_box.mmu_box); + + if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) { + decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box, + vf->mm_box.bmmu_idx); + decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box); + } + + if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) { + decoder_mmu_box_free_idx(vf->mm_box.mmu_box, + vf->mm_box.mmu_idx); + decoder_mmu_try_to_release_box(vf->mm_box.mmu_box); + } + } memset(data, 0, sizeof(struct file_private_data)); kfree(data); } -static void v4l2_buff_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) +int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb) { - struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(buf->vb2_buf.vb2_queue); - - mutex_lock(&ctx->buff_done_lock); - if (buf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "vb is not active state = %d!\n", - buf->vb2_buf.state); - mutex_unlock(&ctx->buff_done_lock); - return; - } - v4l2_m2m_buf_done(buf, state); - mutex_unlock(&ctx->buff_done_lock); -} - -static void comp_buf_set_vframe(struct aml_vcodec_ctx *ctx, - struct vb2_buffer *vb, - struct vframe_s *vf) -{ - dmabuf_set_vframe(vb->planes[0].dbuf, vf, VF_SRC_DECODER); -} - -static void fb_map_table_clean(struct aml_vcodec_ctx *ctx) -{ - int i; ulong flags; + struct vb2_buffer *dst_buf = NULL; + struct vdec_v4l2_buffer *pfb; + struct aml_video_dec_buf *dst_buf_info, *info; + struct vb2_v4l2_buffer *dst_vb2_v4l2; 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 (ctx->state == AML_STATE_ABORT) { + aml_vcodec_ctx_unlock(ctx, flags); + return -1; } - aml_vcodec_ctx_unlock(ctx, flags); - - 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; - } + dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + if (!dst_buf) { + aml_vcodec_ctx_unlock(ctx, flags); + return -1; } - aml_vcodec_ctx_unlock(ctx, flags); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "vbuf idx: %d, state: %d, ready: %d\n", + dst_buf->index, dst_buf->state, + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)); - 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); - } -} + dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); + dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb); -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) -{ - 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 (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; - } - } - - aml_vcodec_ctx_unlock(ctx, flags); - - if (i >= ARRAY_SIZE(ctx->fb_map)) { + pfb = &dst_buf_info->frame_buffer; + pfb->buf_idx = dst_buf->index; + pfb->num_planes = dst_buf->num_planes; + pfb->status = FB_ST_NORMAL; + if (dst_buf->num_planes == 1) { + pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr); + pfb->m.mem[0].size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz; + pfb->m.mem[0].offset = ctx->picinfo.y_len_sz; v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, - "%s, there is new addr:%lx.\n", - __func__, addr); + "idx: %u, 1 plane, y:(0x%lx, %d)\n", dst_buf->index, + pfb->m.mem[0].addr, pfb->m.mem[0].size); + } else if (dst_buf->num_planes == 2) { + pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr); + pfb->m.mem[0].size = ctx->picinfo.y_len_sz; + pfb->m.mem[0].offset = 0; + + pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1); + pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr); + pfb->m.mem[1].size = ctx->picinfo.c_len_sz; + pfb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1; + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)\n", dst_buf->index, + pfb->m.mem[0].addr, pfb->m.mem[0].size, + pfb->m.mem[1].addr, pfb->m.mem[1].size); + } else { + pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr); + pfb->m.mem[0].size = ctx->picinfo.y_len_sz; + pfb->m.mem[0].offset = 0; + + pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1); + pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[2].dma_addr); + pfb->m.mem[1].size = ctx->picinfo.c_len_sz >> 1; + pfb->m.mem[1].offset = 0; + + pfb->m.mem[2].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 2); + pfb->m.mem[2].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr); + pfb->m.mem[2].size = ctx->picinfo.c_len_sz >> 1; + pfb->m.mem[2].offset = 0; + + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)\n", + dst_buf->index, + pfb->m.mem[0].addr, pfb->m.mem[0].size, + pfb->m.mem[1].addr, pfb->m.mem[1].size, + pfb->m.mem[2].addr, pfb->m.mem[2].size); } -} -static bool is_fb_mapped(struct aml_vcodec_ctx *ctx, ulong addr) -{ - int i; - ulong flags; + dst_buf_info->used = true; + ctx->buf_used_count++; - flags = aml_vcodec_ctx_lock(ctx); + *out_fb = pfb; - for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) { - if (addr == ctx->fb_map[i].addr) - break; - } + info = container_of(pfb, struct aml_video_dec_buf, frame_buffer); + + ctx->cap_pool.dec++; + ctx->cap_pool.seq[ctx->cap_pool.out++] = + (V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index); + v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 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 0; +} +EXPORT_SYMBOL(get_fb_from_queue); + +int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb) +{ + struct aml_video_dec_buf *dstbuf; + + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); + + if (in_fb == NULL) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "No free frame buffer\n"); + return -1; } - return true; + dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer); + + mutex_lock(&ctx->lock); + + if (!dstbuf->used) + goto out; + + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "status=%x queue id=%d to rdy_queue\n", + in_fb->status, dstbuf->vb.vb2_buf.index); + + v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb); + + dstbuf->used = false; +out: + mutex_unlock(&ctx->lock); + + return 0; + } +EXPORT_SYMBOL(put_fb_to_queue); - static void post_frame_to_upper(struct aml_vcodec_ctx *ctx, - struct vdec_v4l2_buffer *fb) +void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb) { - 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; - - vf->index_disp = ctx->index_disp; - ctx->index_disp++; - ctx->post_to_upper_done = false; + struct aml_video_dec_buf *dstbuf = NULL; + struct vb2_buffer *vb2_buf = NULL; + struct vframe_s *vf = (struct vframe_s *)fb->vf_handle; v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT, - "OUT_BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, " + "FROM (%s %s) vf: %lx, ts: %llu, idx: %d, " "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n", - ctx->ada_ctx->frm_name, fb->status, vf->index_disp, - vb2_buf->index, vb2_buf, - vf->index & 0xff, vf, - vf->timestamp, + vf_get_provider(ctx->ada_ctx->recv_name)->name, + ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO", + (ulong) vf, vf->timestamp, vf->index, 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); - vb2_v4l2 = container_of(vb2_buf, struct vb2_v4l2_buffer, vb2_buf); + dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer); + vb2_buf = &dstbuf->vb.vb2_buf; if (dstbuf->frame_buffer.num_planes == 1) { - vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used); + vb2_set_plane_payload(&dstbuf->vb.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); + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used); + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->m.mem[1].bytes_used); } - vb2_buf->timestamp = vf->timestamp; - dstbuf->vb.flags |= vf->frame_type; + dstbuf->vb.vb2_buf.timestamp = vf->timestamp; + dstbuf->ready_to_display = true; - if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) { - vb2_v4l2->field = V4L2_FIELD_INTERLACED; - } - - do { - unsigned int dw_mode = VDEC_DW_NO_AFBC; + if (dump_capture_frame) { struct file *fp; - char file_name[32] = {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) - break; - - snprintf(file_name, 32, "/data/dec_dump_%ux%u.raw", vf->width, vf->height); - - fp = filp_open(file_name, + fp = filp_open("/data/dec_dump.raw", O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600); - if (!IS_ERR(fp)) { - struct vb2_buffer *vb = vb2_buf; - - kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0); + struct vb2_buffer *vb = &dstbuf->vb.vb2_buf; + kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].bytesused, 0); if (dstbuf->frame_buffer.num_planes == 2) kernel_write(fp,vb2_plane_vaddr(vb, 1), - vb->planes[1].length, 0); + vb->planes[1].bytesused, 0); pr_info("dump idx: %d %dx%d\n", dump_capture_frame, vf->width, vf->height); - dump_capture_frame--; + dump_capture_frame = false; filp_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)); + } if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { dstbuf->vb.flags = V4L2_BUF_FLAG_LAST; if (dstbuf->frame_buffer.num_planes == 1) { - vb2_set_plane_payload(vb2_buf, 0, 0); + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0); } else if (dstbuf->frame_buffer.num_planes == 2) { - vb2_set_plane_payload(vb2_buf, 0, 0); - vb2_set_plane_payload(vb2_buf, 1, 0); + vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0); + vb2_set_plane_payload(&dstbuf->vb.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", - vb2_buf->index, vb2_buf->state); + dstbuf->vb.vb2_buf.index, + dstbuf->vb.vb2_buf.state); + ATRACE_COUNTER("v4l2_eos", 0); } v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "receive vbuf idx: %d, state: %d\n", - vb2_buf->index, vb2_buf->state); + dstbuf->vb.vb2_buf.index, + dstbuf->vb.vb2_buf.state); if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) { - if (ctx->v4l_resolution_change) { + if (ctx->q_data[AML_Q_DATA_SRC].resolution_changed) { /* make the run to stanby until new buffs to enque. */ ctx->v4l_codec_dpb_ready = false; ctx->reset_flag = V4L_RESET_MODE_LIGHT; - ctx->vpp_cfg.res_chg = true; /* * After all buffers containing decoded frames from @@ -838,449 +606,50 @@ 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; - } - - vf->omx_index = vf->index_disp; + vf->flag |= VFRAME_FLAG_VIDEO_LINEAR; + ATRACE_COUNTER("v4l2_from", vf->index_disp); dstbuf->privdata.vf = *vf; + dstbuf->privdata.vf.omx_index = + dstbuf->vb.vb2_buf.index; - if (vb2_buf->memory == VB2_MEMORY_DMABUF) { - struct dma_buf * dma; - - 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; + v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE); } 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); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_FLUSHED)\n"); } mutex_unlock(&ctx->state_lock); - if (ctx->post_to_upper_done == false) { - ctx->post_to_upper_done = true; - wake_up_interruptible(&ctx->post_done_wq); - } - ctx->decoded_frame_cnt++; } -static void fill_capture_done_cb(void *v4l_ctx, void *fb_ctx) +static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out) { - 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; + int ret = -1; - if (ctx->is_stream_off) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, - "ignore buff idx: %d streamoff\n", fb->buf_idx); - return; - } + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); - ATRACE_COUNTER("VC_OUT_VSINK-0.receive", 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)) { + ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out); + if (ret) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "%s, table is full. token:%lx\n", - __func__, vb_handle); - return false; + "Cannot get param : GET_PARAM_DISP_FRAME_BUFFER\n"); + return -1; } - *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)) { + if (!*out) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "%s, remove token err, token:%lx.\n", - __func__, token); + "No display frame buffer\n"); + return -1; } -} - -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); - } -} - -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) -{ - struct task_chain_s *task = fb->task; - /* - * line 1: dec <==> vpp <==> v4l-sink, for P / P + DI.NR. - * line 2: dec <==> vpp, vpp <==> v4l-sink, for I / I + DI.NR. - * line 3: dec <==> v4l-sink, only for P. - * line 4: dec <==> ge2d, ge2d <==> v4l-sink, used for fmt convert. - * line 5: dec <==> ge2d, ge2d <==>vpp, vpp <==> v4l-sink. - * line 6: dec <==> ge2d, ge2d <==> vpp <==> v4l-sink. - */ - - switch (requester) { - case AML_FB_REQ_DEC: - if (ctx->ge2d) { - /* dec <==> ge2d. */ - task->attach(task, get_ge2d_ops(), ctx->ge2d); - } else if (ctx->vpp) { - if (ctx->vpp->is_prog) { - /* dec <==> vpp <==> v4l-sink. */ - task->attach(task, get_v4l_sink_ops(), ctx); - task->attach(task, get_vpp_ops(), ctx->vpp); - } else { - /* dec <==> vpp. */ - task->attach(task, get_vpp_ops(), ctx->vpp); - } - } else { - /* dec <==> v4l-sink. */ - task->attach(task, get_v4l_sink_ops(), ctx); - } - break; - - case AML_FB_REQ_GE2D: - if (ctx->vpp) { - if (ctx->vpp->is_prog) { - /* ge2d <==> vpp <==> v4l-sink. */ - task->attach(task, get_v4l_sink_ops(), ctx); - task->attach(task, get_vpp_ops(), ctx->vpp); - task->attach(task, get_ge2d_ops(), ctx->ge2d); - } else { - /* ge2d <==> vpp. */ - task->attach(task, get_vpp_ops(), ctx->vpp); - task->attach(task, get_ge2d_ops(), ctx->ge2d); - } - } else { - /* ge2d <==> v4l-sink. */ - task->attach(task, get_v4l_sink_ops(), ctx); - task->attach(task, get_ge2d_ops(), ctx->ge2d); - } - break; - - case AML_FB_REQ_VPP: - /* vpp <==> v4l-sink. */ - task->attach(task, get_v4l_sink_ops(), ctx); - task->attach(task, get_vpp_ops(), ctx->vpp); - break; - - default: - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "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) -{ - 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; - - flags = aml_vcodec_ctx_lock(ctx); - - if (ctx->is_stream_off) { - aml_vcodec_ctx_unlock(ctx, flags); - return -1; - } - - v4l_buf = (struct vb2_v4l2_buffer *) token; - if (!v4l_buf) { - aml_vcodec_ctx_unlock(ctx, flags); - return -1; - } - - 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); - - 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; -} - -static struct task_ops_s v4l_sink_ops = { - .type = TASK_TYPE_V4L_SINK, - .fill_buffer = fill_capture_done_cb, -}; - -static struct task_ops_s *get_v4l_sink_ops(void) -{ - return &v4l_sink_ops; -} - -void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx) -{ - struct aml_q_data *outq = NULL; - struct aml_q_data *capq = NULL; - struct vdec_pic_info pic; - - 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); - 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", - 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", - 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, - 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); -} - -void aml_buffer_status(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 vb2_queue *q = NULL; - ulong flags; - int i; - - flags = aml_vcodec_ctx_lock(ctx); - - q = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!q->streaming) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "can't achieve buffers status before start streaming.\n"); - } - - 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); - } - - aml_vcodec_ctx_unlock(ctx, flags); -} - static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx) { if (!ctx->v4l_codec_dpb_ready) { @@ -1291,26 +660,12 @@ ctx->v4l_codec_dpb_ready = true; 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), + "dpb: %d, ready: %d, used: %d, dpb is ready: %s\n", + ctx->dpb_size, v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no"); } } -static void reconfig_vpp_status(struct aml_vcodec_ctx *ctx) -{ - if (bypass_nr_flag && - !ctx->vpp_cfg.is_prog && - ((ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC_LOCAL) || - (ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC))) { - ctx->vpp_cfg.enable_nr = 0; - ctx->vpp_cfg.enable_local_buf = 0; - - ctx->vpp_cfg.mode = VPP_MODE_DI; - } -} - static int is_vdec_ready(struct aml_vcodec_ctx *ctx) { struct aml_vcodec_dev *dev = ctx->dev; @@ -1326,7 +681,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); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_READY)\n"); } @@ -1338,7 +693,7 @@ 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); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_ACTIVE)\n"); } @@ -1363,7 +718,7 @@ return true; } -static void aml_wait_buf_ready(struct aml_vcodec_ctx *ctx) +static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx) { ulong expires; @@ -1378,75 +733,34 @@ } ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - if ((ready_num + ctx->buf_used_count) >= CTX_BUF_TOTAL(ctx)) + if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size) 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); - struct vb2_v4l2_buffer *vb = NULL; - struct aml_video_dec_buf *buf = NULL; - unsigned long flags; - - 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); - - buf = container_of(vb, struct aml_video_dec_buf, vb); - - if (ctx->is_out_stream_off) - continue; - - 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"); - } - - 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); - } -} - void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle) { - struct aml_vcodec_dev *dev = ctx->dev; - struct vb2_v4l2_buffer *vb = NULL; - struct vb2_queue *q = NULL; + struct vb2_v4l2_buffer *vb; + struct aml_video_dec_buf *buf; + struct vb2_queue *q; int index = handle & 0xf; - unsigned long flags; if (ctx->is_out_stream_off) { v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, "ignore buff idx: %d streamoff\n", index); return; } - q = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); vb = to_vb2_v4l2_buffer(q->bufs[index]); + buf = container_of(vb, struct aml_video_dec_buf, vb); + v4l2_m2m_buf_done(vb, buf->error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_DONE); - 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); + v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, + "recycle buff idx: %d, vbuf: %lx\n", index, + (ulong)vb2_dma_contig_plane_dma_addr(q->bufs[index], 0)); } static void aml_vdec_worker(struct work_struct *work) @@ -1454,12 +768,12 @@ struct aml_vcodec_ctx *ctx = container_of(work, struct aml_vcodec_ctx, decode_work); struct aml_vcodec_dev *dev = ctx->dev; - struct aml_video_dec_buf *aml_buf; - struct vb2_v4l2_buffer *vb2_v4l2; - struct vb2_buffer *vb; + struct vb2_buffer *src_buf; struct aml_vcodec_mem buf; bool res_chg = false; int ret; + struct aml_video_dec_buf *src_buf_info; + struct vb2_v4l2_buffer *src_vb2_v4l2; if (ctx->state < AML_STATE_INIT || ctx->state > AML_STATE_FLUSHED) { @@ -1473,23 +787,21 @@ goto out; } - vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx); - if (vb2_v4l2 == NULL) { + src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); + if (src_buf == NULL) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "src_buf empty.\n"); goto out; } - 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; + src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf); + src_buf_info = container_of(src_vb2_v4l2, struct aml_video_dec_buf, vb); + if (src_buf_info->lastframe) { /*the empty data use to flushed the decoder.*/ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "Got empty flush input buffer.\n"); @@ -1497,34 +809,22 @@ /* * 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); + if (!ctx->v4l_codec_dpb_ready) { + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + goto out; } 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); + ATRACE_COUNTER("v4l2_state", 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); + src_buf = 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. */ @@ -1533,22 +833,21 @@ goto out; } - 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; - buf.model = vb->memory; - buf.timestamp = vb->timestamp; - buf.meta_ptr = (ulong)aml_buf->meta_data; + buf.index = src_buf->index; + buf.vaddr = vb2_plane_vaddr(src_buf, 0); + buf.addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); + buf.size = src_buf->planes[0].bytesused; + buf.model = src_buf->memory; + buf.timestamp = src_buf->timestamp; if (!buf.vaddr && !buf.addr) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "id=%d src_addr is NULL.\n", vb->index); + "id=%d src_addr is NULL.\n", src_buf->index); goto out; } - aml_buf->used = true; + src_buf_info->used = true; /* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "size: 0x%zx, crc: 0x%x\n", @@ -1558,52 +857,29 @@ /*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); - } else { - ATRACE_COUNTER("VO_IN_VSINK-2.write", buf.size); - } - - ATRACE_COUNTER("V_ST_VSINK-input_buffering", 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, - VB2_BUF_STATE_DONE); - } + if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF)) + v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); } else if (ret && ret != -EAGAIN) { - aml_buf->used = false; + src_buf_info->error = (ret == -EIO ? true : 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, - VB2_BUF_STATE_ERROR); - } + if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF)) + v4l2_m2m_buf_done(&src_buf_info->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_wait_dpb_ready(ctx); - aml_buf->used = false; + src_buf_info->used = false; aml_vdec_pic_info_update(ctx); /* * On encountering a resolution change in the stream. @@ -1614,13 +890,13 @@ 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); + ATRACE_COUNTER("v4l2_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; + ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true; while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) { v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); } @@ -1629,10 +905,8 @@ 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); + usleep_range(50000, 55000); } v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); @@ -1650,10 +924,28 @@ if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) { ctx->state = AML_STATE_ABORT; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_ABORT).\n"); + goto out; } + + if (ctx->state == AML_STATE_RESET) { + ctx->state = AML_STATE_PROBE; + ATRACE_COUNTER("v4l2_state", ctx->state); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_PROBE)\n"); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "dpb: %d, ready: %d, used: %d\n", ctx->dpb_size, + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), + ctx->buf_used_count); + + /* vdec has ready to decode subsequence data of new resolution. */ + ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false; + v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx); + } + out: complete(&ctx->comp); return; @@ -1661,13 +953,13 @@ void wait_vcodec_ending(struct aml_vcodec_ctx *ctx) { + struct aml_vcodec_dev *dev = ctx->dev; + /* disable queue output item to worker. */ ctx->output_thread_ready = false; - ctx->is_stream_off = true; /* flush output buffer worker. */ - cancel_work_sync(&ctx->decode_work); - cancel_work_sync(&ctx->dmabuff_recycle_work); + flush_workqueue(dev->decode_workqueue); /* clean output cache and decoder status . */ if (ctx->state > AML_STATE_INIT) @@ -1681,38 +973,33 @@ ctx->v4l_codec_dpb_ready = false; } -void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx) +void try_to_capture(struct aml_vcodec_ctx *ctx) { - struct vb2_v4l2_buffer *vb = NULL; - struct aml_video_dec_buf *aml_buff = NULL; + int ret = 0; struct vdec_v4l2_buffer *fb = NULL; - for (;;) { - mutex_lock(&ctx->capture_buffer_lock); - if (!kfifo_get(&ctx->capture_buffer, &vb)) { - mutex_unlock(&ctx->capture_buffer_lock); - break; - } - mutex_unlock(&ctx->capture_buffer_lock); - - aml_buff = container_of(vb, struct aml_video_dec_buf, vb); - fb = &aml_buff->frame_buffer; - - if (ctx->is_stream_off) - continue; - - post_frame_to_upper(ctx, fb); + ret = get_display_buffer(ctx, &fb); + if (ret) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "the que have no disp buf,ret: %d\n", ret); + return; } -} -EXPORT_SYMBOL_GPL(aml_thread_capture_worker); -static int vdec_capture_thread(void *data) + trans_vframe_to_user(ctx, fb); +} +EXPORT_SYMBOL_GPL(try_to_capture); + +static int vdec_thread(void *data) { + struct sched_param param = + {.sched_priority = MAX_RT_PRIO / 2}; struct aml_vdec_thread *thread = (struct aml_vdec_thread *) data; struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *) thread->priv; + sched_setscheduler(current, SCHED_FIFO, ¶m); + for (;;) { v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s, state: %d\n", __func__, ctx->state); @@ -1728,19 +1015,19 @@ } while (!kthread_should_stop()) { - usleep_range(1000, 2000); + set_current_state(TASK_INTERRUPTIBLE); + schedule(); } return 0; } -void aml_thread_post_task(struct aml_vcodec_ctx *ctx, +void aml_thread_notify(struct aml_vcodec_ctx *ctx, enum aml_thread_type type) { struct aml_vdec_thread *thread = NULL; - ulong flags; - spin_lock_irqsave(&ctx->tsplock, flags); + mutex_lock(&ctx->lock); list_for_each_entry(thread, &ctx->vdec_thread_list, node) { if (thread->task == NULL) continue; @@ -1748,9 +1035,9 @@ if (thread->type == type) up(&thread->sem); } - spin_unlock_irqrestore(&ctx->tsplock, flags); + mutex_unlock(&ctx->lock); } -EXPORT_SYMBOL_GPL(aml_thread_post_task); +EXPORT_SYMBOL_GPL(aml_thread_notify); int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func, enum aml_thread_type type, const char *thread_name) @@ -1768,7 +1055,7 @@ thread->priv = ctx; sema_init(&thread->sem, 0); - thread->task = kthread_run(vdec_capture_thread, thread, "aml-%s-%d", thread_name, ctx->id); + thread->task = kthread_run(vdec_thread, thread, "aml-%s", thread_name); if (IS_ERR(thread->task)) { ret = PTR_ERR(thread->task); thread->task = NULL; @@ -1776,10 +1063,6 @@ } sched_setscheduler_nocheck(thread->task, SCHED_FIFO, ¶m); - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "%s, policy is:%d priority is:%d\n", - __func__, thread->task->policy, thread->task->rt_priority); - list_add(&thread->node, &ctx->vdec_thread_list); return 0; @@ -1794,14 +1077,13 @@ void aml_thread_stop(struct aml_vcodec_ctx *ctx) { struct aml_vdec_thread *thread = NULL; - ulong flags; while (!list_empty(&ctx->vdec_thread_list)) { thread = list_entry(ctx->vdec_thread_list.next, struct aml_vdec_thread, node); - spin_lock_irqsave(&ctx->tsplock, flags); + mutex_lock(&ctx->lock); list_del(&thread->node); - spin_unlock_irqrestore(&ctx->tsplock, flags); + mutex_unlock(&ctx->lock); thread->stop = true; up(&thread->sem); @@ -1823,17 +1105,7 @@ switch (cmd->cmd) { case V4L2_DEC_CMD_STOP: case V4L2_DEC_CMD_START: - if (cmd->cmd == V4L2_DEC_CMD_START) { - if (cmd->start.speed == ~0) - cmd->start.speed = 0; - if (cmd->start.format == ~0) - cmd->start.format = 0; - } - - if (cmd->flags == ~0) - cmd->flags = 0; - - if ((cmd->flags != 0) && (cmd->flags != ~0)) { + if (cmd->flags != 0) { v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "cmd->flags=%u\n", cmd->flags); return -EINVAL; @@ -1862,6 +1134,19 @@ switch (cmd->cmd) { case V4L2_DEC_CMD_STOP: + ATRACE_COUNTER("v4l2_stop", 0); + if (ctx->state != AML_STATE_ACTIVE) { + if (ctx->state >= AML_STATE_IDLE && + ctx->state < AML_STATE_PROBE) { + ctx->state = AML_STATE_ABORT; + ATRACE_COUNTER("v4l2_state", ctx->state); + aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT); + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_ABORT)\n"); + return 0; + } + } + src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!vb2_is_streaming(src_vq)) { @@ -1870,32 +1155,18 @@ 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; - } - /* flush pipeline */ v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb); v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention ctx->receive_cmd_stop = true; - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "%s, receive cmd stop and prepare flush pipeline.\n", __func__); break; case V4L2_DEC_CMD_START: + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "CMD V4L2_DEC_CMD_START\n"); dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE); vb2_clear_last_buffer_dequeued(dst_vq);//pay attention - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "%s, receive cmd start.\n", __func__); break; default: @@ -1905,20 +1176,6 @@ return 0; } -static void aml_wait_resource(struct aml_vcodec_ctx *ctx) -{ - ulong expires = jiffies + msecs_to_jiffies(1000); - - while (atomic_read(&ctx->dev->vpp_count) >= max_di_instance) { - if (time_after(jiffies, expires)) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "wait resource timeout.\n"); - break; - } - usleep_range(2000, 4000); - } -} - static int vidioc_decoder_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { @@ -1927,80 +1184,26 @@ struct vb2_queue *q; q = v4l2_m2m_get_vq(fh->m2m_ctx, i); - if (!V4L2_TYPE_IS_OUTPUT(q->type) && - ctx->is_stream_off) { - if (ctx->vpp_is_need) { - int ret; + if (!V4L2_TYPE_IS_OUTPUT(q->type)) { + if (ctx->is_stream_off) { + mutex_lock(&ctx->state_lock); + if ((ctx->state == AML_STATE_ACTIVE || + ctx->state == AML_STATE_FLUSHING || + ctx->state == AML_STATE_FLUSHED) || + (ctx->reset_flag == V4L_RESET_MODE_LIGHT)) { + ctx->state = AML_STATE_RESET; + ATRACE_COUNTER("v4l2_state", ctx->state); + ctx->v4l_codec_dpb_ready = false; - if (ctx->vpp_cfg.fmt == 0) - ctx->vpp_cfg.fmt = ctx->cap_pix_fmt; - - if (ctx->vpp == NULL) - aml_wait_resource(ctx); - - if ((atomic_read(&ctx->dev->vpp_count) < max_di_instance) || - (ctx->vpp != NULL)) { - if (ctx->vpp && ctx->vpp_cfg.is_vpp_reset && - (ctx->vpp->is_prog == ctx->vpp_cfg.is_prog) && - (ctx->vpp->is_bypass_p == ctx->vpp_cfg.is_bypass_p) && - (ctx->vpp->work_mode == ctx->vpp_cfg.mode)) { - aml_v4l2_vpp_reset(ctx->vpp); - } else { - if (ctx->vpp) { - atomic_dec(&ctx->dev->vpp_count); - aml_v4l2_vpp_destroy(ctx->vpp); - ctx->vpp = NULL; - } - - ret = aml_v4l2_vpp_init(ctx, &ctx->vpp_cfg, &ctx->vpp); - if (ret) { - 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, - "vpp_wrapper instance count: %d\n", - atomic_read(&ctx->dev->vpp_count)); - } - } else { - ctx->vpp_cfg.enable_local_buf = 0; - ctx->vpp_cfg.enable_nr = 0; - ctx->picinfo.dpb_margin += ctx->vpp_size; - ctx->dpb_size = ctx->picinfo.dpb_margin + ctx->picinfo.dpb_frames; - ctx->vpp_size = 0; - vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo); - ctx->vpp_is_need = false; + v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, + "vcodec state (AML_STATE_RESET)\n"); + aml_vdec_reset(ctx); } - ctx->vpp_cfg.is_vpp_reset = false; - } else { - if (ctx->vpp) { - atomic_dec(&ctx->dev->vpp_count); - aml_v4l2_vpp_destroy(ctx->vpp); - ctx->vpp = NULL; - } + mutex_unlock(&ctx->state_lock); + + ctx->is_stream_off = false; + ctx->v4l_resolution_change = false; } - - 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 ctx->is_out_stream_off = false; @@ -2016,26 +1219,12 @@ struct v4l2_fh *fh = file->private_data; struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); struct vb2_queue *q; - ulong flags; q = v4l2_m2m_get_vq(fh->m2m_ctx, i); - - flags = aml_vcodec_ctx_lock(ctx); - - if (V4L2_TYPE_IS_OUTPUT(q->type)) - ctx->is_out_stream_off = true; - else + if (!V4L2_TYPE_IS_OUTPUT(q->type)) ctx->is_stream_off = true; - - aml_vcodec_ctx_unlock(ctx, flags); - - if (!V4L2_TYPE_IS_OUTPUT(q->type)) { - if (ctx->vpp) { - reconfig_vpp_status(ctx); - } - } else { - ctx->index_disp = 0; - } + else + ctx->is_out_stream_off = true; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", __func__, q->type); @@ -2052,38 +1241,19 @@ q = v4l2_m2m_get_vq(fh->m2m_ctx, rb->type); - if (!rb->count) { - if (!V4L2_TYPE_IS_OUTPUT(rb->type)) { - if (wait_event_interruptible_timeout - (ctx->post_done_wq, ctx->post_to_upper_done == true, - msecs_to_jiffies(200)) == 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "wait post frame to upper finish timeout.\n"); - } - } + if (!rb->count) vb2_queue_release(q); - } v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, count: %d\n", __func__, q->type, rb->count); if (!V4L2_TYPE_IS_OUTPUT(rb->type)) { - /* driver needs match v4l buffer number with total size*/ - if (rb->count > CTX_BUF_TOTAL(ctx)) { + /* driver needs match v4l buffer number with dpb_size */ + if (rb->count > ctx->dpb_size) { v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "reqbufs (st:%d) %d -> %d\n", - ctx->state, rb->count, CTX_BUF_TOTAL(ctx)); - ctx->picinfo.dpb_margin += (rb->count - CTX_BUF_TOTAL(ctx)); - ctx->dpb_size = ctx->picinfo.dpb_frames + ctx->picinfo.dpb_margin; - vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo); - v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, - "%s buf updated, dec: %d (%d + %d), vpp %d\n", - __func__, - ctx->dpb_size, - ctx->picinfo.dpb_frames, - ctx->picinfo.dpb_margin, - ctx->vpp_size); + ctx->state, rb->count, ctx->dpb_size); //rb->count = ctx->dpb_size; } } else { @@ -2123,12 +1293,9 @@ { ulong flags; - if (kref_read(&ctx->box_ref)) - kref_put(&ctx->box_ref, box_release); - flags = aml_vcodec_ctx_lock(ctx); ctx->state = AML_STATE_ABORT; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_ABORT)\n"); aml_vcodec_ctx_unlock(ctx, flags); @@ -2154,8 +1321,6 @@ memset(q_data, 0, sizeof(struct aml_q_data)); q_data->visible_width = DFT_CFG_WIDTH; q_data->visible_height = DFT_CFG_HEIGHT; - q_data->coded_width = DFT_CFG_WIDTH; - q_data->coded_height = DFT_CFG_HEIGHT; q_data->fmt = &aml_video_formats[OUT_FMT_IDX]; q_data->field = V4L2_FIELD_NONE; @@ -2169,9 +1334,6 @@ q_data->coded_width = DFT_CFG_WIDTH; q_data->coded_height = DFT_CFG_HEIGHT; q_data->fmt = &aml_video_formats[CAP_FMT_IDX]; - if (support_format_I420) - q_data->fmt = &aml_video_formats[CAP_FMT_I420_IDX]; - q_data->field = V4L2_FIELD_NONE; v4l_bound_align_image(&q_data->coded_width, @@ -2187,11 +1349,8 @@ q_data->bytesperline[1] = q_data->coded_width; ctx->reset_flag = V4L_RESET_MODE_NORMAL; - ctx->fb_ops.query = fb_buff_query; - ctx->fb_ops.alloc = fb_buff_from_queue; - ctx->state = AML_STATE_IDLE; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_IDLE)\n"); } @@ -2215,24 +1374,11 @@ ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 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); - else - ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->m.planes[0].bytesused); - } else { - if (ret == -EAGAIN) - ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->length); - else - ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->length); - } - } else { if (ret == -EAGAIN) - ATRACE_COUNTER("VC_IN_VSINK-1.que_again", buf->index); + ATRACE_COUNTER("v4l2_qbuf_eagain", 0); else - ATRACE_COUNTER("VC_IN_VSINK-0.que", buf->index); + ATRACE_COUNTER("v4l2_qbuf_ok", 0); } - return ret; } @@ -2254,47 +1400,39 @@ } ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); + if (V4L2_TYPE_IS_OUTPUT(buf->type)) { + if (ret == -EAGAIN) + ATRACE_COUNTER("v4l2_dqin_eagain", 0); + else + ATRACE_COUNTER("v4l2_dqin_ok", 0); + } else { + if (ret == -EAGAIN) + ATRACE_COUNTER("v4l2_dqout_eagain", 0); + } + 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.vb_handle = (ulong) ctx->dev; aml_buf->privdata.v4l_dec_ctx = (ulong) ctx; + aml_buf->privdata.v4l_inst_id = ctx->id; file = fget(vb2_v4l2->private); - if (file && is_v4l2_buf_file(file)) { + if (is_v4l2_buf_file(file)) { dmabuf_fd_install_data(vb2_v4l2->private, (void*)&aml_buf->privdata, sizeof(struct file_private_data)); + ATRACE_COUNTER("v4l2_dqout_ok", aml_buf->privdata.vf.index_disp); 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); - else - ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->m.planes[0].bytesused); - } else { - if (ret == -EAGAIN) - ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->length); - else - ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->length); - } - } else { - if (ret == -EAGAIN) - ATRACE_COUNTER("VC_OUT_VSINK-3.deque_again", buf->index); - else - ATRACE_COUNTER("VC_OUT_VSINK-2.deque", buf->index); + fput(file); } return ret; @@ -2304,12 +1442,10 @@ struct v4l2_capability *cap) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); - struct video_device *vfd_dec = video_devdata(file); strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver)); strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info)); strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card)); - cap->device_caps = vfd_dec->device_caps; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, %s\n", __func__, cap->card); @@ -2347,154 +1483,115 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt) { + struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; int i; - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct v4l2_pix_format *pix = &f->fmt.pix; - if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) { - if (V4L2_TYPE_IS_OUTPUT(f->type)) { - pix_mp->num_planes = 1; - pix_mp->plane_fmt[0].bytesperline = 0; + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + pix_fmt_mp->num_planes = 1; + pix_fmt_mp->plane_fmt[0].bytesperline = 0; + if (pix_fmt_mp->pixelformat != V4L2_PIX_FMT_MPEG2 && + pix_fmt_mp->pixelformat != V4L2_PIX_FMT_H264) + pix_fmt_mp->field = V4L2_FIELD_NONE; + else if (pix_fmt_mp->field != V4L2_FIELD_NONE) + pr_info("%s, field: %u, fmt: %u\n", + __func__, pix_fmt_mp->field, + pix_fmt_mp->pixelformat); + } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) { + int tmp_w, tmp_h; - if ((pix_mp->pixelformat != V4L2_PIX_FMT_MPEG2) && - (pix_mp->pixelformat != V4L2_PIX_FMT_H264) && - (pix_mp->pixelformat != V4L2_PIX_FMT_MPEG1)) { - pix_mp->field = V4L2_FIELD_NONE; - } else if (pix_mp->field != V4L2_FIELD_NONE) { - if (pix_mp->field == V4L2_FIELD_ANY) - pix_mp->field = V4L2_FIELD_NONE; + pix_fmt_mp->field = V4L2_FIELD_NONE; + pix_fmt_mp->height = clamp(pix_fmt_mp->height, + AML_VDEC_MIN_H, + AML_VDEC_MAX_H); + pix_fmt_mp->width = clamp(pix_fmt_mp->width, + AML_VDEC_MIN_W, + AML_VDEC_MAX_W); - pr_info("%s, field: %u, fmt: %x\n", - __func__, pix_mp->field, - pix_mp->pixelformat); - } - } else { - if (pix_mp->field != V4L2_FIELD_INTERLACED) - pix_mp->field = V4L2_FIELD_NONE; - pix_mp->height = clamp(pix_mp->height, - AML_VDEC_MIN_H, - AML_VDEC_MAX_H); - pix_mp->width = clamp(pix_mp->width, - AML_VDEC_MIN_W, - AML_VDEC_MAX_W); + /* + * Find next closer width align 64, heign align 64, size align + * 64 rectangle + * Note: This only get default value, the real HW needed value + * only available when ctx in AML_STATE_PROBE state + */ + tmp_w = pix_fmt_mp->width; + tmp_h = pix_fmt_mp->height; + v4l_bound_align_image(&pix_fmt_mp->width, + AML_VDEC_MIN_W, + AML_VDEC_MAX_W, 6, + &pix_fmt_mp->height, + AML_VDEC_MIN_H, + AML_VDEC_MAX_H, 6, 9); - pix_mp->num_planes = fmt->num_planes; + if (pix_fmt_mp->width < tmp_w && + (pix_fmt_mp->width + 64) <= AML_VDEC_MAX_W) + pix_fmt_mp->width += 64; + if (pix_fmt_mp->height < tmp_h && + (pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H) + pix_fmt_mp->height += 64; - pix_mp->plane_fmt[0].bytesperline = pix_mp->width; - pix_mp->plane_fmt[0].sizeimage = - pix_mp->width * pix_mp->height; + pix_fmt_mp->num_planes = fmt->num_planes; + pix_fmt_mp->plane_fmt[0].sizeimage = + pix_fmt_mp->width * pix_fmt_mp->height; + pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width; - pix_mp->plane_fmt[1].bytesperline = pix_mp->width; - pix_mp->plane_fmt[1].sizeimage = - pix_mp->width * pix_mp->height / 2; + if (pix_fmt_mp->num_planes == 2) { + pix_fmt_mp->plane_fmt[1].sizeimage = + (pix_fmt_mp->width * pix_fmt_mp->height) / 2; + pix_fmt_mp->plane_fmt[1].bytesperline = + pix_fmt_mp->width; } - - for (i = 0; i < pix_mp->num_planes; i++) { - memset(&(pix_mp->plane_fmt[i].reserved[0]), 0x0, - sizeof(pix_mp->plane_fmt[0].reserved)); - } - memset(&pix_mp->reserved, 0x0, sizeof(pix_mp->reserved)); - - pix_mp->flags = 0; - } else { - if (V4L2_TYPE_IS_OUTPUT(f->type)) { - pix->bytesperline = 0; - if ((pix->pixelformat != V4L2_PIX_FMT_MPEG2) && - (pix->pixelformat != V4L2_PIX_FMT_H264) && - (pix->pixelformat != V4L2_PIX_FMT_MPEG1)) { - pix->field = V4L2_FIELD_NONE; - } else if (pix->field != V4L2_FIELD_NONE) { - if (pix->field == V4L2_FIELD_ANY) - pix->field = V4L2_FIELD_NONE; - - pr_info("%s, field: %u, fmt: %x\n", - __func__, pix->field, - pix->pixelformat); - } - } else { - if (pix->field != V4L2_FIELD_INTERLACED) - pix->field = V4L2_FIELD_NONE; - - pix->height = clamp(pix->height, - AML_VDEC_MIN_H, - AML_VDEC_MAX_H); - pix->width = clamp(pix->width, - AML_VDEC_MIN_W, - AML_VDEC_MAX_W); - - pix->bytesperline = pix->width; - pix->sizeimage = pix->width * pix->height; - } - pix->flags = 0; } + for (i = 0; i < pix_fmt_mp->num_planes; i++) + memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0, + sizeof(pix_fmt_mp->plane_fmt[0].reserved)); + + pix_fmt_mp->flags = 0; + memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved)); return 0; } -static int vidioc_try_fmt_vid_cap_out(struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) { - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct aml_q_data *q_data = NULL; struct aml_video_fmt *fmt = NULL; struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); - struct vb2_queue *dst_vq; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, - "%s, type: %u, planes: %u, fmt: %x\n", - __func__, f->type, - V4L2_TYPE_IS_MULTIPLANAR(f->type) ? - f->fmt.pix_mp.num_planes : 1, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.pixelformat); - dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!dst_vq) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE); + fmt = aml_vdec_find_format(f); + if (!fmt) return -EINVAL; - } - if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar) - return -EINVAL; + return vidioc_try_fmt(f, fmt); +} + +static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; + struct aml_video_fmt *fmt = NULL; + struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); fmt = aml_vdec_find_format(f); - if (!fmt) { - if (V4L2_TYPE_IS_OUTPUT(f->type)) - f->fmt.pix.pixelformat = aml_video_formats[OUT_FMT_IDX].fourcc; - else - f->fmt.pix.pixelformat = aml_video_formats[CAP_FMT_IDX].fourcc; - fmt = aml_vdec_find_format(f); - } - - vidioc_try_fmt(f, fmt); - - q_data = aml_vdec_get_q_data(ctx, f->type); - if (!q_data) + if (!fmt) return -EINVAL; - if (ctx->state >= AML_STATE_PROBE) - update_ctx_dimension(ctx, f->type); - copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type); - - if (!V4L2_TYPE_IS_OUTPUT(f->type)) - return 0; - - if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) { - if (pix_mp->plane_fmt[0].sizeimage == 0) { - v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, - "sizeimage of output format must be given\n"); - return -EINVAL; - } - } else { - if (pix->sizeimage == 0) { - v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, - "sizeimage of output format must be given\n"); - return -EINVAL; - } + if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "sizeimage of output format must be given\n"); + return -EINVAL; } - return 0; + return vidioc_try_fmt(f, fmt); } static int vidioc_vdec_g_selection(struct file *file, void *priv, @@ -2502,36 +1599,29 @@ { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); struct aml_q_data *q_data; - int ratio = 1; if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) return -EINVAL; - if (ctx->internal_dw_scale) { - if (ctx->state >= AML_STATE_PROBE) { - unsigned int dw_mode = VDEC_DW_NO_AFBC; - if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) - return -EBUSY; - ratio = get_double_write_ratio(dw_mode); - } - } - q_data = &ctx->q_data[AML_Q_DATA_DST]; switch (s->target) { case V4L2_SEL_TGT_COMPOSE_DEFAULT: case V4L2_SEL_TGT_COMPOSE: - s->r.left = 0; - s->r.top = 0; - s->r.width = ctx->picinfo.visible_width / ratio; - s->r.height = ctx->picinfo.visible_height / ratio; + if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) { + /* set to default value if header info not ready yet*/ + s->r.left = 0; + s->r.top = 0; + s->r.width = q_data->visible_width; + s->r.height = q_data->visible_height; + } break; case V4L2_SEL_TGT_COMPOSE_BOUNDS: s->r.left = 0; s->r.top = 0; - s->r.width = ctx->picinfo.coded_width / ratio; - s->r.height = ctx->picinfo.coded_height / ratio; + s->r.width = ctx->picinfo.coded_width; + s->r.height = ctx->picinfo.coded_height; break; default: return -EINVAL; @@ -2555,7 +1645,6 @@ struct v4l2_selection *s) { struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); - int ratio = 1; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n", __func__, s->type); @@ -2563,21 +1652,12 @@ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (ctx->internal_dw_scale) { - if (ctx->state >= AML_STATE_PROBE) { - unsigned int dw_mode = VDEC_DW_NO_AFBC; - if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) - return -EBUSY; - ratio = get_double_write_ratio(dw_mode); - } - } - switch (s->target) { case V4L2_SEL_TGT_COMPOSE: s->r.left = 0; s->r.top = 0; - s->r.width = ctx->picinfo.visible_width / ratio; - s->r.height = ctx->picinfo.visible_height / ratio; + s->r.width = ctx->picinfo.visible_width; + s->r.height = ctx->picinfo.visible_height; break; default: return -EINVAL; @@ -2586,127 +1666,89 @@ return 0; } -/* 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; - 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 (V4L2_TYPE_IS_MULTIPLANAR(type)) { - q_data->sizeimage[0] = ctx->picinfo.y_len_sz; - q_data->sizeimage[1] = ctx->picinfo.c_len_sz; - - 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[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64); - q_data->bytesperline[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64); - } 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); - } -} - static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp, - struct v4l2_pix_format *pix, - struct aml_q_data *q_data, - u32 type) + struct aml_q_data *q_data, u32 type) { - int i; - - if (!pix || !pix_mp || !q_data) + if (!pix_mp || !q_data) return; - if (V4L2_TYPE_IS_MULTIPLANAR(type)) { - pix_mp->width = q_data->coded_width; - pix_mp->height = q_data->coded_height; - pix_mp->num_planes = q_data->fmt->num_planes; - pix_mp->pixelformat = q_data->fmt->fourcc; - - 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 (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + pix_mp->width = q_data->visible_width; + pix_mp->height = q_data->visible_height; } else { - pix->width = q_data->coded_width; - pix->height = q_data->coded_height; - pix->pixelformat = q_data->fmt->fourcc; - pix->bytesperline = q_data->bytesperline[0]; - pix->sizeimage = q_data->sizeimage[0]; + /* + * Width and height are set to the dimensions + * of the movie, the buffer is bigger and + * further processing stages should crop to this + * rectangle. + */ + pix_mp->width = q_data->coded_width; + pix_mp->height = q_data->coded_height; + } + + /* + * Set pixelformat to the format in which mt vcodec + * outputs the decoded frame + */ + pix_mp->num_planes = q_data->fmt->num_planes; + pix_mp->pixelformat = q_data->fmt->fourcc; + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; + if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1]; + pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1]; } } static int vidioc_vdec_s_fmt(struct file *file, void *priv, struct v4l2_format *f) { - int ret = 0; struct aml_vcodec_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct aml_q_data *q_data = NULL; + struct v4l2_pix_format_mplane *pix_mp; + struct aml_q_data *q_data; + int ret = 0; struct aml_video_fmt *fmt; - struct vb2_queue *dst_vq; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, - "%s, type: %u, planes: %u, fmt: %x\n", - __func__, f->type, - V4L2_TYPE_IS_MULTIPLANAR(f->type) ? - f->fmt.pix_mp.num_planes : 1, + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.pixelformat); - dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!dst_vq) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE); - return -EINVAL; - } - - if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar) - return -EINVAL; - q_data = aml_vdec_get_q_data(ctx, f->type); if (!q_data) return -EINVAL; + pix_mp = &f->fmt.pix_mp; if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && 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; } 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; } fmt = aml_vdec_find_format(f); if (fmt == NULL) { - if (V4L2_TYPE_IS_OUTPUT(f->type)) - fmt = &aml_video_formats[OUT_FMT_IDX]; - else - fmt = &aml_video_formats[CAP_FMT_IDX]; - f->fmt.pix.pixelformat = fmt->fourcc; + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + f->fmt.pix.pixelformat = + aml_video_formats[OUT_FMT_IDX].fourcc; + fmt = aml_vdec_find_format(f); + } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) { + f->fmt.pix.pixelformat = + aml_video_formats[CAP_FMT_IDX].fourcc; + fmt = aml_vdec_find_format(f); + } } q_data->fmt = fmt; vidioc_try_fmt(f, q_data->fmt); - if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (ctx->is_drm_mode) + pix_mp->plane_fmt[0].sizeimage = 1; q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; q_data->coded_width = pix_mp->width; q_data->coded_height = pix_mp->height; @@ -2716,7 +1758,6 @@ pix_mp->width, pix_mp->height, pix_mp->plane_fmt[0].sizeimage); - ctx->output_pix_fmt = pix_mp->pixelformat; ctx->colorspace = f->fmt.pix_mp.colorspace; ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; ctx->quantization = f->fmt.pix_mp.quantization; @@ -2732,38 +1773,7 @@ return -EINVAL; } ctx->state = AML_STATE_INIT; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); - v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, - "vcodec state (AML_STATE_INIT)\n"); - } - mutex_unlock(&ctx->state_lock); - } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - q_data->sizeimage[0] = pix->sizeimage; - q_data->coded_width = pix->width; - q_data->coded_height = pix->height; - - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "w: %d, h: %d, size: %d\n", - pix->width, pix->height, - pix->sizeimage); - - ctx->output_pix_fmt = pix->pixelformat; - ctx->colorspace = f->fmt.pix.colorspace; - ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; - ctx->quantization = f->fmt.pix.quantization; - ctx->xfer_func = f->fmt.pix.xfer_func; - - mutex_lock(&ctx->state_lock); - if (ctx->state == AML_STATE_IDLE) { - ret = vdec_if_init(ctx, q_data->fmt->fourcc); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "vdec_if_init() fail ret=%d\n", ret); - mutex_unlock(&ctx->state_lock); - return -EINVAL; - } - ctx->state = AML_STATE_INIT; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_INIT)\n"); } @@ -2771,13 +1781,9 @@ } if (!V4L2_TYPE_IS_OUTPUT(f->type)) { - ctx->cap_pix_fmt = V4L2_TYPE_IS_MULTIPLANAR(f->type) ? - 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); - } + ctx->cap_pix_fmt = pix_mp->pixelformat; + if (ctx->state >= AML_STATE_PROBE) + copy_v4l2_format_dimention(pix_mp, q_data, f->type); } return 0; @@ -2827,31 +1833,16 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) { struct aml_video_fmt *fmt; - int i = 0, j = 0; + int i, j = 0; - /* I420 only used for mjpeg. */ - if (!output_queue && support_mjpeg && support_format_I420) { - for (i = 0; i < NUM_FORMATS; i++) { - fmt = &aml_video_formats[i]; - if ((fmt->fourcc == V4L2_PIX_FMT_YUV420) || - (fmt->fourcc == V4L2_PIX_FMT_YUV420M)) { - break; - } - } - } - - for (; i < NUM_FORMATS; i++) { - fmt = &aml_video_formats[i]; - if (output_queue && (fmt->type != AML_FMT_DEC)) + for (i = 0; i < NUM_FORMATS; i++) { + if (output_queue && (aml_video_formats[i].type != AML_FMT_DEC)) continue; - if (!output_queue && (fmt->type != AML_FMT_FRAME)) - continue; - if (support_mjpeg && !support_format_I420 && - ((fmt->fourcc == V4L2_PIX_FMT_YUV420) || - (fmt->fourcc == V4L2_PIX_FMT_YUV420M))) + if (!output_queue && (aml_video_formats[i].type != AML_FMT_FRAME)) continue; if (j == f->index) { + fmt = &aml_video_formats[i]; f->pixelformat = fmt->fourcc; return 0; } @@ -2888,7 +1879,6 @@ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; struct v4l2_pix_format *pix = &f->fmt.pix; struct vb2_queue *vq; - struct vb2_queue *dst_vq; struct aml_q_data *q_data; int ret = 0; @@ -2899,29 +1889,12 @@ return -EINVAL; } - dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!dst_vq) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE); - return -EINVAL; - } - - if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar) - return -EINVAL; - q_data = aml_vdec_get_q_data(ctx, f->type); ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo); if (ret) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "GET_PARAM_PICTURE_INFO err\n"); - } else { - if ((ctx->picinfo.visible_height < 16 && ctx->picinfo.visible_height > 0) || - (ctx->picinfo.visible_width < 16 && ctx->picinfo.visible_width > 0)) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "The width or height of the stream is less than 16\n"); - return -EPERM; - } } if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) { @@ -2940,8 +1913,24 @@ 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); + /* Until STREAMOFF is called on the CAPTURE queue + * (acknowledging the event), the driver operates as if + * the resolution hasn't changed yet. + * So we just return picinfo yet, and update picinfo in + * stop_streaming hook function + */ + /* it is used for alloc the decode buffer size. */ + q_data->sizeimage[0] = ctx->picinfo.y_len_sz; + q_data->sizeimage[1] = ctx->picinfo.c_len_sz; + + /* it is used for alloc the EGL image buffer size. */ + q_data->coded_width = ctx->picinfo.coded_width; + q_data->coded_height = ctx->picinfo.coded_height; + + q_data->bytesperline[0] = ctx->picinfo.coded_width; + q_data->bytesperline[1] = ctx->picinfo.coded_width; + + copy_v4l2_format_dimention(pix_mp, q_data, f->type); } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* * This is run on OUTPUT @@ -2949,21 +1938,20 @@ * 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_dimention(pix_mp, q_data, f->type); } else { - copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type); + copy_v4l2_format_dimention(pix_mp, 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", f->type, ctx->state); + return -EINVAL; } v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, - "%s, type: %u, planes: %u, fmt: %x\n", - __func__, f->type, - V4L2_TYPE_IS_MULTIPLANAR(f->type) ? - q_data->fmt->num_planes : 1, - q_data->fmt->fourcc); + "%s, type: %u, planes: %u, fmt: %u\n", + __func__, f->type, f->fmt.pix_mp.num_planes, + f->fmt.pix_mp.pixelformat); return 0; } @@ -3019,32 +2007,21 @@ for (i = 0; i < *nplanes; i++) { if (sizes[i] < q_data->sizeimage[i]) return -EINVAL; - alloc_devs[i] = &ctx->dev->plat_dev->dev; - - if (!V4L2_TYPE_IS_OUTPUT(vq->type)) - alloc_devs[i] = v4l_get_dev_from_codec_mm(); + //alloc_devs[i] = &ctx->dev->plat_dev->dev; + alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm } } else { - int dw_mode = VDEC_DW_NO_AFBC; - 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; - } - 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; - - if (!V4L2_TYPE_IS_OUTPUT(vq->type)) - alloc_devs[i] = v4l_get_dev_from_codec_mm(); + sizes[i] = 0; + //alloc_devs[i] = &ctx->dev->plat_dev->dev; + alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm } } @@ -3059,8 +2036,6 @@ { 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; int i; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, @@ -3082,710 +2057,65 @@ } } - 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; - - if (flag & DV_TYPE) { - for (i = 0; i < V4L_CAP_BUFF_MAX; i++) { - ctx->aux_infos.bufs[i].md_buf = vzalloc(MD_BUF_SIZE); - if (ctx->aux_infos.bufs[i].md_buf == NULL) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "v4l2 alloc %dth dv md buffer fail\n", i); - } - - ctx->aux_infos.bufs[i].comp_buf = vzalloc(COMP_BUF_SIZE); - if (ctx->aux_infos.bufs[i].comp_buf == NULL) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "v4l2 alloc %dth dv comp buffer fail\n", i); - } - } - } - - if (flag & SEI_TYPE) { - for (i = 0; i < V4L_CAP_BUFF_MAX; i++) { - ctx->aux_infos.bufs[i].sei_buf = vzalloc(SEI_BUF_SIZE); - if (ctx->aux_infos.bufs[i].sei_buf) { - ctx->aux_infos.bufs[i].sei_size = 0; - ctx->aux_infos.bufs[i].sei_state = 1; - ctx->aux_infos.sei_need_free = false; - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "v4l2 alloc %dth aux buffer:%px\n", - i, ctx->aux_infos.bufs[i].sei_buf); - } else { - ctx->aux_infos.bufs[i].sei_buf = NULL; - ctx->aux_infos.bufs[i].sei_state = 0; - ctx->aux_infos.bufs[i].sei_size = 0; - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "v4l2 alloc %dth aux buffer fail\n", i); - } - } - } -} - -void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag) -{ - int i = 0; - - if (flag & DV_TYPE) { - for (i = 0; i < V4L_CAP_BUFF_MAX; i++) { - if (ctx->aux_infos.bufs[i].md_buf != NULL) { - vfree(ctx->aux_infos.bufs[i].md_buf); - ctx->aux_infos.bufs[i].md_buf = NULL; - } - - if (ctx->aux_infos.bufs[i].comp_buf != NULL) { - vfree(ctx->aux_infos.bufs[i].comp_buf); - ctx->aux_infos.bufs[i].comp_buf = NULL; - } - } - } - - if (flag & SEI_TYPE) { - for (i = 0; i < V4L_CAP_BUFF_MAX; i++) { - if (ctx->aux_infos.bufs[i].sei_buf != NULL) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "v4l2 free %dth aux buffer:%px\n", - i, ctx->aux_infos.bufs[i].sei_buf); - vfree(ctx->aux_infos.bufs[i].sei_buf); - ctx->aux_infos.bufs[i].sei_state = 0; - ctx->aux_infos.bufs[i].sei_size = 0; - ctx->aux_infos.bufs[i].sei_buf = NULL; - } - } - } -} - -void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx) -{ - if (ctx->aux_infos.bufs[idx].sei_buf != NULL) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "v4l2 free %dth aux buffer:%px\n", - idx, ctx->aux_infos.bufs[idx].sei_buf); - - vfree(ctx->aux_infos.bufs[idx].sei_buf); - ctx->aux_infos.bufs[idx].sei_state = 0; - ctx->aux_infos.bufs[idx].sei_size = 0; - ctx->aux_infos.bufs[idx].sei_buf = NULL; - *addr = NULL; - *size = 0; - ctx->aux_infos.sei_need_free = true; - } -} - -void aml_bind_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx) -{ - int index = ctx->aux_infos.sei_index; - int count = 0; - - if (ctx->aux_infos.sei_need_free) { - for (count = 0; count < V4L_CAP_BUFF_MAX; count++) { - if ((ctx->aux_infos.bufs[index].sei_buf != NULL) && - (ctx->aux_infos.bufs[index].sei_state == 1)) { - break; - } - index = (index + 1) % V4L_CAP_BUFF_MAX; - } - } else { - for (count = 0; count < V4L_CAP_BUFF_MAX; count++) { - if ((ctx->aux_infos.bufs[index].sei_buf != NULL) && - ((ctx->aux_infos.bufs[index].sei_state == 1) || - (ctx->aux_infos.bufs[index].sei_state == 2))) { - memset(ctx->aux_infos.bufs[index].sei_buf, 0, SEI_BUF_SIZE); - ctx->aux_infos.bufs[index].sei_size = 0; - break; - } - index = (index + 1) % V4L_CAP_BUFF_MAX; - } - } - - if (count == V4L_CAP_BUFF_MAX) { - *addr = NULL; - *size = 0; - } else { - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "v4l2 bind %dth aux buffer:%px, count = %d\n", - index, ctx->aux_infos.bufs[index].sei_buf, count); - *addr = ctx->aux_infos.bufs[index].sei_buf; - *size = ctx->aux_infos.bufs[index].sei_size; - *idx = index; - ctx->aux_infos.bufs[index].sei_state = 2; - ctx->aux_infos.sei_index = (index + 1) % V4L_CAP_BUFF_MAX; - } -} - -void aml_bind_dv_buffer(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf) -{ - int index = ctx->aux_infos.dv_index; - - if ((ctx->aux_infos.bufs[index].comp_buf != NULL) && - (ctx->aux_infos.bufs[index].md_buf != NULL)) { - *comp_buf = ctx->aux_infos.bufs[index].comp_buf; - *md_buf = ctx->aux_infos.bufs[index].md_buf; - ctx->aux_infos.dv_index = (index + 1) % V4L_CAP_BUFF_MAX; - } -} - -void aml_v4l_ctx_release(struct kref *kref) -{ - struct aml_vcodec_ctx * ctx; - - 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); - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "vpp destory 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"); - } - - 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); - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "v4ldec has been destroyed.\n"); - - if (ctx->sync) { - vdec_clean_all_fence(ctx->sync); - } - - 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 = - (struct aml_uvm_buff_ref*)arg; - struct aml_vcodec_ctx * ctx - = container_of(ubuf->ref, struct aml_vcodec_ctx, ctx_ref); - - v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, - "%s, vb:%d, dbuf:%px, ino:%lu\n", - __func__, ubuf->index, ubuf->dbuf, - file_inode(ubuf->dbuf->file)->i_ino); - - 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 ret = 0; - struct dma_buf *dbuf = vb->planes[0].dbuf; - struct uvm_hook_mod_info u_info; - struct aml_vcodec_ctx *ctx = - vb2_get_drv_priv(vb->vb2_queue); - struct aml_uvm_buff_ref *ubuf = NULL; - - if (vb->memory != VB2_MEMORY_DMABUF || !dmabuf_is_uvm(dbuf)) - return 0; - - ubuf = vzalloc(sizeof(struct aml_uvm_buff_ref)); - if (ubuf == NULL) - return -ENOMEM; - - ubuf->index = vb->index; - ubuf->addr = vb2_dma_contig_plane_dma_addr(vb, 0); - ubuf->dbuf = dbuf; - ubuf->ref = &ctx->ctx_ref; - - u_info.type = VF_PROCESS_DECODER; - u_info.arg = (void *)ubuf; - u_info.free = aml_uvm_buf_free; - ret = uvm_attach_hook_mod(dbuf, &u_info); - if (ret < 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "aml uvm buffer %d attach fail.\n", - ubuf->index); - return ret; - } - - kref_get(ubuf->ref); - - v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, - "%s, vb:%d, dbuf:%px, ino:%lu\n", - __func__, ubuf->index, ubuf->dbuf, - file_inode(ubuf->dbuf->file)->i_ino); - - return ret; -} - -static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx, - struct vb2_buffer *vb) -{ - 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; - - uhmod = uvm_get_hook_mod(dbuf, u_type); - if (IS_ERR_OR_NULL(uhmod)) - return NULL; - - ibuf = !is_v4lvideo ? (struct internal_comp_buf *) uhmod->arg : - container_of(uhmod->arg, struct internal_comp_buf, priv_data); - - uvm_put_hook_mod(dbuf, u_type); - - v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, - "%s, vb2: (%d, %px) --> comp: (%d, %px)\n", - __func__, vb->index, dbuf, ibuf->index, ibuf); - - return ibuf; -} - 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 vb2_v4l2_buffer *vb2_v4l2 = NULL; + struct aml_video_dec_buf *buf = NULL; struct aml_vcodec_mem src_mem; + unsigned int dpb = 0; + + vb2_v4l2 = to_vb2_v4l2_buffer(vb); + buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); 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); - /* * 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; - - if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n"); + if (vb->index >= ctx->dpb_size) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "enque capture buf idx %d/%d is invalid.\n", + vb->index, ctx->dpb_size); return; - } + v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, + "y_addr: %lx, vf_h: %lx, state: %d", + buf->frame_buffer.m.mem[0].addr, + buf->frame_buffer.vf_handle, + buf->frame_buffer.status); + 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)); - /* 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; - } - - /* DI hook must be detached if the dmabuff be reused. */ - if (ctx->vpp_cfg.enable_local_buf) { - struct dma_buf *dma = vb->planes[0].dbuf; - - if (dmabuf_is_uvm(dma) && - 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); + buf->queued_in_vb2 = true; + buf->queued_in_v4l2 = true; + buf->ready_to_display = false; + ctx->cap_pool.seq[ctx->cap_pool.in++] = + (V4L_CAP_BUFF_IN_M2M << 16 | vb->index); /* check dpb ready */ aml_check_dpb_ready(ctx); - } else { - struct vframe_s *vf = fb->vframe; - struct task_chain_s *task = fb->task; + } else if (buf->frame_buffer.status == FB_ST_DISPLAY) { + buf->queued_in_vb2 = false; + buf->queued_in_v4l2 = true; + buf->ready_to_display = false; - 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); + /* recycle vf */ + video_vf_put(ctx->ada_ctx->recv_name, + &buf->frame_buffer, ctx->id); } - - wake_up_interruptible(&ctx->cap_wq); return; } @@ -3795,41 +2125,28 @@ return; } - buf->used = true; vb2_v4l2 = to_vb2_v4l2_buffer(vb); buf = container_of(vb2_v4l2, struct aml_video_dec_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; } 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.addr = vb2_dma_contig_plane_dma_addr(vb, 0); src_mem.size = vb->planes[0].bytesused; 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 { - v4l2_buff_done(to_vb2_v4l2_buffer(vb), - VB2_BUF_STATE_DONE); - } - + if (!(ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF)) + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE); return; } @@ -3837,14 +2154,11 @@ * 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); + if (ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF) { + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); } else if (ctx->param_sets_from_ucode) { - v4l2_buff_done(to_vb2_v4l2_buffer(vb), + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE); } @@ -3854,24 +2168,23 @@ return; } - if (!ctx->picinfo.dpb_frames) + if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "GET_PARAM_DPB_SIZE err\n"); + return; + } + + if (!dpb) return; - v4l_buf_size_decision(ctx); + ctx->dpb_size = dpb; ctx->last_decoded_picinfo = ctx->picinfo; - - 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, - ctx->picinfo.dpb_margin, - CTX_BUF_TOTAL(ctx)); - aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION); mutex_lock(&ctx->state_lock); if (ctx->state == AML_STATE_INIT) { ctx->state = AML_STATE_PROBE; - ATRACE_COUNTER("V_ST_VSINK-state", ctx->state); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_PROBE)\n"); } @@ -3883,19 +2196,26 @@ 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; + bool buf_error; 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); + vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb); - if (buf->error) { + if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + buf->queued_in_v4l2 = false; + buf->queued_in_vb2 = false; + } + buf_error = buf->error; + + 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); + ATRACE_COUNTER("v4l2_state", ctx->state); v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE, "vcodec state (AML_STATE_ABORT)\n"); } @@ -3908,145 +2228,108 @@ 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; - u32 size, phy_addr = 0; - int i; + unsigned int size, phy_addr = 0; + char *owner = __getname(); 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)) { + if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + buf->used = false; + buf->ready_to_display = false; + buf->queued_in_v4l2 = false; + buf->frame_buffer.status = FB_ST_NORMAL; + } else { buf->lastframe = false; } /* codec_mm buffers count */ - if (!V4L2_TYPE_IS_OUTPUT(vb->type)) { + if (V4L2_TYPE_IS_OUTPUT(vb->type)) { if (vb->memory == VB2_MEMORY_MMAP) { - char *owner = __getname(); - - snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id); + size = vb->planes[0].length; + phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id); strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer)); buf->mem_onwer[sizeof(buf->mem_onwer) - 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, - 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; + buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "IN alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); + } + } else { + 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'; - for (i = 0; i < vb->num_planes; i++) { - struct dma_buf * dma; + if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 1)) { + size = vb->planes[0].length; + phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); + } else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) { + size = vb->planes[0].length; + phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); + buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); - 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; - } - /* None-DW mode means single layer */ - if (dw_mode == VDEC_DW_AFBC_ONLY && i > 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "only support single plane in dw mode 0\n"); - return -EINVAL; - } - size = vb->planes[i].length; - dma = vb->planes[i].dbuf; - - if (!dmabuf_is_uvm(dma)) - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "non-uvm dmabuf\n"); - } + size = vb->planes[1].length; + phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1); + buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer, + phy_addr, size, vb->index); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT C alloc, addr: %x, size: %u, idx: %u\n", + phy_addr, size, vb->index); } } - 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; - - 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); - } - - if (V4L2_TYPE_IS_OUTPUT(vb->type)) { - ulong contig_size; - - buf->out_sgt = vb2_dma_sg_plane_desc(vb, 0); - - contig_size = dmabuf_contiguous_size(buf->out_sgt); - if (contig_size < vb->planes[0].bytesused) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "contiguous mapping is too small %lu/%u\n", - contig_size, size); - return -EFAULT; - } - } + __putname(owner); return 0; } -static void vb2ops_vdec_buf_cleanup(struct vb2_buffer *vb) +static void codec_mm_bufs_cnt_clean(struct vb2_queue *q) { - 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_vcodec_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb2_v4l2 = NULL; + struct aml_video_dec_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); + 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); + if (IS_ERR_OR_NULL(buf->mem[0])) + return; - if (!V4L2_TYPE_IS_OUTPUT(vb->type)) { - if (vb->memory == VB2_MEMORY_MMAP) { - int i; + if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) { + v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]); - for (i = 0; i < vb->num_planes ; i++) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, - "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]); - buf->mem[i] = NULL; - } + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "IN clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); + buf->mem[0] = NULL; + continue; } - 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); - } + + if (q->memory == VB2_MEMORY_MMAP) { + v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]); + v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT Y clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i); + v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, + "OUT C clean, addr: %lx, size: %u, idx: %u\n", + buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i); + buf->mem[0] = NULL; + buf->mem[1] = NULL; } } } @@ -4056,10 +2339,6 @@ struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q); ctx->has_receive_eos = false; - 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_set_dst_buffered(ctx->fh.m2m_ctx, true); @@ -4080,81 +2359,40 @@ "%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)) - ctx->is_out_stream_off = true; - else - ctx->is_stream_off = true; + codec_mm_bufs_cnt_clean(q); if (V4L2_TYPE_IS_OUTPUT(q->type)) { - struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx); - unsigned long flags; - - cancel_work_sync(&ctx->dmabuff_recycle_work); - spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags); - 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); + v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); for (i = 0; i < q->num_buffers; ++i) { vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]); if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE) - v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR); - } - - /* - * drop es frame was stored in the vdec_input - * if the capture queue have not start streaming. - */ - 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); - ctx->v4l_resolution_change = false; - ctx->reset_flag = V4L_RESET_MODE_NORMAL; - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "force reset to drop es frames.\n"); - wake_up_interruptible(&ctx->cap_wq); - aml_vdec_reset(ctx); + v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); } } else { /* clean output cache and decoder status . */ - if (ctx->state > AML_STATE_INIT) { - wake_up_interruptible(&ctx->cap_wq); + if (ctx->state > AML_STATE_INIT) 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); + v4l2_m2m_buf_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->frame_buffer.status = FB_ST_NORMAL; + buf->que_in_m2m = false; + buf->vb.flags = 0; + ctx->cap_pool.seq[i] = 0; if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE) - v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR); + v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR); /*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "idx: %d, state: %d\n", q->bufs[i]->index, q->bufs[i]->state);*/ } - fb_map_table_clean(ctx); - - fb_token_clean(ctx); - ctx->buf_used_count = 0; ctx->cap_pool.in = 0; ctx->cap_pool.out = 0; @@ -4172,6 +2410,15 @@ queue_work(dev->decode_workqueue, &ctx->decode_work); } +void vdec_device_vf_run(struct aml_vcodec_ctx *ctx) +{ + if (ctx->state < AML_STATE_INIT || + ctx->state > AML_STATE_FLUSHED) + return; + + aml_thread_notify(ctx, AML_THREAD_CAPTURE); +} + static int m2mops_vdec_job_ready(void *m2m_priv) { struct aml_vcodec_ctx *ctx = m2m_priv; @@ -4201,23 +2448,17 @@ switch (ctrl->id) { case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: if (ctx->state >= AML_STATE_PROBE) { - ctrl->val = CTX_BUF_TOTAL(ctx); + ctrl->val = ctx->dpb_size; } else { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Seqinfo not ready.\n"); ctrl->val = 0; + ret = -EINVAL; } break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ctrl->val = 4; break; - case AML_V4L2_GET_INPUT_BUFFER_NUM: - if (ctx->ada_ctx != NULL) - ctrl->val = vdec_frame_number(ctx->ada_ctx); - break; - case AML_V4L2_GET_FILMGRAIN_INFO: - ctrl->val = ctx->film_grain_present; - break; default: ret = -EINVAL; } @@ -4235,10 +2476,6 @@ ctx->param_sets_from_ucode = true; v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "set stream 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, - "set duration: %x\n", ctrl->val); } return 0; @@ -4261,42 +2498,6 @@ .def = 0, }; -static const struct v4l2_ctrl_config ctrl_gt_input_buffer_number = { - .name = "input buffer number", - .id = AML_V4L2_GET_INPUT_BUFFER_NUM, - .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_st_duration = { - .name = "duration", - .id = AML_V4L2_SET_DURATION, - .ops = &aml_vcodec_dec_ctrl_ops, - .type = V4L2_CTRL_TYPE_INTEGER, - .flags = V4L2_CTRL_FLAG_WRITE_ONLY, - .min = 0, - .max = 96000, - .step = 1, - .def = 0, -}; - -static const struct v4l2_ctrl_config ctrl_gt_filmgrain_info = { - .name = "filmgrain info", - .id = AML_V4L2_GET_FILMGRAIN_INFO, - .ops = &aml_vcodec_dec_ctrl_ops, - .type = V4L2_CTRL_TYPE_INTEGER, - .flags = V4L2_CTRL_FLAG_VOLATILE, - .min = 0, - .max = 1, - .step = 1, - .def = 0, -}; - int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx) { int ret; @@ -4307,42 +2508,24 @@ &aml_vcodec_dec_ctrl_ops, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 0, 32, 1, 2); - if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) { + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + if (ctx->ctrl_hdl.error) { ret = ctx->ctrl_hdl.error; goto err; } - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, &aml_vcodec_dec_ctrl_ops, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 0, 32, 1, 8); - if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) { + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + if (ctx->ctrl_hdl.error) { ret = ctx->ctrl_hdl.error; goto err; } - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_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_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_gt_filmgrain_info, NULL); - if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) { + if (ctx->ctrl_hdl.error) { ret = ctx->ctrl_hdl.error; goto err; } @@ -4362,25 +2545,16 @@ struct v4l2_streamparm *a) { struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); - struct vb2_queue *dst_vq; - dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!dst_vq) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE); - return -EINVAL; - } - - if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar) - return -EINVAL; - - if ((a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) || (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) { - if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO, &ctx->config.parm.dec)) + if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO, + &ctx->config.parm.dec)) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "GET_PARAM_CONFIG_INFO err\n"); - else - memcpy(a->parm.raw_data, ctx->config.parm.data, - sizeof(a->parm.raw_data)); + return -1; + } + memcpy(a->parm.raw_data, ctx->config.parm.data, + sizeof(a->parm.raw_data)); } v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); @@ -4388,65 +2562,22 @@ return 0; } -static int check_dec_cfginfo(struct aml_vdec_cfg_infos *cfg) -{ - 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); - return -1; - } - if (cfg->ref_buf_margin > 20) { - pr_err("invalid margin %d\n", cfg->ref_buf_margin); - return -1; - } - - if (mandatory_dw_mmu) { - cfg->double_write_mode = 0x21; - } - - pr_info("double write mode %d margin %d\n", - cfg->double_write_mode, cfg->ref_buf_margin); - return 0; -} - static int vidioc_vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { struct aml_vcodec_ctx *ctx = fh_to_ctx(fh); - struct vb2_queue *dst_vq; v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__); - dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (!dst_vq) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE); - return -EINVAL; - } - - if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar) - return -EINVAL; - - if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || - a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { struct aml_dec_params *in = (struct aml_dec_params *) a->parm.raw_data; struct aml_dec_params *dec = &ctx->config.parm.dec; ctx->config.type = V4L2_CONFIG_PARM_DECODE; - if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) { - if (check_dec_cfginfo(&in->cfg)) - return -EINVAL; + if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) dec->cfg = in->cfg; - } if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO) dec->ps = in->ps; if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO) @@ -4455,37 +2586,31 @@ dec->cnt = in->cnt; dec->parms_status |= in->parms_status; - - /* 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; - - 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; - - ctx->internal_dw_scale = dec->cfg.metadata_config_flag & (1 << 13); - ctx->second_field_pts_mode = dec->cfg.metadata_config_flag & (1 << 12); - - 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); - - memset(a->parm.output.reserved, 0, sizeof(a->parm.output.reserved)); - } else { - memset(a->parm.capture.reserved, 0, sizeof(a->parm.capture.reserved)); } return 0; } +static void m2mops_vdec_lock(void *m2m_priv) +{ + struct aml_vcodec_ctx *ctx = m2m_priv; + + mutex_lock(&ctx->dev->dev_mutex); +} + +static void m2mops_vdec_unlock(void *m2m_priv) +{ + struct aml_vcodec_ctx *ctx = m2m_priv; + + mutex_unlock(&ctx->dev->dev_mutex); +} const struct v4l2_m2m_ops aml_vdec_m2m_ops = { .device_run = m2mops_vdec_device_run, .job_ready = m2mops_vdec_job_ready, .job_abort = m2mops_vdec_job_abort, + .lock = m2mops_vdec_lock, + .unlock = m2mops_vdec_unlock, }; static const struct vb2_ops aml_vdec_vb2_ops = { @@ -4495,7 +2620,6 @@ .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, .buf_init = vb2ops_vdec_buf_init, - .buf_cleanup = vb2ops_vdec_buf_cleanup, .buf_finish = vb2ops_vdec_buf_finish, .start_streaming = vb2ops_vdec_start_streaming, .stop_streaming = vb2ops_vdec_stop_streaming, @@ -4512,10 +2636,10 @@ .vidioc_qbuf = vidioc_vdec_qbuf, .vidioc_dqbuf = vidioc_vdec_dqbuf, - .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_out, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_out, - .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_cap_out, - .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_cap_out, + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane, + .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out_mplane, .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt, .vidioc_s_fmt_vid_cap = vidioc_vdec_s_fmt, @@ -4528,18 +2652,17 @@ .vidioc_create_bufs = vidioc_vdec_create_bufs, - //fixme - //.vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane, - //.vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane, + .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane, .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap_mplane, + .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane, .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out_mplane, .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_querycap = vidioc_vdec_querycap, .vidioc_subscribe_event = vidioc_vdec_subscribe_evt, .vidioc_unsubscribe_event = vidioc_vdec_event_unsubscribe, - .vidioc_g_selection = vidioc_vdec_g_selection, - .vidioc_s_selection = vidioc_vdec_s_selection, + .vidioc_g_selection = vidioc_vdec_g_selection, + .vidioc_s_selection = vidioc_vdec_s_selection, .vidioc_decoder_cmd = vidioc_decoder_cmd, .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd, @@ -4557,11 +2680,11 @@ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__); src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf); src_vq->ops = &aml_vdec_vb2_ops; - src_vq->mem_ops = &vb2_dma_sg_memops; + src_vq->mem_ops = &vb2_dma_contig_memops; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->dev->dev_mutex; ret = vb2_queue_init(src_vq); @@ -4580,7 +2703,6 @@ 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->min_buffers_needed = 1; ret = vb2_queue_init(dst_vq); if (ret) { vb2_queue_release(src_vq);
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h index a23522c..3653ff0 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.h +++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -20,14 +20,11 @@ #ifndef _AML_VCODEC_DEC_H_ #define _AML_VCODEC_DEC_H_ -#include <linux/kref.h> -#include <linux/scatterlist.h> #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 "aml_vcodec_util.h" -#include "aml_task_chain.h" #define VCODEC_CAPABILITY_4K_DISABLED 0x10 #define VCODEC_DEC_4K_CODED_WIDTH 4096U @@ -41,25 +38,15 @@ #define VDEC_GATHER_MEMORY_TYPE 0 #define VDEC_SCATTER_MEMORY_TYPE 1 -#define META_DATA_SIZE (256) -#define MD_BUF_SIZE (1024) -#define COMP_BUF_SIZE (8196) -#define SEI_BUF_SIZE (2 * 12 * 1024) -#define SEI_TYPE (1) -#define DV_TYPE (2) - - -/* - * struct vdec_v4l2_buffer - decoder frame buffer +/** + * struct vdec_fb - decoder frame buffer * @mem_type : gather or scatter memory. * @num_planes : used number of the plane * @mem[4] : array mem for used planes, * mem[0]: Y, mem[1]: C/U, mem[2]: V * @vf_fd : the file handle of video frame + * @vf_handle : video frame handle * @status : frame buffer status (vdec_fb_status) - * @buf_idx : the index from vb2 index. - * @vframe : store the vframe that get from caller. - * @task : the context of task chain manager. */ struct vdec_v4l2_buffer { @@ -69,19 +56,22 @@ struct aml_vcodec_mem mem[4]; u32 vf_fd; } m; + ulong vf_handle; u32 status; u32 buf_idx; - void *vframe; - - struct task_chain_s *task; }; + /** * struct aml_video_dec_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 + * @ready_to_display: Capture buffer not display yet + * @queued_in_vb2: Capture buffer is queue in vb2 + * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 + * queue yet * @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 @@ -97,21 +87,12 @@ struct codec_mm_s *mem[2]; char mem_onwer[32]; bool used; + bool ready_to_display; bool que_in_m2m; + bool queued_in_vb2; + bool queued_in_v4l2; 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]; - - struct sg_table *out_sgt; - struct sg_table *cap_sgt; }; extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops; @@ -130,19 +111,16 @@ void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx); void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx); int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx); +void vdec_device_vf_run(struct aml_vcodec_ctx *ctx); +void try_to_capture(struct aml_vcodec_ctx *ctx); +void aml_thread_notify(struct aml_vcodec_ctx *ctx, + enum aml_thread_type type); +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 wait_vcodec_ending(struct aml_vcodec_ctx *ctx); void vdec_frame_buffer_release(void *data); void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes); void* v4l_get_vf_handle(int fd); -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); - -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); #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 18f0254..1ed0b97 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c +++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -29,11 +29,11 @@ #include <media/v4l2-mem2mem.h> #include <media/videobuf2-dma-contig.h> #include <linux/kthread.h> -#include <linux/compat.h> + #include "aml_vcodec_drv.h" #include "aml_vcodec_dec.h" #include "aml_vcodec_util.h" -#include "aml_vcodec_vpp.h" +#include "aml_vcodec_vfm.h" #include <linux/file.h> #include <linux/anon_inodes.h> @@ -50,7 +50,6 @@ bool param_sets_from_ucode = 1; bool enable_drm_mode; -extern void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx); static int fops_vcodec_open(struct file *file) { @@ -63,21 +62,12 @@ 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) { 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(ctx); - return -ENOMEM; - } - mutex_lock(&dev->dev_mutex); ctx->empty_flush_buf = aml_buf; ctx->id = dev->id_counter++; @@ -86,26 +76,14 @@ v4l2_fh_add(&ctx->fh); INIT_LIST_HEAD(&ctx->list); INIT_LIST_HEAD(&ctx->vdec_thread_list); - INIT_LIST_HEAD(&ctx->task_chain_pool); dev->filp = file; ctx->dev = dev; init_waitqueue_head(&ctx->queue); - mutex_init(&ctx->capture_buffer_lock); - mutex_init(&ctx->buff_done_lock); mutex_init(&ctx->state_lock); - mutex_init(&ctx->comp_lock); + mutex_init(&ctx->lock); spin_lock_init(&ctx->slock); - spin_lock_init(&ctx->tsplock); - spin_lock_init(&ctx->dmabuff_recycle_lock); 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_KFIFO(ctx->dmabuff_recycle); - INIT_KFIFO(ctx->capture_buffer); - ctx->post_to_upper_done = true; ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0; if (enable_drm_mode) { @@ -133,19 +111,9 @@ ctx->output_thread_ready = true; 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; aml_vcodec_dec_set_default_params(ctx); - ctx->is_stream_off = true; - ctx->aux_infos.dv_index = 0; - ctx->aux_infos.sei_index = 0; - ctx->aux_infos.alloc_buffer = aml_alloc_buffer; - ctx->aux_infos.free_buffer = aml_free_buffer; - 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; - - ret = aml_thread_start(ctx, aml_thread_capture_worker, AML_THREAD_CAPTURE, "cap"); + ret = aml_thread_start(ctx, try_to_capture, AML_THREAD_CAPTURE, "cap"); if (ret) { v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Failed to creat capture thread.\n"); @@ -158,7 +126,7 @@ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n", dev_name(&dev->plat_dev->dev), (ulong)ctx); - return 0; + return ret; /* Deinit when failure occurred */ err_creat_thread: @@ -168,7 +136,6 @@ err_ctrls_setup: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); - vfree(ctx->meta_infos.meta_bufs); kfree(ctx->empty_flush_buf); kfree(ctx); mutex_unlock(&dev->dev_mutex); @@ -184,20 +151,24 @@ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx); mutex_lock(&dev->dev_mutex); + /* + * Call v4l2_m2m_ctx_release before aml_vcodec_dec_release. First, it + * makes sure the worker thread is not running after vdec_if_deinit. + * Second, the decoder will be flushed and all the buffers will be + * returned in stop_streaming. + */ aml_thread_stop(ctx); wait_vcodec_ending(ctx); - vb2_queue_release(&ctx->m2m_ctx->cap_q_ctx.q); - vb2_queue_release(&ctx->m2m_ctx->out_q_ctx.q); - + v4l2_m2m_ctx_release(ctx->m2m_ctx); aml_vcodec_dec_release(ctx); + v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); list_del_init(&ctx->list); - kfree(ctx->empty_flush_buf); - kref_put(&ctx->ctx_ref, aml_v4l_ctx_release); + kfree(ctx); mutex_unlock(&dev->dev_mutex); return 0; } @@ -331,10 +302,8 @@ if (!is_v4l2_buf_file(file)) { fput(file); -#if 0 v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the buf file checked fail!\n"); -#endif return NULL; } @@ -446,43 +415,6 @@ .mmap = v4l2_m2m_fop_mmap, }; -static ssize_t status_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) { - /* basic information. */ - aml_vdec_basic_information(ctx); - - /* buffers status. */ - aml_buffer_status(ctx); - } -out: - mutex_unlock(&dev->dev_mutex); - - return pbuf - buf; -} - -static CLASS_ATTR_RO(status); - -static struct attribute *v4ldec_class_attrs[] = { - &class_attr_status.attr, - NULL -}; - -ATTRIBUTE_GROUPS(v4ldec_class); - static int aml_vcodec_probe(struct platform_device *pdev) { struct aml_vcodec_dev *dev; @@ -495,7 +427,6 @@ INIT_LIST_HEAD(&dev->ctx_list); dev->plat_dev = pdev; - atomic_set(&dev->vpp_count, 0); mutex_init(&dev->dec_mutex); mutex_init(&dev->dev_mutex); @@ -506,7 +437,8 @@ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { - dev_err(&pdev->dev, "v4l2_device_register err=%d\n", ret); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "v4l2_device_register err=%d\n", ret); goto err_res; } @@ -514,7 +446,8 @@ vfd_dec = video_device_alloc(); if (!vfd_dec) { - dev_err(&pdev->dev, "Failed to allocate video device\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to allocate video device\n"); ret = -ENOMEM; goto err_dec_alloc; } @@ -526,7 +459,7 @@ vfd_dec->v4l2_dev = &dev->v4l2_dev; vfd_dec->vfl_dir = VFL_DIR_M2M; vfd_dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | - V4L2_CAP_STREAMING; + V4L2_CAP_STREAMING; snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s", AML_VCODEC_DEC_NAME); @@ -536,16 +469,18 @@ dev->m2m_dev_dec = v4l2_m2m_init(&aml_vdec_m2m_ops); if (IS_ERR((__force void *)dev->m2m_dev_dec)) { - dev_err(&pdev->dev, "Failed to init mem2mem dec device\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to init mem2mem dec device\n"); ret = PTR_ERR((__force void *)dev->m2m_dev_dec); goto err_dec_mem_init; } dev->decode_workqueue = - alloc_ordered_workqueue("output-worker", - __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI); + alloc_ordered_workqueue(AML_VCODEC_DEC_NAME, + WQ_MEM_RECLAIM | WQ_FREEZABLE); if (!dev->decode_workqueue) { - dev_err(&pdev->dev, "Failed to create decode workqueue\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to create decode workqueue\n"); ret = -EINVAL; goto err_event_workq; } @@ -554,26 +489,16 @@ ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26); if (ret) { - dev_err(&pdev->dev, "Failed to register video device\n"); + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, + "Failed to register video device\n"); goto err_dec_reg; } - /*init class*/ - dev->v4ldec_class.name = "v4ldec"; - dev->v4ldec_class.owner = THIS_MODULE; - dev->v4ldec_class.class_groups = v4ldec_class_groups; - ret = class_register(&dev->v4ldec_class); - if (ret) { - dev_err(&pdev->dev, "v4l dec class create fail.\n"); - goto err_reg_class; - } - - dev_info(&pdev->dev, "v4ldec registered as /dev/video%d\n", vfd_dec->num); + v4l_dbg(0, V4L_DEBUG_CODEC_PRINFO, + "decoder registered as /dev/video%d\n", vfd_dec->num); return 0; -err_reg_class: - class_unregister(&dev->v4ldec_class); err_dec_reg: destroy_workqueue(dev->decode_workqueue); err_event_workq: @@ -587,6 +512,13 @@ return ret; } +static const struct of_device_id aml_vcodec_match[] = { + {.compatible = "amlogic, vcodec-dec",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, aml_vcodec_match); + static int aml_vcodec_dec_remove(struct platform_device *pdev) { struct aml_vcodec_dev *dev = platform_get_drvdata(pdev); @@ -594,8 +526,6 @@ flush_workqueue(dev->decode_workqueue); destroy_workqueue(dev->decode_workqueue); - class_unregister(&dev->v4ldec_class); - if (dev->m2m_dev_dec) v4l2_m2m_release(dev->m2m_dev_dec); @@ -604,17 +534,12 @@ v4l2_device_unregister(&dev->v4l2_dev); - dev_info(&pdev->dev, "v4ldec removed.\n"); - return 0; } -static const struct of_device_id aml_vcodec_match[] = { - {.compatible = "amlogic, vcodec-dec",}, - {}, -}; - -MODULE_DEVICE_TABLE(of, aml_vcodec_match); +/*static void aml_vcodec_dev_release(struct device *dev) +{ +}*/ static struct platform_driver aml_vcodec_dec_driver = { .probe = aml_vcodec_probe, @@ -625,36 +550,44 @@ }, }; +/* +static struct platform_device aml_vcodec_dec_device = { + .name = AML_VCODEC_DEC_NAME, + .dev.release = aml_vcodec_dev_release, +};*/ + +module_platform_driver(aml_vcodec_dec_driver); + +/* static int __init amvdec_ports_init(void) { - pr_info("v4l dec module init\n"); + int ret; - if (platform_driver_register(&aml_vcodec_dec_driver)) { - pr_err("failed to register v4l dec driver\n"); - return -ENODEV; - } + ret = platform_device_register(&aml_vcodec_dec_device); + if (ret) + return ret; - return 0; + ret = platform_driver_register(&aml_vcodec_dec_driver); + if (ret) + platform_device_unregister(&aml_vcodec_dec_device); + + return ret; } static void __exit amvdec_ports_exit(void) { - pr_info("v4l dec module exit\n"); - platform_driver_unregister(&aml_vcodec_dec_driver); + platform_device_unregister(&aml_vcodec_dec_device); } module_init(amvdec_ports_init); module_exit(amvdec_ports_exit); +*/ u32 debug_mode; 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); - bool aml_set_vfm_enable; EXPORT_SYMBOL(aml_set_vfm_enable); module_param(aml_set_vfm_enable, bool, 0644); @@ -683,72 +616,20 @@ EXPORT_SYMBOL(multiplanar); module_param(multiplanar, bool, 0644); -int dump_capture_frame; +bool dump_capture_frame; EXPORT_SYMBOL(dump_capture_frame); -module_param(dump_capture_frame, int, 0644); - -int dump_vpp_input; -EXPORT_SYMBOL(dump_vpp_input); -module_param(dump_vpp_input, int, 0644); - -int dump_ge2d_input; -EXPORT_SYMBOL(dump_ge2d_input); -module_param(dump_ge2d_input, int, 0644); +module_param(dump_capture_frame, bool, 0644); int dump_output_frame; EXPORT_SYMBOL(dump_output_frame); module_param(dump_output_frame, int, 0644); -u32 dump_output_start_position; -EXPORT_SYMBOL(dump_output_start_position); -module_param(dump_output_start_position, uint, 0644); - EXPORT_SYMBOL(param_sets_from_ucode); module_param(param_sets_from_ucode, bool, 0644); EXPORT_SYMBOL(enable_drm_mode); module_param(enable_drm_mode, bool, 0644); -int bypass_vpp; -EXPORT_SYMBOL(bypass_vpp); -module_param(bypass_vpp, int, 0644); - -int bypass_ge2d; -EXPORT_SYMBOL(bypass_ge2d); -module_param(bypass_ge2d, int, 0644); - -int max_di_instance = 2; -EXPORT_SYMBOL(max_di_instance); -module_param(max_di_instance, int, 0644); - -int bypass_progressive = 1; -EXPORT_SYMBOL(bypass_progressive); -module_param(bypass_progressive, int, 0644); - -bool support_mjpeg; -EXPORT_SYMBOL(support_mjpeg); -module_param(support_mjpeg, bool, 0644); - -bool support_format_I420; -EXPORT_SYMBOL(support_format_I420); -module_param(support_format_I420, bool, 0644); - -int force_enable_nr; -EXPORT_SYMBOL(force_enable_nr); -module_param(force_enable_nr, int, 0644); - -int force_enable_di_local_buffer; -EXPORT_SYMBOL(force_enable_di_local_buffer); -module_param(force_enable_di_local_buffer, int, 0644); - -int vpp_bypass_frames; -EXPORT_SYMBOL(vpp_bypass_frames); -module_param(vpp_bypass_frames, int, 0644); - -int bypass_nr_flag; -EXPORT_SYMBOL(bypass_nr_flag); -module_param(bypass_nr_flag, 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..2e9e576 100644 --- a/drivers/amvdec_ports/aml_vcodec_drv.h +++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -20,19 +20,14 @@ #ifndef _AML_VCODEC_DRV_H_ #define _AML_VCODEC_DRV_H_ -#include <linux/kref.h> #include <linux/platform_device.h> #include <linux/videodev2.h> -#include <linux/kfifo.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #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 "aml_vcodec_util.h" -#include "aml_vcodec_dec.h" #define AML_VCODEC_DRV_NAME "aml_vcodec_drv" #define AML_VCODEC_DEC_NAME "aml-vcodec-dec" @@ -71,8 +66,6 @@ #define V4L_CAP_BUFF_INVALID (0) #define V4L_CAP_BUFF_IN_M2M (1) #define V4L_CAP_BUFF_IN_DEC (2) -#define V4L_CAP_BUFF_IN_VPP (3) -#define V4L_CAP_BUFF_IN_GE2D (4) /* v4l reset mode */ #define V4L_RESET_MODE_NORMAL (1 << 0) /* reset vdec_input and decoder. */ @@ -86,7 +79,6 @@ /* Instance is currently aborting */ #define TRANS_ABORT (1 << 2) -#define CTX_BUF_TOTAL(ctx) (ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size) /** * enum aml_hw_reg_idx - AML hw register base index */ @@ -127,6 +119,7 @@ * @AML_STATE_ACTIVE - vdec is ready for work. * @AML_STATE_FLUSHING - vdec is flushing. Only used by decoder * @AML_STATE_FLUSHED - decoder has transacted the last frame. + * @AML_STATE_RESET - decoder has be reset after flush. * @AML_STATE_ABORT - vcodec should be aborted */ enum aml_instance_state { @@ -137,6 +130,7 @@ AML_STATE_ACTIVE, AML_STATE_FLUSHING, AML_STATE_FLUSHED, + AML_STATE_RESET, AML_STATE_ABORT, }; @@ -162,10 +156,9 @@ * struct aml_video_fmt - Structure used to store information about pixelformats */ struct aml_video_fmt { - u32 fourcc; + u32 fourcc; enum aml_fmt_type type; - u32 num_planes; - const u8 *name; + u32 num_planes; }; /** @@ -190,13 +183,13 @@ * struct aml_q_data - Structure used to store information about queue */ struct aml_q_data { - u32 visible_width; - u32 visible_height; - u32 coded_width; - u32 coded_height; + unsigned int visible_width; + unsigned int visible_height; + unsigned int coded_width; + unsigned int coded_height; enum v4l2_field field; - u32 bytesperline[AML_VCODEC_MAX_PLANES]; - u32 sizeimage[AML_VCODEC_MAX_PLANES]; + unsigned int bytesperline[AML_VCODEC_MAX_PLANES]; + unsigned int sizeimage[AML_VCODEC_MAX_PLANES]; struct aml_video_fmt *fmt; bool resolution_changed; }; @@ -221,19 +214,42 @@ * @force_intra: force/insert intra frame */ struct aml_enc_params { - u32 bitrate; - u32 num_b_frame; - u32 rc_frame; - u32 rc_mb; - u32 seq_hdr_mode; - u32 intra_period; - u32 gop_size; - u32 framerate_num; - u32 framerate_denom; - u32 h264_max_qp; - u32 h264_profile; - u32 h264_level; - u32 force_intra; + unsigned int bitrate; + unsigned int num_b_frame; + unsigned int rc_frame; + unsigned int rc_mb; + unsigned int seq_hdr_mode; + unsigned int intra_period; + unsigned int gop_size; + unsigned int framerate_num; + unsigned int framerate_denom; + unsigned int h264_max_qp; + unsigned int h264_profile; + unsigned int h264_level; + unsigned int force_intra; +}; + +/** + * struct aml_vcodec_pm - Power management data structure + */ +struct aml_vcodec_pm { + struct clk *vdec_bus_clk_src; + struct clk *vencpll; + + struct clk *vcodecpll; + struct clk *univpll_d2; + struct clk *clk_cci400_sel; + struct clk *vdecpll; + struct clk *vdec_sel; + struct clk *vencpll_d2; + struct clk *venc_sel; + struct clk *univpll1_d2; + struct clk *venc_lt_sel; + struct device *larbvdec; + struct device *larbvenc; + struct device *larbvenclt; + struct device *dev; + struct aml_vcodec_dev *amldev; }; /** @@ -250,38 +266,20 @@ * plane * E.g. suppose picture size is 176x144, * buffer size will be aligned to 176x160. - * @profile_idc: source profile level * @field: frame/field information. - * @dpb_frames: used for DPB size of calculation. - * @dpb_margin: extra buffers for decoder. - * @vpp_margin: extra buffers for vpp. */ struct vdec_pic_info { - u32 visible_width; - u32 visible_height; - u32 coded_width; - u32 coded_height; - u32 y_bs_sz; - u32 c_bs_sz; - u32 y_len_sz; - u32 c_len_sz; + unsigned int visible_width; + unsigned int visible_height; + unsigned int coded_width; + unsigned int coded_height; + unsigned int y_bs_sz; + unsigned int c_bs_sz; + unsigned int y_len_sz; + unsigned int c_len_sz; int profile_idc; + int ref_frame_count; enum v4l2_field field; - u32 dpb_frames; - u32 dpb_margin; - u32 vpp_margin; -}; - -/** - * 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 - * @frame_buffer_size: SG page number to store the frame - */ -struct vdec_comp_buf_info { - u32 max_size; - u32 header_size; - u32 frame_buffer_size; }; struct aml_vdec_cfg_infos { @@ -292,20 +290,6 @@ u32 canvas_mem_mode; u32 canvas_mem_endian; u32 low_latency_mode; - u32 uvm_hook_type; - /* - * 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 1 : Non-standard dv flag. - * bit 0 : dv two layer flag. - */ - u32 metadata_config_flag; // for metadata config flag - u32 duration; - u32 data[4]; }; struct aml_vdec_hdr_infos { @@ -339,10 +323,8 @@ u32 mb_height; u32 dpb_size; u32 ref_frames; - u32 dpb_frames; - u32 dpb_margin; + u32 reorder_frames; u32 field; - u32 data[3]; }; struct aml_vdec_cnt_infos { @@ -379,7 +361,7 @@ */ u32 seq[V4L_CAP_BUFF_MAX]; u32 in, out; - u32 dec, vpp, ge2d; + u32 dec, vpp; }; enum aml_thread_type { @@ -390,203 +372,35 @@ typedef void (*aml_thread_func)(struct aml_vcodec_ctx *ctx); struct aml_vdec_thread { - struct list_head node; - spinlock_t lock; - struct semaphore sem; - struct task_struct *task; - enum aml_thread_type type; - void *priv; - int stop; + struct list_head node; + spinlock_t lock; + struct semaphore sem; + struct task_struct *task; + enum aml_thread_type type; + void *priv; + int stop; - aml_thread_func func; + aml_thread_func func; }; -/* struct internal_comp_buf - compressed buffer - * @index: index of this buf within (B)MMU BOX - * @ref: [0-7]:reference number of this buf - * [8-15]: use for reuse. - * @mmu_box: mmu_box of context - * @bmmu_box: bmmu_box of context - * @box_ref: box_ref of context - * @header_addr: header for compressed buffer - * @frame_buffer_size: SG buffer page number from - * @priv_data use for video composer - * struct vdec_comp_buf_info - */ -struct internal_comp_buf { - u32 index; - u32 ref; - void *mmu_box; - void *bmmu_box; - struct kref *box_ref; - - ulong header_addr; - u32 header_size; - u32 frame_buffer_size; - struct file_private_data priv_data; - ulong header_dw_addr; - void *mmu_box_dw; - void *bmmu_box_dw; -}; - -/* - * struct aml_uvm_buff_ref - uvm buff is used reseve ctx ref count. - * @index : index of video buffer. - * @addr : physic address of video buffer. - * @ref : reference of v4ldec context. - * @dma : dma buf of associated with vb. - */ -struct aml_uvm_buff_ref { - int index; - ulong addr; - struct kref *ref; - struct dma_buf *dbuf; -}; - -/* - * enum aml_fb_requester - indicate which module request fb buffers. - */ -enum aml_fb_requester { - AML_FB_REQ_DEC, - AML_FB_REQ_VPP, - AML_FB_REQ_GE2D, - AML_FB_REQ_MAX -}; - -/* - * @query: try to achieved fb token. - * @alloc: used for allocte fb buffer. - */ -struct aml_fb_ops { - bool (*query)(struct aml_fb_ops *, ulong *); - int (*alloc)(struct aml_fb_ops *, ulong, struct vdec_v4l2_buffer **, u32); -}; - -/* - * struct aml_fb_map_table - record some buffer map infos - * @addr : yuv linear buffer address. - * @header_addr : used for compress buffer. - * @vframe : which is from decoder or vpp vf pool. - * @task : context of task chain. - * @icomp : compress buffer index. - */ -struct aml_fb_map_table { - ulong addr; - ulong header_addr; - struct vframe_s *vframe; - struct task_chain_s *task; - u32 icomp; -}; - -/* - * struct aux_data - record sei data and dv data - * @sei_size: sei data size. - * @sei_buf: sei data addr. - * @sei_state: sei buffer state. (0 free, 1 not used, 2 used) - * @comp_buf: stores comp data parsed from sei data. - * @md_buf: stores md data parsed from sei data. - */ -struct aux_data { - int sei_size; - char* sei_buf; - int sei_state; - char* comp_buf; - char* md_buf; -}; - -/* - * struct aux_info - record aux data infos - * @sei_index: sei data index. - * @dv_index: dv data index. - * @sei_need_free: sei buffer need to free. - * @bufs: stores aux data. - * @alloc_buffer: alloc aux buffer functions. - * @free_buffer: free aux buffer functions. - * @free_one_sei_buffer:free sei buffer with index functions. - * @bind_sei_buffer: bind sei buffer functions. - * @bind_dv_buffer: bind dv buffer functions. - */ -struct aux_info { - int sei_index; - int dv_index; - bool sei_need_free; - struct aux_data bufs[V4L_CAP_BUFF_MAX]; - void (*alloc_buffer)(struct aml_vcodec_ctx *ctx, int flag); - void (*free_buffer)(struct aml_vcodec_ctx *ctx, int flag); - 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); -}; - -/* - * struct meta_data - record meta data. - * @buf[META_DATA_SIZE]: meta data information. - */ -struct meta_data { - char buf[META_DATA_SIZE]; -}; - -/* - * struct meta_info - record some meta data infos - * @index: meta data index. - * @meta_bufs: record meta data. - */ -struct meta_info { - int index; - struct meta_data *meta_bufs; -}; - -/* - * struct aml_vpp_cfg_infos - config vpp init param - * @mode : vpp work mode - * @fmt : picture format used to switch nv21 or nv12. - * @buf_size: config buffer size for vpp - * @is_drm : is drm mode - * @is_prog : is a progressive source. - * @is_bypass_p : to set progressive bypass in vpp - * @enable_nr : enable nosie reduce. - * @enable_local_buf: DI used buff alloc by itself. - * @res_chg : indicate resolution changed. - * @is_vpp_reset: vpp reset just used to res chg. - */ -struct aml_vpp_cfg_infos { - u32 mode; - u32 fmt; - u32 buf_size; - bool is_drm; - bool is_prog; - bool is_bypass_p; - bool enable_nr; - bool enable_local_buf; - bool res_chg; - bool is_vpp_reset; -}; - -struct aml_ge2d_cfg_infos { - u32 mode; - u32 buf_size; - bool is_drm; -}; - -/* +/** * struct aml_vcodec_ctx - Context (instance) private data. + * * @id: index of the context that this structure describes. - * @ctx_ref: for deferred free of this context. * @type: type of the instance - decoder or encoder. * @dev: pointer to the aml_vcodec_dev of the device. * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context. * @ada_ctx: pointer to the aml_vdec_adapt of the context. - * @vpp: pointer to video post processor * @dec_if: hooked decoder driver interface. * @drv_handle: driver handle for specific decode instance * @fh: struct v4l2_fh. * @ctrl_hdl: handler for v4l2 framework. * @slock: protect v4l2 codec context. - * @tsplock: protect the vdec thread context. * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. * @list: link to ctx_list of aml_vcodec_dev. * @q_data: store information of input and output queue of the context. * @queue: waitqueue that can be used to wait for this context to finish. + * @lock: protect the vdec thread. * @state_lock: protect the codec status. * @state: state of the context. * @decode_work: decoder work be used to output buffer. @@ -594,7 +408,6 @@ * @cap_pool: capture buffers are remark in the pool. * @vdec_thread_list: vdec thread be used to capture. * @dpb_size: store dpb count after header parsing - * @vpp_size: store vpp buffer count after header parsing * @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. @@ -617,46 +430,24 @@ * @reset_flag: reset mode includes lightly and normal mode. * @decoded_frame_cnt: the capture buffer deque number to be count. * @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. - * @dmabuff_recycle: kfifo used for store vb buff. - * @capture_buffer: kfifo used for store capture vb buff. - * @mmu_box: mmu_box of context. - * @bmmu_box: bmmu_box of context. - * @box_ref: box_ref of context. - * @comp_info: compress buffer information. - * @comp_bufs: compress buffer describe. - * @comp_lock: used for lock ibuf free cb. - * @fb_ops: frame buffer ops interface. - * @dv_infos: dv data information. - * @vpp_cfg: vpp init parms of configuration. - * @vdec_pic_info_update: update pic info cb. - * @vpp_is_need: the instance is need vpp. - * @task_chain_pool: used to store task chain inst. - * @index_disp: the number of frames output. */ struct aml_vcodec_ctx { int id; - struct kref ctx_ref; enum aml_instance_type type; struct aml_vcodec_dev *dev; struct v4l2_m2m_ctx *m2m_ctx; struct aml_vdec_adapt *ada_ctx; - struct aml_v4l2_vpp *vpp; const struct vdec_common_if *dec_if; ulong drv_handle; struct v4l2_fh fh; struct v4l2_ctrl_handler ctrl_hdl; spinlock_t slock; - spinlock_t tsplock; struct aml_video_dec_buf *empty_flush_buf; struct list_head list; struct aml_q_data q_data[2]; wait_queue_head_t queue; - struct mutex state_lock; + struct mutex lock, state_lock; enum aml_instance_state state; struct work_struct decode_work; bool output_thread_ready; @@ -664,8 +455,6 @@ struct list_head vdec_thread_list; int dpb_size; - int vpp_size; - int ge2d_size; bool param_sets_from_ucode; bool v4l_codec_dpb_ready; bool v4l_resolution_change; @@ -678,7 +467,6 @@ enum v4l2_quantization quantization; enum v4l2_xfer_func xfer_func; u32 cap_pix_fmt; - u32 output_pix_fmt; bool has_receive_eos; bool is_drm_mode; @@ -689,84 +477,81 @@ int reset_flag; int decoded_frame_cnt; 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; - DECLARE_KFIFO(dmabuff_recycle, struct vb2_v4l2_buffer *, 32); - DECLARE_KFIFO(capture_buffer, struct vb2_v4l2_buffer *, 32); - - /* compressed buffer support */ - void *bmmu_box; - void *mmu_box; - struct kref box_ref; - struct vdec_comp_buf_info comp_info; - struct internal_comp_buf *comp_bufs; - struct uvm_hook_mod_info *uvm_proxy; - struct mutex comp_lock; - - struct aml_fb_ops fb_ops; - ulong token_table[32]; - - struct aml_fb_map_table fb_map[32]; - struct aml_vpp_cfg_infos vpp_cfg; - void (*vdec_pic_info_update)(struct aml_vcodec_ctx *ctx); - bool vpp_is_need; - struct list_head task_chain_pool; - struct meta_info meta_infos; - struct vdec_sync *sync; - u32 internal_dw_scale; - - /* ge2d field. */ - struct aml_v4l2_ge2d *ge2d; - struct aml_ge2d_cfg_infos ge2d_cfg; - bool ge2d_is_need; - - bool second_field_pts_mode; - struct aux_info aux_infos; - u32 index_disp; - bool post_to_upper_done; - bool film_grain_present; - void *bmmu_box_dw; - void *mmu_box_dw; }; /** - * struct aml_vcodec_dev - driver data. - * @v4l2_dev : V4L2 device to register video devices for. - * @vfd_dec : Video device for decoder. - * @plat_dev : platform device. - * @m2m_dev_dec : m2m device for decoder. - * @curr_ctx : The context that is waiting for codec hardware. - * @id_counter : used to identify current opened instance. - * @dec_capability : used to identify decode capability, ex: 4k - * @decode_workqueue : the worker used to output buffer schedule. - * @ctx_list : list of struct aml_vcodec_ctx. - * @irqlock : protect data access by irq handler and work thread. - * @dev_mutex : video_device lock. - * @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. + * struct aml_vcodec_dev - driver data + * @v4l2_dev: V4L2 device to register video devices for. + * @vfd_dec: Video device for decoder + * @vfd_enc: Video device for encoder. + * + * @m2m_dev_dec: m2m device for decoder + * @m2m_dev_enc: m2m device for encoder. + * @plat_dev: platform device + * @vpu_plat_dev: aml vpu platform device + * @alloc_ctx: VB2 allocator context + * (for allocations without kernel mapping). + * @ctx_list: list of struct aml_vcodec_ctx + * @irqlock: protect data access by irq handler and work thread + * @curr_ctx: The context that is waiting for codec hardware + * + * @reg_base: Mapped address of AML Vcodec registers. + * + * @id_counter: used to identify current opened instance + * + * @encode_workqueue: encode work queue + * + * @int_cond: used to identify interrupt condition happen + * @int_type: used to identify what kind of interrupt condition happen + * @dev_mutex: video_device lock + * @queue: waitqueue for waiting for completion of device commands + * + * @dec_irq: decoder irq resource + * @enc_irq: h264 encoder irq resource + * @enc_lt_irq: vp8 encoder irq resource + * + * @dec_mutex: decoder hardware lock + * @enc_mutex: encoder hardware lock. + * + * @pm: power management control + * @dec_capability: used to identify decode capability, ex: 4k + * @enc_capability: used to identify encode capability */ struct aml_vcodec_dev { - struct v4l2_device v4l2_dev; - struct video_device *vfd_dec; - struct platform_device *plat_dev; - struct v4l2_m2m_dev *m2m_dev_dec; - struct aml_vcodec_ctx *curr_ctx; - ulong id_counter; - u32 dec_capability; - struct workqueue_struct *decode_workqueue; - struct list_head ctx_list; - struct file *filp; - spinlock_t irqlock; - struct mutex dev_mutex; - struct mutex dec_mutex; - wait_queue_head_t queue; - atomic_t vpp_count; - struct class v4ldec_class; + struct v4l2_device v4l2_dev; + struct video_device *vfd_dec; + struct video_device *vfd_enc; + struct file *filp; + + struct v4l2_m2m_dev *m2m_dev_dec; + struct v4l2_m2m_dev *m2m_dev_enc; + struct platform_device *plat_dev; + struct platform_device *vpu_plat_dev;//?? + struct vb2_alloc_ctx *alloc_ctx;//?? + struct list_head ctx_list; + spinlock_t irqlock; + struct aml_vcodec_ctx *curr_ctx; + void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE]; + + unsigned long id_counter; + + struct workqueue_struct *decode_workqueue; + struct workqueue_struct *encode_workqueue; + int int_cond; + int int_type; + struct mutex dev_mutex; + wait_queue_head_t queue; + + int dec_irq; + int enc_irq; + int enc_lt_irq; + + struct mutex dec_mutex; + struct mutex enc_mutex; + + struct aml_vcodec_pm pm; + unsigned int dec_capability; + unsigned int enc_capability; }; static inline struct aml_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh) @@ -779,10 +564,4 @@ return container_of(ctrl->handler, struct aml_vcodec_ctx, ctrl_hdl); } -void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx); -void aml_thread_post_task(struct aml_vcodec_ctx *ctx, enum aml_thread_type type); -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); - #endif /* _AML_VCODEC_DRV_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.c b/drivers/amvdec_ports/aml_vcodec_ge2d.c deleted file mode 100644 index 2d331ed..0000000 --- a/drivers/amvdec_ports/aml_vcodec_ge2d.c +++ /dev/null
@@ -1,968 +0,0 @@ -/* -* 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 <linux/sched/clock.h> -#include <uapi/linux/sched/types.h> -#include <linux/amlogic/meson_uvm_core.h> -#include <linux/amlogic/media/ge2d/ge2d.h> -#include <linux/amlogic/media/canvas/canvas_mgr.h> - -#include "../common/chips/decoder_cpu_ver_info.h" -#include "aml_vcodec_ge2d.h" -#include "aml_vcodec_adapt.h" -#include "vdec_drv_if.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_buf->vb.vb2_buf.index) -#define INPUT_PORT 0 -#define OUTPUT_PORT 1 - -extern int dump_ge2d_input; -extern int ge2d_bypass_frames; - -enum GE2D_FLAG { - GE2D_FLAG_P = 0x1, - GE2D_FLAG_I = 0x2, - GE2D_FLAG_EOS = 0x4, - GE2D_FLAG_BUF_BY_PASS = 0x8, - GE2D_FLAG_MAX = 0x7FFFFFFF, -}; - -enum videocom_source_type { - DECODER_8BIT_NORMAL = 0, - DECODER_8BIT_BOTTOM, - DECODER_8BIT_TOP, - DECODER_10BIT_NORMAL, - DECODER_10BIT_BOTTOM, - DECODER_10BIT_TOP -}; - -#ifndef CONFIG_AMLOGIC_MEDIA_GE2D -inline void stretchblt_noalpha(struct ge2d_context_s *wq, - int src_x, int src_y, int src_w, int src_h, - int dst_x, int dst_y, int dst_w, int dst_h) { return; } -inline int ge2d_context_config_ex(struct ge2d_context_s *context, - struct config_para_ex_s *ge2d_config) { return -1; } -inline struct ge2d_context_s *create_ge2d_work_queue(void) { return NULL; } -inline int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { return -1; } -#endif - -static int get_source_type(struct vframe_s *vf) -{ - enum videocom_source_type ret; - int interlace_mode; - - interlace_mode = vf->type & VIDTYPE_TYPEMASK; - - if ((vf->bitdepth & BITDEPTH_Y10) && - (!(vf->type & VIDTYPE_COMPRESS)) && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) { - if (interlace_mode == VIDTYPE_INTERLACE_TOP) - ret = DECODER_10BIT_TOP; - else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM) - ret = DECODER_10BIT_BOTTOM; - else - ret = DECODER_10BIT_NORMAL; - } else { - if (interlace_mode == VIDTYPE_INTERLACE_TOP) - ret = DECODER_8BIT_TOP; - else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM) - ret = DECODER_8BIT_BOTTOM; - else - ret = DECODER_8BIT_NORMAL; - } - - return ret; -} - -static int get_input_format(struct vframe_s *vf) -{ - int format = GE2D_FORMAT_M24_YUV420; - enum videocom_source_type soure_type; - - soure_type = get_source_type(vf); - - switch (soure_type) { - case DECODER_8BIT_NORMAL: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422; - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21; - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12; - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444; - else - format = GE2D_FORMAT_M24_YUV420; - break; - case DECODER_8BIT_BOTTOM: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422 - | (GE2D_FORMAT_S16_YUV422B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21 - | (GE2D_FORMAT_M24_NV21B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12 - | (GE2D_FORMAT_M24_NV12B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444 - | (GE2D_FORMAT_S24_YUV444B & (3 << 3)); - else - format = GE2D_FORMAT_M24_YUV420 - | (GE2D_FMT_M24_YUV420B & (3 << 3)); - break; - case DECODER_8BIT_TOP: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422 - | (GE2D_FORMAT_S16_YUV422T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21 - | (GE2D_FORMAT_M24_NV21T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12 - | (GE2D_FORMAT_M24_NV12T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444 - | (GE2D_FORMAT_S24_YUV444T & (3 << 3)); - else - format = GE2D_FORMAT_M24_YUV420 - | (GE2D_FMT_M24_YUV420T & (3 << 3)); - break; - case DECODER_10BIT_NORMAL: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422; - else - format = GE2D_FORMAT_S16_12BIT_YUV422; - } - break; - case DECODER_10BIT_BOTTOM: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422 - | (GE2D_FORMAT_S16_10BIT_YUV422B - & (3 << 3)); - else - format = GE2D_FORMAT_S16_12BIT_YUV422 - | (GE2D_FORMAT_S16_12BIT_YUV422B - & (3 << 3)); - } - break; - case DECODER_10BIT_TOP: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422 - | (GE2D_FORMAT_S16_10BIT_YUV422T - & (3 << 3)); - else - format = GE2D_FORMAT_S16_12BIT_YUV422 - | (GE2D_FORMAT_S16_12BIT_YUV422T - & (3 << 3)); - } - break; - default: - format = GE2D_FORMAT_M24_YUV420; - } - return format; -} - -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; - bool eos = false; - - if (!ge2d || !ge2d->ctx) { - v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, - "fatal %s %d ge2d:%px\n", - __func__, __LINE__, ge2d); - return -1; - } - - fb = &buf->aml_buf->frame_buffer; - 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", - buf->vf, - buf->vf->index, - buf->vf->flag, - buf->flag, - eos ? "eos" : "", - buf->vf->timestamp, - kfifo_len(&ge2d->input), - kfifo_len(&ge2d->output), - kfifo_len(&ge2d->frame), - kfifo_len(&ge2d->in_done_q), - kfifo_len(&ge2d->out_done_q)); - - fb->task->recycle(fb->task, TASK_TYPE_GE2D); - - kfifo_put(&ge2d->input, buf); - - ATRACE_COUNTER("VC_IN_GE2D-1.recycle", fb->buf_idx); - - return 0; -} - -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; - bool bypass = false; - bool eos = false; - - if (!ge2d || !ge2d->ctx) { - v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, - "fatal %s %d ge2d:%px\n", - __func__, __LINE__, ge2d); - return -1; - } - - fb = &buf->aml_buf->frame_buffer; - eos = (buf->flag & GE2D_FLAG_EOS); - bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS); - - /* recovery fb handle. */ - buf->vf->v4l_mem_handle = (ulong)fb; - - kfifo_put(&ge2d->out_done_q, 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", - buf->vf, - buf->vf->index, - buf->vf->flag, - buf->flag, - eos ? "eos" : "", - buf->vf->timestamp, - kfifo_len(&ge2d->input), - kfifo_len(&ge2d->output), - kfifo_len(&ge2d->frame), - kfifo_len(&ge2d->in_done_q), - kfifo_len(&ge2d->out_done_q), - buf->vf->width, buf->vf->height); - - ATRACE_COUNTER("VC_OUT_GE2D-2.submit", fb->buf_idx); - - fb->task->submit(fb->task, TASK_TYPE_GE2D); - - ge2d->out_num[OUTPUT_PORT]++; - - return 0; -} - -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 vframe_s *vf = NULL; - bool bypass = false; - bool eos = false; - - if (!ge2d || !ge2d->ctx) { - v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, - "fatal %s %d ge2d:%px\n", - __func__, __LINE__, ge2d); - return; - } - - if (kfifo_get(&ge2d->out_done_q, &buf)) { - fb = &buf->aml_buf->frame_buffer; - eos = (buf->flag & GE2D_FLAG_EOS); - bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS); - vf = buf->vf; - - if (eos) { - v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL, - "%s %d got eos\n", - __func__, __LINE__); - vf->type |= VIDTYPE_V4L_EOS; - vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - } - - *vf_out = vf; - - ATRACE_COUNTER("VC_OUT_GE2D-3.vf_get", fb->buf_idx); - - 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", - __func__, vf, - vf->index, - vf->flag, - buf->flag, - vf->timestamp, vf->type, vf->width, vf->height); - } -} - -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) -{ - struct aml_v4l2_ge2d* ge2d = param; - struct aml_vcodec_ctx *ctx = ge2d->ctx; - struct config_para_ex_s ge2d_config; - u32 src_fmt = 0, dst_fmt = 0; - struct canvas_s cd; - ulong start_time; - - v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "enter ge2d thread\n"); - while (ge2d->running) { - 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; - - if (down_interruptible(&ge2d->sem_in)) - goto exit; -retry: - if (!ge2d->running) - break; - - if (kfifo_is_empty(&ge2d->output)) { - if (down_interruptible(&ge2d->sem_out)) - goto exit; - goto retry; - } - - mutex_lock(&ge2d->output_lock); - if (!kfifo_get(&ge2d->output, &out_buf)) { - mutex_unlock(&ge2d->output_lock); - v4l_dbg(ctx, 0, "ge2d can not get output\n"); - goto exit; - } - 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; - } - - /* safe to pop in_buf */ - if (!kfifo_get(&ge2d->in_done_q, &in_buf)) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "ge2d can not get input\n"); - goto exit; - } - - mutex_lock(&ge2d->output_lock); - if (!kfifo_get(&ge2d->frame, &vf_out)) { - mutex_unlock(&ge2d->output_lock); - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "ge2d can not get frame\n"); - goto exit; - } - mutex_unlock(&ge2d->output_lock); - - fb = &out_buf->aml_buf->frame_buffer; - fb->status = FB_ST_GE2D; - - /* fill output vframe information. */ - memcpy(vf_out, in_buf->vf, sizeof(*vf_out)); - memcpy(vf_out->canvas0_config, - 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[1].phy_addr = - fb->m.mem[0].addr + fb->m.mem[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); - } else { - vf_out->canvas0_config[1].phy_addr = - fb->m.mem[1].addr; - vf_out->canvas0_config[2].phy_addr = - fb->m.mem[2].addr; - } - - /* fill outbuf parms. */ - out_buf->vf = vf_out; - out_buf->flag = 0; - out_buf->caller_data = ge2d; - - /* fill inbuf parms. */ - in_buf->caller_data = ge2d; - - 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; - else - src_fmt |= GE2D_LITTLE_ENDIAN; - - /* negotiate format of destination */ - dst_fmt = get_input_format(in_buf->vf); - if (ge2d->work_mode & GE2D_MODE_CONVERT_NV12) - dst_fmt |= GE2D_FORMAT_M24_NV12; - else if (ge2d->work_mode & GE2D_MODE_CONVERT_NV21) - dst_fmt |= GE2D_FORMAT_M24_NV21; - - if (ge2d->work_mode & GE2D_MODE_CONVERT_LE) - dst_fmt |= GE2D_LITTLE_ENDIAN; - else - dst_fmt |= GE2D_BIG_ENDIAN; - - if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV12) { - vf_out->type |= VIDTYPE_VIU_NV12; - vf_out->type &= ~VIDTYPE_VIU_NV21; - } else if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV21) { - vf_out->type |= VIDTYPE_VIU_NV21; - vf_out->type &= ~VIDTYPE_VIU_NV12; - } - if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_LITTLE_ENDIAN) { - vf_out->canvas0_config[0].endian = 0; - vf_out->canvas0_config[1].endian = 0; - vf_out->canvas0_config[2].endian = 0; - } else if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_BIG_ENDIAN){ - vf_out->canvas0_config[0].endian = 7; - vf_out->canvas0_config[1].endian = 7; - vf_out->canvas0_config[2].endian = 7; - } - - start_time = local_clock(); - /* 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]); - ge2d_config.src_para.canvas_index = - ge2d->src_canvas_id[0] | - ge2d->src_canvas_id[1] << 8 | - ge2d->src_canvas_id[2] << 16; - - ge2d_config.src_planes[0].addr = - in_buf->vf->canvas0_config[0].phy_addr; - ge2d_config.src_planes[0].w = - in_buf->vf->canvas0_config[0].width; - ge2d_config.src_planes[0].h = - in_buf->vf->canvas0_config[0].height; - ge2d_config.src_planes[1].addr = - in_buf->vf->canvas0_config[1].phy_addr; - ge2d_config.src_planes[1].w = - in_buf->vf->canvas0_config[1].width; - ge2d_config.src_planes[1].h = - in_buf->vf->canvas0_config[1].height; - ge2d_config.src_planes[2].addr = - in_buf->vf->canvas0_config[2].phy_addr; - ge2d_config.src_planes[2].w = - in_buf->vf->canvas0_config[2].width; - ge2d_config.src_planes[2].h = - in_buf->vf->canvas0_config[2].height; - } else { - ge2d_config.src_para.canvas_index = in_buf->vf->canvas0Addr; - } - ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.src_para.format = src_fmt; - ge2d_config.src_para.fill_color_en = 0; - ge2d_config.src_para.fill_mode = 0; - ge2d_config.src_para.x_rev = 0; - ge2d_config.src_para.y_rev = 0; - ge2d_config.src_para.color = 0xffffffff; - ge2d_config.src_para.top = 0; - ge2d_config.src_para.left = 0; - ge2d_config.src_para.width = in_buf->vf->width; - if (in_buf->vf->type & VIDTYPE_INTERLACE) - ge2d_config.src_para.height = in_buf->vf->height >> 1; - else - 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]); - 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]); - 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); - 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); - ge2d_config.dst_planes[1].addr = cd.addr; - ge2d_config.dst_planes[1].w = cd.width; - ge2d_config.dst_planes[1].h = cd.height; - - ge2d_config.dst_para.format = dst_fmt; - ge2d_config.dst_para.width = in_buf->vf->width; - ge2d_config.dst_para.height = in_buf->vf->height; - ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.dst_para.fill_color_en = 0; - ge2d_config.dst_para.fill_mode = 0; - ge2d_config.dst_para.x_rev = 0; - ge2d_config.dst_para.y_rev = 0; - ge2d_config.dst_para.color = 0; - ge2d_config.dst_para.top = 0; - ge2d_config.dst_para.left = 0; - - /* other ge2d parameters configure. */ - ge2d_config.src_key.key_enable = 0; - ge2d_config.src_key.key_mask = 0; - ge2d_config.src_key.key_mode = 0; - ge2d_config.alu_const_color = 0; - ge2d_config.bitmask_en = 0; - ge2d_config.src1_gb_alpha = 0; - ge2d_config.dst_xy_swap = 0; - ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID; - - ATRACE_COUNTER("VC_OUT_GE2D-1.handle_start", - in_buf->aml_buf->frame_buffer.buf_idx); - - 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), " - "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n", - in_buf->vf, in_buf->vf->index, - out_buf->vf, GE2D_BUF_GET_IDX(out_buf), - in_buf->vf->canvas0_config[0].phy_addr, - in_buf->vf->canvas0_config[1].phy_addr, - in_buf->vf->canvas0_config[0].width, - in_buf->vf->canvas0_config[0].height, - vf_out->canvas0_config[0].phy_addr, - vf_out->canvas0_config[1].phy_addr, - vf_out->canvas0_config[0].width, - vf_out->canvas0_config[0].height, - vf_out->width, vf_out->height, - src_fmt, dst_fmt, - kfifo_len(&ge2d->input), - kfifo_len(&ge2d->output), - kfifo_len(&ge2d->frame), - kfifo_len(&ge2d->in_done_q), - kfifo_len(&ge2d->out_done_q)); - - if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "ge2d_context_config_ex error.\n"); - goto exit; - } - - if (!(in_buf->flag & GE2D_FLAG_EOS)) { - if (in_buf->vf->type & VIDTYPE_INTERLACE) { - stretchblt_noalpha(ge2d->ge2d_context, - 0, 0, in_buf->vf->width, in_buf->vf->height / 2, - 0, 0, in_buf->vf->width, in_buf->vf->height); - } else { - stretchblt_noalpha(ge2d->ge2d_context, - 0, 0, in_buf->vf->width, in_buf->vf->height, - 0, 0, in_buf->vf->width, in_buf->vf->height); - } - } - - //pr_info("consume time %d us\n", div64_u64(local_clock() - start_time, 1000)); - - v4l_ge2d_fill_output_done(out_buf); - v4l_ge2d_empty_input_done(in_buf); - - ge2d->in_num[INPUT_PORT]++; - ge2d->out_num[INPUT_PORT]++; - } -exit: - while (!kthread_should_stop()) { - usleep_range(1000, 2000); - } - - v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "exit ge2d thread\n"); - - return 0; -} - -int aml_v4l2_ge2d_get_buf_num(u32 mode) -{ - return 4; -} - -int aml_v4l2_ge2d_init( - struct aml_vcodec_ctx *ctx, - struct aml_ge2d_cfg_infos *cfg, - struct aml_v4l2_ge2d** ge2d_handle) -{ - 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; - - if (!cfg || !ge2d_handle) - return -EINVAL; - - ge2d = kzalloc(sizeof(*ge2d), GFP_KERNEL); - if (!ge2d) - return -ENOMEM; - - ge2d->work_mode = work_mode; - - /* default convert little endian. */ - if (!ge2d->work_mode) { - ge2d->work_mode = GE2D_MODE_CONVERT_LE; - } - - ge2d->ge2d_context = create_ge2d_work_queue(); - if (!ge2d->ge2d_context) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "ge2d_create_instance fail\n"); - ret = -EINVAL; - goto error; - } - - INIT_KFIFO(ge2d->input); - INIT_KFIFO(ge2d->output); - INIT_KFIFO(ge2d->frame); - INIT_KFIFO(ge2d->out_done_q); - INIT_KFIFO(ge2d->in_done_q); - - ge2d->ctx = ctx; - buf_size = cfg->buf_size; - ge2d->buf_size = buf_size; - - /* setup output fifo */ - ret = kfifo_alloc(&ge2d->output, buf_size, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc output fifo fail.\n"); - ret = -ENOMEM; - goto error2; - } - - ge2d->ovbpool = vzalloc(buf_size * sizeof(*ge2d->ovbpool)); - if (!ge2d->ovbpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc output vb pool fail.\n"); - ret = -ENOMEM; - goto error3; - } - - /* setup vframe fifo */ - ret = kfifo_alloc(&ge2d->frame, buf_size, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc ge2d vframe fifo fail.\n"); - ret = -ENOMEM; - goto error4; - } - - ge2d->vfpool = vzalloc(buf_size * sizeof(*ge2d->vfpool)); - if (!ge2d->vfpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc vf pool fail.\n"); - ret = -ENOMEM; - goto error5; - } - - ret = kfifo_alloc(&ge2d->input, GE2D_FRAME_SIZE, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc input fifo fail.\n"); - ret = -ENOMEM; - goto error6; - } - - ge2d->ivbpool = vzalloc(GE2D_FRAME_SIZE * sizeof(*ge2d->ivbpool)); - if (!ge2d->ivbpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc input vb pool fail.\n"); - ret = -ENOMEM; - goto error7; - } - - for (i = 0 ; i < GE2D_FRAME_SIZE ; i++) { - kfifo_put(&ge2d->input, &ge2d->ivbpool[i]); - } - - for (i = 0 ; i < buf_size ; i++) { - kfifo_put(&ge2d->output, &ge2d->ovbpool[i]); - 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)) { - 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]); - goto error8; - } - - mutex_init(&ge2d->output_lock); - sema_init(&ge2d->sem_in, 0); - sema_init(&ge2d->sem_out, 0); - - ge2d->running = true; - ge2d->task = kthread_run(aml_v4l2_ge2d_thread, ge2d, - "%s", "aml-v4l2-ge2d"); - if (IS_ERR(ge2d->task)) { - ret = PTR_ERR(ge2d->task); - goto error9; - } - sched_setscheduler_nocheck(ge2d->task, SCHED_FIFO, ¶m); - - *ge2d_handle = ge2d; - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "GE2D_CFG bsize:%d, wkm:%x, bm:%x, drm:%d\n", - ge2d->buf_size, - ge2d->work_mode, - ge2d->buffer_mode, - cfg->is_drm); - - 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]); -error8: - vfree(ge2d->ivbpool); -error7: - kfifo_free(&ge2d->input); -error6: - vfree(ge2d->vfpool); -error5: - kfifo_free(&ge2d->frame); -error4: - vfree(ge2d->ovbpool); -error3: - kfifo_free(&ge2d->output); -error2: - destroy_ge2d_work_queue(ge2d->ge2d_context); -error: - kfree(ge2d); - - return ret; -} -EXPORT_SYMBOL(aml_v4l2_ge2d_init); - -int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d) -{ - 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); - - destroy_ge2d_work_queue(ge2d->ge2d_context); - /* no more ge2d callback below this line */ - - kfifo_free(&ge2d->frame); - vfree(ge2d->vfpool); - kfifo_free(&ge2d->output); - vfree(ge2d->ovbpool); - kfifo_free(&ge2d->input); - 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]); - - v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL, - "ge2d destroy done\n"); - - kfree(ge2d); - - return 0; -} -EXPORT_SYMBOL(aml_v4l2_ge2d_destroy); - -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; - - if (!ge2d) - return -EINVAL; - - if (!kfifo_get(&ge2d->input, &in_buf)) { - v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_ERROR, - "cat not get free input buffer.\n"); - return -1; - } - - if (vf->type & VIDTYPE_V4L_EOS) - in_buf->flag |= GE2D_FLAG_EOS; - - v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR, - "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); - in_buf->vf = vf; - - do { - unsigned int dw_mode = VDEC_DW_NO_AFBC; - struct file *fp; - - if (!dump_ge2d_input || ge2d->ctx->is_drm_mode) - break; - - if (vdec_if_get_param(ge2d->ctx, GET_PARAM_DW_MODE, &dw_mode)) - break; - - if (dw_mode == VDEC_DW_AFBC_ONLY) - break; - - fp = filp_open("/data/dec_dump_before.raw", - O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600); - if (!IS_ERR(fp)) { - struct vb2_buffer *vb = &in_buf->aml_buf->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_ge2d_input--; - filp_close(fp, NULL); - } - } while(0); - - ATRACE_COUNTER("VC_OUT_GE2D-0.receive", fb->buf_idx); - - kfifo_put(&ge2d->in_done_q, in_buf); - up(&ge2d->sem_in); - - return 0; -} - -static void fill_ge2d_buf_cb(void *v4l_ctx, void *fb_ctx) -{ - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)v4l_ctx; - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)fb_ctx; - int ret = -1; - - ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, fb->vframe); - if (ret < 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "ge2d push vframe err, ret: %d\n", ret); - } -} - -static struct task_ops_s ge2d_ops = { - .type = TASK_TYPE_GE2D, - .get_vframe = ge2d_vf_get, - .put_vframe = ge2d_vf_put, - .fill_buffer = fill_ge2d_buf_cb, -}; - -struct task_ops_s *get_ge2d_ops(void) -{ - return &ge2d_ops; -} -EXPORT_SYMBOL(get_ge2d_ops); -
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.h b/drivers/amvdec_ports/aml_vcodec_ge2d.h deleted file mode 100644 index a12931d..0000000 --- a/drivers/amvdec_ports/aml_vcodec_ge2d.h +++ /dev/null
@@ -1,89 +0,0 @@ -/* -* 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_GE2D_H_ -#define _AML_VCODEC_GE2D_H_ - -#include <linux/kfifo.h> -#include "aml_vcodec_drv.h" -#include "aml_vcodec_dec.h" - -/* define ge2d work mode. */ -#define GE2D_MODE_CONVERT_NV12 (1 << 0) -#define GE2D_MODE_CONVERT_NV21 (1 << 1) -#define GE2D_MODE_CONVERT_LE (1 << 2) -#define GE2D_MODE_CONVERT_BE (1 << 3) -#define GE2D_MODE_SEPARATE_FIELD (1 << 4) -#define GE2D_MODE_422_TO_420 (1 << 5) - -#define GE2D_FRAME_SIZE 64 - -struct aml_v4l2_ge2d_buf { - u32 flag; - struct vframe_s *vf; - void *caller_data; - struct aml_video_dec_buf *aml_buf; -}; - -struct aml_v4l2_ge2d { - struct ge2d_context_s *ge2d_context; /* handle of GE2D */ - u32 buf_size; /* buffer size for ge2d */ - u32 work_mode; /* enum ge2d_work_mode */ - u32 buffer_mode; - struct aml_vcodec_ctx *ctx; - - DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_ge2d_buf*)); - DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_ge2d_buf*)); - DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *)); - DECLARE_KFIFO(out_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE); - DECLARE_KFIFO(in_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE); - - struct vframe_s *vfpool; - struct aml_v4l2_ge2d_buf *ovbpool; - struct aml_v4l2_ge2d_buf *ivbpool; - struct task_struct *task; - bool running; - struct semaphore sem_in, sem_out; - - /* In p to i transition, output/frame can be multi writer */ - struct mutex output_lock; - - /* for debugging */ - /* - * in[0] --> ge2d <-- in[1] - * out[0]<-- ge2d --> out[1] - */ - 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); - -int aml_v4l2_ge2d_init( - struct aml_vcodec_ctx *ctx, - struct aml_ge2d_cfg_infos *cfg, - struct aml_v4l2_ge2d** ge2d_handle); - -int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d); - -#endif
diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c index 54b0d06..509a42a 100644 --- a/drivers/amvdec_ports/aml_vcodec_util.c +++ b/drivers/amvdec_ports/aml_vcodec_util.c
@@ -22,6 +22,72 @@ #include "aml_vcodec_drv.h" #include "aml_vcodec_util.h" +void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data, + unsigned int reg_idx) +{ + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data; + + if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "Invalid arguments, reg_idx=%d\n", reg_idx); + return NULL; + } + return ctx->dev->reg_base[reg_idx]; +} +EXPORT_SYMBOL(aml_vcodec_get_reg_addr); + +int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data, + struct aml_vcodec_mem *mem) +{ + unsigned long size = mem->size; + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data; + struct device *dev = &ctx->dev->plat_dev->dev; + + mem->vaddr = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL); + //mem->vaddr = codec_mm_dma_alloc_coherent(dev_name(dev), size, + // &mem->dma_addr, GFP_KERNEL, 0); + if (!mem->vaddr) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "%s dma_alloc size=%ld failed!\n", dev_name(dev), + size); + return -ENOMEM; + } + + memset(mem->vaddr, 0, size); + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size); + + return 0; +} +EXPORT_SYMBOL(aml_vcodec_mem_alloc); + +void aml_vcodec_mem_free(struct aml_vcodec_ctx *data, + struct aml_vcodec_mem *mem) +{ + unsigned long size = mem->size; + struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data; + struct device *dev = &ctx->dev->plat_dev->dev; + + if (!mem->vaddr) { + v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, + "%s dma_free size=%ld failed!\n", dev_name(dev), + size); + return; + } + + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr); + v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size); + + dma_free_coherent(dev, size, mem->vaddr, mem->dma_addr); + mem->vaddr = NULL; + mem->dma_addr = 0; + mem->size = 0; +} +EXPORT_SYMBOL(aml_vcodec_mem_free); + void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev, struct aml_vcodec_ctx *ctx) {
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h index 96c5453..312ee40 100644 --- a/drivers/amvdec_ports/aml_vcodec_util.h +++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -23,14 +23,14 @@ #include <linux/types.h> #include <linux/dma-direction.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> -/* + typedef unsigned long long u64; typedef signed long long s64; typedef unsigned int u32; typedef unsigned short int u16; typedef short int s16; typedef unsigned char u8; -*/ + #define CODEC_MODE(a, b, c, d)\ (((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d)) @@ -45,16 +45,14 @@ u32 bytes_used; u32 offset; u64 timestamp; + dma_addr_t dma_addr; u32 model; - ulong meta_ptr; - struct dma_buf *dbuf; }; struct aml_vcodec_ctx; struct aml_vcodec_dev; extern u32 debug_mode; -extern u32 mandatory_dw_mmu; #ifdef v4l_dbg #undef v4l_dbg @@ -71,11 +69,6 @@ #define V4L_DEBUG_CODEC_PARSER (1 << 6) #define V4L_DEBUG_CODEC_PROT (1 << 7) #define V4L_DEBUG_CODEC_EXINFO (1 << 8) -#define V4L_DEBUG_VPP_BUFMGR (1 << 9) -#define V4L_DEBUG_VPP_DETAIL (1 << 10) -#define V4L_DEBUG_TASK_CHAIN (1 << 11) -#define V4L_DEBUG_GE2D_BUFMGR (1 << 12) -#define V4L_DEBUG_GE2D_DETAIL (1 << 13) #define __v4l_dbg(h, id, fmt, args...) \ do { \ @@ -99,6 +92,12 @@ } \ } while (0) +void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data, + unsigned int reg_idx); +int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data, + struct aml_vcodec_mem *mem); +void aml_vcodec_mem_free(struct aml_vcodec_ctx *data, + struct aml_vcodec_mem *mem); 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);
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.c b/drivers/amvdec_ports/aml_vcodec_vfm.c new file mode 100644 index 0000000..62896ea --- /dev/null +++ b/drivers/amvdec_ports/aml_vcodec_vfm.c
@@ -0,0 +1,245 @@ +/* +* 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_vcodec_vfm.h" +#include "aml_vcodec_vfq.h" +#include "aml_vcodec_util.h" +#include "aml_vcodec_adapt.h" +#include <media/v4l2-mem2mem.h> + +#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_VIDEO_COMPOSER +#include <trace/events/meson_atrace.h> + +#define RECEIVER_NAME "v4l2-video" +#define PROVIDER_NAME "v4l2-video" + +static struct vframe_s *vdec_vf_peek(void *op_arg) +{ + struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg; + + return vfq_peek(&vfm->vf_que); +} + +static struct vframe_s *vdec_vf_get(void *op_arg) +{ + struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg; + + return vfq_pop(&vfm->vf_que); +} + +static void vdec_vf_put(struct vframe_s *vf, void *op_arg) +{ + struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg; + + /* If the video frame from amvide that means */ + /* the data has been processed and finished, */ + /* then push back to VDA. thus we don't put the */ + /* buffer to the decoder directly.*/ + + //vf_put(vf, vfm->recv_name); + //vf_notify_provider(vfm->recv_name, VFRAME_EVENT_RECEIVER_PUT, NULL); + + if (vfq_level(&vfm->vf_que_recycle) > POOL_SIZE - 1) { + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "vfq full.\n"); + return; + } + + atomic_set(&vf->use_cnt, 1); + + vfq_push(&vfm->vf_que_recycle, vf); + + /* schedule capture work. */ + vdec_device_vf_run(vfm->ctx); +} + +static int vdec_event_cb(int type, void *data, void *private_data) +{ + + if (type & VFRAME_EVENT_RECEIVER_PUT) { + } else if (type & VFRAME_EVENT_RECEIVER_GET) { + } else if (type & VFRAME_EVENT_RECEIVER_FRAME_WAIT) { + } + return 0; +} + +static int vdec_vf_states(struct vframe_states *states, void *op_arg) +{ + struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg; + + states->vf_pool_size = POOL_SIZE; + states->buf_recycle_num = 0; + states->buf_free_num = POOL_SIZE - vfq_level(&vfm->vf_que); + states->buf_avail_num = vfq_level(&vfm->vf_que); + + return 0; +} + +void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id) +{ + struct vframe_provider_s *vfp = vf_get_provider(receiver); + struct vframe_s *vf = (struct vframe_s *)fb->vf_handle; + + ATRACE_COUNTER("v4l2_to", vf->index_disp); + + v4l_dbg(0, V4L_DEBUG_CODEC_OUTPUT, + "[%d]: TO (%s) vf: %p, idx: %d, " + "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n", + id, vfp->name, vf, vf->index, + 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); + + if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) + vf_put(vf, receiver); +} + +static const struct vframe_operations_s vf_provider = { + .peek = vdec_vf_peek, + .get = vdec_vf_get, + .put = vdec_vf_put, + .event_cb = vdec_event_cb, + .vf_states = vdec_vf_states, +}; + +static int video_receiver_event_fun(int type, void *data, void *private_data) +{ + int ret = 0; + struct vframe_states states; + struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)private_data; + + switch (type) { + case VFRAME_EVENT_PROVIDER_UNREG: { + if (vf_get_receiver(vfm->prov_name)) { + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "unreg %s provider.\n", + vfm->prov_name); + vf_unreg_provider(&vfm->vf_prov); + } + + break; + } + + case VFRAME_EVENT_PROVIDER_START: { + if (vf_get_receiver(vfm->prov_name)) { + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "reg %s provider.\n", + vfm->prov_name); + vf_provider_init(&vfm->vf_prov, vfm->prov_name, + &vf_provider, vfm); + vf_reg_provider(&vfm->vf_prov); + vf_notify_receiver(vfm->prov_name, + VFRAME_EVENT_PROVIDER_START, NULL); + } + + vfq_init(&vfm->vf_que, POOL_SIZE + 1, &vfm->pool[0]); + vfq_init(&vfm->vf_que_recycle, POOL_SIZE + 1, &vfm->pool_recycle[0]); + + break; + } + + case VFRAME_EVENT_PROVIDER_QUREY_STATE: { + vdec_vf_states(&states, vfm); + if (states.buf_avail_num > 0) + ret = RECEIVER_ACTIVE; + break; + } + + case VFRAME_EVENT_PROVIDER_VFRAME_READY: { + if (vfq_level(&vfm->vf_que) > POOL_SIZE - 1) + ret = -1; + + if (!vf_peek(vfm->recv_name)) + ret = -1; + + vfm->vf = vf_get(vfm->recv_name); + if (!vfm->vf) + ret = -1; + + if (ret < 0) { + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "receiver vf err.\n"); + break; + } + + vfq_push(&vfm->vf_que, vfm->vf); + + if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) { + vf_notify_receiver(vfm->prov_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + break; + } + + /* schedule capture work. */ + vdec_device_vf_run(vfm->ctx); + + break; + } + + default: + v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO, + "the vf event is %d", type); + } + + return ret; +} + +static const struct vframe_receiver_op_s vf_receiver = { + .event_cb = video_receiver_event_fun +}; + +struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm) +{ + if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) + return vfq_peek(&vfm->vf_que_recycle); + else + return vfq_peek(&vfm->vf_que); +} + +struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm) +{ + if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) + return vfq_pop(&vfm->vf_que_recycle); + else + return vfq_pop(&vfm->vf_que); +} + +int vcodec_vfm_init(struct vcodec_vfm_s *vfm) +{ + int ret; + + snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d", + RECEIVER_NAME, vfm->ctx->id); + snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d", + PROVIDER_NAME, vfm->ctx->id); + + vfm->ada_ctx->recv_name = vfm->recv_name; + + vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm); + ret = vf_reg_receiver(&vfm->vf_recv); + + vfm->vfm_initialized = ret ? false : true; + + return ret; +} + +void vcodec_vfm_release(struct vcodec_vfm_s *vfm) +{ + if (vfm->vfm_initialized) + vf_unreg_receiver(&vfm->vf_recv); +} +
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.h b/drivers/amvdec_ports/aml_vcodec_vfm.h new file mode 100644 index 0000000..141e9a7 --- /dev/null +++ b/drivers/amvdec_ports/aml_vcodec_vfm.h
@@ -0,0 +1,60 @@ +/* +* 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_VFM_H_ +#define __AML_VCODEC_VFM_H_ + +#include "aml_vcodec_vfq.h" +#include "aml_vcodec_drv.h" +#include "aml_vcodec_dec.h" +#include <linux/amlogic/media/vfm/vframe_provider.h> +#include <linux/amlogic/media/vfm/vframe_receiver.h> + +#define VF_NAME_SIZE (32) +#define POOL_SIZE (32) + +struct vcodec_vfm_s { + struct aml_vcodec_ctx *ctx; + struct aml_vdec_adapt *ada_ctx; + struct vfq_s vf_que; + struct vfq_s vf_que_recycle; + struct vframe_s *vf; + struct vframe_s *pool[POOL_SIZE + 1]; + struct vframe_s *pool_recycle[POOL_SIZE + 1]; + char recv_name[VF_NAME_SIZE]; + char prov_name[VF_NAME_SIZE]; + struct vframe_provider_s vf_prov; + struct vframe_receiver_s vf_recv; + bool vfm_initialized; +}; + +int vcodec_vfm_init(struct vcodec_vfm_s *vfm); + +void vcodec_vfm_release(struct vcodec_vfm_s *vfm); + +struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm); + +struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm); + +int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb); +int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb); + +void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id); + +#endif /* __AML_VCODEC_VFM_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_vfq.h b/drivers/amvdec_ports/aml_vcodec_vfq.h new file mode 100644 index 0000000..e19c53c --- /dev/null +++ b/drivers/amvdec_ports/aml_vcodec_vfq.h
@@ -0,0 +1,112 @@ +/* +* 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_VFQ_H_ +#define __AML_VCODEC_VFQ_H_ + +#include <linux/types.h> +#include <asm/barrier.h> + +struct vfq_s { + int rp; + int wp; + int size; + int pre_rp; + int pre_wp; + struct vframe_s **pool; +}; + +static inline void vfq_lookup_start(struct vfq_s *q) +{ + q->pre_rp = q->rp; + q->pre_wp = q->wp; +} +static inline void vfq_lookup_end(struct vfq_s *q) +{ + q->rp = q->pre_rp; + q->wp = q->pre_wp; +} + +static inline void vfq_init(struct vfq_s *q, u32 size, struct vframe_s **pool) +{ + q->rp = q->wp = 0; + q->size = size; + q->pool = pool; +} + +static inline bool vfq_empty(struct vfq_s *q) +{ + return q->rp == q->wp; +} + +static inline void vfq_push(struct vfq_s *q, struct vframe_s *vf) +{ + int wp = q->wp; + + /*ToDo*/ + smp_mb(); + + q->pool[wp] = vf; + + /*ToDo*/ + smp_wmb(); + + q->wp = (wp == (q->size - 1)) ? 0 : (wp + 1); +} + +static inline struct vframe_s *vfq_pop(struct vfq_s *q) +{ + struct vframe_s *vf; + int rp; + + if (vfq_empty(q)) + return NULL; + + rp = q->rp; + + /*ToDo*/ + smp_rmb(); + + vf = q->pool[rp]; + + /*ToDo*/ + smp_mb(); + + q->rp = (rp == (q->size - 1)) ? 0 : (rp + 1); + + return vf; +} + +static inline struct vframe_s *vfq_peek(struct vfq_s *q) +{ + return (vfq_empty(q)) ? NULL : q->pool[q->rp]; +} + +static inline int vfq_level(struct vfq_s *q) +{ + int level = q->wp - q->rp; + + if (level < 0) + level += q->size; + + return level; +} + +#endif /* __AML_VCODEC_VFQ_H_ */ +
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.c b/drivers/amvdec_ports/aml_vcodec_vpp.c deleted file mode 100644 index 9f4e960..0000000 --- a/drivers/amvdec_ports/aml_vcodec_vpp.c +++ /dev/null
@@ -1,1102 +0,0 @@ -/* -* 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 <uapi/linux/sched/types.h> -#include <linux/amlogic/meson_uvm_core.h> - -#include "aml_vcodec_vpp.h" -#include "aml_vcodec_adapt.h" -#include "vdec_drv_if.h" -#include "../common/chips/decoder_cpu_ver_info.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 INPUT_PORT 0 -#define OUTPUT_PORT 1 - -extern int dump_vpp_input; -extern int vpp_bypass_frames; - -static void di_release_keep_buf_wrap(void *arg) -{ - struct di_buffer *buf = (struct di_buffer *)arg; - - v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR, - "%s release di local buffer %px, vf:%px, comm:%s, pid:%d\n", - __func__ , buf, buf->vf, - current->comm, current->pid); - - di_release_keep_buf(buf); - - ATRACE_COUNTER("VC_OUT_VPP_LC-2.lc_release", buf->mng.index); -} - -static int attach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf) -{ - 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 uvm_hook_mod_info u_info; - int ret; - - aml_buf = vpp_buf->aml_buf; - if (!aml_buf) - return -EINVAL; - - dma = aml_buf->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"); - return -EINVAL; - } - - if (!vpp_buf->di_local_buf) { - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "attach_DI_buffer nothing\n"); - return 0; - } - - 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"); - 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; - - 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"); - } - - ATRACE_COUNTER("VC_OUT_VPP_LC-0.lc_attach", vpp_buf->di_local_buf->mng.index); - - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "%s attach di local buffer %px, dbuf:%px\n", - __func__ , vpp_buf->di_local_buf, dma); - - return ret; -} - -static int detach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf) -{ - struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data; - struct dma_buf *dma = NULL; - struct aml_video_dec_buf *aml_buf = NULL; - int ret; - - aml_buf = vpp_buf->aml_buf; - if (!aml_buf) - return -EINVAL; - - dma = aml_buf->vb.vb2_buf.planes[0].dbuf; - if (!dma || !dmabuf_is_uvm(dma)) { - v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR, - "detach_DI_buffer err\n"); - return -EINVAL; - } - - if (!vpp_buf->di_local_buf) { - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "detach_DI_buffer nothing\n"); - return 0; - } - - ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_detach", vpp_buf->di_local_buf->mng.index); - - ret = uvm_detach_hook_mod(dma, VF_PROCESS_DI); - if (ret < 0) { - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "fail to remove dmabuf DI hook\n"); - } - - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "%s detach di local buffer %px, dbuf:%px\n", - __func__ , vpp_buf->di_local_buf, dma); - - return ret; -} - -static void release_DI_buff(struct aml_v4l2_vpp* vpp) -{ - struct aml_v4l2_vpp_buf *vpp_buf = NULL; - - while (kfifo_get(&vpp->out_done_q, &vpp_buf)) { - if (vpp_buf->di_buf.private_data) { - di_release_keep_buf(vpp_buf->di_local_buf); - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "%s release di local buffer %px\n", - __func__ , vpp_buf->di_local_buf); - } - } -} - -static int is_di_input_buff_full(struct aml_v4l2_vpp *vpp) -{ - return ((vpp->in_num[INPUT_PORT] - vpp->in_num[OUTPUT_PORT]) - > vpp->di_ibuf_num) ? true : false; -} - -static int is_di_output_buff_full(struct aml_v4l2_vpp *vpp) -{ - return ((vpp->out_num[INPUT_PORT] - vpp->out_num[OUTPUT_PORT]) - > vpp->di_obuf_num) ? true : false; -} - -static enum DI_ERRORTYPE - v4l_vpp_fill_output_done_alloc_buffer(struct di_buffer *buf) -{ - struct aml_v4l2_vpp *vpp = buf->caller_data; - struct aml_v4l2_vpp_buf *vpp_buf = NULL; - struct vdec_v4l2_buffer *fb = NULL; - bool bypass = false; - bool eos = false; - - if (!vpp || !vpp->ctx) { - pr_err("fatal %s %d vpp:%p\n", - __func__, __LINE__, vpp); - di_release_keep_buf_wrap(buf); - 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); - di_release_keep_buf_wrap(buf); - 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_wrap(buf); - return DI_ERR_UNDEFINED; - } - - fb = &vpp_buf->aml_buf->frame_buffer; - eos = (buf->flag & DI_FLAG_EOS); - bypass = (buf->flag & DI_FLAG_BUF_BY_PASS); - - vpp_buf->di_buf.vf->timestamp = buf->vf->timestamp; - 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; - - if (!eos && !bypass) { - vpp_buf->di_local_buf = buf; - vpp_buf->di_buf.vf->vf_ext = buf->vf; - vpp_buf->di_buf.vf->flag |= VFRAME_FLAG_CONTAIN_POST_FRAME; - } - - kfifo_put(&vpp->out_done_q, vpp_buf); - - if (vpp->is_prog) - kfifo_put(&vpp->input, vpp_buf->inbuf); - - 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, " - "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n", - fb->buf_idx, - vpp_buf->di_buf.vf, - vpp_buf->di_buf.vf->vf_ext, - vpp_buf->di_buf.vf->index, - vpp_buf->di_buf.vf->flag, - 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)); - - ATRACE_COUNTER("VC_OUT_VPP-2.lc_submit", fb->buf_idx); - - fb->task->submit(fb->task, TASK_TYPE_VPP); - - vpp->out_num[OUTPUT_PORT]++; - vpp->in_num[OUTPUT_PORT]++; - - return DI_ERR_NONE; -} - -static enum DI_ERRORTYPE - v4l_vpp_empty_input_done(struct di_buffer *buf) -{ - struct aml_v4l2_vpp *vpp = buf->caller_data; - struct aml_v4l2_vpp_buf *vpp_buf; - struct vdec_v4l2_buffer *fb = NULL; - 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 recycle frame %s %d vpp:%p\n", - __func__, __LINE__, vpp); - return DI_ERR_UNDEFINED; - } - - vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf); - fb = &vpp_buf->aml_buf->frame_buffer; - 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, - buf->vf, - buf->vf->index, - buf->vf->flag, - buf->flag, - vpp->is_prog ? "P" : "I", - eos ? "eos" : "", - 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)); - - if (!vpp->is_prog) { - /* recycle vf only in non-bypass mode */ - fb->task->recycle(fb->task, TASK_TYPE_VPP); - - kfifo_put(&vpp->input, vpp_buf); - } - - if (vpp->buffer_mode != BUFFER_MODE_ALLOC_BUF) - vpp->in_num[OUTPUT_PORT]++; - - ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx); - - return DI_ERR_NONE; -} - -static enum DI_ERRORTYPE - v4l_vpp_fill_output_done(struct di_buffer *buf) -{ - struct aml_v4l2_vpp *vpp = buf->caller_data; - struct aml_v4l2_vpp_buf *vpp_buf = NULL; - struct vdec_v4l2_buffer *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; - } - - vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf); - fb = &vpp_buf->aml_buf->frame_buffer; - eos = (buf->flag & DI_FLAG_EOS); - bypass = (buf->flag & DI_FLAG_BUF_BY_PASS); - - /* recovery fb handle. */ - buf->vf->v4l_mem_handle = (ulong)fb; - - kfifo_put(&vpp->out_done_q, 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, - buf->vf, - buf->vf->index, - buf->vf->flag, - buf->flag, - vpp->is_prog ? "P" : "I", - eos ? "eos" : "", - 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)); - - ATRACE_COUNTER("VC_OUT_VPP-2.submit", fb->buf_idx); - - fb->task->submit(fb->task, TASK_TYPE_VPP); - - vpp->out_num[OUTPUT_PORT]++; - - /* count for bypass nr */ - if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) - 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 di_buffer *buf = NULL; - struct vframe_s *vf = 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; - } - - if (kfifo_get(&vpp->out_done_q, &vpp_buf)) { - fb = &vpp_buf->aml_buf->frame_buffer; - buf = &vpp_buf->di_buf; - eos = (buf->flag & DI_FLAG_EOS); - bypass = (buf->flag & DI_FLAG_BUF_BY_PASS); - vf = buf->vf; - - if (eos) { - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL, - "%s %d got eos\n", - __func__, __LINE__); - vf->type |= VIDTYPE_V4L_EOS; - vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - } - - if (!eos && !bypass) { - if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) { - attach_DI_buffer(vpp_buf); - } - } - - *vf_out = vf; - - ATRACE_COUNTER("VC_OUT_VPP-3.vf_get", fb->buf_idx); - - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n", - __func__, vf, - vf->index, - vf->flag, - buf->flag, - vf->timestamp); - } -} - -static void vpp_vf_put(void *caller, struct vframe_s *vf) -{ - 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_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); - - - vpp_buf = (struct aml_v4l2_vpp_buf *) aml_buf->vpp_buf_handle; - buf = &vpp_buf->di_buf; - eos = (buf->flag & DI_FLAG_EOS); - bypass = (buf->flag & DI_FLAG_BUF_BY_PASS); - - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR, - "%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n", - __func__, vf, - vf->index, - vf->flag, - 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); - } - - if (!eos && !bypass) { - if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) { - detach_DI_buffer(vpp_buf); - } - } - - 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); -} - -static int aml_v4l2_vpp_thread(void* param) -{ - struct aml_v4l2_vpp* vpp = param; - struct aml_vcodec_ctx *ctx = vpp->ctx; - - v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "enter vpp thread\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; - - if (down_interruptible(&vpp->sem_in)) - goto exit; -retry: - if (!vpp->running) - break; - - if (kfifo_is_empty(&vpp->output)) { - if (down_interruptible(&vpp->sem_out)) - goto exit; - goto retry; - } - - if ((vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) && - (is_di_input_buff_full(vpp) || is_di_output_buff_full(vpp))) { - usleep_range(500, 550); - goto retry; - } - - mutex_lock(&vpp->output_lock); - if (!kfifo_get(&vpp->output, &out_buf)) { - mutex_unlock(&vpp->output_lock); - v4l_dbg(ctx, 0, "vpp can not get output\n"); - goto exit; - } - mutex_unlock(&vpp->output_lock); - - /* bind v4l2 buffers */ - if (!vpp->is_prog && !out_buf->aml_buf) { - struct vdec_v4l2_buffer *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)) { - usleep_range(5000, 5500); - mutex_lock(&vpp->output_lock); - kfifo_put(&vpp->output, out_buf); - mutex_unlock(&vpp->output_lock); - 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; - 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; - } - - /* safe to pop in_buf */ - if (!kfifo_get(&vpp->in_done_q, &in_buf)) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "vpp can not get input\n"); - goto exit; - } - - mutex_lock(&vpp->output_lock); - if (!kfifo_get(&vpp->frame, &vf_out)) { - mutex_unlock(&vpp->output_lock); - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "vpp can not get frame\n"); - goto exit; - } - mutex_unlock(&vpp->output_lock); - - if (!vpp->is_prog) { - /* submit I to DI. */ - fb = &out_buf->aml_buf->frame_buffer; - fb->status = 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[1].phy_addr = - fb->m.mem[0].addr + fb->m.mem[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)); - - 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; - - memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out)); - } - - /* fill outbuf parms. */ - out_buf->di_buf.vf = vf_out; - out_buf->di_buf.flag = 0; - out_buf->di_local_buf = NULL; - out_buf->di_buf.caller_data = vpp; - - /* fill inbuf parms. */ - in_buf->di_buf.caller_data = vpp; - - /* - * HWC or SF should hold di buffres refcnt after resolution changed - * that might cause stuck, thus sumbit 10 frames from dec to display directly. - * then frames will be pushed out from these buffer queuen and - * recycle local buffers to DI module. - */ - if (/*(ctx->vpp_cfg.res_chg) && */(vpp->is_prog) && - (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)) { - if (vpp->in_num[INPUT_PORT] < vpp_bypass_frames) { - vpp->is_bypass_p = true; - } else { - vpp->is_bypass_p = false; - ctx->vpp_cfg.res_chg = false; - } - } - - 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, - 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, - in_buf->di_buf.vf->canvas0_config[0].width, - in_buf->di_buf.vf->canvas0_config[0].height, - vf_out->canvas0_config[0].phy_addr, - vf_out->canvas0_config[1].phy_addr, - vf_out->canvas0_config[0].width, - vf_out->canvas0_config[0].height, - vpp->is_prog ? "P" : "", - vpp->is_bypass_p ? "bypass-prog" : "", - kfifo_len(&vpp->input), - kfifo_len(&vpp->output), - kfifo_len(&vpp->frame), - kfifo_len(&vpp->in_done_q), - kfifo_len(&vpp->out_done_q)); - - 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; - - v4l_vpp_fill_output_done(&out_buf->di_buf); - v4l_vpp_empty_input_done(&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); - - di_empty_input_buffer(vpp->di_handle, &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); - - 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); - } - } - vpp->in_num[INPUT_PORT]++; - vpp->out_num[INPUT_PORT]++; - } -exit: - while (!kthread_should_stop()) { - usleep_range(1000, 2000); - } - - v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "exit vpp thread\n"); - - return 0; -} - -int aml_v4l2_vpp_get_buf_num(u32 mode) -{ - if ((mode == VPP_MODE_DI) || - (mode == VPP_MODE_COLOR_CONV) || - (mode == VPP_MODE_NOISE_REDUC)) { - return 4; - } - //TODO: support more modes - return 2; -} - -int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp) -{ - int i; - 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); - - kfifo_reset(&vpp->input); - kfifo_reset(&vpp->output); - kfifo_reset(&vpp->frame); - kfifo_reset(&vpp->out_done_q); - kfifo_reset(&vpp->in_done_q); - kfifo_reset(&vpp->processing); - - for (i = 0 ; i < VPP_FRAME_SIZE ; i++) { - memset(&vpp->ivbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf)); - - kfifo_put(&vpp->input, &vpp->ivbpool[i]); - } - - for (i = 0 ; i < vpp->buf_size ; i++) { - memset(&vpp->ovbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf)); - memset(&vpp->vfpool[i], 0, sizeof(struct vframe_s)); - - kfifo_put(&vpp->output, &vpp->ovbpool[i]); - kfifo_put(&vpp->frame, &vpp->vfpool[i]); - } - - vpp->in_num[0] = 0; - vpp->in_num[1] = 0; - vpp->out_num[0] = 0; - vpp->out_num[1] = 0; - vpp->fb_token = 0; - sema_init(&vpp->sem_in, 0); - sema_init(&vpp->sem_out, 0); - - vpp->running = true; - vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp, - "%s", "aml-v4l2-vpp"); - if (IS_ERR(vpp->task)) { - return PTR_ERR(vpp->task); - } - - sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, ¶m); - - v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PRINFO, "vpp wrapper reset.\n"); - - return 0; - -} -EXPORT_SYMBOL(aml_v4l2_vpp_reset); - -int aml_v4l2_vpp_init( - struct aml_vcodec_ctx *ctx, - struct aml_vpp_cfg_infos *cfg, - struct aml_v4l2_vpp** vpp_handle) -{ - struct di_init_parm init; - u32 buf_size; - int i, ret; - struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; - struct aml_v4l2_vpp *vpp; - u32 work_mode = cfg->mode; - - if (!cfg || work_mode > VPP_MODE_MAX || !ctx || !vpp_handle) - return -EINVAL; - if (cfg->fmt != V4L2_PIX_FMT_NV12 && cfg->fmt != V4L2_PIX_FMT_NV12M && - cfg->fmt != V4L2_PIX_FMT_NV21 && cfg->fmt != V4L2_PIX_FMT_NV21M) - return -EINVAL; - - vpp = kzalloc(sizeof(*vpp), GFP_KERNEL); - if (!vpp) - return -ENOMEM; - - vpp->work_mode = work_mode; - if (vpp->work_mode >= VPP_MODE_DI_LOCAL && - vpp->work_mode <= VPP_MODE_NOISE_REDUC_LOCAL) - vpp->buffer_mode = BUFFER_MODE_ALLOC_BUF; - else - vpp->buffer_mode = BUFFER_MODE_USE_BUF; - - 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; - - if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) { - init.ops.fill_output_done = - v4l_vpp_fill_output_done_alloc_buffer; - } - - 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) && - ((cfg->fmt == V4L2_PIX_FMT_NV21M) || (cfg->fmt == V4L2_PIX_FMT_NV21))) - init.output_format = DI_OUTPUT_NV21 | DI_OUTPUT_LINEAR; - 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 */ - init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR; - - if (cfg->is_drm) - init.output_format |= DI_OUTPUT_TVP; - - vpp->di_handle = di_create_instance(init); - if (vpp->di_handle < 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "di_create_instance fail\n"); - ret = -EINVAL; - goto error; - } - - INIT_KFIFO(vpp->input); - INIT_KFIFO(vpp->output); - INIT_KFIFO(vpp->frame); - INIT_KFIFO(vpp->out_done_q); - INIT_KFIFO(vpp->in_done_q); - INIT_KFIFO(vpp->processing); - - vpp->ctx = ctx; - vpp->is_prog = cfg->is_prog; - vpp->is_bypass_p = cfg->is_bypass_p; - - buf_size = vpp->is_prog ? 16 : cfg->buf_size; - vpp->buf_size = buf_size; - - /* setup output fifo */ - ret = kfifo_alloc(&vpp->output, buf_size, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc output fifo fail.\n"); - ret = -ENOMEM; - goto error2; - } - - vpp->ovbpool = vzalloc(buf_size * sizeof(*vpp->ovbpool)); - if (!vpp->ovbpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc output vb pool fail.\n"); - ret = -ENOMEM; - goto error3; - } - - /* setup vframe fifo */ - ret = kfifo_alloc(&vpp->frame, buf_size, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc vpp vframe fifo fail.\n"); - ret = -ENOMEM; - goto error4; - } - - vpp->vfpool = vzalloc(buf_size * sizeof(*vpp->vfpool)); - if (!vpp->vfpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc vf pool fail.\n"); - ret = -ENOMEM; - goto error5; - } - - /* setup processing fifo */ - ret = kfifo_alloc(&vpp->processing, buf_size, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc processing fifo fail.\n"); - ret = -ENOMEM; - goto error6; - } - - ret = kfifo_alloc(&vpp->input, VPP_FRAME_SIZE, GFP_KERNEL); - if (ret) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc input fifo fail.\n"); - ret = -ENOMEM; - goto error7; - } - - vpp->ivbpool = vzalloc(VPP_FRAME_SIZE * sizeof(*vpp->ivbpool)); - if (!vpp->ivbpool) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "alloc input vb pool fail.\n"); - ret = -ENOMEM; - goto error8; - } - - for (i = 0 ; i < VPP_FRAME_SIZE ; i++) { - kfifo_put(&vpp->input, &vpp->ivbpool[i]); - } - - for (i = 0 ; i < buf_size ; i++) { - kfifo_put(&vpp->output, &vpp->ovbpool[i]); - kfifo_put(&vpp->frame, &vpp->vfpool[i]); - } - - mutex_init(&vpp->output_lock); - sema_init(&vpp->sem_in, 0); - sema_init(&vpp->sem_out, 0); - - vpp->running = true; - vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp, - "aml-%s", "aml-v4l2-vpp"); - if (IS_ERR(vpp->task)) { - ret = PTR_ERR(vpp->task); - goto error9; - } - sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, ¶m); - - vpp->di_ibuf_num = di_get_input_buffer_num(vpp->di_handle); - vpp->di_obuf_num = di_get_output_buffer_num(vpp->di_handle); - - *vpp_handle = vpp; - - v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, - "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, - vpp->di_obuf_num, - vpp->work_mode, - vpp->buffer_mode, - init.output_format, - cfg->is_drm, - cfg->is_prog, - cfg->is_bypass_p, - cfg->enable_local_buf, - cfg->enable_nr); - - return 0; - -error9: - vfree(vpp->ivbpool); -error8: - kfifo_free(&vpp->input); -error7: - kfifo_free(&vpp->processing); -error6: - vfree(vpp->vfpool); -error5: - kfifo_free(&vpp->frame); -error4: - vfree(vpp->ovbpool); -error3: - kfifo_free(&vpp->output); -error2: - di_destroy_instance(vpp->di_handle); -error: - kfree(vpp); - return ret; -} -EXPORT_SYMBOL(aml_v4l2_vpp_init); - -int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp) -{ - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL, - "vpp destroy begin\n"); - vpp->running = false; - 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 */ - - if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) - release_DI_buff(vpp); - - kfifo_free(&vpp->processing); - kfifo_free(&vpp->frame); - vfree(vpp->vfpool); - kfifo_free(&vpp->output); - vfree(vpp->ovbpool); - kfifo_free(&vpp->input); - vfree(vpp->ivbpool); - mutex_destroy(&vpp->output_lock); - v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL, - "vpp_wrapper destroy done\n"); - kfree(vpp); - - return 0; -} -EXPORT_SYMBOL(aml_v4l2_vpp_destroy); - -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; - - 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"); - return -1; - } - -#if 0 //to debug di by frame - if (vpp->in_num[INPUT_PORT] > 2) - return 0; - if (vpp->in_num[INPUT_PORT] == 2) - vf->type |= VIDTYPE_V4L_EOS; -#endif - - in_buf->di_buf.vf = vf; - in_buf->di_buf.flag = 0; - if (vf->type & VIDTYPE_V4L_EOS) { - u32 dw_mode = VDEC_DW_NO_AFBC; - - 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; - - if (dw_mode != VDEC_DW_NO_AFBC) - 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); - - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_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) && - (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) && - (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) && - (vpp->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; - } - - 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); - - do { - unsigned int dw_mode = VDEC_DW_NO_AFBC; - struct file *fp; - - 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) - break; - - fp = filp_open("/data/dec_dump_before.raw", - O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600); - if (!IS_ERR(fp)) { - struct vb2_buffer *vb = &in_buf->aml_buf->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_vpp_input--; - filp_close(fp, NULL); - } - } while(0); - - ATRACE_COUNTER("VC_OUT_VPP-0.receive", fb->buf_idx); - - kfifo_put(&vpp->in_done_q, in_buf); - up(&vpp->sem_in); - - return 0; -} - -static void fill_vpp_buf_cb(void *v4l_ctx, void *fb_ctx) -{ - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)v4l_ctx; - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)fb_ctx; - int ret = -1; - - ret = aml_v4l2_vpp_push_vframe(ctx->vpp, fb->vframe); - if (ret < 0) { - v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, - "vpp push vframe err, ret: %d\n", ret); - } -} - -static struct task_ops_s vpp_ops = { - .type = TASK_TYPE_VPP, - .get_vframe = vpp_vf_get, - .put_vframe = vpp_vf_put, - .fill_buffer = fill_vpp_buf_cb, -}; - -struct task_ops_s *get_vpp_ops(void) -{ - return &vpp_ops; -} -EXPORT_SYMBOL(get_vpp_ops); -
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.h b/drivers/amvdec_ports/aml_vcodec_vpp.h deleted file mode 100644 index 7a5771d..0000000 --- a/drivers/amvdec_ports/aml_vcodec_vpp.h +++ /dev/null
@@ -1,112 +0,0 @@ -/* -* 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_VPP_H_ -#define _AML_VCODEC_VPP_H_ - -#define SUPPORT_V4L_VPP - -#include <linux/kfifo.h> -#ifdef SUPPORT_V4L_VPP -#include <linux/amlogic/media/di/di_interface.h> -#endif -#include "aml_vcodec_drv.h" -#include "aml_vcodec_dec.h" - -enum vpp_work_mode { - VPP_MODE_DI, - VPP_MODE_COLOR_CONV, - VPP_MODE_NOISE_REDUC, - VPP_MODE_DI_LOCAL = 0x81, - VPP_MODE_COLOR_CONV_LOCAL = 0x82, - VPP_MODE_NOISE_REDUC_LOCAL = 0x83, - VPP_MODE_MAX = 0xff -}; - -#define VPP_FRAME_SIZE 64 - -struct aml_v4l2_vpp_buf { -#ifdef SUPPORT_V4L_VPP - struct di_buffer di_buf; - struct di_buffer *di_local_buf; -#endif - struct aml_video_dec_buf *aml_buf; - struct aml_v4l2_vpp_buf *inbuf; -}; - -struct aml_v4l2_vpp { - int di_handle; /* handle of DI */ - struct aml_vcodec_ctx *ctx; - u32 buf_size; /* buffer size for vpp */ - u32 work_mode; /* enum vpp_work_mode */ - u32 buffer_mode; - - DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_vpp_buf*)); - DECLARE_KFIFO_PTR(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); - DECLARE_KFIFO(in_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE); - - struct vframe_s *vfpool; - struct aml_v4l2_vpp_buf *ovbpool; - struct aml_v4l2_vpp_buf *ivbpool; - struct task_struct *task; - bool running; - struct semaphore sem_in, sem_out; - - /* In p to i transition, output/frame can be multi writer */ - struct mutex output_lock; - - /* for debugging */ - /* - * in[0] --> vpp <-- in[1] - * out[0]<-- vpp --> out[1] - */ - int in_num[2]; - int out_num[2]; - ulong fb_token; - - bool is_prog; - bool is_bypass_p; - int di_ibuf_num; - int di_obuf_num; -}; - -struct task_ops_s *get_vpp_ops(void); - -#ifdef SUPPORT_V4L_VPP -/* get number of buffer needed for a working mode */ -int aml_v4l2_vpp_get_buf_num(u32 mode); -int aml_v4l2_vpp_init( - struct aml_vcodec_ctx *ctx, - struct aml_vpp_cfg_infos *cfg, - 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); -#else -static inline int aml_v4l2_vpp_get_buf_num(u32 mode) { return -1; } -static inline int aml_v4l2_vpp_init( - struct aml_vcodec_ctx *ctx, - struct aml_vpp_cfg_infos *cfg, - struct aml_v4l2_vpp** vpp_handle) { return -1; } -static inline int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp) { return -1; } -#endif - -#endif
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c index d0d0198..c9da299 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_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c index 24977a8..4ea76b9 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..0c81cb5 100644 --- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h +++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
@@ -22,6 +22,7 @@ #include "../aml_vcodec_drv.h" #include "../utils/common.h" + #define MAX_DPB_SIZE 16 // A.4.1 #define MAX_REFS 16
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c index c582ab0..fd56755 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..bbc9282 100644 --- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
@@ -1,3 +1,19 @@ +/* + * drivers/amvdec_ports/decoder/aml_mjpeg_parser.h + * + * 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. + * + */ #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..2720446 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..8abbc78 100644 --- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
@@ -1,3 +1,19 @@ +/* + * drivers/amvdec_ports/decoder/aml_mpeg12_parser.h + * + * 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. + * + */ #ifndef AML_MPEG12_PARSER_H #define AML_MPEG12_PARSER_H @@ -7,6 +23,7 @@ #include "../utils/pixfmt.h" #endif + /* Start codes. */ #define SEQ_END_CODE 0x000001b7 #define SEQ_START_CODE 0x000001b3
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c index 9c47c08..f680b12 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>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h index f9b71cf..3e5bf62 100644 --- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h +++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
@@ -1,3 +1,19 @@ +/* + * drivers/amvdec_ports/decoder/aml_mpeg4_parser.h + * + * 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. + * + */ #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..b027b8a 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/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c index c28ca10..e8693d4 100644 --- a/drivers/amvdec_ports/decoder/vdec_av1_if.c +++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -29,6 +29,7 @@ #include "../aml_vcodec_drv.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "../utils/common.h" #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2 @@ -117,9 +118,9 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_av1_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; - struct vdec_comp_buf_info comp_info; }; /*!\brief OBU types. */ @@ -206,7 +207,6 @@ 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); static void get_pic_info(struct vdec_av1_inst *inst, struct vdec_pic_info *pic) @@ -246,12 +246,12 @@ u8 *pbuf = parm; pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); - pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;"); - pbuf += sprintf(pbuf, "av1_double_write_mode:1;"); + pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:11;"); + pbuf += sprintf(pbuf, "av1_double_write_mode:3;"); pbuf += sprintf(pbuf, "av1_buf_width:1920;"); pbuf += sprintf(pbuf, "av1_buf_height:1088;"); - pbuf += sprintf(pbuf, "av1_max_pic_w:4096;"); - pbuf += sprintf(pbuf, "av1_max_pic_h:2304;"); + pbuf += sprintf(pbuf, "av1_max_pic_w:8192;"); + pbuf += sprintf(pbuf, "av1_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;"); @@ -264,10 +264,6 @@ { 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; @@ -277,8 +273,10 @@ 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_buf_width:1920;"); - pbuf += sprintf(pbuf, "av1_buf_height:1088;"); + pbuf += sprintf(pbuf, "av1_buf_width:%d;", + ctx->config.parm.dec.cfg.init_width); + pbuf += sprintf(pbuf, "av1_buf_height:%d;", + ctx->config.parm.dec.cfg.init_height); pbuf += sprintf(pbuf, "save_buffer_mode:0;"); pbuf += sprintf(pbuf, "no_head:0;"); pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;", @@ -287,23 +285,19 @@ 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 = 1; + ctx->config.parm.dec.cfg.double_write_mode = 16; 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) { + inst->parms.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;", @@ -332,8 +326,6 @@ 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; @@ -349,7 +341,6 @@ if (!inst) return -ENOMEM; - inst->vdec.frm_name = "AV1"; inst->vdec.video_type = VFORMAT_AV1; inst->vdec.filp = ctx->dev->filp; inst->vdec.ctx = ctx; @@ -364,6 +355,16 @@ /* to eable av1 hw.*/ inst->vdec.port.type = PORT_TYPE_HEVC; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } + /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_av1_vsi), GFP_KERNEL); if (!inst->vsi) { @@ -372,7 +373,7 @@ } /* alloc the header buffer to be used cache sps or spp etc.*/ - inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE); + inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; @@ -380,6 +381,9 @@ init_completion(&inst->comp); + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "av1 Instance >> %lx\n", (ulong) inst); + ctx->ada_ctx = &inst->vdec; *h_vdec = (unsigned long)inst; @@ -391,13 +395,14 @@ goto err; } - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, - "av1 Instance >> %lx\n", (ulong) inst); + //dump_init(); return 0; err: + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -423,7 +428,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_av1_inst *inst, @@ -444,7 +449,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_av1_inst *inst, u8 *buf, u32 size) @@ -499,13 +504,19 @@ static void vdec_av1_deinit(unsigned long h_vdec) { + ulong flags; struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + + spin_lock_irqsave(&ctx->slock, flags); if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -513,6 +524,42 @@ kfree(inst); ctx->drv_handle = 0; + spin_unlock_irqrestore(&ctx->slock, flags); +} + +static int vdec_av1_get_fb(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_av1_get_vf(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; } // Returns 1 when OBU type is valid, and 0 otherwise. @@ -589,7 +636,7 @@ int i; const size_t leb_size = uleb_size_in_bytes(value); - if (value > kMaximumLeb128Value || leb_size > kMaximumLeb128Size || + if (leb_size > kMaximumLeb128Size || leb_size > available || !coded_value || !coded_size) { return -1; } @@ -657,12 +704,13 @@ static int read_obu_header(struct read_bit_buffer *rb, int is_annexb, struct ObuHeader *header) { - const int bit_buffer_byte_length = - rb->bit_buffer_end - rb->bit_buffer; + int bit_buffer_byte_length; if (!rb || !header) return -1; + bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer; + if (bit_buffer_byte_length < 1) return -1; @@ -1000,13 +1048,13 @@ 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); else ret = -1; vfree(data); } else { - ret = vdec_vframe_write(vdec, buf, size, ts, 0); + ret = vdec_vframe_write(vdec, buf, size, ts); } return ret; @@ -1040,14 +1088,18 @@ { struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - u8 *buf = (u8 *) bs->vaddr; - u32 size = bs->size; + u8 *buf; + u32 size; int ret = -1; if (bs == NULL) return -1; + buf = (u8 *) bs->vaddr; + size = bs->size; + if (vdec_input_full(vdec)) { + ATRACE_COUNTER("vdec_input_full", 0); return -EAGAIN; } @@ -1069,8 +1121,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -1086,6 +1137,7 @@ ret = vdec_write_nalu(inst, buf, size, bs->timestamp); } + ATRACE_COUNTER("v4l2_decode_write", ret); return ret; } @@ -1093,12 +1145,8 @@ static void get_param_config_info(struct vdec_av1_inst *inst, 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_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) @@ -1108,16 +1156,10 @@ parms->parms_status |= inst->parms.parms_status; - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "parms status: %u\n", parms->parms_status); } -static void get_param_comp_buf_info(struct vdec_av1_inst *inst, - struct vdec_comp_buf_info *params) -{ - memcpy(params, &inst->comp_info, sizeof(*params)); -} - static int vdec_av1_get_param(unsigned long h_vdec, enum vdec_get_param_type type, void *out) { @@ -1125,12 +1167,20 @@ struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the av1 inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_av1_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_av1_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -1147,20 +1197,6 @@ get_param_config_info(inst, out); break; - case GET_PARAM_DW_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); - 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); @@ -1175,69 +1211,12 @@ 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) { struct vdec_pic_info *pic = &inst->vsi->pic; struct vdec_av1_dec_info *dec = &inst->vsi->dec; struct v4l2_rect *rect = &inst->vsi->crop; - int dw = inst->parms.cfg.double_write_mode; /* fill visible area size that be used for EGL. */ pic->visible_width = ps->visible_width; @@ -1253,16 +1232,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); + 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 |= @@ -1272,27 +1246,23 @@ 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, crop(%d x %d), coded(%d x %d) dpb: %d\n", ps->visible_width, ps->visible_height, - ps->coded_width, ps->coded_height); -} - -static void set_param_comp_buf_info(struct vdec_av1_inst *inst, - struct vdec_comp_buf_info *info) -{ - memcpy(&inst->comp_info, info, sizeof(*info)); + ps->coded_width, ps->coded_height, + ps->dpb_size); } static void set_param_hdr_info(struct vdec_av1_inst *inst, struct aml_vdec_hdr_infos *hdr) { - if (hdr->signal_type != 0) { + 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, + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "av1 set HDR infos\n"); } } @@ -1304,12 +1274,6 @@ "av1 post event: %d\n", *event); } -static void set_pic_info(struct vdec_av1_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static int vdec_av1_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -1317,7 +1281,7 @@ struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the av1 inst of dec is invalid.\n"); return -1; } @@ -1331,10 +1295,6 @@ 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; @@ -1342,11 +1302,6 @@ case SET_PARAM_POST_EVENT: set_param_post_event(inst, in); break; - - case SET_PARAM_PIC_INFO: - set_pic_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_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c index 911c91d..d13fc34 100644 --- a/drivers/amvdec_ports/decoder/vdec_h264_if.c +++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -30,6 +30,7 @@ #include "../aml_vcodec_drv.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_h264_parser.h" #include "../utils/common.h" @@ -149,6 +150,7 @@ struct aml_vcodec_mem mv_buf[H264_MAX_FB_NUM]; struct aml_vdec_adapt vdec; struct vdec_h264_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; }; @@ -279,10 +281,6 @@ 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_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.parm.dec.cfg.double_write_mode = 16; @@ -299,13 +297,14 @@ { struct vdec_h264_inst *inst = NULL; int ret = -1; + bool dec_init = false; - inst = vzalloc(sizeof(*inst)); + inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) return -ENOMEM; - inst->vdec.frm_name = "H.264"; inst->vdec.video_type = VFORMAT_H264; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.ctx = ctx; inst->ctx = ctx; @@ -316,43 +315,60 @@ if (ctx->is_drm_mode) inst->vdec.port.flag |= PORT_FLAG_DRM; - /* probe info from the stream */ - inst->vsi = vzalloc(sizeof(struct vdec_h264_vsi)); - if (!inst->vsi) { - ret = -ENOMEM; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); 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_h264 init err=%d\n", ret); goto err; } + dec_init = true; + + /* probe info from the stream */ + inst->vsi = kzalloc(sizeof(struct vdec_h264_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 = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); + if (!inst->vsi->header_buf) { + ret = -ENOMEM; + goto err; + } + + init_completion(&inst->comp); v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "H264 Instance >> %lx", (ulong) inst); + ctx->ada_ctx = &inst->vdec; + *h_vdec = (unsigned long)inst; + + //dump_init(); + return 0; err: - if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); - if (inst && inst->vsi) - vfree(inst->vsi); + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) - vfree(inst); + vcodec_vfm_release(&inst->vfm); + if (inst && inst->vsi && inst->vsi->header_buf) + kfree(inst->vsi->header_buf); + if (inst && inst->vsi) + kfree(inst->vsi); + if (inst) + kfree(inst); *h_vdec = 0; return ret; @@ -481,6 +497,7 @@ pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; pic->profile_idc = sps->profile_idc; + pic->ref_frame_count= sps->ref_frame_count; /* calc DPB size */ dec->dpb_sz = sps->num_reorder_frames + margin; @@ -492,7 +509,7 @@ inst->parms.ps.mb_width = sps->mb_width; inst->parms.ps.mb_height = sps->mb_height; inst->parms.ps.ref_frames = sps->ref_frame_count; - inst->parms.ps.dpb_frames = sps->num_reorder_frames; + inst->parms.ps.reorder_frames = sps->num_reorder_frames; inst->parms.ps.dpb_size = dec->dpb_sz; inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO; @@ -554,7 +571,7 @@ 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); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -565,7 +582,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_h264_inst *inst, @@ -586,7 +603,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_h264_inst *inst, u8 *buf, u32 size) @@ -671,20 +688,71 @@ static void vdec_h264_deinit(unsigned long h_vdec) { + ulong flags; struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + + spin_lock_irqsave(&ctx->slock, flags); if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) - vfree(inst->vsi); + kfree(inst->vsi); - vfree(inst); + kfree(inst); ctx->drv_handle = 0; + spin_unlock_irqrestore(&ctx->slock, flags); +} + +static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + if (fb) { + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + } + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used); + //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.vaddr, fb->base_c.size); } static int vdec_write_nalu(struct vdec_h264_inst *inst, @@ -734,7 +802,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); } else { char *write_buf = vmalloc(inst->vsi->head_offset + size); if (!write_buf) { @@ -746,7 +814,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); memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE); inst->vsi->head_offset = 0; @@ -794,7 +862,9 @@ inst->vsi->cur_pic.coded_height != inst->vsi->pic.coded_height) || (inst->vsi->pic.profile_idc != - inst->vsi->cur_pic.profile_idc))) { + inst->vsi->cur_pic.profile_idc) || + (inst->vsi->pic.ref_frame_count != + inst->vsi->cur_pic.ref_frame_count))) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n"); inst->vsi->cur_pic = inst->vsi->pic; return true; @@ -808,13 +878,16 @@ { 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; + u8 *buf; + u32 size; int ret = -1; if (bs == NULL) return -1; + buf = (u8 *) bs->vaddr; + size = bs->size; + if (vdec_input_full(vdec)) return -EAGAIN; @@ -836,8 +909,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -889,12 +961,20 @@ struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the h264 inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_h264_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_h264_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -910,14 +990,6 @@ case GET_PARAM_CONFIG_INFO: get_param_config_info(inst, out); break; - - case GET_PARAM_DW_MODE: - { - unsigned int* mode = out; - *mode = inst->ctx->config.parm.dec.cfg.double_write_mode; - break; - } - default: v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "invalid get parameter type=%d\n", type); @@ -956,10 +1028,8 @@ pic->y_len_sz = pic->coded_width * pic->coded_height; pic->c_len_sz = pic->y_len_sz >> 1; pic->profile_idc = ps->profile; + pic->ref_frame_count = ps->ref_frames; pic->field = ps->field; - pic->dpb_frames = ps->dpb_frames; - pic->dpb_margin = ps->dpb_margin; - pic->vpp_margin = ps->dpb_margin; dec->dpb_sz = ps->dpb_size; inst->parms.ps = *ps; @@ -972,9 +1042,10 @@ 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) dpb: %d, scan: %s\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, + dec->dpb_sz, ps->field == V4L2_FIELD_NONE ? "P" : "I"); } @@ -994,12 +1065,6 @@ } } -static void set_pic_info(struct vdec_h264_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event) { aml_vdec_dispatch_event(inst->ctx, *event); @@ -1014,7 +1079,7 @@ struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the h264 inst of dec is invalid.\n"); return -1; } @@ -1035,11 +1100,6 @@ case SET_PARAM_POST_EVENT: set_param_post_event(inst, in); break; - - case SET_PARAM_PIC_INFO: - set_pic_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..2a41276 100644 --- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c +++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -29,6 +29,7 @@ #include "../aml_vcodec_drv.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_hevc_parser.h" #define HEVC_NAL_TYPE(value) ((value >> 1) & 0x3F) @@ -111,9 +112,9 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_hevc_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; - struct vdec_comp_buf_info comp_info; }; static void get_pic_info(struct vdec_hevc_inst *inst, @@ -154,7 +155,7 @@ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;"); - pbuf += sprintf(pbuf, "hevc_double_write_mode:1;"); + pbuf += sprintf(pbuf, "hevc_double_write_mode:16;"); pbuf += sprintf(pbuf, "hevc_buf_width:4096;"); pbuf += sprintf(pbuf, "hevc_buf_height:2304;"); pbuf += sprintf(pbuf, "save_buffer_mode:0;"); @@ -186,13 +187,9 @@ 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_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.parm.dec.cfg.double_write_mode = 1; + ctx->config.parm.dec.cfg.double_write_mode = 16; ctx->config.parm.dec.cfg.ref_buf_margin = 7; ctx->config.length = vdec_config_default_parms(ctx->config.buf); } @@ -206,13 +203,14 @@ { struct vdec_hevc_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) return -ENOMEM; - inst->vdec.frm_name = "H.265"; inst->vdec.video_type = VFORMAT_HEVC; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.ctx = ctx; inst->ctx = ctx; @@ -226,6 +224,24 @@ /* to eable hevc hw.*/ inst->vdec.port.type = PORT_TYPE_HEVC; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } + + ret = video_decoder_init(&inst->vdec); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_hevc init err=%d\n", ret); + goto err; + } + dec_init = true; + /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL); if (!inst->vsi) { @@ -234,7 +250,7 @@ } /* alloc the header buffer to be used cache sps or spp etc.*/ - inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE); + inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; @@ -242,23 +258,22 @@ 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_hevc init err=%d\n", ret); - goto err; - } - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "hevc Instance >> %lx\n", (ulong) inst); + ctx->ada_ctx = &inst->vdec; + *h_vdec = (unsigned long)inst; + + //dump_init(); + return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -302,8 +317,8 @@ 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; + int w = inst->parms.cfg.init_width; + int h = inst->parms.cfg.init_height; u32 dw = 0x1; /*1:1*/ switch (valid_dw_mode) { @@ -406,7 +421,7 @@ 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); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -417,7 +432,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_hevc_inst *inst, @@ -438,7 +453,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_hevc_inst *inst, u8 *buf, u32 size) @@ -511,13 +526,19 @@ static void vdec_hevc_deinit(unsigned long h_vdec) { + ulong flags; struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + + spin_lock_irqsave(&ctx->slock, flags); if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -525,6 +546,49 @@ kfree(inst); ctx->drv_handle = 0; + spin_unlock_irqrestore(&ctx->slock, flags); +} + +static int vdec_hevc_get_fb(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_hevc_get_vf(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used); + //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.vaddr, fb->base_c.size); } static int vdec_write_nalu(struct vdec_hevc_inst *inst, @@ -533,7 +597,7 @@ 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); return ret; } @@ -580,13 +644,16 @@ { struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - u8 *buf = (u8 *) bs->vaddr; - u32 size = bs->size; + u8 *buf; + u32 size; int ret = -1; if (bs == NULL) return -1; + buf = (u8 *) bs->vaddr; + size = bs->size; + if (vdec_input_full(vdec)) return -EAGAIN; @@ -608,8 +675,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -647,12 +713,6 @@ "parms status: %u\n", parms->parms_status); } -static void get_param_comp_buf_info(struct vdec_hevc_inst *inst, - struct vdec_comp_buf_info *params) -{ - memcpy(params, &inst->comp_info, sizeof(*params)); -} - static int vdec_hevc_get_param(unsigned long h_vdec, enum vdec_get_param_type type, void *out) { @@ -660,12 +720,20 @@ struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the hevc inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_hevc_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_hevc_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -681,21 +749,6 @@ case GET_PARAM_CONFIG_INFO: get_param_config_info(inst, out); break; - - case GET_PARAM_DW_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); - 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); @@ -716,7 +769,6 @@ 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; /* fill visible area size that be used for EGL. */ pic->visible_width = ps->visible_width; @@ -732,14 +784,9 @@ 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 = 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; @@ -751,27 +798,13 @@ 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, crop(%d x %d), coded(%d x %d) dpb: %d, scan: %s\n", pic->visible_width, pic->visible_height, pic->coded_width, pic->coded_height, + dec->dpb_sz, pic->field == V4L2_FIELD_NONE ? "P" : "I"); } -static void set_cfg_info(struct vdec_hevc_inst *inst, - struct aml_vdec_cfg_infos *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)); -} - -static void set_param_comp_buf_info(struct vdec_hevc_inst *inst, - struct vdec_comp_buf_info *info) -{ - memcpy(&inst->comp_info, info, sizeof(*info)); -} - static void set_param_hdr_info(struct vdec_hevc_inst *inst, struct aml_vdec_hdr_infos *hdr) { @@ -794,12 +827,6 @@ "H265 post event: %d\n", *event); } -static void set_pic_info(struct vdec_hevc_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static int vdec_hevc_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -807,7 +834,7 @@ struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the hevc inst of dec is invalid.\n"); return -1; } @@ -817,18 +844,10 @@ set_param_write_sync(inst); break; - case SET_PARAM_CFG_INFO: - set_cfg_info(inst, in); - 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; @@ -836,10 +855,6 @@ case SET_PARAM_POST_EVENT: set_param_post_event(inst, in); break; - - case SET_PARAM_PIC_INFO: - set_pic_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_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c index 8332956..f9816cc 100644 --- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -28,6 +28,7 @@ #include "../aml_vcodec_dec.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_mjpeg_parser.h" #include <media/v4l2-mem2mem.h> @@ -111,6 +112,7 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_mjpeg_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; }; @@ -156,7 +158,6 @@ 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;"); - pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;"); return pbuf - parm; } @@ -176,8 +177,6 @@ ctx->config.parm.dec.cfg.ref_buf_margin); pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;", ctx->config.parm.dec.cfg.canvas_mem_endian); - 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); @@ -193,13 +192,14 @@ { struct vdec_mjpeg_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) return -ENOMEM; - inst->vdec.frm_name = "MJPEG"; inst->vdec.video_type = VFORMAT_MJPEG; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.config = ctx->config; inst->vdec.ctx = ctx; @@ -213,6 +213,24 @@ /* to eable mjpeg hw.*/ inst->vdec.port.type = PORT_TYPE_VIDEO; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } + + ret = video_decoder_init(&inst->vdec); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_mjpeg init err=%d\n", ret); + goto err; + } + dec_init = true; + /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mjpeg_vsi), GFP_KERNEL); if (!inst->vsi) { @@ -221,31 +239,30 @@ } /* alloc the header buffer to be used cache sps or spp etc.*/ - inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE); + inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); 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_mjpeg init err=%d\n", ret); - goto err; - } - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "mjpeg Instance >> %lx\n", (ulong) inst); + init_completion(&inst->comp); + ctx->ada_ctx = &inst->vdec; + *h_vdec = (unsigned long)inst; + + //dump_init(); + return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -291,9 +308,9 @@ dec->dpb_sz = 8; v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR, - "The stream infos, coded:(%d x %d), visible:(%d x %d)\n", + "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n", pic->coded_width, pic->coded_height, - pic->visible_width, pic->visible_height); + pic->visible_width, pic->visible_height, dec->dpb_sz); } static int parse_stream_ucode(struct vdec_mjpeg_inst *inst, @@ -302,7 +319,7 @@ 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); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -313,7 +330,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_mjpeg_inst *inst, @@ -334,7 +351,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size) @@ -414,8 +431,12 @@ video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -423,13 +444,55 @@ kfree(inst); } +static int vdec_mjpeg_get_fb(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_mjpeg_get_vf(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.va, fb->base_y.bytes_used); + //dump_write(fb->base_c.va, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.va, fb->base_c.size); +} + static int vdec_write_nalu(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size, u64 ts) { 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); return ret; } @@ -457,8 +520,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -480,12 +542,20 @@ struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mjpeg inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_mjpeg_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_mjpeg_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -498,13 +568,6 @@ get_crop_info(inst, out); break; - case GET_PARAM_DW_MODE: - { - unsigned int* mode = out; - *mode = VDEC_DW_NO_AFBC; - break; - } - default: v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "invalid get parameter type=%d\n", type); @@ -536,13 +599,9 @@ 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->c_len_sz = pic->y_len_sz; - 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 |= @@ -552,10 +611,10 @@ 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, crop(%d x %d), coded(%d x %d) dpb: %d\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, - pic->field == V4L2_FIELD_NONE ? "P" : "I"); + dec->dpb_sz); } static void set_param_write_sync(struct vdec_mjpeg_inst *inst) @@ -563,12 +622,6 @@ complete(&inst->comp); } -static void set_pic_info(struct vdec_mjpeg_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static int vdec_mjpeg_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -576,7 +629,7 @@ struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mjpeg inst of dec is invalid.\n"); return -1; } @@ -585,15 +638,10 @@ 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; - default: v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c index 2472ac1..9a38e71 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -28,6 +28,7 @@ #include "../aml_vcodec_dec.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_mpeg12_parser.h" #define NAL_TYPE(value) ((value) & 0x1F) @@ -110,6 +111,7 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_mpeg12_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; }; @@ -171,10 +173,6 @@ 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); @@ -189,13 +187,14 @@ { struct vdec_mpeg12_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) return -ENOMEM; - inst->vdec.frm_name = "MPEG2"; inst->vdec.video_type = VFORMAT_MPEG12; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.config = ctx->config; inst->vdec.ctx = ctx; @@ -210,6 +209,24 @@ /* to eable mpeg12 hw.*/ inst->vdec.port.type = PORT_TYPE_VIDEO; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } + + ret = video_decoder_init(&inst->vdec); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "vdec_mpeg12 init err=%d\n", ret); + goto err; + } + dec_init = true; + /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mpeg12_vsi), GFP_KERNEL); if (!inst->vsi) { @@ -218,31 +235,29 @@ } /* alloc the header buffer to be used cache sps or spp etc.*/ - inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE); + inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; } + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, + "mpeg12 Instance >> %lx\n", (ulong) inst); 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_mpeg12 init err=%d\n", ret); - goto err; - } - - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, - "mpeg12 Instance >> %lx\n", (ulong) inst); + //dump_init(); return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -291,7 +306,7 @@ 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); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -302,7 +317,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_mpeg12_inst *inst, @@ -323,7 +338,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size) @@ -403,8 +418,12 @@ video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -412,13 +431,55 @@ kfree(inst); } +static int vdec_mpeg12_get_fb(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_mpeg12_get_vf(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.va, fb->base_y.bytes_used); + //dump_write(fb->base_c.va, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.va, fb->base_c.size); +} + static int vdec_write_nalu(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size, u64 ts) { 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); return ret; } @@ -446,8 +507,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -462,19 +522,6 @@ return ret; } -static void get_param_config_info(struct vdec_mpeg12_inst *inst, - struct aml_dec_params *parms) -{ - - if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO) - parms->hdr = inst->parms.hdr; - - parms->parms_status |= inst->parms.parms_status; - - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, - "parms status: %u\n", parms->parms_status); -} - static int vdec_mpeg12_get_param(unsigned long h_vdec, enum vdec_get_param_type type, void *out) { @@ -482,12 +529,20 @@ struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mpeg12 inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_mpeg12_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_mpeg12_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -500,17 +555,6 @@ get_crop_info(inst, out); break; - case GET_PARAM_CONFIG_INFO: - get_param_config_info(inst, out); - break; - - case GET_PARAM_DW_MODE: - { - unsigned int* mode = out; - *mode = VDEC_DW_NO_AFBC; - break; - } - default: v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "invalid get parameter type=%d\n", type); @@ -525,12 +569,6 @@ complete(&inst->comp); } -static void set_pic_info(struct vdec_mpeg12_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static void set_param_ps_info(struct vdec_mpeg12_inst *inst, struct aml_vdec_ps_infos *ps) { @@ -554,9 +592,6 @@ 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; @@ -568,28 +603,13 @@ 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, crop(%d x %d), coded(%d x %d) dpb: %d scan: %s\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, + dec->dpb_sz, pic->field == V4L2_FIELD_NONE ? "P" : "I"); } -static void set_param_hdr_info(struct vdec_mpeg12_inst *inst, - struct aml_vdec_hdr_infos *hdr) -{ - inst->parms.hdr = *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_PRINFO, - "mpeg12 set HDR infos\n"); - } -} - static int vdec_mpeg12_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -597,7 +617,7 @@ struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mpeg12 inst of dec is invalid.\n"); return -1; } @@ -606,19 +626,10 @@ case SET_PARAM_WRITE_FRAME_SYNC: set_param_write_sync(inst); break; - - case SET_PARAM_HDR_INFO: - set_param_hdr_info(inst, in); - break; - case SET_PARAM_PS_INFO: set_param_ps_info(inst, in); break; - case SET_PARAM_PIC_INFO: - set_pic_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_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c index bc0af24..c47bafc 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -28,6 +28,7 @@ #include "../aml_vcodec_dec.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_mpeg4_parser.h" #define NAL_TYPE(value) ((value) & 0x1F) @@ -110,6 +111,7 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_mpeg4_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; }; @@ -171,8 +173,6 @@ 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_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); @@ -188,14 +188,15 @@ { struct vdec_mpeg4_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) return -ENOMEM; - inst->vdec.frm_name = "MPEG4"; inst->vdec.video_type = VFORMAT_MPEG4; inst->vdec.format = VIDEO_DEC_FORMAT_MPEG4_5; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.config = ctx->config; inst->vdec.ctx = ctx; @@ -209,23 +210,16 @@ /* to eable mpeg4 hw.*/ inst->vdec.port.type = PORT_TYPE_VIDEO; - /* probe info from the stream */ - inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL); - if (!inst->vsi) { - ret = -ENOMEM; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); 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; + dec_init = true; ret = video_decoder_init(&inst->vdec); if (ret) { @@ -234,14 +228,38 @@ goto err; } + /* probe info from the stream */ + inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_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 = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); + if (!inst->vsi->header_buf) { + ret = -ENOMEM; + goto err; + } + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "mpeg4 Instance >> %lx\n", (ulong) inst); + init_completion(&inst->comp); + ctx->ada_ctx = &inst->vdec; + *h_vdec = (unsigned long)inst; + + //dump_init(); + return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -298,7 +316,7 @@ 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); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -309,7 +327,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_mpeg4_inst *inst, @@ -330,7 +348,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size) @@ -410,8 +428,12 @@ video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -419,13 +441,55 @@ kfree(inst); } +static int vdec_mpeg4_get_fb(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_mpeg4_get_vf(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.va, fb->base_y.bytes_used); + //dump_write(fb->base_c.va, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.va, fb->base_c.size); +} + static int vdec_write_nalu(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size, u64 ts) { 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); return ret; } @@ -453,8 +517,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -476,12 +539,20 @@ struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mpeg4 inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_mpeg4_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_mpeg4_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -493,12 +564,6 @@ case GET_PARAM_CROP_INFO: get_crop_info(inst, out); break; - case GET_PARAM_DW_MODE: - { - unsigned int* mode = out; - *mode = VDEC_DW_NO_AFBC; - break; - } default: v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, @@ -533,9 +598,6 @@ 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; @@ -547,9 +609,10 @@ 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, crop(%d x %d), coded(%d x %d) dpb: %d, scan:%s\n", ps->visible_width, ps->visible_height, ps->coded_width, ps->coded_height, + dec->dpb_sz, pic->field == V4L2_FIELD_NONE ? "P" : "I"); } @@ -558,12 +621,6 @@ complete(&inst->comp); } -static void set_pic_info(struct vdec_mpeg4_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static int vdec_mpeg4_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -571,7 +628,7 @@ struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the mpeg4 inst of dec is invalid.\n"); return -1; } @@ -580,15 +637,10 @@ 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; - 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_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c index fe81ddd..6704350 100644 --- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c +++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -29,6 +29,7 @@ #include "../aml_vcodec_drv.h" #include "../aml_vcodec_adapt.h" #include "../vdec_drv_base.h" +#include "../aml_vcodec_vfm.h" #include "aml_vp9_parser.h" #include "vdec_vp9_trigger.h" @@ -122,13 +123,13 @@ struct aml_vcodec_ctx *ctx; struct aml_vdec_adapt vdec; struct vdec_vp9_vsi *vsi; + struct vcodec_vfm_s vfm; struct aml_dec_params parms; struct completion comp; - struct vdec_comp_buf_info comp_info; }; 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); static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) @@ -169,7 +170,7 @@ pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;"); pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;"); - pbuf += sprintf(pbuf, "vp9_double_write_mode:1;"); + pbuf += sprintf(pbuf, "vp9_double_write_mode:16;"); pbuf += sprintf(pbuf, "vp9_buf_width:1920;"); pbuf += sprintf(pbuf, "vp9_buf_height:1088;"); pbuf += sprintf(pbuf, "vp9_max_pic_w:4096;"); @@ -186,10 +187,6 @@ { 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; @@ -211,11 +208,9 @@ 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 = 1; + ctx->config.parm.dec.cfg.double_write_mode = 16; ctx->config.parm.dec.cfg.ref_buf_margin = 7; ctx->config.length = vdec_config_default_parms(ctx->config.buf); } @@ -226,8 +221,6 @@ 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;", @@ -256,8 +249,6 @@ 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; @@ -273,8 +264,8 @@ if (!inst) return -ENOMEM; - inst->vdec.frm_name = "VP9"; inst->vdec.video_type = VFORMAT_VP9; + inst->vdec.dev = ctx->dev->vpu_plat_dev; inst->vdec.filp = ctx->dev->filp; inst->vdec.ctx = ctx; inst->ctx = ctx; @@ -288,6 +279,16 @@ /* to eable vp9 hw.*/ inst->vdec.port.type = PORT_TYPE_HEVC; + /* init vfm */ + inst->vfm.ctx = ctx; + inst->vfm.ada_ctx = &inst->vdec; + ret = vcodec_vfm_init(&inst->vfm); + if (ret) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "init vfm failed.\n"); + goto err; + } + /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL); if (!inst->vsi) { @@ -296,7 +297,7 @@ } /* alloc the header buffer to be used cache sps or spp etc.*/ - inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE); + inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL); if (!inst->vsi->header_buf) { ret = -ENOMEM; goto err; @@ -318,10 +319,14 @@ goto err; } + //dump_init(); + return 0; err: + if (inst) + vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst && inst->vsi) kfree(inst->vsi); if (inst) @@ -342,8 +347,8 @@ 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; + int w = inst->parms.cfg.init_width; + int h = inst->parms.cfg.init_height; u32 dw = 0x1; /*1:1*/ switch (valid_dw_mode) { @@ -438,11 +443,11 @@ } static int parse_stream_ucode(struct vdec_vp9_inst *inst, - u8 *buf, u32 size, u64 timestamp, ulong meta_ptr) + u8 *buf, u32 size, u64 timestamp) { int ret = 0; - ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr); + ret = vdec_write_nalu(inst, buf, size, timestamp); if (ret < 0) { v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, "write frame data failed. err: %d\n", ret); @@ -453,7 +458,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_ucode_dma(struct vdec_vp9_inst *inst, @@ -474,7 +479,7 @@ wait_for_completion_timeout(&inst->comp, msecs_to_jiffies(1000)); - return inst->vsi->pic.dpb_frames ? 0 : -1; + return inst->vsi->dec.dpb_sz ? 0 : -1; } static int parse_stream_cpu(struct vdec_vp9_inst *inst, u8 *buf, u32 size) @@ -523,7 +528,7 @@ if (inst->ctx->param_sets_from_ucode) { ret = parse_stream_ucode(inst, s->data, - s->len, bs->timestamp, 0); + s->len, bs->timestamp); } else { ret = parse_stream_cpu(inst, s->data, s->len); } @@ -534,7 +539,7 @@ } } else { if (inst->ctx->param_sets_from_ucode) { - ret = parse_stream_ucode(inst, buf, size, bs->timestamp, bs->meta_ptr); + ret = parse_stream_ucode(inst, buf, size, bs->timestamp); } else { ret = parse_stream_cpu(inst, buf, size); } @@ -547,13 +552,19 @@ static void vdec_vp9_deinit(unsigned long h_vdec) { + ulong flags; struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; struct aml_vcodec_ctx *ctx = inst->ctx; video_decoder_release(&inst->vdec); + vcodec_vfm_release(&inst->vfm); + + //dump_deinit(); + + spin_lock_irqsave(&ctx->slock, flags); if (inst->vsi && inst->vsi->header_buf) - vfree(inst->vsi->header_buf); + kfree(inst->vsi->header_buf); if (inst->vsi) kfree(inst->vsi); @@ -561,11 +572,54 @@ kfree(inst); ctx->drv_handle = 0; + spin_unlock_irqrestore(&ctx->slock, flags); need_trigger = false; dump_cnt = 0; } +static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out) +{ + return get_fb_from_queue(inst->ctx, out); +} + +static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out) +{ + struct vframe_s *vf = NULL; + struct vdec_v4l2_buffer *fb = NULL; + + vf = peek_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "there is no vframe.\n"); + *out = NULL; + return; + } + + vf = get_video_frame(&inst->vfm); + if (!vf) { + v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + "the vframe is avalid.\n"); + *out = NULL; + return; + } + + atomic_set(&vf->use_cnt, 1); + + fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; + fb->vf_handle = (unsigned long)vf; + fb->status = FB_ST_DISPLAY; + + *out = fb; + + //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used); + //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used); + //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used); + + /* convert yuv format. */ + //swap_uv(fb->base_c.vaddr, fb->base_c.size); +} + static void add_prefix_data(struct vp9_superframe_split *s, u8 **out, u32 *out_size) { @@ -716,7 +770,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); v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR, "write trigger frame %d\n", ret); p += frame_size; @@ -724,7 +778,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) { int ret = 0; struct aml_vdec_adapt *vdec = &inst->vdec; @@ -754,10 +808,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); vfree(data); } else { - ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr); + ret = vdec_vframe_write(vdec, buf, size, ts); } return ret; @@ -791,14 +845,18 @@ { struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; struct aml_vdec_adapt *vdec = &inst->vdec; - u8 *buf = (u8 *) bs->vaddr; - u32 size = bs->size; + u8 *buf; + u32 size; int ret = -1; if (bs == NULL) return -1; + buf = (u8 *) bs->vaddr; + size = bs->size; + if (vdec_input_full(vdec)) { + ATRACE_COUNTER("vdec_input_full", 0); return -EAGAIN; } @@ -820,8 +878,7 @@ ret = vdec_vframe_write(vdec, s->data, s->len, - bs->timestamp, - 0); + bs->timestamp); } else if (bs->model == VB2_MEMORY_DMABUF || bs->model == VB2_MEMORY_USERPTR) { ret = vdec_vframe_write_with_dma(vdec, @@ -834,8 +891,10 @@ 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); } + ATRACE_COUNTER("v4l2_decode_write", ret); return ret; } @@ -858,12 +917,6 @@ "parms status: %u\n", parms->parms_status); } -static void get_param_comp_buf_info(struct vdec_vp9_inst *inst, - struct vdec_comp_buf_info *params) -{ - memcpy(params, &inst->comp_info, sizeof(*params)); -} - static int vdec_vp9_get_param(unsigned long h_vdec, enum vdec_get_param_type type, void *out) { @@ -871,12 +924,20 @@ struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the vp9 inst of dec is invalid.\n"); return -1; } switch (type) { + case GET_PARAM_DISP_FRAME_BUFFER: + vdec_vp9_get_vf(inst, out); + break; + + case GET_PARAM_FREE_FRAME_BUFFER: + ret = vdec_vp9_get_fb(inst, out); + break; + case GET_PARAM_PIC_INFO: get_pic_info(inst, out); break; @@ -892,21 +953,6 @@ case GET_PARAM_CONFIG_INFO: get_param_config_info(inst, out); break; - - case GET_PARAM_DW_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); - 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); @@ -927,7 +973,6 @@ 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; /* fill visible area size that be used for EGL. */ pic->visible_width = ps->visible_width; @@ -943,16 +988,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); + 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 |= @@ -962,15 +1002,10 @@ complete(&inst->comp); v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, - "Parse from ucode, visible(%d x %d), coded(%d x %d)\n", - pic->visible_width, pic->visible_height, - pic->coded_width, pic->coded_height); -} - -static void set_param_comp_buf_info(struct vdec_vp9_inst *inst, - struct vdec_comp_buf_info *info) -{ - memcpy(&inst->comp_info, info, sizeof(*info)); + "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n", + ps->visible_width, ps->visible_height, + ps->coded_width, ps->coded_height, + ps->dpb_size); } static void set_param_hdr_info(struct vdec_vp9_inst *inst, @@ -995,12 +1030,6 @@ "VP9 post event: %d\n", *event); } -static void set_pic_info(struct vdec_vp9_inst *inst, - struct vdec_pic_info *pic) -{ - inst->vsi->pic = *pic; -} - static int vdec_vp9_set_param(unsigned long h_vdec, enum vdec_set_param_type type, void *in) { @@ -1008,7 +1037,7 @@ struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; if (!inst) { - v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR, + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "the vp9 inst of dec is invalid.\n"); return -1; } @@ -1022,10 +1051,6 @@ 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; @@ -1033,11 +1058,6 @@ case SET_PARAM_POST_EVENT: set_param_post_event(inst, in); break; - - case SET_PARAM_PIC_INFO: - set_pic_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/utils/common.c b/drivers/amvdec_ports/utils/common.c index 67cf93b..1d621da 100644 --- a/drivers/amvdec_ports/utils/common.c +++ b/drivers/amvdec_ports/utils/common.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> @@ -221,12 +240,3 @@ _pr_hex("print hex ending. len %d\n\n", l); } -bool is_over_size(int w, int h, int size) -{ - if (h != 0 && (w > size / h)) - return true; - - return false; -} - -
diff --git a/drivers/amvdec_ports/utils/common.h b/drivers/amvdec_ports/utils/common.h index 89ae50b..dd4c51f 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, @@ -132,8 +151,8 @@ AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" AVCOL_TRC_NB ///< Not part of ABI }; -#endif +#endif //fmt const char *av_color_space_name(enum AVColorSpace space); const char *av_color_primaries_name(enum AVColorPrimaries primaries); @@ -150,6 +169,4 @@ //debug void print_hex_debug(u8 *data, u32 len, int max); -bool is_over_size(int w, int h, int size); - -#endif \ No newline at end of file +#endif
diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c index 01510c5..ed9f053 100644 --- a/drivers/amvdec_ports/vdec_drv_if.c +++ b/drivers/amvdec_ports/vdec_drv_if.c
@@ -116,19 +116,6 @@ return ret; } -int vdec_if_set_param(struct aml_vcodec_ctx *ctx, - enum vdec_set_param_type type, void *in) -{ - int ret = 0; - - if (ctx->drv_handle == 0) - return -EIO; - - ret = ctx->dec_if->set_param(ctx->drv_handle, type, in); - - return ret; -} - void vdec_if_deinit(struct aml_vcodec_ctx *ctx) { if (ctx->drv_handle == 0)
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h index 29911f8..a04d832 100644 --- a/drivers/amvdec_ports/vdec_drv_if.h +++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -50,48 +50,33 @@ /** * struct vdec_fb_status - decoder frame buffer status - * @FB_ST_INIT : initial state - * @FB_ST_DECODER : frame buffer be allocted by decoder. - * @FB_ST_VPP : frame buffer be allocate by vpp. - * @FB_ST_DISPLAY : frame buffer is ready to be displayed. + * @FB_ST_NORMAL : initial state + * @FB_ST_DISPLAY : frmae buffer is ready to be displayed * @FB_ST_FREE : frame buffer is not used by decoder any more */ enum vdec_fb_status { - FB_ST_INIT, - FB_ST_DECODER, - FB_ST_VPP, - FB_ST_GE2D, + FB_ST_NORMAL, FB_ST_DISPLAY, 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, -}; - -/* +/* For GET_PARAM_DISP_FRAME_BUFFER and GET_PARAM_FREE_FRAME_BUFFER, * the caller does not own the returned buffer. The buffer will not be * released before vdec_if_deinit. + * GET_PARAM_DISP_FRAME_BUFFER : get next displayable frame buffer, + * struct vdec_fb** + * GET_PARAM_FREE_FRAME_BUFFER : get non-referenced framebuffer, vdec_fb** * GET_PARAM_PIC_INFO : get picture info, struct vdec_pic_info* * GET_PARAM_CROP_INFO : get crop info, struct v4l2_crop* * GET_PARAM_DPB_SIZE : get dpb size, unsigned int* - * GET_PARAM_DW_MODE: : get double write mode, unsigned int* - * GET_PARAM_COMP_BUF_INFO : get compressed buf info, struct vdec_comp_buf_info* */ enum vdec_get_param_type { + GET_PARAM_DISP_FRAME_BUFFER, + GET_PARAM_FREE_FRAME_BUFFER, GET_PARAM_PIC_INFO, GET_PARAM_CROP_INFO, GET_PARAM_DPB_SIZE, - GET_PARAM_CONFIG_INFO, - GET_PARAM_DW_MODE, - GET_PARAM_COMP_BUF_INFO + GET_PARAM_CONFIG_INFO }; /* @@ -100,11 +85,8 @@ enum vdec_set_param_type { SET_PARAM_WRITE_FRAME_SYNC, SET_PARAM_PS_INFO, - SET_PARAM_COMP_BUF_INFO, SET_PARAM_HDR_INFO, - SET_PARAM_POST_EVENT, - SET_PARAM_PIC_INFO, - SET_PARAM_CFG_INFO + SET_PARAM_POST_EVENT }; /** @@ -156,10 +138,7 @@ * @type : [in] input parameter type * @out : [out] buffer to store query result */ -int vdec_if_get_param(struct aml_vcodec_ctx *ctx, - enum vdec_get_param_type type, void *out); - -int vdec_if_set_param(struct aml_vcodec_ctx *ctx, - enum vdec_set_param_type type, void *in); +int vdec_if_get_param(struct aml_vcodec_ctx *ctx, enum vdec_get_param_type type, + void *out); #endif
diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c index 158e32c..d692ca8 100644 --- a/drivers/common/chips/chips.c +++ b/drivers/common/chips/chips.c
@@ -25,7 +25,7 @@ #include <linux/mm.h> #include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include "../../stream_input/amports/amports_priv.h" #include "../../frame_provider/decoder/utils/vdec.h" #include "chips.h" @@ -78,14 +78,6 @@ {AM_MESON_CPU_MAJOR_ID_TL1, "tl1"}, {AM_MESON_CPU_MAJOR_ID_TM2, "tm2"}, {AM_MESON_CPU_MAJOR_ID_SC2, "sc2"}, - {AM_MESON_CPU_MAJOR_ID_T5, "t5"}, - {AM_MESON_CPU_MAJOR_ID_T5D, "t5d"}, - {AM_MESON_CPU_MAJOR_ID_T7, "t7"}, - {AM_MESON_CPU_MAJOR_ID_S4, "s4"}, - {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_T5W, "t5w"}, {0, NULL}, };
diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c index af162b8..d74728c 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.c +++ b/drivers/common/chips/decoder_cpu_ver_info.c
@@ -24,7 +24,7 @@ #include <linux/errno.h> #include <linux/platform_device.h> #include <linux/of_device.h> -#include <linux/amlogic/media/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include "decoder_cpu_ver_info.h" #define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name" @@ -32,7 +32,6 @@ #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]= { @@ -58,22 +57,13 @@ 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_0x2c, 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_0x30, 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 const struct of_device_id cpu_ver_of_match[] = { @@ -124,90 +114,32 @@ .compatible = "amlogic, cpu-major-id-sc2", .data = &cpu_ver_info[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], - }, - { - .compatible = "amlogic, cpu-major-id-t5d", - .data = &cpu_ver_info[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], - }, - { - .compatible = "amlogic, cpu-major-id-s4", - .data = &cpu_ver_info[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], - }, - { - .compatible = "amlogic, cpu-major-id-p1", - .data = &cpu_ver_info[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], - }, - { - .compatible = "amlogic, cpu-major-id-t5w", - .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5W - 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], - }, - { - .compatible = "amlogic, cpu-major-id-tm2-b", - .data = &cpu_sub_info[1], - }, - { - .compatible = "amlogic, cpu-major-id-s4-805x2", - .data = &cpu_sub_info[2], - }, -}; - -static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pid_type, int *sub_id) +static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pidType) { - struct device_node *pnode = NULL; - struct platform_device *pdev = NULL; - const struct of_device_id *pmatch = NULL; + 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) { + pNode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME); + if (NULL == pNode) { pr_err("No find node.\n"); return -EINVAL; } - pdev = of_find_device_by_node(pnode); - if (NULL == pdev) + pDev = of_find_device_by_node(pNode); + if (NULL == pDev) return -EINVAL; - 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; - } + pMatch = of_match_device(cpu_ver_of_match, &pDev->dev); + if (NULL == pMatch) { + pr_err("No find of_match_device\n"); + return -EINVAL; } - *pid_type = (enum AM_MESON_CPU_MAJOR_ID)(*(int *)pmatch->data) & (MAJOY_ID_MASK); - - *sub_id = ((*(int *)pmatch->data) & (SUB_ID_MASK)) >> 8; + *pidType = *(enum AM_MESON_CPU_MAJOR_ID *)pMatch->data; return AM_SUCESS; } @@ -215,20 +147,15 @@ static void initial_cpu_id(void) { enum AM_MESON_CPU_MAJOR_ID id_type = AM_MESON_CPU_MAJOR_ID_MAX; - int sub_id = 0; - if (AM_SUCESS == get_cpu_id_from_dtb(&id_type, &sub_id)) { + if (AM_SUCESS == get_cpu_id_from_dtb(&id_type)) cpu_ver_id = id_type; - cpu_sub_id = sub_id; - } else { + else cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type(); - cpu_sub_id = (is_meson_rev_b()) ? CHIP_REVB : CHIP_REVA; - } - if ((AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) && (CHIP_REVB == cpu_sub_id)) - 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 (AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) + if (is_meson_rev_b()) + cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1; } enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void) @@ -240,32 +167,10 @@ } EXPORT_SYMBOL(get_cpu_major_id); -int get_cpu_sub_id(void) -{ - return cpu_sub_id; -} -EXPORT_SYMBOL(get_cpu_sub_id); - -bool is_cpu_meson_revb(void) -{ - if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id) - initial_cpu_id(); - - return (cpu_sub_id == CHIP_REVB); -} -EXPORT_SYMBOL(is_cpu_meson_revb); - bool is_cpu_tm2_revb(void) { - return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) - && (is_cpu_meson_revb())); + return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && + (is_meson_rev_b())); } EXPORT_SYMBOL(is_cpu_tm2_revb); -bool is_cpu_s4_s805x2(void) -{ - return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4) - && (get_cpu_sub_id() == CHIP_REVX)); -} -EXPORT_SYMBOL(is_cpu_s4_s805x2); -
diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h index 6129244..673b001 100644 --- a/drivers/common/chips/decoder_cpu_ver_info.h +++ b/drivers/common/chips/decoder_cpu_ver_info.h
@@ -19,11 +19,9 @@ */ #ifndef DECODER_CPU_VER_INFO_H #define DECODER_CPU_VER_INFO_H -#include <linux/amlogic/media/registers/cpu_version.h> -/* majoy chip id define */ -#define MAJOY_ID_MASK (0x000000ff) -enum AM_MESON_CPU_MAJOR_ID { +enum AM_MESON_CPU_MAJOR_ID +{ AM_MESON_CPU_MAJOR_ID_M6 = 0x16, AM_MESON_CPU_MAJOR_ID_M6TV = 0x17, AM_MESON_CPU_MAJOR_ID_M6TVL = 0x18, @@ -46,50 +44,18 @@ AM_MESON_CPU_MAJOR_ID_G12B = 0x29, AM_MESON_CPU_MAJOR_ID_GXLX2 = 0x2a, AM_MESON_CPU_MAJOR_ID_SM1 = 0x2b, - AM_MESON_CPU_MAJOR_ID_A1 = 0x2c, + AM_MESON_CPU_MAJOR_ID_RES_0x2c, AM_MESON_CPU_MAJOR_ID_RES_0x2d, AM_MESON_CPU_MAJOR_ID_TL1 = 0x2e, AM_MESON_CPU_MAJOR_ID_TM2 = 0x2f, - AM_MESON_CPU_MAJOR_ID_C1 = 0x30, + AM_MESON_CPU_MAJOR_ID_RES_0x30, AM_MESON_CPU_MAJOR_ID_RES_0x31, AM_MESON_CPU_MAJOR_ID_SC2 = 0x32, - AM_MESON_CPU_MAJOR_ID_C2 = 0x33, - AM_MESON_CPU_MAJOR_ID_T5 = 0x34, - AM_MESON_CPU_MAJOR_ID_T5D = 0x35, - AM_MESON_CPU_MAJOR_ID_T7 = 0x36, - AM_MESON_CPU_MAJOR_ID_S4 = 0x37, - AM_MESON_CPU_MAJOR_ID_T3 = 0x38, - 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_RES_0x33, + AM_MESON_CPU_MAJOR_ID_T5, AM_MESON_CPU_MAJOR_ID_MAX, }; -/* chips sub id define */ -#define CHIP_REVA 0x0 -#define CHIP_REVB 0x1 -#define CHIP_REVC 0x2 -#define CHIP_REVX 0x10 - -#define REVB_MASK (CHIP_REVB << 8) -#define REVC_MASK (CHIP_REVC << 8) -#define REVX_MASK (CHIP_REVX << 8) - -#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_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) - -/* export functions */ enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void); - -bool is_cpu_meson_revb(void); - bool is_cpu_tm2_revb(void); - -int get_cpu_sub_id(void); - -bool is_cpu_s4_s805x2(void); - #endif
diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c index 9422198..85a81e6 100644 --- a/drivers/common/firmware/firmware_drv.c +++ b/drivers/common/firmware/firmware_drv.c
@@ -25,7 +25,7 @@ #include <linux/slab.h> #include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include "../../stream_input/amports/amports_priv.h" #include "../../frame_provider/decoder/utils/vdec.h" #include "firmware_priv.h" @@ -34,14 +34,13 @@ #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 <uapi/linux/major.h> +#include <linux/amlogic/major.h> #include <linux/cdev.h> #include <linux/crc32.h> #include "../chips/decoder_cpu_ver_info.h" /* major.minor */ -#define PACK_VERS "v0.3" +#define PACK_VERS "v0.2" #define CLASS_NAME "firmware_codec" #define DEV_NAME "firmware_vdec" @@ -76,7 +75,6 @@ struct fw_mgr_s *g_mgr; struct fw_dev_s *g_dev; -struct package_head_s package_head; static u32 debug; static u32 detail; @@ -87,7 +85,7 @@ struct fw_mgr_s *mgr = g_mgr; struct fw_info_s *info; - pr_info("[%s], the fw (%s) will be loaded...\n", + pr_info("[%s], the fw (%s) will be loaded.\n", tee_enabled() ? "TEE" : "LOCAL", get_fw_format_name(format)); @@ -111,7 +109,6 @@ break; } - out: mutex_unlock(&mutex); @@ -344,8 +341,6 @@ struct fw_info_s *info; unsigned int secs = 0; struct tm tm; - char history_change_id[7] = {0}; - int i; mutex_lock(&mutex); @@ -355,21 +350,7 @@ } /* shows version of driver. */ - pr_info("The ucode driver version is %s\n", PACK_VERS); - - pr_info("The firmware version is %d.%d.%d-g%s\n", - (package_head.version >> 16) & 0xff, - package_head.version & 0xff, - package_head.submit_count, - package_head.commit); - - pr_info("change id history:\n"); - for (i = 0; i < 5; i++) { - 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); - - } + pr_info("The driver version is %s\n", PACK_VERS); list_for_each_entry(info, &mgr->fw_head, node) { if (IS_ERR_OR_NULL(info->data)) @@ -394,8 +375,7 @@ secs = info->data->head.time - sys_tz.tz_minuteswest * 60; - //time_to_tm(secs, 0, &tm);//kernel4.9 - time64_to_tm(secs, 0, &tm); + time_to_tm(secs, 0, &tm); pr_info("%s %-16s, %02d:%02d:%02d %d/%d/%ld, %s %-8s, %s %-8s, %s %s\n", "fmt:", info->data->head.format, @@ -597,7 +577,6 @@ if (ret != 2) return -1; - package_head = pack->head; major_fw = (pack->head.version >> 16) & 0xff; minor_fw = pack->head.version & 0xff; @@ -616,7 +595,7 @@ if (debug) { pr_info("The package has %d fws totally.\n", pack->head.total); pr_info("The driver ver is v%d.%d\n", major, minor); - pr_info("The firmware ver is v%d.%d.%d\n", major_fw, minor_fw, pack->head.submit_count); + pr_info("The firmware ver is v%d.%d\n", major_fw, minor_fw); } return 0; @@ -931,7 +910,6 @@ return count; } -#if 0 //kernel4.9 static struct class_attribute fw_class_attrs[] = { __ATTR(info, 0664, info_show, info_store), __ATTR(reload, 0664, reload_show, reload_store), @@ -943,26 +921,7 @@ .name = CLASS_NAME, .class_attrs = fw_class_attrs, }; -#else //below is for kernel 4.19 and 5.4 -static CLASS_ATTR_RW(info); -static CLASS_ATTR_RW(reload); -static CLASS_ATTR_RW(debug); -static struct attribute *fw_class_attrs[] = { - &class_attr_info.attr, - &class_attr_reload.attr, - &class_attr_debug.attr, - NULL -}; - -ATTRIBUTE_GROUPS(fw_class); - -static struct class fw_class = { - .name = CLASS_NAME, - .class_groups = fw_class_groups, -}; - -#endif static int fw_driver_init(void) { int ret = -1;
diff --git a/drivers/common/firmware/firmware_priv.h b/drivers/common/firmware/firmware_priv.h index d901f9d..410745b 100644 --- a/drivers/common/firmware/firmware_priv.h +++ b/drivers/common/firmware/firmware_priv.h
@@ -85,11 +85,7 @@ int checksum; int total; int version; - int submit_count; - char change_id[16]; - char commit[16]; - char history_change_id[30]; - char reserved[62]; + char reserved[128]; }; struct package_s {
diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c index 8d95c12..c232020 100644 --- a/drivers/common/firmware/firmware_type.c +++ b/drivers/common/firmware/firmware_type.c
@@ -76,13 +76,6 @@ {AM_MESON_CPU_MAJOR_ID_TL1, "tl1"}, {AM_MESON_CPU_MAJOR_ID_TM2, "tm2"}, {AM_MESON_CPU_MAJOR_ID_SC2, "sc2"}, - {AM_MESON_CPU_MAJOR_ID_T5, "t5"}, - {AM_MESON_CPU_MAJOR_ID_T5D, "t5d"}, - {AM_MESON_CPU_MAJOR_ID_T7, "t7"}, - {AM_MESON_CPU_MAJOR_ID_S4, "s4"}, - {AM_MESON_CPU_MAJOR_ID_T3, "t3"}, - {AM_MESON_CPU_MAJOR_ID_P1, "p1"}, - {AM_MESON_CPU_MAJOR_ID_S4D, "s4d"}, }; const char *get_fw_format_name(unsigned int format)
diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h index 4615baf..e997057 100644 --- a/drivers/common/firmware/firmware_type.h +++ b/drivers/common/firmware/firmware_type.h
@@ -80,7 +80,6 @@ #define OPTEE_VDEC_LEGENCY (0) #define OPTEE_VDEC (1) #define OPTEE_VDEC_HEVC (2) -#define OPTEE_VDEC_HCDEC (3) struct format_name_s { unsigned int format;
diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c index 6340c1a..972bcc1 100644 --- a/drivers/common/media_clock/clk/clk.c +++ b/drivers/common/media_clock/clk/clk.c
@@ -27,7 +27,7 @@ #include <linux/slab.h> #include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include "../../../stream_input/amports/amports_priv.h" #include "../../../frame_provider/decoder/utils/vdec.h" #include "../../chips/chips.h" @@ -165,7 +165,7 @@ void hcodec_clock_enable(void) { - hcodec_clock_set(667); + hcodec_clock_set(1); } EXPORT_SYMBOL(hcodec_clock_enable); @@ -311,21 +311,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); @@ -353,8 +338,7 @@ || format == VFORMAT_AV1) { 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()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { ret_clk = hevc_back_clock_set(clk); clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps; } @@ -388,7 +372,7 @@ */ return 0; /* ignore don't needed firmare. */ } - mgr = kmalloc(sizeof(struct chip_vdec_clk_s), GFP_KERNEL); + mgr = vzalloc(sizeof(struct chip_vdec_clk_s)); if (!mgr) return -ENOMEM; *mgr = *t_mgr; @@ -397,7 +381,7 @@ */ if (mgr->clock_init) { if (mgr->clock_init()) { - kfree(mgr); + vfree(mgr); return -ENOMEM; } } @@ -420,7 +404,7 @@ int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type) { - kfree(get_current_vdec_chip()->clk_mgr[vdec_type]); + vfree(get_current_vdec_chip()->clk_mgr[vdec_type]); return 0; } @@ -439,7 +423,7 @@ */ return 0; /* ignore don't needed this setting . */ } - p_setting = kmalloc(size, GFP_KERNEL); + p_setting = vzalloc(size); if (!p_setting) return -ENOMEM; memcpy(p_setting, setting, size); @@ -465,7 +449,7 @@ int unregister_vdec_clk_setting(void) { - kfree(get_current_vdec_chip()->clk_setting_array); + vfree(get_current_vdec_chip()->clk_setting_array); return 0; }
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h index bbc3bee..82eec1d 100644 --- a/drivers/common/media_clock/clk/clk.h +++ b/drivers/common/media_clock/clk/clk.h
@@ -52,8 +52,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); @@ -132,7 +130,7 @@ #endif #ifdef VDEC_HAS_HEVC register_vdec_clk_mgr(cpus, VDEC_HEVC, &vdec_hevc_clk_mgr); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) register_vdec_clk_mgr(cpus, VDEC_HEVCB, &vdec_hevc_back_clk_mgr); #endif #ifdef VDEC_HAS_VDEC_HCODEC
diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c index c49d150..be2401c 100644 --- a/drivers/common/media_clock/clk/clkg12.c +++ b/drivers/common/media_clock/clk/clkg12.c
@@ -114,6 +114,11 @@ WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1);\ }while(0) +#define CHECK_RET(_ret) if (ret) {debug_print(\ + "%s:%d:function call failed with result: %d\n",\ + __FUNCTION__, __LINE__, _ret);} + + static int clock_real_clk[VDEC_MAX + 1]; static unsigned int set_frq_enable, vdec_frq, hevc_frq, hevcb_frq; @@ -125,14 +130,19 @@ static int gp_pll_user_cb_vdec(struct gp_pll_user_handle_s *user, int event) { + int ret; + debug_print("gp_pll_user_cb_vdec call\n"); if (event == GP_PLL_USER_EVENT_GRANT) { struct clk *clk = clk_get(NULL, "gp0_pll"); if (!IS_ERR(clk)) { - if (is_gp0_div2) - clk_set_rate(clk, 1296000000UL); - else - clk_set_rate(clk, 648000000UL); + if (is_gp0_div2) { + ret = clk_set_rate(clk, 1296000000UL); + CHECK_RET(ret); + } else { + ret = clk_set_rate(clk, 648000000UL); + CHECK_RET(ret); + } VDEC1_SAFE_CLOCK(); VDEC1_CLOCK_OFF(); if (is_gp0_div2) @@ -416,9 +426,7 @@ struct gate_switch_node *node = NULL; char *hevc_mux_str = NULL; - 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)) + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) hevc_mux_str = "clk_hevc_mux"; else hevc_mux_str = "clk_hevcf_mux"; @@ -458,6 +466,7 @@ static int vdec_set_clk(int dec, int rate) { struct clk *clk = NULL; + int ret; switch (dec) { case VDEC_1: @@ -497,7 +506,8 @@ return -1; } - clk_set_rate(clk, rate); + ret = clk_set_rate(clk, rate); + CHECK_RET(ret); return 0; } @@ -513,12 +523,12 @@ { gp_pll_user_vdec = gp_pll_user_register("vdec", 0, gp_pll_user_cb_vdec); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) is_gp0_div2 = false; else is_gp0_div2 = true; - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) { + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) { pr_info("used fix clk for vdec clk source!\n"); //update_vdec_clk_config_settings(1); } @@ -733,14 +743,9 @@ } 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) + get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1) clk = 800; - if (is_cpu_s4_s805x2()) - clk = 500; - if (set_frq_enable && vdec_frq) { pr_info("Set the vdec frq is %u MHz\n", vdec_frq); clk = vdec_frq; @@ -836,15 +841,10 @@ 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)) + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) clk = TL1_HEVC_MAX_CLK; else clk = 667; - - if (is_cpu_s4_s805x2()) - clk = 500; } if (set_frq_enable && hevc_frq) { @@ -1042,14 +1042,6 @@ AM_MESON_CPU_MAJOR_ID_TL1,\ AM_MESON_CPU_MAJOR_ID_TM2,\ AM_MESON_CPU_MAJOR_ID_SC2,\ - 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,\ 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..9d5f7b4 100644 --- a/drivers/common/media_clock/switch/amports_gate.c +++ b/drivers/common/media_clock/switch/amports_gate.c
@@ -99,11 +99,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_info("get gate %s control failed %p\n", gates[i].name, gates[i].clk); } else { - pr_info("get gate %s control ok %px\n", + pr_info("get gate %s control ok %p\n", gates[i].name, gates[i].clk); }
diff --git a/drivers/fake_video_out/Makefile b/drivers/fake_video_out/Makefile new file mode 100644 index 0000000..1dd937c --- /dev/null +++ b/drivers/fake_video_out/Makefile
@@ -0,0 +1 @@ +obj-m += fake_video.o
diff --git a/drivers/fake_video_out/fake_video.c b/drivers/fake_video_out/fake_video.c new file mode 100644 index 0000000..e0e9b16 --- /dev/null +++ b/drivers/fake_video_out/fake_video.c
@@ -0,0 +1,309 @@ +/* +* 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/version.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/mutex.h> +#include <linux/ctype.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/poll.h> +#include <linux/clk.h> +#include <linux/debugfs.h> +#include <linux/dma-mapping.h> +#include <linux/dma-contiguous.h> +#include <linux/sched.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/major.h> +#include "../frame_provider/decoder/utils/vdec.h" +#include <linux/delay.h> +#include <linux/kthread.h> + +#define RECEIVER_NAME "fake-amvideo" +#define DEVICE_NAME "fake-amvideo" + +#define TUNNEL_MODE (0) +#define NON_TUNNEL_MODE (1) + +static u32 display_mode = TUNNEL_MODE; +module_param(display_mode, uint, 0664); +MODULE_PARM_DESC(display_mode, "\n display_mode\n"); + +static struct device *amvideo_dev = NULL; +struct timer_list timer; +struct task_struct *task; +bool thread_stop = false; +atomic_t frame_count; + +static struct vframe_receiver_s fake_video_vf_recv; +static int video_receiver_event_fun(int type, void *data, void *); +static const struct vframe_receiver_op_s fake_video_vf_receiver = { + .event_cb = video_receiver_event_fun +}; + +static struct vframe_s *video_vf_peek(void) +{ + return vf_peek(RECEIVER_NAME); +} + +static struct vframe_s *video_vf_get(void) +{ + struct vframe_s *vf = NULL; + + vf = vf_get(RECEIVER_NAME); + + if (vf) { + atomic_set(&vf->use_cnt, 1); + /*pr_err("Get vframe w: %d, h: %d, fence: %lx, idx: %d\n", + vf->width, vf->height, (ulong)vf->fence, vf->index & 0xff);*/ + } + + return vf; +} + +static void video_vf_put(struct vframe_s *vf) +{ + struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME); + + if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) { + vf_put(vf, RECEIVER_NAME); + } +} + +static int video_receiver_event_fun(int type, void *data, void *private_data) +{ + switch (type) { + case VFRAME_EVENT_PROVIDER_UNREG: { + atomic_set(&frame_count, 0); + pr_info("VFRAME_EVENT_PROVIDER_UNREG\n"); + break; + } + case VFRAME_EVENT_PROVIDER_START: { + pr_info("VFRAME_EVENT_PROVIDER_START\n"); + break; + } + case VFRAME_EVENT_PROVIDER_QUREY_STATE: { + break; + } + case VFRAME_EVENT_PROVIDER_VFRAME_READY: { + pr_info("VFRAME_EVENT_PROVIDER_VFRAME_READY\n"); + atomic_inc(&frame_count); + break; + } + default: + break; + } + + return 0; +} + +static void display_timer_func(unsigned long arg) +{ + struct vframe_s *vf = NULL; + + if (display_mode != TUNNEL_MODE) + goto out; + + vf = video_vf_peek(); + if (!vf) { + goto out; + } + + if (vf->fence) { + if (vdec_fence_status_get(vf->fence) == 1) { + pr_info("[VDEC-FENCE]: Display, idx: %d\n", + vf->index & 0xff); + vf = video_vf_get(); + video_vf_put(vf); + } else { + pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n"); + } + } + +out: + mod_timer(&timer, jiffies + msecs_to_jiffies(16)); +} + +static int display_thread(void *data) +{ + struct vframe_s *vf = NULL; + + for (;;) { + if (thread_stop) + break; + + if ((atomic_read(&frame_count) == 0) || + display_mode != NON_TUNNEL_MODE) + continue; + + if (video_vf_peek()) { + vf = video_vf_get(); + if (!vf) { + pr_err("receiver vf err.\n"); + break; + } + + atomic_dec(&frame_count); + + if (vf->fence) { + u64 timestamp = local_clock(); + /* fence waiting until frame ready. */ + vdec_fence_wait(vf->fence, msecs_to_jiffies(2000)); + + if (vdec_fence_status_get(vf->fence) == 1) { + pr_info("[VDEC-FENCE]: Display, idx: %d, dec cost: %lld\n", + vf->index & 0xff, local_clock() - timestamp); + } else { + pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n"); + } + } + + video_vf_put(vf); + } + msleep(16); + } + return 0; +} + +static int amvideo_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static int amvideo_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg) +{ + file->private_data = NULL; + return 0; +} + +#ifdef CONFIG_COMPAT +static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg) +{ + file->private_data = NULL; + return 0; +} +#endif + +static const struct file_operations amvideo_fops = { + .owner = THIS_MODULE, + .open = amvideo_open, + .release = amvideo_release, + .unlocked_ioctl = amvideo_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = amvideo_compat_ioctl, +#endif + //.poll = amvideo_poll, +}; + +static struct class amvideo_class = { + .name = "fake_video", +}; + +#define FAKEVIDEO_MAJOR (23 + (AML_BASE)) + +static int __init fake_video_init(void) +{ + int ret = 0; + + ret = class_register(&amvideo_class); + if (ret) { + pr_err("create video class fail.\n"); + return 0; + } + + + /* create video device */ + ret = register_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME, &amvideo_fops); + if (ret < 0) { + pr_err("Can't register major for amvideo device\n"); + goto err1; + } + + amvideo_dev = device_create(&amvideo_class, NULL, + MKDEV(FAKEVIDEO_MAJOR, 0), NULL, DEVICE_NAME); + if (IS_ERR(amvideo_dev)) { + pr_err("Can't create amvideo device\n"); + goto err; + } + + vf_receiver_init(&fake_video_vf_recv, RECEIVER_NAME, + &fake_video_vf_receiver, NULL); + vf_reg_receiver(&fake_video_vf_recv); + + atomic_set(&frame_count, 0); + + init_timer(&timer); + //timer.data = 0; + timer.function = display_timer_func; + timer.expires = jiffies + HZ; + add_timer(&timer); + + thread_stop = false; + task = kthread_run(display_thread, NULL, "aml-%s", "fake-video-thread"); + if (IS_ERR(task)) { + ret = PTR_ERR(task); + pr_err("Failed to creat display thread, ret: %d.\n", ret); + goto err; + } + + return 0; + +err: + unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME); +err1: + class_unregister(&amvideo_class); + + return ret; +} + +static void __exit fake_video_exit(void) +{ + thread_stop = true; + kthread_stop(task); + + del_timer_sync(&timer); + + vf_unreg_receiver(&fake_video_vf_recv); + + device_destroy(&amvideo_class, MKDEV(FAKEVIDEO_MAJOR, 0)); + unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME); + class_unregister(&amvideo_class); + +} + + +module_init(fake_video_init); +module_exit(fake_video_exit); + + +MODULE_DESCRIPTION("AMLOGIC fake video output driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>"); +
diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile index f30c4f1..371e088 100644 --- a/drivers/frame_provider/Makefile +++ b/drivers/frame_provider/Makefile
@@ -1,2 +1 @@ obj-y += decoder/ -obj-y += decoder_v4l/
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile index bb0079e..349d381 100644 --- a/drivers/frame_provider/decoder/Makefile +++ b/drivers/frame_provider/decoder/Makefile
@@ -7,6 +7,7 @@ obj-y += h265/ obj-y += vp9/ obj-y += mjpeg/ +obj-y += real/ obj-y += avs/ obj-y += avs2/ obj-y += avs_multi/
diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c index 5869eac..6314f9d 100644 --- a/drivers/frame_provider/decoder/avs/avs.c +++ b/drivers/frame_provider/decoder/avs/avs.c
@@ -43,8 +43,8 @@ #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> +#include <linux/amlogic/tee.h> + #define DRIVER_NAME "amvdec_avs" #define MODULE_NAME "amvdec_avs" @@ -162,6 +162,7 @@ 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; @@ -412,7 +413,6 @@ } } - #ifdef HANDLE_AVS_IRQ static irqreturn_t vavs_isr(int irq, void *dev_id) #else @@ -654,7 +654,6 @@ 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); @@ -741,6 +740,7 @@ 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); @@ -945,35 +945,35 @@ else endian = 0; #ifdef NV21 - config_cav_lut_ex(canvas_base + canvas_num * i + 0, + canvas_config_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, + vdec->canvas_mode, endian); + canvas_config_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); + vdec->canvas_mode, endian); #else - config_cav_lut_ex(canvas_num * i + 0, + canvas_config_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, + vdec->canvas_mode, endian); + canvas_config_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, + vdec->canvas_mode, endian); + canvas_config_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); + vdec->canvas_mode, endian); #endif if (debug_flag & AVS_DEBUG_PRINT) { pr_info("canvas config %d, addr %p\n", i, @@ -1353,8 +1353,10 @@ } } -static void vavs_put_timer_func(struct timer_list *timer) +static void vavs_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; + #ifndef HANDLE_AVS_IRQ vavs_isr(); #endif @@ -1571,6 +1573,7 @@ return -ENOMEM; pr_info("vavs_init\n"); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -1654,8 +1657,10 @@ stat |= STAT_VF_HOOK; - timer_setup(&recycle_timer, vavs_put_timer_func, 0); + recycle_timer.data = (ulong)(&recycle_timer); + recycle_timer.function = vavs_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM;
diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c index de9a3d2..3da87e4 100644 --- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c +++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
@@ -39,9 +39,7 @@ #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 <linux/amlogic/tee.h> #include "../../../stream_input/amports/amports_priv.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> #include "../utils/decoder_mmu_box.h"
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h index be35a5e..3e7fcb8 100644 --- a/drivers/frame_provider/decoder/avs2/avs2_global.h +++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -772,9 +772,6 @@ 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; @@ -817,9 +814,6 @@ u32 hw_decode_time; u32 frame_size; // For frame base mode - - char *cuva_data_buf; - int cuva_data_size; };
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c index e21dc55..a5d550f 100644 --- a/drivers/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -37,9 +37,7 @@ #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 <linux/amlogic/tee.h> #include "../../../stream_input/amports/amports_priv.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> #include "../utils/decoder_mmu_box.h" @@ -57,46 +55,26 @@ #include "../utils/config_parser.h" #include "../utils/firmware.h" #include "../../../common/chips/decoder_cpu_ver_info.h" -#include "../utils/vdec_feature.h" +#include <linux/amlogic/tee.h> + #define I_ONLY_SUPPORT #define MIX_STREAM_SUPPORT +#define G12A_BRINGUP_DEBUG #define CONSTRAIN_MAX_BUF_NUM -#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 @@ -249,9 +227,6 @@ #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]; @@ -261,11 +236,17 @@ static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM]; static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM]; +#ifdef G12A_BRINGUP_DEBUG static u32 decode_timeout_val = 200; - +#else +static u32 decode_timeout_val = 200; +#endif static int start_decode_buf_level = 0x8000; - -static u32 work_buf_size; +#ifdef AVS2_10B_MMU +static u32 work_buf_size; /* = 24 * 1024 * 1024*/; +#else +static u32 work_buf_size = 32 * 1024 * 1024; +#endif static u32 mv_buf_margin; static int pre_decode_buf_level = 0x1000; @@ -279,7 +260,6 @@ * 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; @@ -318,7 +298,7 @@ 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 vavs2_put_timer_func(unsigned long arg); static void dump_data(struct AVS2Decoder_s *dec, int size); static unsigned char get_data_check_sum (struct AVS2Decoder_s *dec, int size); @@ -350,8 +330,6 @@ 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", @@ -427,6 +405,11 @@ #define DOUBLE_WRITE_YSTART_TEMP 0x02000000 #define DOUBLE_WRITE_CSTART_TEMP 0x02900000 + + +typedef unsigned int u32; +typedef unsigned short u16; + #define AVS2_DBG_BUFMGR 0x01 #define AVS2_DBG_BUFMGR_MORE 0x02 #define AVS2_DBG_BUFMGR_DETAIL 0x04 @@ -442,7 +425,6 @@ #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_DIS_LOC_ERROR_PROC 0x10000 #define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000 #define AVS2_DBG_DUMP_PIC_LIST 0x40000 @@ -515,9 +497,6 @@ 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) @@ -532,6 +511,11 @@ #define WRITE_VREG WRITE_VREG_DBG2 #endif + +//#ifdef AVS2_10B_MMU +//#define MMU_COMPRESS_HEADER_SIZE 0x48000 +//#define MMU_COMPRESS_8K_HEADER_SIZE 0x48000*4 +//#endif #define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000 #define MMU_COMPRESS_HEADER_SIZE_4K 0x48000 #define MMU_COMPRESS_HEADER_SIZE_8K 0x120000 @@ -546,7 +530,7 @@ #define FRAME_CONTEXTS_LOG2 2 #define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) /*buffer + header buffer + workspace*/ - +#undef MV_USE_FIXED_BUF #ifdef MV_USE_FIXED_BUF #define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1) #define VF_BUFFER_IDX(n) (n) @@ -558,7 +542,6 @@ #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 @@ -601,10 +584,6 @@ 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; @@ -689,22 +668,11 @@ 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; - +#if 1 + /*AVS2_10B_MMU*/ 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]; @@ -807,14 +775,10 @@ u32 dynamic_buf_margin; int sidebind_type; int sidebind_channel_id; - u32 endian; char vdec_name[32]; char pts_name[32]; char new_q_name[32]; char disp_q_name[32]; - dma_addr_t rdma_phy_adr; - unsigned *rdma_adr; - int hdr_flag; }; static int compute_losless_comp_body_size( @@ -924,19 +888,10 @@ static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec) { - u32 dw_mode; - - dw_mode = (dec->m_ins_flag && + return (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) @@ -994,6 +949,18 @@ return dw; } +static int get_double_write_ratio(struct AVS2Decoder_s *dec, + int dw_mode) +{ + int ratio = 1; + if ((dw_mode == 2) || + (dw_mode == 3)) + ratio = 4; + else if (dw_mode == 4) + ratio = 2; + return ratio; +} + //#define MAX_4K_NUM 0x1200 #ifdef AVS2_10B_MMU int avs2_alloc_mmu( @@ -1007,6 +974,25 @@ int bit_depth_10 = (bit_depth == AVS2_BITS_10); int picture_size; int cur_mmu_4k_number, max_frame_num; +#ifdef DYNAMIC_ALLOC_HEAD + unsigned long buf_addr; + struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic; + if (pic->header_adr == 0) { + if (decoder_bmmu_box_alloc_buf_phy + (dec->bmmu_box, + HEADER_BUFFER_IDX(cur_buf_idx), + get_compress_header_size(dec), + DRIVER_HEADER_NAME, + &buf_addr) < 0){ + avs2_print(dec, 0, + "%s malloc compress header failed %d\n", + DRIVER_HEADER_NAME, cur_buf_idx); + dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; + return -1; + } else + pic->header_adr = buf_addr; + } +#endif picture_size = compute_losless_comp_body_size( dec, pic_width, pic_height, @@ -1029,38 +1015,157 @@ } #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) +#if 0 +/*ndef MV_USE_FIXED_BUF*/ +static void dealloc_mv_bufs(struct AVS2Decoder_s *dec) { - int bit_depth_10 = (bit_depth == AVS2_BITS_10); - int picture_size; - int cur_mmu_4k_number, max_frame_num; - - picture_size = compute_losless_comp_body_size( - 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; - 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 -1; + int i; + for (i = 0; i < FRAME_BUFFERS; i++) { + if (dec->m_mv_BUF[i].start_adr) { + if (debug) + pr_info( + "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n", + i, dec->m_mv_BUF[i].start_adr, + dec->m_mv_BUF[i].size, + dec->m_mv_BUF[i].used_flag); + decoder_bmmu_box_free_idx( + dec->bmmu_box, + MV_BUFFER_IDX(i)); + dec->m_mv_BUF[i].start_adr = 0; + dec->m_mv_BUF[i].size = 0; + dec->m_mv_BUF[i].used_flag = 0; + } } - return decoder_mmu_box_alloc_idx( - dec->dw_mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); } + +static int alloc_mv_buf(struct AVS2Decoder_s *dec, + int i, int size) +{ + int ret = 0; + if (decoder_bmmu_box_alloc_buf_phy + (dec->bmmu_box, + MV_BUFFER_IDX(i), size, + DRIVER_NAME, + &dec->m_mv_BUF[i].start_adr) < 0) { + dec->m_mv_BUF[i].start_adr = 0; + ret = -1; + } else { + dec->m_mv_BUF[i].size = size; + dec->m_mv_BUF[i].used_flag = 0; + ret = 0; + if (debug) { + pr_info( + "MV Buffer %d: start_adr %p size %x\n", + i, + (void *)dec->m_mv_BUF[i].start_adr, + dec->m_mv_BUF[i].size); + } + } + return ret; +} + +static int init_mv_buf_list(struct AVS2Decoder_s *dec) +{ + int i; + int ret = 0; + int count = FRAME_BUFFERS; + int pic_width = dec->init_pic_w; + int pic_height = dec->init_pic_h; + int lcu_size = 64; /*fixed 64*/ + 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 size = ((lcu_total * MV_MEM_UNIT) + 0xffff) & + (~0xffff); + if (mv_buf_margin > 0) + count = dec->avs2_dec.ref_maxbuffer + mv_buf_margin; + for (i = 0; i < count; i++) { + if (alloc_mv_buf(dec, i, size) < 0) { + ret = -1; + break; + } + } + return ret; +} +#if 0 + +static int get_mv_buf(struct AVS2Decoder_s *dec, + struct avs2_frame_s *pic) +{ + int i; + int ret = -1; + for (i = 0; i < FRAME_BUFFERS; i++) { + if (dec->m_mv_BUF[i].start_adr && + dec->m_mv_BUF[i].used_flag == 0) { + dec->m_mv_BUF[i].used_flag = 1; + ret = i; + break; + } + } + + if (ret >= 0) { + pic->mv_buf_index = ret; + pic->mpred_mv_wr_start_addr = + (dec->m_mv_BUF[ret].start_adr + 0xffff) & + (~0xffff); + if (debug & AVS2_DBG_BUFMGR_MORE) + pr_info( + "%s => %d (%d) size 0x%x\n", + __func__, ret, + pic->mpred_mv_wr_start_addr, + dec->m_mv_BUF[ret].size); + } else { + pr_info( + "%s: Error, mv buf is not enough\n", + __func__); + } + return ret; +} + +static void put_mv_buf(struct AVS2Decoder_s *dec, + struct avs2_frame_s *pic) +{ + int i = pic->mv_buf_index; + if (i >= FRAME_BUFFERS) { + if (debug & AVS2_DBG_BUFMGR_MORE) + pr_info( + "%s: index %d beyond range\n", + __func__, i); + return; + } + if (debug & AVS2_DBG_BUFMGR_MORE) + pr_info( + "%s(%d): used_flag(%d)\n", + __func__, i, + dec->m_mv_BUF[i].used_flag); + + pic->mv_buf_index = -1; + if (dec->m_mv_BUF[i].start_adr && + dec->m_mv_BUF[i].used_flag) + dec->m_mv_BUF[i].used_flag = 0; +} + +static void put_un_used_mv_bufs(struct AVS2Decoder_s *dec) +{ + struct VP9_Common_s *const cm = &dec->common; + struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; + int i; + for (i = 0; i < dec->used_buf_num; ++i) { + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.index != -1) && + (frame_bufs[i].buf.mv_buf_index >= 0) + ) + put_mv_buf(dec, &frame_bufs[i].buf); + } +} +#endif + #endif static int get_free_buf_count(struct AVS2Decoder_s *dec) @@ -1203,19 +1308,13 @@ const u32 avs2_version = 201602101; +static u32 debug; 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) - +static u32 endian = 0xff0; #ifdef ERROR_HANDLE_DEBUG static u32 dbg_nal_skip_flag; /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */ @@ -1319,9 +1418,6 @@ #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 @@ -1380,10 +1476,7 @@ #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 +#define WORK_BUF_SPEC_NUM 3 static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = { { /* 8M bytes */ @@ -1392,283 +1485,6 @@ .ipp = { /* IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k */ - .buf_size = 0x4000, - }, - .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*/ - }, -#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*/ - }, -#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, - }, - .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*/ - }, -#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*/ - }, -#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, - }, - .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*/ - }, -#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, - }, -#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, - .max_height = 1088, - .ipp = { - /* IPP work space calculation : - 4096 * (Y+CbCr+Flags) = 12k, round to 16k */ .buf_size = 0x1e00, }, .sao_abv = { @@ -1740,16 +1556,6 @@ }, #endif #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) - }, -#endif -#endif .mpred_above = { .buf_size = 0x1e00, /* 2 * size of hevc*/ }, @@ -1845,16 +1651,6 @@ }, #endif #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) - }, -#endif -#endif .mpred_above = { .buf_size = 0x4000, /* 2 * size of hevc*/ }, @@ -1943,16 +1739,6 @@ }, #endif #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) - }, -#endif -#endif .mpred_above = { .buf_size = 0x8000, }, @@ -2054,70 +1840,64 @@ struct BuffInfo_s *buf_spec) { void *mem_start_virt; - buf_spec->ipp.buf_start = - WORKBUF_ALIGN(buf_spec->start_adr); + buf_spec->ipp.buf_start = buf_spec->start_adr; buf_spec->sao_abv.buf_start = - WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); + buf_spec->ipp.buf_start + buf_spec->ipp.buf_size; + buf_spec->sao_vb.buf_start = - WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size); + 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->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->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->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->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->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->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->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->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->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_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); + 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->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->mmu_vbh.buf_start + buf_spec->mmu_vbh.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 */ + buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size; +#endif #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->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); + 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); + 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->rpm.buf_start + + buf_spec->rpm.buf_size; buf_spec->end_adr = - WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size); + buf_spec->lmem.buf_start + + buf_spec->lmem.buf_size; if (dec) { mem_start_virt = @@ -2170,10 +1950,6 @@ 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 @@ -2191,11 +1967,9 @@ 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; - } +#if 0 +/*ndef MV_USE_FIXED_BUF*/ + dealloc_mv_bufs(dec); #endif decoder_mmu_box_free(dec->mmu_box); dec->mmu_box = NULL; @@ -2236,9 +2010,9 @@ if (dw_mode) { int pic_width_dw = pic_width / - get_double_write_ratio(dw_mode); + get_double_write_ratio(dec, dw_mode); int pic_height_dw = pic_height / - get_double_write_ratio(dw_mode); + get_double_write_ratio(dec, 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); @@ -2269,7 +2043,7 @@ for (i = 0; i < dec->used_buf_num; i++) { if (((i + 1) * buf_size) > dec->mc_buf->buf_size) dec->use_cma_flag = 1; - +#ifndef AVS2_10B_MMU dec->m_BUF[i].alloc_flag = 0; dec->m_BUF[i].index = i; @@ -2310,6 +2084,7 @@ "Buffer %d: start_adr %p size %x\n", i, (void *)dec->m_BUF[i].start_adr, dec->m_BUF[i].size); +#endif } dec->buf_num = i; } @@ -2334,7 +2109,15 @@ pic_height_32 / lcu_size + 1 : pic_height_32 / lcu_size; int lcu_total = pic_width_lcu * pic_height_lcu; - +#if 0 + int32_t MV_MEM_UNIT = + (lcu_size_log2 == 6) ? 0x200 : + ((lcu_size_log2 == 5) ? 0x80 : 0x20); +#endif +#ifdef MV_USE_FIXED_BUF + u32 mpred_mv_end = dec->work_space_buf->mpred_mv.buf_start + + dec->work_space_buf->mpred_mv.buf_size; +#endif u32 y_adr = 0; int buf_size = 0; @@ -2350,11 +2133,11 @@ int mc_buffer_size_u_v_h = 0; int dw_mode = get_double_write_mode_init(dec); - if (dw_mode && ((dw_mode & 0x20) == 0)) { + if (dw_mode) { int pic_width_dw = pic_width / - get_double_write_ratio(dw_mode); + get_double_write_ratio(dec, dw_mode); int pic_height_dw = pic_height / - get_double_write_ratio(dw_mode); + get_double_write_ratio(dec, dw_mode); int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f); int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f); int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ? @@ -2373,150 +2156,171 @@ } 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 +#ifndef AVS2_10B_MMU 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 ((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 - ); - return ret; - } - - if (pic->cma_alloc_addr) - y_adr = pic->cma_alloc_addr; - 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*/ - 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 + - ((mc_buffer_size_u_v_h << 16) << 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 + - ((mc_buffer_size_u_v_h << 16) << 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 + - ((mc_buffer_size_u_v_h << 16) << 1); +#ifndef DYNAMIC_ALLOC_HEAD + pic->header_adr = decoder_bmmu_box_get_phy_addr( + dec->bmmu_box, HEADER_BUFFER_IDX(pic->index)); + + avs2_print(dec, AVS2_DBG_BUFMGR_MORE, + "buf_size %d, MMU header_adr %d: %ld\n", + buf_size, pic->index, pic->header_adr); #endif +#endif + + i = pic->index; +#ifdef MV_USE_FIXED_BUF +#ifdef G12A_BRINGUP_DEBUG + if (1) { +#else + if ((dec->work_space_buf->mpred_mv.buf_start + + (((i + 1) * lcu_total) * MV_MEM_UNIT)) + <= mpred_mv_end + ) { +#endif +#endif +#ifndef AVS2_10B_MMU + if (debug) { + pr_err("start %x .size=%d\n", + dec->mc_buf_spec.buf_start + i * buf_size, + buf_size); + } +#endif +#ifndef AVS2_10B_MMU + 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 ((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 + ); + return ret; + } + + if (pic->cma_alloc_addr) + y_adr = pic->cma_alloc_addr; + 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*/ + pic->BUF_index = i; + pic->lcu_total = lcu_total; + + pic->comp_body_size = losless_comp_body_size; + pic->buf_size = buf_size; +#ifndef AVS2_10B_MMU + pic->mc_y_adr = y_adr; +#endif + pic->mc_canvas_y = pic->index; + pic->mc_canvas_u_v = pic->index; +#ifndef AVS2_10B_MMU + if (dw_mode & 0x10) { + pic->mc_u_v_adr = y_adr + + ((mc_buffer_size_u_v_h << 16) << 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) { + pic->dw_y_adr = y_adr +#ifndef AVS2_10B_MMU + + (mc_buffer_size_h << 16) +#endif + ; + pic->dw_u_v_adr = pic->dw_y_adr + + ((mc_buffer_size_u_v_h << 16) << 1); +#ifdef AVS2_10B_MMU + pic->mc_y_adr = pic->dw_y_adr; + pic->mc_u_v_adr = pic->dw_u_v_adr; +#endif + } +#ifdef MV_USE_FIXED_BUF +#ifdef G12A_BRINGUP_DEBUG + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + pic->mpred_mv_wr_start_addr = + dec->work_space_buf->mpred_mv.buf_start + + (pic->index * 0x120000 * 4); + } else { + pic->mpred_mv_wr_start_addr = + dec->work_space_buf->mpred_mv.buf_start + + (pic->index * 0x120000); + } +#else + pic->mpred_mv_wr_start_addr = + dec->work_space_buf->mpred_mv.buf_start + + ((pic->index * lcu_total) + * MV_MEM_UNIT); +#endif +#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\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, + pic->dw_u_v_adr); + } + ret = 0; } #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\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, - pic->dw_u_v_adr); - } - ret = 0; + } else { + avs2_print(dec, 0, + "mv buffer alloc fail %x > %x\n", + dec->work_space_buf->mpred_mv.buf_start + + (((i + 1) * lcu_total) * MV_MEM_UNIT), + mpred_mv_end); } - +#endif return ret; } @@ -2527,28 +2331,36 @@ 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; - } + unsigned long buf_addr1; + /*alloc AVS2 compress header first*/ + if (decoder_bmmu_box_alloc_buf_phy + (dec->bmmu_box, + HEADER_BUFFER_IDX(-1), get_compress_header_size(dec), + DRIVER_HEADER_NAME, + &buf_addr1) < 0){ + avs2_print(dec, 0, + "%s malloc compress header failed %d\n", + DRIVER_HEADER_NAME, -1); + dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; + return; + } +#ifndef DYNAMIC_ALLOC_HEAD + for (i = 0; i < dec->used_buf_num; i++) { + unsigned long buf_addr; + if (decoder_bmmu_box_alloc_buf_phy + (dec->bmmu_box, + HEADER_BUFFER_IDX(i), get_compress_header_size(dec), + 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; } } #endif +#endif dec->frame_height = avs2_dec->img.height; dec->frame_width = avs2_dec->img.width; @@ -3261,7 +3073,7 @@ if ((get_double_write_mode(dec) & 0x10) == 0) WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr); #endif - if ((get_double_write_mode(dec) & 0x20) == 0) { + if (get_double_write_mode(dec)) { 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); @@ -3273,14 +3085,6 @@ #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) << 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);*/ @@ -3297,22 +3101,6 @@ 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*/ @@ -3344,41 +3132,23 @@ 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, + 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 |= 0x670; // Big-Endian per 64-bit */ + data32 |= endian; /* Big-Endian per 64-bit */ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ #if 0 if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) { @@ -3396,18 +3166,6 @@ 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); if (get_double_write_mode(dec) & 0x10) { @@ -3421,55 +3179,26 @@ 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 ((get_double_write_mode(dec) & 0xf) == 8 || - (get_double_write_mode(dec) & 0xf) == 9) { + if (get_double_write_mode(dec) == 2 || + get_double_write_mode(dec) == 3) data32 |= (0xff<<16); - WRITE_VREG(HEVC_SAO_CTRL26, 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) + else if (get_double_write_mode(dec) == 4) data32 |= (0x33<<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 |= (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 */ + data32 |= 0xf; /* valid only when double write only */ + /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ 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, @@ -3736,110 +3465,6 @@ #endif } -static u32 init_cuva_size; -static int cuva_data_is_avaible(struct AVS2Decoder_s *dec) -{ - u32 reg_val; - - reg_val = READ_VREG(AVS2_CUVA_DATA_SIZE); - 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; -} - -static 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_avaible(dec)) { - avs2_print(dec, AVS2_DBG_HDR_INFO, - "%s:pic 0x%p or data not avaible\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, - "cuva: (size %d)\n", - pic->cuva_data_size); - if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) { - 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; @@ -3886,12 +3511,6 @@ #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); - } -#endif WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start); //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); @@ -3961,38 +3580,11 @@ #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); - +#if 1 +/*MULTI_INSTANCE_SUPPORT*/ + /*new added in simulation???*/ 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 } @@ -4019,6 +3611,7 @@ 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); @@ -4073,13 +3666,11 @@ 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); - } + + 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); @@ -4261,6 +3852,10 @@ } #endif + + + + static struct AVS2Decoder_s gAVS2Decoder; static void avs2_local_uninit(struct AVS2Decoder_s *dec) @@ -4273,14 +3868,6 @@ dec->rpm_phy_addr); dec->rpm_addr = NULL; } - - if (dec->cuva_addr) { - dma_free_coherent(amports_get_dma_device(), - dec->cuva_size, dec->cuva_addr, - dec->cuva_phy_addr); - dec->cuva_addr = NULL; - } - if (dec->lmem_addr) { if (dec->lmem_phy_addr) dma_free_coherent(amports_get_dma_device(), @@ -4298,17 +3885,6 @@ dec->frame_mmu_map_addr = NULL; } #endif - -#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(), - 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; - } -#endif - if (dec->gvs) vfree(dec->gvs); dec->gvs = NULL; @@ -4326,27 +3902,16 @@ memcpy(cur_buf_info, &amvavs2_workbuff_spec[force_bufspec & 0xf], sizeof(struct BuffInfo_s)); 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) - memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */ - sizeof(struct BuffInfo_s)); - else - memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */ - sizeof(struct BuffInfo_s)); - } else - 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()) { - memcpy(cur_buf_info, &amvavs2_workbuff_spec[5], /* 8k */ - sizeof(struct BuffInfo_s)); - } else - memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */ - sizeof(struct BuffInfo_s)); - } - } + } else if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */ + sizeof(struct BuffInfo_s)); + else + memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */ + sizeof(struct BuffInfo_s)); + } else + memcpy(cur_buf_info, &amvavs2_workbuff_spec[0],/* 1080p */ + sizeof(struct BuffInfo_s)); cur_buf_info->start_adr = dec->buf_start; #ifndef AVS2_10B_MMU @@ -4372,15 +3937,14 @@ } 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; - } + + 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 = 8192; + buf_alloc_height = 4608; } dec->init_pic_w = buf_alloc_width ? buf_alloc_width : (dec->vavs2_amstream_dec_info.width ? @@ -4390,6 +3954,13 @@ (dec->vavs2_amstream_dec_info.height ? dec->vavs2_amstream_dec_info.height : dec->work_space_buf->max_height); +#if 0 +/*ndef MV_USE_FIXED_BUF*/ + if (init_mv_buf_list(dec) < 0) { + pr_err("%s: init_mv_buf_list fail\n", __func__); + return -1; + } +#endif #ifndef AVS2_10B_MMU init_buf_list(dec); @@ -4419,20 +3990,6 @@ dec->rpm_ptr = dec->rpm_addr; } - 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); - 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 = dma_alloc_coherent(amports_get_dma_device(), LMEM_BUF_SIZE, &dec->lmem_phy_addr, GFP_KERNEL); @@ -4443,33 +4000,21 @@ 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 = dma_alloc_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(dec), - &dec->frame_mmu_map_phy_addr, GFP_KERNEL); - 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(dec)); + dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(), + get_frame_mmu_map_size(dec), + &dec->frame_mmu_map_phy_addr, GFP_KERNEL); + 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(dec)); #endif -#ifdef AVS2_10B_MMU_DW - if (dec->dw_mmu_enable) { - dec->dw_frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(dec), - &dec->dw_frame_mmu_map_phy_addr, GFP_KERNEL); - 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(dec)); - } -#endif ret = 0; return ret; } @@ -4505,11 +4050,16 @@ /*CANVAS_BLKMODE_64X32*/ if (pic->double_write_mode) { canvas_w = pic->pic_w / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(dec, + 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); + get_double_write_ratio(dec, + pic->double_write_mode); + + if (mem_map_mode == 0) + canvas_w = ALIGN(canvas_w, 32); + else + canvas_w = ALIGN(canvas_w, 64); canvas_h = ALIGN(canvas_h, 32); if (vdec->parallel_dec == 1) { @@ -4522,23 +4072,31 @@ pic->uv_canvas_index = 128 + pic->index * 2 + 1; } - config_cav_lut_ex(pic->y_canvas_index, + canvas_config_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, + CANVAS_ADDR_NOWRAP, blkmode, 0x7); + canvas_config_ex(pic->uv_canvas_index, pic->dw_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, 0x7); #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].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[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].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; #endif } else { @@ -4553,12 +4111,12 @@ pic->uv_canvas_index = 128 + pic->index; } - config_cav_lut_ex(pic->y_canvas_index, + canvas_config_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); + CANVAS_ADDR_NOWRAP, blkmode, 0x7); + canvas_config_ex(pic->uv_canvas_index, + pic->mc_u_v_adr, canvas_w, canvas_h, + CANVAS_ADDR_NOWRAP, blkmode, 0x7); #endif } } @@ -4572,14 +4130,8 @@ 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_typesignal_type 0x%x \n", - vf->signal_type); - pixel_ratio = dec->vavs2_amstream_dec_info.ratio; if (dec->vavs2_ratio == 0) { @@ -4809,32 +4361,6 @@ 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; - - 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; @@ -4936,7 +4462,7 @@ __func__, pic->index, pic->imgtr_fwRefDistance); - if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0) + if (pic->double_write_mode) set_canvas(dec, pic); display_frame_count[dec->index]++; @@ -4949,7 +4475,7 @@ } else { #endif if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { - /* if (pts_lookup_offset(PTS_TYPE_VIDEO, + /* if (pts_lookup_offset(PTS_TYPE_VIDEO, stream_offset, &vf->pts, 0) != 0) { */ if (pts_lookup_offset_us64 (PTS_TYPE_VIDEO, stream_offset, @@ -5004,16 +4530,18 @@ if (vf->pts != 0) dec->last_lookup_pts = vf->pts; - +#if 1 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); +#endif dec->last_pts = vf->pts; if (vf->pts_us64 != 0) dec->last_lookup_pts_us64 = vf->pts_us64; +#if 1 if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION) && ((pic->slice_type != I_IMG) || (!pts_discontinue && !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) { @@ -5021,7 +4549,7 @@ dec->last_pts_us64 + (DUR2PTS(dec->frame_dur) * 100 / 9); } - +#endif 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", @@ -5036,30 +4564,16 @@ 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 - + vf->compBodyAddr = 0; + vf->compHeadAddr = pic->header_adr; #else - vf->compBodyAddr = pic->mc_y_adr; /*body adr*/ - vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size; + vf->compBodyAddr = pic->mc_y_adr; /*body adr*/ + vf->compHeadAddr = pic->mc_y_adr + + pic->comp_body_size; + /*head adr*/ #endif } - if (pic->double_write_mode && - ((pic->double_write_mode & 0x20) == 0)) { + if (pic->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; vf->type |= VIDTYPE_VIU_NV21; @@ -5123,26 +4637,17 @@ vf->width,vf->height, pic->width, pic->height); */ vf->width = pic->pic_w / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(dec, + pic->double_write_mode); vf->height = pic->pic_h / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(dec, + 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; - } + vf->compWidth = pic->pic_w; + vf->compHeight = pic->pic_h; if (force_fps & 0x100) { u32 rate = force_fps & 0xff; if (rate) @@ -5152,26 +4657,12 @@ } #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); - 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); 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, @@ -5214,6 +4705,7 @@ dec->gvs->status = dec->stat | dec->fatal_error; } + static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec) { #ifndef NO_DISPLAY @@ -5233,8 +4725,7 @@ if (pic->error_mark) { avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, - "!!!error pic, skip\n", - 0); + "!!!error pic, skip\n"); continue; } @@ -5243,7 +4734,7 @@ pic->slice_type != I_IMG) { avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "!!!slice type %d (not I) skip\n", - 0, pic->slice_type); + pic->slice_type); continue; } dec->skip_PB_before_I = 0; @@ -5280,7 +4771,7 @@ memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info)); tmp4x.bit_depth_luma = bit_depth_luma; tmp4x.bit_depth_chroma = bit_depth_chroma; - tmp4x.double_write_mode = pic->double_write_mode; + tmp4x.double_write_mode = get_double_write_mode(dec); vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, &tmp4x, vf, pic->hw_decode_time); pvdec->vdec_fps_detec(pvdec->id); if (without_display_mode == 0) { @@ -5474,7 +4965,7 @@ struct vdec_s *vdec = hw_to_vdec(dec); if (!picture) { avs2_print(dec, AVS2_DBG_BUFMGR_MORE, - "%s decode picture is none exist\n"); + "decode picture is none exist\n"); return; } @@ -5941,7 +5432,6 @@ PRINT_LINE(); dec->start_decoding_flag |= 0x3; if (dec->m_ins_flag) { - set_cuva_data(dec); update_decoded_pic(dec); get_picture_qos_info(dec); reset_process_time(dec); @@ -6071,19 +5561,31 @@ dec->avs2_dec.hc.cur_pic = NULL; 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) { - if (pic->refered_by_others == 0) { + if (dec->avs2_dec.fref[ii]-> + bg_flag == 0 && + dec->avs2_dec.fref[ii]-> + is_output == -1 && + dec->avs2_dec.fref[ii]-> + mmu_alloc_flag && + dec->avs2_dec.fref[ii]-> + vf_ref == 0) { + struct avs2_frame_s *pic = + dec->avs2_dec.fref[ii]; + if (dec->avs2_dec.fref[ii]-> + refered_by_others == 0) { #ifdef AVS2_10B_MMU - pic->mmu_alloc_flag = 0; + dec->avs2_dec.fref[ii]-> + mmu_alloc_flag = 0; /*release_buffer_4k( dec->avs2_dec.fref[ii]->index);*/ decoder_mmu_box_free_idx(dec->mmu_box, - pic->index); + dec->avs2_dec.fref[ii]->index); +#ifdef DYNAMIC_ALLOC_HEAD + decoder_bmmu_box_free_idx( + dec->bmmu_box, + HEADER_BUFFER_IDX(pic->index)); + pic->header_adr = 0; +#endif #endif #ifndef MV_USE_FIXED_BUF decoder_bmmu_box_free_idx( @@ -6092,6 +5594,10 @@ pic->mpred_mv_wr_start_addr = 0; #endif } + decoder_bmmu_box_free_idx( + dec->bmmu_box, + VF_BUFFER_IDX(pic->index)); + dec->cma_alloc_addr = 0; } } } @@ -6128,7 +5634,7 @@ 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 0 // 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)) { union param_u *pPara; @@ -6212,9 +5718,9 @@ u32 convert_c = c; if (v & 0x2000) { - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "video_signal_type present:\n"); - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, " %s %s\n", video_format_names[(v >> 10) & 7], ((v >> 9) & 1) ? @@ -6223,21 +5729,21 @@ u32 transfer; u32 maxtrix; - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "color_description present:\n"); - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "color_primarie = %d\n", v & 0xff); - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "transfer_characteristic = %d\n", (c >> 8) & 0xff); - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, " matrix_coefficient = %d\n", c & 0xff); transfer = (c >> 8) & 0xFF; if (transfer >= 15) - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "unsupport transfer_characteristic\n"); else if (transfer == 14) transfer = 18; /* HLG */ @@ -6250,7 +5756,7 @@ maxtrix = c & 0xFF; if (maxtrix >= 10) - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, "unsupport matrix_coefficient\n"); else if (maxtrix == 9) maxtrix = 10; @@ -6259,7 +5765,7 @@ convert_c = (transfer << 8) | (maxtrix); - avs2_print(dec, AVS2_DBG_HDR_INFO, + avs2_print(dec, 0, " convered c:0x%x\n", convert_c); } @@ -6318,58 +5824,34 @@ if (!dec->m_ins_flag) dec->slice_idx++; - if (dec->m_ins_flag && ret - && 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) { - ret = avs2_alloc_mmu(dec, + if (ret >= 0) { + 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, - 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 + ret); } +#endif #ifndef MV_USE_FIXED_BUF - if (ret >= 0 && dec->avs2_dec.hc.cur_pic-> + 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( @@ -6398,8 +5880,7 @@ ret); WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL); #ifdef AVS2_10B_MMU - if (dec->mmu_enable) - avs2_recycle_mmu_buf(dec); + avs2_recycle_mmu_buf(dec); #endif if (dec->m_ins_flag) { dec->dec_result = DEC_RESULT_DONE; @@ -6594,10 +6075,10 @@ return IRQ_WAKE_THREAD; } -static void vavs2_put_timer_func(struct timer_list *timer) +static void vavs2_put_timer_func(unsigned long arg) { - struct AVS2Decoder_s *dec = container_of(timer, - struct AVS2Decoder_s, timer); + struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)arg; + struct timer_list *timer = &dec->timer; uint8_t empty_flag; unsigned int buf_level; @@ -6715,7 +6196,6 @@ } if (debug & AVS2_DBG_DUMP_RPM_BUF) { int i; - pr_info("RPM:\n"); for (i = 0; i < RPM_BUF_SIZE; i += 4) { int ii; @@ -6732,7 +6212,6 @@ } if (debug & AVS2_DBG_DUMP_LMEM_BUF) { int i; - pr_info("LMEM:\n"); for (i = 0; i < LMEM_BUF_SIZE; i += 4) { int ii; @@ -6928,7 +6407,6 @@ WRITE_VREG(DECODE_STOP_POS, udebug_flag); - config_cuva_buf(dec); } #ifdef I_ONLY_SUPPORT @@ -7017,8 +6495,7 @@ int fw_size = 0x1000 * 16; struct firmware_s *fw = NULL; struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private; - - timer_setup(&dec->timer, vavs2_put_timer_func, 0); + init_timer(&dec->timer); dec->stat |= STAT_TIMER_INIT; if (vavs2_local_init(dec) < 0) @@ -7040,6 +6517,8 @@ fw->len = fw_size; if (dec->m_ins_flag) { + dec->timer.data = (ulong) dec; + dec->timer.function = vavs2_put_timer_func; dec->timer.expires = jiffies + PUT_INTERVAL; /*add_timer(&dec->timer); @@ -7052,9 +6531,7 @@ return 0; } - amhevc_enable(); - ret = amhevc_loadmc_ex(VFORMAT_AVS2, NULL, fw->data); if (ret < 0) { amhevc_disable(); @@ -7097,7 +6574,11 @@ } dec->stat |= STAT_VF_HOOK; + dec->timer.data = (ulong)dec; + dec->timer.function = vavs2_put_timer_func; dec->timer.expires = jiffies + PUT_INTERVAL; + + add_timer(&dec->timer); dec->stat |= STAT_TIMER_ARM; @@ -7189,32 +6670,17 @@ CODEC_MM_FLAGS_TVP : 0; int buf_size = 48; +#ifdef AVS2_10B_MMU 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; - } - } -#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; - } + 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; } #endif dec->bmmu_box = decoder_bmmu_box_alloc_box( @@ -7235,20 +6701,16 @@ 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 BUF_s BUF[MAX_BUF_NUM]; 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); + 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->init_flag = 0; dec->first_sc_checked = 0; dec->eos = 0; @@ -7266,14 +6728,6 @@ dec->platform_dev = pdev; platform_set_drvdata(pdev, pdata); -#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"); @@ -7309,12 +6763,6 @@ } 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; /*pdata->set_isreset = vavs2_set_isreset;*/ @@ -7360,16 +6808,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int avs2_suspend(struct device *dev) +{ + amhevc_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int avs2_resume(struct device *dev) +{ + amhevc_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops avs2_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(avs2_suspend, avs2_resume) +}; +#endif 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, +#ifdef CONFIG_PM + .pm = &avs2_pm_ops, +#endif } }; @@ -7537,8 +7001,8 @@ decode_frame_count[dec->index] = dec->frame_count; #ifdef AVS2_10B_MMU - if (dec->mmu_enable) - dec->used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); + dec->used_4k_num = + (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); #endif avs2_print(dec, PRINT_FLAG_VDEC_STATUS, "%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n", @@ -7912,7 +7376,7 @@ 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", + "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n", i, dec->m_mv_BUF[i].start_adr, dec->m_mv_BUF[i].size, @@ -8001,18 +7465,12 @@ 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 AVS2Decoder_s *dec = NULL; + struct BUF_s BUF[MAX_BUF_NUM]; + struct AVS2Decoder_s *dec = NULL; 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; @@ -8020,7 +7478,8 @@ /*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)); + dec = vmalloc(sizeof(struct AVS2Decoder_s)); + memset(dec, 0, sizeof(struct AVS2Decoder_s)); if (dec == NULL) { pr_info("\nammvdec_avs2 device data allocation failed\n"); return -ENOMEM; @@ -8044,26 +7503,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); - */ + 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; - if (is_rdma_enable()) { - dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &dec->rdma_phy_adr, GFP_KERNEL); - 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->vdec_name, sizeof(dec->vdec_name), "avs2-%d", dec->index); @@ -8093,8 +7538,9 @@ 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) { +#if 1 + if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && + pdata->config_len) { /*use ptr config for doubel_write_mode, etc*/ avs2_print(dec, 0, "pdata->config=%s\n", pdata->config); if (get_config_int(pdata->config, "avs2_double_write_mode", @@ -8155,7 +7601,9 @@ | (9 << 0); /* 2020 */ } dec->vf_dp = vf_dp; - } else { + } else +#endif + { /*dec->vavs2_amstream_dec_info.width = 0; dec->vavs2_amstream_dec_info.height = 0; dec->vavs2_amstream_dec_info.rate = 30;*/ @@ -8164,21 +7612,10 @@ } 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 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 0 + dec->buf_start = pdata->mem_start; + dec->buf_size = pdata->mem_end - pdata->mem_start + 1; +#else if (amvdec_avs2_mmu_init(dec) < 0) { pr_err("avs2 alloc bmmu box failed!!\n"); /* devm_kfree(&pdev->dev, (void *)dec); */ @@ -8197,7 +7634,7 @@ } dec->buf_start = dec->cma_alloc_addr; dec->buf_size = work_buf_size; - +#endif dec->init_flag = 0; dec->first_sc_checked = 0; dec->fatal_error = 0; @@ -8219,12 +7656,6 @@ 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 (endian) - dec->endian = endian; - dec->cma_dev = pdata->cma_dev; if (vavs2_init(pdata) < 0) { pr_info("\namvdec_avs2 init failed.\n"); @@ -8253,8 +7684,6 @@ 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) @@ -8275,21 +7704,11 @@ } } - 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()) - dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr); /* devm_kfree(&pdev->dev, (void *)dec); */ vfree((void *)dec); return 0; @@ -8298,12 +7717,11 @@ 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, +#ifdef CONFIG_PM + .pm = &avs2_pm_ops, +#endif } }; #endif @@ -8349,22 +7767,16 @@ { #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]; - } + 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]; init_buff_spec(NULL, p_buf_info); work_buf_size = @@ -8391,10 +7803,10 @@ 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_unsupport"; - } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + amvdec_avs2_profile.profile = + "8k, 10bit, dwrite, compressed"; + } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { if (vdec_is_support_4k()) amvdec_avs2_profile.profile = "4k, 10bit, dwrite, compressed"; @@ -8402,9 +7814,7 @@ amvdec_avs2_profile.profile = "10bit, dwrite, compressed"; } else { - /* cpu id larger than sm1 support 8k */ - amvdec_avs2_profile.profile = - "8k, 10bit, dwrite, compressed"; + amvdec_avs2_profile.name = "avs2_unsupport"; } vcodec_profile_register(&amvdec_avs2_profile); @@ -8414,7 +7824,6 @@ INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node, "avs2", avs2_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_AVS2, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.h b/drivers/frame_provider/decoder/avs2/vavs2.h index 071bfb3..6b51f61 100644 --- a/drivers/frame_provider/decoder/avs2/vavs2.h +++ b/drivers/frame_provider/decoder/avs2/vavs2.h
@@ -19,7 +19,7 @@ #define VAVS2_H #define AVS2_10B_MMU -#define AVS2_10B_MMU_DW +#define MV_USE_FIXED_BUF 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);
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c index 7dd20bb..38e39d0 100644 --- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c +++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -44,7 +44,6 @@ #include "../utils/firmware.h" #include "../../../common/chips/decoder_cpu_ver_info.h" #include <linux/amlogic/tee.h> -#include "../utils/vdec_feature.h" #define DEBUG_MULTI_FLAG 0 /* @@ -124,6 +123,9 @@ #define DECODE_CFG AV_SCRATCH_K + + + #define VF_POOL_SIZE 64 #define PUT_INTERVAL (HZ/100) @@ -151,7 +153,7 @@ #define DEBUG_REG2 AV_SCRATCH_D -static void check_timer_func(struct timer_list *timer); +static void check_timer_func(unsigned long arg); static void vavs_work(struct work_struct *work); #define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001 @@ -1270,35 +1272,35 @@ } else { #ifdef NV21 - config_cav_lut_ex(canvas_base + canvas_num * i + 0, + canvas_config(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, + 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, 0, VDEC_1); + CANVAS_BLKMODE_32X32); #else - config_cav_lut_ex(canvas_num * i + 0, + canvas_config(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, + 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, 0, VDEC_1); - config_cav_lut_ex(canvas_num * i + 2, + 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, 0, VDEC_1); + CANVAS_BLKMODE_32X32); #endif debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, "canvas config %d, addr %p\n", i, @@ -1390,7 +1392,6 @@ #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); #endif - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); #ifdef PIC_DC_NEED_CLEAR CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); @@ -1600,21 +1601,21 @@ vavs_restore_regs(hw); for (i = 0; i < hw->vf_buf_num_used; i++) { - config_cav_lut_ex(canvas_y(hw->canvas_spec[i]), + canvas_config_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); + 0); - config_cav_lut_ex(canvas_u(hw->canvas_spec[i]), + canvas_config_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); + 0); } } else { r = vavs_canvas_init(hw); @@ -1694,7 +1695,6 @@ #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); #endif - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); #ifdef PIC_DC_NEED_CLEAR CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); @@ -1938,10 +1938,9 @@ #ifdef DEBUG_MULTI_WITH_AUTOMODE int delay_count = 0; #endif -static void vavs_put_timer_func(struct timer_list *arg) +static void vavs_put_timer_func(unsigned long arg) { - struct vdec_avs_hw_s *hw = container_of(arg, - struct vdec_avs_hw_s, recycle_timer); + struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; struct timer_list *timer = &hw->recycle_timer; #ifndef HANDLE_AVS_IRQ @@ -2216,10 +2215,9 @@ hw->fw = fw; 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; + 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; @@ -2289,9 +2287,8 @@ hw->stat |= STAT_VF_HOOK; - timer_setup(&hw->recycle_timer, vavs_put_timer_func, 0); - //hw->recycle_timer.data = (ulong)(hw); - //hw->recycle_timer.function = vavs_put_timer_func; + hw->recycle_timer.data = (ulong)(hw); + hw->recycle_timer.function = vavs_put_timer_func; hw->recycle_timer.expires = jiffies + PUT_INTERVAL; add_timer(&hw->recycle_timer); @@ -2513,7 +2510,7 @@ } /****************************************/ -#if 0 +#ifdef DEBUG_WITH_SINGLE_MODE static struct platform_driver amvdec_avs_driver = { .probe = amvdec_avs_probe, .remove = amvdec_avs_remove, @@ -2522,7 +2519,6 @@ } }; #endif - static void recycle_frames(struct vdec_avs_hw_s *hw); static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) @@ -2531,6 +2527,7 @@ (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]) @@ -2852,10 +2849,9 @@ } -static void check_timer_func(struct timer_list *timer) +static void check_timer_func(unsigned long arg) { - struct vdec_avs_hw_s *hw = container_of(timer, - struct vdec_avs_hw_s, check_timer); + struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); unsigned int timeout_val = decode_timeout_val; unsigned long flags; @@ -3195,8 +3191,8 @@ "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n", __func__, READ_VREG(AVS_BUFFERIN), kfifo_len(&hw->recycle_q)); - WRITE_VREG(VIFF_BIT_CNT, size * 8); + if (hw->reset_decode_flag) WRITE_VREG(DECODE_STATUS, 0); else { @@ -3839,6 +3835,7 @@ #endif } + static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq) { @@ -4378,21 +4375,21 @@ vavs_restore_regs(hw); for (i = 0; i < hw->vf_buf_num_used; i++) { - config_cav_lut_ex(canvas_y(hw->canvas_spec[i]), + canvas_config_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); + 0); - config_cav_lut_ex(canvas_u(hw->canvas_spec[i]), + canvas_config_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); + 0); } } } @@ -4452,8 +4449,6 @@ #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); #endif - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - if (start_decoding_delay & 0x20000) msleep(start_decoding_delay&0xffff); @@ -4867,8 +4862,6 @@ pr_info("failed to register amvdec_avs driver\n"); return -ENODEV; } -#else - //amvdec_avs_driver = amvdec_avs_driver; #endif if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) ammvdec_avs_profile.profile = "mavs+"; @@ -4876,7 +4869,6 @@ vcodec_profile_register(&ammvdec_avs_profile); INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node, "mavs", mavs_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_AVS, 0); return 0; } @@ -4989,6 +4981,7 @@ module_param(udebug_pause_ins_id, uint, 0664); MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n"); + module_param(start_decoding_delay, uint, 0664); MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n");
diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c index 55f0581..03a1dba 100644 --- a/drivers/frame_provider/decoder/h264/vh264.c +++ b/drivers/frame_provider/decoder/h264/vh264.c
@@ -23,6 +23,7 @@ #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> @@ -37,6 +38,7 @@ #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" @@ -44,17 +46,19 @@ #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/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 <linux/amlogic/tee.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" @@ -156,7 +160,7 @@ static void vh264_prot_init(void); static int vh264_local_init(void); -static void vh264_put_timer_func(struct timer_list *timer); +static void vh264_put_timer_func(unsigned long arg); static void stream_switching_done(void); static const char vh264_dec_id[] = "vh264-dev"; @@ -249,6 +253,14 @@ #endif static u32 enable_userdata_debug; +/* if not define, must clear AV_SCRATCH_J in isr when + * ITU_T35 code enabled in ucode, otherwise may fatal + * error repeatly. + */ +//#define ENABLE_SEI_ITU_T35 + + + static unsigned int enable_switch_fense = 1; #define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k) static struct vframe_qos_s s_vframe_qos; @@ -460,15 +472,15 @@ int endian; endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0; - config_cav_lut_ex(spec->y_canvas_index, + canvas_config_ex(spec->y_canvas_index, spec->y_addr, width, height, - CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1); + CANVAS_ADDR_NOWRAP, canvas_mode, endian); - config_cav_lut_ex(spec->u_canvas_index, + canvas_config_ex(spec->u_canvas_index, spec->u_addr, width, height / 2, - CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1); + CANVAS_ADDR_NOWRAP, canvas_mode, endian); } @@ -2196,16 +2208,16 @@ buffer_spec[i].v_canvas_height = mb_height << 4; endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0; - config_cav_lut_ex(128 + i * 2, + canvas_config_ex(128 + i * 2, buffer_spec[i].y_addr, mb_width << 4, mb_height << 4, CANVAS_ADDR_NOWRAP, - canvas_mode, endian, VDEC_1); - config_cav_lut_ex(128 + i * 2 + 1, + canvas_mode, endian); + canvas_config_ex(128 + i * 2 + 1, buffer_spec[i].u_addr, mb_width << 4, mb_height << 3, CANVAS_ADDR_NOWRAP, - canvas_mode, endian, VDEC_1); + canvas_mode, endian); WRITE_VREG(ANC0_CANVAS_ADDR + i, spec2canvas(&buffer_spec[i])); } else { @@ -2587,6 +2599,7 @@ gvs->ratio_control = ratio_control; } + #ifdef HANDLE_H264_IRQ static irqreturn_t vh264_isr(int irq, void *dev_id) #else @@ -3335,8 +3348,9 @@ frame_width, frame_height, fps); } -static void vh264_put_timer_func(struct timer_list *timer) +static void vh264_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; unsigned int wait_buffer_status; unsigned int wait_i_pass_frames; unsigned int reg_val; @@ -3786,7 +3800,7 @@ int firmwareloaded = 0; /* pr_info("\nvh264_init\n"); */ - timer_setup(&recycle_timer, vh264_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -3978,7 +3992,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong) &recycle_timer; + recycle_timer.function = vh264_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -4207,17 +4224,17 @@ canvas_read(y_index, &csy); canvas_read(u_index, &csu); - config_cav_lut_ex(fense_buffer_spec[i].y_canvas_index, + canvas_config(fense_buffer_spec[i].y_canvas_index, fense_buffer_spec[i].phy_addr, mb_width_num << 4, mb_height_num << 4, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex(fense_buffer_spec[i].u_canvas_index, + CANVAS_BLKMODE_LINEAR); + canvas_config(fense_buffer_spec[i].u_canvas_index, fense_buffer_spec[i].phy_addr + (mb_total_num << 8), mb_width_num << 4, mb_height_num << 3, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); + CANVAS_BLKMODE_LINEAR); y_desindex = fense_buffer_spec[i].y_canvas_index; u_desindex = fense_buffer_spec[i].u_canvas_index; @@ -4334,6 +4351,8 @@ INIT_WORK(&userdata_push_work, userdata_push_do_work); INIT_WORK(&qos_work, qos_do_work); + + atomic_set(&vh264_active, 1); mutex_unlock(&vh264_mutex); @@ -4376,16 +4395,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int h264_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int h264_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops h264_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(h264_suspend, h264_resume) +}; +#endif static struct platform_driver amvdec_h264_driver = { .probe = amvdec_h264_probe, .remove = amvdec_h264_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &h264_pm_ops, +#endif } }; @@ -4425,8 +4460,7 @@ return -ENODEV; } if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB - && (codec_mm_get_total_size() > 80 * SZ_1M) && - get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D) { + && (codec_mm_get_total_size() > 80 * SZ_1M)) { amvdec_h264_profile.profile = "4k"; } vcodec_profile_register(&amvdec_h264_profile); @@ -4456,7 +4490,7 @@ MODULE_PARM_DESC(dec_control, "\n amvdec_h264 decoder control\n"); module_param(frame_count, uint, 0664); MODULE_PARM_DESC(frame_count, - "\n amvdec_h264 decoded total count\n"); + "\n amvdec_h264 decoded total count\n"); module_param(fatal_error_reset, uint, 0664); MODULE_PARM_DESC(fatal_error_reset, "\n amvdec_h264 decoder reset when fatal error happens\n");
diff --git a/drivers/frame_provider/decoder/h264/vh264_4k2k.c b/drivers/frame_provider/decoder/h264/vh264_4k2k.c new file mode 100644 index 0000000..44465ad --- /dev/null +++ b/drivers/frame_provider/decoder/h264/vh264_4k2k.c
@@ -0,0 +1,1808 @@ +/* + * drivers/amlogic/amports/vh264_4k2k.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/timer.h> +#include <linux/kfifo.h> +#include <linux/platform_device.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.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/delay.h> + +#include <linux/amlogic/media/codec_mm/codec_mm.h> +#include <linux/amlogic/media/video_sink/video_keeper.h> +#include "../utils/firmware.h" +#include <linux/amlogic/tee.h> +#include "../../../common/chips/decoder_cpu_ver_info.h" + + + +#define MEM_NAME "codec_264_4k" + +/* #include <mach/am_regs.h> */ +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + +#include <linux/amlogic/media/vpu/vpu.h> +#endif + +#include <linux/amlogic/media/utils/vdec_reg.h> +#include "../../../stream_input/amports/amports_priv.h" +#include "../utils/vdec.h" +#include "../utils/amvdec.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> + + + +#if 0 /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6TVD */ +#define DOUBLE_WRITE +#endif + +#define DRIVER_NAME "amvdec_h264_4k2k" +#define MODULE_NAME "amvdec_h264_4k2k" + +#define PUT_INTERVAL (HZ/100) +#define ERROR_RESET_COUNT 500 +#define DECODE_BUFFER_NUM_MAX 32 +#define DISPLAY_BUFFER_NUM 6 +#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + DISPLAY_BUFFER_NUM) +#define VF_BUFFER_IDX(n) (2 + n) +#define DECODER_WORK_SPACE_SIZE 0x800000 + +#if 1 /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV */ +#define H264_4K2K_SINGLE_CORE 1 +#else +#define H264_4K2K_SINGLE_CORE IS_MESON_M8M2_CPU +#endif + +#define SLICE_TYPE_I 2 + +static int vh264_4k2k_vf_states(struct vframe_states *states, void *); +static struct vframe_s *vh264_4k2k_vf_peek(void *); +static struct vframe_s *vh264_4k2k_vf_get(void *); +static void vh264_4k2k_vf_put(struct vframe_s *, void *); +static int vh264_4k2k_event_cb(int type, void *data, void *private_data); + +static void vh264_4k2k_prot_init(void); +static int vh264_4k2k_local_init(void); +static void vh264_4k2k_put_timer_func(unsigned long arg); + +static const char vh264_4k2k_dec_id[] = "vh264_4k2k-dev"; +static const char vh264_4k2k_dec_id2[] = "vh264_4k2k-vdec2-dev"; + +#define PROVIDER_NAME "decoder.h264_4k2k" + +static const struct vframe_operations_s vh264_4k2k_vf_provider = { + .peek = vh264_4k2k_vf_peek, + .get = vh264_4k2k_vf_get, + .put = vh264_4k2k_vf_put, + .event_cb = vh264_4k2k_event_cb, + .vf_states = vh264_4k2k_vf_states, +}; +static void *mm_blk_handle; +static struct vframe_provider_s vh264_4k2k_vf_prov; + +static u32 mb_width_old, mb_height_old; +static u32 frame_width, frame_height, frame_dur, frame_ar; +static u32 saved_resolution; +static struct timer_list recycle_timer; +static u32 stat; +static u32 error_watchdog_count; +static uint error_recovery_mode; +static u32 sync_outside; +static u32 vh264_4k2k_rotation; +static u32 first_i_received; +static struct vframe_s *p_last_vf; +static struct work_struct set_clk_work; + +#ifdef DEBUG_PTS +static unsigned long pts_missed, pts_hit; +#endif + +static struct dec_sysinfo vh264_4k2k_amstream_dec_info; +static dma_addr_t mc_dma_handle; +static void *mc_cpu_addr; + +#define AMVDEC_H264_4K2K_CANVAS_INDEX 0x80 +#define AMVDEC_H264_4K2K_CANVAS_MAX 0xc6 +static DEFINE_SPINLOCK(lock); +static int fatal_error; + +static atomic_t vh264_4k2k_active = ATOMIC_INIT(0); + +static DEFINE_MUTEX(vh264_4k2k_mutex); + +static void (*probe_callback)(void); +static void (*remove_callback)(void); +static struct device *cma_dev; + +/* bit[3:0] command : */ +/* 0 - command finished */ +/* (DATA0 - {level_idc_mmco, max_reference_frame_num, width, height} */ +/* 1 - alloc view_0 display_buffer and reference_data_area */ +/* 2 - alloc view_1 display_buffer and reference_data_area */ +#define MAILBOX_COMMAND AV_SCRATCH_0 +#define MAILBOX_DATA_0 AV_SCRATCH_1 +#define MAILBOX_DATA_1 AV_SCRATCH_2 +#define MAILBOX_DATA_2 AV_SCRATCH_3 +#define MAILBOX_DATA_3 AV_SCRATCH_4 +#define MAILBOX_DATA_4 AV_SCRATCH_5 +#define CANVAS_START AV_SCRATCH_6 +#define BUFFER_RECYCLE AV_SCRATCH_7 +#define PICTURE_COUNT AV_SCRATCH_9 +#define DECODE_STATUS AV_SCRATCH_A +#define SPS_STATUS AV_SCRATCH_B +#define PPS_STATUS AV_SCRATCH_C +#define MS_ID AV_SCRATCH_D +#define WORKSPACE_START AV_SCRATCH_E +#define DECODED_PIC_NUM AV_SCRATCH_F +#define DECODE_ERROR_CNT AV_SCRATCH_G +#define CURRENT_UCODE AV_SCRATCH_H +/* bit[15:9]-SPS, bit[8:0]-PPS */ +#define CURRENT_SPS_PPS AV_SCRATCH_I +#define DECODE_SKIP_PICTURE AV_SCRATCH_J +#define DECODE_MODE AV_SCRATCH_K +#define RESERVED_REG_L AV_SCRATCH_L +#define REF_START_VIEW_0 AV_SCRATCH_M +#define REF_START_VIEW_1 AV_SCRATCH_N + +#define VDEC2_MAILBOX_COMMAND VDEC2_AV_SCRATCH_0 +#define VDEC2_MAILBOX_DATA_0 VDEC2_AV_SCRATCH_1 +#define VDEC2_MAILBOX_DATA_1 VDEC2_AV_SCRATCH_2 +#define VDEC2_MAILBOX_DATA_2 VDEC2_AV_SCRATCH_3 +#define VDEC2_MAILBOX_DATA_3 VDEC2_AV_SCRATCH_4 +#define VDEC2_MAILBOX_DATA_4 VDEC2_AV_SCRATCH_5 +#define VDEC2_CANVAS_START VDEC2_AV_SCRATCH_6 +#define VDEC2_BUFFER_RECYCLE VDEC2_AV_SCRATCH_7 +#define VDEC2_PICTURE_COUNT VDEC2_AV_SCRATCH_9 +#define VDEC2_DECODE_STATUS VDEC2_AV_SCRATCH_A +#define VDEC2_SPS_STATUS VDEC2_AV_SCRATCH_B +#define VDEC2_PPS_STATUS VDEC2_AV_SCRATCH_C +#define VDEC2_MS_ID VDEC2_AV_SCRATCH_D +#define VDEC2_WORKSPACE_START VDEC2_AV_SCRATCH_E +#define VDEC2_DECODED_PIC_NUM VDEC2_AV_SCRATCH_F +#define VDEC2_DECODE_ERROR_CNT VDEC2_AV_SCRATCH_G +#define VDEC2_CURRENT_UCODE VDEC2_AV_SCRATCH_H +/* bit[15:9]-SPS, bit[8:0]-PPS */ +#define VDEC2_CURRENT_SPS_PPS VDEC2_AV_SCRATCH_I +#define VDEC2_DECODE_SKIP_PICTURE VDEC2_AV_SCRATCH_J +#define VDEC2_RESERVED_REG_K VDEC2_AV_SCRATCH_K +#define VDEC2_RESERVED_REG_L VDEC2_AV_SCRATCH_L +#define VDEC2_REF_START_VIEW_0 VDEC2_AV_SCRATCH_M +#define VDEC2_REF_START_VIEW_1 VDEC2_AV_SCRATCH_N + +/******************************************** + * DECODE_STATUS Define + ******************************************* + */ +#define DECODE_IDLE 0 +#define DECODE_START_HEADER 1 +#define DECODE_HEADER 2 +#define DECODE_START_MMCO 3 +#define DECODE_MMCO 4 +#define DECODE_START_SLICE 5 +#define DECODE_SLICE 6 +#define DECODE_WAIT_BUFFER 7 + +/******************************************** + * Dual Core Communication + ******************************************** + */ +#define FATAL_ERROR DOS_SCRATCH16 +#define PRE_MASTER_UPDATE_TIMES DOS_SCRATCH20 +/* bit[31] - REQUEST */ +/* bit[30:0] - MASTER_UPDATE_TIMES */ +#define SLAVE_WAIT_DPB_UPDATE DOS_SCRATCH21 +/* [15:8] - current_ref, [7:0] current_dpb (0x80 means no buffer found) */ +#define SLAVE_REF_DPB DOS_SCRATCH22 +#define SAVE_MVC_ENTENSION_0 DOS_SCRATCH23 +#define SAVE_I_POC DOS_SCRATCH24 +/* bit[31:30] - core_status 0-idle, 1-mmco, 2-decoding, 3-finished */ +/* bit[29:0] - core_pic_count */ +#define CORE_STATUS_M DOS_SCRATCH25 +#define CORE_STATUS_S DOS_SCRATCH26 +#define SAVE_ref_status_view_0 DOS_SCRATCH27 +#define SAVE_ref_status_view_1 DOS_SCRATCH28 +#define ALLOC_INFO_0 DOS_SCRATCH29 +#define ALLOC_INFO_1 DOS_SCRATCH30 + +/******************************************** + * Mailbox command + ********************************************/ +#define CMD_FINISHED 0 +#define CMD_ALLOC_VIEW 1 +#define CMD_FRAME_DISPLAY 3 +#define CMD_DEBUG 10 + +#define MC_TOTAL_SIZE (28*SZ_1K) +#define MC_SWAP_SIZE (4*SZ_1K) + +static unsigned long work_space_adr, ref_start_addr; +static unsigned long reserved_buffer; + + +#define video_domain_addr(adr) (adr&0x7fffffff) + + +struct buffer_spec_s { + unsigned int y_addr; + unsigned int uv_addr; +#ifdef DOUBLE_WRITE + unsigned int y_dw_addr; + unsigned int uv_dw_addr; +#endif + + int y_canvas_index; + int uv_canvas_index; +#ifdef DOUBLE_WRITE + int y_dw_canvas_index; + int uv_dw_canvas_index; +#endif + + struct page *alloc_pages; + unsigned long phy_addr; + int alloc_count; +}; + +static struct buffer_spec_s buffer_spec[MAX_BMMU_BUFFER_NUM]; + +#ifdef DOUBLE_WRITE +#define spec2canvas(x) \ + (((x)->uv_dw_canvas_index << 16) | \ + ((x)->uv_dw_canvas_index << 8) | \ + ((x)->y_dw_canvas_index << 0)) +#else +#define spec2canvas(x) \ + (((x)->uv_canvas_index << 16) | \ + ((x)->uv_canvas_index << 8) | \ + ((x)->y_canvas_index << 0)) +#endif + +#define VF_POOL_SIZE 32 + +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 s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; +static struct vframe_s vfpool[VF_POOL_SIZE]; + +static struct work_struct alloc_work; +static struct vdec_info *gvs; + +static void set_frame_info(struct vframe_s *vf) +{ + unsigned int ar; + +#ifdef DOUBLE_WRITE + vf->width = frame_width / 2; + vf->height = frame_height / 2; +#else + vf->width = frame_width; + vf->height = frame_height; +#endif + vf->duration = frame_dur; + vf->duration_pulldown = 0; + vf->flag = 0; + + ar = min_t(u32, frame_ar, DISP_RATIO_ASPECT_RATIO_MAX); + vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); + vf->orientation = vh264_4k2k_rotation; + +} + +static int vh264_4k2k_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; +} + +static struct vframe_s *vh264_4k2k_vf_peek(void *op_arg) +{ + struct vframe_s *vf; + + if (kfifo_peek(&display_q, &vf)) + return vf; + + return NULL; +} + +static struct vframe_s *vh264_4k2k_vf_get(void *op_arg) +{ + struct vframe_s *vf; + + if (kfifo_get(&display_q, &vf)) + return vf; + + return NULL; +} + +static void vh264_4k2k_vf_put(struct vframe_s *vf, void *op_arg) +{ + kfifo_put(&recycle_q, (const struct vframe_s *)vf); +} + +static int vh264_4k2k_event_cb(int type, void *data, void *private_data) +{ + if (type & VFRAME_EVENT_RECEIVER_RESET) { + unsigned long flags; + + amvdec_stop(); + + if (!H264_4K2K_SINGLE_CORE) + amvdec2_stop(); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_light_unreg_provider(&vh264_4k2k_vf_prov); +#endif + spin_lock_irqsave(&lock, flags); + vh264_4k2k_local_init(); + vh264_4k2k_prot_init(); + spin_unlock_irqrestore(&lock, flags); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_reg_provider(&vh264_4k2k_vf_prov); +#endif + amvdec_start(); + + if (!H264_4K2K_SINGLE_CORE) + amvdec2_start(); + } + + return 0; +} + +static int init_canvas(int refbuf_size, long dpb_size, int dpb_number, + int mb_width, int mb_height, + struct buffer_spec_s *buffer_spec) +{ + unsigned long addr; + int i, j, ret = -1; + int mb_total; + int canvas_addr = ANC0_CANVAS_ADDR; + int vdec2_canvas_addr = VDEC2_ANC0_CANVAS_ADDR; + int index = AMVDEC_H264_4K2K_CANVAS_INDEX; + + mb_total = mb_width * mb_height; + mutex_lock(&vh264_4k2k_mutex); + + for (j = 0; j < (dpb_number + 1); j++) { + int page_count; + if (j == 0) { + ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, 1, + refbuf_size, DRIVER_NAME, &ref_start_addr); + if (ret < 0) { + mutex_unlock(&vh264_4k2k_mutex); + return ret; + } + continue; + } + + WRITE_VREG(canvas_addr++, index | ((index + 1) << 8) | + ((index + 1) << 16)); + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(vdec2_canvas_addr++, + index | ((index + 1) << 8) | + ((index + 1) << 16)); + } + + i = j - 1; +#ifdef DOUBLE_WRITE + page_count = + PAGE_ALIGN((mb_total << 8) + (mb_total << 7) + + (mb_total << 6) + (mb_total << 5)) / PAGE_SIZE; +#else + page_count = + PAGE_ALIGN((mb_total << 8) + (mb_total << 7)) / PAGE_SIZE; +#endif + + ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, + VF_BUFFER_IDX(i), page_count << PAGE_SHIFT, + DRIVER_NAME, &buffer_spec[i].phy_addr); + + if (ret < 0) { + buffer_spec[i].alloc_count = 0; + mutex_unlock(&vh264_4k2k_mutex); + return ret; + } + addr = buffer_spec[i].phy_addr; + buffer_spec[i].alloc_count = page_count; + buffer_spec[i].y_addr = addr; + buffer_spec[i].y_canvas_index = index; + canvas_config(index, + addr, + mb_width << 4, + mb_height << 4, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + + addr += mb_total << 8; + index++; + + buffer_spec[i].uv_addr = addr; + buffer_spec[i].uv_canvas_index = index; + canvas_config(index, + addr, + mb_width << 4, + mb_height << 3, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + + addr += mb_total << 7; + index++; + +#ifdef DOUBLE_WRITE + buffer_spec[i].y_dw_addr = addr; + buffer_spec[i].y_dw_canvas_index = index; + canvas_config(index, + addr, + mb_width << 3, + mb_height << 3, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + + addr += mb_total << 6; + index++; + + buffer_spec[i].uv_dw_addr = addr; + buffer_spec[i].uv_dw_canvas_index = index; + canvas_config(index, + addr, + mb_width << 3, + mb_height << 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + + index++; +#endif + } + + mutex_unlock(&vh264_4k2k_mutex); + + pr_info + ("H264 4k2k decoder canvas allocation successful, "); + + return 0; +} + +static int get_max_dec_frame_buf_size(int level_idc, + int max_reference_frame_num, int mb_width, + int mb_height) +{ + int pic_size = mb_width * mb_height * 384; + + int size = 0; + + switch (level_idc) { + case 9: + size = 152064; + break; + case 10: + size = 152064; + break; + case 11: + size = 345600; + break; + case 12: + size = 912384; + break; + case 13: + size = 912384; + break; + case 20: + size = 912384; + break; + case 21: + size = 1824768; + break; + case 22: + size = 3110400; + break; + case 30: + size = 3110400; + break; + case 31: + size = 6912000; + break; + case 32: + size = 7864320; + break; + case 40: + size = 12582912; + break; + case 41: + size = 12582912; + break; + case 42: + size = 13369344; + break; + case 50: + size = 42393600; + break; + case 51: + case 52: + default: + size = 70778880; + break; + } + + size /= pic_size; + size = size + 1; /* need one more buffer */ + + if (max_reference_frame_num > size) + size = max_reference_frame_num; + + if (size > DECODE_BUFFER_NUM_MAX) + size = DECODE_BUFFER_NUM_MAX; + + return size; +} + +static void do_alloc_work(struct work_struct *work) +{ + int level_idc, max_reference_frame_num, mb_width, mb_height, + frame_mbs_only_flag; + int dpb_size, ref_size, refbuf_size; + int max_dec_frame_buffering, + total_dec_frame_buffering; + unsigned int chroma444; + unsigned int crop_infor, crop_bottom, crop_right; + int ret = READ_VREG(MAILBOX_COMMAND); + + + ret = READ_VREG(MAILBOX_DATA_0); + /* MAILBOX_DATA_1 : + * bit15 : frame_mbs_only_flag + * bit 0-7 : chroma_format_idc + * MAILBOX_DATA_2: + * bit31-16: (left << 8 | right ) << 1 + * bit15-0 : (top << 8 | bottom ) << (2 - frame_mbs_only_flag) + */ + frame_mbs_only_flag = READ_VREG(MAILBOX_DATA_1); + crop_infor = READ_VREG(MAILBOX_DATA_2); + level_idc = (ret >> 24) & 0xff; + max_reference_frame_num = (ret >> 16) & 0xff; + mb_width = (ret >> 8) & 0xff; + if (mb_width == 0) + mb_width = 256; + mb_height = (ret >> 0) & 0xff; + max_dec_frame_buffering = + get_max_dec_frame_buf_size(level_idc, max_reference_frame_num, + mb_width, mb_height); + total_dec_frame_buffering = + max_dec_frame_buffering + DISPLAY_BUFFER_NUM; + + chroma444 = ((frame_mbs_only_flag&0xffff) == 3) ? 1 : 0; + frame_mbs_only_flag = (frame_mbs_only_flag >> 16) & 0x01; + crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag); + crop_right = ((crop_infor >> 16) & 0xff) >> 1; + pr_info("crop_right = 0x%x crop_bottom = 0x%x chroma_format_idc = 0x%x\n", + crop_right, crop_bottom, chroma444); + + if ((frame_width == 0) || (frame_height == 0) || crop_infor || + mb_width != mb_width_old || + mb_height != mb_height_old) { + frame_width = mb_width << 4; + frame_height = mb_height << 4; + mb_width_old = mb_width; + mb_height_old = mb_height; + if (frame_mbs_only_flag) { + frame_height -= (2 >> chroma444) * + min(crop_bottom, + (unsigned int)((8 << chroma444) - 1)); + frame_width -= (2 >> chroma444) * + min(crop_right, + (unsigned int)((8 << chroma444) - 1)); + } else { + frame_height -= (4 >> chroma444) * + min(crop_bottom, + (unsigned int)((8 << chroma444) - 1)); + frame_width -= (4 >> chroma444) * + min(crop_right, + (unsigned int)((8 << chroma444) - 1)); + } + pr_info("frame_mbs_only_flag %d, crop_bottom %d frame_height %d, mb_height %d crop_right %d, frame_width %d, mb_width %d\n", + frame_mbs_only_flag, crop_bottom, frame_height, + mb_height, crop_right, frame_width, mb_height); + } + + mb_width = (mb_width + 3) & 0xfffffffc; + mb_height = (mb_height + 3) & 0xfffffffc; + + dpb_size = mb_width * mb_height * 384; + ref_size = mb_width * mb_height * 96; + refbuf_size = ref_size * (max_reference_frame_num + 1) * 2; + + + pr_info("mb_width=%d, mb_height=%d\n", + mb_width, mb_height); + + ret = init_canvas(refbuf_size, dpb_size, + total_dec_frame_buffering, mb_width, mb_height, + buffer_spec); + + if (ret == -1) { + pr_info(" Un-expected memory alloc problem\n"); + return; + } + + if (frame_width == 0) + frame_width = mb_width << 4; + if (frame_height == 0) + frame_height = mb_height << 4; + + WRITE_VREG(REF_START_VIEW_0, video_domain_addr(ref_start_addr)); + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(VDEC2_REF_START_VIEW_0, + video_domain_addr(ref_start_addr)); + } + + WRITE_VREG(MAILBOX_DATA_0, + (max_dec_frame_buffering << 8) | + (total_dec_frame_buffering << 0)); + WRITE_VREG(MAILBOX_DATA_1, ref_size); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + + /* ///////////// FAKE FIRST PIC */ + +} + +static irqreturn_t vh264_4k2k_isr(int irq, void *dev_id) +{ + int drop_status, display_buff_id, display_POC, slice_type, error; + unsigned int stream_offset; + struct vframe_s *vf = NULL; + int ret = READ_VREG(MAILBOX_COMMAND); + u32 frame_size; + + switch (ret & 0xff) { + case CMD_ALLOC_VIEW: + schedule_work(&alloc_work); + break; + + case CMD_FRAME_DISPLAY: + ret >>= 8; + display_buff_id = (ret >> 0) & 0x3f; + drop_status = (ret >> 8) & 0x1; + slice_type = (ret >> 9) & 0x7; + error = (ret >> 12) & 0x1; + display_POC = READ_VREG(MAILBOX_DATA_0); + stream_offset = READ_VREG(MAILBOX_DATA_1); + + smp_rmb();/* rmb smp */ + + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + + if (kfifo_get(&newframe_q, &vf) == 0) { + pr_info("fatal error, no available buffer slot."); + return IRQ_HANDLED; + } + + if (vf) { + vfbuf_use[display_buff_id]++; + + vf->pts = 0; + vf->pts_us64 = 0; + + if ((!sync_outside) + || (sync_outside && + (slice_type == SLICE_TYPE_I))) { + ret = pts_lookup_offset_us64(PTS_TYPE_VIDEO, + stream_offset, + &vf->pts, + &frame_size, + 0, + &vf->pts_us64); + if (ret != 0) + pr_debug(" vpts lookup failed\n"); + } +#ifdef H264_4K2K_SINGLE_CORE + if (READ_VREG(DECODE_MODE) & 1) { + /* for I only mode, ignore the PTS information + * and only uses 10fps for each + * I frame decoded + */ + if (p_last_vf) { + vf->pts = 0; + vf->pts_us64 = 0; + } + frame_dur = 96000 / 10; + } +#endif + vf->signal_type = 0; + vf->index = display_buff_id; + vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; + vf->type |= VIDTYPE_VIU_NV21; + vf->canvas0Addr = vf->canvas1Addr = + spec2canvas(&buffer_spec[display_buff_id]); + set_frame_info(vf); + + if (error) + gvs->drop_frame_count++; + + gvs->frame_dur = frame_dur; + vdec_count_info(gvs, error, stream_offset); + + if (((error_recovery_mode & 2) && error) + || (!first_i_received + && (slice_type != SLICE_TYPE_I))) { + kfifo_put(&recycle_q, + (const struct vframe_s *)vf); + } else { + p_last_vf = vf; + first_i_received = 1; + vf->mem_handle = + decoder_bmmu_box_get_mem_handle( + mm_blk_handle, + VF_BUFFER_IDX(display_buff_id)); + 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); + } + } + break; + + case CMD_DEBUG: + pr_info("M: core_status 0x%08x 0x%08x; ", + READ_VREG(CORE_STATUS_M), READ_VREG(CORE_STATUS_S)); + switch (READ_VREG(MAILBOX_DATA_0)) { + case 1: + pr_info("H264_BUFFER_INFO_INDEX = 0x%x\n", + READ_VREG(MAILBOX_DATA_1)); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 2: + pr_info("H264_BUFFER_INFO_DATA = 0x%x\n", + READ_VREG(MAILBOX_DATA_1)); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 3: + pr_info("REC_CANVAS_ADDR = 0x%x\n", + READ_VREG(MAILBOX_DATA_1)); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 4: + pr_info("after DPB_MMCO\n"); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 5: + pr_info("MBY = 0x%x, S_MBXY = 0x%x\n", + READ_VREG(MAILBOX_DATA_1), + READ_VREG(0x2c07)); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 6: + pr_info("after FIFO_OUT_FRAME\n"); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 7: + pr_info("after RELEASE_EXCEED_REF_BUFF\n"); + WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); + break; + case 0x5a: + pr_info("\n"); + break; + default: + pr_info("\n"); + break; + } + break; + + default: + break; + } + + return IRQ_HANDLED; +} + +#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ +static irqreturn_t vh264_4k2k_vdec2_isr(int irq, void *dev_id) +{ + int ret = READ_VREG(VDEC2_MAILBOX_COMMAND); + + switch (ret & 0xff) { + case CMD_DEBUG: + pr_info("S: core_status 0x%08x 0x%08x; ", + READ_VREG(CORE_STATUS_M), READ_VREG(CORE_STATUS_S)); + switch (READ_VREG(VDEC2_MAILBOX_DATA_0)) { + case 1: + pr_info("H264_BUFFER_INFO_INDEX = 0x%x\n", + READ_VREG(VDEC2_MAILBOX_DATA_1)); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 2: + pr_info("H264_BUFFER_INFO_DATA = 0x%x\n", + READ_VREG(VDEC2_MAILBOX_DATA_1)); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 3: + pr_info("REC_CANVAS_ADDR = 0x%x\n", + READ_VREG(VDEC2_MAILBOX_DATA_1)); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 4: + pr_info("after DPB_MMCO\n"); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 5: + pr_info("MBY = 0x%x, M/S_MBXY = 0x%x-0x%x\n", + READ_VREG(VDEC2_MAILBOX_DATA_1), + READ_VREG(0xc07), READ_VREG(0x2c07)); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 6: + pr_info("after FIFO_OUT_FRAME\n"); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 7: + pr_info("after RELEASE_EXCEED_REF_BUFF\n"); + WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED); + break; + case 0x5a: + pr_info("\n"); + break; + default: + pr_info("\n"); + break; + } + break; + + default: + break; + } + + return IRQ_HANDLED; +} +#endif + +static void vh264_4k2k_set_clk(struct work_struct *work) +{ + if (first_i_received &&/*do switch after first i frame ready.*/ + frame_dur > 0 && saved_resolution != + frame_width * frame_height * (96000 / frame_dur)) { + int fps = 96000 / frame_dur; + + pr_info("H264 4k2k resolution changed!!\n"); + if (vdec_source_changed(VFORMAT_H264_4K2K, + frame_width, frame_height, fps) > 0)/*changed clk ok*/ + saved_resolution = frame_width * frame_height * fps; + } +} + +static void vh264_4k2k_put_timer_func(unsigned long arg) +{ + struct timer_list *timer = (struct timer_list *)arg; + enum receviver_start_e state = RECEIVER_INACTIVE; + + if (vf_get_receiver(PROVIDER_NAME)) { + state = vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_QUREY_STATE, NULL); + if ((state == RECEIVER_STATE_NULL) + || (state == RECEIVER_STATE_NONE)) + state = RECEIVER_INACTIVE; + } else + state = RECEIVER_INACTIVE; + + /* error watchdog */ + if (((READ_VREG(VLD_MEM_VIFIFO_CONTROL) & 0x100) == 0) &&/* dec has in*/ + (state == RECEIVER_INACTIVE) && /* rec has no buf to recycle */ + (kfifo_is_empty(&display_q)) && /* no buf in display queue */ + (kfifo_is_empty(&recycle_q)) && /* no buf to recycle */ + (READ_VREG(MS_ID) & 0x100) +#ifdef CONFIG_H264_2K4K_SINGLE_CORE + && (READ_VREG(VDEC2_MS_ID) & 0x100) + +/* with both decoder + * have started decoding + */ +#endif + && first_i_received) { + if (++error_watchdog_count == ERROR_RESET_COUNT) { + /* and it lasts for a while */ + pr_info("H264 4k2k decoder fatal error watchdog.\n"); + fatal_error = DECODER_FATAL_ERROR_UNKNOWN; + } + } else + error_watchdog_count = 0; + + if (READ_VREG(FATAL_ERROR) != 0) { + pr_info("H264 4k2k decoder ucode fatal error.\n"); + fatal_error = DECODER_FATAL_ERROR_UNKNOWN; + WRITE_VREG(FATAL_ERROR, 0); + } + + while (!kfifo_is_empty(&recycle_q) && + (READ_VREG(BUFFER_RECYCLE) == 0)) { + struct vframe_s *vf; + + if (kfifo_get(&recycle_q, &vf)) { + if ((vf->index < DECODE_BUFFER_NUM_MAX) + && (--vfbuf_use[vf->index] == 0)) { + WRITE_VREG(BUFFER_RECYCLE, vf->index + 1); + vf->index = DECODE_BUFFER_NUM_MAX; + } + + kfifo_put(&newframe_q, (const struct vframe_s *)vf); + } + } + + schedule_work(&set_clk_work); + + timer->expires = jiffies + PUT_INTERVAL; + + add_timer(timer); +} + +int vh264_4k2k_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) +{ + 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 = 0; + vstatus->status = stat | fatal_error; + 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; +} + +static int vh264_4k2k_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; +} + +int vh264_4k2k_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + if (trickmode == TRICKMODE_I) { + WRITE_VREG(DECODE_MODE, 1); + trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + WRITE_VREG(DECODE_MODE, 0); + trickmode_i = 0; + } + + return 0; +} + +static void H264_DECODE_INIT(void) +{ + int i; + + WRITE_VREG(GCLK_EN, 0x3ff); + + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); + WRITE_VREG(DOS_SW_RESET0, 0); + + READ_VREG(DOS_SW_RESET0); + READ_VREG(DOS_SW_RESET0); + 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); + + READ_VREG(DOS_SW_RESET0); + READ_VREG(DOS_SW_RESET0); + READ_VREG(DOS_SW_RESET0); + + /* fill_weight_pred */ + WRITE_VREG(MC_MPORT_CTRL, 0x0300); + for (i = 0; i < 192; i++) + WRITE_VREG(MC_MPORT_DAT, 0x100); + WRITE_VREG(MC_MPORT_CTRL, 0); + + WRITE_VREG(MB_WIDTH, 0xff); /* invalid mb_width */ + + /* set slice start to 0x000000 or 0x000001 for check more_rbsp_data */ + WRITE_VREG(SLICE_START_BYTE_01, 0x00000000); + WRITE_VREG(SLICE_START_BYTE_23, 0x01010000); + /* set to mpeg2 to enable mismatch logic */ + WRITE_VREG(MPEG1_2_REG, 1); + WRITE_VREG(VLD_ERROR_MASK, + 0x1011); + + /* Config MCPU Amrisc interrupt */ + WRITE_VREG(ASSIST_AMR1_INT0, 0x1); /* viu_vsync_int */ + WRITE_VREG(ASSIST_AMR1_INT1, 0x5); /* mbox_isr */ + WRITE_VREG(ASSIST_AMR1_INT2, 0x8); /* vld_isr */ + /* WRITE_VREG(ASSIST_AMR1_INT3, 0x15); // vififo_empty */ + WRITE_VREG(ASSIST_AMR1_INT4, 0xd); /* rv_ai_mb_finished_int */ + WRITE_VREG(ASSIST_AMR1_INT7, 0x14); /* dcac_dma_done */ + WRITE_VREG(ASSIST_AMR1_INT8, 0x15); /* vififo_empty */ + + /* Config MCPU Amrisc interrupt */ + WRITE_VREG(ASSIST_AMR1_INT5, 0x9); /* MCPU interrupt */ + WRITE_VREG(ASSIST_AMR1_INT6, 0x17); /* CCPU interrupt */ + + WRITE_VREG(CPC_P, 0xc00); /* CCPU Code will start from 0xc00 */ + WRITE_VREG(CINT_VEC_BASE, (0xc20 >> 5)); + WRITE_VREG(POWER_CTL_VLD, (1 << 10) | /* disable cabac_step_2 */ + (1 << 9) | /* viff_drop_flag_en */ + (1 << 6)); /* h264_000003_en */ + WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */ + + WRITE_VREG(CANVAS_START, AMVDEC_H264_4K2K_CANVAS_INDEX); + /* Start Address of Workspace (UCODE, temp_data...) */ + WRITE_VREG(WORKSPACE_START, + video_domain_addr(work_space_adr)); + /* Clear all sequence parameter set available */ + WRITE_VREG(SPS_STATUS, 0); + /* Clear all picture parameter set available */ + WRITE_VREG(PPS_STATUS, 0); + /* Set current microcode to NULL */ + WRITE_VREG(CURRENT_UCODE, 0xff); + /* Set current SPS/PPS to NULL */ + WRITE_VREG(CURRENT_SPS_PPS, 0xffff); + /* Set decode status to DECODE_START_HEADER */ + WRITE_VREG(DECODE_STATUS, 1); +} + +static void H264_DECODE2_INIT(void) +{ + int i; + + WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); + + WRITE_VREG(DOS_SW_RESET2, (1 << 7) | (1 << 6) | (1 << 4)); + WRITE_VREG(DOS_SW_RESET2, 0); + + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + + WRITE_VREG(DOS_SW_RESET2, (1 << 7) | (1 << 6) | (1 << 4)); + WRITE_VREG(DOS_SW_RESET2, 0); + + WRITE_VREG(DOS_SW_RESET2, (1 << 9) | (1 << 8)); + WRITE_VREG(DOS_SW_RESET2, 0); + + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + + /* fill_weight_pred */ + WRITE_VREG(VDEC2_MC_MPORT_CTRL, 0x0300); + for (i = 0; i < 192; i++) + WRITE_VREG(VDEC2_MC_MPORT_DAT, 0x100); + WRITE_VREG(VDEC2_MC_MPORT_CTRL, 0); + + WRITE_VREG(VDEC2_MB_WIDTH, 0xff); /* invalid mb_width */ + + /* set slice start to 0x000000 or 0x000001 for check more_rbsp_data */ + WRITE_VREG(VDEC2_SLICE_START_BYTE_01, 0x00000000); + WRITE_VREG(VDEC2_SLICE_START_BYTE_23, 0x01010000); + /* set to mpeg2 to enable mismatch logic */ + WRITE_VREG(VDEC2_MPEG1_2_REG, 1); + /* disable COEF_GT_64 , error_m4_table and voff_rw_err */ + WRITE_VREG(VDEC2_VLD_ERROR_MASK, + 0x1011); + + /* Config MCPU Amrisc interrupt */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT0, 0x1);/* viu_vsync_int */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT1, 0x5);/* mbox_isr */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT2, 0x8);/* vld_isr */ + /* WRITE_VREG(VDEC2_ASSIST_AMR1_INT3, 0x15); // vififo_empty */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT4, 0xd);/* rv_ai_mb_finished_int */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT7, 0x14);/* dcac_dma_done */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT8, 0x15);/* vififo_empty */ + + /* Config MCPU Amrisc interrupt */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT5, 0x9);/* MCPU interrupt */ + WRITE_VREG(VDEC2_ASSIST_AMR1_INT6, 0x17);/* CCPU interrupt */ + + WRITE_VREG(VDEC2_CPC_P, 0xc00); /* CCPU Code will start from 0xc00 */ + WRITE_VREG(VDEC2_CINT_VEC_BASE, (0xc20 >> 5)); + WRITE_VREG(VDEC2_POWER_CTL_VLD, (1 << 10) |/* disable cabac_step_2 */ + (1 << 9) | /* viff_drop_flag_en */ + (1 << 6)); /* h264_000003_en */ + /* H264_DECODE_INFO - h264_en */ + WRITE_VREG(VDEC2_M4_CONTROL_REG, (1 << 13)); + + WRITE_VREG(VDEC2_CANVAS_START, AMVDEC_H264_4K2K_CANVAS_INDEX); + /* Start Address of Workspace (UCODE, temp_data...) */ + WRITE_VREG(VDEC2_WORKSPACE_START, + video_domain_addr(work_space_adr)); + /* Clear all sequence parameter set available */ + WRITE_VREG(VDEC2_SPS_STATUS, 0); + /* Clear all picture parameter set available */ + WRITE_VREG(VDEC2_PPS_STATUS, 0); + /* Set current microcode to NULL */ + WRITE_VREG(VDEC2_CURRENT_UCODE, 0xff); + /* Set current SPS/PPS to NULL */ + WRITE_VREG(VDEC2_CURRENT_SPS_PPS, 0xffff); + /* Set decode status to DECODE_START_HEADER */ + WRITE_VREG(VDEC2_DECODE_STATUS, 1); +} + +static void vh264_4k2k_prot_init(void) +{ + /* clear mailbox interrupt */ +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_ASSIST_MBOX0_CLR_REG, 1); +#endif + WRITE_VREG(VDEC_ASSIST_MBOX1_CLR_REG, 1); + + /* enable mailbox interrupt */ +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_ASSIST_MBOX0_MASK, 1); +#endif + WRITE_VREG(VDEC_ASSIST_MBOX1_MASK, 1); + + /* disable PSCALE for hardware sharing */ + WRITE_VREG(PSCALE_CTRL, 0); + + H264_DECODE_INIT(); + if (!H264_4K2K_SINGLE_CORE) + H264_DECODE2_INIT(); + + WRITE_VREG(DOS_SW_RESET0, (1 << 11)); + WRITE_VREG(DOS_SW_RESET0, 0); + + READ_VREG(DOS_SW_RESET0); + READ_VREG(DOS_SW_RESET0); + READ_VREG(DOS_SW_RESET0); + + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(DOS_SW_RESET2, (1 << 11)); + WRITE_VREG(DOS_SW_RESET2, 0); + + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + READ_VREG(DOS_SW_RESET2); + } + + WRITE_VREG(MAILBOX_COMMAND, 0); + WRITE_VREG(BUFFER_RECYCLE, 0); + + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(VDEC2_MAILBOX_COMMAND, 0); + WRITE_VREG(VDEC2_BUFFER_RECYCLE, 0); + } + + CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); + if (!H264_4K2K_SINGLE_CORE) + CLEAR_VREG_MASK(VDEC2_MDEC_PIC_DC_CTRL, 1 << 17); + + /* set VDEC Master/ID 0 */ + WRITE_VREG(MS_ID, (1 << 7) | (0 << 0)); + if (!H264_4K2K_SINGLE_CORE) { + /* set VDEC2 Slave/ID 0 */ + WRITE_VREG(VDEC2_MS_ID, (0 << 7) | (1 << 0)); + } + WRITE_VREG(DECODE_SKIP_PICTURE, 0); + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_DECODE_SKIP_PICTURE, 0); + + WRITE_VREG(PRE_MASTER_UPDATE_TIMES, 0); + WRITE_VREG(SLAVE_WAIT_DPB_UPDATE, 0); + WRITE_VREG(SLAVE_REF_DPB, 0); + WRITE_VREG(SAVE_MVC_ENTENSION_0, 0); + WRITE_VREG(SAVE_I_POC, 0); + WRITE_VREG(CORE_STATUS_M, 0); + WRITE_VREG(CORE_STATUS_S, 0); + WRITE_VREG(SAVE_ref_status_view_0, 0); + WRITE_VREG(SAVE_ref_status_view_1, 0); + WRITE_VREG(ALLOC_INFO_0, 0); + WRITE_VREG(ALLOC_INFO_1, 0); + WRITE_VREG(FATAL_ERROR, 0); + + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); + if (!H264_4K2K_SINGLE_CORE) + SET_VREG_MASK(VDEC2_MDEC_PIC_DC_CTRL, 1 << 17); + + WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(VDEC2_MDEC_PIC_DC_THRESH, 0x404038aa); + } +#ifdef DOUBLE_WRITE + WRITE_VREG(MDEC_DOUBLEW_CFG0, (0 << 31) | /* half y address */ + (1 << 30) | /* 0:No Merge 1:Automatic Merge */ + (0 << 28) | + +/* Field Picture, 0x:no skip + * 10:top only + * 11:bottom only + */ + (0 << 27) | /* Source from, 1:MCW 0:DBLK */ + (0 << 24) | /* Endian Control for Chroma */ + (0 << 18) | /* DMA ID */ + (0 << 12) | /* DMA Burst Number */ + (0 << 11) | /* DMA Urgent */ + (0 << 10) | /* 1:Round 0:Truncation */ + (1 << 9) | + +/* Size by vertical, 0:original size + * 1: 1/2 shrunken size + */ + (1 << 8) | + +/* Size by horizontal, 0:original size + * 1: 1/2 shrunken size + */ + (0 << 6) | + +/* Pixel sel by vertical, 0x:1/2 + * 10:up + * 11:down + */ + (0 << 4) | + +/* Pixel sel by horizontal, 0x:1/2 + * 10:left + * 11:right + */ + (0 << 1) | /* Endian Control for Luma */ + (1 << 0)); /* Double Write Enable */ + if (!H264_4K2K_SINGLE_CORE) { + WRITE_VREG(VDEC2_MDEC_DOUBLEW_CFG0, + (0 << 31) | /* half y address */ + (1 << 30) | + +/* 0:No Merge + * 1:Automatic Merge + */ + (0 << 28) | + +/* Field Picture, 0x:no skip + * 10:top only + * 11:bottom only + */ + (0 << 27) | /* Source from, 1:MCW 0:DBLK */ + (0 << 24) | /* Endian Control for Chroma */ + (0 << 18) | /* DMA ID */ + (0 << 12) | /* DMA Burst Number */ + (0 << 11) | /* DMA Urgent */ + (0 << 10) | /* 1:Round 0:Truncation */ + (1 << 9) | + +/* Size by vertical, + * 0:original size + * 1: 1/2 shrunken size + */ + (1 << 8) | + +/* Size by horizontal, + * 0:original size + * 1: 1/2 shrunken size + */ + (0 << 6) | + +/* Pixel sel by vertical, + * 0x:1/2 + * 10:up + * 11:down + */ + (0 << 4) | + +/* Pixel sel by horizontal, + * 0x:1/2 + * 10:left + * 11:right + */ + (0 << 1) | /* Endian Control for Luma */ + (1 << 0)); /* Double Write Enable */ + } +#endif +} + +static int vh264_4k2k_local_init(void) +{ + int i, size, ret; + +#ifdef DEBUG_PTS + pts_missed = 0; + pts_hit = 0; +#endif + mb_width_old = 0; + mb_height_old = 0; + saved_resolution = 0; + vh264_4k2k_rotation = + (((unsigned long) vh264_4k2k_amstream_dec_info.param) >> 16) + & 0xffff; + frame_width = vh264_4k2k_amstream_dec_info.width; + frame_height = vh264_4k2k_amstream_dec_info.height; + frame_dur = + (vh264_4k2k_amstream_dec_info.rate == + 0) ? 3600 : vh264_4k2k_amstream_dec_info.rate; + if (frame_width && frame_height) + frame_ar = frame_height * 0x100 / frame_width; + sync_outside = ((unsigned long) vh264_4k2k_amstream_dec_info.param + & 0x02) >> 1; + error_watchdog_count = 0; + + pr_info("H264_4K2K: decinfo: %dx%d rate=%d\n", + frame_width, frame_height, + frame_dur); + + if (frame_dur == 0) + frame_dur = 96000 / 24; + + INIT_KFIFO(display_q); + INIT_KFIFO(recycle_q); + INIT_KFIFO(newframe_q); + + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + vfbuf_use[i] = 0; + + for (i = 0; i < VF_POOL_SIZE; i++) { + const struct vframe_s *vf = &vfpool[i]; + + vfpool[i].index = DECODE_BUFFER_NUM_MAX; + kfifo_put(&newframe_q, vf); + } + + reserved_buffer = 0; + p_last_vf = NULL; + first_i_received = 0; + INIT_WORK(&alloc_work, do_alloc_work); + + 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); + + size = DECODER_WORK_SPACE_SIZE; + ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, 0, + size, DRIVER_NAME, &work_space_adr); + return ret; +} + +static s32 vh264_4k2k_init(void) +{ + int ret = -1, size = -1; + char *buf = vmalloc(0x1000 * 16); + + if (buf == NULL) + return -ENOMEM; + + pr_info("\nvh264_4k2k_init\n"); + + init_timer(&recycle_timer); + + stat |= STAT_TIMER_INIT; + + ret = vh264_4k2k_local_init(); + if (ret < 0) { + vfree(buf); + return ret; + } + amvdec_enable(); + + /* -- ucode loading (amrisc and swap code) */ + mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL); + if (!mc_cpu_addr) { + amvdec_disable(); + vfree(buf); + pr_err("vh264_4k2k init: Can not allocate mc memory.\n"); + return -ENOMEM; + } + + WRITE_VREG(AV_SCRATCH_L, mc_dma_handle); + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_AV_SCRATCH_L, mc_dma_handle); + + if (H264_4K2K_SINGLE_CORE) + size = get_firmware_data(VIDEO_DEC_H264_4k2K_SINGLE, buf); + else + size = get_firmware_data(VIDEO_DEC_H264_4k2K, buf); + + if (size < 0) { + pr_err("get firmware fail."); + vfree(buf); + return -1; + } + + if (H264_4K2K_SINGLE_CORE) + ret = amvdec_loadmc_ex(VFORMAT_H264_4K2K, "single_core", buf); + else + ret = amvdec_loadmc_ex(VFORMAT_H264_4K2K, NULL, buf); + + if (ret < 0) { + amvdec_disable(); + dma_free_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); + mc_cpu_addr = NULL; + pr_err("H264_4K2K: the %s fw loading failed, err: %x\n", + tee_enabled() ? "TEE" : "local", ret); + return -EBUSY; + } + + if (!H264_4K2K_SINGLE_CORE) { + amvdec2_enable(); + + if (amvdec2_loadmc_ex(VFORMAT_H264_4K2K, NULL, buf) < 0) { + amvdec_disable(); + amvdec2_disable(); + dma_free_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); + mc_cpu_addr = NULL; + return -EBUSY; + } + } + + /*header*/ + memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000); + + /*mmco*/ + memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000); + + /*slice*/ + memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000); + + stat |= STAT_MC_LOAD; + + /* enable AMRISC side protocol */ + vh264_4k2k_prot_init(); + + if (vdec_request_irq(VDEC_IRQ_1, vh264_4k2k_isr, + "vh264_4k2k-irq", (void *)vh264_4k2k_dec_id)) { + pr_info("vh264_4k2k irq register error.\n"); + amvdec_disable(); + if (!H264_4K2K_SINGLE_CORE) + amvdec2_disable(); + + return -ENOENT; + } +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + if (!H264_4K2K_SINGLE_CORE) { + if (vdec_request_irq(VDEC_IRQ_0, vh264_4k2k_vdec2_isr, + "vh264_4k2k-vdec2-irq", + (void *)vh264_4k2k_dec_id2)) { + pr_info("vh264_4k2k irq register error.\n"); + vdec_free_irq(VDEC_IRQ_1, (void *)vh264_4k2k_dec_id); + amvdec_disable(); + amvdec2_disable(); + return -ENOENT; + } + } +#endif + + stat |= STAT_ISR_REG; + + vf_provider_init(&vh264_4k2k_vf_prov, PROVIDER_NAME, + &vh264_4k2k_vf_provider, NULL); + vf_reg_provider(&vh264_4k2k_vf_prov); + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); + + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long) + vh264_4k2k_amstream_dec_info.rate)); + + stat |= STAT_VF_HOOK; + + recycle_timer.data = (ulong) (&recycle_timer); + recycle_timer.function = vh264_4k2k_put_timer_func; + recycle_timer.expires = jiffies + PUT_INTERVAL; + + add_timer(&recycle_timer); + + stat |= STAT_TIMER_ARM; + + amvdec_start(); + if (!H264_4K2K_SINGLE_CORE) + amvdec2_start(); + + stat |= STAT_VDEC_RUN; + + ret = vh264_4k2k_vdec_info_init(); + if (0 != ret) + return -ret; + + return 0; +} + +static int vh264_4k2k_stop(void) +{ + + if (stat & STAT_VDEC_RUN) { + amvdec_stop(); + if (!H264_4K2K_SINGLE_CORE) + amvdec2_stop(); + stat &= ~STAT_VDEC_RUN; + } + + if (stat & STAT_ISR_REG) { + WRITE_VREG(VDEC_ASSIST_MBOX1_MASK, 0); + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_ASSIST_MBOX0_MASK, 0); + + vdec_free_irq(VDEC_IRQ_1, (void *)vh264_4k2k_dec_id); +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ + if (!H264_4K2K_SINGLE_CORE) + vdec_free_irq(VDEC_IRQ_0, (void *)vh264_4k2k_dec_id2); +#endif + stat &= ~STAT_ISR_REG; + } + + if (stat & STAT_TIMER_ARM) { + del_timer_sync(&recycle_timer); + stat &= ~STAT_TIMER_ARM; + } + + if (stat & STAT_VF_HOOK) { + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + + vf_unreg_provider(&vh264_4k2k_vf_prov); + stat &= ~STAT_VF_HOOK; + } +#ifdef DOUBLE_WRITE + WRITE_VREG(MDEC_DOUBLEW_CFG0, 0); + if (!H264_4K2K_SINGLE_CORE) + WRITE_VREG(VDEC2_MDEC_DOUBLEW_CFG0, 0); +#endif + + if (stat & STAT_MC_LOAD) { + if (mc_cpu_addr != NULL) { + dma_free_coherent(amports_get_dma_device(), + MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); + mc_cpu_addr = NULL; + } + + stat &= ~STAT_MC_LOAD; + } + + amvdec_disable(); + if (!H264_4K2K_SINGLE_CORE) + amvdec2_disable(); +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + msleep(100); +#endif + if (mm_blk_handle) { + decoder_bmmu_box_free(mm_blk_handle); + mm_blk_handle = NULL; + } + + return 0; +} + +void vh264_4k_free_cmabuf(void) +{ + int i; + + if (atomic_read(&vh264_4k2k_active)) + return; + mutex_lock(&vh264_4k2k_mutex); + for (i = 0; i < ARRAY_SIZE(buffer_spec); i++) { + if (buffer_spec[i].phy_addr) { + codec_mm_free_for_dma(MEM_NAME, + buffer_spec[i].phy_addr); + buffer_spec[i].phy_addr = 0; + buffer_spec[i].alloc_pages = NULL; + buffer_spec[i].alloc_count = 0; + pr_info("force free CMA buffer %d\n", i); + } + } + mutex_unlock(&vh264_4k2k_mutex); +} + +static int amvdec_h264_4k2k_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + + pr_info("amvdec_h264_4k2k probe start.\n"); + + mutex_lock(&vh264_4k2k_mutex); + + fatal_error = 0; + + if (pdata == NULL) { + pr_info("\namvdec_h264_4k2k memory resource undefined.\n"); + mutex_unlock(&vh264_4k2k_mutex); + return -EFAULT; + } + + if (pdata->sys_info) + vh264_4k2k_amstream_dec_info = *pdata->sys_info; + cma_dev = pdata->cma_dev; + + pr_info(" sysinfo: %dx%d, rate = %d, param = 0x%lx\n", + vh264_4k2k_amstream_dec_info.width, + vh264_4k2k_amstream_dec_info.height, + vh264_4k2k_amstream_dec_info.rate, + (unsigned long) vh264_4k2k_amstream_dec_info.param); + + if (!H264_4K2K_SINGLE_CORE) { + if (vdec_on(VDEC_2)) { /* ++++ */ + vdec_poweroff(VDEC_2); /* ++++ */ + mdelay(10); + } + vdec_poweron(VDEC_2); + } + + + if (!H264_4K2K_SINGLE_CORE) + vdec2_power_mode(1); + + pdata->dec_status = vh264_4k2k_dec_status; + if (H264_4K2K_SINGLE_CORE) + pdata->set_trickmode = vh264_4k2k_set_trickmode; + + if (vh264_4k2k_init() < 0) { + pr_info("\namvdec_h264_4k2k init failed.\n"); + mutex_unlock(&vh264_4k2k_mutex); + kfree(gvs); + gvs = NULL; + + return -ENODEV; + } +#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ + request_vpu_clk_vmod(360000000, VPU_VIU_VD1); +#endif + + if (probe_callback) + probe_callback(); + /*set the max clk for smooth playing...*/ + vdec_source_changed(VFORMAT_H264_4K2K, + 4096, 2048, 30); + INIT_WORK(&set_clk_work, vh264_4k2k_set_clk); + + atomic_set(&vh264_4k2k_active, 1); + mutex_unlock(&vh264_4k2k_mutex); + + return 0; +} + +static int amvdec_h264_4k2k_remove(struct platform_device *pdev) +{ + cancel_work_sync(&alloc_work); + cancel_work_sync(&set_clk_work); + mutex_lock(&vh264_4k2k_mutex); + atomic_set(&vh264_4k2k_active, 0); + + vh264_4k2k_stop(); + + vdec_source_changed(VFORMAT_H264_4K2K, 0, 0, 0); + + if (!H264_4K2K_SINGLE_CORE) { + vdec_poweroff(VDEC_2); + } +#ifdef DEBUG_PTS + pr_info("pts missed %ld, pts hit %ld, duration %d\n", + pts_missed, pts_hit, frame_dur); +#endif + + if (remove_callback) + remove_callback(); + + mutex_unlock(&vh264_4k2k_mutex); + + kfree(gvs); + gvs = NULL; + + pr_info("amvdec_h264_4k2k_remove\n"); + return 0; +} + +void vh264_4k2k_register_module_callback(void (*enter_func)(void), + void (*remove_func)(void)) +{ + probe_callback = enter_func; + remove_callback = remove_func; +} +EXPORT_SYMBOL(vh264_4k2k_register_module_callback); + +/****************************************/ + +static struct platform_driver amvdec_h264_4k2k_driver = { + .probe = amvdec_h264_4k2k_probe, + .remove = amvdec_h264_4k2k_remove, +#ifdef CONFIG_PM + .suspend = amvdec_suspend, + .resume = amvdec_resume, +#endif + .driver = { + .name = DRIVER_NAME, + } +}; + +static struct codec_profile_t amvdec_h264_4k2k_profile = { + .name = "h264_4k2k", + .profile = "" +}; +static struct mconfig h264_4k2k_configs[] = { + MC_PU32("stat", &stat), + MC_PU32("error_recovery_mode", &error_recovery_mode), +}; +static struct mconfig_node h264_4k2k_node; + +static int __init amvdec_h264_4k2k_driver_init_module(void) +{ + pr_debug("amvdec_h264_4k2k module init\n"); + + if (platform_driver_register(&amvdec_h264_4k2k_driver)) { + pr_err("failed to register amvdec_h264_4k2k driver\n"); + return -ENODEV; + } + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXTVBB) + vcodec_profile_register(&amvdec_h264_4k2k_profile); + INIT_REG_NODE_CONFIGS("media.decoder", &h264_4k2k_node, + "h264_4k2k", h264_4k2k_configs, CONFIG_FOR_RW); + return 0; +} + +static void __exit amvdec_h264_4k2k_driver_remove_module(void) +{ + pr_debug("amvdec_h264_4k2k module remove.\n"); + + platform_driver_unregister(&amvdec_h264_4k2k_driver); +} + +/****************************************/ + +module_param(stat, uint, 0664); +MODULE_PARM_DESC(stat, "\n amvdec_h264_4k2k stat\n"); + +module_param(error_recovery_mode, uint, 0664); +MODULE_PARM_DESC(error_recovery_mode, "\n amvdec_h264 error_recovery_mode\n"); + +module_init(amvdec_h264_4k2k_driver_init_module); +module_exit(amvdec_h264_4k2k_driver_remove_module); + +MODULE_DESCRIPTION("AMLOGIC h264_4k2k Video Decoder Driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/h264/vh264_mvc.c b/drivers/frame_provider/decoder/h264/vh264_mvc.c index 4827e38..0efd1a0 100644 --- a/drivers/frame_provider/decoder/h264/vh264_mvc.c +++ b/drivers/frame_provider/decoder/h264/vh264_mvc.c
@@ -31,8 +31,11 @@ #include <linux/workqueue.h> #include <linux/dma-mapping.h> #include <linux/atomic.h> +#include <linux/amlogic/tee.h> + #include <linux/module.h> #include <linux/slab.h> + #include <linux/amlogic/media/utils/vdec_reg.h> #include "../../../stream_input/amports/amports_priv.h" #include "../utils/vdec.h" @@ -42,8 +45,8 @@ #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/amlogic/media/codec_mm/configs.h> #include "../utils/firmware.h" +#include <linux/amlogic/tee.h> #include "../utils/config_parser.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" #define TIME_TASK_PRINT_ENABLE 0x100 #define PUT_PRINT_ENABLE 0x200 @@ -79,7 +82,7 @@ static void vh264mvc_prot_init(void); static int vh264mvc_local_init(void); -static void vh264mvc_put_timer_func(struct timer_list *timer); +static void vh264mvc_put_timer_func(unsigned long arg); static const char vh264mvc_dec_id[] = "vh264mvc-dev"; @@ -512,10 +515,10 @@ static struct vframe_s *vh264mvc_vf_get(void *op_arg) { + struct vframe_s *vf; int view0_buf_id; int view1_buf_id; - struct buffer_spec_s *buf_spec_0, *buf_spec_1; if (get_ptr == fill_ptr) return NULL; @@ -527,27 +530,10 @@ if ((view0_buf_id >= 0) && (view1_buf_id >= 0)) { if (view_mode == 0 || view_mode == 1) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - - buf_spec_0 = (view_mode == 0) ? (&buffer_spec0[view0_buf_id]) : - (&buffer_spec1[view1_buf_id]); - vf->canvas0Addr = vf->canvas1Addr = spec2canvas(buf_spec_0); - - if (is_support_vdec_canvas()) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->canvas0_config[0].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[0].phy_addr = buf_spec_0->y_addr; - vf->canvas0_config[0].width = vdec_cav_get_width(buf_spec_0->y_canvas_index); - vf->canvas0_config[0].height = vdec_cav_get_height(buf_spec_0->y_canvas_index); - vf->canvas0_config[1].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[1].phy_addr = buf_spec_0->u_addr; - vf->canvas0_config[1].width = vdec_cav_get_width(buf_spec_0->u_canvas_index); - vf->canvas0_config[1].height = vdec_cav_get_height(buf_spec_0->u_canvas_index); - vf->canvas0_config[2].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[2].phy_addr = buf_spec_0->v_addr; - vf->canvas0_config[2].width = vdec_cav_get_width(buf_spec_0->v_canvas_index); - vf->canvas0_config[2].height = vdec_cav_get_height(buf_spec_0->v_canvas_index); - vf->plane_num = 3; - } + vf->canvas0Addr = vf->canvas1Addr = + (view_mode == + 0) ? spec2canvas(&buffer_spec0[view0_buf_id]) : + spec2canvas(&buffer_spec1[view1_buf_id]); } else { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_MVC; @@ -559,50 +545,25 @@ vf->right_eye.start_y = 0; vf->right_eye.width = vf->width; vf->right_eye.height = vf->height; - //vf->trans_fmt = TVIN_TFMT_3D_TB; + vf->trans_fmt = TVIN_TFMT_3D_TB; if (view_mode == 2) { - buf_spec_0 = &buffer_spec1[view1_buf_id]; - buf_spec_1 = &buffer_spec0[view0_buf_id]; + vf->canvas0Addr = + spec2canvas(&buffer_spec1[ + view1_buf_id]); + vf->canvas1Addr = + spec2canvas(&buffer_spec0[ + view0_buf_id]); } else { - buf_spec_0 = &buffer_spec0[view0_buf_id]; - buf_spec_1 = &buffer_spec1[view1_buf_id]; - } - if (is_support_vdec_canvas()) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->canvas0_config[0].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[0].phy_addr = buf_spec_0->y_addr; - vf->canvas0_config[0].width = vdec_cav_get_width(buf_spec_0->y_canvas_index); - vf->canvas0_config[0].height = vdec_cav_get_height(buf_spec_0->y_canvas_index); - vf->canvas0_config[1].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[1].phy_addr = buf_spec_0->u_addr; - vf->canvas0_config[1].width = vdec_cav_get_width(buf_spec_0->u_canvas_index); - vf->canvas0_config[1].height = vdec_cav_get_height(buf_spec_0->u_canvas_index); - vf->canvas0_config[2].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas0_config[2].phy_addr = buf_spec_0->v_addr; - vf->canvas0_config[2].width = vdec_cav_get_width(buf_spec_0->v_canvas_index); - vf->canvas0_config[2].height = vdec_cav_get_height(buf_spec_0->v_canvas_index); - - vf->canvas1_config[0].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas1_config[0].phy_addr = buf_spec_1->y_addr; - vf->canvas1_config[0].width = vdec_cav_get_width(buf_spec_1->y_canvas_index); - vf->canvas1_config[0].height = vdec_cav_get_height(buf_spec_1->y_canvas_index); - vf->canvas1_config[1].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas1_config[1].phy_addr = buf_spec_1->u_addr; - vf->canvas1_config[1].width = vdec_cav_get_width(buf_spec_1->u_canvas_index); - vf->canvas1_config[1].height = vdec_cav_get_height(buf_spec_1->u_canvas_index); - vf->canvas1_config[2].block_mode = CANVAS_BLKMODE_32X32; - vf->canvas1_config[2].phy_addr = buf_spec_1->v_addr; - vf->canvas1_config[2].width = vdec_cav_get_width(buf_spec_1->v_canvas_index); - vf->canvas1_config[2].height = vdec_cav_get_height(buf_spec_1->v_canvas_index); - vf->plane_num = 3; - } else { - vf->canvas0Addr = spec2canvas(buf_spec_0); - vf->canvas1Addr = spec2canvas(buf_spec_1); + vf->canvas0Addr = + spec2canvas(&buffer_spec0[ + view0_buf_id]); + vf->canvas1Addr = + spec2canvas(&buffer_spec1[ + view1_buf_id]); } } } - vf->type_original = vf->type; if (((vfpool_idx[get_ptr].view0_drop != 0) || (vfpool_idx[get_ptr].view1_drop != 0)) @@ -743,23 +704,23 @@ buffer_spec[i].alloc_count = page_count; buffer_spec[i].y_addr = addr; buffer_spec[i].y_canvas_index = index; - config_cav_lut_ex(index, addr, + canvas_config(index, addr, mb_width << 4, mb_height << 4, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); addr += mb_total << 8; index++; buffer_spec[i].u_addr = addr; buffer_spec[i].u_canvas_index = index; - config_cav_lut_ex(index, addr, mb_width << 3, mb_height << 3, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); + canvas_config(index, addr, mb_width << 3, mb_height << 3, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); addr += mb_total << 6; index++; buffer_spec[i].v_addr = addr; buffer_spec[i].v_canvas_index = index; - config_cav_lut_ex(index, addr, mb_width << 3, mb_height << 3, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); + canvas_config(index, addr, mb_width << 3, mb_height << 3, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); index++; } @@ -897,10 +858,7 @@ refbuf_size = ref_size * (max_reference_frame_num + 1) * 2; - if (is_support_vdec_canvas()) - index = 0; - else - index = CANVAS_INDEX_START; + index = CANVAS_INDEX_START; ANC_CANVAS_ADDR = ANC0_CANVAS_ADDR; ret = @@ -979,10 +937,7 @@ max_reference_frame_num); } - if (is_support_vdec_canvas()) - index = total_dec_frame_buffering[0] * 3; - else - index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3; + index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3; ANC_CANVAS_ADDR = ANC0_CANVAS_ADDR + total_dec_frame_buffering[0]; @@ -1233,8 +1188,10 @@ } } -static void vh264mvc_put_timer_func(struct timer_list *timer) +static void vh264mvc_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; + int valid_frame = 0; mvc_set_rp(); @@ -1423,10 +1380,7 @@ #endif WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */ - if (is_support_vdec_canvas()) - WRITE_VREG(CANVAS_START, 0); - else - WRITE_VREG(CANVAS_START, CANVAS_INDEX_START); + WRITE_VREG(CANVAS_START, CANVAS_INDEX_START); #if 1 /* Start Address of Workspace (UCODE, temp_data...) */ WRITE_VREG(WORKSPACE_START, @@ -1481,9 +1435,6 @@ WRITE_VREG(BUFFER_RECYCLE, 0); WRITE_VREG(DROP_CONTROL, 0); CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); - - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - #if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); #endif @@ -1529,6 +1480,7 @@ max_dec_frame_buffering[1] = -1; fill_ptr = get_ptr = put_ptr = putting_ptr = 0; dirty_frame_num = 0; + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { view0_vfbuf_use[i] = 0; view1_vfbuf_use[i] = 0; @@ -1572,12 +1524,11 @@ { int ret = -1; char *buf = vmalloc(0x1000 * 16); - if (buf == NULL) return -ENOMEM; pr_info("\nvh264mvc_init\n"); - timer_setup(&recycle_timer, vh264mvc_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -1667,7 +1618,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong) (&recycle_timer); + recycle_timer.function = vh264mvc_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -1834,16 +1788,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int h264mvc_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int h264mvc_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops h264mvc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(h264mvc_suspend, h264mvc_resume) +}; +#endif static struct platform_driver amvdec_h264mvc_driver = { .probe = amvdec_h264mvc_probe, .remove = amvdec_h264mvc_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &h264mvc_pm_ops, +#endif } };
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c old mode 100644 new mode 100755 index 52d9611..b583a82 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
@@ -37,19 +37,15 @@ if (((h264_debug_flag & debug_flag) && ((1 << index) & h264_debug_mask)) || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); + unsigned char buf[512]; int len = 0; va_list args; - if (!buf) - return 0; - va_start(args, fmt); len = sprintf(buf, "%d: ", index); vsnprintf(buf + len, 512-len, fmt, args); pr_debug("%s", buf); va_end(args); - kfree(buf); } return 0; } @@ -59,18 +55,13 @@ if (((h264_debug_flag & debug_flag) && ((1 << index) & h264_debug_mask)) || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); + unsigned char buf[512]; int len = 0; va_list args; - - if (!buf) - return 0; - va_start(args, fmt); vsnprintf(buf + len, 512-len, fmt, args); pr_info("%s", buf); va_end(args); - kfree(buf); } return 0; } @@ -421,8 +412,6 @@ pSlice->long_term_reference_flag, pSlice->no_output_of_prior_pics_flag); - p_H264_Dpb->long_term_reference_flag = pSlice->long_term_reference_flag; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, "idr set pre_frame_num(%d) to frame_num (%d)\n", @@ -663,7 +652,7 @@ (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; /* POC200301 */ - } else if (pSlice->bottom_field_flag == 0) { + } else if (pSlice->bottom_field_flag == FALSE) { /* top field */ pSlice->ThisPOC = pSlice->toppoc = pSlice->PicOrderCntMsb + @@ -781,7 +770,7 @@ (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; /* POC200301 */ - } else if (pSlice->bottom_field_flag == 0) { + } else if (pSlice->bottom_field_flag == FALSE) { /* top field */ pSlice->ThisPOC = pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + @@ -835,7 +824,7 @@ if (pSlice->field_pic_flag == 0) pSlice->toppoc = pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC; - else if (pSlice->bottom_field_flag == 0) + else if (pSlice->bottom_field_flag == FALSE) pSlice->toppoc = pSlice->framepoc = pSlice->ThisPOC; else @@ -1850,35 +1839,6 @@ } -static void unmark_for_long_term_reference(struct FrameStore *fs) -{ - if (fs->is_used & 1) { - if (fs->top_field) { - fs->top_field->used_for_reference = 0; - fs->top_field->is_long_term = 0; - } - } - if (fs->is_used & 2) { - if (fs->bottom_field) { - fs->bottom_field->used_for_reference = 0; - fs->bottom_field->is_long_term = 0; - } - } - if (fs->is_used == 3) { - if (fs->top_field && fs->bottom_field) { - fs->top_field->used_for_reference = 0; - fs->top_field->is_long_term = 0; - fs->bottom_field->used_for_reference = 0; - fs->bottom_field->is_long_term = 0; - } - fs->frame->used_for_reference = 0; - fs->frame->is_long_term = 0; - } - - fs->is_reference = 0; - fs->is_long_term = 0; -} - int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb, int buf_spec_num) { @@ -2093,7 +2053,7 @@ p_Dpb->used_size--; } -int is_used_for_reference(struct FrameStore *fs) +static int is_used_for_reference(struct FrameStore *fs) { if (fs->is_reference) return 1; @@ -2204,6 +2164,7 @@ struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; int ret = 0; unsigned char removed_flag = 0; + do { ret = remove_unused_frame_from_dpb(p_H264_Dpb); if (ret != 0) @@ -2370,8 +2331,7 @@ "%s first_insert_frame %d \n", __func__, p_H264_Dpb->first_insert_frame); } if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) { - if (!p_H264_Dpb->without_display_mode && - p_Dpb->fs[pos]->show_frame != false) + if (!p_H264_Dpb->without_display_mode) p_Dpb->fs[pos]->pre_output = 1; } else { if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) { @@ -2595,14 +2555,6 @@ if (p->no_output_of_prior_pics_flag) { - int i; - for (i = 0; i < p_Dpb->used_size; i++) { - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - if (p_Dpb->fs[i]->is_long_term) - unmark_for_long_term_reference(p_Dpb->fs[i]); - if (!p_Dpb->fs[i]->is_output && !p_Dpb->fs[i]->pre_output) - set_frame_output_flag(p_H264_Dpb, i); - } #if 0 /*???*/ /* free all stored pictures */ @@ -2701,90 +2653,108 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) { - unsigned int i; - unsigned char *buf = NULL; - unsigned int buf_size = 512, len = 0; + unsigned i; struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, struct h264_dpb_stru, mDPB); - -#define DPB_STRCAT(args...) do { \ - len += snprintf(buf + len, \ - buf_size - len, ##args);\ - } while (0) - if ((h264_debug_flag & PRINT_FLAG_DUMP_DPB) == 0 && force == 0) return; - - buf = kzalloc(buf_size, GFP_ATOMIC); - if (buf == NULL) - return; - for (i = 0; i < p_Dpb->used_size; i++) { - len = 0; - memset(buf, 0, buf_size); - DPB_STRCAT("fn=%d is_used %d ", + dpb_print(p_H264_Dpb->decoder_index, + 0, + "("); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "fn=%d is_used %d ", p_Dpb->fs[i]->frame_num, p_Dpb->fs[i]->is_used); - if (p_Dpb->fs[i]->is_used & 1) { if (p_Dpb->fs[i]->top_field) - DPB_STRCAT("T: poc=%d pic_num=%d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "T: poc=%d pic_num=%d ", p_Dpb->fs[i]->top_field->poc, p_Dpb->fs[i]->top_field->pic_num); else - DPB_STRCAT("T: poc=%d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "T: poc=%d ", p_Dpb->fs[i]->frame->top_poc); } if (p_Dpb->fs[i]->is_used & 2) { if (p_Dpb->fs[i]->bottom_field) - DPB_STRCAT("B: poc=%d pic_num=%d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "B: poc=%d pic_num=%d ", p_Dpb->fs[i]->bottom_field->poc, p_Dpb->fs[i]->bottom_field->pic_num); else - DPB_STRCAT("B: poc=%d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "B: poc=%d ", p_Dpb->fs[i]->frame->bottom_poc); } if (p_Dpb->fs[i]->is_used == 3) { if (p_Dpb->fs[i]->frame != NULL) - DPB_STRCAT("F: poc=%d pic_num=%d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "F: poc=%d pic_num=%d ", p_Dpb->fs[i]->frame->poc, p_Dpb->fs[i]->frame->pic_num); else - DPB_STRCAT("fs[%d] frame is null ", i); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, "fs[%d] frame is null ", i); } - DPB_STRCAT("G: poc=%d) ", p_Dpb->fs[i]->poc); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "G: poc=%d) ", p_Dpb->fs[i]->poc); if (p_Dpb->fs[i]->is_reference) - DPB_STRCAT("ref (%d) ", p_Dpb->fs[i]->is_reference); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "ref (%d) ", p_Dpb->fs[i]->is_reference); if (p_Dpb->fs[i]->is_long_term) - DPB_STRCAT("lt_ref (%d) ", p_Dpb->fs[i]->is_reference); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "lt_ref (%d) ", p_Dpb->fs[i]->is_reference); if (p_Dpb->fs[i]->is_output) - DPB_STRCAT("out(displayed) "); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "out(displayed) "); if (p_Dpb->fs[i]->pre_output) - DPB_STRCAT("pre_output(in dispq or displaying) "); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "pre_output(in dispq or displaying) "); if (p_Dpb->fs[i]->is_used == 3) { if (p_Dpb->fs[i]->frame != NULL && p_Dpb->fs[i]->frame->non_existing) - DPB_STRCAT("non_existing "); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "non_existing "); else - DPB_STRCAT("fs[%d] frame is null ", i); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, "fs[%d] frame is null ", i); } - DPB_STRCAT("dpb_frame_count %d ", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "dpb_frame_count %d ", p_Dpb->fs[i]->dpb_frame_count); #if (MVC_EXTENSION_ENABLE) if (p_Dpb->fs[i]->is_reference) - DPB_STRCAT("view_id (%d) ", p_Dpb->fs[i]->view_id); + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "view_id (%d) ", p_Dpb->fs[i]->view_id); #endif if (p_Dpb->fs[i]->data_flag) { - DPB_STRCAT("data_flag(0x%x)", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + "data_flag(0x%x)", p_Dpb->fs[i]->data_flag); } - DPB_STRCAT(" bufspec %d\n", + dpb_print_cont(p_H264_Dpb->decoder_index, + 0, + " bufspec %d\n", p_Dpb->fs[i]->buf_spec_num); - dpb_print(p_H264_Dpb->decoder_index, 0, "%s", buf); } - - kfree(buf); } /*! @@ -2902,6 +2872,35 @@ } } +static void unmark_for_long_term_reference(struct FrameStore *fs) +{ + if (fs->is_used & 1) { + if (fs->top_field) { + fs->top_field->used_for_reference = 0; + fs->top_field->is_long_term = 0; + } + } + if (fs->is_used & 2) { + if (fs->bottom_field) { + fs->bottom_field->used_for_reference = 0; + fs->bottom_field->is_long_term = 0; + } + } + if (fs->is_used == 3) { + if (fs->top_field && fs->bottom_field) { + fs->top_field->used_for_reference = 0; + fs->top_field->is_long_term = 0; + fs->bottom_field->used_for_reference = 0; + fs->bottom_field->is_long_term = 0; + } + fs->frame->used_for_reference = 0; + fs->frame->is_long_term = 0; + } + + fs->is_reference = 0; + fs->is_long_term = 0; +} + /*! ************************************************************************ * \brief @@ -3688,7 +3687,8 @@ else i = 0; - if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)) { + if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE) || + ((p_Dpb->size - frame_outside_count) == p_H264_Dpb->dec_dpb_size)) { while (output_frames(p_H264_Dpb, i)) ; } @@ -5066,7 +5066,7 @@ } dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s: RefPicListX[ %d ] = pic %x (%d)\n", __func__, + "%s: RefPicListX[ %d ] = pic %px (%d)\n", __func__, *refIdxLX, picLX, picNumLX); RefPicListX[(*refIdxLX)++] = picLX; @@ -5501,7 +5501,7 @@ p_old_slice->pps_id = INT_MAX; p_old_slice->frame_num = INT_MAX; p_old_slice->nal_ref_idc = INT_MAX; - p_old_slice->idr_flag = 0; + p_old_slice->idr_flag = FALSE; p_old_slice->pic_oder_cnt_lsb = UINT_MAX; p_old_slice->delta_pic_oder_cnt_bottom = INT_MAX; @@ -5836,7 +5836,11 @@ * p_Vid->height_cr, */ 1); - if (p_H264_Dpb->mVideo.dec_picture) { + if (!p_H264_Dpb->mVideo.dec_picture) { + dpb_print(p_H264_Dpb->decoder_index, + PRINT_FLAG_DPB_DETAIL, "p_H264_Dpb->decoder_index is null\n"); + return -1; + } else { u32 offset_lo, offset_hi; struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; @@ -5888,13 +5892,12 @@ } } #endif - if (post_picture_early(p_H264_Dpb->vdec, - p_H264_Dpb->mVideo.dec_picture->buf_spec_num)) - return -1; } } - + if (post_picture_early(p_H264_Dpb->vdec, + p_H264_Dpb->mVideo.dec_picture->buf_spec_num)) + return -1; if (p_H264_Dpb->mSlice.slice_type == P_SLICE) init_lists_p_slice(&p_H264_Dpb->mSlice); @@ -5946,15 +5949,8 @@ /*int j;*/ struct Slice *currSlice = &p_H264_Dpb->mSlice; /* in first output, ignore ref check */ - if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) && - (p_H264_Dpb->mVideo.dec_picture) && - p_H264_Dpb->first_output_poc > p_H264_Dpb->mVideo.dec_picture->poc) { - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "p_H264_Dpb->first_output_poc %d, p_H264_Dpb->mVideo.dec_picture->poc %d\n", - p_H264_Dpb->first_output_poc, p_H264_Dpb->mVideo.dec_picture->poc); + if (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE) return 0; - } if ((currSlice->slice_type != I_SLICE) && (currSlice->slice_type != SI_SLICE)) { for (i = 0; i < currSlice->listXsize[0]; i++) {
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h old mode 100644 new mode 100755 index 8b3e8bb..8f90961 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
@@ -39,7 +39,6 @@ #define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800 #define PRINT_FLAG_DUMP_BUFSPEC 0x1000 #define PRINT_FLAG_FCC_STATUS 0x2000 -#define PRINT_FLAG_SEI_DETAIL 0x4000 #define PRINT_FLAG_V4L_DETAIL 0x8000 #define DISABLE_ERROR_HANDLE 0x10000 #define DEBUG_DUMP_STAT 0x80000 @@ -65,7 +64,7 @@ #define H264_OUTPUT_MODE_NORMAL 0x4 #define H264_OUTPUT_MODE_FAST 0x8 -//#define FALSE 0 +#define FALSE 0 #define H264_SLICE_HEAD_DONE 0x01 #define H264_PIC_DATA_DONE 0x02 @@ -824,7 +823,7 @@ u32 hw_decode_time; u32 frame_size2; // For recording the chunk->size in frame mode bool show_frame; - struct dma_fence *fence; + struct fence *fence; u32 decoded_frame_size; }; @@ -926,7 +925,6 @@ int first_output_poc; int dpb_frame_count; u32 without_display_mode; - int long_term_reference_flag; }; @@ -1000,6 +998,4 @@ int post_picture_early(struct vdec_s *vdec, int index); -int is_used_for_reference(struct FrameStore *fs); - #endif
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c old mode 100644 new mode 100755 index 5932c91..04ac980 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -23,6 +23,7 @@ #include <linux/kfifo.h> #include <linux/platform_device.h> #include <linux/random.h> + #include <linux/amlogic/media/utils/amstream.h> #include <linux/amlogic/media/frame_sync/ptsserv.h> #include <linux/amlogic/media/canvas/canvas.h> @@ -40,10 +41,10 @@ #include <linux/dma-contiguous.h> #include "../../../stream_input/amports/amports_priv.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> + #include "../utils/vdec_input.h" -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> -#include <linux/sched/clock.h> +#include <linux/amlogic/tee.h> + #include <linux/amlogic/media/utils/vdec_reg.h> #include "../utils/vdec.h" #include "../utils/amvdec.h" @@ -54,14 +55,13 @@ #include "../utils/decoder_mmu_box.h" #include "../utils/decoder_bmmu_box.h" #include "../utils/firmware.h" +#include <linux/amlogic/tee.h> #include <linux/uaccess.h> #include "../utils/config_parser.h" #include "../../../common/chips/decoder_cpu_ver_info.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include <linux/crc32.h> #include <media/v4l2-mem2mem.h> -#include "../utils/vdec_feature.h" - #define DETECT_WRONG_MULTI_SLICE @@ -118,9 +118,6 @@ #define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96) #define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2 -#define ALIGN_WIDTH(x) (ALIGN((x), 64)) -#define ALIGN_HEIGHT(x) (ALIGN((x), 32)) - #define H264_DEV_NUM 9 #define CONSTRAIN_MAX_BUF_NUM @@ -129,6 +126,7 @@ #define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000 #define INVALID_IDX -1 /* Invalid buffer index.*/ + static int mmu_enable; /*mmu do not support mbaff*/ static int force_enable_mmu = 0; @@ -155,8 +153,6 @@ static int pre_decode_buf_level = 0x1000; static int stream_mode_start_num = 4; static int dirty_again_threshold = 100; -static unsigned int colocate_old_cal; - static int check_dirty_data(struct vdec_s *vdec); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -290,7 +286,6 @@ bit[20] 1: fixed some error stream will lead to the diffusion of the error, resulting playback stuck. bit[21] 1: fixed DVB loop playback cause jetter issue. bit[22] 1: In streaming mode, support for discarding data. - bit[23] 0: set error flag on frame number gap error and drop it, 1: ignore error. */ static unsigned int error_proc_policy = 0x7fCfb6; /*0x1f14*/ @@ -562,6 +557,7 @@ #define DEC_RESULT_EOS 7 #define DEC_RESULT_FORCE_EXIT 8 #define DEC_RESULT_TIMEOUT 9 +#define DEC_RESULT_DISCARD_DATA 10 /* @@ -614,7 +610,6 @@ NAL_SEARCH_CTL: bit 0, enable itu_t35 NAL_SEARCH_CTL: bit 1, enable mmu NAL_SEARCH_CTL: bit 2, detect frame_mbs_only_flag whether switch resolution - NAL_SEARCH_CTL: bit 15,bitstream_restriction_flag */ #define NAL_SEARCH_CTL AV_SCRATCH_9 #define MBY_MBX MB_MOTION_MODE /*0xc07*/ @@ -626,6 +621,8 @@ #define DECODE_MODE_MULTI_DVENL 0x4 static DEFINE_MUTEX(vmh264_mutex); + + #ifdef MH264_USERDATA_ENABLE struct mh264_userdata_record_t { @@ -654,11 +651,6 @@ #endif -struct mh264_fence_vf_t { - u32 used_size; - struct vframe_s *fence_vf[VF_POOL_SIZE]; -}; - struct vdec_h264_hw_s { spinlock_t lock; spinlock_t bufspec_lock; @@ -829,8 +821,8 @@ /**/ unsigned int last_frame_time; u32 vf_pre_count; - atomic_t vf_get_count; - atomic_t vf_put_count; + u32 vf_get_count; + u32 vf_put_count; /* timeout handle */ unsigned long int start_process_time; @@ -938,7 +930,6 @@ bool enable_fence; int fence_usage; bool discard_dv_data; - u32 metadata_config_flag; int vdec_pg_enable_flag; u32 save_reg_f; u32 start_bit_cnt; @@ -946,14 +937,11 @@ u32 wrong_frame_count; u32 error_frame_width; u32 error_frame_height; - ulong fb_token; + char vdec_name[32]; + char pts_name[32]; + char new_q_name[32]; + char disp_q_name[32]; int dec_again_cnt; - struct mh264_fence_vf_t fence_vf_s; - struct mutex fence_mutex; - u32 no_decoder_buffer_flag; - u32 video_signal_type; - struct trace_decoder_name trace; - int csd_change_flag; }; static u32 again_threshold; @@ -1007,15 +995,11 @@ static u32 mem_map_mode = H265_MEM_MAP_MODE; #define MAX_SIZE_4K (4096 * 2304) -#define MAX_SIZE_2K (1920 * 1088) static int is_oversize(int w, int h) { int max = MAX_SIZE_4K; - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) - max = MAX_SIZE_2K; - if (w < 0 || h < 0) return true; @@ -1109,6 +1093,19 @@ return hsize; } +static int get_double_write_ratio(struct vdec_h264_hw_s *hw) +{ + int ratio = 1; + int dw_mode = hw->double_write_mode; + if ((dw_mode == 2) || + (dw_mode == 3)) + ratio = 4; + else if (dw_mode == 4) + ratio = 2; + return ratio; +} + + static int get_dw_size(struct vdec_h264_hw_s *hw, u32 *pdw_buffer_size_u_v_h) { int pic_width, pic_height; @@ -1123,9 +1120,9 @@ if (dw_mode) { int pic_width_dw = pic_width / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); int pic_height_dw = pic_height / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); int pic_width_lcu_dw = (pic_width_dw % lcu_size) ? pic_width_dw / lcu_size + 1 : @@ -1160,7 +1157,6 @@ u32 dw_buffer_size_u_v_h; u32 blkmode = hw->canvas_mode; int dw_mode = hw->double_write_mode; - struct vdec_s *vdec = hw_to_vdec(hw); canvas_addr = ANC0_CANVAS_ADDR; for (i = 0; i < num_buff; i++) @@ -1195,11 +1191,6 @@ DRIVER_HEADER_NAME, i); return; } - if (hw->enable_fence) { - vdec_fence_buffer_count_increase((ulong)vdec->sync); - INIT_LIST_HEAD(&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)].node); - decoder_bmmu_box_add_callback_func(hw->bmmu_box, HEADER_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[i]); - } } else maddr = hw->buffer_spec[i].alloc_header_addr; WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, maddr >> 5); @@ -1214,9 +1205,9 @@ int canvas_h; canvas_w = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); canvas_h = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); if (hw->canvas_mode == 0) canvas_w = ALIGN(canvas_w, 32); @@ -1383,9 +1374,7 @@ u32 mc_buffer_size_u_v_h; int dw_mode = hw->double_write_mode; - /*lcu_x_num = (width + 15) >> 4;*/ - // width need to be round to 64 pixel -- case0260 1/10/2020 - lcu_x_num = (((width + 63) >> 6) << 2); + lcu_x_num = (width + 15) >> 4; lcu_y_num = (height + 15) >> 4; lcu_total = lcu_x_num * lcu_y_num; @@ -1434,7 +1423,7 @@ /* ipp_enable*/ WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1 << 1); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(HEVC_DBLK_CFG1, 0x2); // set ctusize==16 WRITE_VREG(HEVC_DBLK_CFG2, ((height & 0xffff)<<16) | (width & 0xffff)); if (dw_mode & 0x10) @@ -1602,7 +1591,7 @@ } /*Reset SAO + Enable SAO slice_start*/ - if (hw->mmu_enable && get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + if (hw->mmu_enable && get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) WRITE_VREG(HEVC_DBLK_CFG0, 0x1); // reset buffer32x4 in lpf for every picture WRITE_VREG(HEVC_SAO_INT_STATUS, READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 28); @@ -1611,7 +1600,7 @@ /*pr_info("hevc_sao_set_pic_buffer:mc_y_adr: %x\n", mc_y_adr);*/ /*Send coommand to hevc-code to supply 4k buffers to sao*/ - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { + if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(H265_SAO_4K_SET_BASE, (u32)hw->frame_mmu_map_phy_addr); WRITE_VREG(H265_SAO_4K_SET_COUNT, MAX_FRAME_4K_NUM); } else @@ -1686,7 +1675,7 @@ } timeout = jiffies + HZ; if ((hw->frame_busy == 1) && (hw->frame_done == 1) ) { - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { + if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET); while ((READ_VREG(SYS_COMMAND) & 0xff) != H265_ABORT_SAO_4K_SET_DONE) { @@ -1736,8 +1725,7 @@ vf->index = -1; } } - /* buffers are alloced when error reset, v4l must find buffer by buffer_wrap[] */ - if (hw->reset_bufmgr_flag && buffer_reset_flag) { + if (buffer_reset_flag) { for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { if (hw->buffer_spec[i].used == 1 || hw->buffer_spec[i].used == 2) hw->buffer_spec[i].used = 0; @@ -1756,7 +1744,6 @@ spin_unlock_irqrestore(&hw->bufspec_lock, flags); } - /*is active in buf management */ static unsigned char is_buf_spec_in_use(struct vdec_h264_hw_s *hw, int buf_spec_num) @@ -1800,142 +1787,137 @@ buf_size += (hw->mb_total << 7) + (hw->mb_total << 6); else if (IS_VDEC_DW(hw) == 2) buf_size += (hw->mb_total << 6) + (hw->mb_total << 5); - else if (IS_VDEC_DW(hw) == 4) - buf_size += (hw->mb_total << 4) + (hw->mb_total << 3); - else if (IS_VDEC_DW(hw) == 8) - buf_size += (hw->mb_total << 2) + (hw->mb_total << 1); - if (IS_VDEC_DW(hw)) { - u32 align_size; - /* add align padding size for blk64x32: (mb_w<<4)*32, (mb_h<<4)*64 */ - align_size = ((hw->mb_width << 9) + (hw->mb_height << 10)) / IS_VDEC_DW(hw); - /* double align padding size for uv*/ - align_size <<= 1; - buf_size += align_size + PAGE_SIZE; - } #endif if (hw->buffer_spec[i].cma_alloc_addr) return 0; - if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i, - PAGE_ALIGN(buf_size), DRIVER_NAME, - &hw->buffer_spec[i].cma_alloc_addr) < 0) { - hw->buffer_spec[i].cma_alloc_addr = 0; - if (hw->no_mem_count++ > 3) { - hw->stat |= DECODER_FATAL_ERROR_NO_MEM; - hw->reset_bufmgr_flag = 1; - } - dpb_print(DECODE_ID(hw), 0, - "%s, fail to alloc buf for bufspec%d, try later\n", - __func__, i - ); - return -1; - } else { - if (hw->enable_fence) { - vdec_fence_buffer_count_increase((ulong)vdec->sync); - INIT_LIST_HEAD(&vdec->sync->release_callback[i].node); - decoder_bmmu_box_add_callback_func(hw->bmmu_box, i, (void *)&vdec->sync->release_callback[i]); - } - hw->no_mem_count = 0; - hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM; + if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i, + PAGE_ALIGN(buf_size), DRIVER_NAME, + &hw->buffer_spec[i].cma_alloc_addr) < 0) { + hw->buffer_spec[i].cma_alloc_addr = 0; + if (hw->no_mem_count++ > 3) { + hw->stat |= DECODER_FATAL_ERROR_NO_MEM; + hw->reset_bufmgr_flag = 1; } - if (!vdec_secure(vdec)) { - /*init internal buf*/ - char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr); + dpb_print(DECODE_ID(hw), 0, + "%s, fail to alloc buf for bufspec%d, try later\n", + __func__, i + ); + return -1; + } else { + hw->no_mem_count = 0; + hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM; + } + if (!vdec_secure(vdec)) { + /*init internal buf*/ + char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr); + if (tmpbuf) { + memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); + codec_mm_dma_flush(tmpbuf, + PAGE_ALIGN(buf_size), + DMA_TO_DEVICE); + } else { + tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size)); if (tmpbuf) { memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); codec_mm_dma_flush(tmpbuf, PAGE_ALIGN(buf_size), DMA_TO_DEVICE); - } else { - tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size)); - if (tmpbuf) { - memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); - codec_mm_dma_flush(tmpbuf, - PAGE_ALIGN(buf_size), - DMA_TO_DEVICE); - codec_mm_unmap_phyaddr(tmpbuf); - } + codec_mm_unmap_phyaddr(tmpbuf); } } - hw->buffer_spec[i].buf_adr = - hw->buffer_spec[i].cma_alloc_addr; - addr = hw->buffer_spec[i].buf_adr; + } + hw->buffer_spec[i].buf_adr = + hw->buffer_spec[i].cma_alloc_addr; + addr = hw->buffer_spec[i].buf_adr; - hw->buffer_spec[i].y_addr = addr; - addr += hw->mb_total << 8; - hw->buffer_spec[i].u_addr = addr; - hw->buffer_spec[i].v_addr = addr; - addr += hw->mb_total << 7; + hw->buffer_spec[i].y_addr = addr; + addr += hw->mb_total << 8; + hw->buffer_spec[i].u_addr = addr; + hw->buffer_spec[i].v_addr = addr; + addr += hw->mb_total << 7; - hw->buffer_spec[i].canvas_config[0].phy_addr = - hw->buffer_spec[i].y_addr; - hw->buffer_spec[i].canvas_config[0].width = + hw->buffer_spec[i].canvas_config[0].phy_addr = + hw->buffer_spec[i].y_addr; + hw->buffer_spec[i].canvas_config[0].width = + hw->mb_width << 4; + hw->buffer_spec[i].canvas_config[0].height = + hw->mb_height << 4; + hw->buffer_spec[i].canvas_config[0].block_mode = + hw->canvas_mode; + + hw->buffer_spec[i].canvas_config[1].phy_addr = + hw->buffer_spec[i].u_addr; + hw->buffer_spec[i].canvas_config[1].width = hw->mb_width << 4; - hw->buffer_spec[i].canvas_config[0].height = - hw->mb_height << 4; - hw->buffer_spec[i].canvas_config[0].block_mode = + hw->buffer_spec[i].canvas_config[1].height = + hw->mb_height << 3; + hw->buffer_spec[i].canvas_config[1].block_mode = hw->canvas_mode; - - hw->buffer_spec[i].canvas_config[1].phy_addr = - hw->buffer_spec[i].u_addr; - hw->buffer_spec[i].canvas_config[1].width = - hw->mb_width << 4; - hw->buffer_spec[i].canvas_config[1].height = - hw->mb_height << 3; - hw->buffer_spec[i].canvas_config[1].block_mode = - hw->canvas_mode; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, alloc buf for bufspec%d\n", - __func__, i); + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s, alloc buf for bufspec%d\n", + __func__, i + ); #ifdef VDEC_DW - if (!IS_VDEC_DW(hw)) - return 0; - else { - int w_shift = 3, h_shift = 3; - if (IS_VDEC_DW(hw) == 1) { - w_shift = 3; - h_shift = 4; - } else if (IS_VDEC_DW(hw) == 2) { - w_shift = 3; - h_shift = 3; - } else if (IS_VDEC_DW(hw) == 4) { - w_shift = 2; - h_shift = 2; - } else if (IS_VDEC_DW(hw) == 8) { - w_shift = 1; - h_shift = 1; - } + if (!IS_VDEC_DW(hw)) + return 0; + else if (IS_VDEC_DW(hw) == 1) { + addr = hw->buffer_spec[i].cma_alloc_addr + orig_buf_size; + hw->buffer_spec[i].vdec_dw_y_addr = addr; + addr += hw->mb_total << 7; + hw->buffer_spec[i].vdec_dw_u_addr = addr; + hw->buffer_spec[i].vdec_dw_v_addr = addr; + addr += hw->mb_total << 6; - addr = hw->buffer_spec[i].cma_alloc_addr + PAGE_ALIGN(orig_buf_size); - hw->buffer_spec[i].vdec_dw_y_addr = addr; - addr += ALIGN_WIDTH(hw->mb_width << w_shift) * ALIGN_HEIGHT(hw->mb_height << h_shift); - hw->buffer_spec[i].vdec_dw_u_addr = addr; - hw->buffer_spec[i].vdec_dw_v_addr = addr; - addr += hw->mb_total << (w_shift + h_shift - 1); + hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr = + hw->buffer_spec[i].vdec_dw_y_addr; + hw->buffer_spec[i].vdec_dw_canvas_config[0].width = + hw->mb_width << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[0].height = + hw->mb_height << 4; + hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode = + CANVAS_BLKMODE_32X32; - hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr = - hw->buffer_spec[i].vdec_dw_y_addr; - hw->buffer_spec[i].vdec_dw_canvas_config[0].width = - ALIGN_WIDTH(hw->mb_width << w_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[0].height = - ALIGN_HEIGHT(hw->mb_height << h_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode = - hw->canvas_mode; - - hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr = + hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr = hw->buffer_spec[i].vdec_dw_u_addr; - hw->buffer_spec[i].vdec_dw_canvas_config[1].width = - ALIGN_WIDTH(hw->mb_width << w_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[1].height = - ALIGN_HEIGHT(hw->mb_height << (h_shift - 1)); - hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode = - hw->canvas_mode; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, vdec_dw: alloc buf for bufspec%d blkmod %d\n", - __func__, i, hw->canvas_mode); - } + hw->buffer_spec[i].vdec_dw_canvas_config[1].width = + hw->mb_width << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[1].height = + hw->mb_height << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode = + CANVAS_BLKMODE_32X32; + }else { + addr = hw->buffer_spec[i].cma_alloc_addr + orig_buf_size; + hw->buffer_spec[i].vdec_dw_y_addr = addr; + addr += hw->mb_total << 6; + hw->buffer_spec[i].vdec_dw_u_addr = addr; + hw->buffer_spec[i].vdec_dw_v_addr = addr; + addr += hw->mb_total << 5; + + hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr = + hw->buffer_spec[i].vdec_dw_y_addr; + hw->buffer_spec[i].vdec_dw_canvas_config[0].width = + hw->mb_width << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[0].height = + hw->mb_height << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode = + CANVAS_BLKMODE_32X32; + + hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr = + hw->buffer_spec[i].vdec_dw_u_addr; + hw->buffer_spec[i].vdec_dw_canvas_config[1].width = + hw->mb_width << 3; + hw->buffer_spec[i].vdec_dw_canvas_config[1].height = + hw->mb_height << 2; + hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode = + CANVAS_BLKMODE_32X32; + } + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s, vdec_dw: alloc buf for bufspec%d\n", + __func__, i + ); #endif } return 0; @@ -1965,7 +1947,7 @@ ctx->id, __func__, (hw->mb_total << 8) + (hw->mb_total << 7)); - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, "[%d] get fb fail.\n", ctx->id); @@ -1974,7 +1956,7 @@ bs->cma_alloc_addr = (unsigned long)fb; dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), cma alloc addr: 0x%x, out %d dec %d\n", + "[%d] %s(), cma alloc addr: 0x%lx, out %d dec %d\n", ctx->id, __func__, bs->cma_alloc_addr, ctx->cap_pool.out, ctx->cap_pool.dec); @@ -1989,8 +1971,6 @@ fb->m.mem[1].bytes_used = fb->m.mem[1].size; } - fb->status = FB_ST_DECODER; - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, "[%d] %s(), y_addr: %x, size: %u\n", ctx->id, __func__, y_addr, fb->m.mem[0].size); @@ -2044,15 +2024,14 @@ if (hw->is_used_v4l) endian = 7; - config_cav_lut_ex(hw->buffer_spec[i]. + canvas_config_ex(hw->buffer_spec[i]. y_canvas_index, hw->buffer_spec[i].y_addr, hw->mb_width << 4, hw->mb_height << 4, CANVAS_ADDR_NOWRAP, blkmode, - endian, - VDEC_1); + endian); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, @@ -2063,15 +2042,14 @@ ); } - config_cav_lut_ex(hw->buffer_spec[i]. + canvas_config_ex(hw->buffer_spec[i]. u_canvas_index, hw->buffer_spec[i].u_addr, hw->mb_width << 4, hw->mb_height << 3, CANVAS_ADDR_NOWRAP, blkmode, - endian, - VDEC_1); + endian); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, @@ -2088,16 +2066,46 @@ #ifdef VDEC_DW if (!IS_VDEC_DW(hw)) return; - else { - config_cav_lut_ex(hw->buffer_spec[i]. + else if (IS_VDEC_DW(hw) == 1) { + canvas_config_ex(hw->buffer_spec[i]. vdec_dw_y_canvas_index, - hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr, - hw->buffer_spec[i].vdec_dw_canvas_config[0].width, - hw->buffer_spec[i].vdec_dw_canvas_config[0].height, + hw->buffer_spec[i].vdec_dw_y_addr, + hw->mb_width << 3, + hw->mb_height << 4, CANVAS_ADDR_NOWRAP, blkmode, - endian, - VDEC_1); + endian); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, + (1 << 11) | + (blkmode << 10) | + (1 << 8) | + (hw->buffer_spec[i].vdec_dw_y_canvas_index << 0)); + } + canvas_config_ex(hw->buffer_spec[i]. + vdec_dw_u_canvas_index, + hw->buffer_spec[i].vdec_dw_u_addr, + hw->mb_width << 3, + hw->mb_height << 3, + CANVAS_ADDR_NOWRAP, + blkmode, + endian); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, + (1 << 11) | + (blkmode << 10) | + (1 << 8) | + (hw->buffer_spec[i].vdec_dw_u_canvas_index << 0)); + } + } else { + canvas_config_ex(hw->buffer_spec[i]. + vdec_dw_y_canvas_index, + hw->buffer_spec[i].vdec_dw_y_addr, + hw->mb_width << 3, + hw->mb_height << 3, + CANVAS_ADDR_NOWRAP, + blkmode, + endian); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, (1 << 11) | @@ -2106,15 +2114,14 @@ (hw->buffer_spec[i].vdec_dw_y_canvas_index << 0)); } - config_cav_lut_ex(hw->buffer_spec[i]. + canvas_config_ex(hw->buffer_spec[i]. vdec_dw_u_canvas_index, - hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr, - hw->buffer_spec[i].vdec_dw_canvas_config[1].width, - hw->buffer_spec[i].vdec_dw_canvas_config[1].height, + hw->buffer_spec[i].vdec_dw_u_addr, + hw->mb_width << 3, + hw->mb_height << 2, CANVAS_ADDR_NOWRAP, blkmode, - endian, - VDEC_1); + endian); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, (1 << 11) | @@ -2133,9 +2140,9 @@ int canvas_h; canvas_w = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); canvas_h = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); if (hw->canvas_mode == 0) canvas_w = ALIGN(canvas_w, 32); @@ -2143,27 +2150,26 @@ canvas_w = ALIGN(canvas_w, 64); canvas_h = ALIGN(canvas_h, 32); - config_cav_lut_ex(hw->buffer_spec[i]. + canvas_config_ex(hw->buffer_spec[i]. y_canvas_index, hw->buffer_spec[i].dw_y_adr, canvas_w, canvas_h, CANVAS_ADDR_NOWRAP, blkmode, - 7, - VDEC_HEVC); + 7); - config_cav_lut_ex(hw->buffer_spec[i]. + canvas_config_ex(hw->buffer_spec[i]. u_canvas_index, hw->buffer_spec[i].dw_u_v_adr, canvas_w, canvas_h, CANVAS_ADDR_NOWRAP, blkmode, - 7, - VDEC_HEVC); + 7); } + static int v4l_get_free_buffer_spec(struct vdec_h264_hw_s *hw) { int i; @@ -2195,7 +2201,7 @@ struct buffer_spec_s *pic = NULL; int i, rt, idx = INVALID_IDX; ulong flags; - u32 state = 0, index; + u32 state, index; spin_lock_irqsave(&hw->bufspec_lock, flags); for (i = 0; i < pool->in; ++i) { @@ -2228,6 +2234,7 @@ } break; default: + pr_err("v4l buffer state err %d.\n", state); break; } @@ -2239,17 +2246,12 @@ spin_unlock_irqrestore(&hw->bufspec_lock, flags); if (idx < 0) { - dpb_print(DECODE_ID(hw), 0, "%s fail, state %d\n", __func__, state); + dpb_print(DECODE_ID(hw), 0, "%s fail\n", __func__); for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { dpb_print(DECODE_ID(hw), 0, "%s, %d\n", __func__, hw->buffer_wrap[i]); } vmh264_dump_state(vdec); - } else { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)pic->cma_alloc_addr; - - fb->status = FB_ST_DECODER; } return idx; @@ -2300,7 +2302,6 @@ } } } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); if (hw->start_search_pos >= buf_total) hw->start_search_pos = 0; @@ -2548,7 +2549,7 @@ int i; unsigned long addr; struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx * ctx = hw->v4l2_ctx; + struct aml_vcodec_ctx * v4l = hw->v4l2_ctx; int canvas_pos_min = BUFSPEC_POOL_SIZE; int index = -1; int ret = 0; @@ -2557,10 +2558,6 @@ if (hw->is_used_v4l) { struct h264_dpb_stru *dpb = &hw->dpb; - /* trigger to parse head data. */ - if (!hw->v4l_params_parsed) - return 1; - if (dpb->mDPB.used_size >= dpb->mDPB.size - 1) return 0; @@ -2572,13 +2569,10 @@ } } - if (ctx->cap_pool.dec < hw->dpb.mDPB.size) { - if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) >= - run_ready_min_buf_num) { - if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) - return 1; - } - } + if (v4l->cap_pool.dec < hw->dpb.mDPB.size && + v4l2_m2m_num_dst_bufs_ready(v4l->m2m_ctx) + >= run_ready_min_buf_num) + return 1; return 0; } @@ -2661,9 +2655,6 @@ if (vdec_secure(hw_to_vdec(hw))) return 0; - if (hw->i_only) - return 0; - if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE) && hw->bitstream_restriction_flag && (hw->frame_width == 1920) @@ -2677,7 +2668,9 @@ && (hw->frame_dur == 3840)) { bForceInterlace = 1; } - + if ((frame->frame) && (hw->is_used_v4l) && (bForceInterlace == 0)) { + bForceInterlace = (frame->frame->mb_aff_frame_flag)?1:0; + } return bForceInterlace; } @@ -2779,22 +2772,23 @@ if (frame->frame == NULL && ((frame->is_used == 1 && frame->top_field) || (frame->is_used == 2 && frame->bottom_field))) { - if (hw->i_only) { - if (frame->is_used == 1) - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s No bottom_field !! frame_num %d used %d\n", - __func__, frame->frame_num, frame->is_used); - if (frame->is_used == 2) - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s No top_field !! frame_num %d used %d\n", - __func__, frame->frame_num, frame->is_used); - } - else { - frame->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "%s Error frame_num %d used %d\n", + if (hw->i_only) { + if (frame->is_used == 1) + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s No bottom_field !! frame_num %d used %d\n", __func__, frame->frame_num, frame->is_used); - } + if (frame->is_used == 2) + dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, + "%s No top_field !! frame_num %d used %d\n", + __func__, frame->frame_num, frame->is_used); + } + else { + frame->data_flag |= ERROR_FLAG; + dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, + "%s Error frame_num %d used %d\n", + __func__, frame->frame_num, frame->is_used); + } + } if (vdec_stream_based(vdec) && !(frame->data_flag & NODISP_FLAG)) { if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { @@ -2815,7 +2809,6 @@ hw->wrong_frame_count++; } } - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s error= 0x%x poc = %d offset= 0x%x pts= 0x%x last_pts =0x%x pts64 = %lld last_pts64= %lld duration = %d\n", __func__, (frame->data_flag & ERROR_FLAG), frame->poc, @@ -2874,13 +2867,13 @@ } - if ((!hw->enable_fence) && - ((frame->data_flag & NODISP_FLAG) || + if ((frame->data_flag & NODISP_FLAG) || (frame->data_flag & NULL_FLAG) || ((!hw->send_error_frame_flag) && (frame->data_flag & ERROR_FLAG)) || ((hw->i_only & 0x1) && - (!(frame->data_flag & I_FLAG))))) { + (!(frame->data_flag & I_FLAG)))) { + set_frame_output_flag(&hw->dpb, frame->index); frame->show_frame = false; return 0; } @@ -2909,7 +2902,6 @@ struct vframe_s *vf = NULL; int buffer_index = frame->buf_spec_num; struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; ulong nv_order = VIDTYPE_VIU_NV21; int bForceInterlace = 0; int vf_count = 1; @@ -2930,15 +2922,12 @@ bForceInterlace = check_force_interlace(hw, frame); if (bForceInterlace) vf_count = 2; - + if (hw->is_used_v4l) + vf_count = 1; if (!hw->enable_fence) hw->buffer_spec[buffer_index].vf_ref = 0; fill_frame_info(hw, frame); - if ((hw->is_used_v4l) && - (vdec->prog_only)) - vf_count = 1; - for (i = 0; i < vf_count; i++) { if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) { @@ -2963,7 +2952,6 @@ if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->buffer_spec[buffer_index].cma_alloc_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; } if (hw->enable_fence) { @@ -3029,14 +3017,9 @@ vf->canvas0Addr = vf->canvas1Addr = spec2canvas(&hw->buffer_spec[buffer_index]); #ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw)) - vf->canvas0Addr = vf->canvas1Addr = - vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]); - } else { - if (IS_VDEC_DW(hw)) - vf->canvas0Addr = vf->canvas1Addr = -1; - } + if (IS_VDEC_DW(hw)) + vf->canvas0Addr = vf->canvas1Addr = + vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]); #endif } @@ -3047,17 +3030,9 @@ if (hw->mmu_enable && hw->double_write_mode) { vf->width = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); vf->height = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); - } - - if (frame->slice_type == I_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME; - } else if (frame->slice_type == P_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_PFRAME; - } else if (frame->slice_type == B_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_BFRAME; + get_double_write_ratio(hw); } vf->flag = 0; @@ -3148,30 +3123,6 @@ } } - /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/ - vf->sar_width = hw->width_aspect_ratio; - vf->sar_height = hw->height_aspect_ratio; - if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) { - /* offset for tsplayer pts lookup */ - if (i == 0) { - vf->pts_us64 = - (((u64)vf->duration << 32) & - 0xffffffff00000000) | frame->offset_delimiter; - vf->pts = 0; - } else { - vf->pts_us64 = (u64)-1; - vf->pts = 0; - } - } - - hw->vf_pre_count++; - vdec_vframe_ready(hw_to_vdec(hw), vf); - if (!frame->show_frame) { - vh264_vf_put(vf, vdec); - atomic_add(1, &hw->vf_get_count); - continue; - } - if (i == 0) { struct vdec_s *pvdec; struct vdec_info vs; @@ -3187,49 +3138,41 @@ __func__, __LINE__,vs.i_decoded_frames,vs.p_decoded_frames,vs.b_decoded_frames); } + /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/ + vf->sar_width = hw->width_aspect_ratio; + vf->sar_height = hw->height_aspect_ratio; + if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) { + /* offset for tsplayer pts lookup */ + if (i == 0) { + vf->pts_us64 = + (((u64)vf->duration << 32) & + 0xffffffff00000000) | frame->offset_delimiter; + vf->pts = 0; + } else { + vf->pts_us64 = (u64)-1; + vf->pts = 0; + } + } + vdec_vframe_ready(hw_to_vdec(hw), vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.pts_name, vf->pts); - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); + ATRACE_COUNTER(hw->pts_name, vf->pts); + ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q)); + ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q)); hw->vf_pre_count++; vdec->vdec_fps_detec(vdec->id); #ifdef AUX_DATA_CRC decoder_do_aux_data_check(vdec, hw->buffer_spec[buffer_index].aux_data_buf, hw->buffer_spec[buffer_index].aux_data_size); #endif - - dpb_print(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL, "aux_data_size: %d, signal_type: 0x%x\n", - hw->buffer_spec[buffer_index].aux_data_size, hw->video_signal_type); - - if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL)) { - int i = 0; - PR_INIT(128); - - for (i = 0; i < hw->buffer_spec[buffer_index].aux_data_size; i++) { - PR_FILL("%02x ", hw->buffer_spec[buffer_index].aux_data_buf[i]); - if (((i + 1) & 0xf) == 0) - PR_INFO(hw->id); - } - PR_INFO(hw->id); - } - - if (hw->is_used_v4l) { + if (hw->is_used_v4l) update_vframe_src_fmt(vf, hw->buffer_spec[buffer_index].aux_data_buf, hw->buffer_spec[buffer_index].aux_data_size, false, vdec->vf_provider_name, NULL); - } if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vh264_vf_put(vh264_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vh264_vf_put(vh264_vf_get(vdec), vdec); } @@ -3251,13 +3194,13 @@ return 0; /* create fence for each buffers. */ - if (vdec_timeline_create_fence(vdec->sync)) + if (vdec_timeline_create_fence(&vdec->sync)) return -1; memset(&fs, 0, sizeof(fs)); fs.buf_spec_num = index; - fs.fence = vdec->sync->fence; + fs.fence = vdec->sync.fence; fs.slice_type = dpb_stru->mSlice.slice_type; fs.dpb_frame_count = dpb_stru->dpb_frame_count; @@ -3270,7 +3213,7 @@ fs.pts64 = hw->chunk->pts64; fs.timestamp = hw->chunk->timestamp; } - fs.show_frame = true; + post_video_frame(vdec, &fs); display_frame_count[DECODE_ID(hw)]++; @@ -3283,10 +3226,6 @@ (struct vdec_h264_hw_s *)vdec->private; if (hw->enable_fence) { - int i, j, used_size, ret; - int signed_count = 0; - struct vframe_s *signed_fence[VF_POOL_SIZE]; - post_prepare_process(vdec, frame); if (!frame->show_frame) @@ -3297,36 +3236,16 @@ hw->buffer_spec[frame->buf_spec_num].fs_idx = frame->index; /* notify signal to wake up wq of fence. */ - vdec_timeline_increase(vdec->sync, 1); - - mutex_lock(&hw->fence_mutex); - used_size = hw->fence_vf_s.used_size; - if (used_size) { - for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) { - if (hw->fence_vf_s.fence_vf[i] != NULL) { - ret = dma_fence_get_status(hw->fence_vf_s.fence_vf[i]->fence); - if (ret == 1) { - signed_fence[signed_count] = hw->fence_vf_s.fence_vf[i]; - hw->fence_vf_s.fence_vf[i] = NULL; - hw->fence_vf_s.used_size--; - signed_count++; - } - j++; - } - } - } - mutex_unlock(&hw->fence_mutex); - if (signed_count != 0) { - for (i = 0; i < signed_count; i++) - vh264_vf_put(signed_fence[i], vdec); - } - + vdec_timeline_increase(&vdec->sync, 1); return 0; } if (post_prepare_process(vdec, frame)) return -1; + if (!frame->show_frame) + return 0; + if (post_video_frame(vdec, frame)) return -1; @@ -3353,8 +3272,7 @@ } if (index == INVALID_IDX) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { + if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) { pr_err("[%d] EOS get free buff fail.\n", ctx->id); return -1; } @@ -3366,18 +3284,12 @@ vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb : hw->buffer_spec[index].cma_alloc_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - ATRACE_COUNTER(hw->trace.pts_name, vf->pts); - - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + ATRACE_COUNTER(hw->pts_name, vf->pts); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); pr_info("[%d] H264 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } @@ -3484,7 +3396,7 @@ hw_buf->prefix_aux_size; } if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) { + PRINT_FLAG_DEC_DETAIL)) { dpb_print(DECODE_ID(hw), 0, "%s:poc %d old size %d count %d,suf %d dv_flag %d\r\n", __func__, pic->poc, AUX_DATA_SIZE(pic), @@ -3583,7 +3495,7 @@ h[7] = (padding_len) & 0xff; } if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) { + PRINT_FLAG_DEC_DETAIL)) { dpb_print(DECODE_ID(hw), 0, "aux: (size %d) suffix_flag %d\n", AUX_DATA_SIZE(pic), suffix_flag); @@ -3663,98 +3575,6 @@ } } -#ifdef VDEC_DW - -struct vdec_dw_param_set{ - char dw_x_shrink_1st; - char dw_x_shrink_2nd; - char dw_x_shrink_3rd; - char dw_y_shrink_1st; - char dw_y_shrink_2nd; - char dw_y_shrink_3rd; - char dw_merge_8to16; - char dw_merge_16to32; - char dw_dma_blk_mode; - char dw_bwsave_mode; -}; -//#define FOR_LPDDR4_EFFICIENCY - -static void h264_vdec_dw_cfg(struct vdec_h264_hw_s *hw, int canvas_pos) -{ - u32 data32 = 0, stride = 0; - struct vdec_dw_param_set *p = NULL; - struct vdec_dw_param_set dw_param_set_pool[] = { - /*x1, x2, x3, y1, y2, y3, m8t6, m16to32 */ - //{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/1, 1/1 */ - {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/1 */ - {1, 0, 0, 1, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/2 */ - //{1, 0, 0, 1, 1, 0, 0, 0, 0, 1}, /* 1/4, 1/2 */ - {2, 0, 1, 1, 3, 0, 0, 1, 0, 1}, /* 1/4, 1/4 */ - //{1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/4 */ - {1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/8 */ - }; - - if (IS_VDEC_DW(hw)) - p = &dw_param_set_pool[__ffs(IS_VDEC_DW(hw))]; - else - return; - - WRITE_VREG(MDEC_DOUBLEW_CFG3, - hw->buffer_spec[canvas_pos].vdec_dw_y_addr); // luma start address - WRITE_VREG(MDEC_DOUBLEW_CFG4, - hw->buffer_spec[canvas_pos].vdec_dw_u_addr); // chroma start address - - stride = ALIGN_WIDTH((hw->mb_width << 4) / (IS_VDEC_DW(hw))); - if ((IS_VDEC_DW(hw)) == 1) //width 1/2 - stride >>= 1; - data32 = (stride << 16) | stride; - WRITE_VREG(MDEC_DOUBLEW_CFG5, data32); // chroma stride | luma stride - - data32 = 0; - p->dw_dma_blk_mode = hw->canvas_mode; - data32 |= ((p->dw_x_shrink_1st << 0 ) | // 1st down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_1st << 2 ) | // 1st down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_x_shrink_2nd << 4 ) | // 2nd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_2nd << 6 ) | // 2nd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_x_shrink_3rd << 8 ) | // 3rd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_3rd << 10) | // 3rd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_merge_8to16 << 12 ) | // 8->16 horizontal block merge for better ddr efficiency - (p->dw_merge_16to32 << 13) | // 16->32 horizontal block merge for better ddr efficiency - (p->dw_dma_blk_mode << 14) | // DMA block mode, 0:linear 1:32x32 2:64x32 -#ifdef FOR_LPDDR4_EFFICIENCY - (1 << 19) | -#endif - (p->dw_bwsave_mode << 22)); // Save line buffers to save band width - WRITE_VREG(MDEC_DOUBLEW_CFG1, data32); // add some special tests here - - data32 = 0; - data32 |= (1 << 0) | (0 << 27); - WRITE_VREG(MDEC_DOUBLEW_CFG0, data32); // Double Write Enable | source from dblk - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "vdec_double_write mode %d\n", - IS_VDEC_DW(hw)); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "param {%d, %d, %d, %d, %d, %d, %d, %d, %d}\n", - p->dw_x_shrink_1st, - p->dw_y_shrink_1st, - p->dw_x_shrink_2nd, - p->dw_y_shrink_2nd, - p->dw_x_shrink_3rd, - p->dw_y_shrink_3rd, - p->dw_merge_8to16, - p->dw_merge_16to32, - p->dw_dma_blk_mode); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "cfg0,1,3,4,5 = {%x, %x, %x, %x, %x}\n", - READ_VREG(MDEC_DOUBLEW_CFG0), - READ_VREG(MDEC_DOUBLEW_CFG1), - READ_VREG(MDEC_DOUBLEW_CFG3), - READ_VREG(MDEC_DOUBLEW_CFG4), - READ_VREG(MDEC_DOUBLEW_CFG5)); -} -#endif - static void config_decode_mode(struct vdec_h264_hw_s *hw) { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -3785,7 +3605,6 @@ else WRITE_VREG(INIT_FLAG_REG, 1); } - int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) { /* static int count = 0; */ @@ -3847,11 +3666,9 @@ print_pic_info(DECODE_ID(hw), "cur", pic, pSlice->slice_type); #ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag) - WRITE_VREG(MDEC_DOUBLEW_CFG0, - (READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30)))); - } + if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag) + WRITE_VREG(MDEC_DOUBLEW_CFG0, + ( READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30)))); #endif WRITE_VREG(CURR_CANVAS_CTRL, canvas_pos << 24); canvas_adr = READ_VREG(CURR_CANVAS_CTRL) & 0xffffff; @@ -3861,13 +3678,9 @@ WRITE_VREG(DBKR_CANVAS_ADDR, canvas_adr); WRITE_VREG(DBKW_CANVAS_ADDR, canvas_adr); #ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - WRITE_VREG(MDEC_DOUBLEW_CFG1, - (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index | - (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8))); - } else { - h264_vdec_dw_cfg(hw, canvas_pos); - } + WRITE_VREG(MDEC_DOUBLEW_CFG1, + (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index + | (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8))); #endif } else hevc_sao_set_pic_buffer(hw, pic); @@ -4187,16 +4000,12 @@ * 00 - top field, 01 - bottom field, * 10 - frame, 11 - mbaff frame */ - int l10_structure, cur_structure; + int l10_structure; int cur_colocate_ref_type; /* H264_CO_MB_RD_ADDR[bit 29], top/bot for B field pciture, * 0 - top, 1 - bot */ unsigned int val; - unsigned int colocate_rd_adr_offset; - unsigned int mby_mbx; - unsigned int mby, mbx; - #ifdef ERROR_CHECK if (colocate_pic == NULL) { hw->data_flag |= ERROR_FLAG; @@ -4222,60 +4031,6 @@ l10_structure = (colocate_pic->structure == BOTTOM_FIELD) ? 1 : 0; } - - //ALLEGRO_FIX, ported from single mode ucode - mby_mbx = READ_VREG(MBY_MBX); - mby = pSlice->first_mb_in_slice / hw->mb_width; - mbx = pSlice->first_mb_in_slice % hw->mb_width; - if (pic->mb_aff_frame_flag) - cur_structure = 3; - else { - if (pic->coded_frame) - cur_structure = 2; - else - cur_structure = (pic->structure == - BOTTOM_FIELD) ? 1 : 0; - } - if (cur_structure < 2) { - //current_field_structure - if (l10_structure != 2) { - colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2; - } else { - // field_ref_from_frame co_mv_rd_addr : - // mby*2*mb_width + mbx - colocate_rd_adr_offset = mby * 2 * hw->mb_width + mbx; - } - - } else { - //current_frame_structure - if (l10_structure < 2) { - //calculate_co_mv_offset_frame_ref_field: - // frame_ref_from_field co_mv_rd_addr : - // (mby/2*mb_width+mbx)*2 - colocate_rd_adr_offset = ((mby / 2) * hw->mb_width + mbx) * 2; - } else if (cur_structure == 2) { - colocate_rd_adr_offset = pSlice->first_mb_in_slice; - } else { - //mbaff frame case1196 - colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2; - } - - } - - colocate_rd_adr_offset *= 96; - if (use_direct_8x8) - colocate_rd_adr_offset >>= 2; - - if (colocate_old_cal) - colocate_rd_adr_offset = colocate_adr_offset; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "first_mb_in_slice 0x%x 0x%x 0x%x (MBY_MBX reg 0x%x) use_direct_8x8 %d cur %d (mb_aff_frame_flag %d, coded_frame %d structure %d) col %d (mb_aff_frame_flag %d, coded_frame %d structure %d) offset 0x%x rdoffset 0x%x\n", - pSlice->first_mb_in_slice, mby, mbx, mby_mbx, use_direct_8x8, - cur_structure, pic->mb_aff_frame_flag, pic->coded_frame, pic->structure, - l10_structure, colocate_pic->mb_aff_frame_flag, colocate_pic->coded_frame, colocate_pic->structure, - colocate_adr_offset, - colocate_rd_adr_offset); - #if 0 /*case0016, p16, *cur_colocate_ref_type should be configured base on current pic @@ -4335,14 +4090,14 @@ * [2:0] will set to 3'b000 */ /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */ - val = ((colocate_rd_adr+colocate_rd_adr_offset) >> 3) | + val = ((colocate_rd_adr+colocate_adr_offset) >> 3) | (l10_structure << 30) | (cur_colocate_ref_type << 29); WRITE_VREG(H264_CO_MB_RD_ADDR, val); dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "co idx %d, WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, addr %x L1(0) pic_structure %d mbaff %d\n", colocate_pic->colocated_buf_index, - val, colocate_rd_adr + colocate_rd_adr_offset, + val, colocate_rd_adr + colocate_adr_offset, colocate_pic->structure, colocate_pic->mb_aff_frame_flag); } else { @@ -4374,7 +4129,7 @@ * [2:0] will set to 3'b000 */ /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */ - val = ((colocate_rd_adr+colocate_rd_adr_offset)>>3) | + val = ((colocate_rd_adr+colocate_adr_offset)>>3) | (l10_structure << 30) | (cur_colocate_ref_type << 29); WRITE_VREG(H264_CO_MB_RD_ADDR, val); dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, @@ -4442,12 +4197,14 @@ struct vframe_s *vf; struct vdec_s *vdec = op_arg; struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; + struct aml_vcodec_ctx * v4l2_ctx; ulong nv_order = VIDTYPE_VIU_NV21; if (!hw) return NULL; + v4l2_ctx = hw->v4l2_ctx; + /* swap uv */ if (hw->is_used_v4l) { if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || @@ -4517,9 +4274,9 @@ if (hw->double_write_mode) { vf->width = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); vf->height = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); + get_double_write_ratio(hw); } } else { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | @@ -4540,7 +4297,7 @@ unsigned int frame_interval = 1000*(time - hw->last_frame_time)/HZ; struct vframe_s *next_vf = NULL; - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); + ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q)); if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL)) { struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; @@ -4552,10 +4309,10 @@ __func__, vf->index); } else { dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms, ts: %lld\n", + "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n", __func__, BUFSPEC_INDEX(vf->index), vf, p_H264_Dpb->mFrameStore[frame_index].poc, - vf->duration, vf->pts, frame_interval, vf->timestamp); + vf->duration, vf->pts, frame_interval); } } if (hw->last_frame_time > 0) { @@ -4565,14 +4322,13 @@ = frame_interval; } hw->last_frame_time = time; - vf->index_disp = atomic_read(&hw->vf_get_count); - atomic_add(1, &hw->vf_get_count); + vf->index_disp = hw->vf_get_count; + hw->vf_get_count++; if (kfifo_peek(&hw->display_q, &next_vf) && next_vf) { vf->next_vf_pts_valid = true; vf->next_vf_pts = next_vf->pts; } else vf->next_vf_pts_valid = false; - return vf; } @@ -4618,24 +4374,6 @@ return; } - if (hw->enable_fence && vf->fence) { - int ret, i; - - mutex_lock(&hw->fence_mutex); - ret = dma_fence_get_status(vf->fence); - if (ret == 0) { - for (i = 0; i < VF_POOL_SIZE; i++) { - if (hw->fence_vf_s.fence_vf[i] == NULL) { - hw->fence_vf_s.fence_vf[i] = vf; - hw->fence_vf_s.used_size++; - mutex_unlock(&hw->fence_mutex); - return; - } - } - } - mutex_unlock(&hw->fence_mutex); - } - buf_spec_num = BUFSPEC_INDEX(vf->index); if (hw->enable_fence) frame_index = hw->buffer_spec[buf_spec_num].fs_idx; @@ -4691,17 +4429,10 @@ } - if (hw->is_used_v4l) { - struct buffer_spec_s *pic = &hw->buffer_spec[buf_spec_num]; - - if (vf->v4l_mem_handle != pic->cma_alloc_addr) - pic->cma_alloc_addr = vf->v4l_mem_handle; - } - - atomic_add(1, &hw->vf_put_count); - if (vf && (vf_valid_check(vf, hw) == true)) { + hw->vf_put_count++; + if (vf_valid_check(vf, hw) == true) { kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); + ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q)); } #define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG @@ -4709,7 +4440,6 @@ WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1); spin_unlock_irqrestore(&hw->bufspec_lock, flags); } - void * vh264_get_bufspec_lock(struct vdec_s *vdec) { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; @@ -4730,7 +4460,7 @@ int buf_spec_num; if (!req->vf) { - req->aux_size = atomic_read(&hw->vf_put_count); + req->aux_size = hw->vf_put_count; return 0; } buf_spec_num = BUFSPEC_INDEX(req->vf->index); @@ -4793,7 +4523,6 @@ } } else vf->signal_type = 0; - hw->video_signal_type = vf->signal_type; vf->width = hw->frame_width; vf->height = hw->frame_height; @@ -4823,11 +4552,9 @@ #endif if (IS_VDEC_DW(hw)) { - if (IS_VDEC_DW(hw) == 1) - vf->width = hw->frame_width / 2; - else - vf->width = (hw->frame_width / IS_VDEC_DW(hw)); - vf->height = (hw->frame_height / IS_VDEC_DW(hw)); + vf->width = (hw->frame_width /2); + if (IS_VDEC_DW(hw) == 2) + vf->height = (hw->frame_height /2); p_canvas_config = &hw->buffer_spec[index].vdec_dw_canvas_config[0]; } else p_canvas_config = &hw->buffer_spec[index].canvas_config[0]; @@ -5320,68 +5047,11 @@ size = size_vui; } - size += 2; /* need two more buffer */ + size += 1; /* need one more buffer */ return size; } -static int get_dec_dpb_size_active(struct vdec_h264_hw_s *hw, u32 param1) -{ -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - struct vdec_s *vdec = hw_to_vdec(hw); -#endif - int mb_width, mb_total; - int mb_height = 0; - int active_buffer_spec_num, dec_dpb_size; - u32 used_reorder_dpb_size_margin - = hw->reorder_dpb_size_margin; - - mb_width = param1 & 0xff; - mb_total = (param1 >> 8) & 0xffff; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - if (mb_width) - mb_height = mb_total/mb_width; - if (mb_width <= 0 || mb_height <= 0 || - is_oversize(mb_width << 4, mb_height << 4)) { - dpb_print(DECODE_ID(hw), 0, - "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", - param1, - mb_width, - mb_height); - hw->error_frame_width = mb_width << 4; - hw->error_frame_height = mb_height << 4; - return -1; - } - hw->error_frame_width = 0; - hw->error_frame_height = 0; - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (vdec->master || vdec->slave) - used_reorder_dpb_size_margin = - reorder_dpb_size_margin_dv; -#endif - - dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height); - - active_buffer_spec_num = - dec_dpb_size - + used_reorder_dpb_size_margin; - - if (active_buffer_spec_num > MAX_VF_BUF_NUM) { - active_buffer_spec_num = MAX_VF_BUF_NUM; - dec_dpb_size = active_buffer_spec_num - - used_reorder_dpb_size_margin; - } - - hw->dpb.mDPB.size = active_buffer_spec_num; - - if (hw->no_poc_reorder_flag) - dec_dpb_size = 1; - - return dec_dpb_size; -} - static void vh264_config_canvs_for_mmu(struct vdec_h264_hw_s *hw) { int i, j; @@ -5419,7 +5089,6 @@ unsigned int used_reorder_dpb_size_margin = hw->reorder_dpb_size_margin; u8 *colocate_vaddr = NULL; - int dec_dpb_size_change = 0; #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (vdec->master || vdec->slave) @@ -5438,7 +5107,7 @@ if (mb_width <= 0 || mb_height <= 0 || is_oversize(mb_width << 4, mb_height << 4)) { dpb_print(DECODE_ID(hw), 0, - "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", + "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x)\r\n", seq_info2, mb_width, mb_height); @@ -5449,28 +5118,11 @@ hw->error_frame_width = 0; hw->error_frame_height = 0; - dec_dpb_size_change = hw->csd_change_flag && (hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1)); - - if (((seq_info2 != 0 && - hw->seq_info2 != seq_info2) || hw->csd_change_flag) && + if (seq_info2 != 0 && + hw->seq_info2 != seq_info2 && hw->seq_info2 != 0 - ) { - if (hw->seq_info2 != seq_info2 || dec_dpb_size_change) { /*picture size changed*/ - h264_reconfig(hw); - } else { - /*someting changes and not including dpb_size, width, height, ...*/ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - u32 reg_val = param4; - max_reference_size = (reg_val >> 8) & 0xff; - hw->dpb.reorder_output = max_reference_size; - - if (p_H264_Dpb->bitstream_restriction_flag && - p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering && - p_H264_Dpb->num_reorder_frames >= 0) { - hw->dpb.reorder_output = hw->num_reorder_frames + 1; - } - } - } + ) /*picture size changed*/ + h264_reconfig(hw); if (hw->config_bufmgr_done == 0) { struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; @@ -5492,8 +5144,7 @@ p_H264_Dpb->fast_output_enable = fast_output_enable; /*mb_mv_byte = (seq_info2 & 0x80000000) ? 24 : 96;*/ - if (hw->enable_fence) - p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST; + #if 1 /*crop*/ /* AV_SCRATCH_2 @@ -5579,6 +5230,10 @@ hevc_mcr_sao_global_hw_init(hw, (hw->mb_width << 4), (hw->mb_height << 4)); + reg_val = param4; + level_idc = reg_val & 0xff; + max_reference_size = (reg_val >> 8) & 0xff; + hw->dpb.reorder_output = max_reference_size; dpb_print(DECODE_ID(hw), 0, "mb height/widht/total: %x/%x/%x level_idc %x max_ref_num %x\n", mb_height, mb_width, mb_total, @@ -5595,6 +5250,11 @@ used_reorder_dpb_size_margin); if (p_H264_Dpb->bitstream_restriction_flag && + p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering) { + hw->dpb.reorder_output = hw->num_reorder_frames + 1; + } + + if (p_H264_Dpb->bitstream_restriction_flag && p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering && p_H264_Dpb->num_reorder_frames >= 0) { hw->dpb.reorder_output = hw->num_reorder_frames + 1; @@ -6079,19 +5739,13 @@ ((p_H264_Dpb->mDPB.used_size >= (p_H264_Dpb->mDPB.size - 1)) || (!have_free_buf_spec(vdec)))) { - unsigned long flags; - spin_lock_irqsave(&hw->bufspec_lock, flags); + bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); for (i = 0; i < p_Dpb->used_size; i++) { if (p_Dpb->fs[i]->pre_output) frame_outside_count++; - else if (p_Dpb->fs[i]->is_output && !is_used_for_reference(p_Dpb->fs[i])) { - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); - return 0; - } } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); + inner_size = p_Dpb->size - frame_outside_count; if (inner_size >= p_H264_Dpb->dec_dpb_size) { @@ -6105,7 +5759,6 @@ } } } - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); } else if ((error_proc_policy & 0x8) && (p_Dpb->ref_frames_in_buffer > (imax( @@ -6118,11 +5771,10 @@ if (hw->reset_bufmgr_flag == 1) buffer_available = 1; + else if (hw->is_used_v4l) + buffer_available = have_free_buf_spec(vdec); } - if (hw->is_used_v4l) - buffer_available = have_free_buf_spec(vdec); - return buffer_available; } @@ -6348,11 +6000,8 @@ mb_width = 256; decode_mb_count = ((mby_mbx & 0xff) * mb_width + (((mby_mbx >> 8) & 0xff) + 1)); - if ((mby_mbx == 0) && (p_H264_Dpb->dec_dpb_status != H264_SLICE_HEAD_DONE)) { - dpb_print(DECODE_ID(hw), 0, - "mby_mbx is zero\n"); + if (mby_mbx == 0) return; - } if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME) mb_total /= 2; @@ -6361,11 +6010,11 @@ p->data_flag |= ERROR_FLAG; } - if (error_proc_policy & 0x100 && !(p->data_flag & ERROR_FLAG)) { + if (error_proc_policy & 0x100) { if (decode_mb_count < mb_total) { p->data_flag |= ERROR_FLAG; - if (((error_proc_policy & 0x20000) && - decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100)) { + if ((error_proc_policy & 0x20000) && + decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100) { p->data_flag &= ~ERROR_FLAG; } } @@ -6556,7 +6205,6 @@ p_H264_Dpb->mVideo.dec_picture->data_flag); - if (ret == -1) { release_cur_decoding_buf(hw); bufmgr_force_recover(p_H264_Dpb); @@ -6601,6 +6249,61 @@ return 0; } +#ifdef VDEC_FCC_SUPPORT +static void fcc_discard_mode_process(struct vdec_s *vdec) +{ + struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); + struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; + + if (vdec->fcc_status == AGAIN_STATUS) { + vdec->stream_offset = (p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_LO] | + p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_HI] << 16); + dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Notify stream_offset: %d\n", + vdec->id, vdec->stream_offset); + vdec_wakeup_fcc_poll(vdec); + amvdec_stop(); + vdec->mc_loaded = 0; + hw->init_flag = 0; + vdec->fcc_status = WAIT_MSG_STATUS; + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } else if (vdec->fcc_status == DISCARD_STATUS) { + dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Discard current gop and to find next gop!\n", + vdec->id); + amvdec_stop(); + vdec->mc_loaded = 0; + hw->init_flag = 0; + vdec->fcc_status = AGAIN_STATUS; + hw->dec_result = DEC_RESULT_DISCARD_DATA; + vdec_schedule_work(&hw->work); + } +} + +static int vh264_fcc_process(struct vdec_s *vdec) +{ + struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); + + if (input_stream_based(vdec)) { + switch (vdec->fcc_mode) { + case FCC_DISCARD_MODE: + fcc_discard_mode_process(vdec); + return 1; + case FCC_DEC_MODE: + dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Current is Dec mode.\n", vdec->id); + break; + case FCC_BUTT: + default: + break; + } + } + + return 0; +} +#endif + static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) { int i; @@ -6609,18 +6312,6 @@ unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status; u32 debug_tag; - if (dec_dpb_status == H264_SLICE_HEAD_DONE || - p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START); - } - else if (dec_dpb_status == H264_PIC_DATA_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START); - } - else if (dec_dpb_status == H264_SEI_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_SEI_START); - else if (dec_dpb_status == H264_AUX_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_AUX_START); - if (dec_dpb_status == H264_CONFIG_REQUEST) { #if 1 unsigned short *p = (unsigned short *)hw->lmem_addr; @@ -6645,13 +6336,7 @@ } } } - if (p_H264_Dpb->bitstream_restriction_flag != - ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "p_H264_Dpb->bitstream_restriction_flag 0x%x, new 0x%x\n", - p_H264_Dpb->bitstream_restriction_flag, ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)); - hw->csd_change_flag = 1; - } + p_H264_Dpb->bitstream_restriction_flag = (p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1; p_H264_Dpb->num_reorder_frames = @@ -6678,7 +6363,7 @@ p_H264_Dpb->frame_crop_top_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_top_offset; p_H264_Dpb->frame_crop_bottom_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_bottom_offset; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, + dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, "%s chroma_format_idc %d crop offset: left %d right %d top %d bottom %d\n", __func__, p_H264_Dpb->chroma_format_idc, p_H264_Dpb->frame_crop_left_offset, @@ -6687,6 +6372,11 @@ p_H264_Dpb->frame_crop_bottom_offset); #endif +#ifdef VDEC_FCC_SUPPORT + if (vh264_fcc_process(vdec) > 0) + return IRQ_HANDLED; +#endif + WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE); reset_process_time(hw); hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); @@ -6706,7 +6396,6 @@ hw->multi_slice_pic_flag = 0; hw->picture_slice_count = 0; #endif - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); vdec_schedule_work(&hw->work); } else if (dec_dpb_status == H264_SLICE_HEAD_DONE) { u16 data_hight; @@ -6722,27 +6411,18 @@ unsigned mb_width = hw->seq_info2 & 0xff; unsigned short first_mb_in_slice; unsigned int decode_mb_count, mby_mbx; - struct StorablePicture *pic = p_H264_Dpb->mVideo.dec_picture; reset_process_time(hw); - hw->frmbase_cont_flag = 0; - - if ((pic != NULL) && (pic->mb_aff_frame_flag == 1)) - first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3] * 2; - else - first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3]; #ifdef DETECT_WRONG_MULTI_SLICE hw->cur_picture_slice_count++; - - if ((error_proc_policy & 0x10000) && - (hw->cur_picture_slice_count > 1) && - (first_mb_in_slice == 0) && - (hw->multi_slice_pic_flag == 0)) - hw->multi_slice_pic_check_count = 0; - - if ((error_proc_policy & 0x10000) && - (hw->cur_picture_slice_count > 1) && - (hw->multi_slice_pic_flag == 1)) { + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count == 1 && + (error_proc_policy & 0x10000)) { + hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num; + } + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count > 1 && + (error_proc_policy & 0x10000)) { dpb_print(DECODE_ID(hw), 0, "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n", __func__, @@ -6751,6 +6431,7 @@ hw->cur_picture_slice_count, hw->multi_slice_pic_flag); + first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3]; mby_mbx = READ_VREG(MBY_MBX); decode_mb_count = ((mby_mbx & 0xff) * mb_width + (((mby_mbx >> 8) & 0xff) + 1)); @@ -6763,19 +6444,8 @@ hw->multi_slice_pic_flag = 0; hw->multi_slice_pic_check_count = 0; - } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count) { + } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count) vh264_pic_done_proc(vdec); - //if (p_H264_Dpb->mDPB.used_size == p_H264_Dpb->mDPB.size) { - if (!have_free_buf_spec(vdec)) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "dpb full, wait buffer\n"); - p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num; - hw->last_picture_slice_count = hw->cur_picture_slice_count; - hw->no_decoder_buffer_flag = 1; - hw->dec_result = DEC_RESULT_AGAIN; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } else { if (p_H264_Dpb->mVideo.dec_picture) { if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) { @@ -6842,9 +6512,6 @@ } #else dpb_param_bak = p_H264_Dpb->dpb_param; - - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_START); - for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { int ii; @@ -6867,7 +6534,6 @@ } } } - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_END); #endif #ifdef DETECT_WRONG_MULTI_SLICE @@ -7006,9 +6672,6 @@ else p_H264_Dpb->fast_output_enable = fast_output_enable; - if (hw->enable_fence) - p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST; - hw->data_flag = I_flag; if ((p_H264_Dpb-> dpb_param.dpb.NAL_info_mmco & 0x1f) @@ -7050,15 +6713,13 @@ }*/ } - if (!I_flag && frame_num_gap && !p_H264_Dpb->long_term_reference_flag) { - if (!(error_proc_policy & 0x800000)) { - hw->data_flag |= ERROR_FLAG; - p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), 0, "frame number gap error\n"); - } + if (!I_flag && frame_num_gap) { + hw->data_flag |= ERROR_FLAG; + p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; + dpb_print(DECODE_ID(hw), 0, "frame number gap error\n"); } - if ((error_proc_policy & 0x400) && !hw->enable_fence) { + if (error_proc_policy & 0x400) { int ret = dpb_check_ref_list_error(p_H264_Dpb); if (ret != 0) { hw->reflist_error_count ++; @@ -7101,10 +6762,9 @@ return IRQ_HANDLED; } } - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_START); + cfg_ret = config_decode_buf(hw, p_H264_Dpb->mVideo.dec_picture); - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_END); if (cfg_ret < 0) { dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, "config_decode_buf fail (%d)\n", @@ -7122,12 +6782,11 @@ } } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); - - if (slice_header_process_status == 1) + if (slice_header_process_status == 1) { WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_NEWPIC); - else + } else { WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_SLICE); + } hw->last_mby_mbx = 0; hw->last_vld_level = 0; start_process_time(hw); @@ -7162,16 +6821,6 @@ pic_done_proc: reset_process_time(hw); - if ((dec_dpb_status == H264_SEARCH_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_TIMEOUT) || - ((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) { - hw->data_flag |= ERROR_FLAG; - if (hw->dpb.mVideo.dec_picture) - hw->dpb.mVideo.dec_picture->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s, mark err_frame\n", __func__); - } vh264_pic_done_proc(vdec); if (hw->frmbase_cont_flag) { @@ -7223,7 +6872,6 @@ hw->got_valid_nal = 1; } #endif - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); hw->dec_result = DEC_RESULT_DONE; vdec_schedule_work(&hw->work); @@ -7238,7 +6886,7 @@ reset_process_time(hw); if (READ_VREG(H264_AUX_DATA_SIZE) != 0) { if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) + PRINT_FLAG_DPB_DETAIL)) dump_aux_buf(hw); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (vdec_frame_based(vdec)) { @@ -7276,7 +6924,6 @@ #endif dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s H264_AUX_DATA_READY\n", __func__); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); hw->dec_result = DEC_RESULT_DONE; vdec_schedule_work(&hw->work); } else if (/*(dec_dpb_status == H264_DATA_REQUEST) ||*/ @@ -7286,8 +6933,7 @@ empty_proc: reset_process_time(hw); if ((error_proc_policy & 0x40000) && - ((dec_dpb_status == H264_DECODE_TIMEOUT) || - (!hw->frmbase_cont_flag && (dec_dpb_status == H264_SEARCH_BUFEMPTY || dec_dpb_status == H264_DECODE_BUFEMPTY) && input_frame_based(vdec)))) + dec_dpb_status == H264_DECODE_TIMEOUT) goto pic_done_proc; if (!hw->frmbase_cont_flag) release_cur_decoding_buf(hw); @@ -7328,7 +6974,7 @@ (p_H264_Dpb->mSlice.slice_type != B_SLICE))) { dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, "%s last dpb status 0x%x need bugmgr reset \n", - p_H264_Dpb->last_dpb_status, __func__); + __func__, p_H264_Dpb->last_dpb_status); hw->reset_bufmgr_flag = 1; } } @@ -7341,7 +6987,9 @@ } else { /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */ #ifdef DETECT_WRONG_MULTI_SLICE - if (error_proc_policy & 0x10000) { + if (hw->multi_slice_pic_flag == 1 && + hw->cur_picture_slice_count > 1 && + (error_proc_policy & 0x10000)) { p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num; } hw->last_picture_slice_count = hw->cur_picture_slice_count; @@ -7438,7 +7086,6 @@ left_len); } } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); WRITE_VREG(DPB_STATUS_REG, H264_SEI_DATA_DONE); return IRQ_HANDLED; @@ -7519,17 +7166,6 @@ p_H264_Dpb->vdec = vdec; p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG); - if (p_H264_Dpb->dec_dpb_status == H264_SLICE_HEAD_DONE || - p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE); - } - else if (p_H264_Dpb->dec_dpb_status == H264_PIC_DATA_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE); - } - else if (p_H264_Dpb->dec_dpb_status == H264_SEI_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_SEI_DONE); - else if (p_H264_Dpb->dec_dpb_status == H264_AUX_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_AUX_DONE); dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, "%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n", @@ -7550,7 +7186,6 @@ WRITE_VREG(DPB_STATUS_REG, H264_WRRSP_DONE); return IRQ_HANDLED; } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END); return IRQ_WAKE_THREAD; } @@ -7571,6 +7206,7 @@ pr_err("%s h264[%d] work pending, do nothing.\n",__func__, vdec->id); return; } + hw->timeout_num++; amvdec_stop(); vdec->mc_loaded = 0; @@ -7579,7 +7215,7 @@ hevc_sao_wait_done(hw); } dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, "%s decoder timeout, DPB_STATUS_REG 0x%x\n", __func__, READ_VREG(DPB_STATUS_REG)); + PRINT_FLAG_ERROR, "%s decoder timeout\n", __func__); release_cur_decoding_buf(hw); hw->dec_result = DEC_RESULT_TIMEOUT; hw->data_flag |= ERROR_FLAG; @@ -7625,7 +7261,7 @@ dpb_print(DECODE_ID(hw), 0, "====== %s\n", __func__); dpb_print(DECODE_ID(hw), 0, - "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d video_signal_type 0x%x send_err %d \n", + "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d send_err %d\n", hw->frame_width, hw->frame_height, hw->num_reorder_frames, @@ -7633,7 +7269,6 @@ hw->dpb.mDPB.size, hw->max_reference_size, hw->i_only, - hw->video_signal_type, hw->send_error_frame_flag ); @@ -7661,7 +7296,9 @@ hw->cur_picture_slice_count, hw->multi_slice_pic_flag); #endif - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + + + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -7767,10 +7404,9 @@ } -static void check_timer_func(struct timer_list *timer) +static void check_timer_func(unsigned long arg) { - struct vdec_h264_hw_s *hw = container_of(timer, - struct vdec_h264_hw_s, check_timer); + struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); int error_skip_frame_count = error_skip_count & 0xfff; unsigned int timeout_val = decode_timeout_val; @@ -7824,9 +7460,7 @@ if ((dpb_status == H264_ACTION_DECODE_NEWPIC) || (dpb_status == H264_ACTION_DECODE_SLICE) || (dpb_status == H264_SEI_DATA_DONE) || - (dpb_status == H264_STATE_SEARCH_HEAD) || - (dpb_status == H264_SLICE_HEAD_DONE) || - (dpb_status == H264_SEI_DATA_READY)) { + (dpb_status == H264_STATE_SEARCH_HEAD)) { if (h264_debug_flag & DEBUG_TIMEOUT_DEC_STAT) pr_debug("%s dpb_status = 0x%x last_mby_mbx = %u mby_mbx = %u\n", __func__, dpb_status, hw->last_mby_mbx, mby_mbx); @@ -7927,7 +7561,6 @@ int i, j; struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - hw->frmbase_cont_flag = 0; /* if (hw->init_flag == 0) { */ if (h264_debug_flag & 0x40000000) { /* if (1) */ @@ -8019,14 +7652,12 @@ #endif #ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw)) { - u32 data = ((1 << 30) |(1 << 0) |(1 << 8)); + if (IS_VDEC_DW(hw)) { + u32 data = ((1 << 30) |(1 << 0) |(1 << 8)); - if (IS_VDEC_DW(hw) == 2) - data |= (1 << 9); - WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/ - } + if (IS_VDEC_DW(hw) == 2) + data |= (1 << 9); + WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/ } #endif if (hw->dpb.mDPB.size > 0) { @@ -8052,8 +7683,9 @@ if (hw->init_flag == 0) WRITE_VREG(DPB_STATUS_REG, 0); - else + else { WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_START); + } WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count); WRITE_VREG(AV_SCRATCH_8, hw->buf_offset); @@ -8222,7 +7854,10 @@ /* init_timer(&hw->recycle_timer); */ /* timer init */ - timer_setup(&hw->check_timer, check_timer_func, 0); + init_timer(&hw->check_timer); + + hw->check_timer.data = (unsigned long)hw; + hw->check_timer.function = check_timer_func; hw->check_timer.expires = jiffies + CHECK_INTERVAL; /* add_timer(&hw->check_timer); */ @@ -8358,13 +7993,13 @@ return -1; } - hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL); + hw->sei_data_buf = vzalloc(SEI_DATA_SIZE); if (hw->sei_data_buf == NULL) { pr_err("%s: failed to alloc sei itu data buffer\n", __func__); return -1; } - hw->sei_itu_data_buf = kmalloc(SEI_ITU_DATA_SIZE, GFP_KERNEL); + hw->sei_itu_data_buf = vzalloc(SEI_ITU_DATA_SIZE); if (hw->sei_itu_data_buf == NULL) { pr_err("%s: failed to alloc sei itu data buffer\n", __func__); @@ -8372,15 +8007,14 @@ hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, hw->aux_phy_addr); hw->aux_addr = NULL; - kfree(hw->sei_data_buf); + vfree(hw->sei_data_buf); hw->sei_data_buf = NULL; return -1; } if (NULL == hw->sei_user_data_buffer) { - hw->sei_user_data_buffer = kmalloc(USER_DATA_SIZE, - GFP_KERNEL); + hw->sei_user_data_buffer = vzalloc(USER_DATA_SIZE); if (!hw->sei_user_data_buffer) { pr_info("%s: Can not allocate sei_data_buffer\n", __func__); @@ -8388,9 +8022,9 @@ hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, hw->aux_phy_addr); hw->aux_addr = NULL; - kfree(hw->sei_data_buf); + vfree(hw->sei_data_buf); hw->sei_data_buf = NULL; - kfree(hw->sei_itu_data_buf); + vfree(hw->sei_itu_data_buf); hw->sei_itu_data_buf = NULL; return -1; @@ -8416,7 +8050,6 @@ } #ifdef VDEC_DW WRITE_VREG(MDEC_DOUBLEW_CFG0, 0); - WRITE_VREG(MDEC_DOUBLEW_CFG1, 0); #endif #ifdef MH264_USERDATA_ENABLE cancel_work_sync(&hw->user_data_ready_work); @@ -8425,6 +8058,7 @@ cancel_work_sync(&hw->timeout_work); cancel_work_sync(&hw->work); + if (hw->stat & STAT_MC_LOAD) { if (hw->mc_cpu_addr != NULL) { dma_free_coherent(amports_get_dma_device(), @@ -8458,15 +8092,15 @@ hw->aux_addr = NULL; } if (hw->sei_data_buf != NULL) { - kfree(hw->sei_data_buf); + vfree(hw->sei_data_buf); hw->sei_data_buf = NULL; } if (hw->sei_itu_data_buf != NULL) { - kfree(hw->sei_itu_data_buf); + vfree(hw->sei_itu_data_buf); hw->sei_itu_data_buf = NULL; } if (hw->sei_user_data_buffer != NULL) { - kfree(hw->sei_user_data_buffer); + vfree(hw->sei_user_data_buffer); hw->sei_user_data_buffer = NULL; } /* amvdec_disable(); */ @@ -8509,10 +8143,6 @@ struct vdec_h264_hw_s *hw = container_of(work, struct vdec_h264_hw_s, notify_work); struct vdec_s *vdec = hw_to_vdec(hw); - - if (hw->is_used_v4l) - return; - if (vdec->fr_hint_state == VDEC_NEED_HINT) { vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_FR_HINT, @@ -8807,7 +8437,7 @@ static int vmh264_init_userdata_dump(void) { - user_data_buf = kmalloc(MAX_USER_DATA_SIZE, GFP_KERNEL); + user_data_buf = vzalloc(MAX_USER_DATA_SIZE); if (user_data_buf) return 1; else @@ -8818,7 +8448,7 @@ { if (user_data_buf) { show_user_data_buf(); - kfree(user_data_buf); + vfree(user_data_buf); user_data_buf = NULL; } } @@ -9180,7 +8810,7 @@ if (mb_width <= 0 || mb_height <= 0 || is_oversize(mb_width << 4, mb_height << 4)) { dpb_print(DECODE_ID(hw), 0, - "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", + "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x)\r\n", param1, mb_width, mb_height); @@ -9211,8 +8841,6 @@ - used_reorder_dpb_size_margin; } - hw->dpb.mDPB.size = active_buffer_spec_num; - if (hw->no_poc_reorder_flag) dec_dpb_size = 1; @@ -9222,7 +8850,6 @@ * bit 15: frame_mbs_only_flag * bit 13-14: chroma_format_idc */ - hw->seq_info = param2; frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01; if (hw->dpb.mSPS.profile_idc != 100 && hw->dpb.mSPS.profile_idc != 110 && @@ -9281,8 +8908,9 @@ ps->visible_height = frame_height; ps->coded_width = ALIGN(mb_width << 4, 64); ps->coded_height = ALIGN(mb_height << 4, 64); - ps->dpb_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */ + ps->reorder_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */ ps->dpb_size = active_buffer_spec_num; + ps->field = frame_mbs_only_flag ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED; return 0; } @@ -9295,36 +8923,34 @@ (struct aml_vcodec_ctx *)(hw->v4l2_ctx); struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; int ret = 0; - int dec_dpb_size_change = hw->csd_change_flag && (hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1)); if (ctx->param_sets_from_ucode && hw->res_ch_flag == 0) { - if (((param1 != 0 && - hw->seq_info2 != param1) || hw->csd_change_flag) && - hw->seq_info2 != 0) { - if (hw->seq_info2 != param1 || dec_dpb_size_change) { /*picture size changed*/ - struct aml_vdec_ps_infos ps; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "h264 res_change\n"); - if (vmh264_get_ps_info(hw, param1, - param2, param3, param4, &ps) < 0) { - dpb_print(DECODE_ID(hw), 0, - "set parameters error\n"); - } - hw->v4l_params_parsed = false; - vdec_v4l_set_ps_infos(ctx, &ps); - vdec_v4l_res_ch_event(ctx); - hw->res_ch_flag = 1; - ctx->v4l_resolution_change = 1; - amvdec_stop(); - if (hw->mmu_enable) - amhevc_stop(); - hw->eos = 1; - flush_dpb(p_H264_Dpb); - //del_timer_sync(&hw->check_timer); - notify_v4l_eos(hw_to_vdec(hw)); - ret = 1; + if (param1 != 0 && + hw->seq_info2 != param1 && + hw->seq_info2 != 0) /*picture size changed*/ { + struct aml_vdec_ps_infos ps; + dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, + "h264 res_change\n"); + if (vmh264_get_ps_info(hw, param1, + param2, param3, param4, &ps) < 0) { + dpb_print(DECODE_ID(hw), 0, + "set parameters error\n"); } + hw->v4l_params_parsed = false; + vdec_v4l_set_ps_infos(ctx, &ps); + vdec_v4l_res_ch_event(ctx); + hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; + amvdec_stop(); + if (hw->mmu_enable) + amhevc_stop(); + hw->eos = 1; + flush_dpb(p_H264_Dpb); + //del_timer_sync(&hw->check_timer); + if (hw->is_used_v4l) + notify_v4l_eos(hw_to_vdec(hw)); + ret = 1; } } @@ -9363,13 +8989,6 @@ /* finished decoding one frame or error, * notify vdec core to switch context */ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - if (hw->dec_result == DEC_RESULT_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START); - } else if (hw->dec_result == DEC_RESULT_AGAIN) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN); - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, "%s dec_result %d %x %x %x\n", __func__, @@ -9397,6 +9016,7 @@ if (!v4l_res_change(hw, param1, param2, param3, param4)) { if (!hw->v4l_params_parsed) { struct aml_vdec_ps_infos ps; + dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "h264 parsered csd data\n"); @@ -9546,6 +9166,7 @@ return; } else if (hw->dec_result == DEC_RESULT_DONE || hw->dec_result == DEC_RESULT_TIMEOUT) { + /* if (!hw->ctx_valid) hw->ctx_valid = 1; */ hw->dec_again_cnt = 0; @@ -9566,7 +9187,7 @@ for (i = 0; i < p_Dpb->used_size; i++) { int i_flag = p_Dpb->fs[i]->bottom_field || p_Dpb->fs[i]->top_field; - int threshold = (i_flag || (hw->max_reference_size >= 12)) ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size; + int threshold = i_flag ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size; if ((p_Dpb->fs[i]->dpb_frame_count + threshold < p_H264_Dpb->dpb_frame_count) && p_Dpb->fs[i]->is_reference && @@ -9610,7 +9231,17 @@ hw->gvs.b_decoded_frames++; } amvdec_stop(); - + if (!vdec_is_support_4k()) { + if (clk_adj_frame_count < VDEC_CLOCK_ADJUST_FRAME) { + clk_adj_frame_count++; + if (clk_adj_frame_count == VDEC_CLOCK_ADJUST_FRAME) { + if (hw->frame_height <= 144) + vdec_source_changed(VFORMAT_H264, 1920, 1080, 29); + else + vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); + } + } + } dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s dec_result %d %x %x %x\n", __func__, @@ -9628,12 +9259,11 @@ frame base: vdec_prepare_input fail */ if (!vdec_has_more_input(vdec) && (hw_to_vdec(hw)->next_status != - VDEC_STATUS_DISCONNECTED) && (hw->no_decoder_buffer_flag == 0)) { + VDEC_STATUS_DISCONNECTED)) { hw->dec_result = DEC_RESULT_EOS; vdec_schedule_work(&hw->work); return; } - if ((vdec_stream_based(vdec)) && (error_proc_policy & 0x400000) && check_dirty_data(vdec)) { @@ -9641,7 +9271,6 @@ vdec_schedule_work(&hw->work); return; } - hw->no_decoder_buffer_flag = 0; hw->next_again_flag = 1; } else if (hw->dec_result == DEC_RESULT_EOS) { struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; @@ -9670,14 +9299,12 @@ vdec_free_irq(VDEC_IRQ_1, (void *)hw); hw->stat &= ~STAT_ISR_REG; } + } else if (hw->dec_result == DEC_RESULT_DISCARD_DATA) { + mutex_lock(&hw->chunks_mutex); + vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); + hw->chunk = NULL; + mutex_unlock(&hw->chunks_mutex); } - - if (p_H264_Dpb->mVideo.dec_picture) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, release decoded picture\n", __func__); - release_cur_decoding_buf(hw); - } - WRITE_VREG(ASSIST_MBOX1_MASK, 0); del_timer_sync(&hw->check_timer); hw->stat &= ~STAT_TIMER_ARM; @@ -9685,9 +9312,7 @@ if (hw->dec_result != DEC_RESULT_AGAIN) hw->last_picture_slice_count = 0; #endif - ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START); wait_vmh264_search_done(hw); - ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END); /* mark itself has all HW resource released and input released */ #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -9710,9 +9335,6 @@ return; } } - if (hw->dec_result == DEC_RESULT_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END); - } /* mark itself has all HW resource released and input released */ if (vdec->parallel_dec == 1) { @@ -9760,8 +9382,16 @@ hw->timeout_processing = 1; vh264_work_implement(hw, vdec, 1); + } +#ifdef VDEC_FCC_SUPPORT +static void vmh264_wakeup_fcc_poll(struct vdec_s *vdec) +{ + amstream_wakeup_fcc_poll(vdec); +} +#endif + static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { bool ret = 0; @@ -9769,6 +9399,9 @@ (struct vdec_h264_hw_s *)vdec->private; int tvp = vdec_secure(hw_to_vdec(hw)) ? CODEC_MM_FLAGS_TVP : 0; +#ifdef VDEC_FCC_SUPPORT + int get_msg = 1; +#endif if (hw->timeout_processing && (work_pending(&hw->work) || work_busy(&hw->work) || @@ -9841,7 +9474,7 @@ ret = is_buffer_available(vdec); #ifdef CONSTRAIN_MAX_BUF_NUM - if (ret && (hw->dpb.mDPB.size > 0)) { /*make sure initilized*/ + if (hw->dpb.mDPB.size > 0) { /*make sure initilized*/ if (run_ready_max_vf_only_num > 0 && get_vf_ref_only_buf_count(hw) >= run_ready_max_vf_only_num @@ -9854,15 +9487,12 @@ /*avoid more buffers consumed when switching resolution*/ if (run_ready_max_buf_num == 0xff && - get_used_buf_count(hw) > - hw->dpb.mDPB.size) + !have_free_buf_spec(vdec)) ret = 0; else if (run_ready_max_buf_num && get_used_buf_count(hw) >= run_ready_max_buf_num) ret = 0; - if (ret == 0) - bufmgr_h264_remove_unused_frame(&hw->dpb, 0); } #endif if (hw->is_used_v4l) { @@ -9871,12 +9501,13 @@ if (ctx->param_sets_from_ucode) { if (hw->v4l_params_parsed) { - if (ctx->cap_pool.dec < hw->dpb.mDPB.size) { - if (is_buffer_available(vdec)) - ret = 1; - else - ret = 0; - } + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; + else if (ctx->v4l_codec_dpb_ready && + !is_buffer_available(vdec)) + ret = 0; } else { if (ctx->v4l_resolution_change) ret = 0; @@ -9886,12 +9517,19 @@ run_ready_min_buf_num) ret = 0; } + } +#ifdef VDEC_FCC_SUPPORT + get_msg = vdec_has_get_fcc_new_msg(vdec); + ret &= get_msg; +#endif + if (ret) not_run_ready[DECODE_ID(hw)] = 0; else not_run_ready[DECODE_ID(hw)]++; + if (vdec->parallel_dec == 1) { if (hw->mmu_enable == 0) return ret ? (CORE_MASK_VDEC_1) : 0; @@ -9936,8 +9574,6 @@ if (hw->mmu_enable) amhevc_enable(); } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START); - run_count[DECODE_ID(hw)]++; vdec_reset_core(vdec); if (hw->mmu_enable) @@ -9966,7 +9602,6 @@ ((error_proc_policy & 0x40) && p_H264_Dpb->buf_alloc_fail)) { h264_reset_bufmgr(vdec); - //flag must clear after reset for v4l buf_spec_init use hw->reset_bufmgr_flag = 0; } @@ -9998,7 +9633,6 @@ hw->dec_result = DEC_RESULT_NONE; hw->get_data_count = 0; - hw->csd_change_flag = 0; #if 0 pr_info("VLD_MEM_VIFIFO_LEVEL = 0x%x, rp = 0x%x, wp = 0x%x\n", READ_VREG(VLD_MEM_VIFIFO_LEVEL), @@ -10068,7 +9702,7 @@ */ WRITE_VREG(AV_SCRATCH_G, hw->reg_g_status); } else { - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START); + ret = amvdec_vdec_loadmc_ex(VFORMAT_H264, "mh264", vdec, hw->fw->data); if (ret < 0) { amvdec_enable_flag = false; @@ -10099,18 +9733,13 @@ vdec->mc_type = ((1 << 16) | VFORMAT_H264); } vdec->mc_loaded = 0; - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END); } vmh264_reset_udr_mgr(hw); - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START); + if (vh264_hw_ctx_restore(hw) < 0) { vdec_schedule_work(&hw->work); return; } - if (error_proc_policy & 0x10000) { - hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num; - } - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END); if (input_frame_based(vdec)) { int decode_size = 0; @@ -10144,14 +9773,12 @@ WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) & (~0x2)); } - WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | (1 << 2) | (hw->bitstream_restriction_flag << 15)); - + WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | (1 << 2)); if (udebug_flag) WRITE_VREG(AV_SCRATCH_K, udebug_flag); - hw->stat |= STAT_TIMER_ARM; mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) { if (hw->mmu_enable) SET_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3); @@ -10176,7 +9803,6 @@ /* } */ hw->init_flag = 1; - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END); } static void clear_refer_bufs(struct vdec_h264_hw_s *hw) @@ -10293,12 +9919,6 @@ hw->buffer_spec[i].used = 4; hw->buffer_spec[i].canvas_pos = -1; - - if (hw->buffer_spec[i].used == 4 && - hw->buffer_spec[i].vf_ref != 0 && - hw->buffer_spec[i].cma_alloc_addr) { - hw->buffer_spec[i].used = 3; - } } spin_unlock_irqrestore(&hw->bufspec_lock, flags); hw->has_i_frame = 0; @@ -10394,15 +10014,15 @@ __func__, hw->decode_pic_count+1, hw->skip_frame_count); - flush_dpb(&hw->dpb); + /* Only the caller from inside decoder we call flush_dbp */ + if (!hw->reset_bufmgr_flag) + flush_dpb(&hw->dpb); - if (!hw->is_used_v4l) { - timeout = jiffies + HZ; - while (kfifo_len(&hw->display_q) > 0) { - if (time_after(jiffies, timeout)) - break; - schedule(); - } + timeout = jiffies + HZ; + while (kfifo_len(&hw->display_q) > 0) { + if (time_after(jiffies, timeout)) + break; + schedule(); } buf_spec_init(hw, true); @@ -10491,10 +10111,12 @@ struct vdec_h264_hw_s *hw = NULL; char *tmpbuf; int config_val; + if (pdata == NULL) { pr_info("\nammvdec_h264 memory resource undefined.\n"); return -EFAULT; } + pr_info("%s:cts test\n",__func__); hw = (struct vdec_h264_hw_s *)h264_alloc_hw_stru(&pdev->dev, sizeof(struct vdec_h264_hw_s), GFP_KERNEL); @@ -10505,22 +10127,14 @@ hw->id = pdev->id; hw->platform_dev = pdev; - snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name), + snprintf(hw->vdec_name, sizeof(hw->vdec_name), "h264-%d", hw->id); - snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name), - "%s-pts", hw->trace.vdec_name); - snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name), - "%s-newframe_q", hw->trace.vdec_name); - snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name), - "%s-dispframe_q", hw->trace.vdec_name); - snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name), - "decoder_time%d", pdev->id); - snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name), - "decoder_run_time%d", pdev->id); - snprintf(hw->trace.decode_header_time_name, sizeof(hw->trace.decode_header_time_name), - "decoder_header_time%d", pdev->id); - snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name), - "decoder_work_time%d", pdev->id); + snprintf(hw->pts_name, sizeof(hw->pts_name), + "%s-pts", hw->vdec_name); + snprintf(hw->new_q_name, sizeof(hw->new_q_name), + "%s-newframe_q", hw->vdec_name); + snprintf(hw->disp_q_name, sizeof(hw->disp_q_name), + "%s-dispframe_q", hw->vdec_name); /* the ctx from v4l2 driver. */ hw->v4l2_ctx = pdata->private; @@ -10557,7 +10171,6 @@ } if (pdata->config_len) { - dpb_print(DECODE_ID(hw), 0, "pdata->config=%s\n", pdata->config); /*use ptr config for doubel_write_mode, etc*/ if (get_config_int(pdata->config, "mh264_double_write_mode", &config_val) == 0) @@ -10607,16 +10220,6 @@ hw->discard_dv_data = config_val; dpb_print(DECODE_ID(hw), 0, "discard dv data\n"); } - - if (get_config_int(pdata->config, - "parm_v4l_metadata_config_flag", - &config_val) == 0) { - hw->metadata_config_flag = config_val; - hw->discard_dv_data = hw->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE; - if (hw->discard_dv_data) - dpb_print(DECODE_ID(hw), 0, "discard dv data\n"); - } - } else hw->double_write_mode = double_write_mode; @@ -10633,6 +10236,9 @@ hw->enable_fence, hw->fence_usage); } + if (hw->enable_fence) + pdata->sync.usage = hw->fence_usage; + if (!hw->is_used_v4l) { hw->reorder_dpb_size_margin = reorder_dpb_size_margin; hw->canvas_mode = mem_map_mode; @@ -10685,6 +10291,11 @@ pdata->user_data_read = NULL; pdata->reset_userdata_fifo = NULL; #endif + +#ifdef VDEC_FCC_SUPPORT + pdata->wakeup_fcc_poll = vmh264_wakeup_fcc_poll; +#endif + if (pdata->use_vfm_path) { snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, VFM_DEC_PROVIDER_NAME); @@ -10692,38 +10303,24 @@ } #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION else if (vdec_dual(pdata)) { - if (!pdata->is_stream_mode_dv_multi) { - if (dv_toggle_prov_name) /*debug purpose*/ - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME : - VFM_DEC_DVEL_PROVIDER_NAME); - else - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : - VFM_DEC_DVBL_PROVIDER_NAME); - } else { - if (dv_toggle_prov_name) /*debug purpose*/ - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME2 : - VFM_DEC_DVEL_PROVIDER_NAME2); - else - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME2 : - VFM_DEC_DVBL_PROVIDER_NAME2); - } + if (dv_toggle_prov_name) /*debug purpose*/ + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME : + VFM_DEC_DVEL_PROVIDER_NAME); + else + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : + VFM_DEC_DVBL_PROVIDER_NAME); } #endif else snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, PROVIDER_NAME ".%02x", pdev->id & 0xff); - if (!hw->is_used_v4l) - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vf_provider_ops, pdata); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vf_provider_ops, pdata); platform_set_drvdata(pdev, pdata); @@ -10746,7 +10343,7 @@ DCAC_READ_MARGIN; if (hw->mmu_enable) { u32 extif_size = EXTIF_BUF_SIZE; - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) extif_size <<= 1; if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_EXTIF_IDX, extif_size, DRIVER_NAME, &hw->extif_addr) < 0) { @@ -10809,8 +10406,19 @@ dpb_print(DECODE_ID(hw), 0, "ammvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx\n", pdata->mem_start, hw->buf_offset, hw->cma_alloc_addr); - vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); - + if (vdec_is_support_4k() || + (clk_adj_frame_count > (VDEC_CLOCK_ADJUST_FRAME - 1))) + vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); + else if (pdata->sys_info->height * pdata->sys_info->width < 1280 * 720) + { + vdec_source_changed(VFORMAT_H264, 1280, 720, 29); + } else if (pdata->sys_info->height * pdata->sys_info->width < 1920 * 1080) + { + vdec_source_changed(VFORMAT_H264, 1920, 1080, 29); + } else + { + vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); + } if (hw->mmu_enable) hevc_source_changed(VFORMAT_HEVC, 3840, 2160, 60); @@ -10848,19 +10456,10 @@ display_frame_count[DECODE_ID(hw)] = 0; decode_frame_count[DECODE_ID(hw)] = 0; hw->dpb.without_display_mode = without_display_mode; - mutex_init(&hw->fence_mutex); + if (hw->enable_fence) { - pdata->sync = vdec_sync_get(); - if (!pdata->sync) { - dpb_print(DECODE_ID(hw), 0, "alloc fence timeline error\n"); - ammvdec_h264_mmu_release(hw); - h264_free_hw_stru(&pdev->dev, (void *)hw); - pdata->dec_status = NULL; - return -ENODEV; - } - pdata->sync->usage = hw->fence_usage; /* creat timeline. */ - vdec_timeline_create(pdata->sync, DRIVER_NAME); + vdec_timeline_create(&pdata->sync, DRIVER_NAME); } return 0; @@ -10870,6 +10469,7 @@ struct vdec_sync *sync) { ulong expires; + int i; /* clear display pool. */ clear_refer_bufs(hw); @@ -10885,7 +10485,14 @@ } } - pr_info("fence start release\n"); + for (i = 0; i < VF_POOL_SIZE; i++) { + struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i]; + + if (vf->fence) { + vdec_fence_put(vf->fence); + vf->fence = NULL; + } + } /* decreases refcnt of timeline. */ vdec_timeline_put(sync); @@ -10959,7 +10566,7 @@ } if (hw->enable_fence) - vdec_fence_release(hw, vdec->sync); + vdec_fence_release(hw, &vdec->sync); ammvdec_h264_mmu_release(hw); h264_free_hw_stru(&pdev->dev, (void *)hw); @@ -10969,16 +10576,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mh264_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mh264_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mh264_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mh264_suspend, mh264_resume) +}; +#endif static struct platform_driver ammvdec_h264_driver = { .probe = ammvdec_h264_probe, .remove = ammvdec_h264_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mh264_pm_ops, +#endif } }; @@ -11017,7 +10640,6 @@ static int __init ammvdec_h264_driver_init_module(void) { - pr_info("ammvdec_h264 module init\n"); if (platform_driver_register(&ammvdec_h264_driver)) { pr_info("failed to register ammvdec_h264 driver\n"); @@ -11027,25 +10649,15 @@ if (vdec_is_support_4k()) { if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX) { ammvdec_h264_profile.profile = - "4k, dwrite, compressed, frame_dv, fence, v4l"; + "4k, dwrite, compressed, frame_dv, fence"; } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB) { - ammvdec_h264_profile.profile = "4k, frame_dv, fence, v4l"; - } - } else { - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) { - ammvdec_h264_profile.profile = - "dwrite, compressed, frame_dv, v4l"; - } else { - ammvdec_h264_profile.profile = - "dwrite, compressed, v4l"; + ammvdec_h264_profile.profile = "4k, frame_dv, fence"; } } vcodec_profile_register(&ammvdec_h264_profile); INIT_REG_NODE_CONFIGS("media.decoder", &hm264_node, "mh264", hm264_configs, CONFIG_FOR_RW); - - vcodec_feature_register(VFORMAT_H264, 0); return 0; } @@ -11206,9 +10818,6 @@ module_param(stream_mode_start_num, uint, 0664); MODULE_PARM_DESC(stream_mode_start_num, "\n stream_mode_start_num\n"); -module_param(colocate_old_cal, uint, 0664); -MODULE_PARM_DESC(colocate_old_cal, "\n amvdec_mh264 colocate_old_cal\n"); - /* module_param(trigger_task, uint, 0664); MODULE_PARM_DESC(trigger_task, "\n amvdec_h264 trigger_task\n");
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c old mode 100644 new mode 100755 index d5945ce..2e9bafc --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -38,10 +38,7 @@ #include <linux/dma-contiguous.h> #include <linux/slab.h> #include <linux/mm.h> -#include <linux/timer.h> -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> -#include <linux/sched/clock.h> +#include <linux/amlogic/tee.h> #include "../../../stream_input/amports/amports_priv.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> #include "../utils/decoder_mmu_box.h" @@ -60,8 +57,6 @@ #define HEVC_8K_LFTOFFSET_FIX #define SUPPORT_LONG_TERM_RPS -//#define CO_MV_COMPRESS - #define CONSTRAIN_MAX_BUF_NUM #define SWAP_HEVC_UCODE @@ -86,7 +81,7 @@ #define DB_NUM 20 #define MAX_FRAME_4K_NUM 0x1200 -#define MAX_FRAME_8K_NUM ((MAX_FRAME_4K_NUM) * 4) +#define MAX_FRAME_8K_NUM (0x1200*4) //#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4) #define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7 @@ -94,16 +89,8 @@ #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_DBLK_CFGB 0x350b #define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7 @@ -117,11 +104,9 @@ #include "../utils/amvdec.h" #include <linux/amlogic/media/video_sink/video.h> #include <linux/amlogic/media/codec_mm/configs.h> -#include "../utils/vdec_feature.h" #define SEND_LMEM_WITH_RPM #define SUPPORT_10BIT -#define H265_10B_MMU_DW /* #define ERROR_HANDLE_DEBUG */ #ifndef STAT_KTHREAD @@ -148,7 +133,6 @@ #define MAX_SIZE_8K (8192 * 4608) #define MAX_SIZE_4K (4096 * 2304) -#define MAX_SIZE_2K (1920 * 1088) #define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K) #define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088)) @@ -183,11 +167,10 @@ #endif static void vh265_prot_init(struct hevc_state_s *hevc); static int vh265_local_init(struct hevc_state_s *hevc); -static void vh265_check_timer_func(struct timer_list *timer); +static void vh265_check_timer_func(unsigned long arg); static void config_decode_mode(struct hevc_state_s *hevc); static int check_data_size(struct vdec_s *vdec); - static const char vh265_dec_id[] = "vh265-dev"; #define PROVIDER_NAME "decoder.h265" @@ -256,11 +239,6 @@ #define HEVC_CM_HEADER_LENGTH 0x3629 #define HEVC_CM_HEADER_OFFSET 0x362b #define HEVC_SAO_CTRL9 0x362d - -#define HEVC_CM_BODY_LENGTH2 0x3663 -#define HEVC_CM_HEADER_OFFSET2 0x3664 -#define HEVC_CM_HEADER_LENGTH2 0x3665 - #define LOSLESS_COMPRESS_MODE /* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */ /* double_write_mode: @@ -270,7 +248,6 @@ * 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, from t7 * 0x10, double write only * 0x100, if > 1080p,use mode 4,else use mode 1; * 0x200, if > 1080p,use mode 2,else use mode 1; @@ -353,14 +330,7 @@ static u32 dbg_cmd; static u32 dump_nal; 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) - +static u32 endian = 0xff0; #ifdef ERROR_HANDLE_DEBUG static u32 dbg_nal_skip_flag; /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */ @@ -504,7 +474,8 @@ *bit 9: 0, discard dirty data on playback start * 1, do not discard dirty data on playback start *bit 10:0, when ucode always returns again, it supports discarding data - * 1, When ucode always returns again, it does not support discarding data + * 1, When ucode always returns again, it does not support discarding data + * */ static u32 error_handle_policy; @@ -989,10 +960,6 @@ struct buff_s dblk_data2; struct buff_s mmu_vbh; struct buff_s cm_header; -#ifdef H265_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; @@ -1004,7 +971,7 @@ //#define VBH_BUF_SIZE (2 * 16 * 2304) //#define VBH_BUF_COUNT 4 -/*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/ + /*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 @@ -1016,288 +983,12 @@ #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 +#define WORK_BUF_SPEC_NUM 3 static struct BuffInfo_s amvh265_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, - }, - .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, - }, - .vps = { - /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, - * total 0x0800 bytes - */ - .buf_size = 0x800, - }, - .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 = { -#ifdef SUPPORT_10BIT - .buf_size = 0x40000, -#else - /* DBLK -> Max 256(4096/16) LCU, each para - *512bytes(total:0x20000), data 1024bytes(total:0x40000) - */ - .buf_size = 0x20000, -#endif - }, - .dblk_data = { - .buf_size = 0x40000, - }, - .dblk_data2 = { - .buf_size = 0x80000 * 2, - }, /*dblk data for adapter*/ - .mmu_vbh = { - .buf_size = 0x5000, /*2*16*2304/4, 4K*/ - }, -#if 0 - .cm_header = {/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ - .buf_size = MMU_COMPRESS_HEADER_SIZE * - (MAX_REF_PIC_NUM + 1), - }, -#endif - .mpred_above = { - .buf_size = 0x8000, - }, -#ifdef MV_USE_FIXED_BUF - .mpred_mv = {/* 1080p, 0x40000 per buffer */ - .buf_size = 0x40000 * MAX_REF_PIC_NUM, - }, -#endif - .rpm = { - .buf_size = RPM_BUF_SIZE, - }, - .lmem = { - .buf_size = 0x500 * 2, - } - }, - { - .max_width = 4096, - .max_height = 2048, - .ipp = { - /* IPP work space calculation : - * 4096 * (Y+CbCr+Flags) = 12k, round to 16k - */ - .buf_size = 0x1e00, - }, - .sao_abv = { - .buf_size = 0, //0x30000, - }, - .sao_vb = { - .buf_size = 0, //0x30000, - }, - .short_term_rps = { - /* SHORT_TERM_RPS - Max 64 set, 16 entry every set, - * total 64x16x2 = 2048 bytes (0x800) - */ - .buf_size = 0x800, - }, - .vps = { - /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, - * total 0x0800 bytes - */ - .buf_size = 0x800, - }, - .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 - * 512bytes(total:0x20000), - * data 1024bytes(total:0x40000) - */ - .buf_size = 0x20000, - }, - .dblk_data = { - .buf_size = 0x80000, - }, - .dblk_data2 = { - .buf_size = 0x80000, - }, /*dblk data for adapter*/ - .mmu_vbh = { - .buf_size = 0x5000, /*2*16*2304/4, 4K*/ - }, -#if 0 - .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ - .buf_size = MMU_COMPRESS_HEADER_SIZE * - (MAX_REF_PIC_NUM + 1), - }, -#endif - .mpred_above = { - .buf_size = 0x8000, - }, -#ifdef MV_USE_FIXED_BUF - .mpred_mv = { - /* .buf_size = 0x100000*16, - //4k2k , 0x100000 per buffer */ - /* 4096x2304 , 0x120000 per buffer */ - .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM, - }, -#endif - .rpm = { - .buf_size = RPM_BUF_SIZE, - }, - .lmem = { - .buf_size = 0x500 * 2, - } - }, - - { - .max_width = 4096*2, - .max_height = 2048*2, - .ipp = { - // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k - .buf_size = 0x4000*2, - }, - .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, - }, - .vps = { - // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes - .buf_size = 0x800, - }, - .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*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 parameter - .dblk_data = {.buf_size = 0x80000*2, }, // dblk data for left/top - .dblk_data2 = {.buf_size = 0x80000*2, }, // dblk data for adapter - .mmu_vbh = { - .buf_size = 0x5000*2, //2*16*2304/4, 4K - }, -#if 0 - .cm_header = { - .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * - MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif - .mpred_above = { - .buf_size = 0x8000*2, - }, -#ifdef MV_USE_FIXED_BUF - .mpred_mv = { - .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer - }, -#endif - .rpm = { - .buf_size = RPM_BUF_SIZE, - }, - .lmem = { - .buf_size = 0x500 * 2, - }, - }, - { - /* 8M bytes */ - .max_width = 1920, - .max_height = 1088, .ipp = {/*checked*/ /* IPP work space calculation : * 4096 * (Y+CbCr+Flags) = 12k, round to 16k @@ -1367,16 +1058,6 @@ (MAX_REF_PIC_NUM + 1), }, #endif -#ifdef H265_10B_MMU_DW - .mmu_vbh_dw = {/*checked*/ - .buf_size = DW_VBH_BUF_SIZE_1080P, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*2304/4, 4K - }, -#ifdef USE_FIXED_MMU_DW_HEADER - .cm_header_dw = {/*checked*/ - .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = {/*checked*/ .buf_size = 0x1e00, }, @@ -1454,7 +1135,7 @@ }, .dblk_para = {.buf_size = 0x19100, }, // dblk parameter .dblk_data = {.buf_size = 0x88800, }, // dblk data for left/top - .dblk_data2 = {.buf_size = 0x48800, }, // dblk data for adapter + .dblk_data2 = {.buf_size = 0x80000, }, // dblk data for adapter .mmu_vbh = { .buf_size = VBH_BUF_SIZE_4K, /*2*16*2304/4, 4K*/ }, @@ -1464,16 +1145,6 @@ (MAX_REF_PIC_NUM + 1), }, #endif -#ifdef H265_10B_MMU_DW - .mmu_vbh_dw = { - .buf_size = DW_VBH_BUF_SIZE_4K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K - }, -#ifdef USE_FIXED_MMU_DW_HEADER - .cm_header_dw = { - .buf_size = MMU_COMPRESS_HEADER_SIZE_4K * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = { .buf_size = 0x4000, }, @@ -1549,16 +1220,6 @@ MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) }, #endif -#ifdef H265_10B_MMU_DW - .mmu_vbh_dw = { - .buf_size = DW_VBH_BUF_SIZE_8K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*2304/4, 4K - }, -#ifdef USE_FIXED_MMU_DW_HEADER - .cm_header_dw = { - .buf_size = MMU_COMPRESS_HEADER_SIZE_8K * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = { .buf_size = 0x8000, }, @@ -1579,66 +1240,64 @@ static void init_buff_spec(struct hevc_state_s *hevc, struct BuffInfo_s *buf_spec) { - buf_spec->ipp.buf_start = - WORKBUF_ALIGN(buf_spec->start_adr); + buf_spec->ipp.buf_start = buf_spec->start_adr; buf_spec->sao_abv.buf_start = - WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); + buf_spec->ipp.buf_start + buf_spec->ipp.buf_size; + buf_spec->sao_vb.buf_start = - WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size); + 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->sao_vb.buf_start + buf_spec->sao_vb.buf_size; buf_spec->vps.buf_start = - WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size); + buf_spec->short_term_rps.buf_start + + buf_spec->short_term_rps.buf_size; buf_spec->sps.buf_start = - WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size); + buf_spec->vps.buf_start + buf_spec->vps.buf_size; buf_spec->pps.buf_start = - WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size); + 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->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->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->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->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->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_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); + buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; buf_spec->mmu_vbh.buf_start = - WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size); -#ifdef H265_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->cm_header_dw.buf_start = - WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size); + buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size; buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_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 + buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size; #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->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); + 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); + 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->rpm.buf_start + + buf_spec->rpm.buf_size; buf_spec->end_adr = - WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size); + buf_spec->lmem.buf_start + + buf_spec->lmem.buf_size; if (hevc && get_dbg_flag2(hevc)) { hevc_print(hevc, 0, - "%s workspace (%x %x) size = %x\n", __func__, - buf_spec->start_adr, buf_spec->end_adr, - buf_spec->end_adr - buf_spec->start_adr); + "%s workspace (%x %x) size = %x\n", __func__, + buf_spec->start_adr, buf_spec->end_adr, + buf_spec->end_adr - buf_spec->start_adr); hevc_print(hevc, 0, "ipp.buf_start :%x\n", @@ -1682,14 +1341,6 @@ hevc_print(hevc, 0, "dblk_data2.buf_start :%x\n", buf_spec->dblk_data2.buf_start); -#ifdef H265_10B_MMU_DW - hevc_print(hevc, 0, - "mmu_vbh_dw.buf_start :%x\n", - buf_spec->mmu_vbh_dw.buf_start); - hevc_print(hevc, 0, - "cm_header_dw.buf_start :%x\n", - buf_spec->cm_header_dw.buf_start); -#endif hevc_print(hevc, 0, "mpred_above.buf_start :%x\n", buf_spec->mpred_above.buf_start); @@ -1776,9 +1427,6 @@ unsigned int dw_y_adr; unsigned int dw_u_v_adr; #endif - u32 luma_size; - u32 chroma_size; - int mc_canvas_y; int mc_canvas_u_v; int width; @@ -1797,9 +1445,6 @@ #ifdef LOSLESS_COMPRESS_MODE unsigned int losless_comp_body_size; #endif -#ifdef H265_10B_MMU_DW - u32 header_dw_adr; -#endif unsigned char pic_struct; int vf_ref; @@ -1832,10 +1477,11 @@ u32 hw_decode_time; u32 frame_size; // For frame base mode + bool vframe_bound; bool ip_mode; u32 hdr10p_data_size; char *hdr10p_data_buf; - struct dma_fence *fence; + struct fence *fence; bool show_frame; } /*PIC_t */; @@ -1854,8 +1500,6 @@ #define SEI_MASTER_DISPLAY_COLOR_MASK 0x00000001 #define SEI_CONTENT_LIGHT_LEVEL_MASK 0x00000002 #define SEI_HDR10PLUS_MASK 0x00000004 -#define SEI_HDR_CUVA_MASK 0x00000008 - #define VF_POOL_SIZE 32 @@ -1872,6 +1516,7 @@ #define DEC_RESULT_EOS 9 #define DEC_RESULT_FORCE_EXIT 10 #define DEC_RESULT_FREE_CANVAS 11 +#define DEC_RESULT_DISCARD_DATA 12 static void vh265_work(struct work_struct *work); @@ -1885,11 +1530,6 @@ uint8_t data; /*will alloc more size*/ }; -struct mh265_fence_vf_t { - u32 used_size; - struct vframe_s *fence_vf[VF_POOL_SIZE]; -}; - struct hevc_state_s { #ifdef MULTI_INSTANCE_SUPPORT struct platform_device *platform_dev; @@ -2116,12 +1756,6 @@ void *mmu_box; void *bmmu_box; int mmu_enable; -#ifdef H265_10B_MMU_DW - void *frame_dw_mmu_map_addr; - dma_addr_t frame_dw_mmu_map_phy_addr; - void *mmu_box_dw; - int dw_mmu_enable; -#endif unsigned int dec_status; @@ -2147,8 +1781,8 @@ u32 start_shift_bytes; u32 vf_pre_count; - atomic_t vf_get_count; - atomic_t vf_put_count; + u32 vf_get_count; + u32 vf_put_count; #ifdef SWAP_HEVC_UCODE dma_addr_t mc_dma_handle; void *mc_cpu_addr; @@ -2178,7 +1812,6 @@ u32 skip_nal_count; bool is_swap; bool is_4k; - int frameinfo_enable; struct vframe_qos_s vframe_qos; bool is_used_v4l; @@ -2187,6 +1820,7 @@ u32 mem_map_mode; u32 performance_profile; struct vdec_info *gvs; + u32 res_ch_flag; bool ip_mode; u32 kpi_first_i_comming; u32 kpi_first_i_decoded; @@ -2201,21 +1835,18 @@ bool discard_dv_data; bool enable_fence; int fence_usage; - int buffer_wrap[MAX_REF_PIC_NUM]; int low_latency_flag; - u32 metadata_config_flag; - int last_width; - int last_height; - int used_buf_num; u32 dirty_shift_flag; - u32 endian; - ulong fb_token; + char vdec_name[32]; + char set_canvas0_addr[32]; + char get_canvas0_addr[32]; + char put_canvas0_addr[32]; + char vf_put_name[32]; + char vf_get_name[32]; + char new_q_name[32]; + char disp_q_name[32]; + char pts_name[32]; int dec_again_cnt; - struct mh265_fence_vf_t fence_vf_s; - struct mutex fence_mutex; - dma_addr_t rdma_phy_adr; - unsigned *rdma_adr; - struct trace_decoder_name trace; } /*hevc_stru_t */; #ifdef AGAIN_HAS_THRESHOLD @@ -2239,9 +1870,6 @@ int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? MAX_SIZE_8K : MAX_SIZE_4K; - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) - max = MAX_SIZE_2K; - if (w < 0 || h < 0) return true; @@ -2307,7 +1935,7 @@ #ifdef SUPPORT_10BIT /* Losless compression body buffer size 4K per 64x32 (jt) */ -static int compute_losless_comp_body_size(struct hevc_state_s *hevc, +static int compute_losless_comp_body_size(struct hevc_state_s *hevc, int width, int height, int mem_saving_mode) { int width_x64; @@ -2330,7 +1958,7 @@ } /* Losless compression header buffer size 32bytes per 128x64 (jt) */ -static int compute_losless_comp_header_size(int width, int height) +static int compute_losless_comp_header_size(int width, int height) { int width_x128; int height_x64; @@ -2414,18 +2042,10 @@ #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC static int get_valid_double_write_mode(struct hevc_state_s *hevc) { - u32 dw = (hevc->m_ins_flag && + return (hevc->m_ins_flag && ((double_write_mode & 0x80000000) == 0)) ? hevc->double_write_mode : (double_write_mode & 0x7fffffff); - if (dw & 0x20) { - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3) - && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) { - pr_info("MMU doueble write 1:4 not supported !!!\n"); - dw = 0; - } - } - return dw; } static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc) @@ -2443,15 +2063,30 @@ int w = hevc->pic_w; int h = hevc->pic_h; u32 dw = 0x1; /*1:1*/ - - if (hevc->is_used_v4l) { - unsigned int out; - - vdec_v4l_get_dw_mode(hevc->v4l2_ctx, &out); - dw = out; - return dw; + 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 v4l_parser_get_double_write_mode(struct hevc_state_s *hevc, int w, int h) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hevc); + u32 dw = 0x1; /*1:1*/ switch (valid_dw_mode) { case 0x100: if (w > 1920 && h > 1088) @@ -2480,6 +2115,19 @@ return dw; } + +static int get_double_write_ratio(struct hevc_state_s *hevc, + int dw_mode) +{ + int ratio = 1; + if ((dw_mode == 2) || + (dw_mode == 3)) + ratio = 4; + else if ((dw_mode == 4) || + (dw_mode == 5)) + ratio = 2; + return ratio; +} #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC static unsigned char get_idx(struct hevc_state_s *hevc) { @@ -2492,7 +2140,7 @@ static int hevc_print(struct hevc_state_s *hevc, int flag, const char *fmt, ...) { -#define HEVC_PRINT_BUF 512 +#define HEVC_PRINT_BUF 256 unsigned char buf[HEVC_PRINT_BUF]; int len = 0; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC @@ -2591,7 +2239,7 @@ release_aux_data(hevc, hevc->decoding_pic); hevc->decoding_pic = NULL; } - /*if (vdec_stream_based(vdec) && + if (vdec_stream_based(vdec) && (hevc->decode_idx - hevc->decode_idx_bak > 1)) { int i; hevc_print(hevc, 0, "decode_idx %d, decode_idx_bak %d\n", @@ -2617,7 +2265,7 @@ release_aux_data(hevc, pic); } } - }*/ + } hevc->decode_idx = hevc->decode_idx_bak; hevc->m_pocRandomAccess = hevc->m_pocRandomAccess_bak; hevc->curr_POC = hevc->curr_POC_bak; @@ -2743,10 +2391,6 @@ static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic, unsigned short bit_depth, unsigned int *mmu_index_adr); -#ifdef H265_10B_MMU_DW -static int H265_alloc_mmu_dw(struct hevc_state_s *hevc, struct PIC_s *new_pic, - unsigned short bit_depth, unsigned int *mmu_index_adr); -#endif #ifdef DETREFILL_ENABLE #define DETREFILL_BUF_SIZE (4 * 0x4000) @@ -2943,7 +2587,7 @@ uint16_t ctuy = (ctuPosition>> 0) & 0xffff; int32_t aboveCtuAvailable = (ctuy) ? 1 : 0; - uint16_t *cmBodyBuf = NULL; + uint16_t cmBodyBuf[32 * 18]; uint32_t pic_width_x64_pre = picWidth + 0x3f; uint32_t pic_width_x64 = pic_width_x64_pre >> 6; @@ -2965,10 +2609,6 @@ int32_t blkIdx; - cmBodyBuf = vzalloc(sizeof(uint16_t) * 32 * 18); - if (!cmBodyBuf) - return; - WRITE_VREG(HEVC_SAO_CTRL10, cmHeaderAddrAbv); WRITE_VREG(HEVC_SAO_CTRL11, cmHeaderAddrCur); WRITE_VREG(HEVC_SAO_DBG_MODE0, hevc->detbuf_adr); @@ -3087,7 +2727,6 @@ } while (tmpData32); hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, "%s, %d\n", __func__, __LINE__); - vfree(cmBodyBuf); } static void delrefill(struct hevc_state_s *hevc) @@ -3153,18 +2792,17 @@ struct PIC_s *pic; int i; - for (i = 0; i < hevc->used_buf_num; i++) { + for (i = 0; i < MAX_REF_PIC_NUM; i++) { pic = hevc->m_PIC[i]; - if ((pic == NULL) || - (pic->index == -1) || - (pic->BUF_index == -1)) + if (pic == NULL || + pic->index == -1 || + pic->BUF_index == -1) continue; - if ((pic->output_mark == 0) && - (pic->referenced == 0) && - (pic->output_ready == 0) && - (pic->vf_ref == 0) && - (pic->cma_alloc_addr)) { + if (pic->output_mark == 0 && + pic->referenced == 0 && + pic->output_ready == 0 && + pic->cma_alloc_addr) { pic->output_ready = 1; index = i; break; @@ -3239,46 +2877,80 @@ static int init_buf_spec(struct hevc_state_s *hevc); +static bool v4l_is_there_vframe_bound(struct hevc_state_s *hevc) +{ + int i; + + for (i = 0; i < MAX_REF_PIC_NUM; i++) { + struct PIC_s *pic = hevc->m_PIC[i]; + + if (pic && pic->vframe_bound) + return true; + } + + return false; +} + +static void v4l_mmu_buffer_release(struct hevc_state_s *hevc) +{ + int i; + + /* release workspace */ + if (hevc->bmmu_box) + decoder_bmmu_box_free_idx(hevc->bmmu_box, + BMMU_WORKSPACE_ID); + /* + * it's only when vframe get back to driver, right now we can be sure + * that vframe and fd are related. if the playback exits, the capture + * requires the upper app to release when the fd is closed, and others + * buffers drivers are released by driver. + */ + for (i = 0; i < MAX_REF_PIC_NUM; i++) { + struct PIC_s *pic = hevc->m_PIC[i]; + + if (pic && !pic->vframe_bound) { + if (hevc->bmmu_box) + decoder_bmmu_box_free_idx(hevc->bmmu_box, + VF_BUFFER_IDX(i)); + if (hevc->mmu_box) + decoder_mmu_box_free_idx(hevc->mmu_box, i); + + hevc_print(hevc, PRINT_FLAG_V4L_DETAIL, + "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n", + __func__, i, hevc->bmmu_box, hevc->mmu_box); + } + } +} static void uninit_mmu_buffers(struct hevc_state_s *hevc) { - if (hevc->mmu_box) { + if (hevc->is_used_v4l && + v4l_is_there_vframe_bound(hevc)) { + if (get_double_write_mode(hevc) != 0x10) { + v4l_mmu_buffer_release(hevc); + return; + } + } + + if (hevc->mmu_box) decoder_mmu_box_free(hevc->mmu_box); - hevc->mmu_box = NULL; - } -#ifdef H265_10B_MMU_DW - if (hevc->mmu_box_dw) { - decoder_mmu_box_free(hevc->mmu_box_dw); - hevc->mmu_box_dw = NULL; - } -#endif - if (hevc->bmmu_box) { - /* release workspace */ - decoder_bmmu_box_free_idx(hevc->bmmu_box, - BMMU_WORKSPACE_ID); + hevc->mmu_box = NULL; + + if (hevc->bmmu_box) decoder_bmmu_box_free(hevc->bmmu_box); - hevc->bmmu_box = NULL; - } + hevc->bmmu_box = NULL; } -/* return in MB */ -static int hevc_max_mmu_buf_size(int max_w, int max_h) -{ - int buf_size = 64; - - if ((max_w * max_h) > 0 && - (max_w * max_h) <= 1920*1088) { - buf_size = 24; - } - return buf_size; -} - -static int init_mmu_buffers(struct hevc_state_s *hevc, int bmmu_flag) +static int init_mmu_box(struct hevc_state_s *hevc) { int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ? CODEC_MM_FLAGS_TVP : 0; - int buf_size = hevc_max_mmu_buf_size(hevc->max_pic_w, - hevc->max_pic_h); + int buf_size = 64; + + if ((hevc->max_pic_w * hevc->max_pic_h) > 0 && + (hevc->max_pic_w * hevc->max_pic_h) <= 1920*1088) { + buf_size = 24; + } if (get_dbg_flag(hevc)) { hevc_print(hevc, 0, "%s max_w %d max_h %d\n", @@ -3287,7 +2959,43 @@ hevc->need_cache_size = buf_size * SZ_1M; hevc->sc_start_time = get_jiffies_64(); - if (hevc->mmu_enable && !hevc->is_used_v4l) { + if (hevc->mmu_enable + && ((get_double_write_mode(hevc) & 0x10) == 0)) { + hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, + hevc->index, + MAX_REF_PIC_NUM, + buf_size * SZ_1M, + tvp_flag + ); + if (!hevc->mmu_box) { + hevc_print(hevc, 0, "h265 alloc mmu box failed!!\n"); + return -1; + } + } + + return 0; +} + +static int init_mmu_buffers(struct hevc_state_s *hevc) +{ + int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ? + CODEC_MM_FLAGS_TVP : 0; + int buf_size = 64; + + if ((hevc->max_pic_w * hevc->max_pic_h) > 0 && + (hevc->max_pic_w * hevc->max_pic_h) <= 1920*1088) { + buf_size = 24; + } + + if (get_dbg_flag(hevc)) { + hevc_print(hevc, 0, "%s max_w %d max_h %d\n", + __func__, hevc->max_pic_w, hevc->max_pic_h); + } + + hevc->need_cache_size = buf_size * SZ_1M; + hevc->sc_start_time = get_jiffies_64(); + if (hevc->mmu_enable + && ((get_double_write_mode(hevc) & 0x10) == 0)) { hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, hevc->index, MAX_REF_PIC_NUM, @@ -3298,21 +3006,7 @@ pr_err("h265 alloc mmu box failed!!\n"); return -1; } -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - hevc->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME, - hevc->index, - MAX_REF_PIC_NUM, - buf_size * SZ_1M, - tvp_flag - ); - if (!hevc->mmu_box_dw) - goto dw_mmu_box_failed; - } -#endif } - if (bmmu_flag) - return 0; hevc->bmmu_box = decoder_bmmu_box_alloc_box(DRIVER_NAME, hevc->index, @@ -3321,23 +3015,14 @@ CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER | tvp_flag); - if (!hevc->bmmu_box) - goto bmmu_box_failed; - - return 0; -bmmu_box_failed: -#ifdef H265_10B_MMU_DW - if (hevc->mmu_box_dw) - decoder_mmu_box_free(hevc->mmu_box_dw); - hevc->mmu_box_dw = NULL; -dw_mmu_box_failed: -#endif - if (hevc->mmu_box) { - decoder_mmu_box_free(hevc->mmu_box); + if (!hevc->bmmu_box) { + if (hevc->mmu_box) + decoder_mmu_box_free(hevc->mmu_box); + hevc->mmu_box = NULL; + pr_err("h265 alloc mmu box failed!!\n"); + return -1; } - hevc->mmu_box = NULL; - pr_err("h265 %s failed!!\n", __func__); - return -1; + return 0; } struct buf_stru_s @@ -3355,7 +3040,7 @@ if (hevc->m_mv_BUF[i].start_adr) { if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) hevc_print(hevc, 0, - "dealloc mv buf(%d) adr 0x%p size 0x%x used_flag %d\n", + "dealloc mv buf(%d) adr 0x%lx size 0x%x used_flag %d\n", i, hevc->m_mv_BUF[i].start_adr, hevc->m_mv_BUF[i].size, hevc->m_mv_BUF[i].used_flag); @@ -3553,20 +3238,10 @@ #endif } -static int hevc_get_header_size(int w, int h) -{ - 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; - else - return MMU_COMPRESS_HEADER_SIZE_1080P; -} - static int cal_current_buf_size(struct hevc_state_s *hevc, struct buf_stru_s *buf_stru) { + int buf_size; int pic_width = hevc->pic_w; int pic_height = hevc->pic_h; @@ -3588,21 +3263,22 @@ int dw_mode = get_double_write_mode(hevc); - if (hevc->mmu_enable) - buf_size = hevc_get_header_size(hevc->pic_w, hevc->pic_h); - else + if (hevc->mmu_enable) { + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))) + buf_size = ((MMU_COMPRESS_HEADER_SIZE_8K + 0xffff) >> 16) + << 16; + else + buf_size = ((MMU_COMPRESS_HEADER_SIZE_4K + 0xffff) >> 16) + << 16; + } else buf_size = 0; -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - buf_size = ((buf_size + 0xffff) >> 16) << 16; - buf_size <<= 1; - } -#endif - if (dw_mode && ((dw_mode & 0x20) == 0)) { + + if (dw_mode) { int pic_width_dw = pic_width / - get_double_write_ratio(dw_mode); + get_double_write_ratio(hevc, dw_mode); int pic_height_dw = pic_height / - get_double_write_ratio(dw_mode); + get_double_write_ratio(hevc, dw_mode); int pic_width_lcu_dw = (pic_width_dw % lcu_size) ? pic_width_dw / lcu_size + 1 : @@ -3643,48 +3319,40 @@ return buf_size; } -static struct internal_comp_buf* v4lfb_to_icomp_buf( - struct hevc_state_s *hevc, - struct vdec_v4l2_buffer *fb) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; - - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - -static struct internal_comp_buf* index_to_icomp_buf( - struct hevc_state_s *hevc, int index) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; - - fb = (struct vdec_v4l2_buffer *) - hevc->m_BUF[index].v4l_ref_buf_addr; - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic) { int ret = -1; int i = pic->index; - struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hevc->v4l2_ctx; struct vdec_v4l2_buffer *fb = NULL; - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hevc->fb_token, &fb, AML_FB_REQ_DEC); + if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM) + return ret; + + ret = vdec_v4l_get_buffer(hevc->v4l2_ctx, &fb); if (ret < 0) { - hevc_print(hevc, 0, "[%d] H265 get buffer fail.\n", ctx->id); + hevc_print(hevc, 0, "[%d] H265 get buffer fail.\n", + ((struct aml_vcodec_ctx *)(hevc->v4l2_ctx))->id); return ret; } - fb->status = FB_ST_DECODER; - if (hevc->mmu_enable) { - struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hevc, fb); - hevc->m_BUF[i].header_addr = ibuf->header_addr; + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))) + hevc->m_BUF[i].header_size = + ALIGN(MMU_COMPRESS_HEADER_SIZE_8K, 0x10000); + else + hevc->m_BUF[i].header_size = + ALIGN(MMU_COMPRESS_HEADER_SIZE_4K, 0x10000); + + ret = decoder_bmmu_box_alloc_buf_phy(hevc->bmmu_box, + VF_BUFFER_IDX(i), hevc->m_BUF[i].header_size, + DRIVER_NAME, &hevc->m_BUF[i].header_addr); + if (ret < 0) { + hevc_print(hevc, PRINT_FLAG_ERROR, + "%s[%d], header size: %d, no mem fatal err\n", + __func__, i, hevc->m_BUF[i].header_size); + return ret; + } } hevc->m_BUF[i].used_flag = 0; @@ -3697,8 +3365,6 @@ fb->m.mem[0].bytes_used = fb->m.mem[0].size; pic->dw_y_adr = hevc->m_BUF[i].start_adr; pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size; - pic->luma_size = fb->m.mem[0].offset; - pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset; } else if (fb->num_planes == 2) { hevc->m_BUF[i].start_adr = fb->m.mem[0].addr; hevc->m_BUF[i].luma_size = fb->m.mem[0].size; @@ -3709,8 +3375,6 @@ fb->m.mem[1].bytes_used = fb->m.mem[1].size; pic->dw_y_adr = hevc->m_BUF[i].start_adr; pic->dw_u_v_adr = hevc->m_BUF[i].chroma_addr; - pic->luma_size = fb->m.mem[0].size; - pic->chroma_size = fb->m.mem[1].size; } return ret; @@ -3721,7 +3385,6 @@ int i; int ret = -1; int buf_size = cal_current_buf_size(hevc, NULL); - struct vdec_s *vdec = hw_to_vdec(hevc); if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM) return ret; @@ -3749,11 +3412,6 @@ } if (ret >= 0) { - if (hevc->enable_fence) { - vdec_fence_buffer_count_increase((ulong)vdec->sync); - INIT_LIST_HEAD(&vdec->sync->release_callback[VF_BUFFER_IDX(i)].node); - decoder_bmmu_box_add_callback_func(hevc->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[VF_BUFFER_IDX(i)]); - } hevc->m_BUF[i].size = buf_size; hevc->m_BUF[i].used_flag = 0; ret = 0; @@ -3788,7 +3446,7 @@ if (ret >= 0) { if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { hevc_print(hevc, 0, - "alloc buf(%d) for %d/%d size 0x%x) => %p\n", + "alloc buf(%d) for %d/%d size 0x%x) => %lx\n", i, hevc->pic_w, hevc->pic_h, buf_size, hevc->m_BUF[i].start_adr); @@ -3818,7 +3476,7 @@ hevc->m_BUF[i].used_flag == 0) { if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { hevc_print(hevc, 0, - "dealloc buf(%d) adr 0x%p size 0x%x\n", + "dealloc buf(%d) adr 0x%lx size 0x%x\n", i, hevc->m_BUF[i].start_adr, hevc->m_BUF[i].size); } @@ -3827,7 +3485,6 @@ hevc->bmmu_box, VF_BUFFER_IDX(i)); hevc->m_BUF[i].start_adr = 0; - hevc->m_BUF[i].header_addr = 0; hevc->m_BUF[i].size = 0; } } @@ -3843,7 +3500,7 @@ hevc->m_BUF[i].start_adr) { if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { hevc_print(hevc, 0, - "dealloc buf(%d) adr 0x%p size 0x%x\n", + "dealloc buf(%d) adr 0x%lx size 0x%x\n", i, hevc->m_BUF[i].start_adr, hevc->m_BUF[i].size); } @@ -3854,7 +3511,6 @@ VF_BUFFER_IDX(i)); hevc->m_BUF[i].used_flag = 0; hevc->m_BUF[i].start_adr = 0; - hevc->m_BUF[i].header_addr = 0; hevc->m_BUF[i].size = 0; } } @@ -3945,8 +3601,10 @@ "save buf _mode : dynamic_buf_num_margin %d ----> %d \n", dynamic_buf_num_margin, hevc->dynamic_buf_num_margin); - if (sps_pic_buf_diff >= 3) - used_buf_num += sps_pic_buf_diff; + if (sps_pic_buf_diff >= 4) + { + used_buf_num += sps_pic_buf_diff;; + } /* for eos add more buffer to flush.*/ used_buf_num++; @@ -4023,35 +3681,26 @@ if (hevc->mmu_enable) { pic->header_adr = hevc->m_BUF[i].start_adr; - y_adr = hevc->m_BUF[i].start_adr + - hevc_get_header_size(hevc->pic_w, hevc->pic_h); + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + (IS_8K_SIZE(hevc->pic_w, hevc->pic_h))) + y_adr = hevc->m_BUF[i].start_adr + + MMU_COMPRESS_HEADER_SIZE_8K; + else + y_adr = hevc->m_BUF[i].start_adr + + MMU_COMPRESS_HEADER_SIZE_4K; } else y_adr = hevc->m_BUF[i].start_adr; y_adr = ((y_adr + 0xffff) >> 16) << 16; /*64k alignment*/ -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { -#ifdef USE_FIXED_MMU_DW_HEADER - pic->header_dw_adr = hevc->work_space_buf->cm_header_dw.buf_start + - (i * hevc_get_header_size(hevc->pic_w, hevc->pic_h)); -#else - pic->header_dw_adr = y_adr; - y_adr = pic->header_dw_adr + - hevc_get_header_size(hevc->pic_w, hevc->pic_h); -#endif - hevc_print(hevc, H265_DEBUG_BUFMGR, - "MMU header_dw_adr %d: %x\n", pic->header_dw_adr); - } -#endif - pic->POC = INVALID_POC; /*ensure get_pic_by_POC() not get the buffer not decoded*/ pic->BUF_index = i; if ((!hevc->mmu_enable) && - ((dw_mode & 0x10) == 0)) { + ((dw_mode & 0x10) == 0) + ) { pic->mc_y_adr = y_adr; y_adr += (buf_stru.mc_buffer_size_h << 16); } @@ -4066,7 +3715,7 @@ pic->dw_y_adr = pic->mc_y_adr; pic->dw_u_v_adr = pic->mc_u_v_adr; - } else if (dw_mode && (dw_mode & 0x20) == 0) { + } else if (dw_mode) { pic->dw_y_adr = y_adr; pic->dw_u_v_adr = pic->dw_y_adr + ((buf_stru.mc_buffer_size_u_v_h << 16) << 1); @@ -4077,7 +3726,8 @@ "%s index %d BUF_index %d mc_y_adr %x\n", __func__, pic->index, pic->BUF_index, pic->mc_y_adr); - if (hevc->mmu_enable && dw_mode) + if (hevc->mmu_enable && + dw_mode) hevc_print(hevc, 0, "mmu double write adr %ld\n", pic->cma_alloc_addr); @@ -4134,7 +3784,6 @@ pic->width = hevc->pic_w; pic->height = hevc->pic_h; pic->double_write_mode = dw_mode; - pic->POC = INVALID_POC; /*config canvas will be delay if work on v4l. */ if (!hevc->is_used_v4l) { @@ -4225,34 +3874,7 @@ data32 |= (1<<10); WRITE_VREG(HEVC_SAO_CTRL5, data32); } -#ifdef H265_10B_MMU_DW - if (hevc->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)); - 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))); - /* use HEVC_CM_HEADER_START_ADDR */ - data32 |= (1 << 15); - } else - data32 &= ~(1 << 15); - WRITE_VREG(HEVC_SAO_CTRL5, data32); -#endif if (!hevc->m_ins_flag) hevc_print(hevc, 0, "%s: (%d, %d) body_size 0x%x header_size 0x%x\n", @@ -4460,8 +4082,10 @@ decode_idx)) pic_display = pic; + } else pic_display = pic; + } } #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -4474,6 +4098,7 @@ && (!fisrt_pic_flag)) pic_display = NULL; #endif + if (pic_display) { if ((num_pic_not_yet_display > pic_display->num_reorder_pic) @@ -5228,12 +4853,6 @@ "write HEVC_DBLK_CFG3 to %x\n", READ_VREG(HEVC_DBLK_CFG3)); } #endif -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW); - WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, hevc->frame_dw_mmu_map_phy_addr); - } -#endif /* cfg_p_addr */ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start); /* cfg_d_addr */ @@ -5373,13 +4992,9 @@ 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(hevc->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); - } + 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); @@ -5525,6 +5140,7 @@ WRITE_VREG(HEVCD_IPP_TOP_CNTL, (1 << 1) | /* enable ipp */ (0 << 0) /* software reset ipp and mpp */ ); + } #ifdef CONFIG_HEVC_CLK_FORCED_ON @@ -5911,7 +5527,6 @@ int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16; struct PIC_s *cur_pic = hevc->cur_pic; struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; - int dw_mode = get_double_write_mode(hevc); data32 = READ_VREG(HEVC_SAO_CTRL0); data32 &= (~0xf); @@ -5928,50 +5543,34 @@ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); #ifdef LOSLESS_COMPRESS_MODE /*SUPPORT_10BIT*/ - if ((dw_mode & 0x10) == 0) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) - WRITE_VREG(HEVC_SAO_CTRL26, 0); - + if ((get_double_write_mode(hevc) & 0x10) == 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 (hevc->mem_saving_mode == 1) - data32 |= (1 << 9); - else - data32 &= ~(1 << 9); - if (workaround_enable & 1) - data32 |= (1 << 7); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - } + if (get_double_write_mode(hevc) == 2 || + get_double_write_mode(hevc) == 3) + data32 |= (0xff<<16); + else if (get_double_write_mode(hevc) == 4 || + get_double_write_mode(hevc) == 5) + data32 |= (0x33<<16); + + if (hevc->mem_saving_mode == 1) + data32 |= (1 << 9); + else + data32 &= ~(1 << 9); + if (workaround_enable & 1) + data32 |= (1 << 7); + WRITE_VREG(HEVC_SAO_CTRL5, data32); } data32 = cur_pic->mc_y_adr; - if (dw_mode && ((dw_mode & 0x20) == 0)) + if (get_double_write_mode(hevc)) WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr); - if ((dw_mode & 0x10) == 0) + if ((get_double_write_mode(hevc) & 0x10) == 0) WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32); if (hevc->mmu_enable) WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr); -#ifdef H265_10B_MMU_DW - if (hevc->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, cur_pic->header_dw_adr); - } -#endif #else data32 = cur_pic->mc_y_adr; WRITE_VREG(HEVC_SAO_Y_START_ADDR, data32); @@ -5981,7 +5580,7 @@ #ifdef LOSLESS_COMPRESS_MODE /*SUPPORT_10BIT*/ - if (dw_mode && ((dw_mode & 0x20) == 0)) + if (get_double_write_mode(hevc)) WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr); #else data32 = cur_pic->mc_u_v_adr; @@ -5990,20 +5589,9 @@ data32 = (mc_buffer_size_u_v_h << 16); WRITE_VREG(HEVC_SAO_C_LENGTH, data32); - if (hevc->is_used_v4l) { - WRITE_VREG(HEVC_SAO_Y_LENGTH, cur_pic->luma_size); - WRITE_VREG(HEVC_SAO_C_LENGTH, cur_pic->chroma_size); - if (debug & PRINT_FLAG_V4L_DETAIL) { - pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n", - v4l2_ctx->id, cur_pic->index, - cur_pic->dw_y_adr, cur_pic->luma_size, - cur_pic->dw_u_v_adr, cur_pic->chroma_size); - } - } - #ifdef LOSLESS_COMPRESS_MODE /*SUPPORT_10BIT*/ - if (dw_mode && ((dw_mode & 0x20) == 0)) { + if (get_double_write_mode(hevc)) { WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr); WRITE_VREG(HEVC_SAO_C_WPTR, cur_pic->dw_u_v_adr); } @@ -6027,9 +5615,9 @@ if (hevc->pic_w >= 1280) data32 |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/ data32 &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/ - if (dw_mode == 0) + if (get_double_write_mode(hevc) == 0) data32 |= (0x1 << 8); /*enable first write*/ - else if (dw_mode == 0x10) + else if (get_double_write_mode(hevc) == 0x10) data32 |= (0x1 << 9); /*double write only*/ else data32 |= ((0x1 << 8) |(0x1 << 9)); @@ -6056,7 +5644,7 @@ data32 |= (hevc->lcu_size == 64) ? 0 : ((hevc->lcu_size == 32) ? 1 : 2); - data32 |= (hevc->pic_w <= 64) ? (1 << 20) : 0; + WRITE_VREG(HEVC_DBLK_CFG1, data32); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { @@ -6093,19 +5681,19 @@ /* m8baby test1902 */ data32 = READ_VREG(HEVC_SAO_CTRL1); data32 &= (~0x3000); - /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */ - data32 |= (hevc->mem_map_mode << 12); + data32 |= (hevc->mem_map_mode << + 12); + +/* [13:12] axi_aformat, 0-Linear, + * 1-32x32, 2-64x32 + */ data32 &= (~0xff0); -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable == 0) - data32 |= ((hevc->endian >> 8) & 0xfff); -#else - data32 |= ((hevc->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */ -#endif + /* data32 |= 0x670; // Big-Endian per 64-bit */ + data32 |= endian; /* Big-Endian per 64-bit */ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ - if (dw_mode == 0) + if (get_double_write_mode(hevc) == 0) data32 |= 0x2; /*disable double write*/ - else if (dw_mode & 0x10) + else if (get_double_write_mode(hevc) & 0x10) data32 |= 0x1; /*disable cm*/ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { unsigned int data; @@ -6114,9 +5702,9 @@ if (hevc->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) + if (get_double_write_mode(hevc) == 0) data |= (0x1 << 8); /*enable first write*/ - else if (dw_mode & 0x10) + else if (get_double_write_mode(hevc) & 0x10) data |= (0x1 << 9); /*double write only*/ else data |= ((0x1 << 8) |(0x1 << 9)); @@ -6133,8 +5721,7 @@ else data32 |= (1 << 8); /* NV12 */ } - data32 &= (~(3 << 14)); - data32 |= (2 << 14); + /* * [31:24] ar_fifo1_axi_thred * [23:16] ar_fifo0_axi_thred @@ -6147,8 +5734,9 @@ * [1] dw_disable:disable double write output * [0] cm_disable:disable compress output */ + WRITE_VREG(HEVC_SAO_CTRL1, data32); - if (dw_mode & 0x10) { + if (get_double_write_mode(hevc) & 0x10) { /* [23:22] dw_v1_ctrl *[21:20] dw_v0_ctrl *[19:18] dw_h1_ctrl @@ -6163,9 +5751,11 @@ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); data32 &= (~0x30); /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */ - data32 |= (hevc->mem_map_mode << 4); + data32 |= (hevc->mem_map_mode << + 4); data32 &= (~0xF); - data32 |= (hevc->endian & 0xf); /* valid only when double write only */ + data32 |= 0xf; /* valid only when double write only */ + /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ /* swap uv */ if (hevc->is_used_v4l) { @@ -6175,8 +5765,7 @@ else data32 &= ~(1 << 12); /* NV12 */ } - data32 &= (~(3 << 8)); - data32 |= (2 << 8); + /* * [3:0] little_endian * [5:4] address_format 00:linear 01:32x32 10:64x32 @@ -6298,9 +5887,7 @@ if (alloc_pic_count > work_pic_num) { pic->width = 0; pic->height = 0; - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); release_pic_mmu_buf(hevc, pic); - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); pic->index = -1; } else { pic->width = hevc->pic_w; @@ -6416,21 +6003,6 @@ return NULL; } } -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - ret = H265_alloc_mmu_dw(hevc, new_pic, - rpm_param->p.bit_depth, - hevc->frame_dw_mmu_map_addr); - if (ret != 0) { - put_mv_buf(hevc, new_pic); - hevc_print(hevc, 0, - "can't alloc need mmu_dw_1,idx %d ret =%d\n", - new_pic->decode_idx, - ret); - return NULL; - } - } -#endif new_pic->referenced = 1; new_pic->decode_idx = hevc->decode_idx; new_pic->slice_idx = 0; @@ -6486,24 +6058,6 @@ return new_pic; } -static int get_free_fb_idx(struct hevc_state_s *hevc) -{ - int i; - - for (i = 0; i < MAX_REF_PIC_NUM; ++i) { - if (hevc->m_PIC[i] == NULL) - continue; - - if ((hevc->m_PIC[i]->referenced == 0) && - (hevc->m_PIC[i]->vf_ref == 0) && - (!hevc->m_PIC[i]->cma_alloc_addr)) - break; - } - - return (hevc->m_PIC[i] && - (i != MAX_REF_PIC_NUM)) ? i : -1; -} - static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc, union param_u *rpm_param) { @@ -6513,7 +6067,7 @@ struct v4l_buff_pool *pool = &v4l->cap_pool; struct PIC_s *new_pic = NULL; struct PIC_s *pic = NULL; - int i, j, idx; + int i; for (i = 0; i < pool->in; ++i) { u32 state = (pool->seq[i] >> 16); @@ -6521,37 +6075,22 @@ switch (state) { case V4L_CAP_BUFF_IN_DEC: - for (j = 0; j < MAX_REF_PIC_NUM; j++) { - pic = hevc->m_PIC[j]; - if (pic == NULL || pic->index == -1) - continue; - - if (pic->output_mark == 0 && - pic->referenced == 0 && - pic->output_ready == 0 && - pic->width == hevc->pic_w && - pic->height == hevc->pic_h && - pic->vf_ref == 0 && - pic->cma_alloc_addr) { - if (new_pic) { - if (new_pic->POC != INVALID_POC) { - if (pic->POC == INVALID_POC || - pic->POC < new_pic->POC) - new_pic = pic; - } - } else - new_pic = pic; - } + pic = hevc->m_PIC[i]; + if (pic && (pic->index != -1) && + (pic->output_mark == 0) && + (pic->referenced == 0) && + (pic->output_ready == 0) && + (pic->width == hevc->pic_w) && + (pic->height == hevc->pic_h) && + (pic->vf_ref == 0) && + pic->cma_alloc_addr) { + new_pic = pic; } break; case V4L_CAP_BUFF_IN_M2M: - idx = get_free_fb_idx(hevc); - if (idx < 0) - break; - pic = hevc->m_PIC[idx]; + pic = hevc->m_PIC[index]; pic->width = hevc->pic_w; pic->height = hevc->pic_h; - hevc->buffer_wrap[idx] = index; if ((pic->index != -1) && !v4l_alloc_buf(hevc, pic)) { v4l_config_pic(hevc, pic); @@ -6601,10 +6140,10 @@ new_pic->dis_mark = 0; /* new_pic->output_ready = 0; */ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; - new_pic->ip_mode = hevc->low_latency_flag ? true : - (!new_pic->num_reorder_pic && - !(vdec->slave || vdec->master) && - !disable_ip_mode) ? true : false; + new_pic->ip_mode = (!new_pic->num_reorder_pic && + !(vdec->slave || vdec->master) && + !disable_ip_mode && + hevc->low_latency_flag) ? true : false; new_pic->losless_comp_body_size = hevc->losless_comp_body_size; new_pic->POC = hevc->curr_POC; new_pic->pic_struct = hevc->curr_pic_struct; @@ -6633,14 +6172,7 @@ new_pic->chroma_format_idc = hevc->param.p.chroma_format_idc; - if (new_pic) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)new_pic->cma_alloc_addr; - - fb->status = FB_ST_DECODER; - } - - hevc_print(hevc, H265_DEBUG_BUFMGR, + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, "%s: index %d, buf_idx %d, decode_idx %d, POC %d\n", __func__, new_pic->index, new_pic->BUF_index, new_pic->decode_idx, @@ -6796,7 +6328,7 @@ aux_size = hevc->prefix_aux_size; } - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) { + if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { hevc_print(hevc, 0, "%s:pic 0x%p old size %d count %d,suf %d dv_flag %d\r\n", __func__, pic, pic->aux_data_size, @@ -6905,7 +6437,7 @@ h[6] = (padding_len >> 8) & 0xff; h[7] = (padding_len) & 0xff; } - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) { + if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { hevc_print(hevc, 0, "aux: (size %d) suffix_flag %d\n", pic->aux_data_size, suffix_flag); @@ -6941,39 +6473,6 @@ pic->aux_data_size = 0; } -static int recycle_mmu_buf_tail(struct hevc_state_s *hevc, - bool check_dma) -{ - hevc_print(hevc, - H265_DEBUG_BUFMGR_MORE, - "%s pic index %d scatter_alloc %d page_start %d\n", - "decoder_mmu_box_free_idx_tail", - hevc->cur_pic->index, - hevc->cur_pic->scatter_alloc, - hevc->used_4k_num); - if (check_dma) - hevc_mmu_dma_check(hw_to_vdec(hevc)); - - if (hevc->is_used_v4l) { - int index = hevc->cur_pic->BUF_index; - struct internal_comp_buf *ibuf = - index_to_icomp_buf(hevc, index); - - decoder_mmu_box_free_idx_tail( - ibuf->mmu_box, - ibuf->index, - hevc->used_4k_num); - } else { - decoder_mmu_box_free_idx_tail( - hevc->mmu_box, - hevc->cur_pic->index, - hevc->used_4k_num); - } - hevc->cur_pic->scatter_alloc = 2; - hevc->used_4k_num = -1; - return 0; -} - static inline void hevc_pre_pic(struct hevc_state_s *hevc, struct PIC_s *pic) { @@ -7022,10 +6521,22 @@ (hevc->used_4k_num >= 0) && (hevc->cur_pic->scatter_alloc == 1)) { - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); - recycle_mmu_buf_tail(hevc, true); - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } + hevc_print(hevc, + H265_DEBUG_BUFMGR_MORE, + "%s pic index %d scatter_alloc %d page_start %ld\n", + "decoder_mmu_box_free_idx_tail", + hevc->cur_pic->index, + hevc->cur_pic->scatter_alloc, + hevc->used_4k_num); + hevc_mmu_dma_check(hw_to_vdec(hevc)); + decoder_mmu_box_free_idx_tail( + hevc->mmu_box, + hevc->cur_pic->index, + hevc->used_4k_num); + hevc->cur_pic->scatter_alloc + = 2; + } + hevc->used_4k_num = -1; } } if (!pic->ip_mode) @@ -7113,7 +6624,7 @@ hevc_print(hevc, 0, "clear referenced flag of all buffers\n"); } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) + if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) dump_pic_list(hevc); if (hevc->vf_pre_count == 1 && hevc->first_pic_flag == 1) { @@ -7674,14 +7185,17 @@ union param_u *rpm_param, int decode_pic_begin) { -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION struct vdec_s *vdec = hw_to_vdec(hevc); -#endif int i; int lcu_x_num_div; int lcu_y_num_div; int Col_ref; int dbg_skip_flag = 0; + struct aml_vcodec_ctx *ctx = + (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); + + if (hevc->is_used_v4l && ctx->param_sets_from_ucode) + hevc->res_ch_flag = 0; if (hevc->wait_buf == 0) { hevc->sps_num_reorder_pics_0 = @@ -7695,22 +7209,11 @@ (rpm_param->p.profile_etc >> 2) & 0x1; hevc->curr_pic_struct = (rpm_param->p.sei_frame_field_info >> 3) & 0xf; - hevc->frame_field_info_present_flag = - (rpm_param->p.sei_frame_field_info >> 8) & 0x1; - - if (hevc->frame_field_info_present_flag) { - if (hevc->curr_pic_struct == 0 - || hevc->curr_pic_struct == 7 - || hevc->curr_pic_struct == 8) - hevc->interlace_flag = 0; + if (parser_sei_enable & 0x4) { + hevc->frame_field_info_present_flag = + (rpm_param->p.sei_frame_field_info >> 8) & 0x1; } - hevc_print(hevc, H265_DEBUG_PIC_STRUCT, - "frame_field_info_present_flag = %d curr_pic_struct = %d interlace_flag = %d\n", - hevc->frame_field_info_present_flag, - hevc->curr_pic_struct, - hevc->interlace_flag); - /* if (interlace_enable == 0 || hevc->m_ins_flag) */ if (interlace_enable == 0) hevc->interlace_flag = 0; @@ -7765,7 +7268,6 @@ rpm_param->p.pic_width_in_luma_samples, rpm_param->p.pic_height_in_luma_samples, hevc->interlace_flag); - hevc->pic_w = rpm_param->p.pic_width_in_luma_samples; hevc->pic_h = rpm_param->p.pic_height_in_luma_samples; hevc->frame_width = hevc->pic_w; @@ -7932,7 +7434,7 @@ /**/ /* if((iPrevPOC != curr_POC)){ */ if (rpm_param->p.slice_segment_address == 0) { - struct PIC_s *pic = NULL; + struct PIC_s *pic; hevc->new_pic = 1; #ifdef MULTI_INSTANCE_SUPPORT @@ -7941,10 +7443,6 @@ check_pic_decoded_error_pre(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff); - if (vdec_stream_based(vdec) && ((READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff) != 0)) { - if (hevc->cur_pic) - hevc->cur_pic->error_mark = 1; - } /**/ if (use_cma == 0) { if (hevc->pic_list_init_flag == 0) { init_pic_list(hevc); @@ -8001,7 +7499,7 @@ v4l_get_new_pic(hevc, rpm_param) : get_new_pic(hevc, rpm_param); if (hevc->cur_pic == NULL) { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) + if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) dump_pic_list(hevc); hevc->wait_buf = 1; return -1; @@ -8323,7 +7821,7 @@ || (dbg_skip_flag)) return 0xf; #endif - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START); + config_mc_buffer(hevc, hevc->cur_pic); if (is_skip_decoding(hevc, @@ -8371,7 +7869,7 @@ config_mpred_hw(hevc); config_sao_hw(hevc, rpm_param); - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END); + if ((hevc->slice_type != 2) && (hevc->i_only & 0x2)) return 0xf; @@ -8381,106 +7879,50 @@ return 0; } -/* return page number */ -static int hevc_mmu_page_num(struct hevc_state_s *hevc, - int w, int h, int save_mode) -{ - int picture_size; - int page_num; - int max_frame_num; - picture_size = compute_losless_comp_body_size(hevc, w, - h, save_mode); - page_num = ((picture_size + PAGE_SIZE - 1) >> PAGE_SHIFT); + +static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic, + unsigned short bit_depth, unsigned int *mmu_index_adr) { + int cur_buf_idx = new_pic->index; + int bit_depth_10 = (bit_depth != 0x00); + int picture_size; + int cur_mmu_4k_number; + int ret, max_frame_num; + picture_size = compute_losless_comp_body_size(hevc, new_pic->width, + new_pic->height, !bit_depth_10); + cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12); + if (get_double_write_mode(hevc) == 0x10) + return 0; + /*hevc_print(hevc, 0, + "alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n", + cur_buf_idx, picture_size, cur_mmu_4k_number);*/ 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 (page_num > max_frame_num) { + if (cur_mmu_4k_number > max_frame_num) { hevc_print(hevc, 0, "over max !! 0x%x width %d height %d\n", - page_num, w, h); + cur_mmu_4k_number, + new_pic->width, + new_pic->height); return -1; } - return page_num; -} - -static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic, - unsigned short bit_depth, unsigned int *mmu_index_adr) { - int bit_depth_10 = (bit_depth != 0x00); - int cur_mmu_4k_number; - int ret; - - if (get_double_write_mode(hevc) == 0x10) - return 0; - - cur_mmu_4k_number = hevc_mmu_page_num(hevc, new_pic->width, - new_pic->height, !bit_depth_10); - if (cur_mmu_4k_number < 0) - return -1; - - if (hevc->is_used_v4l) { - struct internal_comp_buf *ibuf = - index_to_icomp_buf(hevc, new_pic->BUF_index); - - ret = decoder_mmu_box_alloc_idx( - ibuf->mmu_box, - ibuf->index, - ibuf->frame_buffer_size, - mmu_index_adr); - } else { - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); - ret = decoder_mmu_box_alloc_idx( - hevc->mmu_box, - new_pic->index, - cur_mmu_4k_number, - mmu_index_adr); - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } + ret = decoder_mmu_box_alloc_idx( + hevc->mmu_box, + cur_buf_idx, + cur_mmu_4k_number, + mmu_index_adr); new_pic->scatter_alloc = 1; hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, "%s pic index %d page count(%d) ret =%d\n", - __func__, new_pic->index, + __func__, cur_buf_idx, cur_mmu_4k_number, ret); return ret; } -#ifdef H265_10B_MMU_DW -static int H265_alloc_mmu_dw(struct hevc_state_s *hevc, struct PIC_s *new_pic, - unsigned short bit_depth, unsigned int *mmu_index_adr) { - int bit_depth_10 = (bit_depth != 0x00); - int cur_mmu_4k_number; - int ret; - if (!hevc->mmu_box_dw) { - hevc_print(hevc, 0, - "%s, error no mmu box dw!\n", __func__); - return -1; - } - - if (get_double_write_mode(hevc) == 0x10) - return 0; - - cur_mmu_4k_number = hevc_mmu_page_num(hevc, new_pic->width, - new_pic->height, !bit_depth_10); - if (cur_mmu_4k_number < 0) - return -1; - - ret = decoder_mmu_box_alloc_idx( - hevc->mmu_box_dw, - new_pic->index, - cur_mmu_4k_number, - mmu_index_adr); - - hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, - "%s pic index %d page count(%d) ret =%d\n", - __func__, new_pic->index, - cur_mmu_4k_number, ret); - return ret; -} -#endif static void release_pic_mmu_buf(struct hevc_state_s *hevc, struct PIC_s *pic) @@ -8491,20 +7933,9 @@ pic->scatter_alloc); if (hevc->mmu_enable - && !(hevc->double_write_mode & 0x10) - && pic->scatter_alloc) { - if (!hevc->is_used_v4l) - decoder_mmu_box_free_idx(hevc->mmu_box, pic->index); - else { - struct internal_comp_buf *ibuf = - ibuf = index_to_icomp_buf(hevc, pic->BUF_index); - decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index); - } - } -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) - decoder_mmu_box_free_idx(hevc->mmu_box_dw, pic->index); -#endif + && ((hevc->double_write_mode & 0x10) == 0) + && pic->scatter_alloc) + decoder_mmu_box_free_idx(hevc->mmu_box, pic->index); pic->scatter_alloc = 0; } @@ -8564,16 +7995,7 @@ hevc->frame_mmu_map_addr = NULL; } -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable && hevc->frame_dw_mmu_map_addr) { - if (hevc->frame_dw_mmu_map_phy_addr) - dma_free_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(), hevc->frame_dw_mmu_map_addr, - hevc->frame_dw_mmu_map_phy_addr); - hevc->frame_dw_mmu_map_addr = NULL; - } -#endif //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs); } @@ -8585,34 +8007,20 @@ memset(&hevc->param, 0, sizeof(union param_u)); cur_buf_info = &hevc->work_space_buf_store; - if (force_bufspec) { memcpy(cur_buf_info, &amvh265_workbuff_spec[force_bufspec & 0xf], sizeof(struct BuffInfo_s)); 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) - memcpy(cur_buf_info, &amvh265_workbuff_spec[2], /* 4k */ - sizeof(struct BuffInfo_s)); - else - memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k */ - sizeof(struct BuffInfo_s)); - } else { - memcpy(cur_buf_info, &amvh265_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()) { - memcpy(cur_buf_info, &amvh265_workbuff_spec[5], /* 4k */ - sizeof(struct BuffInfo_s)); - } else { - memcpy(cur_buf_info, &amvh265_workbuff_spec[3], /* 1080p */ - sizeof(struct BuffInfo_s)); - } - } - } + } else if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + memcpy(cur_buf_info, &amvh265_workbuff_spec[2], /* 4k */ + sizeof(struct BuffInfo_s)); + else + memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k */ + sizeof(struct BuffInfo_s)); + } else + memcpy(cur_buf_info, &amvh265_workbuff_spec[0], /* 1080p */ + sizeof(struct BuffInfo_s)); cur_buf_info->start_adr = hevc->buf_start; init_buff_spec(hevc, cur_buf_info); @@ -8671,19 +8079,6 @@ } memset(hevc->frame_mmu_map_addr, 0, get_frame_mmu_map_size()); } -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - hevc->frame_dw_mmu_map_addr = - dma_alloc_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(), - &hevc->frame_dw_mmu_map_phy_addr, GFP_KERNEL); - if (hevc->frame_dw_mmu_map_addr == NULL) { - pr_err("%s: failed to alloc count_buffer\n", __func__); - return -1; - } - memset(hevc->frame_dw_mmu_map_addr, 0, get_frame_mmu_map_size()); - } -#endif ret = 0; return ret; } @@ -8720,14 +8115,16 @@ /*CANVAS_BLKMODE_64X32*/ #ifdef SUPPORT_10BIT - if (pic->double_write_mode && - ((pic->double_write_mode & 0x20) == 0)) { + if (pic->double_write_mode) { canvas_w = pic->width / - get_double_write_ratio(pic->double_write_mode & 0xf); + get_double_write_ratio(hevc, pic->double_write_mode); canvas_h = pic->height / - get_double_write_ratio(pic->double_write_mode & 0xf); + get_double_write_ratio(hevc, pic->double_write_mode); - canvas_w = ALIGN(canvas_w, 64); + if (hevc->mem_map_mode == 0) + canvas_w = ALIGN(canvas_w, 32); + else + canvas_w = ALIGN(canvas_w, 64); canvas_h = ALIGN(canvas_h, 32); if (vdec->parallel_dec == 1) { @@ -8740,12 +8137,12 @@ pic->uv_canvas_index = 128 + pic->index * 2 + 1; } - config_cav_lut_ex(pic->y_canvas_index, + canvas_config_ex(pic->y_canvas_index, pic->dw_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); - config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr, + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); + canvas_config_ex(pic->uv_canvas_index, pic->dw_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); #ifdef MULTI_INSTANCE_SUPPORT pic->canvas_config[0].phy_addr = pic->dw_y_adr; @@ -8767,11 +8164,11 @@ blkmode; pic->canvas_config[1].endian = hevc->is_used_v4l ? 0 : 7; - ATRACE_COUNTER(hevc->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr); + ATRACE_COUNTER(hevc->set_canvas0_addr, pic->canvas_config[0].phy_addr); hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n", __func__, pic->canvas_config[0].phy_addr); #else - ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic)); + ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic)); hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n", __func__, spec2canvas(pic)); #endif @@ -8787,14 +8184,14 @@ pic->uv_canvas_index = 128 + pic->index; } - config_cav_lut_ex(pic->y_canvas_index, + canvas_config_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); - config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr, + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); + canvas_config_ex(pic->uv_canvas_index, pic->mc_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); } - ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic)); + ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic)); hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n", __func__, spec2canvas(pic)); } @@ -8810,13 +8207,13 @@ } - config_cav_lut_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); - config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr, + canvas_config_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h, + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); + canvas_config_ex(pic->uv_canvas_index, pic->mc_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7); - ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic)); + ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic)); hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n", __func__, spec2canvas(pic)); #endif @@ -8850,8 +8247,8 @@ char *p = sei_buf; char *p_sei; uint16_t header; - uint16_t nal_unit_type; - uint16_t payload_type, payload_size; + uint8_t nal_unit_type; + uint8_t payload_type, payload_size; int i, j; if (size < 2) @@ -8863,16 +8260,9 @@ if ((nal_unit_type != NAL_UNIT_SEI) && (nal_unit_type != NAL_UNIT_SEI_SUFFIX)) return 0; - while (p+4 <= sei_buf+size) { + while (p+2 <= sei_buf+size) { payload_type = *p++; - if (payload_type == 0xff) { - payload_type += *p++; - } payload_size = *p++; - if (payload_size == 0xff) { - payload_size += *p++; - } - if (p+payload_size <= sei_buf+size) { switch (payload_type) { case SEI_PicTiming: @@ -8911,25 +8301,6 @@ pic->hdr10p_data_buf = NULL; pic->hdr10p_data_size = 0; } - } else if (p_sei[0] == 0x26 - && p_sei[1] == 0x00 - && p_sei[2] == 0x04 - && p_sei[3] == 0x00 - && p_sei[4] == 0x05) { - hevc->sei_present_flag |= SEI_HDR_CUVA_MASK; - - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) { - hevc_print(hevc, 0, - "hdr cuva data: (size %d)\n", - payload_size); - for (i = 0; i < payload_size; i++) { - hevc_print_cont(hevc, 0, - "%02x ", p_sei[i]); - if (((i + 1) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - hevc_print_cont(hevc, 0, "\n"); - } } break; @@ -9089,9 +8460,9 @@ = &vf->prop.master_display_colour; vf->width = pic->width / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(hevc, pic->double_write_mode); vf->height = pic->height / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(hevc, pic->double_write_mode); vf->duration = hevc->frame_dur; vf->duration_pulldown = 0; @@ -9149,14 +8520,6 @@ data = data | (0x30<<8); vf->signal_type = data; } - - if (hevc->sei_present_flag & SEI_HDR_CUVA_MASK) { - u32 data; - data = vf->signal_type; - data = data & 0x7FFFFFFF; - data = data | (1<<31); - vf->signal_type = data; - } } else vf->signal_type = 0; @@ -9187,8 +8550,7 @@ vf_dp->content_light_level.present_flag = 0; if (hevc->is_used_v4l && - ((hevc->video_signal_type & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) || - (hevc->sei_present_flag & SEI_HDR10PLUS_MASK) || + ((hevc->sei_present_flag & SEI_HDR10PLUS_MASK) || (vf_dp->present_flag) || (vf_dp->content_light_level.present_flag))) { struct aml_vdec_hdr_infos hdr; @@ -9203,34 +8565,32 @@ if ((hevc->sei_present_flag & SEI_HDR10PLUS_MASK) && (pic->hdr10p_data_buf != NULL) && (pic->hdr10p_data_size != 0)) { - if (pic->hdr10p_data_size <= 128) { - char *new_buf; - new_buf = kzalloc(pic->hdr10p_data_size, GFP_ATOMIC); + char *new_buf; + new_buf = vzalloc(pic->hdr10p_data_size); - if (new_buf) { - memcpy(new_buf, pic->hdr10p_data_buf, pic->hdr10p_data_size); - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) { - hevc_print(hevc, 0, - "hdr10p data: (size %d)\n", - pic->hdr10p_data_size); - for (i = 0; i < pic->hdr10p_data_size; i++) { - hevc_print_cont(hevc, 0, - "%02x ", pic->hdr10p_data_buf[i]); - if (((i + 1) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - hevc_print_cont(hevc, 0, "\n"); - } - - vf->hdr10p_data_size = pic->hdr10p_data_size; - vf->hdr10p_data_buf = new_buf; - } else { + if (new_buf) { + memcpy(new_buf, pic->hdr10p_data_buf, pic->hdr10p_data_size); + if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { hevc_print(hevc, 0, - "%s:hdr10p data vzalloc size(%d) fail\n", - __func__, pic->hdr10p_data_size); - vf->hdr10p_data_buf = NULL; - vf->hdr10p_data_size = 0; + "hdr10p data: (size %d)\n", + pic->hdr10p_data_size); + for (i = 0; i < pic->hdr10p_data_size; i++) { + hevc_print_cont(hevc, 0, + "%02x ", pic->hdr10p_data_buf[i]); + if (((i + 1) & 0xf) == 0) + hevc_print_cont(hevc, 0, "\n"); + } + hevc_print_cont(hevc, 0, "\n"); } + + vf->hdr10p_data_size = pic->hdr10p_data_size; + vf->hdr10p_data_buf = new_buf; + } else { + hevc_print(hevc, 0, + "%s:hdr10p data vzalloc size(%d) fail\n", + __func__, pic->hdr10p_data_size); + vf->hdr10p_data_buf = NULL; + vf->hdr10p_data_size = 0; } vfree(pic->hdr10p_data_buf); @@ -9316,7 +8676,6 @@ return NULL; else if (step == 1) step = 2; - #if 0 if (force_disp_pic_index & 0x100) { int buffer_index = force_disp_pic_index & 0xff; @@ -9381,9 +8740,9 @@ set_frame_info(hevc, vf); vf->width = pic->width / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(hevc, pic->double_write_mode); vf->height = pic->height / - get_double_write_ratio(pic->double_write_mode); + get_double_write_ratio(hevc, pic->double_write_mode); force_disp_pic_index |= 0x200; return vf; @@ -9393,17 +8752,17 @@ if (kfifo_get(&hevc->display_q, &vf)) { struct vframe_s *next_vf = NULL; - ATRACE_COUNTER(hevc->trace.vf_get_name, (long)vf); - ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q)); + ATRACE_COUNTER(hevc->vf_get_name, (long)vf); + ATRACE_COUNTER(hevc->disp_q_name, kfifo_len(&hevc->display_q)); #ifdef MULTI_INSTANCE_SUPPORT - ATRACE_COUNTER(hevc->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr); + ATRACE_COUNTER(hevc->set_canvas0_addr, vf->canvas0_config[0].phy_addr); #else - ATRACE_COUNTER(hevc->trace.get_canvas0_addr, vf->canvas0Addr); + ATRACE_COUNTER(hevc->get_canvas0_addr, vf->canvas0Addr); #endif if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) { hevc_print(hevc, 0, - "%s(vf 0x%p type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", + "%s(vf 0x%p type %d index 0x%x poc %d/%d) pts(%d,%ld) dur %d\n", __func__, vf, vf->type, vf->index, get_pic_poc(hevc, vf->index & 0xff), get_pic_poc(hevc, (vf->index >> 8) & 0xff), @@ -9433,8 +8792,8 @@ } #endif hevc->show_frame_num++; - vf->index_disp = atomic_read(&hevc->vf_get_count); - atomic_add(1, &hevc->vf_get_count); + vf->index_disp = hevc->vf_get_count; + hevc->vf_get_count++; if (kfifo_peek(&hevc->display_q, &next_vf) && next_vf) { vf->next_vf_pts_valid = true; @@ -9472,39 +8831,23 @@ unsigned char index_top; unsigned char index_bot; - if (!vf) + if (vf && (vf_valid_check(vf, hevc) == false)) return; if (vf == (&hevc->vframe_dummy)) return; - if (vf && (vf_valid_check(vf, hevc) == false)) + if (!vf) return; - if (hevc->enable_fence && vf->fence) { - int ret, i; - - mutex_lock(&hevc->fence_mutex); - ret = dma_fence_get_status(vf->fence); - if (ret == 0) { - for (i = 0; i < VF_POOL_SIZE; i++) { - if (hevc->fence_vf_s.fence_vf[i] == NULL) { - hevc->fence_vf_s.fence_vf[i] = vf; - hevc->fence_vf_s.used_size++; - mutex_unlock(&hevc->fence_mutex); - return; - } - } - } - mutex_unlock(&hevc->fence_mutex); - } - - ATRACE_COUNTER(hevc->trace.vf_put_name, (long)vf); + ATRACE_COUNTER(hevc->vf_put_name, (long)vf); #ifdef MULTI_INSTANCE_SUPPORT - ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr); + ATRACE_COUNTER(hevc->put_canvas0_addr, vf->canvas0_config[0].phy_addr); #else - ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0Addr); + ATRACE_COUNTER(hevc->put_canvas0_addr, vf->canvas0Addr); #endif + index_top = vf->index & 0xff; index_bot = (vf->index >> 8) & 0xff; + if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) hevc_print(hevc, 0, "%s(vf 0x%p type %d index 0x%x put canvas0 addr:0x%x)\n", @@ -9515,25 +8858,27 @@ , vf->canvas0Addr #endif ); - atomic_add(1, &hevc->vf_put_count); + + hevc->vf_put_count++; spin_lock_irqsave(&lock, flags); kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q)); + ATRACE_COUNTER(hevc->new_q_name, kfifo_len(&hevc->newframe_q)); if (hevc->enable_fence && vf->fence) { vdec_fence_put(vf->fence); vf->fence = NULL; } if (vf->hdr10p_data_buf) { - kfree(vf->hdr10p_data_buf); + vfree(vf->hdr10p_data_buf); vf->hdr10p_data_buf = NULL; vf->hdr10p_data_size = 0; } - if (index_top != 0xff && index_top < MAX_REF_PIC_NUM && hevc->m_PIC[index_top]) { + if (hevc->is_used_v4l) + hevc->m_PIC[index_top]->vframe_bound = true; if (hevc->m_PIC[index_top]->vf_ref > 0) { hevc->m_PIC[index_top]->vf_ref--; @@ -9551,6 +8896,8 @@ if (index_bot != 0xff && index_bot < MAX_REF_PIC_NUM && hevc->m_PIC[index_bot]) { + if (hevc->is_used_v4l) + hevc->m_PIC[index_bot]->vframe_bound = true; if (hevc->m_PIC[index_bot]->vf_ref > 0) { hevc->m_PIC[index_bot]->vf_ref--; @@ -9597,14 +8944,13 @@ unsigned char index; if (!req->vf) { - req->aux_size = atomic_read(&hevc->vf_put_count); + req->aux_size = hevc->vf_put_count; return 0; } spin_lock_irqsave(&lock, flags); index = req->vf->index & 0xff; req->aux_buf = NULL; req->aux_size = 0; - req->format = VFORMAT_HEVC; if (req->bot_flag) index = (req->vf->index >> 8) & 0xff; if (index != 0xff @@ -9677,8 +9023,6 @@ if (kfifo_len(&hevc->pending_q) > 1) { unsigned long flags; - int index1; - int index2; /* do not pending more than 1 frame */ if (kfifo_get(&hevc->pending_q, &vf) == 0) { hevc_print(hevc, 0, @@ -9687,45 +9031,34 @@ } if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) hevc_print(hevc, 0, - "%s warning(1), vf=>display_q: (index 0x%x), vf 0x%px\n", - __func__, vf->index, vf); + "%s warning(1), vf=>display_q: (index 0x%x)\n", + __func__, vf->index); if ((pair_pic->double_write_mode == 3) && (!(IS_8K_SIZE(vf->width, vf->height)))) { vf->type |= VIDTYPE_COMPRESS; if (hevc->mmu_enable) vf->type |= VIDTYPE_SCATTER; } - hevc->vf_pre_count++; spin_lock_irqsave(&lock, flags); kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf); - index1 = vf->index & 0xff; - index2 = (vf->index >> 8) & 0xff; - if (index1 >= MAX_REF_PIC_NUM && - index2 >= MAX_REF_PIC_NUM) { + vf->index &= 0xff; + if (vf->index >= MAX_REF_PIC_NUM) { spin_unlock_irqrestore(&lock, flags); return -1; } - - if (index1 < MAX_REF_PIC_NUM) { - hevc->m_PIC[index1]->vf_ref = 0; - hevc->m_PIC[index1]->output_ready = 0; - } - if (index2 < MAX_REF_PIC_NUM) { - hevc->m_PIC[index2]->vf_ref = 0; - hevc->m_PIC[index2]->output_ready = 0; - } - + hevc->m_PIC[vf->index]->vf_ref = 0; + hevc->m_PIC[vf->index]->output_ready = 0; if (hevc->wait_buf != 0) WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1); spin_unlock_irqrestore(&lock, flags); - ATRACE_COUNTER(hevc->trace.pts_name, vf->pts); + ATRACE_COUNTER(hevc->pts_name, vf->pts); } if (kfifo_peek(&hevc->pending_q, &vf)) { - if (pair_pic == NULL || pair_pic->vf_ref <= 0) { + if (pair_pic->vf_ref <= 0) { /* *if pair_pic is recycled (pair_pic->vf_ref <= 0), *do not use it @@ -9750,7 +9083,7 @@ vdec_vframe_ready(hw_to_vdec(hevc), vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hevc->trace.pts_name, vf->pts); + ATRACE_COUNTER(hevc->pts_name, vf->pts); } } else if ((!pair_frame_top_flag) && (((vf->index >> 8) & 0xff) == 0xff)) { @@ -9772,7 +9105,7 @@ vdec_vframe_ready(hw_to_vdec(hevc), vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hevc->trace.pts_name, vf->pts); + ATRACE_COUNTER(hevc->pts_name, vf->pts); hevc->vf_pre_count++; if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) hevc_print(hevc, 0, @@ -9799,7 +9132,7 @@ vdec_vframe_ready(hw_to_vdec(hevc), vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hevc->trace.pts_name, vf->pts); + ATRACE_COUNTER(hevc->pts_name, vf->pts); hevc->vf_pre_count++; if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) hevc_print(hevc, 0, @@ -9814,33 +9147,16 @@ static void update_vf_memhandle(struct hevc_state_s *hevc, struct vframe_s *vf, struct PIC_s *pic) { - vf->mem_handle = NULL; - vf->mem_head_handle = NULL; - - /* keeper not needed for v4l solution */ - if (hevc->is_used_v4l) - return; - - if (vf->type & VIDTYPE_SCATTER) { -#ifdef H265_10B_MMU_DW - if (hevc->dw_mmu_enable) { - vf->mem_handle = - decoder_mmu_box_get_mem_handle( - hevc->mmu_box_dw, pic->index); - vf->mem_head_handle = - decoder_bmmu_box_get_mem_handle( - hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index)); - } else - -#endif - { - vf->mem_handle = - decoder_mmu_box_get_mem_handle( - hevc->mmu_box, pic->index); - vf->mem_head_handle = - decoder_bmmu_box_get_mem_handle( - hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index)); - } + if (pic->index < 0) { + vf->mem_handle = NULL; + vf->mem_head_handle = NULL; + } else if (vf->type & VIDTYPE_SCATTER) { + vf->mem_handle = + decoder_mmu_box_get_mem_handle( + hevc->mmu_box, pic->index); + vf->mem_head_handle = + decoder_bmmu_box_get_mem_handle( + hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index)); } else { vf->mem_handle = decoder_bmmu_box_get_mem_handle( @@ -9912,11 +9228,11 @@ } -static inline void hevc_update_gvs(struct hevc_state_s *hevc, struct PIC_s *pic) +static inline void hevc_update_gvs(struct hevc_state_s *hevc) { - if (hevc->gvs->frame_height != pic->height) { - hevc->gvs->frame_width = pic->width; - hevc->gvs->frame_height = pic->height; + if (hevc->gvs->frame_height != hevc->frame_height) { + hevc->gvs->frame_width = hevc->frame_width; + hevc->gvs->frame_height = hevc->frame_height; } if (hevc->gvs->frame_dur != hevc->frame_dur) { hevc->gvs->frame_dur = hevc->frame_dur; @@ -9938,7 +9254,7 @@ decoder_do_frame_check(hw_to_vdec(hevc), vf); vdec_vframe_ready(hw_to_vdec(hevc), vf); kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hevc->trace.pts_name, vf->pts); + ATRACE_COUNTER(hevc->pts_name, vf->pts); } static int post_prepare_process(struct vdec_s *vdec, struct PIC_s *frame) @@ -9950,7 +9266,7 @@ frame->output_ready = 0; frame->show_frame = false; hevc_print(hevc, 0, "discard show frame.\n"); - return 0; + return -1; } frame->show_frame = true; @@ -9968,8 +9284,6 @@ u32 frame_size = 0; struct vdec_info tmp4x; struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; - int index; /* swap uv */ if (hevc->is_used_v4l) { @@ -9992,12 +9306,11 @@ if (hevc->is_used_v4l) { vf->v4l_mem_handle = hevc->m_BUF[pic->BUF_index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; if (hevc->mmu_enable) { vf->mm_box.bmmu_box = hevc->bmmu_box; - vf->mm_box.bmmu_idx = VF_BUFFER_IDX(hevc->buffer_wrap[pic->BUF_index]); + vf->mm_box.bmmu_idx = VF_BUFFER_IDX(pic->BUF_index); vf->mm_box.mmu_box = hevc->mmu_box; - vf->mm_box.mmu_idx = hevc->buffer_wrap[pic->BUF_index]; + vf->mm_box.mmu_idx = pic->index; } } @@ -10027,8 +9340,7 @@ if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { if (pts_lookup_offset_us64 (PTS_TYPE_VIDEO, stream_offset, &vf->pts, - &frame_size, 0, - &vf->pts_us64) != 0) { + &frame_size, 0, &vf->pts_us64) != 0) { #ifdef DEBUG_PTS hevc->pts_missed++; #endif @@ -10076,8 +9388,8 @@ hevc->last_pts_us64 = vf->pts_us64; if ((get_dbg_flag(hevc) & H265_DEBUG_OUT_PTS) != 0) { hevc_print(hevc, 0, - "H265 dec out pts: vf->pts=%d, vf->pts_us64 = %lld, ts: %llu\n", - vf->pts, vf->pts_us64, vf->timestamp); + "H265 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n", + vf->pts, vf->pts_us64); } /* @@ -10097,44 +9409,26 @@ /* double write only */ vf->compBodyAddr = 0; vf->compHeadAddr = 0; -#ifdef H265_10B_MMU_DW - vf->dwBodyAddr = 0; - vf->dwHeadAddr = 0; -#endif } else { - if (hevc->mmu_enable) { - vf->compBodyAddr = 0; - vf->compHeadAddr = pic->header_adr; -#ifdef H265_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->header_dw_adr; - else if ((mode == 1 || mode == 2 || mode == 4) - && (debug & H265_DEBUG_OUT_PTS) == 0) { - vf->compHeadAddr = pic->header_dw_adr; - pr_debug("Use dw mmu for display\n"); - } - } -#endif - } else { - vf->compBodyAddr = pic->mc_y_adr; /*body adr*/ - vf->compHeadAddr = pic->mc_y_adr + - pic->losless_comp_body_size; - vf->mem_head_handle = NULL; - } - /*head adr*/ + + if (hevc->mmu_enable) { + vf->compBodyAddr = 0; + vf->compHeadAddr = pic->header_adr; + } else { + vf->compBodyAddr = pic->mc_y_adr; /*body adr*/ + vf->compHeadAddr = pic->mc_y_adr + + pic->losless_comp_body_size; + vf->mem_head_handle = NULL; + } + + /*head adr*/ vf->canvas0Addr = vf->canvas1Addr = 0; } - if (pic->double_write_mode && - ((pic->double_write_mode & 0x20) == 0)) { + if (pic->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; vf->type |= nv_order; - if (((pic->double_write_mode == 3) || (pic->double_write_mode == 5) || - (pic->double_write_mode == 9)) && + if (((pic->double_write_mode == 3) || (pic->double_write_mode == 5)) && (!(IS_8K_SIZE(pic->width, pic->height)))) { vf->type |= VIDTYPE_COMPRESS; if (hevc->mmu_enable) @@ -10286,21 +9580,9 @@ vf->sar_height = hevc->cur_pic->sar_height; } vf->width = vf->width / - get_double_write_ratio(pic->double_write_mode & 0xf); + get_double_write_ratio(hevc, pic->double_write_mode); vf->height = vf->height / - get_double_write_ratio(pic->double_write_mode & 0xf); - -#ifdef H265_10B_MMU_DW - if ((pic->double_write_mode & 0x20) && - ((pic->double_write_mode & 0xf) == 2 || - (pic->double_write_mode & 0xf) == 4)) { - vf->compWidth = vf->width; - vf->compHeight = vf->height; - } -#endif - if (hevc->is_used_v4l && vdec->prog_only) - pic->pic_struct = 0; - + get_double_write_ratio(hevc, pic->double_write_mode); #ifdef HEVC_PIC_STRUCT_SUPPORT if (pic->pic_struct == 3 || pic->pic_struct == 4) { struct vframe_s *vf2; @@ -10331,20 +9613,12 @@ vf2->type = VIDTYPE_INTERLACE_TOP | nv_order; } - if (pic->show_frame) { - put_vf_to_display_q(hevc, vf); - hevc->vf_pre_count++; - vdec_vframe_ready(hw_to_vdec(hevc), vf2); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf2); - ATRACE_COUNTER(hevc->trace.pts_name, vf2->pts); - } else { - vh265_vf_put(vf, vdec); - vh265_vf_put(vf2, vdec); - atomic_add(2, &hevc->vf_get_count); - hevc->vf_pre_count += 2; - return 0; - } + put_vf_to_display_q(hevc, vf); + hevc->vf_pre_count++; + vdec_vframe_ready(hw_to_vdec(hevc), vf2); + kfifo_put(&hevc->display_q, + (const struct vframe_s *)vf2); + ATRACE_COUNTER(hevc->pts_name, vf2->pts); } else if (pic->pic_struct == 5 || pic->pic_struct == 6) { struct vframe_s *vf2, *vf3; @@ -10385,26 +9659,18 @@ vf3->type = VIDTYPE_INTERLACE_BOTTOM | nv_order; } - if (pic->show_frame) { - put_vf_to_display_q(hevc, vf); - hevc->vf_pre_count++; - vdec_vframe_ready(hw_to_vdec(hevc), vf2); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf2); - ATRACE_COUNTER(hevc->trace.pts_name, vf2->pts); - hevc->vf_pre_count++; - vdec_vframe_ready(hw_to_vdec(hevc), vf3); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf3); - ATRACE_COUNTER(hevc->trace.pts_name, vf3->pts); - } else { - vh265_vf_put(vf, vdec); - vh265_vf_put(vf2, vdec); - vh265_vf_put(vf3, vdec); - atomic_add(3, &hevc->vf_get_count); - hevc->vf_pre_count += 3;; - return 0; - } + put_vf_to_display_q(hevc, vf); + hevc->vf_pre_count++; + vdec_vframe_ready(hw_to_vdec(hevc), vf2); + kfifo_put(&hevc->display_q, + (const struct vframe_s *)vf2); + ATRACE_COUNTER(hevc->pts_name, vf2->pts); + hevc->vf_pre_count++; + vdec_vframe_ready(hw_to_vdec(hevc), vf3); + kfifo_put(&hevc->display_q, + (const struct vframe_s *)vf3); + ATRACE_COUNTER(hevc->pts_name, vf3->pts); + } else if (pic->pic_struct == 9 || pic->pic_struct == 10) { if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) @@ -10417,40 +9683,35 @@ /* process previous pending vf*/ process_pending_vframe(hevc, pic, (pic->pic_struct == 9)); + + decoder_do_frame_check(vdec, vf); + vdec_vframe_ready(vdec, vf); + /* process current vf */ + kfifo_put(&hevc->pending_q, + (const struct vframe_s *)vf); vf->height <<= 1; - if (pic->show_frame) { - decoder_do_frame_check(vdec, vf); - vdec_vframe_ready(vdec, vf); - /* process current vf */ - kfifo_put(&hevc->pending_q, - (const struct vframe_s *)vf); - if (pic->pic_struct == 9) { - vf->type = VIDTYPE_INTERLACE_TOP - | nv_order | VIDTYPE_VIU_FIELD; - process_pending_vframe(hevc, - hevc->pre_bot_pic, 0); - } else { - vf->type = VIDTYPE_INTERLACE_BOTTOM | - nv_order | VIDTYPE_VIU_FIELD; - vf->index = (pic->index << 8) | 0xff; - process_pending_vframe(hevc, - hevc->pre_top_pic, 1); - } - - if (hevc->vf_pre_count == 0) - hevc->vf_pre_count++; - - /**/ - if (pic->pic_struct == 9) - hevc->pre_top_pic = pic; - else - hevc->pre_bot_pic = pic; + if (pic->pic_struct == 9) { + vf->type = VIDTYPE_INTERLACE_TOP + | nv_order | VIDTYPE_VIU_FIELD; + process_pending_vframe(hevc, + hevc->pre_bot_pic, 0); } else { - vh265_vf_put(vf, vdec); - atomic_add(1, &hevc->vf_get_count); - hevc->vf_pre_count++; - return 0; + vf->type = VIDTYPE_INTERLACE_BOTTOM | + nv_order | VIDTYPE_VIU_FIELD; + vf->index = (pic->index << 8) | 0xff; + process_pending_vframe(hevc, + hevc->pre_top_pic, 1); } + + if (hevc->vf_pre_count == 0) + hevc->vf_pre_count++; + + /**/ + if (pic->pic_struct == 9) + hevc->pre_top_pic = pic; + else + hevc->pre_bot_pic = pic; + } else if (pic->pic_struct == 11 || pic->pic_struct == 12) { if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) @@ -10473,25 +9734,19 @@ nv_order | VIDTYPE_VIU_FIELD; vf->index = (pic->index << 8) | 0xff; } - if (pic->show_frame) { - decoder_do_frame_check(vdec, vf); - vdec_vframe_ready(vdec, vf); - kfifo_put(&hevc->pending_q, - (const struct vframe_s *)vf); - if (hevc->vf_pre_count == 0) - hevc->vf_pre_count++; - - /**/ - if (pic->pic_struct == 11) - hevc->pre_top_pic = pic; - else - hevc->pre_bot_pic = pic; - } else { - vh265_vf_put(vf, vdec); - atomic_add(1, &hevc->vf_get_count); + decoder_do_frame_check(vdec, vf); + vdec_vframe_ready(vdec, vf); + kfifo_put(&hevc->pending_q, + (const struct vframe_s *)vf); + if (hevc->vf_pre_count == 0) hevc->vf_pre_count++; - return 0; - } + + /**/ + if (pic->pic_struct == 11) + hevc->pre_top_pic = pic; + else + hevc->pre_bot_pic = pic; + } else { pic->vf_ref = 1; @@ -10524,81 +9779,50 @@ hevc->pre_bot_pic = pic; break; } - if (pic->show_frame) { - put_vf_to_display_q(hevc, vf); - } else { - vh265_vf_put(vf, vdec); - atomic_add(1, &hevc->vf_get_count); - hevc->vf_pre_count++; - return 0; - } + put_vf_to_display_q(hevc, vf); } #else vf->type_original = vf->type; pic->vf_ref = 1; put_vf_to_display_q(hevc, vf); #endif - ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q)); - ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q)); + ATRACE_COUNTER(hevc->new_q_name, kfifo_len(&hevc->newframe_q)); + ATRACE_COUNTER(hevc->disp_q_name, kfifo_len(&hevc->display_q)); /*count info*/ vdec_count_info(hevc->gvs, 0, stream_offset); - if (pic->slice_type == I_SLICE) { - hevc->gvs->i_decoded_frames++; - vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME; - } else if (pic->slice_type == P_SLICE) { - hevc->gvs->p_decoded_frames++; - vf->frame_type |= V4L2_BUF_FLAG_PFRAME; - } else if (pic->slice_type == B_SLICE) { - hevc->gvs->b_decoded_frames++; - vf->frame_type |= V4L2_BUF_FLAG_BFRAME; + if (hevc->cur_pic != NULL) { + if (hevc->cur_pic->slice_type == I_SLICE) { + hevc->gvs->i_decoded_frames++; + } else if (hevc->cur_pic->slice_type == P_SLICE) { + hevc->gvs->p_decoded_frames++; + } else if (hevc->cur_pic->slice_type == B_SLICE) { + hevc->gvs->b_decoded_frames++; + } } - hevc_update_gvs(hevc, pic); + hevc_update_gvs(hevc); memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info)); - tmp4x.bit_depth_luma = pic->bit_depth_luma; - tmp4x.bit_depth_chroma = pic->bit_depth_chroma; - tmp4x.double_write_mode = pic->double_write_mode; + tmp4x.bit_depth_luma = hevc->bit_depth_luma; + tmp4x.bit_depth_chroma = hevc->bit_depth_chroma; + tmp4x.double_write_mode = get_double_write_mode(hevc); vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, &tmp4x, vf, pic->hw_decode_time); vdec->vdec_fps_detec(vdec->id); hevc_print(hevc, H265_DEBUG_BUFMGR, - "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n", + "%s(type %d index 0x%x poc %d/%d) pts(%d,%lld) dur %d\n", __func__, vf->type, vf->index, get_pic_poc(hevc, vf->index & 0xff), get_pic_poc(hevc, (vf->index >> 8) & 0xff), vf->pts, vf->pts_us64, vf->duration); - - if (pic->pic_struct == 10 || pic->pic_struct == 12) { - index = (vf->index >> 8) & 0xff; - } else { - index = vf->index & 0xff; - } - #ifdef AUX_DATA_CRC - if (index <= MAX_REF_PIC_NUM) - decoder_do_aux_data_check(vdec, hevc->m_PIC[index]->aux_data_buf, - hevc->m_PIC[index]->aux_data_size); + if ((vf->index & 0xff) <= MAX_REF_PIC_NUM) + decoder_do_aux_data_check(vdec, hevc->m_PIC[vf->index & 0xff]->aux_data_buf, + hevc->m_PIC[vf->index & 0xff]->aux_data_size); #endif - - hevc_print(hevc, H265_DEBUG_PRINT_SEI, - "aux_data_size:%d, signal_type: %d, sei_present_flag: %d\n", - hevc->m_PIC[index]->aux_data_size, hevc->video_signal_type, hevc->sei_present_flag); - - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) { - int i = 0; - PR_INIT(128); - for (i = 0; i < hevc->m_PIC[index]->aux_data_size; i++) { - PR_FILL("%02x ", hevc->m_PIC[index]->aux_data_buf[i]); - if (((i + 1) & 0xf) == 0) - PR_INFO(hevc->index); - } - PR_INFO(hevc->index); - } - if (hevc->is_used_v4l) update_vframe_src_fmt(vf, - hevc->m_PIC[index]->aux_data_buf, - hevc->m_PIC[index]->aux_data_size, - hevc->dv_duallayer, hevc->provider_name, NULL); + hevc->m_PIC[vf->index & 0xff]->aux_data_buf, + hevc->m_PIC[vf->index & 0xff]->aux_data_size, + false, hevc->provider_name, NULL); /*if (pic->vf_ref == hevc->vf_pre_count) {*/ if (hevc->kpi_first_i_decoded == 0) { @@ -10608,16 +9832,8 @@ } if (without_display_mode == 0) { - if (hevc->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vh265_vf_put(vh265_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } + vf_notify_receiver(hevc->provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vh265_vf_put(vh265_vf_get(vdec), vdec); @@ -10635,10 +9851,10 @@ return 0; /* create fence for each buffers. */ - if (vdec_timeline_create_fence(vdec->sync)) + if (vdec_timeline_create_fence(&vdec->sync)) return -1; - pic->fence = vdec->sync->fence; + pic->fence = vdec->sync.fence; pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT); if (hevc->chunk) { @@ -10646,7 +9862,7 @@ pic->pts64 = hevc->chunk->pts64; pic->timestamp = hevc->chunk->timestamp; } - pic->show_frame = true; + post_video_frame(vdec, pic); display_frame_count[hevc->index]++; @@ -10660,10 +9876,6 @@ (struct hevc_state_s *)vdec->private; if (hevc->enable_fence) { - int i, j, used_size, ret; - int signed_count = 0; - struct vframe_s *signed_fence[VF_POOL_SIZE]; - post_prepare_process(vdec, frame); if (!frame->show_frame) @@ -10672,35 +9884,16 @@ hevc->m_PIC[frame->index]->vf_ref = 1; /* notify signal to wake up wq of fence. */ - vdec_timeline_increase(vdec->sync, 1); - mutex_lock(&hevc->fence_mutex); - used_size = hevc->fence_vf_s.used_size; - if (used_size) { - for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) { - if (hevc->fence_vf_s.fence_vf[i] != NULL) { - ret = dma_fence_get_status(hevc->fence_vf_s.fence_vf[i]->fence); - if (ret == 1) { - signed_fence[signed_count] = hevc->fence_vf_s.fence_vf[i]; - hevc->fence_vf_s.fence_vf[i] = NULL; - hevc->fence_vf_s.used_size--; - signed_count++; - } - j++; - } - } - } - mutex_unlock(&hevc->fence_mutex); - if (signed_count != 0) { - for (i = 0; i < signed_count; i++) - vh265_vf_put(signed_fence[i], vdec); - } - + vdec_timeline_increase(&vdec->sync, 1); return 0; } if (post_prepare_process(vdec, frame)) return -1; + if (!frame->show_frame) + return 0; + if (post_video_frame(vdec, frame)) return -1; @@ -10727,8 +9920,7 @@ } if (index == INVALID_IDX) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { + if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) { pr_err("[%d] EOS get free buff fail.\n", ctx->id); return -1; } @@ -10740,16 +9932,10 @@ vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb : hw->m_BUF[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; - vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); pr_info("[%d] H265 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } @@ -11080,7 +10266,7 @@ struct vdec_s *vdec = hw_to_vdec(hevc); if (get_dbg_flag(hevc) & - H265_DEBUG_PRINT_SEI) + H265_DEBUG_BUFMGR_MORE) dump_aux_buf(hevc); if (vdec->dolby_meta_with_el || vdec->slave) { set_aux_data(hevc, @@ -11111,123 +10297,49 @@ hevc->rps_set_id = (decode_info >> 8) & 0xff; } -static int vh265_get_ps_info(struct hevc_state_s *hevc, - union param_u *rpm_param, - struct aml_vdec_ps_infos *ps) +static int vh265_get_ps_info(struct hevc_state_s *hevc, int width, int height, struct aml_vdec_ps_infos *ps) { - u32 width = rpm_param->p.pic_width_in_luma_samples; - u32 height = rpm_param->p.pic_height_in_luma_samples; - u32 SubWidthC, SubHeightC; + int dw_mode = v4l_parser_get_double_write_mode(hevc, width, height); - switch (rpm_param->p.chroma_format_idc) { - case 1: - SubWidthC = 2; - SubHeightC = 2; - break; - case 2: - SubWidthC = 2; - SubHeightC = 1; - break; - default: - SubWidthC = 1; - SubHeightC = 1; - break; - } - - width -= SubWidthC * - (rpm_param->p.conf_win_left_offset + - rpm_param->p.conf_win_right_offset); - height -= SubHeightC * - (rpm_param->p.conf_win_top_offset + - rpm_param->p.conf_win_bottom_offset); - - hevc->last_width = rpm_param->p.pic_width_in_luma_samples; - hevc->last_height = rpm_param->p.pic_height_in_luma_samples; - hevc->sps_num_reorder_pics_0 = - rpm_param->p.sps_num_reorder_pics_0; - hevc->used_buf_num = v4l_parser_work_pic_num(hevc); - - ps->visible_width = width; - ps->visible_height = height; - ps->coded_width = ALIGN(width, 64); - ps->coded_height = ALIGN(height, 64); + ps->visible_width = width / get_double_write_ratio(hevc, dw_mode); + ps->visible_height = height / get_double_write_ratio(hevc, dw_mode); + ps->coded_width = ALIGN(width, 32) / get_double_write_ratio(hevc, dw_mode); + ps->coded_height = ALIGN(height, 32) / get_double_write_ratio(hevc, dw_mode); ps->dpb_size = v4l_parser_work_pic_num(hevc); + ps->field = hevc->interlace_flag ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; return 0; } -static void get_comp_buf_info(struct hevc_state_s *hevc, - struct vdec_comp_buf_info *info) -{ - u16 bit_depth = hevc->param.p.bit_depth; - int w = hevc->param.p.pic_width_in_luma_samples; - int h = hevc->param.p.pic_height_in_luma_samples; - - info->max_size = hevc_max_mmu_buf_size( - hevc->max_pic_w, - hevc->max_pic_h); - info->header_size = hevc_get_header_size(w,h); - info->frame_buffer_size = hevc_mmu_page_num( - hevc, w, h, bit_depth == 0); - - pr_info("hevc get comp info: %d %d %d\n", - info->max_size, info->header_size, - info->frame_buffer_size); -} - static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); - int i, ret = 0; + int ret = 0; - if (ctx->param_sets_from_ucode) { + if (ctx->param_sets_from_ucode && + hevc->res_ch_flag == 0) { struct aml_vdec_ps_infos ps; int width = rpm_param->p.pic_width_in_luma_samples; int height = rpm_param->p.pic_height_in_luma_samples; - if ((hevc->last_width != 0 && - hevc->last_height != 0) && - (hevc->last_width != width || - hevc->last_height != height)) { + if ((hevc->pic_w != 0 && + hevc->pic_h != 0) && + (hevc->pic_w != width || + hevc->pic_h != height)) { hevc_print(hevc, 0, "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n", - hevc->last_width, hevc->last_height, + hevc->pic_w, hevc->pic_h, width, height, hevc->interlace_flag); - if (get_valid_double_write_mode(hevc) != 16) { - struct vdec_comp_buf_info info; - - get_comp_buf_info(hevc, &info); - vdec_v4l_set_comp_buf_info(ctx, &info); - } - - vh265_get_ps_info(hevc, &hevc->param, &ps); + vh265_get_ps_info(hevc, width, height, &ps); vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); hevc->v4l_params_parsed = false; + hevc->res_ch_flag = 1; ctx->v4l_resolution_change = 1; hevc->eos = 1; - - /* - * marks frame valid on the dpb is the ouput state, - * then via flush_output all frames can be flushed out. - */ - for (i = 0; i < MAX_REF_PIC_NUM; ++i) { - if ((hevc->m_PIC[i] == NULL) || - (hevc->m_PIC[i]->index == -1) || - (hevc->m_PIC[i]->BUF_index == -1)) - continue; - - if ((hevc->m_PIC[i]->POC != INVALID_POC) && - (hevc->m_PIC[i]->output_ready == 0) && - hevc->m_PIC[i]->referenced && - (hevc->m_PIC[i]->POC >= hevc->decoded_poc)) { - hevc->m_PIC[i]->output_mark = 1; - } - } - flush_output(hevc, NULL); //del_timer_sync(&hevc->timer); notify_v4l_eos(hw_to_vdec(hevc)); @@ -11254,6 +10366,55 @@ return 0; } +#ifdef VDEC_FCC_SUPPORT +static void fcc_discard_mode_process(struct vdec_s *vdec, struct hevc_state_s *hevc) +{ + if (vdec->fcc_status == AGAIN_STATUS && + hevc->param.p.slice_type == I_SLICE) { + vdec->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT); + hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, + "[%d][FCC]: Notify stream_offset: %u\n", + vdec->id, vdec->stream_offset); + + vdec_wakeup_fcc_poll(vdec); + amhevc_stop(); + vdec->fcc_status = WAIT_MSG_STATUS; + hevc->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hevc->work); + } else if (vdec->fcc_status == DISCARD_STATUS || + hevc->param.p.slice_type != I_SLICE) { + hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, + "[%d][FCC]: Discard current gop and to find next gop!\n", + vdec->id); + + amhevc_stop(); + vdec->fcc_status = AGAIN_STATUS; + hevc->dec_result = DEC_RESULT_DISCARD_DATA; + vdec_schedule_work(&hevc->work); + } +} + +static int vh265_fcc_process(struct vdec_s *vdec, struct hevc_state_s *hevc) +{ + if (input_stream_based(vdec)) { + switch (vdec->fcc_mode) { + case FCC_DISCARD_MODE: + fcc_discard_mode_process(vdec, hevc); + return 1; + case FCC_DEC_MODE: + hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, + "[%d][FCC]: Current is Dec mode.\n", vdec->id); + break; + case FCC_BUTT: + default: + break; + } + } + + return 0; +} +#endif + static void aspect_ratio_set(struct hevc_state_s *hevc) { int aspect_ratio_idc = hevc->param.p.aspect_ratio_idc; @@ -11356,13 +10517,6 @@ struct vdec_s *vdec = hw_to_vdec(hevc); - if (dec_status == HEVC_SLICE_SEGMENT_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START); - } - else if (dec_status == HEVC_DECPIC_DATA_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START); - } - if (hevc->eos) return IRQ_HANDLED; if ( @@ -11548,20 +10702,11 @@ #endif hevc->empty_flag = 0; pic_done: - if (vdec->master == NULL && vdec->slave == NULL && - hevc->empty_flag == 0) { - hevc->over_decode = - (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1; - if (hevc->over_decode) - hevc_print(hevc, 0, - "!!!Over decode %d\n", __LINE__); - } if (input_frame_based(hw_to_vdec(hevc)) && frmbase_cont_bitlevel != 0 && (hevc->decode_size > READ_VREG(HEVC_SHIFT_BYTE_COUNT)) && (hevc->decode_size - (READ_VREG(HEVC_SHIFT_BYTE_COUNT)) > frmbase_cont_bitlevel)) { - check_pic_decoded_error(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff); /*handle the case: multi pictures in one packet*/ hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, "%s has more data index= %d, size=0x%x shiftcnt=0x%x)\n", @@ -11617,12 +10762,27 @@ && ((hevc->double_write_mode & 0x10) == 0)) { if (!hevc->m_ins_flag) { hevc->used_4k_num = - READ_VREG(HEVC_SAO_MMU_STATUS) >> 16; + READ_VREG(HEVC_SAO_MMU_STATUS) >> 16; + if ((!is_skip_decoding(hevc, pic)) && (hevc->used_4k_num >= 0) && (hevc->cur_pic->scatter_alloc - == 1)) - recycle_mmu_buf_tail(hevc, false); + == 1)) { + hevc_print(hevc, + H265_DEBUG_BUFMGR_MORE, + "%s pic index %d scatter_alloc %d page_start %ld\n", + "decoder_mmu_box_free_idx_tail", + hevc->cur_pic->index, + hevc->cur_pic->scatter_alloc, + hevc->used_4k_num); + decoder_mmu_box_free_idx_tail( + hevc->mmu_box, + hevc->cur_pic->index, + hevc->used_4k_num); + hevc->cur_pic->scatter_alloc + = 2; + } + hevc->used_4k_num = -1; } } @@ -11636,7 +10796,7 @@ } } /*Detects the first frame whether has an over decode error*/ - if (vdec->master == NULL && vdec->slave == NULL && + if ((!vdec_dual(vdec)) && hevc->empty_flag == 0) { hevc->over_decode = (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1; @@ -11688,7 +10848,7 @@ } } } - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_EDN); + vdec_schedule_work(&hevc->work); } @@ -11828,7 +10988,7 @@ } #endif /*Detects frame whether has an over decode error*/ - if (vdec->master == NULL && vdec->slave == NULL && + if ((!vdec_dual(vdec)) && hevc->empty_flag == 0 && input_stream_based(vdec)) { hevc->over_decode = (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1; @@ -12036,7 +11196,7 @@ if (get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) get_rpm_param(&hevc->param); else { - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START); + for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { int ii; @@ -12046,11 +11206,14 @@ - ii]; } } - ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END); #ifdef SEND_LMEM_WITH_RPM check_head_error(hevc); #endif } +#ifdef VDEC_FCC_SUPPORT + if (vh265_fcc_process(vdec, hevc) > 0) + return IRQ_HANDLED; +#endif if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { hevc_print(hevc, 0, "rpm_param: (%d)\n", hevc->slice_idx); @@ -12078,22 +11241,9 @@ struct aml_vdec_ps_infos ps; int width = hevc->param.p.pic_width_in_luma_samples; int height = hevc->param.p.pic_height_in_luma_samples; - int log = hevc->param.p.log2_min_coding_block_size_minus3; - int log_s = hevc->param.p.log2_diff_max_min_coding_block_size; - - hevc->pic_w = width; - hevc->pic_h = height; - hevc->lcu_size = 1 << (log + 3 + log_s); pr_debug("set ucode parse\n"); - if (get_valid_double_write_mode(hevc) != 16) { - struct vdec_comp_buf_info info; - - get_comp_buf_info(hevc, &info); - vdec_v4l_set_comp_buf_info(ctx, &info); - } - - vh265_get_ps_info(hevc, &hevc->param, &ps); + vh265_get_ps_info(hevc, width, height, &ps); /*notice the v4l2 codec.*/ vdec_v4l_set_ps_infos(ctx, &ps); hevc->v4l_params_parsed = true; @@ -12112,6 +11262,7 @@ reset_process_time(hevc); vdec_schedule_work(&hevc->work); return IRQ_HANDLED; + } } @@ -12124,7 +11275,7 @@ ) { if (get_dbg_flag(hevc) & - H265_DEBUG_PRINT_SEI) + H265_DEBUG_BUFMGR_MORE) dump_aux_buf(hevc); } @@ -12250,16 +11401,15 @@ } else { hevc->sps_num_reorder_pics_0 = hevc->param.p.sps_num_reorder_pics_0; - hevc->ip_mode = hevc->low_latency_flag ? true : - (!hevc->sps_num_reorder_pics_0 && - !(vdec->slave || vdec->master) && - !disable_ip_mode) ? true : false; + hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 && + !(vdec->slave || vdec->master) && + !disable_ip_mode && + hevc->low_latency_flag) ? true : false; hevc->pic_list_init_flag = 1; if ((!IS_4K_SIZE(hevc->pic_w, hevc->pic_h)) && ((hevc->param.p.profile_etc & 0xc) == 0x4) && (interlace_enable != 0)) { hevc->double_write_mode = 1; - hevc->mmu_enable = 1; hevc->interlace_flag = 1; hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2; hevc_print(hevc, 0, @@ -12267,7 +11417,7 @@ hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar, get_double_write_mode(hevc)); /* When dw changed from 0x10 to 1, the mmu_box is NULL */ - if (!hevc->mmu_box && init_mmu_buffers(hevc, 1) != 0) { + if (!hevc->mmu_box && init_mmu_box(hevc) != 0) { hevc->dec_result = DEC_RESULT_FORCE_EXIT; hevc->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; @@ -12276,17 +11426,6 @@ 0, "can not alloc mmu box, force exit\n"); return IRQ_HANDLED; } - if (hevc->frame_mmu_map_addr == NULL) { - hevc->frame_mmu_map_addr = - dma_alloc_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(), - &hevc->frame_mmu_map_phy_addr, GFP_KERNEL); - if (hevc->frame_mmu_map_addr == NULL) { - pr_err("%s: failed to alloc count_buffer\n", __func__); - return IRQ_HANDLED; - } - memset(hevc->frame_mmu_map_addr, 0, get_frame_mmu_map_size()); - } } #ifdef MULTI_INSTANCE_SUPPORT if (hevc->m_ins_flag) { @@ -12296,7 +11435,6 @@ up(&h265_sema); hevc_print(hevc, 0, "set pic_list_init_flag 1\n"); } - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); return IRQ_HANDLED; } @@ -12325,6 +11463,7 @@ hevc_print(hevc, H265_DEBUG_OUT_PTS, "read stream_offset = 0x%x\n", hevc->cur_pic->stream_offset); + hevc->cur_pic->aspect_ratio_idc = hevc->param.p.aspect_ratio_idc; hevc->cur_pic->sar_width = @@ -12376,8 +11515,6 @@ WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); } - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); - } else if (dec_status == HEVC_DECODE_OVER_SIZE) { hevc_print(hevc, 0 , "hevc decode oversize !!\n"); #ifdef MULTI_INSTANCE_SUPPORT @@ -12411,14 +11548,6 @@ u32 debug_tag; dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - - if (dec_status == HEVC_SLICE_SEGMENT_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_HEAD_DONE); - } - else if (dec_status == HEVC_DECPIC_DATA_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_PIC_DONE); - } - if (hevc->init_flag == 0) return IRQ_HANDLED; hevc->dec_status = dec_status; @@ -12509,7 +11638,7 @@ return IRQ_HANDLED; } } - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_END); + return IRQ_WAKE_THREAD; } @@ -12527,10 +11656,10 @@ hevc->frame_height * fps; } -static void vh265_check_timer_func(struct timer_list *timer) +static void vh265_check_timer_func(unsigned long arg) { - struct hevc_state_s *hevc = container_of(timer, - struct hevc_state_s, timer); + struct hevc_state_s *hevc = (struct hevc_state_s *)arg; + struct timer_list *timer = &hevc->timer; unsigned char empty_flag; unsigned int buf_level; @@ -12836,17 +11965,11 @@ 96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1); else vstatus->frame_rate = -1; - vstatus->error_count = hevc->gvs->error_frame_count; - vstatus->status = hevc->stat | hevc->fatal_error; - if (!vdec_is_support_4k() && - (IS_4K_SIZE(vstatus->frame_width, vstatus->frame_height)) && - (vstatus->frame_width <= 4096 && vstatus->frame_height <= 2304)) { - vstatus->status |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; - } - vstatus->bit_rate = hevc->gvs->bit_rate; + vstatus->status = hevc->stat | hevc->fatal_error; vstatus->frame_dur = hevc->frame_dur; if (hevc->gvs) { + vstatus->error_count = hevc->gvs->error_frame_count; vstatus->bit_rate = hevc->gvs->bit_rate; vstatus->frame_data = hevc->gvs->frame_data; vstatus->total_data = hevc->gvs->total_data; @@ -12913,28 +12036,28 @@ int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) { - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; - hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode); + struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; + hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode); - if (trickmode == TRICKMODE_I) { + if (trickmode == TRICKMODE_I) { trickmode_i = 1; i_only_flag = 0x1; - } else if (trickmode == TRICKMODE_NONE) { + } else if (trickmode == TRICKMODE_NONE) { trickmode_i = 0; i_only_flag = 0x0; - } else if (trickmode == 0x02) { + } else if (trickmode == 0x02) { trickmode_i = 0; i_only_flag = 0x02; - } else if (trickmode == 0x03) { + } else if (trickmode == 0x03) { trickmode_i = 1; i_only_flag = 0x03; - } else if (trickmode == 0x07) { + } else if (trickmode == 0x07) { trickmode_i = 1; i_only_flag = 0x07; - } - //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i); + } + //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i); - return 0; + return 0; } static void config_decode_mode(struct hevc_state_s *hevc) @@ -13026,6 +12149,7 @@ } else { /* check vps/sps/pps/i-slice in ucode */ unsigned ctl_val = 0x8; + if (hevc->PB_skip_mode == 0) ctl_val = 0x4; /* check vps/sps/pps only in ucode */ else if (hevc->PB_skip_mode == 3) @@ -13164,7 +12288,7 @@ int fw_size = 0x1000 * 16; struct firmware_s *fw = NULL; - timer_setup(&hevc->timer, vh265_check_timer_func, 0); + init_timer(&hevc->timer); hevc->stat |= STAT_TIMER_INIT; @@ -13183,11 +12307,11 @@ INIT_WORK(&hevc->notify_work, vh265_notify_work); INIT_WORK(&hevc->set_clk_work, vh265_set_clk); - fw = vzalloc(sizeof(struct firmware_s) + fw_size); + fw = vmalloc(sizeof(struct firmware_s) + fw_size); if (IS_ERR_OR_NULL(fw)) return -ENOMEM; - if (hevc->mmu_enable) { + if (hevc->mmu_enable) if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM) size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data); else { @@ -13206,7 +12330,7 @@ size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data); } - } else + else size = get_firmware_data(VIDEO_DEC_HEVC, fw->data); if (size < 0) { @@ -13236,7 +12360,7 @@ hevc->swap_size); hevc_print(hevc, 0, - "vh265 mmu ucode swap loaded %x\n", + "vh265 mmu ucode swap loaded %llx\n", hevc->mc_dma_handle); } } @@ -13244,8 +12368,8 @@ #ifdef MULTI_INSTANCE_SUPPORT if (hevc->m_ins_flag) { - //hevc->timer.data = (ulong) hevc; - //hevc->timer.function = vh265_check_timer_func; + hevc->timer.data = (ulong) hevc; + hevc->timer.function = vh265_check_timer_func; hevc->timer.expires = jiffies + PUT_INTERVAL; hevc->fw = fw; @@ -13311,23 +12435,21 @@ hevc->provider_name = PROVIDER_NAME; #ifdef MULTI_INSTANCE_SUPPORT - if (!hevc->is_used_v4l) { - vf_provider_init(&vh265_vf_prov, hevc->provider_name, - &vh265_vf_provider, vdec); - vf_reg_provider(&vh265_vf_prov); - vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START, - NULL); - if (hevc->frame_dur != 0) { - if (!is_reset) { - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long)hevc->frame_dur)); - fr_hint_status = VDEC_HINTED; - } - } else - fr_hint_status = VDEC_NEED_HINT; - } + vf_provider_init(&vh265_vf_prov, hevc->provider_name, + &vh265_vf_provider, vdec); + vf_reg_provider(&vh265_vf_prov); + vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START, + NULL); + if (hevc->frame_dur != 0) { + if (!is_reset) { + vf_notify_receiver(hevc->provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)hevc->frame_dur)); + fr_hint_status = VDEC_HINTED; + } + } else + fr_hint_status = VDEC_NEED_HINT; #else vf_provider_init(&vh265_vf_prov, PROVIDER_NAME, &vh265_vf_provider, hevc); @@ -13344,8 +12466,8 @@ #endif hevc->stat |= STAT_VF_HOOK; - //hevc->timer.data = (ulong) hevc; - //hevc->timer.function = vh265_check_timer_func; + hevc->timer.data = (ulong) hevc; + hevc->timer.function = vh265_check_timer_func; hevc->timer.expires = jiffies + PUT_INTERVAL; add_timer(&hevc->timer); @@ -13659,38 +12781,6 @@ } #endif -static bool is_avaliable_buffer(struct hevc_state_s *hevc) -{ - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); - struct PIC_s *pic = NULL; - int i, free_count = 0; - - if (ctx->cap_pool.dec < hevc->used_buf_num) { - free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - if (free_count && - !ctx->fb_ops.query(&ctx->fb_ops, &hevc->fb_token)) { - return false; - } - } - - for (i = 0; i < hevc->used_buf_num; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || - pic->index == -1 || - pic->BUF_index == -1) - continue; - - if (pic->output_mark == 0 && - pic->referenced == 0 && - pic->output_ready == 0 && - pic->cma_alloc_addr) { - free_count++; - } - } - - return free_count < run_ready_min_buf_num ? 0 : 1; -} static unsigned char is_new_pic_available(struct hevc_state_s *hevc) { @@ -13722,7 +12812,7 @@ new_pic = pic; } } - if (!hevc->is_used_v4l && new_pic == NULL) { + if (new_pic == NULL) { enum receviver_start_e state = RECEIVER_INACTIVE; if (vf_get_receiver(vdec->vf_provider_name)) { state = @@ -13742,7 +12832,7 @@ if ((pic->referenced == 0) && (pic->error_mark == 1) && (pic->output_mark == 1)) { - if (poc == INVALID_POC || (pic->POC < poc)) { + if (pic->POC < poc) { new_pic = pic; poc = pic->POC; } @@ -13785,7 +12875,7 @@ if (!(error_handle_policy & 0x400)) { spin_unlock_irqrestore(&lock, flags); flush_output(hevc, NULL); - hevc_print(hevc, H265_DEBUG_BUFMGR, "flush dpb, ref_error_count %d, sps_max_dec_pic_buffering_minus1_0 %d\n", + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, "flush dpb, ref_error_count %d, sps_max_dec_pic_buffering_minus1_0 %d\n", decode_count, hevc->param.p.sps_max_dec_pic_buffering_minus1_0); return 0; } @@ -13803,10 +12893,6 @@ struct vdec_s *vdec = hw_to_vdec(hevc); enum receviver_start_e state = RECEIVER_INACTIVE; - - if (hevc->is_used_v4l) - return; - if (vf_get_receiver(vdec->vf_provider_name)) { state = vf_notify_receiver(vdec->vf_provider_name, @@ -13834,7 +12920,7 @@ if ((pic->referenced == 0) && (pic->error_mark == 1) && (pic->output_mark == 1)) { - if (poc == INVALID_POC || (pic->POC < poc)) { + if (pic->POC < poc) { new_pic = pic; poc = pic->POC; } @@ -13876,7 +12962,7 @@ hevc->stat &= ~STAT_ISR_REG; } - if (!hevc->is_used_v4l && hevc->stat & STAT_VF_HOOK) { + if (hevc->stat & STAT_VF_HOOK) { if (fr_hint_status == VDEC_HINTED) vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -13939,14 +13025,6 @@ for (jj = 0; jj < size; jj++) sum += data[jj]; - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", - __func__, size, sum, - data[0], data[1], data[2], data[3], - data[4], data[5], data[size - 4], - data[size - 3], data[size - 2], - data[size - 1]); - if (!hevc->chunk->block->is_mapped) codec_mm_unmap_phyaddr(data); return sum; @@ -13959,10 +13037,6 @@ struct hevc_state_s, notify_work); struct vdec_s *vdec = hw_to_vdec(hevc); - - if (hevc->is_used_v4l) - return; - #ifdef MULTI_INSTANCE_SUPPORT if (vdec->fr_hint_state == VDEC_NEED_HINT) { vf_notify_receiver(hevc->provider_name, @@ -13993,11 +13067,6 @@ static void vh265_work_implement(struct hevc_state_s *hevc, struct vdec_s *vdec,int from) { - if (hevc->dec_result == DEC_RESULT_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_START); - } else if (hevc->dec_result == DEC_RESULT_AGAIN) - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_AGAIN); - if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) { /*USE_BUF_BLOCK*/ uninit_pic_list(hevc); @@ -14179,20 +13248,34 @@ } } #endif + if (hevc->mmu_enable && ((hevc->double_write_mode & 0x10) == 0)) { hevc->used_4k_num = READ_VREG(HEVC_SAO_MMU_STATUS) >> 16; if (hevc->used_4k_num >= 0 && hevc->cur_pic && hevc->cur_pic->scatter_alloc - == 1) - recycle_mmu_buf_tail(hevc, hevc->m_ins_flag); + == 1) { + hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, + "%s pic index %d scatter_alloc %d page_start %ld\n", + "decoder_mmu_box_free_idx_tail", + hevc->cur_pic->index, + hevc->cur_pic->scatter_alloc, + hevc->used_4k_num); + if (hevc->m_ins_flag) + hevc_mmu_dma_check(hw_to_vdec(hevc)); + decoder_mmu_box_free_idx_tail( + hevc->mmu_box, + hevc->cur_pic->index, + hevc->used_4k_num); + hevc->cur_pic->scatter_alloc = 2; + } } hevc->pic_decoded_lcu_idx = READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff; - if (vdec->master == NULL && vdec->slave == NULL && + if ((!vdec_dual(vdec)) && hevc->empty_flag == 0) { hevc->over_decode = (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1; @@ -14203,7 +13286,7 @@ if (is_log_enable(hevc)) add_log(hevc, - "%s dec_result %d lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x", + "%s dec_result %d lcu %d used_mmu %ld shiftbyte 0x%x decbytes 0x%x", __func__, hevc->dec_result, hevc->pic_decoded_lcu_idx, @@ -14214,7 +13297,7 @@ ); hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s dec_result %d (%x %x %x) lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x\n", + "%s dec_result %d (%x %x %x) lcu %d used_mmu %ld shiftbyte 0x%x decbytes 0x%x\n", __func__, hevc->dec_result, READ_VREG(HEVC_STREAM_LEVEL), @@ -14316,6 +13399,7 @@ stream base: stream buf empty or timeout frame base: vdec_prepare_input fail */ + if (!vdec_has_more_input(vdec)) { hevc->dec_result = DEC_RESULT_EOS; vdec_schedule_work(&hevc->work); @@ -14391,6 +13475,11 @@ } hevc_print(hevc, 0, "%s: force exit end\n", __func__); + } else if (hevc->dec_result == DEC_RESULT_DISCARD_DATA) { + mutex_lock(&hevc->chunks_mutex); + vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk); + hevc->chunk = NULL; + mutex_unlock(&hevc->chunks_mutex); } if (hevc->stat & STAT_VDEC_RUN) { @@ -14402,10 +13491,8 @@ del_timer_sync(&hevc->timer); hevc->stat &= ~STAT_TIMER_ARM; } - ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START); - wait_hevc_search_done(hevc); - ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END); + wait_hevc_search_done(hevc); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (hevc->switch_dvlayer_flag) { if (vdec->slave) @@ -14427,9 +13514,6 @@ //cancel_work_sync(&hevc->work);//reserved for future considraion } } - if (hevc->dec_result == DEC_RESULT_DONE) { - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_END); - } /* mark itself has all HW resource released and input released */ if (vdec->parallel_dec == 1) @@ -14471,6 +13555,12 @@ vh265_work_implement(hevc, vdec, 1); } +#ifdef VDEC_FCC_SUPPORT +static void vh265_wakeup_fcc_poll(struct vdec_s *vdec) +{ + amstream_wakeup_fcc_poll(vdec); +} +#endif static int vh265_hw_ctx_restore(struct hevc_state_s *hevc) { @@ -14485,6 +13575,9 @@ int tvp = vdec_secure(hw_to_vdec(hevc)) ? CODEC_MM_FLAGS_TVP : 0; bool ret = 0; +#ifdef VDEC_FCC_SUPPORT + int get_msg = 1; +#endif if (step == 0x12) return 0; else if (step == 0x11) @@ -14506,17 +13599,7 @@ } hevc->timeout_processing = 0; if (!hevc->first_sc_checked && hevc->mmu_enable) { - int size; - void * mmu_box; - - if (hevc->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hevc->v4l2_ctx); - mmu_box = ctx->mmu_box; - } else - mmu_box = hevc->mmu_box; - - size = decoder_mmu_box_sc_check(mmu_box, tvp); + int size = decoder_mmu_box_sc_check(hevc->mmu_box, tvp); hevc->first_sc_checked =1; hevc_print(hevc, 0, "vh265 cached=%d need_size=%d speed= %d ms\n", @@ -14572,7 +13655,7 @@ } #ifdef CONSTRAIN_MAX_BUF_NUM - if (hevc->pic_list_init_flag == 3 && !hevc->is_used_v4l) { + if (hevc->pic_list_init_flag == 3) { if (run_ready_max_vf_only_num > 0 && get_vf_ref_only_buf_count(hevc) >= run_ready_max_vf_only_num @@ -14604,12 +13687,10 @@ if (ctx->param_sets_from_ucode) { if (hevc->v4l_params_parsed) { - if (ctx->cap_pool.dec < hevc->used_buf_num) { - if (is_avaliable_buffer(hevc)) - ret = 1; - else - ret = 0; - } + if (!ctx->v4l_codec_dpb_ready && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; } else { if (ctx->v4l_resolution_change) ret = 0; @@ -14621,6 +13702,10 @@ } } +#ifdef VDEC_FCC_SUPPORT + get_msg = vdec_has_get_fcc_new_msg(vdec); + ret &= get_msg; +#endif if (ret) not_run_ready[hevc->index] = 0; else @@ -14643,8 +13728,6 @@ hevc->vdec_cb_arg = arg; hevc->vdec_cb = callback; hevc->aux_data_dirty = 1; - - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_START); hevc_reset_core(vdec); #ifdef AGAIN_HAS_THRESHOLD @@ -14722,7 +13805,6 @@ if (!hevc->chunk->block->is_mapped) codec_mm_unmap_phyaddr(data); } - ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START); if (vdec->mc_loaded) { /*firmware have load before, and not changes to another. @@ -14732,7 +13814,7 @@ get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->swap_addr); } else { - if (hevc->mmu_enable) { + if (hevc->mmu_enable) if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM) loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec, "h265_mmu", hevc->fw->data); @@ -14757,10 +13839,9 @@ VFORMAT_HEVC, vdec, "h265_mmu", hevc->fw->data); } - } else + else loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec, NULL, hevc->fw->data); - if (loadr < 0) { amhevc_disable(); hevc_print(hevc, 0, "H265: the %s fw loading failed, err: %x\n", @@ -14781,14 +13862,10 @@ vdec->mc_loaded = 1; vdec->mc_type = VFORMAT_HEVC; } - ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END); - - ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START); if (vh265_hw_ctx_restore(hevc) < 0) { vdec_schedule_work(&hevc->work); return; } - ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END); vdec_enable_input(vdec); WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); @@ -14817,7 +13894,6 @@ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) dump_pic_list(hevc); backup_decode_state(hevc); - start_process_time(hevc); mod_timer(&hevc->timer, jiffies); hevc->stat |= STAT_TIMER_ARM; @@ -14826,8 +13902,6 @@ vdec->mvfrm->hw_decode_start = local_clock(); amhevc_start(); hevc->stat |= STAT_VDEC_RUN; - - ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_END); } static void aml_free_canvas(struct vdec_s *vdec) @@ -14845,7 +13919,6 @@ vdec->free_canvas_ex(pic->uv_canvas_index, vdec->id); } } - hevc->buffer_wrap[i] = i; } } @@ -14953,15 +14026,7 @@ else hevc->mmu_enable = 1; } -#ifdef H265_10B_MMU_DW - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - hevc->dw_mmu_enable = - get_double_write_mode(hevc) & 0x20 ? 1 : 0; - } else { - hevc->dw_mmu_enable = 0; - } -#endif - if (init_mmu_buffers(hevc, 0)) { + if (init_mmu_buffers(hevc)) { hevc_print(hevc, 0, "\n 265 mmu init failed!\n"); vfree(hevc); @@ -15015,13 +14080,6 @@ hevc->vh265_amstream_dec_info.height = 0; hevc->vh265_amstream_dec_info.rate = 30; } - - hevc->endian = HEVC_CONFIG_LITTLE_ENDIAN; - if (is_support_vdec_canvas()) - hevc->endian = HEVC_CONFIG_BIG_ENDIAN; - if (endian) - hevc->endian = endian; - #ifndef MULTI_INSTANCE_SUPPORT if (pdata->flag & DEC_FLAG_HEVC_WORKAROUND) { workaround_enable |= 3; @@ -15154,7 +14212,7 @@ input_empty[hevc->index] ); - if (hevc->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -15183,17 +14241,16 @@ for (i = 0; i < BUF_POOL_SIZE; i++) { hevc_print(hevc, 0, - "Buf(%d) start_adr 0x%x header_addr 0x%x size 0x%x used %d\n", + "Buf(%d) start_adr 0x%lx size 0x%x used %d\n", i, hevc->m_BUF[i].start_adr, - hevc->m_BUF[i].header_addr, hevc->m_BUF[i].size, hevc->m_BUF[i].used_flag); } for (i = 0; i < MAX_REF_PIC_NUM; i++) { hevc_print(hevc, 0, - "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n", + "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n", i, hevc->m_mv_BUF[i].start_adr, hevc->m_mv_BUF[i].size, @@ -15290,17 +14347,17 @@ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; struct hevc_state_s *hevc = NULL; int ret; - int i; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC int config_val; #endif - + //pr_err("[%s pid=%d tgid=%d] \n",__func__, current->pid, current->tgid); if (pdata == NULL) { pr_info("\nammvdec_h265 memory resource undefined.\n"); return -EFAULT; } - + /* hevc = (struct hevc_state_s *)devm_kzalloc(&pdev->dev, + sizeof(struct hevc_state_s), GFP_KERNEL); */ hevc = vmalloc(sizeof(struct hevc_state_s)); if (hevc == NULL) { pr_info("\nammvdec_h265 device data allocation failed\n"); @@ -15320,48 +14377,30 @@ pdata->irq_handler = vh265_irq_cb; pdata->threaded_irq_handler = vh265_threaded_irq_cb; pdata->dump_state = vh265_dump_state; - +#ifdef VDEC_FCC_SUPPORT + pdata->wakeup_fcc_poll = vh265_wakeup_fcc_poll; +#endif hevc->index = pdev->id; hevc->m_ins_flag = 1; - if (is_rdma_enable()) { - hevc->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hevc->rdma_phy_adr, GFP_KERNEL); - for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) { - hevc->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff; - hevc->rdma_adr[i * 4 + 1] = i; - hevc->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff; - hevc->rdma_adr[i * 4 + 3] = 0; - if (i == SCALELUT_DATA_WRITE_NUM - 1) { - hevc->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000; - } - } - } - snprintf(hevc->trace.vdec_name, sizeof(hevc->trace.vdec_name), + snprintf(hevc->vdec_name, sizeof(hevc->vdec_name), "h265-%d", hevc->index); - snprintf(hevc->trace.pts_name, sizeof(hevc->trace.pts_name), - "%s-pts", hevc->trace.vdec_name); - snprintf(hevc->trace.vf_get_name, sizeof(hevc->trace.vf_get_name), - "%s-vf_get", hevc->trace.vdec_name); - snprintf(hevc->trace.vf_put_name, sizeof(hevc->trace.vf_put_name), - "%s-vf_put", hevc->trace.vdec_name); - snprintf(hevc->trace.set_canvas0_addr, sizeof(hevc->trace.set_canvas0_addr), - "%s-set_canvas0_addr", hevc->trace.vdec_name); - snprintf(hevc->trace.get_canvas0_addr, sizeof(hevc->trace.get_canvas0_addr), - "%s-get_canvas0_addr", hevc->trace.vdec_name); - snprintf(hevc->trace.put_canvas0_addr, sizeof(hevc->trace.put_canvas0_addr), - "%s-put_canvas0_addr", hevc->trace.vdec_name); - snprintf(hevc->trace.new_q_name, sizeof(hevc->trace.new_q_name), - "%s-newframe_q", hevc->trace.vdec_name); - snprintf(hevc->trace.disp_q_name, sizeof(hevc->trace.disp_q_name), - "%s-dispframe_q", hevc->trace.vdec_name); - snprintf(hevc->trace.decode_time_name, sizeof(hevc->trace.decode_time_name), - "decoder_time%d", pdev->id); - snprintf(hevc->trace.decode_run_time_name, sizeof(hevc->trace.decode_run_time_name), - "decoder_run_time%d", pdev->id); - snprintf(hevc->trace.decode_header_memory_time_name, sizeof(hevc->trace.decode_header_memory_time_name), - "decoder_header_time%d", pdev->id); - snprintf(hevc->trace.decode_work_time_name, sizeof(hevc->trace.decode_work_time_name), - "decoder_work_time%d", pdev->id); + snprintf(hevc->pts_name, sizeof(hevc->pts_name), + "%s-pts", hevc->vdec_name); + snprintf(hevc->vf_get_name, sizeof(hevc->vf_get_name), + "%s-vf_get", hevc->vdec_name); + snprintf(hevc->vf_put_name, sizeof(hevc->vf_put_name), + "%s-vf_put", hevc->vdec_name); + snprintf(hevc->set_canvas0_addr, sizeof(hevc->set_canvas0_addr), + "%s-set_canvas0_addr", hevc->vdec_name); + snprintf(hevc->get_canvas0_addr, sizeof(hevc->get_canvas0_addr), + "%s-get_canvas0_addr", hevc->vdec_name); + snprintf(hevc->put_canvas0_addr, sizeof(hevc->put_canvas0_addr), + "%s-put_canvas0_addr", hevc->vdec_name); + snprintf(hevc->new_q_name, sizeof(hevc->new_q_name), + "%s-newframe_q", hevc->vdec_name); + snprintf(hevc->disp_q_name, sizeof(hevc->disp_q_name), + "%s-dispframe_q", hevc->vdec_name); if (pdata->use_vfm_path) { snprintf(pdata->vf_provider_name, @@ -15373,30 +14412,16 @@ else if (vdec_dual(pdata)) { struct hevc_state_s *hevc_pair = NULL; - if (!pdata->is_stream_mode_dv_multi) { - if (dv_toggle_prov_name) /*debug purpose*/ - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME : - VFM_DEC_DVEL_PROVIDER_NAME); - else - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : - VFM_DEC_DVBL_PROVIDER_NAME); - } else { - if (dv_toggle_prov_name) /*debug purpose*/ - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME2 : - VFM_DEC_DVEL_PROVIDER_NAME2); - else - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME2 : - VFM_DEC_DVBL_PROVIDER_NAME2); - } - + if (dv_toggle_prov_name) /*debug purpose*/ + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME : + VFM_DEC_DVEL_PROVIDER_NAME); + else + snprintf(pdata->vf_provider_name, + VDEC_PROVIDER_NAME_SIZE, + (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : + VFM_DEC_DVBL_PROVIDER_NAME); hevc->dolby_enhance_flag = pdata->master ? 1 : 0; if (pdata->master) hevc_pair = (struct hevc_state_s *) @@ -15413,13 +14438,16 @@ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vh265_vf_provider, pdata); + hevc->provider_name = pdata->vf_provider_name; platform_set_drvdata(pdev, pdata); hevc->platform_dev = pdev; if (((get_dbg_flag(hevc) & IGNORE_PARAM_FROM_CONFIG) == 0) && - pdata->config_len) { + pdata->config && pdata->config_len) { #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*use ptr config for doubel_write_mode, etc*/ hevc_print(hevc, 0, "pdata->config=%s\n", pdata->config); @@ -15468,18 +14496,18 @@ &config_val) == 0) hevc->mem_map_mode = config_val; + if (get_config_int(pdata->config, "dv_duallayer", + &config_val) == 0) + hevc->dv_duallayer = config_val; + else + hevc->dv_duallayer = false; + if (get_config_int(pdata->config, "negative_dv", &config_val) == 0) { hevc->discard_dv_data = config_val; hevc_print(hevc, 0, "discard dv data\n"); } - if (get_config_int(pdata->config, "dv_duallayer", - &config_val) == 0) { - hevc->dv_duallayer = config_val; - hevc_print(hevc, 0, "dv dual layer\n"); - } - if (get_config_int(pdata->config, "parm_enable_fence", &config_val) == 0) @@ -15495,17 +14523,6 @@ &config_val) == 0) hevc->low_latency_flag = config_val; - if (get_config_int(pdata->config, - "parm_v4l_metadata_config_flag", - &config_val) == 0) { - hevc->metadata_config_flag = config_val; - hevc->discard_dv_data = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE; - hevc->dv_duallayer = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_TWOLARYER; - if (hevc->discard_dv_data) - hevc_print(hevc, 0, "discard dv data\n"); - if (hevc->dv_duallayer) - hevc_print(hevc, 0, "dv_duallayer\n"); - } #endif } else { if (pdata->sys_info) @@ -15517,10 +14534,8 @@ } hevc->double_write_mode = double_write_mode; } - - - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vh265_vf_provider, pdata); + /* get valid double write from configure or node */ + //hevc->double_write_mode = get_double_write_mode(hevc); if (force_config_fence) { hevc->enable_fence = true; @@ -15532,45 +14547,31 @@ hevc->enable_fence, hevc->fence_usage); } - if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2) - hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2; - else - hevc->dynamic_buf_num_margin = dynamic_buf_num_margin; - - hevc->mem_map_mode = mem_map_mode; - - hevc->endian = HEVC_CONFIG_LITTLE_ENDIAN; - if (is_support_vdec_canvas()) - hevc->endian = HEVC_CONFIG_BIG_ENDIAN; - if (endian) - hevc->endian = endian; + if (hevc->enable_fence) + pdata->sync.usage = hevc->fence_usage; if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) && (hevc->double_write_mode == 3)) hevc->double_write_mode = 0x1000; - /* get valid double write from node */ - if (double_write_mode) - hevc->double_write_mode = get_double_write_mode(hevc); + if (!hevc->is_used_v4l) { + /* get valid double write from configure or node */ + //hevc->double_write_mode = get_double_write_mode(hevc); + if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2) + hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2; + else + hevc->dynamic_buf_num_margin = dynamic_buf_num_margin; + hevc->mem_map_mode = mem_map_mode; + } - if (mmu_enable_force) { - hevc->mmu_enable = 1; - } else { - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) || - (hevc->double_write_mode & 0x10)) + if (mmu_enable_force == 0) { + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) hevc->mmu_enable = 0; else hevc->mmu_enable = 1; } -#ifdef H265_10B_MMU_DW - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - hevc->dw_mmu_enable = - get_double_write_mode(hevc) & 0x20 ? 1 : 0; - } else { - hevc->dw_mmu_enable = 0; - } -#endif - if (init_mmu_buffers(hevc, 0) < 0) { + + if (init_mmu_buffers(hevc) < 0) { hevc_print(hevc, 0, "\n 265 mmu init failed!\n"); mutex_unlock(&vh265_mutex); @@ -15659,25 +14660,9 @@ vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC | CORE_MASK_COMBINE); - mutex_init(&hevc->fence_mutex); if (hevc->enable_fence) { - pdata->sync = vdec_sync_get(); - if (!pdata->sync) { - hevc_print(hevc, 0, "alloc fence timeline error\n"); - hevc_local_uninit(hevc); - if (hevc->gvs) - kfree(hevc->gvs); - hevc->gvs = NULL; - uninit_mmu_buffers(hevc); - /* devm_kfree(&pdev->dev, (void *)hevc); */ - if (hevc) - vfree((void *)hevc); - pdata->dec_status = NULL; - return -ENODEV; - } - pdata->sync->usage = hevc->fence_usage; /* creat timeline. */ - vdec_timeline_create(pdata->sync, DRIVER_NAME); + vdec_timeline_create(&pdata->sync, DRIVER_NAME); } return 0; @@ -15687,6 +14672,7 @@ struct vdec_sync *sync) { ulong expires; + int i; /* notify signal to wake up all fences. */ vdec_timeline_increase(sync, VF_POOL_SIZE); @@ -15699,6 +14685,15 @@ } } + for (i = 0; i < VF_POOL_SIZE; i++) { + struct vframe_s *vf = &hw->vfpool[i]; + + if (vf->fence) { + vdec_fence_put(vf->fence); + vf->fence = NULL; + } + } + /* decreases refcnt of timeline. */ vdec_timeline_put(sync); } @@ -15733,9 +14728,8 @@ vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED); if (hevc->enable_fence) - vdec_fence_release(hevc, vdec->sync); - if (is_rdma_enable()) - dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hevc->rdma_adr, hevc->rdma_phy_adr); + vdec_fence_release(hevc, &vdec->sync); + vfree((void *)hevc); return 0; @@ -15822,20 +14816,13 @@ { 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 = &amvh265_workbuff_spec[2]; - else - p_buf_info = &amvh265_workbuff_spec[1]; - } else - p_buf_info = &amvh265_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 = &amvh265_workbuff_spec[5]; + if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + p_buf_info = &amvh265_workbuff_spec[2]; else - p_buf_info = &amvh265_workbuff_spec[3]; - } + p_buf_info = &amvh265_workbuff_spec[1]; + } else + p_buf_info = &amvh265_workbuff_spec[0]; init_buff_spec(NULL, p_buf_info); work_buf_size = @@ -15875,26 +14862,19 @@ amvdec_h265_profile.profile = "4k"; } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { amvdec_h265_profile.profile = - "8k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, v4l-uvm"; + "8k, 8bit, 10bit, dwrite, compressed, frame_dv, fence"; }else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) { amvdec_h265_profile.profile = - "4k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, v4l-uvm"; + "4k, 8bit, 10bit, dwrite, compressed, frame_dv, fence"; } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_MG9TV) amvdec_h265_profile.profile = "4k"; - } else { - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) { - amvdec_h265_profile.profile = - "8bit, 10bit, dwrite, compressed, frame_dv, v4l"; - } else { - amvdec_h265_profile.profile = - "8bit, 10bit, dwrite, compressed, v4l"; - } } #endif if (codec_mm_get_total_size() < 80 * SZ_1M) { pr_info("amvdec_h265 default mmu enabled.\n"); mmu_enable = 1; } + vcodec_profile_register(&amvdec_h265_profile); amvdec_h265_profile_single = amvdec_h265_profile; amvdec_h265_profile_single.name = "h265"; @@ -15904,7 +14884,6 @@ vcodec_profile_register(&amvdec_h265_profile_mult); INIT_REG_NODE_CONFIGS("media.decoder", &decoder_265_node, "h265", h265_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_HEVC, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg.c index 917a2a1..6b87d4a 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg.c
@@ -28,6 +28,7 @@ #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/vdec_reg.h> #include "../../../stream_input/amports/amports_priv.h" #include <linux/amlogic/media/registers/register.h> @@ -35,6 +36,9 @@ #include "../utils/decoder_bmmu_box.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/amlogic/media/codec_mm/configs.h> +#include <linux/amlogic/tee.h> + + #ifdef CONFIG_AM_VDEC_MJPEG_LOG #define AMLOG @@ -393,8 +397,10 @@ } } -static void vmjpeg_put_timer_func(struct timer_list *timer) +static void vmjpeg_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; + while (!kfifo_is_empty(&recycle_q) && (READ_VREG(MREG_TO_AMRISC) == 0)) { struct vframe_s *vf; @@ -483,61 +489,61 @@ if (ret < 0) return ret; #ifdef NV21 - config_cav_lut_ex(index2canvas0(i) & 0xff, + canvas_config(index2canvas0(i) & 0xff, buf_start, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas0(i) >> 8) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas0(i) >> 8) & 0xff, buf_start + decbuf_y_size, canvas_width, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex(index2canvas1(i) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config(index2canvas1(i) & 0xff, buf_start + decbuf_size / 2, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas1(i) >> 8) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas1(i) >> 8) & 0xff, buf_start + decbuf_y_size + decbuf_uv_size / 2, canvas_width, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); + CANVAS_BLKMODE_LINEAR); #else - config_cav_lut_ex(index2canvas0(i) & 0xff, + canvas_config(index2canvas0(i) & 0xff, buf_start, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas0(i) >> 8) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas0(i) >> 8) & 0xff, buf_start + decbuf_y_size, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas0(i) >> 16) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas0(i) >> 16) & 0xff, buf_start + decbuf_y_size + decbuf_uv_size, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex(index2canvas1(i) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config(index2canvas1(i) & 0xff, buf_start + decbuf_size / 2, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas1(i) >> 8) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas1(i) >> 8) & 0xff, buf_start + decbuf_y_size + decbuf_uv_size / 2, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); - config_cav_lut_ex((index2canvas1(i) >> 16) & 0xff, + CANVAS_BLKMODE_LINEAR); + canvas_config((index2canvas1(i) >> 16) & 0xff, buf_start + decbuf_y_size + decbuf_uv_size + decbuf_uv_size / 2, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, 0, VDEC_1); + CANVAS_BLKMODE_LINEAR); #endif } @@ -734,7 +740,7 @@ if (IS_ERR_OR_NULL(buf)) return -ENOMEM; - timer_setup(&recycle_timer, vmjpeg_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -799,7 +805,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong)&recycle_timer; + recycle_timer.function = vmjpeg_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -902,16 +911,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mjpeg_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mjpeg_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mjpeg_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mjpeg_suspend, mjpeg_resume) +}; +#endif static struct platform_driver amvdec_mjpeg_driver = { .probe = amvdec_mjpeg_probe, .remove = amvdec_mjpeg_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mjpeg_pm_ops, +#endif } };
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c index 22d7dbd..108f5da 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
@@ -29,8 +29,7 @@ #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/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> #include <linux/amlogic/media/utils/vdec_reg.h> #include <linux/amlogic/media/registers/register.h> @@ -48,7 +47,6 @@ #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" #include <media/v4l2-mem2mem.h> -#include "../utils/vdec_feature.h" #define MEM_NAME "codec_mmjpeg" @@ -98,7 +96,6 @@ static int vmjpeg_vf_states(struct vframe_states *states, void *); static int vmjpeg_event_cb(int type, void *data, void *private_data); static void vmjpeg_work(struct work_struct *work); -static int notify_v4l_eos(struct vdec_s *vdec); static int pre_decode_buf_level = 0x800; static int start_decode_buf_level = 0x2000; static u32 without_display_mode; @@ -127,19 +124,14 @@ if (((debug_enable & debug_flag) && ((1 << index) & mmjpeg_debug_mask)) || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); + unsigned char buf[512]; int len = 0; va_list args; - - if (!buf) - return 0; - va_start(args, fmt); len = sprintf(buf, "%d: ", index); vsnprintf(buf + len, 512-len, fmt, args); pr_info("%s", buf); va_end(args); - kfree(buf); } return 0; } @@ -216,7 +208,7 @@ struct firmware_s *fw; struct timer_list check_timer; u32 decode_timeout_count; - u32 start_process_time; + unsigned long int start_process_time; u32 last_vld_level; u8 eos; u32 frame_num; @@ -237,7 +229,6 @@ u32 res_ch_flag; u32 canvas_mode; u32 canvas_endian; - ulong fb_token; char vdec_name[32]; char pts_name[32]; char new_q_name[32]; @@ -335,8 +326,7 @@ hw->res_ch_flag = 1; ctx->v4l_resolution_change = 1; hw->eos = 1; - if (hw->is_used_v4l) - notify_v4l_eos(hw_to_vdec(hw)); + notify_v4l_eos(hw_to_vdec(hw)); ret = 1; } @@ -348,8 +338,6 @@ static irqreturn_t vmjpeg_isr_thread_fn(struct vdec_s *vdec, int irq) { struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)(vdec->private); - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; u32 reg; struct vframe_s *vf = NULL; u32 index, offset = 0, pts; @@ -412,7 +400,6 @@ if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->buffer_spec[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, "[%d] %s(), v4l mem handle: 0x%lx\n", ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, @@ -468,17 +455,9 @@ vf->pts, vf->pts_us64, vf->duration); vdec->vdec_fps_detec(vdec->id); if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); } else vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec); @@ -671,12 +650,12 @@ hw->buffer_spec[i].v_canvas_index = canvas_v(canvas); } - config_cav_lut_ex(hw->buffer_spec[i].y_canvas_index, + canvas_config_ex(hw->buffer_spec[i].y_canvas_index, hw->buffer_spec[i].y_addr, canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, endian, VDEC_1); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[0].phy_addr = hw->buffer_spec[i].y_addr; hw->buffer_spec[i].canvas_config[0].width = @@ -688,12 +667,12 @@ hw->buffer_spec[i].canvas_config[0].endian = endian; - config_cav_lut_ex(hw->buffer_spec[i].u_canvas_index, + canvas_config_ex(hw->buffer_spec[i].u_canvas_index, hw->buffer_spec[i].u_addr, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, endian, VDEC_1); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[1].phy_addr = hw->buffer_spec[i].u_addr; hw->buffer_spec[i].canvas_config[1].width = @@ -705,12 +684,12 @@ hw->buffer_spec[i].canvas_config[1].endian = endian; - config_cav_lut_ex(hw->buffer_spec[i].v_canvas_index, + canvas_config_ex(hw->buffer_spec[i].v_canvas_index, hw->buffer_spec[i].v_addr, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR, endian, VDEC_1); + CANVAS_BLKMODE_LINEAR, endian); hw->buffer_spec[i].canvas_config[2].phy_addr = hw->buffer_spec[i].v_addr; hw->buffer_spec[i].canvas_config[2].width = @@ -833,7 +812,7 @@ hw->not_run_ready, hw->input_empty ); - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -936,10 +915,9 @@ vdec_schedule_work(&hw->work); } -static void check_timer_func(struct timer_list *timer) +static void check_timer_func(unsigned long arg) { - struct vdec_mjpeg_hw_s *hw = container_of(timer, - struct vdec_mjpeg_hw_s, check_timer); + struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); int timeout_val = decode_timeout_val; @@ -1008,16 +986,10 @@ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - if (hw->buffer_spec[i].v4l_ref_buf_addr) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *) - hw->buffer_spec[i].v4l_ref_buf_addr; - - fb->status = FB_ST_DECODER; + if (hw->buffer_spec[i].v4l_ref_buf_addr) return 0; - } - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { mmjpeg_debug_print(DECODE_ID(hw), 0, "[%d] get fb fail.\n", @@ -1026,8 +998,6 @@ return ret; } - fb->status = FB_ST_DECODER; - if (!hw->frame_width || !hw->frame_height) { struct vdec_pic_info pic; vdec_v4l_get_pic_info(ctx, &pic); @@ -1053,7 +1023,7 @@ decbuf_start = fb->m.mem[0].addr; decbuf_y_size = fb->m.mem[0].size; decbuf_u_start = fb->m.mem[1].addr; - decbuf_u_size = fb->m.mem[1].size >> 1; + decbuf_u_size = fb->m.mem[1].size; decbuf_v_start = decbuf_u_start + decbuf_u_size; decbuf_v_size = decbuf_u_size; canvas_width = ALIGN(hw->frame_width, 64); @@ -1075,7 +1045,7 @@ } mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] v4l ref buf addr: 0x%x\n", ctx->id, fb); + "[%d] v4l ref buf addr: 0x%px\n", ctx->id, fb); if (vdec->parallel_dec == 1) { if (hw->buffer_spec[i].y_canvas_index == -1) @@ -1105,8 +1075,8 @@ hw->buffer_spec[i].canvas_config[0].endian = hw->canvas_endian; - config_cav_lut(hw->buffer_spec[i].y_canvas_index, - &hw->buffer_spec[i].canvas_config[0], VDEC_1); + canvas_config_config(hw->buffer_spec[i].y_canvas_index, + &hw->buffer_spec[i].canvas_config[0]); hw->buffer_spec[i].canvas_config[1].phy_addr = decbuf_u_start; @@ -1119,8 +1089,8 @@ hw->buffer_spec[i].canvas_config[1].endian = hw->canvas_endian; - config_cav_lut(hw->buffer_spec[i].u_canvas_index, - &hw->buffer_spec[i].canvas_config[1], VDEC_1); + canvas_config_config(hw->buffer_spec[i].u_canvas_index, + &hw->buffer_spec[i].canvas_config[1]); hw->buffer_spec[i].canvas_config[2].phy_addr = decbuf_v_start; @@ -1133,8 +1103,8 @@ hw->buffer_spec[i].canvas_config[2].endian = hw->canvas_endian; - config_cav_lut(hw->buffer_spec[i].v_canvas_index, - &hw->buffer_spec[i].canvas_config[2], VDEC_1); + canvas_config_config(hw->buffer_spec[i].v_canvas_index, + &hw->buffer_spec[i].canvas_config[2]); /* mjpeg decoder canvas need to be revert to match display. */ hw->buffer_spec[i].canvas_config[0].endian = hw->canvas_endian ? 0 : 7; @@ -1187,9 +1157,6 @@ /*run to parser csd data*/ i = 0; } else { - if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) - return -1; - if (vmjpeg_v4l_alloc_buff_config_canvas(hw, i)) return -1; } @@ -1216,12 +1183,12 @@ if (!hw->is_used_v4l) { for (i = 0; i < hw->buf_num; i++) { buff_spec = &hw->buffer_spec[i]; - config_cav_lut(buff_spec->y_canvas_index, - &buff_spec->canvas_config[0], VDEC_1); - config_cav_lut(buff_spec->u_canvas_index, - &buff_spec->canvas_config[1], VDEC_1); - config_cav_lut(buff_spec->v_canvas_index, - &buff_spec->canvas_config[2], VDEC_1); + canvas_config_config(buff_spec->y_canvas_index, + &buff_spec->canvas_config[0]); + canvas_config_config(buff_spec->u_canvas_index, + &buff_spec->canvas_config[1]); + canvas_config_config(buff_spec->v_canvas_index, + &buff_spec->canvas_config[2]); } } } @@ -1317,7 +1284,10 @@ CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER); - timer_setup(&hw->check_timer, check_timer_func, 0); + init_timer(&hw->check_timer); + + hw->check_timer.data = (unsigned long)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; @@ -1520,12 +1490,9 @@ if (hw->is_used_v4l) { index = find_free_buffer(hw); - if (index == -1) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { - pr_err("[%d] get fb fail.\n", ctx->id); - return -1; - } + if ((index == -1) && vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { + pr_err("[%d] get fb fail.\n", ctx->id); + return -1; } } @@ -1534,18 +1501,13 @@ vf->v4l_mem_handle = (index == -1) ? (ulong)fb : hw->buffer_spec[index].v4l_ref_buf_addr; vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - - pr_info("[%d] mjpeg EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); + pr_info("[%d] mpeg12 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } return 0; @@ -1756,9 +1718,8 @@ hw->buf_num = vmjpeg_get_buf_num(hw); - if (!hw->is_used_v4l) - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vf_provider_ops, pdata); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vf_provider_ops, pdata); platform_set_drvdata(pdev, pdata); @@ -1813,7 +1774,6 @@ vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id); } } - vfree(hw); pr_info("%s\n", __func__); @@ -1821,22 +1781,38 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mmjpeg_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mmjpeg_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mmjpeg_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmjpeg_suspend, mmjpeg_resume) +}; +#endif static struct platform_driver ammvdec_mjpeg_driver = { .probe = ammvdec_mjpeg_probe, .remove = ammvdec_mjpeg_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mmjpeg_pm_ops, +#endif } }; static struct codec_profile_t ammvdec_mjpeg_profile = { .name = "mmjpeg", - .profile = "v4l" + .profile = "" }; static int __init ammvdec_mjpeg_driver_init_module(void) @@ -1846,7 +1822,6 @@ return -ENODEV; } vcodec_profile_register(&ammvdec_mjpeg_profile); - vcodec_feature_register(VFORMAT_MJPEG, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c index a813ac7..29757a0 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c
@@ -29,7 +29,7 @@ #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/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/dma-mapping.h> #include <linux/slab.h> @@ -41,8 +41,7 @@ #include "../utils/decoder_bmmu_box.h" #include <linux/uaccess.h> #include <linux/amlogic/media/codec_mm/configs.h> -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> @@ -1311,9 +1310,11 @@ } -static void vmpeg_put_timer_func(struct timer_list *timer) +static void vmpeg_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; int fatal_reset = 0; + enum receviver_start_e state = RECEIVER_INACTIVE; if (vf_get_receiver(PROVIDER_NAME)) { @@ -1764,30 +1765,30 @@ } else { #ifdef NV21 - config_cav_lut_ex(2 * i + 0, + canvas_config(2 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - config_cav_lut_ex(2 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(2 * i + 1, buf_start + decbuf_y_size, canvas_width, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32, 0, VDEC_1); + CANVAS_BLKMODE_32X32); #else - config_cav_lut_ex(3 * i + 0, + canvas_config(3 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - config_cav_lut_ex(3 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(3 * 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(3 * i + 2, + CANVAS_BLKMODE_32X32); + canvas_config(3 * 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_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); #endif } } @@ -1948,7 +1949,7 @@ if (IS_ERR_OR_NULL(buf)) return -ENOMEM; - timer_setup(&recycle_timer, vmpeg_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -2013,7 +2014,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong)&recycle_timer; + recycle_timer.function = vmpeg_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -2155,16 +2159,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mpeg12_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mpeg12_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mpeg12_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mpeg12_suspend, mpeg12_resume) +}; +#endif static struct platform_driver amvdec_mpeg12_driver = { .probe = amvdec_mpeg12_probe, .remove = amvdec_mpeg12_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mpeg12_pm_ops, +#endif } };
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index f77bb7f..76a021e 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
@@ -15,7 +15,6 @@ * */ -#define DEBUG #include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> @@ -27,19 +26,19 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/delay.h> -#include <linux/sched/clock.h> + #include <linux/amlogic/media/frame_sync/ptsserv.h> #include <linux/amlogic/media/utils/amstream.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/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> #include <linux/amlogic/media/utils/vdec_reg.h> #include <linux/amlogic/media/registers/register.h> #include "../../../stream_input/amports/amports_priv.h" + #include "../utils/vdec_input.h" #include "../utils/vdec.h" #include "../utils/amvdec.h" @@ -52,7 +51,8 @@ #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" #include <media/v4l2-mem2mem.h> -#include "../utils/vdec_feature.h" + + #define MEM_NAME "codec_mmpeg12" #define CHECK_INTERVAL (HZ/100) @@ -88,6 +88,7 @@ #define PICINFO_RPT_FIRST 0x4000 #define PICINFO_TOP_FIRST 0x2000 #define PICINFO_FRAME 0x1000 + #define TOP_FIELD 0x1000 #define BOTTOM_FIELD 0x2000 #define FRAME_PICTURE 0x3000 @@ -111,8 +112,6 @@ #define CTX_DECBUF_OFFSET (CTX_CO_MV_OFFSET + 0x11000) #define DEFAULT_MEM_SIZE (32*SZ_1M) -#define INVALID_IDX (-1) /* Invalid buffer index.*/ - static u32 buf_size = 32 * 1024 * 1024; static int pre_decode_buf_level = 0x800; static int start_decode_buf_level = 0x4000; @@ -180,6 +179,7 @@ #define DEC_RESULT_EOS 5 #define DEC_RESULT_GET_DATA 6 #define DEC_RESULT_GET_DATA_RETRY 7 +#define DEC_RESULT_DISCARD_DATA 8 #define DEC_DECODE_TIMEOUT 0x21 #define DECODE_ID(hw) (hw_to_vdec(hw)->id) @@ -217,7 +217,6 @@ ulong v4l_ref_buf_addr; u32 hw_decode_time; u32 frame_size; // For frame base mode - u64 timestamp; }; struct vdec_mpeg12_hw_s { @@ -271,7 +270,6 @@ s32 refs[2]; int dec_result; u32 timeout_processing; - wait_queue_head_t wait_q; struct work_struct work; struct work_struct timeout_work; struct work_struct notify_work; @@ -303,7 +301,6 @@ u32 pre_parser_wr_ptr; u8 next_again_flag; #endif - struct work_struct userdata_push_work; struct mutex userdata_mutex; struct mmpeg2_userdata_info_t userdata_info; @@ -342,18 +339,17 @@ u32 level_idc; int dec_again_cnt; int vdec_pg_enable_flag; - ulong fb_token; char vdec_name[32]; char pts_name[32]; char new_q_name[32]; char disp_q_name[32]; - bool run_flag; + u32 last_frame_offset; }; static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw); static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw); static void reset_process_time(struct vdec_mpeg12_hw_s *hw); -static int vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw); +static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw); static void flush_output(struct vdec_mpeg12_hw_s *hw); static struct vframe_s *vmpeg_vf_peek(void *); static struct vframe_s *vmpeg_vf_get(void *); @@ -363,12 +359,14 @@ static int notify_v4l_eos(struct vdec_s *vdec); static void start_process_time_set(struct vdec_mpeg12_hw_s *hw); static int check_dirty_data(struct vdec_s *vdec); + static int debug_enable; /*static struct work_struct userdata_push_work;*/ #undef pr_info #define pr_info printk unsigned int mpeg12_debug_mask = 0xff; /*static int counter_max = 5;*/ + static u32 run_ready_min_buf_num = 2; static int dirty_again_threshold = 100; static int error_proc_policy = 0x1; @@ -376,7 +374,7 @@ #define PRINT_FLAG_ERROR 0x0 #define PRINT_FLAG_RUN_FLOW 0X0001 #define PRINT_FLAG_TIMEINFO 0x0002 -#define PRINT_FLAG_UCODE_DETAIL 0x0004 +#define PRINT_FLAG_UCODE_DETAIL 0x0004 #define PRINT_FLAG_VLD_DETAIL 0x0008 #define PRINT_FLAG_DEC_DETAIL 0x0010 #define PRINT_FLAG_BUFFER_DETAIL 0x0020 @@ -390,28 +388,25 @@ #define PRINT_FLAG_USERDATA_DETAIL 0x2000 #define PRINT_FLAG_TIMEOUT_STATUS 0x4000 #define PRINT_FLAG_V4L_DETAIL 0x8000 +#define PRINT_FLAG_FCC_STATUS 0x10000 #define IGNORE_PARAM_FROM_CONFIG 0x8000000 + int debug_print(int index, int debug_flag, const char *fmt, ...) { if (((debug_enable & debug_flag) && ((1 << index) & mpeg12_debug_mask)) || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); + unsigned char buf[512]; int len = 0; va_list args; - - if (!buf) - return 0; - va_start(args, fmt); len = sprintf(buf, "%d: ", index); vsnprintf(buf + len, 512-len, fmt, args); pr_info("%s", buf); va_end(args); - kfree(buf); } return 0; } @@ -449,16 +444,10 @@ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - if (hw->pics[i].v4l_ref_buf_addr) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *) - hw->pics[i].v4l_ref_buf_addr; - - fb->status = FB_ST_DECODER; + if (hw->pics[i].v4l_ref_buf_addr) return 0; - } - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { debug_print(DECODE_ID(hw), 0, "[%d] get fb fail %d/%d.\n", @@ -466,8 +455,6 @@ return ret; } - fb->status = FB_ST_DECODER; - if (!hw->frame_width || !hw->frame_height) { struct vdec_pic_info pic; vdec_v4l_get_pic_info(ctx, &pic); @@ -498,7 +485,7 @@ fb->m.mem[1].bytes_used = decbuf_uv_size; } - debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n", + debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%px\n", ctx->id, __func__, fb); if (vdec->parallel_dec == 1) { @@ -526,11 +513,7 @@ hw->canvas_config[i][0].block_mode = hw->canvas_mode; hw->canvas_config[i][0].endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; - config_cav_lut(canvas_y(canvas), &hw->canvas_config[i][0], VDEC_1); - - /* mpeg2 decoder canvas need to be revert to match display canvas */ - hw->canvas_config[i][0].endian = - (hw->canvas_mode != CANVAS_BLKMODE_LINEAR) ? 7 : 0; + canvas_config_config(canvas_y(canvas), &hw->canvas_config[i][0]); hw->canvas_config[i][1].phy_addr = decbuf_uv_start; hw->canvas_config[i][1].width = canvas_width; @@ -538,14 +521,10 @@ hw->canvas_config[i][1].block_mode = hw->canvas_mode; hw->canvas_config[i][1].endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; - config_cav_lut(canvas_u(canvas), &hw->canvas_config[i][1], VDEC_1); - - /* mpeg2 decoder canvas need to be revert to match display canvas */ - hw->canvas_config[i][1].endian = - (hw->canvas_mode != CANVAS_BLKMODE_LINEAR) ? 7 : 0; + canvas_config_config(canvas_u(canvas), &hw->canvas_config[i][1]); debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL, - "[%d] %s(), canvas: 0x%x mode: %d y: %x uv: %x w: %d h: %d\n", + "[%d] %s(), canvas: 0x%x mode: %d y: %lx uv: %lx w: %d h: %d\n", ctx->id, __func__, canvas, hw->canvas_mode, decbuf_start, decbuf_uv_start, canvas_width, canvas_height); @@ -553,7 +532,6 @@ return 0; } - static unsigned int vmpeg12_get_buf_num(struct vdec_mpeg12_hw_s *hw) { unsigned int buf_num = DECODE_BUFFER_NUM_DEF; @@ -598,9 +576,6 @@ /*run to parser csd data*/ i = 0; } else { - if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) - return -1; - if (vmpeg12_v4l_alloc_buff_config_canvas(hw, i)) return -1; } @@ -1481,11 +1456,6 @@ offset = READ_VREG(AV_SCRATCH_I); - codec_mm_dma_flush( - hw->ccbuf_phyAddress_virt, - CCBUF_SIZE, - DMA_FROM_DEVICE); - mutex_lock(&hw->userdata_mutex); if (hw->ccbuf_phyAddress_virt) { pdata = (u8 *)hw->ccbuf_phyAddress_virt + hw->ucode_cc_last_wp; @@ -1568,7 +1538,6 @@ if (pdata >= hw->userdata_info.data_buf_end) pdata = hw->userdata_info.data_buf; } - pcur_ud_rec = hw->ud_record + hw->cur_ud_idx; pcur_ud_rec->meta_info = meta_info; @@ -1595,6 +1564,7 @@ hw->cur_ud_idx++; WRITE_VREG(AV_SCRATCH_J, 0); + } @@ -1641,10 +1611,12 @@ u32 info = pic->buffer_info; struct vdec_s *vdec = hw_to_vdec(hw); struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; ulong nv_order = VIDTYPE_VIU_NV21; bool pb_skip = false; +#ifdef NV21 + type = nv_order; +#endif /* swap uv */ if (hw->is_used_v4l) { if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || @@ -1652,9 +1624,6 @@ nv_order = VIDTYPE_VIU_NV12; } -#ifdef NV21 - type = nv_order; -#endif if (hw->i_only) { pb_skip = 1; } @@ -1676,10 +1645,6 @@ field_num = (info & PICINFO_RPT_FIRST) ? 3 : 2; } - if ((hw->is_used_v4l) && - (vdec->prog_only)) - field_num = 1; - for (i = 0; i < field_num; i++) { if (kfifo_get(&hw->newframe_q, &vf) == 0) { debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, @@ -1692,7 +1657,6 @@ if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->pics[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, "[%d] %s(), v4l mem handle: 0x%lx\n", ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, @@ -1737,11 +1701,9 @@ if (i > 0) { vf->pts = 0; vf->pts_us64 = 0; - vf->timestamp = 0; } else { vf->pts = (pic->pts_valid) ? pic->pts : 0; vf->pts_us64 = (pic->pts_valid) ? pic->pts64 : 0; - vf->timestamp = pic->timestamp; } vf->type_original = vf->type; @@ -1818,17 +1780,9 @@ __func__); } if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); } else vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); @@ -1909,18 +1863,20 @@ return 0; } -static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps) +static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height, + bool frame_prog, struct aml_vdec_ps_infos *ps) { ps->visible_width = width; ps->visible_height = height; ps->coded_width = ALIGN(width, 64); ps->coded_height = ALIGN(height, 32); ps->dpb_size = hw->buf_num; + ps->field = frame_prog ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED; return 0; } -static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height) +static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height, bool frame_prog) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); @@ -1939,7 +1895,7 @@ hw->frame_width, hw->frame_height, width, height); - vmpeg2_get_ps_info(hw, width, height, &ps); + vmpeg2_get_ps_info(hw, width, height, frame_prog, &ps); vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; @@ -1947,8 +1903,7 @@ ctx->v4l_resolution_change = 1; hw->eos = 1; flush_output(hw); - if (hw->is_used_v4l) - notify_v4l_eos(hw_to_vdec(hw)); + notify_v4l_eos(hw_to_vdec(hw)); ret = 1; } @@ -1957,6 +1912,65 @@ return ret; } +#ifdef VDEC_FCC_SUPPORT +static void fcc_discard_mode_process(struct vdec_s *vdec) +{ + struct vdec_mpeg12_hw_s *hw = + (struct vdec_mpeg12_hw_s *)(vdec->private); + int wrap_count; + u32 rp; + u32 first_ptr; + + if (vdec->fcc_status == AGAIN_STATUS) { + wrap_count = READ_VREG(VLD_MEM_VIFIFO_WRAP_COUNT); + rp = READ_VREG(VLD_MEM_VIFIFO_RP); + first_ptr = vdec->vbuf.ext_buf_addr; + + vdec->stream_offset = rp + vdec->input.size * wrap_count - first_ptr; + debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Notify stream_offset: %d\n", + vdec->id, vdec->stream_offset); + + debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: rp : 0x%x size: 0x%x wrap_count:%d first_ptr: 0x%x\n", + vdec->id, rp, vdec->input.size, wrap_count, first_ptr); + vdec_wakeup_fcc_poll(vdec); + vdec->fcc_status = WAIT_MSG_STATUS; + hw->dec_result = DEC_RESULT_AGAIN; + vdec_schedule_work(&hw->work); + } else if (vdec->fcc_status == DISCARD_STATUS) { + debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Discard current gop and to find next gop!\n", + vdec->id); + vdec->fcc_status = AGAIN_STATUS; + hw->dec_result = DEC_RESULT_DISCARD_DATA; + vdec_schedule_work(&hw->work); + } +} + +static int vmpeg2_fcc_process(struct vdec_s *vdec) +{ + struct vdec_mpeg12_hw_s *hw = + (struct vdec_mpeg12_hw_s *)(vdec->private); + + if (input_stream_based(vdec)) { + switch (vdec->fcc_mode) { + case FCC_DISCARD_MODE: + fcc_discard_mode_process(vdec); + return 1; + case FCC_DEC_MODE: + debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS, + "[%d][FCC]: Current is Dec mode.\n", vdec->id); + break; + case FCC_BUTT: + default: + break; + } + } + + return 0; +} +#endif static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq) { @@ -1988,16 +2002,26 @@ "[vdec_kpi][%s] First I frame coming.\n", __func__); } + +#ifdef VDEC_FCC_SUPPORT + if (vmpeg2_fcc_process(vdec) > 0) { + WRITE_VREG(AV_SCRATCH_G, 0); + return IRQ_HANDLED; + } +#endif if (hw->is_used_v4l) { int frame_width = READ_VREG(MREG_PIC_WIDTH); int frame_height = READ_VREG(MREG_PIC_HEIGHT); - if (!v4l_res_change(hw, frame_width, frame_height)) { + int info = READ_VREG(MREG_SEQ_INFO); + bool frame_prog = info & 0x10000; + + if (!v4l_res_change(hw, frame_width, frame_height, frame_prog)) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { struct aml_vdec_ps_infos ps; - vmpeg2_get_ps_info(hw, frame_width, frame_height, &ps); + vmpeg2_get_ps_info(hw, frame_width, frame_height, frame_prog, &ps); hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); userdata_pushed_drop(hw); @@ -2019,7 +2043,7 @@ } reg = READ_VREG(AV_SCRATCH_J); - if (reg & (1<<16)) { + if (reg & (1 << 16)) { vdec_schedule_work(&hw->userdata_push_work); return IRQ_HANDLED; } @@ -2042,7 +2066,6 @@ READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_CONTROL), READ_VREG(VIFF_BIT_CNT)); - if (vdec_frame_based(vdec)) { userdata_pushed_drop(hw); hw->dec_result = DEC_RESULT_DONE; @@ -2119,7 +2142,6 @@ new_pic->pts_valid = hw->chunk->pts_valid; new_pic->pts = hw->chunk->pts; new_pic->pts64 = hw->chunk->pts64; - new_pic->timestamp = hw->chunk->timestamp; if (hw->last_chunk_pts == hw->chunk->pts) { new_pic->pts_valid = 0; debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, @@ -2139,9 +2161,12 @@ } else { if (hw->chunk) { hw->last_chunk_pts = hw->chunk->pts; - new_pic->timestamp = hw->chunk->timestamp; + new_pic->pts_valid = hw->chunk->pts_valid; + new_pic->pts = hw->chunk->pts; + new_pic->pts64 = hw->chunk->pts64; + } else { + new_pic->pts_valid = false; } - new_pic->pts_valid = false; } debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, @@ -2199,10 +2224,9 @@ } debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "mmpeg12: disp_pic=%d(%c), ind=%d, offst=%x, pts=(%d,%lld,%llx)(%d)\n", + "mmpeg12: disp_pic=%d(%c), ind=%d, offst=%x, pts=(%d,%lld)(%d)\n", hw->disp_num, GET_SLICE_TYPE(info), index, disp_pic->offset, - disp_pic->pts, disp_pic->pts64, - disp_pic->timestamp, disp_pic->pts_valid); + disp_pic->pts, disp_pic->pts64, disp_pic->pts_valid); prepare_display_buf(hw, disp_pic); vdec_schedule_work(&hw->work); @@ -2214,30 +2238,32 @@ { u32 info, offset; struct vdec_mpeg12_hw_s *hw = - (struct vdec_mpeg12_hw_s *)(vdec->private); + (struct vdec_mpeg12_hw_s *)(vdec->private); if (hw->eos) return IRQ_HANDLED; info = READ_VREG(MREG_PIC_INFO); offset = READ_VREG(MREG_FRAME_OFFSET); - - vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset); - if (info &PICINFO_ERROR) { - if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) { - hw->gvs.i_concealed_frames++; - } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) { - hw->gvs.p_concealed_frames++; - } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) { - hw->gvs.b_concealed_frames++; + if (offset != hw->last_frame_offset) { + vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset); + if (info & PICINFO_ERROR) { + if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) { + hw->gvs.i_concealed_frames++; + } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) { + hw->gvs.p_concealed_frames++; + } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) { + hw->gvs.b_concealed_frames++; + } } - } - if (offset) { - if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) { - hw->gvs.i_decoded_frames++; - } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) { - hw->gvs.p_decoded_frames++; - } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) { - hw->gvs.b_decoded_frames++; + if (offset) { + if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) { + hw->gvs.i_decoded_frames++; + } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) { + hw->gvs.p_decoded_frames++; + } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) { + hw->gvs.b_decoded_frames++; + } } + hw->last_frame_offset = offset; } WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); @@ -2251,7 +2277,7 @@ struct vdec_mpeg12_hw_s, notify_work); struct vdec_s *vdec = hw_to_vdec(hw); - if (!hw->is_used_v4l && vdec->fr_hint_state == VDEC_NEED_HINT) { + if (vdec->fr_hint_state == VDEC_NEED_HINT) { vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_FR_HINT, (void *)((unsigned long)hw->frame_dur)); @@ -2303,7 +2329,7 @@ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); struct vframe_s *vf = NULL; struct vdec_v4l2_buffer *fb = NULL; - int index = INVALID_IDX; + int index = -1; if (hw->eos) { if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) { @@ -2314,31 +2340,24 @@ } if (hw->is_used_v4l) { index = find_free_buffer(hw); - if (index == INVALID_IDX) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { - pr_err("[%d] get fb fail.\n", ctx->id); - return -1; - } + if ((index == -1) && + vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { + pr_err("[%d] get fb fail.\n", ctx->id); + return -1; } } vf->type |= VIDTYPE_V4L_EOS; vf->timestamp = ULONG_MAX; - vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb : + vf->v4l_mem_handle = (index == -1) ? (ulong)fb : hw->pics[index].v4l_ref_buf_addr; vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(hw->pts_name, vf->pts); - - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); pr_info("[%d] mpeg12 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } @@ -2455,6 +2474,10 @@ debug_print(DECODE_ID(hw), 0, "%s: end of stream, num %d(%d)\n", __func__, hw->disp_num, hw->dec_num); + } else if (hw->dec_result == DEC_RESULT_DISCARD_DATA) { + hw->dec_again_cnt = 0; + vdec_vframe_dirty(vdec, hw->chunk); + hw->chunk = NULL; } if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); @@ -2483,7 +2506,6 @@ else vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC); - wake_up_interruptible(&hw->wait_q); if (hw->is_used_v4l) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); @@ -2703,7 +2725,7 @@ /****************************************/ -static int vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw) +static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw) { int i, ret; u32 canvas_width, canvas_height; @@ -2740,9 +2762,9 @@ ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i, decbuf_size, DRIVER_NAME, &decbuf_start); if (ret < 0) { - pr_err("bmmu alloc failed! size 0x%d idx %d\n", + pr_err("mmu alloc failed! size 0x%d idx %d\n", decbuf_size, i); - return ret; + return; } } @@ -2753,7 +2775,7 @@ GFP_KERNEL); if (hw->ccbuf_phyAddress_virt == NULL) { pr_err("%s: failed to alloc cc buffer\n", __func__); - return -ENOMEM; + return; } hw->buf_start = decbuf_start; WRITE_VREG(MREG_CO_MV_START, hw->buf_start); @@ -2791,8 +2813,8 @@ hw->canvas_config[i][0].endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0; - config_cav_lut(canvas_y(canvas), - &hw->canvas_config[i][0], VDEC_1); + canvas_config_config(canvas_y(canvas), + &hw->canvas_config[i][0]); hw->canvas_config[i][1].phy_addr = decbuf_start + decbuf_y_size; @@ -2802,11 +2824,11 @@ hw->canvas_config[i][1].endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0; - config_cav_lut(canvas_u(canvas), - &hw->canvas_config[i][1], VDEC_1); + canvas_config_config(canvas_u(canvas), + &hw->canvas_config[i][1]); } } - return 0; + return; } static void vmpeg2_dump_state(struct vdec_s *vdec) @@ -2817,12 +2839,11 @@ debug_print(DECODE_ID(hw), 0, "====== %s\n", __func__); debug_print(DECODE_ID(hw), 0, - "width/height (%d/%d),i_first %d, buf_num %d, run_flag %d\n", + "width/height (%d/%d),i_first %d, buf_num %d\n", hw->frame_width, hw->frame_height, hw->first_i_frame_ready, - hw->buf_num, - hw->run_flag + hw->buf_num ); debug_print(DECODE_ID(hw), 0, "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d,input_empty %d\n", @@ -2843,7 +2864,7 @@ hw->vfbuf_use[i], hw->ref_use[i]); } - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -2941,6 +2962,7 @@ hw->decode_timeout_count = 10; hw->start_process_time = jiffies; } + static void timeout_process(struct vdec_mpeg12_hw_s *hw) { struct vdec_s *vdec = hw_to_vdec(hw); @@ -2972,10 +2994,9 @@ vdec_schedule_work(&hw->timeout_work); } -static void check_timer_func(struct timer_list *timer) +static void check_timer_func(unsigned long arg) { - struct vdec_mpeg12_hw_s *hw = container_of(timer, - struct vdec_mpeg12_hw_s, check_timer); + struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); unsigned int timeout_val = decode_timeout_val; @@ -3015,26 +3036,24 @@ static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw) { - u32 index = -1, i; + int index = -1; + u32 i; struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; index = find_free_buffer(hw); if (index < 0 || index >= hw->buf_num) return -1; - if (!hw->init_flag) { - if (vmpeg12_canvas_init(hw) < 0) { - debug_print(DECODE_ID(hw), 0, "vmpeg12_canvas_init failed\n"); - return -1; - } - } else { + if (!hw->init_flag) + vmpeg12_canvas_init(hw); + else { WRITE_VREG(MREG_CO_MV_START, hw->buf_start); WRITE_VREG(MREG_CC_ADDR, hw->ccbuf_phyAddress); if (!hw->is_used_v4l) { for (i = 0; i < hw->buf_num; i++) { - config_cav_lut(canvas_y(hw->canvas_spec[i]), - &hw->canvas_config[i][0], VDEC_1); - config_cav_lut(canvas_u(hw->canvas_spec[i]), - &hw->canvas_config[i][1], VDEC_1); + canvas_config_config(canvas_y(hw->canvas_spec[i]), + &hw->canvas_config[i][0]); + canvas_config_config(canvas_u(hw->canvas_spec[i]), + &hw->canvas_config[i][1]); } } } @@ -3059,7 +3078,6 @@ READ_VREG(MREG_REF1), READ_VREG(REC_CANVAS_ADDR), hw->ctx_valid, index); - /* set to mpeg1 default */ WRITE_VREG(MPEG1_2_REG, (hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 0); @@ -3207,7 +3225,6 @@ hw->dec_again_cnt = 0; hw->error_frame_skip_level = error_frame_skip_level; - init_waitqueue_head(&hw->wait_q); if (dec_control) hw->dec_control = dec_control; } @@ -3255,10 +3272,9 @@ USER_DATA_SIZE); //amvdec_enable(); - timer_setup(&hw->check_timer, check_timer_func, 0); - //init_timer(&hw->check_timer); - //hw->check_timer.data = (unsigned long)hw; - //hw->check_timer.function = check_timer_func; + init_timer(&hw->check_timer); + hw->check_timer.data = (unsigned long)hw; + hw->check_timer.function = check_timer_func; hw->check_timer.expires = jiffies + CHECK_INTERVAL; hw->stat |= STAT_TIMER_ARM; @@ -3270,6 +3286,13 @@ return 0; } +#ifdef VDEC_FCC_SUPPORT +static void vmmpeg2_wakeup_fcc_poll(struct vdec_s *vdec) +{ + amstream_wakeup_fcc_poll(vdec); +} +#endif + static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct vdec_mpeg12_hw_s *hw = @@ -3283,7 +3306,6 @@ "mpeg12 work pending,not ready for run.\n"); return 0; } - hw->timeout_processing = 0; if (vdec_stream_based(vdec) && (hw->init_flag == 0) && pre_decode_buf_level != 0) { u32 rp, wp, level; @@ -3341,10 +3363,17 @@ } if (!is_enough_free_buffer(hw)) { - hw->not_run_ready++; hw->buffer_not_ready++; return 0; } + +#ifdef VDEC_FCC_SUPPORT + if (!vdec_has_get_fcc_new_msg(vdec)) { + hw->buffer_not_ready++; + return 0; + } +#endif + hw->not_run_ready = 0; hw->buffer_not_ready = 0; if (vdec->parallel_dec == 1) @@ -3391,7 +3420,6 @@ if (level > (vdec->input.size / 2)) hw->dec_again_cnt++; - if (hw->dec_again_cnt > dirty_again_threshold) { debug_print(DECODE_ID(hw), 0, "mpeg12 data skipped %x\n", level); hw->dec_again_cnt = 0; @@ -3409,8 +3437,6 @@ (struct vdec_mpeg12_hw_s *)vdec->private; int save_reg; int size, ret; - - hw->run_flag = 1; if (!hw->vdec_pg_enable_flag) { hw->vdec_pg_enable_flag = 1; amvdec_enable(); @@ -3441,7 +3467,6 @@ debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, "vdec_prepare_input: Insufficient data\n"); vdec_schedule_work(&hw->work); - hw->run_flag = 0; return; } @@ -3470,8 +3495,8 @@ u8 *data = NULL; if (hw->chunk) debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "run: chunk offset 0x%x, size %d\n", - hw->chunk->offset, hw->chunk->size); + "run: chunk offset 0x%x, size %d, pts %d, pts64 %lld\n", + hw->chunk->offset, hw->chunk->size, hw->chunk->pts, hw->chunk->pts64); if (!hw->chunk->block->is_mapped) data = codec_mm_vmap(hw->chunk->block->start + @@ -3532,7 +3557,6 @@ hw->fw->name, 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; @@ -3543,7 +3567,7 @@ hw->dec_result = DEC_RESULT_ERROR; debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, "ammvdec_mpeg12: error HW context restore\n"); - hw->run_flag = 0; + vdec_schedule_work(&hw->work); return; } /*wmb();*/ @@ -3556,29 +3580,14 @@ vdec->mvfrm->hw_decode_start = local_clock(); amvdec_start(); hw->stat |= STAT_VDEC_RUN; - hw->stat |= STAT_TIMER_ARM; hw->init_flag = 1; - if (hw->mm_blk_handle) - mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); - hw->run_flag = 0; + + mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); } static void reset(struct vdec_s *vdec) { - struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private; - pr_info("ammvdec_mpeg12: reset.\n"); - - vmpeg12_local_init(hw); - - if (hw->is_used_v4l) { - u32 i, buf_num = vmpeg12_get_buf_num(hw); - for (i = 0; i < buf_num; i++) { - hw->pics[i].v4l_ref_buf_addr = 0; - } - } - - hw->ctx_valid = 0; } static int vmpeg12_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) @@ -3634,6 +3643,9 @@ pdata->reset_userdata_fifo = vmmpeg2_reset_userdata_fifo; pdata->wakeup_userdata_poll = vmmpeg2_wakeup_userdata_poll; +#ifdef VDEC_FCC_SUPPORT + pdata->wakeup_fcc_poll = vmmpeg2_wakeup_fcc_poll; +#endif snprintf(hw->vdec_name, sizeof(hw->vdec_name), "mpeg12-%d", pdev->id); snprintf(hw->pts_name, sizeof(hw->pts_name), @@ -3726,6 +3738,7 @@ vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC | CORE_MASK_COMBINE); } + hw->last_frame_offset = 0xFFFFFFFF; #ifdef DUMP_USER_DATA amvdec_mmpeg12_init_userdata_dump(hw); reset_user_data_buf(hw); @@ -3744,17 +3757,6 @@ struct vdec_s *vdec = hw_to_vdec(hw); int i; - if (vdec->next_status == VDEC_STATUS_DISCONNECTED - && (vdec->status == VDEC_STATUS_ACTIVE)) { - debug_print(DECODE_ID(hw), 0, - "%s, force exit %d\n", __func__, __LINE__); - hw->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&hw->work); - wait_event_interruptible_timeout(hw->wait_q, - (vdec->status == VDEC_STATUS_CONNECTED), - msecs_to_jiffies(1000)); /* wait for work done */ - } - if (hw->stat & STAT_VDEC_RUN) { amvdec_stop(); hw->stat &= ~STAT_VDEC_RUN; @@ -3775,12 +3777,8 @@ cancel_work_sync(&hw->timeout_work); if (hw->mm_blk_handle) { - void *bmmu_box_tmp = hw->mm_blk_handle; + decoder_bmmu_box_free(hw->mm_blk_handle); hw->mm_blk_handle = NULL; - while (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); @@ -3825,22 +3823,38 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mmpeg12_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mmpeg12_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mmpeg12_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmpeg12_suspend, mmpeg12_resume) +}; +#endif static struct platform_driver ammvdec_mpeg12_driver = { .probe = ammvdec_mpeg12_probe, .remove = ammvdec_mpeg12_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mmpeg12_pm_ops, +#endif } }; static struct codec_profile_t ammvdec_mpeg12_profile = { .name = "mmpeg12", - .profile = "v4l" + .profile = "" }; static struct mconfig mmpeg12_configs[] = { @@ -3872,7 +3886,6 @@ vcodec_profile_register(&ammvdec_mpeg12_profile); INIT_REG_NODE_CONFIGS("media.decoder", &mmpeg12_node, "mmpeg12", mmpeg12_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_MPEG12, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c index 7d33a75..b13ca9c 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c
@@ -26,10 +26,12 @@ #include <linux/dma-mapping.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/canvas/canvas.h> + #include <linux/amlogic/media/utils/vdec_reg.h> #include "vmpeg4.h" #include <linux/amlogic/media/registers/register.h> @@ -38,12 +40,10 @@ #include "../utils/decoder_bmmu_box.h" #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/amlogic/media/codec_mm/configs.h> -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> #include "../../../common/chips/decoder_cpu_ver_info.h" - /* #define CONFIG_AM_VDEC_MPEG4_LOG */ #ifdef CONFIG_AM_VDEC_MPEG4_LOG #define AMLOG @@ -182,6 +182,7 @@ static struct work_struct notify_work; static struct work_struct set_clk_work; static bool is_reset; +static bool first_i_frame_ready; static DEFINE_SPINLOCK(lock); @@ -435,8 +436,8 @@ pts += vop_time_inc_since_last_anch * PTS_UNIT / rate; - pts_us64 += div_u64((u64)(vop_time_inc_since_last_anch * - PTS_UNIT / rate) * 100, 9); + pts_us64 += (u64)(vop_time_inc_since_last_anch * + PTS_UNIT / rate) * 100 / 9; if (vop_time_inc_since_last_anch > (1 << 14)) { /* avoid overflow */ @@ -462,6 +463,11 @@ } } + if ( (first_i_frame_ready == 0) && + (picture_type == I_PICTURE)) { + first_i_frame_ready = 1; + } + if (reg & INTERLACE_FLAG) { /* interlace */ if (kfifo_get(&newframe_q, &vf) == 0) { printk @@ -492,17 +498,23 @@ set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO)); vfbuf_use[buffer_index]++; - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( + + if (first_i_frame_ready == 0) { + kfifo_put(&recycle_q, (const struct vframe_s *)vf); + } else { + 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); + 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); + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + + } if (kfifo_get(&newframe_q, &vf) == 0) { printk( @@ -533,23 +545,29 @@ set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO)); - vfbuf_use[buffer_index]++; - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); - amlog_mask(LOG_MASK_PTS, "[%s:%d] [inte] dur=0x%x rate=%d picture_type=%d\n", __func__, __LINE__, vf->duration, vmpeg4_amstream_dec_info.rate, picture_type); - kfifo_put(&display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(MODULE_NAME, vf->pts); + vfbuf_use[buffer_index]++; - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, + if (first_i_frame_ready == 0) { + kfifo_put(&recycle_q, (const struct vframe_s *)vf); + } else { + 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); + } + } else { /* progressive */ if (kfifo_get(&newframe_q, &vf) == 0) { @@ -586,18 +604,25 @@ __func__, __LINE__, vf->duration, vmpeg4_amstream_dec_info.rate, picture_type); + vfbuf_use[buffer_index]++; - vf->mem_handle = + + if (first_i_frame_ready == 0) { + kfifo_put(&recycle_q, (const struct vframe_s *)vf); + } else { + vf->mem_handle = decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); + mm_blk_handle, + buffer_index); - kfifo_put(&display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(MODULE_NAME, vf->pts); + 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); + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } + } total_frame += repeat_cnt + 1; @@ -725,8 +750,10 @@ frame_width, frame_height, fps); } -static void vmpeg_put_timer_func(struct timer_list *timer) +static void vmpeg_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; + while (!kfifo_is_empty(&recycle_q) && (READ_VREG(MREG_BUFFERIN) == 0)) { struct vframe_s *vf; @@ -742,7 +769,7 @@ if (frame_dur > 0 && saved_resolution != frame_width * frame_height * (96000 / frame_dur)) - schedule_work(&set_clk_work); + schedule_work(&set_clk_work); if (READ_VREG(AV_SCRATCH_L)) { pr_info("mpeg4 fatal error happened,need reset !!\n"); @@ -872,30 +899,30 @@ #ifdef NV21 - config_cav_lut_ex(2 * i + 0, + canvas_config(2 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - config_cav_lut_ex(2 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(2 * i + 1, buf_start + decbuf_y_size, canvas_width, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32, 0, VDEC_1); + CANVAS_BLKMODE_32X32); #else - config_cav_lut_ex(3 * i + 0, + canvas_config(3 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - config_cav_lut_ex(3 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(3 * 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(3 * i + 2, + CANVAS_BLKMODE_32X32); + canvas_config(3 * 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_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); #endif } @@ -997,6 +1024,7 @@ frame_num_since_last_anch = 0; + first_i_frame_ready = 0; #ifdef CONFIG_AM_VDEC_MPEG4_LOG pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0; #endif @@ -1073,7 +1101,7 @@ stat |= STAT_MC_LOAD; query_video_status(0, &trickmode_fffb); - timer_setup(&recycle_timer, vmpeg_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; if (vdec_request_irq(VDEC_IRQ_1, vmpeg4_isr, @@ -1118,7 +1146,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong)&recycle_timer; + recycle_timer.function = vmpeg_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -1225,16 +1256,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mpeg4_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mpeg4_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mpeg4_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mpeg4_suspend, mpeg4_resume) +}; +#endif static struct platform_driver amvdec_mpeg4_driver = { .probe = amvdec_mpeg4_probe, .remove = amvdec_mpeg4_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mpeg4_pm_ops, +#endif } };
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 00ceb71..167204c 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
@@ -24,17 +24,15 @@ #include <linux/kfifo.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> -#include <linux/delay.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/canvas/canvas.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> -#include <linux/sched/clock.h> +#include <linux/amlogic/tee.h> #include <linux/amlogic/media/utils/vdec_reg.h> #include <linux/amlogic/media/registers/register.h> #include "../../../stream_input/amports/amports_priv.h" @@ -49,8 +47,8 @@ #include "../utils/firmware.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include "../utils/config_parser.h" +#include "../../../common/chips/decoder_cpu_ver_info.h" #include <media/v4l2-mem2mem.h> -#include "../utils/vdec_feature.h" #define DRIVER_NAME "ammvdec_mpeg4" @@ -187,19 +185,14 @@ if (((debug_enable & debug_flag) && ((1 << index) & mpeg4_debug_mask)) || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); + unsigned char buf[512]; int len = 0; va_list args; - - if (!buf) - return 0; - va_start(args, fmt); len = sprintf(buf, "%d: ", index); vsnprintf(buf + len, 512-len, fmt, args); pr_info("%s", buf); va_end(args); - kfree(buf); } return 0; } @@ -216,7 +209,6 @@ ulong v4l_ref_buf_addr; u32 hw_decode_time; u32 frame_size; // For frame base mode; - u64 timestamp; u32 offset; u32 height; u32 width; @@ -329,8 +321,6 @@ int sidebind_type; int sidebind_channel_id; u32 res_ch_flag; - u32 profile_idc; - u32 level_idc; unsigned int i_decoded_frames; unsigned int i_lost_frames; unsigned int i_concealed_frames; @@ -340,13 +330,13 @@ unsigned int b_decoded_frames; unsigned int b_lost_frames; unsigned int b_concealed_frames; + u32 profile_idc; + u32 level_idc; int vdec_pg_enable_flag; - ulong fb_token; char vdec_name[32]; char pts_name[32]; char new_q_name[32]; char disp_q_name[32]; - bool run_flag; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -381,6 +371,7 @@ static void reset_process_time(struct vdec_mpeg4_hw_s *hw); + static int vmpeg4_get_buf_num(struct vdec_mpeg4_hw_s *hw) { int buf_num = DECODE_BUFFER_NUM_DEF; @@ -404,16 +395,10 @@ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - if (hw->pic[i].v4l_ref_buf_addr) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *) - hw->pic[i].v4l_ref_buf_addr; - - fb->status = FB_ST_DECODER; + if (hw->pic[i].v4l_ref_buf_addr) return 0; - } - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] get fb fail.\n", @@ -422,8 +407,6 @@ return ret; } - fb->status = FB_ST_DECODER; - if (!hw->frame_width || !hw->frame_height) { struct vdec_pic_info pic; vdec_v4l_get_pic_info(ctx, &pic); @@ -454,8 +437,8 @@ fb->m.mem[1].bytes_used = decbuf_uv_size; } - mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n", - ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, __func__, fb); + mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%px\n", + ctx->id, __func__, fb); if (vdec->parallel_dec == 1) { u32 tmp; @@ -484,11 +467,8 @@ hw->canvas_config[i][0].endian = 7; else hw->canvas_config[i][0].endian = 0; - config_cav_lut(canvas_y(canvas), - &hw->canvas_config[i][0], VDEC_1); - /* mpeg4 decoder canvas need to be revert to match display canvas */ - hw->canvas_config[i][0].endian = - (hw->blkmode != CANVAS_BLKMODE_LINEAR) ? 7 : 0; + canvas_config_config(canvas_y(canvas), + &hw->canvas_config[i][0]); hw->canvas_config[i][1].phy_addr = decbuf_uv_start; @@ -499,11 +479,8 @@ hw->canvas_config[i][1].endian = 7; else hw->canvas_config[i][1].endian = 0; - config_cav_lut(canvas_u(canvas), - &hw->canvas_config[i][1], VDEC_1); - /* mpeg4 decoder canvas need to be revert to match display canvas */ - hw->canvas_config[i][1].endian = - (hw->blkmode != CANVAS_BLKMODE_LINEAR) ? 7 : 0; + canvas_config_config(canvas_u(canvas), + &hw->canvas_config[i][1]); return 0; } @@ -537,16 +514,14 @@ (struct aml_vcodec_ctx *)(hw->v4l2_ctx); if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { /*run to parser csd data*/ - i = 0xffffff; + i = 0; } else { - if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) - return -1; - if (vmpeg4_v4l_alloc_buff_config_canvas(hw, i)) return -1; } } + return i; } @@ -714,7 +689,6 @@ struct vframe_s *vf = NULL; struct vdec_s *vdec = hw_to_vdec(hw); struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; ulong nv_order = VIDTYPE_VIU_NV21; int index = pic->index; bool pb_skip = false; @@ -725,8 +699,6 @@ if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) nv_order = VIDTYPE_VIU_NV12; - if (vdec->prog_only) - pic->pic_info &= ~INTERLACE_FLAG; } if (hw->i_only) @@ -742,7 +714,6 @@ if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->pic[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, "[%d] %s(), v4l mem handle: 0x%lx\n", ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, @@ -757,7 +728,6 @@ vf->orientation = hw->vmpeg4_rotation; vf->pts = pic->pts; vf->pts_us64 = pic->pts64; - vf->timestamp = pic->timestamp; vf->duration = pic->duration >> 1; vf->duration_pulldown = 0; vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? @@ -771,6 +741,7 @@ mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, "field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); + if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) { vf->pts_us64 = (((u64)vf->duration << 32) & @@ -808,20 +779,11 @@ hw->b_decoded_frames++; } if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); } - if (kfifo_get(&hw->newframe_q, &vf) == 0) { mmpeg4_debug_print(DECODE_ID(hw), 0, "error, no available buf.\n"); @@ -829,6 +791,16 @@ return -1; } + if (hw->is_used_v4l) { + vf->v4l_mem_handle + = hw->pic[index].v4l_ref_buf_addr; + mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, + "[%d] %s(), v4l mem handle: 0x%lx\n", + ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, + __func__, vf->v4l_mem_handle); + } + + vf->index = pic->index; vf->width = pic->width; vf->height = pic->height; @@ -837,7 +809,6 @@ vf->orientation = hw->vmpeg4_rotation; vf->pts = 0; vf->pts_us64 = 0; - vf->timestamp = 0; vf->duration = pic->duration >> 1; vf->duration_pulldown = 0; vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ? @@ -856,6 +827,7 @@ vf->pts_us64 = (u64)-1; vf->pts = 0; } + if (((hw->first_i_frame_ready == 0) || pb_skip) && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; @@ -890,16 +862,8 @@ hw->b_decoded_frames++; } if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); } @@ -911,7 +875,6 @@ hw->dec_result = DEC_RESULT_ERROR; return -1; } - if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->pic[index].v4l_ref_buf_addr; @@ -929,7 +892,6 @@ vf->orientation = hw->vmpeg4_rotation; vf->pts = pic->pts; vf->pts_us64 = pic->pts64; - vf->timestamp = pic->timestamp; vf->duration = pic->duration; vf->duration_pulldown = pic->repeat_cnt * pic->duration; @@ -946,12 +908,14 @@ mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, "prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); + if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) { vf->pts_us64 = (((u64)vf->duration << 32) & 0xffffffff00000000) | pic->offset; vf->pts = 0; } + if (((hw->first_i_frame_ready == 0) || pb_skip) && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; @@ -992,16 +956,8 @@ vdec_fill_vdec_frame(vdec, NULL, &vinfo, vf, pic->hw_decode_time); if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vmpeg_vf_put(vmpeg_vf_get(vdec), vdec); } @@ -1027,7 +983,8 @@ /* reset VLD fifo for all vdec */ WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3)); WRITE_VREG(DOS_SW_RESET0, 0); - + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) + dummy = READ_RESET_REG(RESET0_REGISTER); WRITE_VREG(POWER_CTL_VLD, 1 << 4); /* @@ -1069,18 +1026,19 @@ } } -static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps) +static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace, struct aml_vdec_ps_infos *ps) { ps->visible_width = width; ps->visible_height = height; ps->coded_width = ALIGN(width, 64); ps->coded_height = ALIGN(height, 64); ps->dpb_size = hw->buf_num; + ps->field = interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; return 0; } -static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height) +static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); @@ -1099,7 +1057,7 @@ hw->frame_width, hw->frame_height, width, height); - vmpeg4_get_ps_info(hw, width, height, &ps); + vmpeg4_get_ps_info(hw, width, height, interlace, &ps); vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; @@ -1107,8 +1065,7 @@ ctx->v4l_resolution_change = 1; hw->eos = 1; flush_output(hw); - if (hw->is_used_v4l) - notify_v4l_eos(hw_to_vdec(hw)); + notify_v4l_eos(hw_to_vdec(hw)); ret = 1; } @@ -1130,6 +1087,7 @@ u32 repeat_cnt, duration = 3200; struct pic_info_t *dec_pic, *disp_pic; struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)(vdec->private); + if (hw->eos) return IRQ_HANDLED; @@ -1137,13 +1095,16 @@ if (hw->is_used_v4l) { int frame_width = READ_VREG(MP4_PIC_WH)>> 16; int frame_height = READ_VREG(MP4_PIC_WH) & 0xffff; - if (!v4l_res_change(hw, frame_width, frame_height)) { + int interlace = (READ_VREG(MP4_PIC_RATIO) & 0x80000000) >> 31; + mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL, + "interlace = %d\n", interlace); + if (!v4l_res_change(hw, frame_width, frame_height, interlace)) { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { struct aml_vdec_ps_infos ps; - vmpeg4_get_ps_info(hw, frame_width, frame_height, &ps); + vmpeg4_get_ps_info(hw, frame_width, frame_height, interlace, &ps); hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); reset_process_time(hw); @@ -1162,14 +1123,6 @@ return IRQ_HANDLED; } - if ((hw->is_used_v4l) && !hw->v4l_params_parsed) { - mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "The head was not found, can not to decode\n"); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); if (READ_VREG(AV_SCRATCH_M) != 0 && (debug_enable & PRINT_FLAG_UCODE_DETAIL)) { @@ -1267,7 +1220,6 @@ dec_pic->pts_valid = false; dec_pic->pts = 0; dec_pic->pts64 = 0; - dec_pic->timestamp = 0; mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL, "new pic: index=%d, used=%d, repeat=%d, time_inc=%d\n", index, hw->vfbuf_use[index], repeat_cnt, vop_time_inc); @@ -1282,7 +1234,6 @@ hw->frame_height = dec_h; dec_pic->height = dec_h; } - hw->res_ch_flag = 0; if (hw->vmpeg4_amstream_dec_info.rate == 0) { if (vop_time_inc < hw->last_vop_time_inc) { @@ -1327,7 +1278,6 @@ dec_pic->pts_valid = hw->chunk->pts_valid; dec_pic->pts = hw->chunk->pts; dec_pic->pts64 = hw->chunk->pts64; - dec_pic->timestamp = hw->chunk->timestamp; if ((B_PICTURE == picture_type) || (hw->last_dec_pts == dec_pic->pts)) dec_pic->pts_valid = 0; @@ -1340,7 +1290,6 @@ dec_pic->pts_valid = hw->chunk->pts_valid; dec_pic->pts = hw->chunk->pts; dec_pic->pts64 = hw->chunk->pts64; - dec_pic->timestamp = hw->chunk->timestamp; } else { dec_pic->offset = offset; if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { @@ -1368,11 +1317,10 @@ dec_pic->duration = duration; hw->vfbuf_use[index] = 0; mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "mmpeg4: pic_num: %d, index %d, type %c, pts %x\n", + "mmpeg4: pic_num: %d, index %d, type %c, pts %x, pts64 %lld, height %d, width %d\n", hw->frame_num, index, GET_PIC_TYPE(picture_type), - dec_pic->pts); - + dec_pic->pts, dec_pic->pts64, dec_pic->height, dec_pic->width); /* buffer management */ if ((picture_type == I_PICTURE) || (picture_type == P_PICTURE)) { @@ -1492,17 +1440,15 @@ if (!disp_pic->pts_valid) { disp_pic->pts = 0; disp_pic->pts64 = 0; - disp_pic->timestamp = 0; } } mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, - "disp: pic_type %c, pts %d(%lld), diff %d, cnt %d, disp_pic->timestamp %llu\n", + "disp: pic_type %c, pts %d(%lld), diff %d, cnt %d\n", GET_PIC_TYPE(disp_pic->pic_type), disp_pic->pts, disp_pic->pts64, disp_pic->pts - hw->last_pts, - hw->chunk_frame_count, - disp_pic->timestamp); + hw->chunk_frame_count); hw->last_pts = disp_pic->pts; hw->last_pts64 = disp_pic->pts64; hw->frame_dur = duration; @@ -1597,12 +1543,10 @@ if (hw->is_used_v4l) { index = find_free_buffer(hw); - if ((index == -1) || (index == 0xffffff)) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { - pr_err("[%d] get fb fail.\n", ctx->id); - return -1; - } + if ((index == -1) && + vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) { + pr_err("[%d] get fb fail.\n", ctx->id); + return -1; } } @@ -1611,17 +1555,12 @@ vf->v4l_mem_handle = (index == -1) ? (ulong)fb : hw->pic[index].v4l_ref_buf_addr;; vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); ATRACE_COUNTER(hw->pts_name, vf->pts); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); pr_info("[%d] mpeg4 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } @@ -1648,7 +1587,7 @@ hw->ctx_valid = 1; } else if ((hw->dec_result == DEC_RESULT_DONE) || - ((!hw->is_used_v4l) && (input_frame_based(&vdec->input)) && hw->chunk)) { + ((input_frame_based(&vdec->input)) && hw->chunk)) { if (!hw->ctx_valid) hw->ctx_valid = 1; @@ -1683,7 +1622,6 @@ hw->chunk = NULL; vdec_clean_input(vdec); flush_output(hw); - notify_v4l_eos(vdec); mmpeg4_debug_print(DECODE_ID(hw), 0, @@ -1913,26 +1851,25 @@ ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i, decbuf_size, DRIVER_NAME, &decbuf_start); if (ret < 0) { - pr_err("bmmu alloc failed! size %d idx %d\n", + pr_err("mmu alloc failed! size %d idx %d\n", decbuf_size, i); return ret; } - } - - if (!vdec_secure(vdec)) { - /*init internal buf*/ - char *tmpbuf = (char *)codec_mm_phys_to_virt(decbuf_start); - if (tmpbuf) { - memset(tmpbuf, 0, decbuf_size); - codec_mm_dma_flush(tmpbuf, - decbuf_size, DMA_TO_DEVICE); - } else { - tmpbuf = codec_mm_vmap(decbuf_start, decbuf_size); + if (!vdec_secure(vdec)) { + /*init internal buf*/ + char *tmpbuf = (char *)codec_mm_phys_to_virt(decbuf_start); if (tmpbuf) { memset(tmpbuf, 0, decbuf_size); codec_mm_dma_flush(tmpbuf, decbuf_size, DMA_TO_DEVICE); - codec_mm_unmap_phyaddr(tmpbuf); + } else { + tmpbuf = codec_mm_vmap(decbuf_start, decbuf_size); + if (tmpbuf) { + memset(tmpbuf, 0, decbuf_size); + codec_mm_dma_flush(tmpbuf, + decbuf_size, DMA_TO_DEVICE); + codec_mm_unmap_phyaddr(tmpbuf); + } } } } @@ -1969,8 +1906,8 @@ hw->canvas_config[i][0].endian = 7; else hw->canvas_config[i][0].endian = 0; - config_cav_lut(canvas_y(canvas), - &hw->canvas_config[i][0], VDEC_1); + canvas_config_config(canvas_y(canvas), + &hw->canvas_config[i][0]); hw->canvas_config[i][1].phy_addr = decbuf_start + decbuf_y_size; @@ -1981,8 +1918,8 @@ hw->canvas_config[i][1].endian = 7; else hw->canvas_config[i][1].endian = 0; - config_cav_lut(canvas_u(canvas), - &hw->canvas_config[i][1], VDEC_1); + canvas_config_config(canvas_u(canvas), + &hw->canvas_config[i][1]); } } @@ -1997,13 +1934,12 @@ mmpeg4_debug_print(DECODE_ID(hw), 0, "====== %s\n", __func__); mmpeg4_debug_print(DECODE_ID(hw), 0, - "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d, run_flag %d\n", + "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d\n", hw->frame_width, hw->frame_height, hw->first_i_frame_ready, hw->buffer_not_ready, - hw->buf_num, - hw->run_flag + hw->buf_num ); for (i = 0; i < hw->buf_num; i++) { mmpeg4_debug_print(DECODE_ID(hw), 0, @@ -2028,7 +1964,7 @@ hw->drop_frame_count ); - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -2143,10 +2079,9 @@ } -static void check_timer_func(struct timer_list *timer) +static void check_timer_func(unsigned long arg) { - struct vdec_mpeg4_hw_s *hw = container_of(timer, - struct vdec_mpeg4_hw_s, check_timer); + struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)arg; struct vdec_s *vdec = hw_to_vdec(hw); unsigned int timeout_val = decode_timeout_val; @@ -2200,10 +2135,10 @@ } else { if (!hw->is_used_v4l) { for (i = 0; i < hw->buf_num; i++) { - config_cav_lut(canvas_y(hw->canvas_spec[i]), - &hw->canvas_config[i][0], VDEC_1); - config_cav_lut(canvas_u(hw->canvas_spec[i]), - &hw->canvas_config[i][1], VDEC_1); + canvas_config_config(canvas_y(hw->canvas_spec[i]), + &hw->canvas_config[i][0]); + canvas_config_config(canvas_u(hw->canvas_spec[i]), + &hw->canvas_config[i][1]); } } } @@ -2216,17 +2151,14 @@ WRITE_VREG(MREG_REF0, (hw->refs[1] == -1) ? 0xffffffff : hw->canvas_spec[hw->refs[1]]); } else { - WRITE_VREG(MREG_REF0, hw->canvas_spec[hw->refs[0]]); + WRITE_VREG(MREG_REF0, (hw->refs[0] == -1) ? 0xffffffff : + hw->canvas_spec[hw->refs[0]]); } WRITE_VREG(MREG_REF1, (hw->refs[1] == -1) ? 0xffffffff : hw->canvas_spec[hw->refs[1]]); - if ((hw->is_used_v4l) && (index == 0xffffff)) { - WRITE_VREG(REC_CANVAS_ADDR, 0xffffff); - WRITE_VREG(ANC2_CANVAS_ADDR, 0xffffff); - } else { - WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]); - WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]); - } + + WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]); + WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]); mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE, "restore ref0=0x%x, ref1=0x%x, rec=0x%x, ctx_valid=%d,index=%d\n", @@ -2322,7 +2254,7 @@ hw->unstable_pts = (((unsigned long) hw->vmpeg4_amstream_dec_info.param & 0x40) >> 6); mmpeg4_debug_print(DECODE_ID(hw), 0, - "param = 0x%x unstable_pts = %d\n", + "param = 0x%px unstable_pts = %d\n", hw->vmpeg4_amstream_dec_info.param, hw->unstable_pts); hw->last_dec_pts = -1; @@ -2422,10 +2354,9 @@ //amvdec_enable(); - timer_setup(&hw->check_timer, check_timer_func, 0); - //init_timer(&hw->check_timer); - //hw->check_timer.data = (unsigned long)hw; - //hw->check_timer.function = check_timer_func; + init_timer(&hw->check_timer); + hw->check_timer.data = (unsigned long)hw; + hw->check_timer.function = check_timer_func; hw->check_timer.expires = jiffies + CHECK_INTERVAL; hw->stat |= STAT_TIMER_ARM; hw->eos = 0; @@ -2440,6 +2371,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; + if (hw->eos) return 0; if (vdec_stream_based(vdec) && (hw->init_flag == 0) @@ -2519,8 +2451,6 @@ { struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; int size = 0, ret = 0; - - hw->run_flag = 1; if (!hw->vdec_pg_enable_flag) { hw->vdec_pg_enable_flag = 1; amvdec_enable(); @@ -2540,7 +2470,6 @@ hw->input_empty++; hw->dec_result = DEC_RESULT_AGAIN; vdec_schedule_work(&hw->work); - hw->run_flag = 0; return; } if ((vdec_frame_based(vdec)) && @@ -2567,10 +2496,10 @@ if (!hw->chunk->block->is_mapped) data = codec_mm_vmap(hw->chunk->block->start + - hw->chunk_offset, size); + hw->chunk->offset, size); else data = ((u8 *)hw->chunk->block->start_virt) + - hw->chunk_offset; + hw->chunk->offset; mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", @@ -2625,7 +2554,6 @@ hw->fw->name, 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; @@ -2635,7 +2563,7 @@ hw->dec_result = DEC_RESULT_ERROR; mmpeg4_debug_print(DECODE_ID(hw), 0, "amvdec_mpeg4: error HW context restore\n"); - hw->run_flag = 0; + vdec_schedule_work(&hw->work); return; } if (vdec_frame_based(vdec)) { @@ -2656,10 +2584,8 @@ vdec->mvfrm->hw_decode_start = local_clock(); amvdec_start(); hw->stat |= STAT_VDEC_RUN; - hw->stat |= STAT_TIMER_ARM; hw->init_flag = 1; mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); - hw->run_flag = 0; } static int vmpeg4_stop(struct vdec_mpeg4_hw_s *hw) @@ -2667,12 +2593,8 @@ cancel_work_sync(&hw->work); if (hw->mm_blk_handle) { - void *bmmu_box_tmp = hw->mm_blk_handle; - hw->mm_blk_handle = NULL; - while (hw->run_flag) - usleep_range(1000, 2000); - decoder_bmmu_box_free(bmmu_box_tmp); - bmmu_box_tmp = NULL; + decoder_bmmu_box_free(hw->mm_blk_handle); + hw->mm_blk_handle = NULL; } if (hw->stat & STAT_TIMER_ARM) { @@ -2694,12 +2616,6 @@ vmpeg4_local_init(hw); - if (hw->is_used_v4l) { - u32 i, buf_num = vmpeg4_get_buf_num(hw); - for (i = 0; i < buf_num; i++) { - hw->pic[i].v4l_ref_buf_addr = 0; - } - } hw->ctx_valid = 0; } @@ -2771,24 +2687,15 @@ platform_set_drvdata(pdev, pdata); hw->platform_dev = pdev; - if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { - mmpeg4_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config); - if (get_config_int(pdata->config, "parm_v4l_buffer_margin", - &config_val) == 0) - hw->dynamic_buf_num_margin = config_val; - else - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } else { - hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - } - hw->buf_num = vmpeg4_get_buf_num(hw); - if (pdata->parallel_dec == 1) { int i; for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) hw->canvas_spec[i] = 0xffffff; } + vf_provider_init(&pdata->vframe_provider, + pdata->vf_provider_name, &vf_provider_ops, pdata); + hw->blkmode = pdata->canvas_mode; if (pdata->sys_info) { @@ -2810,6 +2717,7 @@ hw->vmpeg4_amstream_dec_info.height, hw->vmpeg4_amstream_dec_info.rate); } + if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) { mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, "pdata->config: %s\n", pdata->config); @@ -2839,10 +2747,6 @@ } else hw->dynamic_buf_num_margin = dynamic_buf_num_margin; - if (!hw->is_used_v4l) - vf_provider_init(&pdata->vframe_provider, - pdata->vf_provider_name, &vf_provider_ops, pdata); - hw->buf_num = vmpeg4_get_buf_num(hw); if (vmmpeg4_init(hw) < 0) { @@ -2913,22 +2817,38 @@ } /****************************************/ +#ifdef CONFIG_PM +static int mmpeg4_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int mmpeg4_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops mmpeg4_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmpeg4_suspend, mmpeg4_resume) +}; +#endif static struct platform_driver ammvdec_mpeg4_driver = { .probe = ammvdec_mpeg4_probe, .remove = ammvdec_mpeg4_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &mmpeg4_pm_ops, +#endif } }; static struct codec_profile_t amvdec_mpeg4_profile = { .name = "mmpeg4", - .profile = "v4l, no_single" + .profile = "" }; static int __init ammvdec_mpeg4_driver_init_module(void) @@ -2940,7 +2860,6 @@ return -ENODEV; } vcodec_profile_register(&amvdec_mpeg4_profile); - vcodec_feature_register(VFORMAT_MPEG4, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/real/Makefile b/drivers/frame_provider/decoder/real/Makefile new file mode 100644 index 0000000..ab03ef2 --- /dev/null +++ b/drivers/frame_provider/decoder/real/Makefile
@@ -0,0 +1,2 @@ +obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_REAL) += amvdec_real.o +amvdec_real-objs += vreal.o
diff --git a/drivers/frame_provider/decoder/real/vreal.c b/drivers/frame_provider/decoder/real/vreal.c new file mode 100644 index 0000000..f6474b6 --- /dev/null +++ b/drivers/frame_provider/decoder/real/vreal.c
@@ -0,0 +1,1069 @@ +/* + * drivers/amlogic/amports/vreal.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/types.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/timer.h> +#include <linux/fs.h> +#include <linux/kfifo.h> +#include <linux/platform_device.h> + +#include <linux/amlogic/media/canvas/canvas.h> + +#include <linux/dma-mapping.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/vfm/vframe.h> +#include <linux/amlogic/media/vfm/vframe_provider.h> +#include <linux/amlogic/media/vfm/vframe_receiver.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/uaccess.h> +#include "../../../stream_input/amports/amports_priv.h" +#include "../utils/vdec.h" +#include <linux/amlogic/media/utils/vdec_reg.h> +#include "../utils/amvdec.h" + +#include "../../../stream_input/amports/streambuf.h" +#include "../../../stream_input/amports/streambuf_reg.h" +#include "../../../stream_input/parser/rmparser.h" + +#include "vreal.h" +#include <linux/amlogic/media/registers/register.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 <linux/amlogic/tee.h> + + + +#define DRIVER_NAME "amvdec_real" +#define MODULE_NAME "amvdec_real" + +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ +#define NV21 +#endif + +#define RM_DEF_BUFFER_ADDR 0x01000000 +/* protocol registers */ +#define STATUS_AMRISC AV_SCRATCH_4 + +#define RV_PIC_INFO AV_SCRATCH_5 +#define VPTS_TR AV_SCRATCH_6 +#define VDTS AV_SCRATCH_7 +#define FROM_AMRISC AV_SCRATCH_8 +#define TO_AMRISC AV_SCRATCH_9 +#define SKIP_B_AMRISC AV_SCRATCH_A +#define INT_REASON AV_SCRATCH_B +#define WAIT_BUFFER AV_SCRATCH_E + +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ +#define MDEC_WIDTH AV_SCRATCH_I +#define MDEC_HEIGHT AV_SCRATCH_J +#else +#define MDEC_WIDTH HARM_ASB_MB2 +#define MDEC_HEIGHT HASB_ARM_MB0 +#endif + +#define PARC_FORBIDDEN 0 +#define PARC_SQUARE 1 +#define PARC_CIF 2 +#define PARC_10_11 3 +#define PARC_16_11 4 +#define PARC_40_33 5 +#define PARC_RESERVED 6 +/* values between 6 and 14 are reserved */ +#define PARC_EXTENDED 15 + +#define VF_POOL_SIZE 16 +#define VF_BUF_NUM 4 +#define PUT_INTERVAL (HZ/100) +#define WORKSPACE_SIZE (1 * SZ_1M) +#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM + 1) +#define RV_AI_BUFF_START_IP 0x01f00000 + +static struct vframe_s *vreal_vf_peek(void *); +static struct vframe_s *vreal_vf_get(void *); +static void vreal_vf_put(struct vframe_s *, void *); +static int vreal_vf_states(struct vframe_states *states, void *); +static int vreal_event_cb(int type, void *data, void *private_data); + +static int vreal_prot_init(void); +static void vreal_local_init(void); + +static const char vreal_dec_id[] = "vreal-dev"; + +#define PROVIDER_NAME "decoder.real" + +/* + *int query_video_status(int type, int *value); + */ +static const struct vframe_operations_s vreal_vf_provider = { + .peek = vreal_vf_peek, + .get = vreal_vf_get, + .put = vreal_vf_put, + .event_cb = vreal_event_cb, + .vf_states = vreal_vf_states, +}; + +static struct vframe_provider_s vreal_vf_prov; +static void *mm_blk_handle; + +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 struct vframe_s vfpool[VF_POOL_SIZE]; +static s32 vfbuf_use[VF_BUF_NUM]; + +static u32 frame_width, frame_height, frame_dur, frame_prog; +static u32 saved_resolution; +static struct timer_list recycle_timer; +static u32 stat; +static u32 buf_size = 32 * 1024 * 1024; +static u32 buf_offset; +static u32 vreal_ratio; +u32 vreal_format; +static u32 wait_key_frame; +static u32 last_tr; +static u32 frame_count; +static u32 current_vdts; +static u32 hold; +static u32 decoder_state; +static u32 real_err_count; + +static u32 fatal_flag; +static s32 wait_buffer_counter; +static struct work_struct set_clk_work; +static bool is_reset; + +static DEFINE_SPINLOCK(lock); + +static unsigned short pic_sz_tbl[12] ____cacheline_aligned; +static dma_addr_t pic_sz_tbl_map; +static const unsigned char RPR_size[9] = { 0, 1, 1, 2, 2, 3, 3, 3, 3 }; + +static struct dec_sysinfo vreal_amstream_dec_info; + +static unsigned char aspect_ratio_table[16] = { + PARC_FORBIDDEN, + PARC_SQUARE, + PARC_CIF, + PARC_10_11, + PARC_16_11, + PARC_40_33, + PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, + PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, + PARC_RESERVED, PARC_EXTENDED +}; + +static inline u32 index2canvas(u32 index) +{ + const u32 canvas_tab[4] = { +#ifdef NV21 + 0x010100, 0x030302, 0x050504, 0x070706 +#else + 0x020100, 0x050403, 0x080706, 0x0b0a09 +#endif + }; + + return canvas_tab[index]; +} + +static void set_aspect_ratio(struct vframe_s *vf, unsigned int pixel_ratio) +{ + int ar = 0; + + if (vreal_ratio == 0) { + vf->ratio_control |= (0x90 << + DISP_RATIO_ASPECT_RATIO_BIT); + /* always stretch to 16:9 */ + } else { + switch (aspect_ratio_table[pixel_ratio]) { + case 0: + ar = vreal_amstream_dec_info.height * vreal_ratio / + vreal_amstream_dec_info.width; + break; + case 1: + case 0xff: + ar = vreal_ratio * vf->height / vf->width; + break; + case 2: + ar = (vreal_ratio * vf->height * 12) / (vf->width * 11); + break; + case 3: + ar = (vreal_ratio * vf->height * 11) / (vf->width * 10); + break; + case 4: + ar = (vreal_ratio * vf->height * 11) / (vf->width * 16); + break; + case 5: + ar = (vreal_ratio * vf->height * 33) / (vf->width * 40); + break; + default: + ar = vreal_ratio * vf->height / vf->width; + break; + } + } + + ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX); + + vf->ratio_control |= (ar << DISP_RATIO_ASPECT_RATIO_BIT); +} + +static irqreturn_t vreal_isr(int irq, void *dev_id) +{ + u32 from; + struct vframe_s *vf = NULL; + u32 buffer_index; + unsigned int status; + unsigned int vdts; + unsigned int info; + unsigned int tr; + unsigned int pictype; + u32 r = READ_VREG(INT_REASON); + + if (decoder_state == 0) + return IRQ_HANDLED; + + status = READ_VREG(STATUS_AMRISC); + if (status & (PARSER_ERROR_WRONG_PACKAGE_SIZE | + PARSER_ERROR_WRONG_HEAD_VER | + DECODER_ERROR_VLC_DECODE_TBL)) { + /* decoder or parser error */ + real_err_count++; + /* pr_info("real decoder or parser + *error, status 0x%x\n", status); + */ + } + + if (r == 2) { + pr_info("first vpts = 0x%x\n", READ_VREG(VDTS)); + pts_checkin_offset(PTS_TYPE_AUDIO, 0, READ_VREG(VDTS) * 90); + WRITE_VREG(AV_SCRATCH_B, 0); + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + return IRQ_HANDLED; + } else if (r == 3) { + pr_info("first apts = 0x%x\n", READ_VREG(VDTS)); + pts_checkin_offset(PTS_TYPE_VIDEO, 0, READ_VREG(VDTS) * 90); + WRITE_VREG(AV_SCRATCH_B, 0); + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + return IRQ_HANDLED; + } + + from = READ_VREG(FROM_AMRISC); + if ((hold == 0) && from) { + tr = READ_VREG(VPTS_TR); + pictype = (tr >> 13) & 3; + tr = (tr & 0x1fff) * 96; + + if (kfifo_get(&newframe_q, &vf) == 0) { + pr_info("fatal error, no available buffer slot."); + return IRQ_HANDLED; + } + + vdts = READ_VREG(VDTS); + if (last_tr == -1) /* ignore tr for first time */ + vf->duration = frame_dur; + else { + if (tr > last_tr) + vf->duration = tr - last_tr; + else + vf->duration = (96 << 13) + tr - last_tr; + + if (vf->duration > 10 * frame_dur) { + /* not a reasonable duration, + *should not happen + */ + vf->duration = frame_dur; + } +#if 0 + else { + if (check_frame_duration == 0) { + frame_dur = vf->duration; + check_frame_duration = 1; + } + } +#endif + } + + last_tr = tr; + buffer_index = from & 0x03; + + if (pictype == 0) { /* I */ + current_vdts = vdts * 90 + 1; + vf->pts = current_vdts; + if (wait_key_frame) + wait_key_frame = 0; + } else { + if (wait_key_frame) { + while (READ_VREG(TO_AMRISC)) + ; + WRITE_VREG(TO_AMRISC, ~(1 << buffer_index)); + WRITE_VREG(FROM_AMRISC, 0); + return IRQ_HANDLED; + } else { + current_vdts += + vf->duration - (vf->duration >> 4); + vf->pts = current_vdts; + } + } + + /* pr_info("pts %d, picture type %d\n", vf->pts, pictype); */ + + info = READ_VREG(RV_PIC_INFO); + vf->signal_type = 0; + vf->index = buffer_index; + vf->width = info >> 16; + vf->height = (info >> 4) & 0xfff; + vf->bufWidth = 1920; + vf->flag = 0; + vf->ratio_control = 0; + set_aspect_ratio(vf, info & 0x0f); + vf->duration_pulldown = 0; +#ifdef NV21 + vf->type = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21; +#else + vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; +#endif + vf->canvas0Addr = vf->canvas1Addr = index2canvas(buffer_index); + vf->orientation = 0; + vf->type_original = vf->type; + + vfbuf_use[buffer_index] = 1; + 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); + + frame_count++; + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + WRITE_VREG(FROM_AMRISC, 0); + } + + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + + return IRQ_HANDLED; +} + +static struct vframe_s *vreal_vf_peek(void *op_arg) +{ + struct vframe_s *vf; + + if (kfifo_peek(&display_q, &vf)) + return vf; + + return NULL; +} + +static struct vframe_s *vreal_vf_get(void *op_arg) +{ + struct vframe_s *vf; + + if (kfifo_get(&display_q, &vf)) + return vf; + + return NULL; +} + +static void vreal_vf_put(struct vframe_s *vf, void *op_arg) +{ + kfifo_put(&recycle_q, (const struct vframe_s *)vf); +} + +static int vreal_event_cb(int type, void *data, void *private_data) +{ + if (type & VFRAME_EVENT_RECEIVER_RESET) { + unsigned long flags; + + amvdec_stop(); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_light_unreg_provider(&vreal_vf_prov); +#endif + spin_lock_irqsave(&lock, flags); + vreal_local_init(); + vreal_prot_init(); + spin_unlock_irqrestore(&lock, flags); +#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_reg_provider(&vreal_vf_prov); +#endif + amvdec_start(); + } + return 0; +} + +static int vreal_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; +} +#if 0 +#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER +static void vreal_ppmgr_reset(void) +{ + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); + + vreal_local_init(); + + pr_info("vrealdec: vf_ppmgr_reset\n"); +} +#endif +#endif + +static void vreal_set_clk(struct work_struct *work) +{ + if (frame_dur > 0 && + saved_resolution != + frame_width * frame_height * (96000 / frame_dur)) { + int fps = 96000 / frame_dur; + + saved_resolution = frame_width * frame_height * fps; + vdec_source_changed(VFORMAT_REAL, + frame_width, frame_height, fps); + } +} + +static void vreal_put_timer_func(unsigned long arg) +{ + struct timer_list *timer = (struct timer_list *)arg; + /* unsigned int status; */ + +#if 0 + enum receviver_start_e state = RECEIVER_INACTIVE; + + if (vf_get_receiver(PROVIDER_NAME)) { + state = + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_QUREY_STATE, NULL); + if ((state == RECEIVER_STATE_NULL) + || (state == RECEIVER_STATE_NONE)) { + /* receiver has no event_cb + *or receiver's event_cb does not process this event + */ + state = RECEIVER_INACTIVE; + } + } else + state = RECEIVER_INACTIVE; + + if ((READ_VREG(WAIT_BUFFER) != 0) && + kfifo_is_empty(&display_q) && + kfifo_is_empty(&recycle_q) && (state == RECEIVER_INACTIVE)) { + pr_info("$$$$$$decoder is waiting for buffer\n"); + if (++wait_buffer_counter > 2) { + amvdec_stop(); + +#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vreal_ppmgr_reset(); +#else + vf_light_unreg_provider(&vreal_vf_prov); + vreal_local_init(); + vf_reg_provider(&vreal_vf_prov); +#endif + vreal_prot_init(); + amvdec_start(); + } + } +#endif + + while (!kfifo_is_empty(&recycle_q) && (READ_VREG(TO_AMRISC) == 0)) { + struct vframe_s *vf; + + if (kfifo_get(&recycle_q, &vf)) { + if ((vf->index < VF_BUF_NUM) + && (--vfbuf_use[vf->index] == 0)) { + WRITE_VREG(TO_AMRISC, ~(1 << vf->index)); + vf->index = VF_BUF_NUM; + } + + kfifo_put(&newframe_q, (const struct vframe_s *)vf); + } + } + + schedule_work(&set_clk_work); + + timer->expires = jiffies + PUT_INTERVAL; + + add_timer(timer); +} + +int vreal_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) +{ + if (!(stat & STAT_VDEC_RUN)) + return -1; + + vstatus->frame_width = vreal_amstream_dec_info.width; + vstatus->frame_height = vreal_amstream_dec_info.height; + if (0 != vreal_amstream_dec_info.rate) + vstatus->frame_rate = 96000 / vreal_amstream_dec_info.rate; + else + vstatus->frame_rate = 96000; + vstatus->error_count = real_err_count; + vstatus->status = + ((READ_VREG(STATUS_AMRISC) << 16) | fatal_flag) | stat; + /* pr_info("vreal_dec_status 0x%x\n", vstatus->status); */ + return 0; +} + +int vreal_set_isreset(struct vdec_s *vdec, int isreset) +{ + is_reset = isreset; + return 0; +} + +/****************************************/ +static int vreal_canvas_init(void) +{ + int i, ret; + unsigned long buf_start; + u32 canvas_width, canvas_height; + u32 alloc_size, decbuf_size, decbuf_y_size, decbuf_uv_size; + + 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 */ + #if 1 + int w = vreal_amstream_dec_info.width; + int h = vreal_amstream_dec_info.height; + int align_w, align_h; + int max, min; + + align_w = ALIGN(w, 64); + align_h = ALIGN(h, 64); + if (align_w > align_h) { + max = align_w; + min = align_h; + } else { + canvas_width = 1920; + canvas_height = 1088; + max = align_h; + min = align_w; + } + /* HD & SD */ + if ((max > 1920 || min > 1088) && + ALIGN(align_w * align_h * 3/2, SZ_64K) * 9 <= + buf_size) { + canvas_width = align_w; + canvas_height = align_h; + decbuf_y_size = ALIGN(align_w * align_h, SZ_64K); + decbuf_uv_size = ALIGN(align_w * align_h/4, SZ_64K); + decbuf_size = ALIGN(align_w * align_h * 3/2, SZ_64K); + } else { /*1080p*/ + if (h > w) { + canvas_width = 1088; + canvas_height = 1920; + } else { + canvas_width = 1920; + canvas_height = 1088; + } + decbuf_y_size = 0x200000; + decbuf_uv_size = 0x80000; + decbuf_size = 0x300000; + } + #endif + } + + for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) { + /* workspace mem */ + if (i == (MAX_BMMU_BUFFER_NUM - 1)) + alloc_size = WORKSPACE_SIZE; + else + alloc_size = decbuf_size; + + ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, i, + alloc_size, DRIVER_NAME, &buf_start); + if (ret < 0) + return ret; + + if (i == (MAX_BMMU_BUFFER_NUM - 1)) { + buf_offset = buf_start - RV_AI_BUFF_START_IP; + continue; + } + +#ifdef NV21 + canvas_config(2 * i + 0, + buf_start, + canvas_width, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(2 * i + 1, + buf_start + + decbuf_y_size, canvas_width, + canvas_height / 2, CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_32X32); +#else + canvas_config(3 * i + 0, + buf_start, + canvas_width, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(3 * i + 1, + buf_start + + decbuf_y_size, canvas_width / 2, + canvas_height / 2, CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_32X32); + canvas_config(3 * i + 2, + buf_start + + decbuf_y_size + decbuf_uv_size, + canvas_width / 2, canvas_height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); +#endif + } + + return 0; +} + +static int vreal_prot_init(void) +{ + int r; +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ + WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6)); + WRITE_VREG(DOS_SW_RESET0, 0); +#else + WRITE_RESET_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC); +#endif + + + + r = vreal_canvas_init(); + + /* index v << 16 | u << 8 | y */ +#ifdef NV21 + WRITE_VREG(AV_SCRATCH_0, 0x010100); + WRITE_VREG(AV_SCRATCH_1, 0x030302); + WRITE_VREG(AV_SCRATCH_2, 0x050504); + WRITE_VREG(AV_SCRATCH_3, 0x070706); +#else + 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); + +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ + WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); + WRITE_VREG(DOS_SW_RESET0, 0); +#else + WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); +#endif + + /* disable PSCALE for hardware sharing */ + WRITE_VREG(PSCALE_CTRL, 0); + + WRITE_VREG(FROM_AMRISC, 0); + WRITE_VREG(TO_AMRISC, 0); + WRITE_VREG(STATUS_AMRISC, 0); + + WRITE_VREG(RV_PIC_INFO, 0); + WRITE_VREG(VPTS_TR, 0); + WRITE_VREG(VDTS, 0); + WRITE_VREG(SKIP_B_AMRISC, 0); + + WRITE_VREG(MDEC_WIDTH, (frame_width + 15) & 0xfff0); + WRITE_VREG(MDEC_HEIGHT, (frame_height + 15) & 0xfff0); + + /* clear mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); + + /* enable mailbox interrupt */ + WRITE_VREG(ASSIST_MBOX1_MASK, 1); + + /* clear wait buffer status */ + WRITE_VREG(WAIT_BUFFER, 0); + +#ifdef NV21 + SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); +#endif + return r; +} + +static void vreal_local_init(void) +{ + int i; + + /* vreal_ratio = vreal_amstream_dec_info.ratio; */ + vreal_ratio = 0x100; + + frame_prog = 0; + + frame_width = vreal_amstream_dec_info.width; + frame_height = vreal_amstream_dec_info.height; + frame_dur = vreal_amstream_dec_info.rate; + + for (i = 0; i < VF_BUF_NUM; i++) + vfbuf_use[i] = 0; + + 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; + kfifo_put(&newframe_q, vf); + } + + 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); + + decoder_state = 1; + hold = 0; + last_tr = -1; + wait_key_frame = 1; + frame_count = 0; + current_vdts = 0; + real_err_count = 0; + + pic_sz_tbl_map = 0; + saved_resolution = 0; + fatal_flag = 0; + wait_buffer_counter = 0; +} + +static void load_block_data(void *dest, unsigned int count) +{ + unsigned short *pdest = (unsigned short *)dest; + unsigned short src_tbl[12]; + unsigned int i; + + src_tbl[0] = RPR_size[vreal_amstream_dec_info.extra + 1]; + memcpy((void *)&src_tbl[1], vreal_amstream_dec_info.param, + 2 << src_tbl[0]); + +#if 0 + for (i = 0; i < 12; i++) + pr_info("src_tbl[%d]: 0x%x\n", i, src_tbl[i]); +#endif + + for (i = 0; i < count / 4; i++) { + pdest[i * 4] = src_tbl[i * 4 + 3]; + pdest[i * 4 + 1] = src_tbl[i * 4 + 2]; + pdest[i * 4 + 2] = src_tbl[i * 4 + 1]; + pdest[i * 4 + 3] = src_tbl[i * 4]; + } + + pic_sz_tbl_map = dma_map_single(amports_get_dma_device(), &pic_sz_tbl, + sizeof(pic_sz_tbl), DMA_TO_DEVICE); + +} + +s32 vreal_init(struct vdec_s *vdec) +{ + int ret = -1, size = -1; + char fw_name[32] = {0}; + char *buf = vmalloc(0x1000 * 16); + + if (IS_ERR_OR_NULL(buf)) + return -ENOMEM; + + pr_info("vreal_init\n"); + + init_timer(&recycle_timer); + + stat |= STAT_TIMER_INIT; + + amvdec_enable(); + + vreal_local_init(); + + ret = rmparser_init(vdec); + if (ret) { + amvdec_disable(); + vfree(buf); + pr_info("rm parser init failed\n"); + return ret; + } + + if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_8) { + if (vreal_amstream_dec_info.param == NULL) { + rmparser_release(); + amvdec_disable(); + vfree(buf); + return -1; + } + load_block_data((void *)pic_sz_tbl, 12); + + /* TODO: need to load the table into lmem */ + WRITE_VREG(LMEM_DMA_ADR, (unsigned int)pic_sz_tbl_map); + WRITE_VREG(LMEM_DMA_COUNT, 10); + WRITE_VREG(LMEM_DMA_CTRL, 0xc178 | (3 << 11)); + while (READ_VREG(LMEM_DMA_CTRL) & 0x8000) + ; + size = get_firmware_data(VIDEO_DEC_REAL_V8, buf); + strncpy(fw_name, "vreal_mc_8", sizeof(fw_name)); + + pr_info("load VIDEO_DEC_FORMAT_REAL_8\n"); + } else if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_9) { + size = get_firmware_data(VIDEO_DEC_REAL_V9, buf); + strncpy(fw_name, "vreal_mc_9", sizeof(fw_name)); + + pr_info("load VIDEO_DEC_FORMAT_REAL_9\n"); + } else + pr_info("unsurpported real format\n"); + + if (size < 0) { + rmparser_release(); + amvdec_disable(); + pr_err("get firmware fail."); + vfree(buf); + return -1; + } + + ret = amvdec_loadmc_ex(VFORMAT_REAL, fw_name, buf); + if (ret < 0) { + rmparser_release(); + amvdec_disable(); + vfree(buf); + pr_err("%s: the %s fw loading failed, err: %x\n", + fw_name, tee_enabled() ? "TEE" : "local", ret); + return -EBUSY; + } + + vfree(buf); + + stat |= STAT_MC_LOAD; + + /* enable AMRISC side protocol */ + ret = vreal_prot_init(); + if (ret < 0) { + rmparser_release(); + amvdec_disable(); + return ret; + } + if (vdec_request_irq(VDEC_IRQ_1, vreal_isr, + "vreal-irq", (void *)vreal_dec_id)) { + rmparser_release(); + amvdec_disable(); + + pr_info("vreal irq register error.\n"); + return -ENOENT; + } + + stat |= STAT_ISR_REG; +#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER + vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider, + NULL); + vf_reg_provider(&vreal_vf_prov); + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); +#else + vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider, + NULL); + vf_reg_provider(&vreal_vf_prov); +#endif + + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, + (void *)((unsigned long)vreal_amstream_dec_info.rate)); + + stat |= STAT_VF_HOOK; + + recycle_timer.data = (ulong)&recycle_timer; + recycle_timer.function = vreal_put_timer_func; + recycle_timer.expires = jiffies + PUT_INTERVAL; + + add_timer(&recycle_timer); + + stat |= STAT_TIMER_ARM; + + amvdec_start(); + + stat |= STAT_VDEC_RUN; + + pr_info("vreal init finished\n"); + + return 0; +} + +void vreal_set_fatal_flag(int flag) +{ + if (flag) + fatal_flag = PARSER_FATAL_ERROR; +} + +static int amvdec_real_probe(struct platform_device *pdev) +{ + struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; + + if (pdata == NULL) { + pr_info("amvdec_real memory resource undefined.\n"); + return -EFAULT; + } + if (pdata->sys_info) + vreal_amstream_dec_info = *pdata->sys_info; + + pdata->dec_status = vreal_dec_status; + pdata->set_isreset = vreal_set_isreset; + is_reset = 0; + + INIT_WORK(&set_clk_work, vreal_set_clk); + if (vreal_init(pdata) < 0) { + pr_info("amvdec_real init failed.\n"); + pdata->dec_status = NULL; + return -ENODEV; + } + return 0; +} + +static int amvdec_real_remove(struct platform_device *pdev) +{ + cancel_work_sync(&set_clk_work); + if (stat & STAT_VDEC_RUN) { + amvdec_stop(); + stat &= ~STAT_VDEC_RUN; + } + + if (stat & STAT_ISR_REG) { + vdec_free_irq(VDEC_IRQ_1, (void *)vreal_dec_id); + stat &= ~STAT_ISR_REG; + } + + if (stat & STAT_TIMER_ARM) { + del_timer_sync(&recycle_timer); + stat &= ~STAT_TIMER_ARM; + } + + if (stat & STAT_VF_HOOK) { + if (!is_reset) + vf_notify_receiver(PROVIDER_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); + + vf_unreg_provider(&vreal_vf_prov); + stat &= ~STAT_VF_HOOK; + } + + if (pic_sz_tbl_map != 0) { + dma_unmap_single(NULL, pic_sz_tbl_map, sizeof(pic_sz_tbl), + DMA_TO_DEVICE); + } + + rmparser_release(); + + vdec_source_changed(VFORMAT_REAL, 0, 0, 0); + + amvdec_disable(); + + if (mm_blk_handle) { + decoder_bmmu_box_free(mm_blk_handle); + mm_blk_handle = NULL; + } + pr_info("frame duration %d, frames %d\n", frame_dur, frame_count); + return 0; +} + +/****************************************/ +#ifdef CONFIG_PM +static int real_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int real_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops real_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(real_suspend, real_resume) +}; +#endif + +static struct platform_driver amvdec_real_driver = { + .probe = amvdec_real_probe, + .remove = amvdec_real_remove, + .driver = { + .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &real_pm_ops, +#endif + } +}; + +static struct codec_profile_t amvdec_real_profile = { + .name = "real", + .profile = "rmvb,1080p+" +}; +static struct mconfig real_configs[] = { + MC_PU32("stat", &stat), +}; +static struct mconfig_node real_node; + +static int __init amvdec_real_driver_init_module(void) +{ + pr_debug("amvdec_real module init\n"); + + if (platform_driver_register(&amvdec_real_driver)) { + pr_err("failed to register amvdec_real driver\n"); + return -ENODEV; + } + vcodec_profile_register(&amvdec_real_profile); + INIT_REG_NODE_CONFIGS("media.decoder", &real_node, + "real", real_configs, CONFIG_FOR_R); + return 0; +} + +static void __exit amvdec_real_driver_remove_module(void) +{ + pr_debug("amvdec_real module remove.\n"); + + platform_driver_unregister(&amvdec_real_driver); +} + +/****************************************/ + +module_init(amvdec_real_driver_init_module); +module_exit(amvdec_real_driver_remove_module); + +MODULE_DESCRIPTION("AMLOGIC REAL Video Decoder Driver"); +MODULE_LICENSE("GPL");
diff --git a/drivers/frame_provider/decoder_v4l/vp9/vvp9.h b/drivers/frame_provider/decoder/real/vreal.h similarity index 71% rename from drivers/frame_provider/decoder_v4l/vp9/vvp9.h rename to drivers/frame_provider/decoder/real/vreal.h index 1db9d09..734cc6f 100644 --- a/drivers/frame_provider/decoder_v4l/vp9/vvp9.h +++ b/drivers/frame_provider/decoder/real/vreal.h
@@ -1,5 +1,5 @@ /* - * drivers/amlogic/amports/vvp9.h + * drivers/amlogic/amports/vreal.h * * Copyright (C) 2015 Amlogic, Inc. All rights reserved. * @@ -15,9 +15,12 @@ * */ -#ifndef VVP9_H -#define VVP9_H +#ifndef VREAL_H +#define VREAL_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); +#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ +/* TODO: move to register headers */ +#define VPP_VD1_POSTBLEND (1 << 10) #endif + +#endif /* VREAL_H */
diff --git a/drivers/frame_provider/decoder/utils/Makefile b/drivers/frame_provider/decoder/utils/Makefile index 6f8540b..1e7552b 100644 --- a/drivers/frame_provider/decoder/utils/Makefile +++ b/drivers/frame_provider/decoder/utils/Makefile
@@ -1,13 +1,10 @@ obj-m += decoder_common.o decoder_common-objs += utils.o vdec.o vdec_input.o amvdec.o decoder_common-objs += decoder_mmu_box.o decoder_bmmu_box.o -decoder_common-objs += config_parser.o vdec_profile.o +decoder_common-objs += config_parser.o secprot.o vdec_profile.o decoder_common-objs += amstream_profile.o decoder_common-objs += frame_check.o amlogic_fbc_hook.o decoder_common-objs += vdec_v4l2_buffer_ops.o decoder_common-objs += vdec_sync.o decoder_common-objs += vdec_power_ctrl.o -decoder_common-objs += vdec_canvas_utils.o -decoder_common-objs += vdec_feature.o -decoder_common-objs += vdec_ge2d_utils.o
diff --git a/drivers/frame_provider/decoder/utils/amstream_profile.c b/drivers/frame_provider/decoder/utils/amstream_profile.c index 0e2b9c8..c8033ce 100644 --- a/drivers/frame_provider/decoder/utils/amstream_profile.c +++ b/drivers/frame_provider/decoder/utils/amstream_profile.c
@@ -66,3 +66,5 @@ return ret; } EXPORT_SYMBOL(is_support_profile); + +
diff --git a/drivers/frame_provider/decoder/utils/amvdec.c b/drivers/frame_provider/decoder/utils/amvdec.c index d525fe8..af36ef1 100644 --- a/drivers/frame_provider/decoder/utils/amvdec.c +++ b/drivers/frame_provider/decoder/utils/amvdec.c
@@ -43,8 +43,7 @@ #include "amvdec.h" #include <linux/amlogic/media/utils/amports_config.h> #include "firmware.h" -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> #include "../../../common/chips/decoder_cpu_ver_info.h" #define MC_SIZE (4096 * 16) @@ -485,16 +484,9 @@ } else format = VIDEO_DEC_H264; break; - case VFORMAT_JPEG_ENC: - format = VIDEO_ENC_JPEG; - vdec = OPTEE_VDEC_HCDEC; - break; - case VFORMAT_H264_ENC: - format = VIDEO_ENC_H264; - vdec = OPTEE_VDEC_HCDEC; - break; + default: - pr_info("Unknow vdec format: %u\n", (u32)type); + pr_info("Unknow vdec format!\n"); break; } @@ -683,17 +675,13 @@ WRITE_VREG(HEVC_IMEM_DMA_ADR, mc_addr_map); WRITE_VREG(HEVC_IMEM_DMA_COUNT, 0x1000); - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) - WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (0xf << 16))); - else - WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (0x7 << 16))); + WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); while (READ_VREG(HEVC_IMEM_DMA_CTRL) & 0x8000) { if (time_before(jiffies, timeout)) schedule(); else { - pr_err("hevc load mc error\n"); + pr_err("vdec2 load mc error\n"); ret = -EBUSY; break; } @@ -978,14 +966,6 @@ #ifdef CONFIG_PM int amvdec_suspend(struct platform_device *dev, pm_message_t event) { - struct vdec_s *vdec = *(struct vdec_s **)dev->dev.platform_data;; - - if (vdec) { - wait_event_interruptible_timeout(vdec->idle_wait, - (vdec->status != VDEC_STATUS_ACTIVE), - msecs_to_jiffies(100)); - } - amvdec_pg_enable(false); /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ @@ -1020,14 +1000,6 @@ int amhevc_suspend(struct platform_device *dev, pm_message_t event) { - struct vdec_s *vdec = *(struct vdec_s **)dev->dev.platform_data;; - - if (vdec) { - wait_event_interruptible_timeout(vdec->idle_wait, - (vdec->status != VDEC_STATUS_ACTIVE), - msecs_to_jiffies(100)); - } - if (has_hevc_vdec()) { amhevc_pg_enable(false); /*vdec_set_suspend_clk(1, 1);*//*DEBUG_TMP*/ @@ -1189,8 +1161,9 @@ module_init(amvdec_init); module_exit(amvdec_exit); -#endif + MODULE_DESCRIPTION("Amlogic Video Decoder Utility Driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); +#endif
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c index 33a9e4b..461621b 100644 --- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c +++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
@@ -141,7 +141,7 @@ int memflags = mem_flags; if (!box || idx < 0 || idx >= box->max_mm_num) { - pr_err("can't alloc bmmu box(%p),idx:%d\n", + pr_err("can't alloc mmu box(%p),idx:%d\n", box, idx); return -1; } @@ -324,7 +324,7 @@ } /*flags: &0x1 for wait,*/ -int decoder_bmmu_box_check_and_wait_size(int size, int flags, int mem_flags) +int decoder_bmmu_box_check_and_wait_size(int size, int flags) { if ((flags & BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER) && codec_mm_get_free_size() < size) { @@ -335,7 +335,7 @@ } return codec_mm_enough_for_size(size, - flags & BMMU_ALLOC_FLAGS_WAIT, mem_flags); + flags & BMMU_ALLOC_FLAGS_WAIT); } int decoder_bmmu_box_alloc_idx_wait( @@ -361,8 +361,7 @@ } have_space = decoder_bmmu_box_check_and_wait_size( size, - wait_flags, - mem_flags); + wait_flags); if (have_space) { ret = decoder_bmmu_box_alloc_idx(handle, idx, size, aligned_2n, mem_flags); @@ -383,14 +382,9 @@ int size, unsigned char *driver_name, unsigned long *buf_phy_addr) { - struct decoder_bmmu_box *bmmu_box = (struct decoder_bmmu_box *)handle; - - if (bmmu_box == NULL) - return -EINVAL; - if (!decoder_bmmu_box_check_and_wait_size( size, - 1, bmmu_box->mem_flags)) { + 1)) { pr_info("%s not enough buf for buf_idx = %d\n", driver_name, idx); return -ENOMEM; @@ -400,8 +394,9 @@ idx, size, -1, - bmmu_box->mem_flags, - BMMU_ALLOC_FLAGS_WAITCLEAR)) { + -1, + BMMU_ALLOC_FLAGS_WAITCLEAR + )) { *buf_phy_addr = decoder_bmmu_box_get_phy_addr( handle, @@ -419,25 +414,6 @@ } EXPORT_SYMBOL(decoder_bmmu_box_alloc_buf_phy); -int decoder_bmmu_box_add_callback_func( - void *handle, int idx, - void *cb) -{ - struct decoder_bmmu_box *box = handle; - struct codec_mm_s *mm; - - if (!box || idx < 0 || idx >= box->max_mm_num) - return 0; - - mutex_lock(&box->mutex); - mm = box->mm_list[idx]; - codec_mm_add_release_callback(mm, (struct codec_mm_cb_s *)cb); - mutex_unlock(&box->mutex); - - return 0; -} -EXPORT_SYMBOL(decoder_bmmu_box_add_callback_func); - static int decoder_bmmu_box_dump(struct decoder_bmmu_box *box, void *buf, int size) { @@ -446,7 +422,6 @@ int tsize = 0; int s; int i; - if (!buf) { pbuf = sbuf; size = 512; @@ -491,7 +466,6 @@ int s; int i; struct list_head *head, *list; - if (!buf) { pbuf = sbuf; size = 512; @@ -549,7 +523,7 @@ return ret; } -static ssize_t debug_show(struct class *class, +static ssize_t box_debug_show(struct class *class, struct class_attribute *attr, char *buf) { @@ -563,7 +537,8 @@ return size; } -static ssize_t debug_store(struct class *class, + +static ssize_t box_debug_store(struct class *class, struct class_attribute *attr, const char *buf, size_t size) { @@ -584,21 +559,19 @@ } -static CLASS_ATTR_RO(box_dump); -static CLASS_ATTR_RW(debug); -static struct attribute *decoder_bmmu_box_class_attrs[] = { - &class_attr_box_dump.attr, - &class_attr_debug.attr, - NULL + +static struct class_attribute decoder_bmmu_box_class_attrs[] = { + __ATTR_RO(box_dump), + __ATTR(debug, S_IRUGO | S_IWUSR | S_IWGRP, + box_debug_show, box_debug_store), + __ATTR_NULL }; -ATTRIBUTE_GROUPS(decoder_bmmu_box_class); - static struct class decoder_bmmu_box_class = { - .name = "decoder_bmmu_box", - .class_groups = decoder_bmmu_box_class_groups, -}; + .name = "decoder_bmmu_box", + .class_attrs = decoder_bmmu_box_class_attrs, + }; int decoder_bmmu_box_init(void) {
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h index 93974ec..778cb8e 100644 --- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h +++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
@@ -41,17 +41,13 @@ /*flags: &0x1 for wait,*/ int decoder_bmmu_box_check_and_wait_size( - int size, int flags, int mem_flags); + int size, int flags); int decoder_bmmu_box_alloc_buf_phy( void *handle, int idx, int size, unsigned char *driver_name, unsigned long *buf_phy_addr); -int decoder_bmmu_box_add_callback_func( - void *handle, int idx, - void *cb); - #define BMMU_ALLOC_FLAGS_WAIT (1 << 0) #define BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER (1 << 1) #define BMMU_ALLOC_FLAGS_WAITCLEAR \
diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c b/drivers/frame_provider/decoder/utils/decoder_mmu_box.c index 57180dd..75862ec 100644 --- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c +++ b/drivers/frame_provider/decoder/utils/decoder_mmu_box.c
@@ -28,11 +28,13 @@ #include <linux/slab.h> #include <linux/amlogic/media/codec_mm/codec_mm_scatter.h> #include <linux/platform_device.h> + struct decoder_mmu_box { int max_sc_num; const char *name; int channel_id; int tvp_mode; + int box_ref_cnt; struct mutex mutex; struct list_head list; struct codec_mm_scatter *sc_list[1]; @@ -74,6 +76,51 @@ return 0; } +bool decoder_mmu_box_valide_check(void *box) +{ + struct decoder_mmu_box_mgr *mgr = get_decoder_mmu_box_mgr(); + struct decoder_mmu_box *mmu_box = NULL; + bool is_valide = false; + + mutex_lock(&mgr->mutex); + list_for_each_entry(mmu_box, &mgr->box_list, list) { + if (mmu_box && mmu_box == box) { + is_valide = true; + break; + } + } + mutex_unlock(&mgr->mutex); + + return is_valide; +} +EXPORT_SYMBOL(decoder_mmu_box_valide_check); + +void decoder_mmu_try_to_release_box(void *handle) +{ + struct decoder_mmu_box *box = handle; + bool is_keep = false; + int i; + + if (!box || box->box_ref_cnt) + return; + + mutex_lock(&box->mutex); + for (i = 0; i < box->max_sc_num; i++) { + if (box->sc_list[i]) { + is_keep = true; + break; + } + } + mutex_unlock(&box->mutex); + + if (!is_keep) { + decoder_mmu_box_mgr_del_box(box); + codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode); + kfree(box); + } +} +EXPORT_SYMBOL(decoder_mmu_try_to_release_box); + int decoder_mmu_box_sc_check(void *handle, int is_tvp) { struct decoder_mmu_box *box = handle; @@ -115,7 +162,7 @@ mutex_init(&box->mutex); INIT_LIST_HEAD(&box->list); decoder_mmu_box_mgr_add_box(box); - codec_mm_scatter_mgt_delay_free_switch(1, 2000, + codec_mm_scatter_mgt_delay_free_swith(1, 2000, min_size_M, box->tvp_mode); return (void *)box; } @@ -142,6 +189,7 @@ ret = codec_mm_scatter_alloc_want_pages(sc, num_pages); else { + box->box_ref_cnt--; codec_mm_scatter_dec_owner_user(sc, 0); box->sc_list[idx] = NULL; sc = NULL; @@ -158,6 +206,7 @@ return -1; } box->sc_list[idx] = sc; + box->box_ref_cnt++; } for (i = 0; i < num_pages; i++) @@ -203,16 +252,18 @@ box ? (box->max_sc_num - 1) : 0); return -1; } - mutex_lock(&box->mutex); sc = box->sc_list[idx]; if (sc && sc->page_cnt > 0) { codec_mm_scatter_dec_owner_user(sc, 0); box->sc_list[idx] = NULL; + box->box_ref_cnt--; } - mutex_unlock(&box->mutex); + if (sc && box->box_ref_cnt == 0) + codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode); + return 0; } EXPORT_SYMBOL(decoder_mmu_box_free_idx); @@ -227,24 +278,18 @@ pr_err("can't free box of NULL box!\n"); return -1; } - mutex_lock(&box->mutex); for (i = 0; i < box->max_sc_num; i++) { sc = box->sc_list[i]; if (sc) { codec_mm_scatter_dec_owner_user(sc, 0); box->sc_list[i] = NULL; - } } - - codec_mm_scatter_mgt_delay_free_switch(0, 0, 0, box->tvp_mode); - mutex_unlock(&box->mutex); - decoder_mmu_box_mgr_del_box(box); + codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode); kfree(box); - return 0; } EXPORT_SYMBOL(decoder_mmu_box_free); @@ -366,18 +411,16 @@ return ret; } -static CLASS_ATTR_RO(box_dump); -static struct attribute *decoder_mmu_box_class_attrs[] = { - &class_attr_box_dump.attr, - NULL + +static struct class_attribute decoder_mmu_box_class_attrs[] = { + __ATTR_RO(box_dump), + __ATTR_NULL }; -ATTRIBUTE_GROUPS(decoder_mmu_box_class); - static struct class decoder_mmu_box_class = { .name = "decoder_mmu_box", - .class_groups = decoder_mmu_box_class_groups, + .class_attrs = decoder_mmu_box_class_attrs, }; int decoder_mmu_box_init(void)
diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h b/drivers/frame_provider/decoder/utils/decoder_mmu_box.h index 13b3dd9..029f91a 100644 --- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h +++ b/drivers/frame_provider/decoder/utils/decoder_mmu_box.h
@@ -40,13 +40,11 @@ int decoder_mmu_box_move_keep_idx(void *box_handle, int keep_idx); int decoder_mmu_box_free_keep(int keep_id); - int decoder_mmu_box_free_all_keep(void); - void *decoder_mmu_box_get_mem_handle(void *box_handle, int idx); - +bool decoder_mmu_box_valide_check(void *box); +void decoder_mmu_try_to_release_box(void *handle); int decoder_mmu_box_init(void); - void decoder_mmu_box_exit(void); #endif
diff --git a/drivers/frame_provider/decoder/utils/firmware.h b/drivers/frame_provider/decoder/utils/firmware.h index cd48036..c799fd0 100644 --- a/drivers/frame_provider/decoder/utils/firmware.h +++ b/drivers/frame_provider/decoder/utils/firmware.h
@@ -22,9 +22,6 @@ #include "../../../common/firmware/firmware_type.h" #include <linux/amlogic/media/utils/vformat.h> -#if defined(CONFIG_AMLOGIC_TEE) || defined(CONFIG_AMLOGIC_TEE_MODULE) -#include <linux/amlogic/tee.h> -#endif #define FW_LOAD_FORCE (0x1) #define FW_LOAD_TRY (0X2) @@ -41,16 +38,4 @@ extern int get_firmware_data(unsigned int foramt, char *buf); extern int video_fw_reload(int mode); -#if !defined(CONFIG_AMLOGIC_TEE) && !defined(CONFIG_AMLOGIC_TEE_MODULE) -static inline bool tee_enabled(void) { return false; } -static inline int tee_load_video_fw_swap(u32 index, u32 vdec, bool is_swap) -{ - return -1; -} -static inline int tee_load_video_fw(u32 index, u32 vdec) -{ - return -1; -} -#endif - #endif
diff --git a/drivers/frame_provider/decoder/utils/frame_check.c b/drivers/frame_provider/decoder/utils/frame_check.c index 0600f8e..4cd80c0 100644 --- a/drivers/frame_provider/decoder/utils/frame_check.c +++ b/drivers/frame_provider/decoder/utils/frame_check.c
@@ -25,8 +25,9 @@ #include <linux/timer.h> #include <linux/kfifo.h> #include <linux/kthread.h> -#include <linux/vmalloc.h> #include <linux/platform_device.h> +#include <linux/amlogic/media/canvas/canvas.h> +#include <linux/amlogic/media/canvas/canvas_mgr.h> #include <linux/amlogic/media/vfm/vframe.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/dma-mapping.h> @@ -71,7 +72,7 @@ #define dbg_print(mask, ...) do { \ if ((fc_debug & mask) || \ (mask == FC_ERROR)) \ - printk("[FRAME_CHECK] "__VA_ARGS__);\ + printk("[FRMAE_CHECK] "__VA_ARGS__);\ } while(0) @@ -166,18 +167,6 @@ return false; } -unsigned long vdec_cav_get_addr(int index); -unsigned int vdec_cav_get_width(int index); -unsigned int vdec_cav_get_height(int index); -#define canvas_0(v) ((v) & 0xff) -#define canvas_1(v) (((v) >> 8) & 0xff) -#define canvas_2(v) (((v) >> 16) & 0xff) -#define canvas_3(v) (((v) >> 24) & 0xff) - -#define canvasY(v) canvas_0(v) -#define canvasU(v) canvas_1(v) -#define canvasV(v) canvas_2(v) -#define canvasUV(v) canvas_1(v) static int get_frame_size(struct pic_check_mgr_t *pic, struct vframe_s *vf) @@ -199,10 +188,10 @@ if ((vf->canvas0Addr == vf->canvas1Addr) && (vf->canvas0Addr != 0) && (vf->canvas0Addr != -1)) { - pic->canvas_w = vdec_cav_get_width(canvasY(vf->canvas0Addr)); - //canvas_get_width(canvasY(vf->canvas0Addr)); - pic->canvas_h = vdec_cav_get_height(canvasY(vf->canvas0Addr)); - //canvas_get_height(canvasY(vf->canvas0Addr)); + pic->canvas_w = + canvas_get_width(canvasY(vf->canvas0Addr)); + pic->canvas_h = + canvas_get_height(canvasY(vf->canvas0Addr)); } else { pic->canvas_w = vf->canvas0_config[0].width; pic->canvas_h = vf->canvas0_config[0].height; @@ -232,8 +221,8 @@ if ((vf->canvas0Addr == vf->canvas1Addr) && (vf->canvas0Addr != 0) && (vf->canvas0Addr != -1)) { - phy_y_addr = vdec_cav_get_addr(canvasY(vf->canvas0Addr)); //canvas_get_addr(canvasY(vf->canvas0Addr)); - phy_uv_addr = vdec_cav_get_addr(canvasUV(vf->canvas0Addr)); //canvas_get_addr(canvasUV(vf->canvas0Addr)); + phy_y_addr = canvas_get_addr(canvasY(vf->canvas0Addr)); + phy_uv_addr = canvas_get_addr(canvasU(vf->canvas0Addr)); } else { phy_y_addr = vf->canvas0_config[0].phy_addr; phy_uv_addr = vf->canvas0_config[1].phy_addr; @@ -437,14 +426,10 @@ static int write_crc_work(struct pic_check_mgr_t *mgr) { unsigned int wr_size; - char *crc_buf, *crc_tmp = NULL; + char *crc_buf, crc_tmp[64*30]; mm_segment_t old_fs; struct pic_check_t *check = &mgr->pic_check; - crc_tmp = (char *)vzalloc(64 * 30); - if (!crc_tmp) - return -1; - if (mgr->enable & CRC_MASK) { wr_size = 0; while (kfifo_get(&check->wr_chk_q, &crc_buf) != 0) { @@ -468,11 +453,10 @@ set_fs(old_fs); } } - - vfree(crc_tmp); return 0; } + static int write_aux_data_crc_work(struct aux_data_check_mgr_t *mgr) { unsigned int wr_size; @@ -506,6 +490,8 @@ return 0; } + + static void do_check_work(struct work_struct *work) { struct pic_check_mgr_t *mgr = container_of(work, @@ -1123,10 +1109,6 @@ single_mode_vdec = NULL; } - if (!single_mode_vdec && - unlikely(in_interrupt())) - return 0; - if ((mgr == NULL) || (vf == NULL) || (mgr->enable == 0)) return 0; @@ -1149,8 +1131,7 @@ resize = 0; mgr->last_size_pic = mgr->size_pic; - if ((vf->type & VIDTYPE_VIU_NV21) || (mgr->mjpeg_flag) || - (vf->type & VIDTYPE_VIU_NV12)) { + if ((vf->type & VIDTYPE_VIU_NV21) || (mgr->mjpeg_flag)) { int flush_size; if (canvas_get_virt_addr(mgr, vf) < 0)
diff --git a/drivers/frame_provider/decoder/utils/secprot.c b/drivers/frame_provider/decoder/utils/secprot.c new file mode 100644 index 0000000..a1e7fa7 --- /dev/null +++ b/drivers/frame_provider/decoder/utils/secprot.c
@@ -0,0 +1,75 @@ +/* + * drivers/amlogic/amports/arch/secprot.c + * + * 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. + * +*/ + +#include <linux/kernel.h> +#include <asm/compiler.h> +#include "secprot.h" +#ifndef CONFIG_ARM64 +#include <asm/opcodes-sec.h> +#endif + +#ifdef CONFIG_ARM64 + +int tee_config_device_secure(int dev_id, int secure) +{ + int ret = 0; + register unsigned x0 asm("x0"); + register unsigned x1 asm("x1"); + register unsigned x2 asm("x2"); + + x0 = OPTEE_SMC_CONFIG_DEVICE_SECURE; + x1 = dev_id; + x2 = secure; + + asm volatile( + __asmeq("%0", "x0") + __asmeq("%1", "x0") + __asmeq("%2", "x1") + __asmeq("%3", "x2") + "smc #0\n" + : "=r"(x0) + : "r"(x0), "r"(x1), "r"(x2)); + ret = x0; + + return ret; +} +#else +int tee_config_device_secure(int dev_id, int secure) +{ + int ret = 0; + register unsigned int r0 asm("r0"); + register unsigned int r1 asm("r1"); + register unsigned int r2 asm("r2"); + + r0 = OPTEE_SMC_CONFIG_DEVICE_SECURE; + r1 = dev_id; + r2 = secure; + + asm volatile( + __asmeq("%0", "r0") + __asmeq("%1", "r0") + __asmeq("%2", "r1") + __asmeq("%3", "r2") + __SMC(0) + : "=r"(r0) + : "r"(r0), "r"(r1), "r"(r2)); + ret = r0; + + return ret; +} +#endif +
diff --git a/drivers/frame_provider/decoder/utils/secprot.h b/drivers/frame_provider/decoder/utils/secprot.h new file mode 100644 index 0000000..28ee477 --- /dev/null +++ b/drivers/frame_provider/decoder/utils/secprot.h
@@ -0,0 +1,39 @@ +/* + * drivers/amlogic/amports/arch/secprot.h + * + * 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. + * +*/ + +#ifndef __SECPROT_H_ +#define __SECPROT_H_ + +#define DMC_DEV_TYPE_NON_SECURE 0 +#define DMC_DEV_TYPE_SECURE 1 + +#define DMC_DEV_ID_GPU 1 +#define DMC_DEV_ID_HEVC 4 +#define DMC_DEV_ID_PARSER 7 +#define DMC_DEV_ID_VPU 8 +#define DMC_DEV_ID_VDEC 13 +#define DMC_DEV_ID_HCODEC 14 +#define DMC_DEV_ID_GE2D 15 + +#define OPTEE_SMC_CONFIG_DEVICE_SECURE 0xb200000e + +/*#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"*/ + +extern int tee_config_device_secure(int dev_id, int secure); + +#endif /* __SECPROT_H_ */ +
diff --git a/drivers/frame_provider/decoder/utils/utils.c b/drivers/frame_provider/decoder/utils/utils.c index 0372a18..44b1626 100644 --- a/drivers/frame_provider/decoder/utils/utils.c +++ b/drivers/frame_provider/decoder/utils/utils.c
@@ -69,6 +69,5 @@ module_init(decoder_common_init); module_exit(decoder_common_exit); - MODULE_DESCRIPTION("AMLOGIC decoder_common driver"); -MODULE_LICENSE("GPL"); \ No newline at end of file +MODULE_LICENSE("GPL");
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index 98f0e3c..69ec60c 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c
@@ -37,11 +37,9 @@ #include <linux/amlogic/media/video_sink/v4lvideo_ext.h> #endif #include <linux/amlogic/media/vfm/vfm_ext.h> -#include <linux/sched/clock.h> -#include <uapi/linux/sched/types.h> -#include <linux/signal.h> /*for VDEC_DEBUG_SUPPORT*/ #include <linux/time.h> + #include <linux/amlogic/media/utils/vdec_reg.h> #include "../../../stream_input/amports/streambuf.h" #include "vdec.h" @@ -49,7 +47,6 @@ #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC #include "vdec_profile.h" #endif -#include <linux/sched/clock.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/libfdt_env.h> @@ -68,27 +65,21 @@ #include "../../../common/media_clock/clk/clk.h" #include <linux/reset.h> -#include <linux/amlogic/media/registers/cpu_version.h> +#include <linux/amlogic/cpu_version.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/amlogic/media/video_sink/video_keeper.h> #include <linux/amlogic/media/codec_mm/configs.h> #include <linux/amlogic/media/frame_sync/ptsserv.h> +#include "secprot.h" #include "../../../common/chips/decoder_cpu_ver_info.h" #include "frame_check.h" -#include <linux/amlogic/tee.h> -#include "vdec_canvas_utils.h" -#include "../../../amvdec_ports/aml_vcodec_drv.h" - #ifdef CONFIG_AMLOGIC_POWER #include <linux/amlogic/power_ctrl.h> #endif -#ifdef CONFIG_AMLOGIC_IONVIDEO -#include <linux/amlogic/media/video_sink/ionvideo_ext.h> -#endif -//#include <dt-bindings/power/sc2-pd.h> -//#include <linux/amlogic/pwr_ctrl.h> +#include <dt-bindings/power/sc2-pd.h> +#include <linux/amlogic/pwr_ctrl.h> #include <linux/of_device.h> #include "vdec_power_ctrl.h" @@ -105,12 +96,10 @@ static unsigned int debug_trace_num = 16 * 20; static int step_mode; static unsigned int clk_config; -/* -0x1 : enable rdma -0x2 : check rdma result -*/ -static int rdma_mode = 0x1; - +#ifdef VDEC_FCC_SUPPORT +static int fcc_debug; +static void vdec_fcc_jump_back(struct vdec_s *vdec); +#endif /* * 0x1 : sched_priority to MAX_RT_PRIO -1. * 0x2 : always reload firmware. @@ -122,36 +111,23 @@ #define VDEC_DBG_CANVAS_STATUS (0x4) #define VDEC_DBG_ENABLE_FENCE (0x100) +#define FRAME_BASE_PATH_DI_V4LVIDEO_0 (29) +#define FRAME_BASE_PATH_DI_V4LVIDEO_1 (30) +#define FRAME_BASE_PATH_DI_V4LVIDEO_2 (31) -#define HEVC_RDMA_F_CTRL 0x30f0 -#define HEVC_RDMA_F_START_ADDR 0x30f1 -#define HEVC_RDMA_F_END_ADDR 0x30f2 -#define HEVC_RDMA_F_STATUS0 0x30f3 - -#define HEVC_RDMA_B_CTRL 0x30f8 -#define HEVC_RDMA_B_START_ADDR 0x30f9 -#define HEVC_RDMA_B_END_ADDR 0x30fa -#define HEVC_RDMA_B_STATUS0 0x30fb - - -static u32 debug = VDEC_DBG_ALWAYS_LOAD_FW; - -u32 vdec_get_debug(void) -{ - return debug; -} -EXPORT_SYMBOL(vdec_get_debug); - +u32 debug = VDEC_DBG_ALWAYS_LOAD_FW; +EXPORT_SYMBOL(debug); int hevc_max_reset_count; EXPORT_SYMBOL(hevc_max_reset_count); int no_powerdown; EXPORT_SYMBOL(no_powerdown); + static int parallel_decode = 1; static int fps_detection; static int fps_clear; -static bool prog_only; + static int force_nosecure_even_drm; static int disable_switch_single_to_mult; @@ -167,12 +143,8 @@ #define RESET7_REGISTER_LEVEL 0x1127 #define P_RESETCTRL_RESET5_LEVEL 0x15 -#define str(a) #a -#define xstr(a) str(a) - static int frameinfo_flag = 0; static int v4lvideo_add_di = 1; -static int v4lvideo_add_ppmgr = 0; static int max_di_instance = 2; static int max_supported_di_instance = 4; @@ -181,39 +153,12 @@ static int enable_mvdec_info = 1; int decode_underflow = 0; -u32 debug_meta; static int enable_stream_mode_multi_dec; -st_userdata userdata; +#define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1) -typedef void (*vdec_frame_rate_event_func)(int); - -#if 1 extern void vframe_rate_uevent(int duration); -vdec_frame_rate_event_func frame_rate_notify = vframe_rate_uevent; -#else -vdec_frame_rate_event_func frame_rate_notify = NULL; -#endif - -void vdec_frame_rate_uevent(int dur) -{ - if (frame_rate_notify == NULL) - return; - - if (unlikely(in_interrupt())) - return; - pr_info("vdec_frame_rate_uevent %d\n", dur); - frame_rate_notify(dur); -} -EXPORT_SYMBOL(vdec_frame_rate_uevent); - - -void register_frame_rate_uevent_func(vdec_frame_rate_event_func func) -{ - frame_rate_notify = func; -} -EXPORT_SYMBOL(register_frame_rate_uevent_func); struct am_reg { char *name; @@ -266,9 +211,15 @@ unsigned long stream_buff_flag; struct power_manager_s *pm; u32 vdec_resouce_status; - struct post_task_mgr_s post; }; +struct canvas_status_s { + int type; + int canvas_used_flag; + int id; +}; + + static struct vdec_core_s *vdec_core; static const char * const vdec_status_string[] = { @@ -278,7 +229,6 @@ "VDEC_STATUS_ACTIVE" }; /* -bit [29] enable steam mode dv multi; bit [28] enable print bit [23:16] etc bit [15:12] @@ -336,6 +286,9 @@ "reserved", }; +static struct canvas_status_s canvas_stat[AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1]; + + int vdec_get_debug_flags(void) { return debugflags; @@ -349,6 +302,15 @@ } EXPORT_SYMBOL(VDEC_PRINT_FUN_LINENO); +bool is_support_no_parser(void) +{ + if ((enable_stream_mode_multi_dec) || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) + return true; + return false; +} +EXPORT_SYMBOL(is_support_no_parser); + unsigned char is_mult_inc(unsigned int type) { unsigned char ret = 0; @@ -361,16 +323,6 @@ } EXPORT_SYMBOL(is_mult_inc); -bool is_support_no_parser(void) -{ - if ((enable_stream_mode_multi_dec) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_SC2) || - (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)) - return true; - return false; -} -EXPORT_SYMBOL(is_support_no_parser); - static const bool cores_with_input[VDEC_MAX] = { true, /* VDEC_1 */ false, /* VDEC_HCODEC */ @@ -387,17 +339,17 @@ VDEC_IRQ_HEVC_BACK }; -unsigned long vdec_canvas_lock(void) +unsigned long vdec_canvas_lock(struct vdec_core_s *core) { unsigned long flags; - spin_lock_irqsave(&vdec_core->canvas_lock, flags); + spin_lock_irqsave(&core->canvas_lock, flags); return flags; } -void vdec_canvas_unlock(unsigned long flags) +void vdec_canvas_unlock(struct vdec_core_s *core, unsigned long flags) { - spin_unlock_irqrestore(&vdec_core->canvas_lock, flags); + spin_unlock_irqrestore(&core->canvas_lock, flags); } unsigned long vdec_fps_lock(struct vdec_core_s *core) @@ -463,9 +415,14 @@ up(&core->sem); } + static u64 vdec_get_us_time_system(void) { - return div64_u64(local_clock(), 1000); + struct timeval tv; + + do_gettimeofday(&tv); + + return div64_u64(timeval_to_ns(&tv), 1000); } static void vdec_fps_clear(int id) @@ -526,6 +483,130 @@ vdec_fps_unlock(vdec_core, flags); } + + +static int get_canvas(unsigned int index, unsigned int base) +{ + int start; + int canvas_index = index * base; + int ret; + + if ((base > 4) || (base == 0)) + return -1; + + if ((AMVDEC_CANVAS_START_INDEX + canvas_index + base - 1) + <= AMVDEC_CANVAS_MAX1) { + start = AMVDEC_CANVAS_START_INDEX + base * index; + } else { + canvas_index -= (AMVDEC_CANVAS_MAX1 - + AMVDEC_CANVAS_START_INDEX + 1) / base * base; + if (canvas_index <= AMVDEC_CANVAS_MAX2) + start = canvas_index / base; + else + return -1; + } + + if (base == 1) { + ret = start; + } else if (base == 2) { + ret = ((start + 1) << 16) | ((start + 1) << 8) | start; + } else if (base == 3) { + ret = ((start + 2) << 16) | ((start + 1) << 8) | start; + } else if (base == 4) { + ret = (((start + 3) << 24) | (start + 2) << 16) | + ((start + 1) << 8) | start; + } + + return ret; +} + +static int get_canvas_ex(int type, int id) +{ + int i; + unsigned long flags; + + flags = vdec_canvas_lock(vdec_core); + + for (i = 0; i < CANVAS_MAX_SIZE; i++) { + if ((canvas_stat[i].type == type) && + (canvas_stat[i].id & (1 << id)) == 0) { + canvas_stat[i].canvas_used_flag++; + canvas_stat[i].id |= (1 << id); + if (debug & 4) + pr_debug("get used canvas %d\n", i); + vdec_canvas_unlock(vdec_core, flags); + if (i < AMVDEC_CANVAS_MAX2 + 1) + return i; + else + return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1); + } + } + + for (i = 0; i < CANVAS_MAX_SIZE; i++) { + if (canvas_stat[i].type == 0) { + canvas_stat[i].type = type; + canvas_stat[i].canvas_used_flag = 1; + canvas_stat[i].id = (1 << id); + if (debug & 4) { + pr_debug("get canvas %d\n", i); + pr_debug("canvas_used_flag %d\n", + canvas_stat[i].canvas_used_flag); + pr_debug("canvas_stat[i].id %d\n", + canvas_stat[i].id); + } + vdec_canvas_unlock(vdec_core, flags); + if (i < AMVDEC_CANVAS_MAX2 + 1) + return i; + else + return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1); + } + } + vdec_canvas_unlock(vdec_core, flags); + + pr_info("cannot get canvas\n"); + + return -1; +} + +static void free_canvas_ex(int index, int id) +{ + unsigned long flags; + int offset; + + flags = vdec_canvas_lock(vdec_core); + if (index >= 0 && + index < AMVDEC_CANVAS_MAX2 + 1) + offset = index; + else if ((index >= AMVDEC_CANVAS_START_INDEX) && + (index <= AMVDEC_CANVAS_MAX1)) + offset = index + AMVDEC_CANVAS_MAX2 + 1 - AMVDEC_CANVAS_START_INDEX; + else { + vdec_canvas_unlock(vdec_core, flags); + return; + } + + if ((canvas_stat[offset].canvas_used_flag > 0) && + (canvas_stat[offset].id & (1 << id))) { + canvas_stat[offset].canvas_used_flag--; + canvas_stat[offset].id &= ~(1 << id); + if (canvas_stat[offset].canvas_used_flag == 0) { + canvas_stat[offset].type = 0; + canvas_stat[offset].id = 0; + } + if (debug & 4) { + pr_debug("free index %d used_flag %d, type = %d, id = %d\n", + offset, + canvas_stat[offset].canvas_used_flag, + canvas_stat[offset].type, + canvas_stat[offset].id); + } + } + vdec_canvas_unlock(vdec_core, flags); + + return; + +} + static void vdec_dmc_pipeline_reset(void) { /* @@ -576,143 +657,42 @@ } } -#define VDEC_ASSIST_DBUS_DISABLE 0x0046 -#define HEVC_ASSIST_AXI_STATUS2_LO 0x307f - -static void vdec_dbus_ctrl(bool enable) -{ - if (enable) { - WRITE_VREG(VDEC_ASSIST_DBUS_DISABLE, 0); - } else { - u32 nop_cnt = 200; - WRITE_VREG(VDEC_ASSIST_DBUS_DISABLE, 0xffff); - while (READ_VREG(VDEC_ASSIST_DBUS_DISABLE) != 0xffff); - while (nop_cnt--); - } -} - -static void hevc_arb_ctrl(bool enable) -{ - u32 axi_ctrl, axi_status, nop_cnt = 200; - - if (enable) { - axi_ctrl = READ_VREG(HEVC_ASSIST_AXI_CTRL); - axi_ctrl &= (~((1 << 6) | (1 << 14))); - WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); //enable front/back arbitor - } else { - axi_ctrl = READ_VREG(HEVC_ASSIST_AXI_CTRL); - axi_ctrl |= (1 << 6); - WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); // disable front arbitor - - do { - axi_status = READ_VREG(HEVC_ASSIST_AXI_STATUS); - if (axi_status & ((1 << 15) | (1 << 11))) //read/write disable - break; - } while (1); - - axi_ctrl |= (1 << 14); - WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); // disable back arbitor - - do { - axi_status = READ_VREG(HEVC_ASSIST_AXI_STATUS2_LO); - if (axi_status & ((1 << 15) | (1 << 11))) //read/write disable - break; - } while (1); - - while (nop_cnt--); - } -} - -static void dec_dmc_port_ctrl(bool dmc_on, u32 target) -{ - unsigned long flags; - unsigned int sts_reg_addr = DMC_CHAN_STS; - unsigned int mask = 0; - unsigned int cpu_type = get_cpu_major_id(); - - if (target == VDEC_INPUT_TARGET_VLD) { - mask = (1 << 13); /*bit13: DOS VDEC interface*/ - if (cpu_type >= AM_MESON_CPU_MAJOR_ID_G12A) - mask = (1 << 21); - } else if (target == VDEC_INPUT_TARGET_HEVC) { - mask = (1 << 4); /*hevc*/ - if (cpu_type >= AM_MESON_CPU_MAJOR_ID_G12A) - mask |= (1 << 8); /*hevcb */ - } - - if (!mask) { - pr_info("debug dmc ctrl return\n"); - return; - } - - if (dmc_on) { - /* dmc async on requset */ - spin_lock_irqsave(&vdec_spin_lock, flags); - - codec_dmcbus_write(DMC_REQ_CTRL, - codec_dmcbus_read(DMC_REQ_CTRL) | mask); - - spin_unlock_irqrestore(&vdec_spin_lock, flags); - } else { - /* dmc async off requset */ - spin_lock_irqsave(&vdec_spin_lock, flags); - - codec_dmcbus_write(DMC_REQ_CTRL, - codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); - - spin_unlock_irqrestore(&vdec_spin_lock, flags); - - switch (cpu_type) { - case AM_MESON_CPU_MAJOR_ID_S4: - case AM_MESON_CPU_MAJOR_ID_S4D: - case AM_MESON_CPU_MAJOR_ID_T5W: - sts_reg_addr = S4_DMC_CHAN_STS; - break; - case AM_MESON_CPU_MAJOR_ID_T5: - case AM_MESON_CPU_MAJOR_ID_T5D: - sts_reg_addr = T5_DMC_CHAN_STS; - break; - case AM_MESON_CPU_MAJOR_ID_SC2: - sts_reg_addr = TM2_REVB_DMC_CHAN_STS; - break; - case AM_MESON_CPU_MAJOR_ID_TM2: - if (is_cpu_meson_revb()) - sts_reg_addr = TM2_REVB_DMC_CHAN_STS; - else - sts_reg_addr = DMC_CHAN_STS; - break; - default: - sts_reg_addr = DMC_CHAN_STS; - break; - } - while (!(codec_dmcbus_read(sts_reg_addr) - & mask)) - ; - } -} - static void vdec_disable_DMC(struct vdec_s *vdec) { /*close first,then wait pedding end,timing suggestion from vlsi*/ struct vdec_input_s *input = &vdec->input; + unsigned long flags; + unsigned int mask = 0; + + if (input->target == VDEC_INPUT_TARGET_VLD) { + mask = (1 << 13); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask = (1 << 21); + } else if (input->target == VDEC_INPUT_TARGET_HEVC) { + mask = (1 << 4); /*hevc*/ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask |= (1 << 8); /*hevcb */ + } /* need to stop armrisc. */ if (!IS_ERR_OR_NULL(vdec->dev)) vdec_stop_armrisc(input->target); - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) { - if (input->target == VDEC_INPUT_TARGET_VLD) { - if (!vdec_on(VDEC_1)) - return; - vdec_dbus_ctrl(0); - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - if (!vdec_on(VDEC_HEVC)) - return; - hevc_arb_ctrl(0); - } - } else - dec_dmc_port_ctrl(0, input->target); + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); + + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; + } else { + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; + } pr_debug("%s input->target= 0x%x\n", __func__, input->target); } @@ -720,22 +700,27 @@ static void vdec_enable_DMC(struct vdec_s *vdec) { struct vdec_input_s *input = &vdec->input; + unsigned long flags; + unsigned int mask = 0; - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) { - if (input->target == VDEC_INPUT_TARGET_VLD) - vdec_dbus_ctrl(1); - else if (input->target == VDEC_INPUT_TARGET_HEVC) - hevc_arb_ctrl(1); - return; + if (input->target == VDEC_INPUT_TARGET_VLD) { + mask = (1 << 13); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask = (1 << 21); + } else if (input->target == VDEC_INPUT_TARGET_HEVC) { + mask = (1 << 4); /*hevc*/ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask |= (1 << 8); /*hevcb */ } /*must to be reset the dmc pipeline if it's g12b.*/ if (get_cpu_type() == AM_MESON_CPU_MAJOR_ID_G12B) vdec_dmc_pipeline_reset(); - dec_dmc_port_ctrl(1, input->target); - + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) | mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); pr_debug("%s input->target= 0x%x\n", __func__, input->target); } @@ -867,7 +852,6 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) { int r; - if (vdec->set_trickmode) { r = vdec->set_trickmode(vdec, trickmode); @@ -876,7 +860,6 @@ trickmode); return r; } - return -1; } EXPORT_SYMBOL(vdec_set_trickmode); @@ -938,9 +921,7 @@ EXPORT_SYMBOL(vdec_count_info); int vdec_is_support_4k(void) { - return ((!is_meson_gxl_package_805X()) && - (!is_cpu_s4_s805x2()) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)); + return !is_meson_gxl_package_805X(); } EXPORT_SYMBOL(vdec_is_support_4k); @@ -967,12 +948,6 @@ return vdec_core->cma_dev; } -int vdec_get_core_nr(void) -{ - return (int)atomic_read(&vdec_core->vdec_nr); -} -EXPORT_SYMBOL(vdec_get_core_nr); - #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC static const char * const vdec_device_name[] = { "amvdec_mpeg12", "ammvdec_mpeg12", @@ -1132,6 +1107,7 @@ struct vdec_s *vdec; int type = VDEC_TYPE_SINGLE; int id; + if (is_mult_inc(port->type)) type = (port->type & PORT_TYPE_FRAME) ? VDEC_TYPE_FRAME_BLOCK : @@ -1155,14 +1131,11 @@ INIT_LIST_HEAD(&vdec->list); - init_waitqueue_head(&vdec->idle_wait); - atomic_inc(&vdec_core->vdec_nr); #ifdef CONFIG_AMLOGIC_V4L_VIDEO3 v4lvideo_dec_count_increase(); #endif vdec->id = id; - vdec->video_id = 0xffffffff; vdec_input_init(&vdec->input, vdec); vdec->input.vdec_is_input_frame_empty = vdec_is_input_frame_empty; vdec->input.vdec_up = vdec_up; @@ -1198,7 +1171,6 @@ vdec->slave->format = format; vdec->slave->port_flag |= PORT_FLAG_VFORMAT; } - //trace_vdec_set_format(vdec, format);/*DEBUG_TMP*/ return 0; @@ -1222,34 +1194,6 @@ } EXPORT_SYMBOL(vdec_set_timestamp); -void vdec_set_metadata(struct vdec_s *vdec, ulong meta_ptr) -{ - char *tmp_buf = NULL; - u32 size = 0; - - if (!meta_ptr) - return; - - tmp_buf = vmalloc(META_DATA_SIZE + 4); - if (!tmp_buf) { - pr_err("%s:vmalloc 256+4 fail\n", __func__); - return; - } - memcpy(tmp_buf, (void *)meta_ptr, META_DATA_SIZE + 4); - - size = tmp_buf[0] + (tmp_buf[1] << 8) + - (tmp_buf[2] << 16) + (tmp_buf[3] << 24); - - if ((size > 0) && (size <= META_DATA_SIZE)) { - memcpy(vdec->hdr10p_data_buf, tmp_buf + 4, size); - vdec->hdr10p_data_size = size; - vdec->hdr10p_data_valid = true; - } - - vfree(tmp_buf); -} -EXPORT_SYMBOL(vdec_set_metadata); - int vdec_set_pts64(struct vdec_s *vdec, u64 pts64) { vdec->pts64 = pts64; @@ -1478,8 +1422,6 @@ } EXPORT_SYMBOL(vdec_stream_skip_data); - - /* *get next frame from input chain */ @@ -1637,6 +1579,9 @@ while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7)) ; WRITE_VREG(VLD_MEM_SWAP_CTL, 0); +#ifdef VDEC_FCC_SUPPORT + vdec_fcc_jump_back(vdec); +#endif /* restore wrap count */ WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, @@ -1670,7 +1615,9 @@ & (1<<7)) ; WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0); - +#ifdef VDEC_FCC_SUPPORT + vdec_fcc_jump_back(vdec); +#endif /* restore stream offset */ WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, input->stream_cookie); @@ -1703,6 +1650,7 @@ else first_set_rp = input->start; } + if (input->target == VDEC_INPUT_TARGET_VLD) { WRITE_VREG(VLD_MEM_VIFIFO_START_PTR, input->start); @@ -1764,57 +1712,6 @@ } EXPORT_SYMBOL(vdec_prepare_input); -u32 vdec_offset_prepare_input(struct vdec_s *vdec, u32 consume_byte, u32 data_offset, u32 data_size) -{ - struct vdec_input_s *input = &vdec->input; - u32 res_byte, header_offset, header_data_size, data_invalid; - - res_byte = data_size - consume_byte; - header_offset = data_offset; - header_data_size = data_size; - data_offset += consume_byte; - data_size = res_byte; - - if (input->target == VDEC_INPUT_TARGET_VLD) { - //to do - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - data_invalid = data_offset - round_down(data_offset, 0x40); - data_offset -= data_invalid; - data_size += data_invalid; - - if (data_offset < header_offset) { - data_invalid = consume_byte; - data_offset = header_offset; - data_size = header_data_size; - } - - if (input_frame_based(input)) { - struct vframe_chunk_s *chunk = vdec_input_next_chunk(&vdec->input); - struct vframe_block_list_s *block = NULL; - int dummy; - - block = chunk->block; - WRITE_VREG(HEVC_STREAM_START_ADDR, block->start); - WRITE_VREG(HEVC_STREAM_END_ADDR, block->start + - block->size); - WRITE_VREG(HEVC_STREAM_RD_PTR, block->start + - data_offset); - dummy = data_offset + data_size + - HEVC_PADDING_SIZE; - if (dummy >= block->size) - dummy -= block->size; - WRITE_VREG(HEVC_STREAM_WR_PTR, - round_down(block->start + dummy, - VDEC_FIFO_ALIGN)); - - /* set endian */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, 7 << 4); - } - } - return data_invalid; -} -EXPORT_SYMBOL(vdec_offset_prepare_input); - void vdec_enable_input(struct vdec_s *vdec) { struct vdec_input_s *input = &vdec->input; @@ -2012,13 +1909,29 @@ EXPORT_SYMBOL(vdec_need_more_data); -static void hevc_wait_ddr(void) +void hevc_wait_ddr(void) { - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) { - hevc_arb_ctrl(0); + unsigned long flags; + unsigned int mask = 0; + + mask = 1 << 4; /* hevc */ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask |= (1 << 8); /* hevcb */ + + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); + + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; } else { - dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_HEVC); + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; } } @@ -2335,18 +2248,7 @@ return 0; discon_timeout: pr_err("%s timeout!!! status: 0x%x force it to 2\n", __func__, vdec->status); - if (vdec->status == VDEC_STATUS_ACTIVE) { - if (vdec->input.target == VDEC_INPUT_TARGET_VLD) { - amvdec_stop(); - WRITE_VREG(ASSIST_MBOX1_MASK, 0); - vdec_free_irq(VDEC_IRQ_1, NULL); - } else if (vdec->input.target == VDEC_INPUT_TARGET_HEVC) { - amhevc_stop(); - WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0); - vdec_free_irq(VDEC_IRQ_0, NULL); - } - } - + vdec_set_status(vdec, VDEC_STATUS_CONNECTED); return 0; } EXPORT_SYMBOL(vdec_disconnect); @@ -2382,10 +2284,41 @@ true : false; } -static bool is_res_locked(u32 pre, u32 cur) +static bool is_nontunnel_pipeline(u32 pl) { - return is_tunnel_pipeline(pre) ? - (is_tunnel_pipeline(cur) ? true : false) : false; + return (pl & BIT(FRAME_BASE_PATH_DI_V4LVIDEO)) ? true : false; +} + +static bool is_v4lvideo_already_used(u32 pre, int vf_receiver_inst) +{ + if (vf_receiver_inst == 0) { + if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0)) { + return true; + } + } else if (vf_receiver_inst == 1) { + if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1)) { + return true; + } + } else if (vf_receiver_inst == 2) { + if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2)) { + return true; + } + } + return false; +} + +static bool is_res_locked(u32 pre, u32 cur, int vf_receiver_inst) +{ + if (is_tunnel_pipeline(pre)) { + if (is_tunnel_pipeline(cur)) { + return true; + } + } else if (is_nontunnel_pipeline(cur)) { + if (is_v4lvideo_already_used(pre,vf_receiver_inst)) { + return true; + } + } + return false; } int vdec_resource_checking(struct vdec_s *vdec) @@ -2396,9 +2329,9 @@ * pipeline these are being released. */ ulong expires = jiffies + msecs_to_jiffies(2000); - while (is_res_locked(vdec_core->vdec_resouce_status, - BIT(vdec->frame_base_video_path))) { + BIT(vdec->frame_base_video_path), + vdec->vf_receiver_inst)) { if (time_after(jiffies, expires)) { pr_err("wait vdec resource timeout.\n"); return -EBUSY; @@ -2414,32 +2347,29 @@ *register vdec_device * create output, vfm or create ionvideo output */ -s32 vdec_init(struct vdec_s *vdec, int is_4k, bool is_v4l) +s32 vdec_init(struct vdec_s *vdec, int is_4k) { int r = 0; struct vdec_s *p = vdec; - const char *pdev_name; - char dev_name[32] = {0}; + const char *dev_name; int id = PLATFORM_DEVID_AUTO;/*if have used my self*/ int max_di_count = max_di_instance; - char postprocess_name[64] = {0}; + if (vdec_stream_based(vdec)) max_di_count = max_supported_di_instance; - vdec->is_v4l = is_v4l ? 1 : 0; - if (is_res_locked(vdec_core->vdec_resouce_status, - BIT(vdec->frame_base_video_path))) - return -EBUSY; + if (is_res_locked(vdec_core->vdec_resouce_status, + BIT(vdec->frame_base_video_path), + vdec->vf_receiver_inst)) + return -EBUSY; //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid); - pdev_name = get_dev_name(vdec_single(vdec), vdec->format); - if (pdev_name == NULL) + dev_name = get_dev_name(vdec_single(vdec), vdec->format); + + if (dev_name == NULL) return -ENODEV; - snprintf(dev_name, sizeof(dev_name), - "%s%s", pdev_name, is_v4l ? "_v4l": ""); - - pr_info("vdec_init, dev_name:%s, vdec_type=%s, format: %d\n", - dev_name, vdec_type_str(vdec), vdec->format); + pr_info("vdec_init, dev_name:%s, vdec_type=%s id = %d\n", + dev_name, vdec_type_str(vdec), vdec->id); snprintf(vdec->name, sizeof(vdec->name), "vdec-%d", vdec->id); @@ -2479,31 +2409,24 @@ if (vdec_single(vdec) || (vdec_get_debug_flags() & 0x2)) vdec_enable_DMC(vdec); p->cma_dev = vdec_core->cma_dev; - - vdec_canvas_port_register(vdec); - + p->get_canvas = get_canvas; + p->get_canvas_ex = get_canvas_ex; + p->free_canvas_ex = free_canvas_ex; p->vdec_fps_detec = vdec_fps_detec; /* todo */ if (!vdec_dual(vdec)) { p->use_vfm_path = - is_support_no_parser() ? + (is_support_no_parser()) ? vdec_single(vdec) : vdec_stream_based(vdec); } - if (debugflags & (1 << 29)) - p->is_stream_mode_dv_multi = true; - else - p->is_stream_mode_dv_multi = false; - if (debugflags & 0x4) p->use_vfm_path = 1; /* vdec_dev_reg.flag = 0; */ if (vdec->id >= 0) id = vdec->id; p->parallel_dec = parallel_decode; - p->prog_only = prog_only; - vdec_core->parallel_dec = parallel_decode; vdec->canvas_mode = CANVAS_BLKMODE_32X32; #ifdef FRAME_CHECK @@ -2566,7 +2489,7 @@ if (p->use_vfm_path) { vdec->vf_receiver_inst = -1; vdec->vfm_map_id[0] = 0; - } else if (!vdec_dual(vdec) && !vdec->disable_vfm) { + } else if (!vdec_dual(vdec)) { /* create IONVIDEO instance and connect decoder's * vf_provider interface to it */ @@ -2686,32 +2609,21 @@ mutex_unlock(&vdec_mutex); goto error; } - if (v4lvideo_add_ppmgr) - snprintf(postprocess_name, sizeof(postprocess_name), - "%s ", "ppmgr"); - if (debug_vdetect && (vdec->vf_receiver_inst == 0)) - snprintf(postprocess_name + strlen(postprocess_name), sizeof(postprocess_name), - "%s ", "vdetect.0"); - /* 8K remove di */ - if ((vdec->sys_info->width * vdec->sys_info->height > (4096 * 2304)) - || (!v4lvideo_add_di)) + if (!v4lvideo_add_di) snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s%s", vdec->vf_provider_name, - postprocess_name, + "%s %s", vdec->vf_provider_name, vdec->vf_receiver_name); else { if ((vdec->vf_receiver_inst == 0) && (max_di_count > 0)) if (max_di_count == 1) snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s%s %s", vdec->vf_provider_name, - postprocess_name, + "%s %s %s", vdec->vf_provider_name, "deinterlace", vdec->vf_receiver_name); else snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s%s %s", vdec->vf_provider_name, - postprocess_name, + "%s %s %s", vdec->vf_provider_name, "dimulti.1", vdec->vf_receiver_name); else if ((vdec->vf_receiver_inst < @@ -2773,27 +2685,6 @@ "amlvideo amvideo"); snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, "vdec-map-%d", vdec->id); - } else if (p->frame_base_video_path == - FRAME_BASE_PATH_V4LVIDEO_FENCE) { -#ifdef CONFIG_AMLOGIC_V4L_VIDEO3 - r = v4lvideo_assign_map(&vdec->vf_receiver_name, - &vdec->vf_receiver_inst); -#else - r = -1; -#endif - if (r < 0) { - pr_err("V4lVideo frame receiver allocation failed.\n"); - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - goto error; - } - - snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s", vdec->vf_provider_name, - vdec->vf_receiver_name); - snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, - "vdec-map-%d", vdec->id); } if (vfm_map_add(vdec->vfm_map_id, @@ -2829,7 +2720,7 @@ } - if (!vdec_single(vdec) && !vdec->disable_vfm) { + if (!vdec_single(vdec)) { vf_reg_provider(&p->vframe_provider); vf_notify_receiver(p->vf_provider_name, @@ -2861,6 +2752,15 @@ mutex_lock(&vdec_mutex); vdec_core->vdec_resouce_status |= BIT(p->frame_base_video_path); + if (p->frame_base_video_path == FRAME_BASE_PATH_DI_V4LVIDEO) { + if (p->vf_receiver_inst == 0) { + vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0); + } else if (p->vf_receiver_inst == 1) { + vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1); + } else if (p->vf_receiver_inst == 2) { + vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2); + } + } mutex_unlock(&vdec_mutex); vdec_input_prepare_bufs(/*prepared buffer for fast playing.*/ @@ -2869,6 +2769,13 @@ vdec->sys_info->height); /* vdec is now ready to be active */ vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED); + +#ifdef VDEC_FCC_SUPPORT + init_waitqueue_head(&vdec->jump_back_wq); + mutex_init(&vdec->jump_back_mutex); + vdec->fcc_mode = FCC_BUTT; + vdec->fcc_status = STATUS_BUTT; +#endif return 0; error: @@ -2908,36 +2815,6 @@ vdec_core_unlock(core, flags); } -st_userdata *get_vdec_userdata_ctx() -{ - return &userdata; -} -EXPORT_SYMBOL(get_vdec_userdata_ctx); - -static void vdec_userdata_ctx_release(struct vdec_s *vdec) -{ - int i; - st_userdata *userdata = get_vdec_userdata_ctx(); - - mutex_lock(&userdata->mutex); - - for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) { - if (userdata->used[i] == 1 && vdec->video_id != 0xffffffff) { - if (vdec_get_debug_flags() & 0x10000000) - pr_info("ctx_release i: %d userdata.id %d\n", - i, userdata->id[i]); - userdata->ready_flag[i] = 0; - userdata->id[i] = -1; - userdata->used[i] = 0; - userdata->set_id_flag = 0; - } - } - - mutex_unlock(&userdata->mutex); - - return; -} - /* vdec_create/init/release/destroy are applied to both dual running decoders */ void vdec_release(struct vdec_s *vdec) @@ -2954,10 +2831,10 @@ } #endif /* When release, userspace systemctl need this duration 0 event */ - vdec_frame_rate_uevent(0); + vframe_rate_uevent(0); vdec_disconnect(vdec); - if (!vdec->disable_vfm && vdec->vframe_provider.name) { + if (vdec->vframe_provider.name) { if (!vdec_single(vdec)) { if (vdec_core->hint_fr_vdec == vdec && vdec->fr_hint_state == VDEC_HINTED) @@ -3010,20 +2887,27 @@ if (vdec->vbuf.ops && !vdec->master) vdec->vbuf.ops->release(&vdec->vbuf); - vdec_userdata_ctx_release(vdec); - - pr_debug("vdec_release instance %p, total %d\n", vdec, - atomic_read(&vdec_core->vdec_nr)); + pr_debug("vdec_release instance %p, total %d id = %d\n", vdec, + atomic_read(&vdec_core->vdec_nr), vdec->id); mutex_lock(&vdec_mutex); + if (vdec->frame_base_video_path == FRAME_BASE_PATH_DI_V4LVIDEO) { + if (vdec->vf_receiver_inst == 0) { + vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0); + } else if (vdec->vf_receiver_inst == 1) { + vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1); + } else if (vdec->vf_receiver_inst == 2) { + vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2); + } + } vdec_core->vdec_resouce_status &= ~BIT(vdec->frame_base_video_path); mutex_unlock(&vdec_mutex); + vdec_destroy(vdec); mutex_lock(&vdec_mutex); inited_vcodec_num--; mutex_unlock(&vdec_mutex); - } EXPORT_SYMBOL(vdec_release); @@ -3035,13 +2919,11 @@ vdec_disconnect(vdec); - if (!vdec->disable_vfm) { - if (vdec->vframe_provider.name) - vf_unreg_provider(&vdec->vframe_provider); + if (vdec->vframe_provider.name) + vf_unreg_provider(&vdec->vframe_provider); - if ((vdec->slave) && (vdec->slave->vframe_provider.name)) - vf_unreg_provider(&vdec->slave->vframe_provider); - } + if ((vdec->slave) && (vdec->slave->vframe_provider.name)) + vf_unreg_provider(&vdec->slave->vframe_provider); if (vdec->reset) { vdec->reset(vdec); @@ -3056,17 +2938,15 @@ vdec_input_prepare_bufs(&vdec->input, vdec->sys_info->width, vdec->sys_info->height); - if (!vdec->disable_vfm) { - vf_reg_provider(&vdec->vframe_provider); - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_START, vdec); + vf_reg_provider(&vdec->vframe_provider); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_START, vdec); - if (vdec->slave) { - vf_reg_provider(&vdec->slave->vframe_provider); - vf_notify_receiver(vdec->slave->vf_provider_name, - VFRAME_EVENT_PROVIDER_START, vdec->slave); - vdec->slave->mc_loaded = 0;/*clear for reload firmware*/ - } + if (vdec->slave) { + vf_reg_provider(&vdec->slave->vframe_provider); + vf_notify_receiver(vdec->slave->vf_provider_name, + VFRAME_EVENT_PROVIDER_START, vdec->slave); + vdec->slave->mc_loaded = 0;/*clear for reload firmware*/ } vdec_connect(vdec); @@ -3081,13 +2961,11 @@ pr_debug("vdec_v4l2_reset %d\n", flag); vdec_disconnect(vdec); if (flag != 2) { - if (!vdec->disable_vfm) { - if (vdec->vframe_provider.name) - vf_unreg_provider(&vdec->vframe_provider); + if (vdec->vframe_provider.name) + vf_unreg_provider(&vdec->vframe_provider); - if ((vdec->slave) && (vdec->slave->vframe_provider.name)) - vf_unreg_provider(&vdec->slave->vframe_provider); - } + if ((vdec->slave) && (vdec->slave->vframe_provider.name)) + vf_unreg_provider(&vdec->slave->vframe_provider); if (vdec->reset) { vdec->reset(vdec); @@ -3103,17 +2981,15 @@ vdec_input_prepare_bufs(&vdec->input, vdec->sys_info->width, vdec->sys_info->height); - if (!vdec->disable_vfm) { - vf_reg_provider(&vdec->vframe_provider); - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_START, vdec); + vf_reg_provider(&vdec->vframe_provider); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_START, vdec); - if (vdec->slave) { - vf_reg_provider(&vdec->slave->vframe_provider); - vf_notify_receiver(vdec->slave->vf_provider_name, - VFRAME_EVENT_PROVIDER_START, vdec->slave); - vdec->slave->mc_loaded = 0;/*clear for reload firmware*/ - } + if (vdec->slave) { + vf_reg_provider(&vdec->slave->vframe_provider); + vf_notify_receiver(vdec->slave->vf_provider_name, + VFRAME_EVENT_PROVIDER_START, vdec->slave); + vdec->slave->mc_loaded = 0;/*clear for reload firmware*/ } } else { if (vdec->reset) { @@ -3125,10 +3001,13 @@ vdec_connect(vdec); + vdec_frame_check_init(vdec); + return 0; } EXPORT_SYMBOL(vdec_v4l2_reset); + void vdec_free_cmabuf(void) { mutex_lock(&vdec_mutex); @@ -3191,10 +3070,8 @@ t &= ~(1 << i); } - if (vdec->active_mask == 0) { + if (vdec->active_mask == 0) vdec_set_status(vdec, VDEC_STATUS_CONNECTED); - wake_up_interruptible(&vdec->idle_wait); - } mutex_unlock(&vdec_mutex); } @@ -3325,30 +3202,6 @@ return ret; } -int vdec_check_rec_num_enough(struct vdec_s *vdec) { - - if (vdec->vbuf.use_ptsserv) { - return (pts_get_rec_num(PTS_TYPE_VIDEO, - vdec->input.total_rd_count) >= 2); - } else { - u64 total_rd_count = vdec->input.total_rd_count; - - if (vdec->input.target == VDEC_INPUT_TARGET_VLD) { - //total_rd_count -= vdec->input.start; - /*just like use ptsserv, alway return true*/ - return 1; - } - if ((total_rd_count >= vdec->vbuf.last_offset[0]) && - (total_rd_count - vdec->vbuf.last_offset[0] < 0x80000000)) - return 0; - else if ((total_rd_count >= vdec->vbuf.last_offset[1]) && - (total_rd_count - vdec->vbuf.last_offset[1] < 0x80000000)) - return 0; - - return 1; - } -} - unsigned long vdec_ready_to_run(struct vdec_s *vdec, unsigned long mask) { unsigned long ready_mask; @@ -3376,6 +3229,7 @@ inc_profi_count(mask, vdec->check_count); #endif if (vdec_core_with_input(mask)) { + /* check frame based input underrun */ if (input && !input->eos && input_frame_based(input) && (!vdec_input_next_chunk(input))) { @@ -3396,7 +3250,8 @@ level = wp - rp; if ((level < input->prepare_level) && - !vdec_check_rec_num_enough(vdec)) { + (pts_get_rec_num(PTS_TYPE_VIDEO, + vdec->input.total_rd_count) < 2)) { vdec->need_more_data |= VDEC_NEED_MORE_DATA; #ifdef VDEC_DEBUG_SUPPORT inc_profi_count(mask, vdec->input_underrun_count); @@ -3465,9 +3320,6 @@ * Perform need_more_data checking and set flag is decoder * is not consuming data. */ -#define DMC_DEV_TYPE_NON_SECURE 0 -#define DMC_DEV_TYPE_SECURE 1 - void vdec_prepare_run(struct vdec_s *vdec, unsigned long mask) { struct vdec_input_s *input = &vdec->input; @@ -3481,12 +3333,12 @@ if (vdec_stream_based(vdec) && !vdec_secure(vdec)) { - tee_config_device_state(DMC_DEV_ID_PARSER, 0); + tee_config_device_secure(DMC_DEV_ID_PARSER, 0); } if (input->target == VDEC_INPUT_TARGET_VLD) - tee_config_device_state(DMC_DEV_ID_VDEC, secure); + tee_config_device_secure(DMC_DEV_ID_VDEC, secure); else if (input->target == VDEC_INPUT_TARGET_HEVC) - tee_config_device_state(DMC_DEV_ID_HEVC, secure); + tee_config_device_secure(DMC_DEV_ID_HEVC, secure); if (vdec_stream_based(vdec) && ((vdec->need_more_data & VDEC_NEED_MORE_DATA_RUN) && @@ -3498,6 +3350,7 @@ vdec->need_more_data &= ~VDEC_NEED_MORE_DATA_DIRTY; } + /* struct vdec_core_shread manages all decoder instance in active list. When * a vdec is added into the active list, it can onlt be in two status: * VDEC_STATUS_CONNECTED(the decoder does not own HW resource and ready to run) @@ -3697,6 +3550,7 @@ inc_profi_count(mask, vdec->run_count); update_profi_clk_run(vdec, mask, get_current_clk()); #endif + vdec->run(vdec, mask, vdec_callback, core); @@ -3796,7 +3650,6 @@ } EXPORT_SYMBOL(vdec_power_reset); - void vdec_poweron(enum vdec_type_e core) { if (core >= VDEC_MAX) @@ -3944,12 +3797,27 @@ void vdec_reset_core(struct vdec_s *vdec) { - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) { - /* t7 no dmc req for vdec only */ - vdec_dbus_ctrl(0); + unsigned long flags; + unsigned int mask = 0; + + mask = 1 << 13; /*bit13: DOS VDEC interface*/ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask = 1 << 21; /*bit21: DOS VDEC interface*/ + + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); + + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; } else { - dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_VLD); + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; } /* * 2: assist @@ -3969,11 +3837,10 @@ WRITE_VREG(DOS_SW_RESET0, (1<<3)|(1<<4)|(1<<5)|(1<<7)|(1<<8)|(1<<9)); WRITE_VREG(DOS_SW_RESET0, 0); - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) - vdec_dbus_ctrl(1); - else - dec_dmc_port_ctrl(1, VDEC_INPUT_TARGET_VLD); + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) | mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); } EXPORT_SYMBOL(vdec_reset_core); @@ -4013,25 +3880,39 @@ void hevc_reset_core(struct vdec_s *vdec) { - int cpu_type = get_cpu_major_id(); + unsigned long flags; + unsigned int mask = 0; + int cpu_type; - if ((cpu_type == AM_MESON_CPU_MAJOR_ID_T7) || - (cpu_type == AM_MESON_CPU_MAJOR_ID_T3)) { - /* t7 no dmc req for hevc only */ - hevc_arb_ctrl(0); + mask = 1 << 4; /*bit4: hevc*/ + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + mask |= 1 << 8; /*bit8: hevcb*/ + + WRITE_VREG(HEVC_STREAM_CONTROL, 0); + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) & ~mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); + + if (is_cpu_tm2_revb() || + (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) { + while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS) + & mask)) + ; } else { - WRITE_VREG(HEVC_STREAM_CONTROL, 0); - - dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_HEVC); + while (!(codec_dmcbus_read(DMC_CHAN_STS) + & mask)) + ; } if (vdec == NULL || input_frame_based(vdec)) WRITE_VREG(HEVC_STREAM_CONTROL, 0); + WRITE_VREG(HEVC_SAO_MMU_RESET_CTRL, READ_VREG(HEVC_SAO_MMU_RESET_CTRL) | 1); - /* + /* * 2: assist * 3: parser * 4: parser_state @@ -4048,17 +3929,25 @@ * 24:hevc_afifo * 26:rst_mmu_n */ - WRITE_VREG(DOS_SW_RESET3, - (1<<3)|(1<<4)|(1<<8)|(1<<10)|(1<<11)| - (1<<12)|(1<<13)|(1<<14)|(1<<15)| - (1<<17)|(1<<18)|(1<<19)|(1<<24)|(1<<26)); + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) && + (vdec->format == VFORMAT_AVS2)) { + WRITE_VREG(DOS_SW_RESET3, + (1<<3)|(1<<4)|(1<<8)|(1<<11)| + (1<<12)|(1<<14)|(1<<15)| + (1<<17)|(1<<18)|(1<<19)); + } else { + WRITE_VREG(DOS_SW_RESET3, + (1<<3)|(1<<4)|(1<<8)|(1<<10)|(1<<11)| + (1<<12)|(1<<13)|(1<<14)|(1<<15)| + (1<<17)|(1<<18)|(1<<19)|(1<<24)|(1<<26)); + } WRITE_VREG(DOS_SW_RESET3, 0); while (READ_VREG(HEVC_WRRSP_LMEM) & 0xfff) ; WRITE_VREG(HEVC_SAO_MMU_RESET_CTRL, READ_VREG(HEVC_SAO_MMU_RESET_CTRL) & (~1)); - + cpu_type = get_cpu_major_id(); if (cpu_type == AM_MESON_CPU_MAJOR_ID_TL1 && is_meson_rev_b()) cpu_type = AM_MESON_CPU_MAJOR_ID_G12B; @@ -4073,17 +3962,12 @@ case AM_MESON_CPU_MAJOR_ID_SM1: case AM_MESON_CPU_MAJOR_ID_TL1: case AM_MESON_CPU_MAJOR_ID_TM2: - case AM_MESON_CPU_MAJOR_ID_T5: - case AM_MESON_CPU_MAJOR_ID_T5D: - case AM_MESON_CPU_MAJOR_ID_T5W: WRITE_RESET_REG((RESET7_REGISTER_LEVEL), READ_RESET_REG(RESET7_REGISTER_LEVEL) & (~((1<<13)))); WRITE_RESET_REG((RESET7_REGISTER_LEVEL), READ_RESET_REG((RESET7_REGISTER_LEVEL)) | ((1<<13))); break; case AM_MESON_CPU_MAJOR_ID_SC2: - case AM_MESON_CPU_MAJOR_ID_S4: - case AM_MESON_CPU_MAJOR_ID_S4D: WRITE_RESET_REG(P_RESETCTRL_RESET5_LEVEL, READ_RESET_REG(P_RESETCTRL_RESET5_LEVEL) & (~((1<<1)|(1<<12)|(1<<13)))); WRITE_RESET_REG(P_RESETCTRL_RESET5_LEVEL, @@ -4093,11 +3977,12 @@ break; } - if ((cpu_type == AM_MESON_CPU_MAJOR_ID_T7) || - (cpu_type == AM_MESON_CPU_MAJOR_ID_T3)) - hevc_arb_ctrl(1); - else - dec_dmc_port_ctrl(1, VDEC_INPUT_TARGET_HEVC); + + spin_lock_irqsave(&vdec_spin_lock, flags); + codec_dmcbus_write(DMC_REQ_CTRL, + codec_dmcbus_read(DMC_REQ_CTRL) | mask); + spin_unlock_irqrestore(&vdec_spin_lock, flags); + } EXPORT_SYMBOL(hevc_reset_core); @@ -4245,7 +4130,7 @@ int i; char *pbuf = buf; ssize_t ret; - u16 *trace_buf = kmalloc(debug_trace_num * 2, GFP_KERNEL); + u16 *trace_buf = vzalloc(debug_trace_num * 2); if (!trace_buf) { pbuf += sprintf(pbuf, "No Memory bug\n"); @@ -4256,7 +4141,7 @@ mutex_lock(&vdec_mutex); if (!vdec_on(VDEC_1)) { mutex_unlock(&vdec_mutex); - kfree(trace_buf); + vfree(trace_buf); pbuf += sprintf(pbuf, "amrisc is power off\n"); ret = pbuf - buf; return ret; @@ -4312,7 +4197,7 @@ } while (i < debug_trace_num) ; - kfree(trace_buf); + vfree(trace_buf); pbuf += sprintf(pbuf, "\n"); ret = pbuf - buf; return ret; @@ -4356,7 +4241,8 @@ return count; } -static ssize_t poweron_clock_level_store(struct class *class, + +static ssize_t store_poweron_clock_level(struct class *class, struct class_attribute *attr, const char *buf, size_t size) { @@ -4372,7 +4258,7 @@ return size; } -static ssize_t poweron_clock_level_show(struct class *class, +static ssize_t show_poweron_clock_level(struct class *class, struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", poweron_clock_level); @@ -4383,7 +4269,7 @@ *always don't release *vdec 64 memory for fast play. */ -static ssize_t keep_vdec_mem_store(struct class *class, +static ssize_t store_keep_vdec_mem(struct class *class, struct class_attribute *attr, const char *buf, size_t size) { @@ -4398,14 +4284,15 @@ return size; } -static ssize_t keep_vdec_mem_show(struct class *class, +static ssize_t show_keep_vdec_mem(struct class *class, struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", keep_vdec_mem); } + #ifdef VDEC_DEBUG_SUPPORT -static ssize_t debug_store(struct class *class, +static ssize_t store_debug(struct class *class, struct class_attribute *attr, const char *buf, size_t size) { @@ -4444,10 +4331,6 @@ "VDEC_DEBUG: HHI_VDEC4_CLK_CNTL = 0x%x, HHI_VDEC2_CLK_CNTL = 0x%x\n", READ_HHI_REG(HHI_VDEC4_CLK_CNTL), READ_HHI_REG(HHI_VDEC2_CLK_CNTL)); - } else if (strcmp(cbuf, "no_interlace") == 0) { - prog_only ^= 1; - pr_info("set prog only %d, %s output\n", - prog_only, prog_only?"force one filed only":"interlace"); } flags = vdec_core_lock(vdec_core); @@ -4466,7 +4349,7 @@ return size; } -static ssize_t debug_show(struct class *class, +static ssize_t show_debug(struct class *class, struct class_attribute *attr, char *buf) { char *pbuf = buf; @@ -4492,8 +4375,6 @@ pbuf += sprintf(pbuf, "read_hevc_clk_reg - read HHI register for hevc clk\n"); pbuf += sprintf(pbuf, - "no_interlace - force v4l no_interlace output. %d\n", prog_only); - pbuf += sprintf(pbuf, "===================\n"); pbuf += sprintf(pbuf, @@ -4531,6 +4412,7 @@ } #endif + int show_stream_buffer_status(char *buf, int (*callback) (struct stream_buf_s *, char *)) { @@ -4554,7 +4436,7 @@ } EXPORT_SYMBOL(show_stream_buffer_status); -static ssize_t vdec_vfm_path_store(struct class *class, +static ssize_t store_vdec_vfm_path(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { @@ -4613,7 +4495,7 @@ return count; } -static ssize_t vdec_vfm_path_show(struct class *class, +static ssize_t show_vdec_vfm_path(struct class *class, struct class_attribute *attr, char *buf) { int len = 0; @@ -4668,6 +4550,7 @@ vdec_core->isr_context[num].dev_isr = handler; vdec_core->isr_context[num].dev_threaded_isr = thread_fn; vdec_core->isr_context[num].dev_id = dev; + ret = request_threaded_irq(res_irq, vdec_isr, vdec_thread_isr, @@ -4725,20 +4608,6 @@ } EXPORT_SYMBOL(vdec_free_irq); -void vdec_sync_irq(enum vdec_irq_num num) -{ -#if 0 - if (!vdec) - return; - if (vdec->input.target == VDEC_INPUT_TARGET_HEVC) - synchronize_irq(vdec_core->isr_context[VDEC_IRQ_0].irq); - else (vdec->input.target == VDEC_INPUT_TARGET_VLD) - synchronize_irq(vdec_core->isr_context[VDEC_IRQ_1].irq); -#endif - synchronize_irq(vdec_core->isr_context[num].irq); -} -EXPORT_SYMBOL(vdec_sync_irq); - struct vdec_s *vdec_get_default_vdec_for_userdata(void) { struct vdec_s *vdec; @@ -4865,6 +4734,192 @@ } EXPORT_SYMBOL(vdec_set_profile_level); +#ifdef VDEC_FCC_SUPPORT +int vdec_wakeup_fcc_poll(struct vdec_s *vdec) +{ + if (vdec) { + if (vdec->wakeup_fcc_poll) + vdec->wakeup_fcc_poll(vdec); + } + + return 0; +} +EXPORT_SYMBOL(vdec_wakeup_fcc_poll); + +int vdec_has_get_fcc_new_msg(struct vdec_s *vdec) +{ + int ret = 1; + + if (vdec == NULL) { + pr_info("Error, invalid vdec instance!\n"); + return 0; + } + + if (input_stream_based(vdec)) { + if (vdec->fcc_mode == FCC_DISCARD_MODE && + vdec->fcc_status == STATUS_BUTT) { + ret = 1; + vdec->fcc_status = AGAIN_STATUS; + } else if (vdec->fcc_mode == FCC_DEC_MODE && + vdec->fcc_status != SWITCH_DONE_STATUS) { + ret = 1; + + if (wait_event_interruptible_timeout(vdec->jump_back_wq, vdec->jump_back_done | vdec->jump_back_error, + HZ / 2) <= 0) { + pr_info("[%d][FCC]: Error! Wait jump back wp timeout 500ms!\n", + vdec->id); + vdec->fcc_status = SWITCH_DONE_STATUS; + } else { + if (fcc_debug_enable()) + pr_info("[%d][FCC]: jump_back_done = %d\n", + vdec->id, vdec->jump_back_done); + if (vdec->jump_back_done) { + vdec->fcc_status = JUMP_BACK_STATUS; + vdec->jump_back_done = 0; + } else { + vdec->fcc_status = SWITCH_DONE_STATUS; + vdec->jump_back_error = 0; + } + } + + if (fcc_debug_enable()) + pr_info("[%d][FCC]: It is DEC mode now! fcc_status: %d\n", + vdec->id, vdec->fcc_status); + } else if (vdec->fcc_mode == FCC_DISCARD_MODE && + !vdec->fcc_new_msg) { + if (vdec->fcc_status == WAIT_MSG_STATUS) { + if (fcc_debug_enable()) + pr_info("[%d][FCC]: Wait msg!\n", vdec->id); + ret = 0; + } else { + if (fcc_debug_enable()) + pr_info("[%d][FCC]: Continue to find header!\n", vdec->id); + ret = 1; + } + } else if (vdec->fcc_new_msg) { + if (fcc_debug_enable()) + pr_info("[%d][FCC]: Got discard msg!\n", vdec->id); + ret = 1; + vdec->fcc_new_msg = 0; + if (vdec->fcc_mode == FCC_DISCARD_MODE) { + vdec->fcc_status = DISCARD_STATUS; + } + } + } + + return ret; +} +EXPORT_SYMBOL(vdec_has_get_fcc_new_msg); +void vdec_set_dmc_urgent(struct vdec_s *vdec, int urgentType) +{ +#ifndef DMC_AXI4_G12_CHAN_CTRL +#define DMC_AXI4_G12_CHAN_CTRL (0x90 << 2) +#endif +#define DMC_URGENT_TYPE_NORMAL 1 +#define DMC_URGENT_TYPE_URGENT 2 +#define DMC_URGENT_TYPE_SUPERURGENT 4 + + if (vdec) { + if (urgentType == DMC_URGENT_TYPE_NORMAL || + urgentType == DMC_URGENT_TYPE_URGENT || + urgentType == DMC_URGENT_TYPE_SUPERURGENT) { + int type; + unsigned int val; + + type = vdec_get_hw_type(vdec->port->vformat); + if (type == CORE_MASK_HEVC) { + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { + val = READ_DMCREG(DMC_AXI4_CHAN_CTRL); + val &= (~(0x7 << 16)); + val |= ((urgentType & 0x7) << 16); + WRITE_DMCREG(DMC_AXI4_CHAN_CTRL, val); + } else { + val = READ_DMCREG(DMC_AXI4_G12_CHAN_CTRL); + val &= (~(0x7 << 16)); + val |= ((urgentType & 0x7) << 16); + WRITE_DMCREG(DMC_AXI4_G12_CHAN_CTRL, val); + } + } + } + } + +} +EXPORT_SYMBOL(vdec_set_dmc_urgent); + +int fcc_debug_enable(void) +{ + return fcc_debug; +} +EXPORT_SYMBOL(fcc_debug_enable); + +static void vdec_fcc_jump_back(struct vdec_s *vdec) +{ + u32 cur_rp, set_rp; + struct vdec_input_s *input = &vdec->input; + + if (fcc_debug_enable()) + pr_info("[%d][FCC]: fcc_mode = %d fcc_status = %d\n", + vdec->id, vdec->fcc_mode, vdec->fcc_status); + + if (input->target == VDEC_INPUT_TARGET_VLD) { + if (vdec->fcc_mode == FCC_DEC_MODE && + vdec->fcc_status == JUMP_BACK_STATUS) { + set_rp = vdec->jump_back_rp; + cur_rp =READ_VREG(VLD_MEM_VIFIFO_RP); + input->stream_cookie = READ_VREG(VLD_MEM_VIFIFO_WRAP_COUNT); + if (cur_rp < set_rp) { + if (fcc_debug_enable()) + pr_info("[%d][FCC]: Packet is wrapped! VLD_MEM_VIFIFO_WRAP_COUNT = %d\n", + vdec->id, input->stream_cookie); + input->stream_cookie = (input->stream_cookie - 1) < 0 ? + 0 : input->stream_cookie - 1; + } + + WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR, set_rp); + WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1); + WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0); + + WRITE_VREG(VLD_MEM_SWAP_ADDR, + input->swap_page_phys); + WRITE_VREG(VLD_MEM_SWAP_CTL, 3); + while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7)) + ; + WRITE_VREG(VLD_MEM_SWAP_CTL, 0); + vdec->fcc_status = SWITCH_DONE_STATUS; + if (fcc_debug_enable()) { + pr_info("[%d][FCC]:Current VLD_MEM_VIFIFO_WRAP_COUNT = %d cur_rp = %x set_rp = %x\n", + vdec->id, input->stream_cookie, cur_rp, set_rp); + } + } + } else if (input->target == VDEC_INPUT_TARGET_HEVC) { + if (vdec->fcc_mode == FCC_DEC_MODE && + vdec->fcc_status == JUMP_BACK_STATUS) { + set_rp = vdec->jump_back_rp; + cur_rp = READ_VREG(HEVC_STREAM_RD_PTR); + if (cur_rp < set_rp) { + input->stream_cookie = input->stream_cookie + set_rp - cur_rp - vdec->input.size; + } else { + input->stream_cookie = input->stream_cookie - cur_rp + set_rp; + } + + WRITE_VREG(HEVC_STREAM_RD_PTR, set_rp); + vdec->fcc_status = SWITCH_DONE_STATUS; + + WRITE_VREG(HEVC_STREAM_SWAP_ADDR, + input->swap_page_phys); + WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 3); + + while (READ_VREG(HEVC_STREAM_SWAP_CTRL) + & (1<<7)) + ; + WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0); + } + } + + return; +} +#endif + static int dump_mode; static ssize_t dump_risc_mem_store(struct class *class, struct class_attribute *attr, @@ -4981,11 +5036,10 @@ list_for_each_entry(vdec, &core->connected_vdec_list, list) { pbuf += sprintf(pbuf, - "\tvdec.%d (%p (%s%s)), status = %s,\ttype = %s, \tactive_mask = %lx\n", + "\tvdec.%d (%p (%s)), status = %s,\ttype = %s, \tactive_mask = %lx\n", vdec->id, vdec, vdec_device_name[vdec->format * 2], - (vdec->is_v4l == 1) ? "_v4l" : "", vdec_status_str(vdec), vdec_type_str(vdec), vdec->active_mask); @@ -5155,28 +5209,6 @@ return pbuf - buf; } -static ssize_t version_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; -#ifdef DECODER_VERSION - pbuf += sprintf(pbuf, "DECODER VERSION: V" xstr(DECODER_VERSION) "\n"); -#else -#ifdef RELEASED_VERSION - pbuf += sprintf(pbuf, "Due to project compilation environment problems,\ -the current decoder version could not be detected,\ -Please Use The DECODER BASE Version for traceability\n"); - pbuf += sprintf(pbuf, "DECODER BASE Version: " xstr(RELEASED_VERSION) "\n"); -#endif -#endif - -#ifdef UCODE_VERSION - pbuf += sprintf(pbuf, "UCODE VERSION: V" xstr(UCODE_VERSION) "\n"); -#endif - - return pbuf - buf; -} - static char * parser_h264_profile(char *pbuf, struct vdec_s *vdec) { switch (vdec->profile_idc) { @@ -5444,65 +5476,71 @@ return pbuf - buf; } -static CLASS_ATTR_RO(amrisc_regs); -static CLASS_ATTR_RO(dump_trace); -static CLASS_ATTR_RO(clock_level); -static CLASS_ATTR_RW(poweron_clock_level); -static CLASS_ATTR_RW(dump_risc_mem); -static CLASS_ATTR_RW(keep_vdec_mem); -static CLASS_ATTR_RW(enable_mvdec_info); -static CLASS_ATTR_RO(core); -static CLASS_ATTR_RO(vdec_status); -static CLASS_ATTR_RO(dump_vdec_blocks); -static CLASS_ATTR_RO(dump_vdec_chunks); -static CLASS_ATTR_RO(dump_decoder_state); -#ifdef VDEC_DEBUG_SUPPORT -static CLASS_ATTR_RW(debug); -#endif -static CLASS_ATTR_RW(vdec_vfm_path); -#ifdef FRAME_CHECK -static CLASS_ATTR_RW(dump_yuv); -static CLASS_ATTR_RW(frame_check); -#endif -static CLASS_ATTR_RO(dump_fps); -static CLASS_ATTR_RO(profile_idc); -static CLASS_ATTR_RO(level_idc); -static CLASS_ATTR_RO(version); +#ifdef VDEC_FCC_SUPPORT +static ssize_t store_fcc_debug(struct class *class, + struct class_attribute *attr, + const char *buf, size_t size) +{ + unsigned int val; + ssize_t ret; -static struct attribute *vdec_class_attrs[] = { - &class_attr_amrisc_regs.attr, - &class_attr_dump_trace.attr, - &class_attr_clock_level.attr, - &class_attr_poweron_clock_level.attr, - &class_attr_dump_risc_mem.attr, - &class_attr_keep_vdec_mem.attr, - &class_attr_enable_mvdec_info.attr, - &class_attr_core.attr, - &class_attr_vdec_status.attr, - &class_attr_dump_vdec_blocks.attr, - &class_attr_dump_vdec_chunks.attr, - &class_attr_dump_decoder_state.attr, + ret = kstrtoint(buf, 0, &val); + if (ret != 0) + return -EINVAL; + fcc_debug = val; + return size; +} + +static ssize_t show_fcc_debug(struct class *class, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", fcc_debug); +} +#endif + +static struct class_attribute vdec_class_attrs[] = { + __ATTR_RO(amrisc_regs), + __ATTR_RO(dump_trace), + __ATTR_RO(clock_level), + __ATTR(enable_mvdec_info, S_IRUGO | S_IWUSR | S_IWGRP, + enable_mvdec_info_show, enable_mvdec_info_store), + __ATTR(poweron_clock_level, S_IRUGO | S_IWUSR | S_IWGRP, + show_poweron_clock_level, store_poweron_clock_level), + __ATTR(dump_risc_mem, S_IRUGO | S_IWUSR | S_IWGRP, + dump_risc_mem_show, dump_risc_mem_store), + __ATTR(keep_vdec_mem, S_IRUGO | S_IWUSR | S_IWGRP, + show_keep_vdec_mem, store_keep_vdec_mem), + __ATTR_RO(core), + __ATTR_RO(vdec_status), + __ATTR_RO(dump_vdec_blocks), + __ATTR_RO(dump_vdec_chunks), + __ATTR_RO(dump_decoder_state), #ifdef VDEC_DEBUG_SUPPORT - &class_attr_debug.attr, + __ATTR(debug, S_IRUGO | S_IWUSR | S_IWGRP, + show_debug, store_debug), #endif - &class_attr_vdec_vfm_path.attr, #ifdef FRAME_CHECK - &class_attr_dump_yuv.attr, - &class_attr_frame_check.attr, + __ATTR(dump_yuv, S_IRUGO | S_IWUSR | S_IWGRP, + dump_yuv_show, dump_yuv_store), + __ATTR(frame_check, S_IRUGO | S_IWUSR | S_IWGRP, + frame_check_show, frame_check_store), #endif - &class_attr_dump_fps.attr, - &class_attr_profile_idc.attr, - &class_attr_level_idc.attr, - &class_attr_version.attr, - NULL + __ATTR_RO(dump_fps), + __ATTR_RO(profile_idc), + __ATTR_RO(level_idc), + __ATTR(vfm_path, S_IRUGO | S_IWUSR | S_IWGRP, + show_vdec_vfm_path, store_vdec_vfm_path), +#ifdef VDEC_FCC_SUPPORT + __ATTR(fcc_debug, S_IRUGO | S_IWUSR | S_IWGRP, + show_fcc_debug, store_fcc_debug), +#endif + __ATTR_NULL }; -ATTRIBUTE_GROUPS(vdec_class); - static struct class vdec_class = { - .name = "vdec", - .class_groups = vdec_class_groups, -}; + .name = "vdec", + .class_attrs = vdec_class_attrs, + }; struct device *get_vdec_device(void) { @@ -5510,119 +5548,6 @@ } EXPORT_SYMBOL(get_vdec_device); -static int vdec_post_task_recycle(void *args) -{ - struct post_task_mgr_s *post = - (struct post_task_mgr_s *)args; - - while (post->running && - down_interruptible(&post->sem) == 0) { - if (kthread_should_stop()) - break; - mutex_lock(&post->mutex); - if (!list_empty(&post->task_recycle)) { - struct vdec_post_task_parms_s *parms, *tmp; - list_for_each_entry_safe(parms, tmp, &post->task_recycle, recycle) { - if (parms->scheduled) { - list_del(&parms->recycle); - kthread_stop(parms->task); - kfree(parms); - parms = NULL; - } - } - } - mutex_unlock(&post->mutex); - } - - return 0; -} - -static void vdec_post_task_exit(void) -{ - struct post_task_mgr_s *post = &vdec_core->post; - - post->running = false; - up(&post->sem); - - kthread_stop(post->task); -} - -static int vdec_post_task_init(void) -{ - struct post_task_mgr_s *post = &vdec_core->post; - - sema_init(&post->sem, 0); - INIT_LIST_HEAD(&post->task_recycle); - mutex_init(&post->mutex); - post->running = true; - - post->task = kthread_run(vdec_post_task_recycle, - post, "task-post-daemon-thread"); - if (IS_ERR(post->task)) { - pr_err("%s, creat task post daemon thread faild %ld\n", - __func__, PTR_ERR(post->task)); - return PTR_ERR(post->task); - } - - return 0; -} - -static int vdec_post_handler(void *args) -{ - struct vdec_post_task_parms_s *parms = - (struct vdec_post_task_parms_s *) args; - struct post_task_mgr_s *post = &vdec_core->post; - - complete(&parms->park); - - /* process client task. */ - parms->func(parms->private); - parms->scheduled = 1; - up(&post->sem); - - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - usleep_range(1000, 2000); - } - - return 0; -} - -int vdec_post_task(post_task_handler func, void *args) -{ - struct vdec_post_task_parms_s *parms; - struct post_task_mgr_s *post = &vdec_core->post; - - parms = kzalloc(sizeof(*parms), GFP_KERNEL); - if (parms == NULL) - return -ENOMEM; - - parms->func = func; - parms->private = args; - init_completion(&parms->park); - parms->scheduled = 0; - parms->task = kthread_run(vdec_post_handler, - parms, "task-post-thread"); - if (IS_ERR(parms->task)) { - pr_err("%s, creat task post thread faild %ld\n", - __func__, PTR_ERR(parms->task)); - kfree(parms); - return PTR_ERR(parms->task); - } - if (!__kthread_should_park(parms->task)) - wait_for_completion(&parms->park); - - mutex_lock(&post->mutex); - /* add to list for resource recycle in post daemon kthread */ - list_add_tail(&parms->recycle, &post->task_recycle); - mutex_unlock(&post->mutex); - - return 0; -} -EXPORT_SYMBOL(vdec_post_task); - - - static int vdec_probe(struct platform_device *pdev) { s32 i, r; @@ -5703,8 +5628,6 @@ WQ_MEM_RECLAIM |WQ_HIGHPRI/*high priority*/, "vdec-work"); /*work queue priority lower than vdec-core.*/ - vdec_post_task_init(); - /* power manager init. */ vdec_core->pm = (struct power_manager_s *) of_device_get_match_data(&pdev->dev); @@ -5714,7 +5637,6 @@ pr_err("vdec power manager init failed\n"); return r; } - pr_err("vdec power init success!\n"); } return 0; @@ -5735,8 +5657,6 @@ } } - vdec_post_task_exit(); - kthread_stop(vdec_core->thread); destroy_workqueue(vdec_core->vdec_core_wq); @@ -5892,9 +5812,9 @@ ready = (ready + fifo[slot].frame_dur) / 2; else ready = fifo[slot].frame_dur; - pr_debug("%s inner driver dur%u \n",__func__, ready); - } - goto end_handle; + pr_debug("%s inner driver dur%u \n",__func__, ready); + } + goto end_handle; } if (slot == 1) { @@ -5933,7 +5853,7 @@ end_handle: if (must_send) { ++must_send; - vdec_frame_rate_uevent(ready); + vframe_rate_uevent(ready); } } @@ -5971,7 +5891,7 @@ fifo_buf[i].pts_us64 = vf->pts_us64; /* Calculate the duration from pts */ - if (!vdec->is_v4l && (mvfrm->wr < MINIMUM_FRAMES && mvfrm->wr > 0)) + if (mvfrm->wr < MINIMUM_FRAMES && mvfrm->wr > 0) cal_dur_from_pts(vdec, i); } mvfrm->wr++; @@ -5987,76 +5907,6 @@ } EXPORT_SYMBOL(vdec_vframe_ready); -void set_meta_data_to_vf(struct vframe_s *vf, u32 type, void *v4l2_ctx) -{ - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(v4l2_ctx); - struct aml_meta_head_s head; - struct aml_vf_base_info_s vfb_infos; - - if ((ctx == NULL) || (vf == NULL)) - return ; - - if (vf->meta_data_buf == NULL) { - vf->meta_data_buf = ctx->meta_infos.meta_bufs[ctx->meta_infos.index].buf; - ctx->meta_infos.index = (ctx->meta_infos.index + 1) % V4L_CAP_BUFF_MAX; - } - - switch (type) { - case UVM_META_DATA_VF_BASE_INFOS: - if ((vf->meta_data_size + sizeof(struct aml_vf_base_info_s) + AML_META_HEAD_SIZE) <= META_DATA_SIZE) { - head.magic = META_DATA_MAGIC; - head.type = UVM_META_DATA_VF_BASE_INFOS; - head.data_size = sizeof(struct aml_vf_base_info_s); - - memcpy(vf->meta_data_buf + vf->meta_data_size, - &head, AML_META_HEAD_SIZE); - vf->meta_data_size += AML_META_HEAD_SIZE; - - vfb_infos.width = vf->width; - vfb_infos.height = vf->height; - vfb_infos.duration = vf->duration; - vfb_infos.frame_type = vf->frame_type; - vfb_infos.type = vf->type; - - memcpy(vf->meta_data_buf + vf->meta_data_size, - &vfb_infos, sizeof(struct aml_vf_base_info_s)); - vf->meta_data_size += sizeof(struct aml_vf_base_info_s); - - if (debug_meta) { - pr_debug("vf->meta_data_size = %d\n", vf->meta_data_size); - pr_debug("vf:width:%d height:%d duration:%d frame_type:%d type:%d\n", - vfb_infos.width, vfb_infos.height, vfb_infos.duration, - vfb_infos.frame_type, vfb_infos.type); - } - } - break; - case UVM_META_DATA_HDR10P_DATA: - if ((vf->meta_data_size + vf->hdr10p_data_size + AML_META_HEAD_SIZE) <= META_DATA_SIZE) { - head.magic = META_DATA_MAGIC; - head.type = UVM_META_DATA_HDR10P_DATA; - head.data_size = vf->hdr10p_data_size; - - memcpy(vf->meta_data_buf + vf->meta_data_size, - &head, AML_META_HEAD_SIZE); - vf->meta_data_size += AML_META_HEAD_SIZE; - - memcpy(vf->meta_data_buf + vf->meta_data_size, - vf->hdr10p_data_buf, vf->hdr10p_data_size); - vf->meta_data_size += vf->hdr10p_data_size; - - if (debug_meta) { - pr_debug("vf->meta_data_size = %d\n", vf->meta_data_size); - pr_debug("vf->hdr10p_data_size = %d\n", vf->hdr10p_data_size); - } - } - break; - default: - break; - } -} -EXPORT_SYMBOL(set_meta_data_to_vf); - /* In this function,if we use copy_to_user, we may encounter sleep, which may block the vdec_fill_vdec_frame,this is not acceptable. So, we should use a tmp buffer(passed by caller) to get the content */ @@ -6113,23 +5963,6 @@ } EXPORT_SYMBOL(vdec_get_frame_vdec); -int get_double_write_ratio(int dw_mode) -{ - int ratio = 1; - - if ((dw_mode == 2) || - (dw_mode == 3)) - ratio = 4; - else if ((dw_mode == 4) || - (dw_mode == 5)) - ratio = 2; - else if ((dw_mode == 8) || - (dw_mode == 9)) - ratio = 8; - return ratio; -} -EXPORT_SYMBOL(get_double_write_ratio); - void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp) { if (vdec_single(vdec)) { @@ -6177,111 +6010,6 @@ } EXPORT_SYMBOL(vdec_config_vld_reg); -static void check_rdma_result(int num) -{ - int i, wr,rd,data; - int flag = 1; - for (i = 0; i < num; i++) { - wr = READ_VREG(HEVC_IQIT_SCALELUT_WR_ADDR); - rd = READ_VREG(HEVC_IQIT_SCALELUT_RD_ADDR); - data = READ_VREG(HEVC_IQIT_SCALELUT_DATA); - if (wr != (num & 0x3ff)) { - pr_info("--->HEVC_IQIT_SCALELUT_WR_ADDR = 0x%x\n", wr); - flag = 0; - break; - } - if (rd != i) { - pr_info("--->HEVC_IQIT_SCALELUT_RD_ADDR = 0x%x\n", rd); - flag = 0; - break; - } - - if (data != 0) { - pr_info("--->HEVC_IQIT_SCALELUT_DATA = 0x%x\n", data); - flag = 0; - break; - } - } - if (flag == 0) - pr_info("-->%d--rdma flail\n", i); - else - pr_info("rdma ok\n"); - return; - -} - -int is_rdma_enable(void) -{ - if (rdma_mode && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) - return 1; - else - return 0; -} -EXPORT_SYMBOL(is_rdma_enable); - -void rdma_front_end_wrok(dma_addr_t ddr_phy_addr, u32 size) -{ - ulong expires; - - WRITE_VREG(HEVC_RDMA_F_CTRL, - (0X0 << 7) | //axi id - (0X7 << 3) | //axi length - (0X0 << 2) | //rdma force cg en - (0X1 << 1)); //rdma path en - WRITE_VREG(HEVC_RDMA_F_START_ADDR, ddr_phy_addr); //rdma start address - WRITE_VREG(HEVC_RDMA_F_END_ADDR, ddr_phy_addr + 0xff); //rdma end address - WRITE_VREG(HEVC_RDMA_F_STATUS0, 0X1); //trigger rdma start to work - - expires = jiffies + msecs_to_jiffies(2000); - while (1) { - if ((READ_VREG(HEVC_RDMA_F_STATUS0) & 0x1) == 0) { - //pr_info("rdma front_end done\n"); - break; - } - if (time_after(jiffies, expires)) { - pr_info("wait rdma done timeout\n"); - break; - } - } - - if (rdma_mode & 0x2) - check_rdma_result(SCALELUT_DATA_WRITE_NUM); - - return; -} -EXPORT_SYMBOL(rdma_front_end_wrok); - -void rdma_back_end_work(dma_addr_t back_ddr_phy_addr, u32 size) -{ - ulong expires; - - WRITE_VREG(HEVC_RDMA_B_CTRL, - (0X0 << 7) | //axi id - (0X7 << 3) | //axi length - (0X0 << 2) | //rdma force cg en - (0X1 << 1)); //rdma path en - WRITE_VREG(HEVC_RDMA_B_START_ADDR, back_ddr_phy_addr); //rdma start address - WRITE_VREG(HEVC_RDMA_B_END_ADDR, back_ddr_phy_addr + size -1); //rdma end address - WRITE_VREG(HEVC_RDMA_B_STATUS0, 0X1); //trigger rdma start to work - - expires = jiffies + msecs_to_jiffies(2000); - while (1) { - if ((READ_VREG(HEVC_RDMA_B_STATUS0) & 0x1) == 0) { - //pr_info("rdma back_end done\n"); - break; - } - if (time_after(jiffies, expires)) { - pr_info("wait rdma done timeout\n"); - break; - } - } - if (rdma_mode & 0x2) - check_rdma_result(SCALELUT_DATA_WRITE_NUM); - - return; -} -EXPORT_SYMBOL(rdma_back_end_work); - RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup); /* uint force_hevc_clock_cntl; @@ -6301,8 +6029,6 @@ module_param(force_nosecure_even_drm, int, 0664); module_param(disable_switch_single_to_mult, int, 0664); -module_param(debug_meta, uint, 0664); - module_param(frameinfo_flag, int, 0664); MODULE_PARM_DESC(frameinfo_flag, "\n frameinfo_flag\n"); @@ -6310,10 +6036,6 @@ MODULE_PARM_DESC(v4lvideo_add_di, "\n v4lvideo_add_di\n"); -module_param(v4lvideo_add_ppmgr, int, 0664); -MODULE_PARM_DESC(v4lvideo_add_ppmgr, - "\n v4lvideo_add_ppmgr\n"); - module_param(max_di_instance, int, 0664); MODULE_PARM_DESC(max_di_instance, "\n max_di_instance\n"); @@ -6321,16 +6043,19 @@ module_param(max_supported_di_instance, int, 0664); MODULE_PARM_DESC(max_supported_di_instance, "\n max_supported_di_instance\n"); + module_param(debug_vdetect, int, 0664); MODULE_PARM_DESC(debug_vdetect, "\n debug_vdetect\n"); +#ifdef VDEC_FCC_SUPPORT +module_param(fcc_debug, int, 0664); +MODULE_PARM_DESC(fcc_debug, "\n fcc_debug\n"); +#endif + module_param(enable_stream_mode_multi_dec, int, 0664); +EXPORT_SYMBOL(enable_stream_mode_multi_dec); MODULE_PARM_DESC(enable_stream_mode_multi_dec, "\n enable multi-decoding on stream mode. \n"); - -module_param(rdma_mode, int, 0664); -MODULE_PARM_DESC(rdma_mode, "\n rdma_enable\n"); - /* *module_init(vdec_module_init); *module_exit(vdec_module_exit);
diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h index a50bdb5..302bfad 100644 --- a/drivers/frame_provider/decoder/utils/vdec.h +++ b/drivers/frame_provider/decoder/utils/vdec.h
@@ -23,7 +23,7 @@ #include <linux/list.h> #include <linux/completion.h> #include <linux/irqreturn.h> -#include <linux/videodev2.h> + #include <linux/amlogic/media/utils/amstream.h> #include <linux/amlogic/media/vfm/vframe.h> #include <linux/amlogic/media/vfm/vframe_provider.h> @@ -37,7 +37,6 @@ #include "vdec_input.h" #include "frame_check.h" #include "vdec_sync.h" -#include "vdec_canvas_utils.h" s32 vdec_dev_register(void); s32 vdec_dev_unregister(void); @@ -57,84 +56,17 @@ #define VDEC_FIFO_ALIGN 8 +#define VDEC_FCC_SUPPORT + enum vdec_type_e { VDEC_1 = 0, VDEC_HCODEC, VDEC_2, VDEC_HEVC, VDEC_HEVCB, - VDEC_WAVE, VDEC_MAX }; -struct trace_decoder_name { - char set_canvas0_addr[32]; - char get_canvas0_addr[32]; - char put_canvas0_addr[32]; - char vf_put_name[32]; - char vf_get_name[32]; - char vdec_name[32]; - char pts_name[32]; - char new_q_name[32]; - char disp_q_name[32]; - char decode_time_name[32]; - char decode_run_time_name[32]; - char decode_header_time_name[32]; - char decode_work_time_name[32]; - char decode_header_memory_time_name[32]; -}; - - -enum e_trace_decoder_status { - DECODER_RUN_START = 1, - DECODER_RUN_END = 2, - DECODER_ISR_HEAD_DONE = 3, - DECODER_ISR_PIC_DONE = 4, - DECODER_ISR_END = 5, - DECODER_ISR_THREAD_HEAD_START = 6, - DECODER_ISR_THREAD_PIC_DONE_START = 7, - DECODER_ISR_THREAD_EDN = 8, - DECODER_WORKER_START = 9, - DECODER_WORKER_END = 10, - DECODER_WORKER_AGAIN = 11, - DECODER_ISR_SEI_DONE = 12, - DECODER_ISR_THREAD_SEI_START = 13, - DECODER_ISR_AUX_DONE = 14, - DECODER_ISR_THREAD_AUX_START = 15, - DECODER_ISR_THREAD_HEAD_END = 16, -}; - -enum e_trace_run_status { - TRACE_RUN_LOADING_FW_START = 1, - TRACE_RUN_LOADING_FW_END = 2, - TRACE_RUN_LOADING_RESTORE_START = 3, - TRACE_RUN_LOADING_RESTORE_END = 4, -}; - -enum e_trace_header_status { - TRACE_HEADER_MEMORY_START = 1, - TRACE_HEADER_MEMORY_END = 2, - TRACE_HEADER_REGISTER_START = 3, - TRACE_HEADER_REGISTER_END = 4, - TRACE_HEADER_RPM_START = 5, - TRACE_HEADER_RPM_END = 6, -}; - -enum e_trace_work_status { - TRACE_WORK_WAIT_SEARCH_DONE_START = 1, - TRACE_WORK_WAIT_SEARCH_DONE_END = 2, -}; - - -#define VDEC_CFG_FLAG_DV_TWOLARYER (1 << 0) -#define VDEC_CFG_FLAG_DV_NEGATIVE (1 << 1) -#define VDEC_CFG_FLAG_DIS_ERR_POLICY (1 << 11) - -#define VDEC_CFG_FLAG_PROG_ONLY (1 << 16) - -#define UVM_META_DATA_VF_BASE_INFOS (1 << 0) -#define UVM_META_DATA_HDR10P_DATA (1 << 1) - #define CORE_MASK_VDEC_1 (1 << VDEC_1) #define CORE_MASK_HCODEC (1 << VDEC_HCODEC) #define CORE_MASK_VDEC_2 (1 << VDEC_2) @@ -143,16 +75,14 @@ #define CORE_MASK_HEVC_BACK (1 << VDEC_HEVCB) #define CORE_MASK_COMBINE (1UL << 31) -#define META_DATA_SIZE (256) - -#define SEI_TYPE (1) -#define DV_TYPE (2) - extern void vdec2_power_mode(int level); extern void vdec_poweron(enum vdec_type_e core); extern void vdec_poweroff(enum vdec_type_e core); extern bool vdec_on(enum vdec_type_e core); extern void vdec_power_reset(void); +extern void vdec_set_dmc_urgent(struct vdec_s *vdec, int urgentType); + + /*irq num as same as .dts*/ @@ -186,6 +116,19 @@ VDEC_NEED_HINT, VDEC_HINTED, }; + +#ifdef VDEC_FCC_SUPPORT +typedef enum { + DISCARD_STATUS = 1, + AGAIN_STATUS, + WAIT_MSG_STATUS, + SWITCHING_STATUS, + JUMP_BACK_STATUS, + SWITCH_DONE_STATUS, + STATUS_BUTT +} FCC_STATUS; +#endif + extern s32 vdec_request_threaded_irq(enum vdec_irq_num num, irq_handler_t handler, irq_handler_t thread_fn, @@ -208,6 +151,7 @@ extern void vdec_vframe_ready(struct vdec_s *vdec, struct vframe_s *vf); extern void vdec_set_vframe_comm(struct vdec_s *vdec, char *n); + struct vdec_s; enum vformat_t; @@ -246,9 +190,6 @@ #define VDEC_NEED_MORE_DATA_DIRTY 0x02 #define VDEC_NEED_MORE_DATA 0x04 -#define SCALELUT_DATA_WRITE_NUM 1024 -#define RDMA_SIZE (1024 * 4 * 4) - struct vdec_s { u32 magic; struct list_head list; @@ -274,7 +215,7 @@ int flag; int sched; int need_more_data; - u32 canvas_mode; //canvas block mode + u32 canvas_mode; struct completion inactive_done; @@ -336,6 +277,9 @@ struct userdata_param_t *puserdata_para); void (*reset_userdata_fifo)(struct vdec_s *vdec, int bInit); void (*wakeup_userdata_poll)(struct vdec_s *vdec); +#ifdef VDEC_FCC_SUPPORT + void (*wakeup_fcc_poll)(struct vdec_s *vdec); +#endif /* private */ void *private; /* decoder per instance specific data */ #ifdef VDEC_DEBUG_SUPPORT @@ -352,7 +296,7 @@ u64 irq_cnt; int parallel_dec; struct vdec_frames_s *mvfrm; - struct vdec_sync *sync; + struct vdec_sync sync; /*aux data check*/ struct aux_data_check_mgr_t adc; @@ -362,90 +306,29 @@ bool hdr10p_data_valid; u32 profile_idc; u32 level_idc; - bool prog_only; - bool disable_vfm; +#ifdef VDEC_FCC_SUPPORT + enum fcc_mode_e fcc_mode; + u32 stream_offset; + int fcc_new_msg; + FCC_STATUS fcc_status; + wait_queue_head_t jump_back_wq; + struct mutex jump_back_mutex; + u32 jump_back_done; + u32 jump_back_error; + u32 jump_back_rp; +#endif + u32 video_id; char name[32]; char dec_spend_time[32]; char dec_spend_time_ave[32]; u32 discard_start_data_flag; - u32 video_id; - int is_v4l; - bool is_stream_mode_dv_multi; - wait_queue_head_t idle_wait; }; -#define CODEC_MODE(a, b, c, d)\ - (((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d)) - -#define META_DATA_MAGIC CODEC_MODE('M', 'E', 'T', 'A') -#define AML_META_HEAD_NUM 8 -#define AML_META_HEAD_SIZE (AML_META_HEAD_NUM * sizeof(u32)) - - -struct aml_meta_head_s { - u32 magic; - u32 type; - u32 data_size; - u32 data[5]; -}; - -struct aml_vf_base_info_s { - u32 width; - u32 height; - u32 duration; - u32 frame_type; - u32 type; - u32 data[12]; -}; - -struct aml_meta_info_s { - union { - struct aml_meta_head_s head; - u32 buf[AML_META_HEAD_NUM]; - }; - u8 data[0]; -}; - -typedef int (*post_task_handler)(void *args); - -struct post_task_mgr_s { - struct list_head task_recycle; - struct task_struct *task; - struct semaphore sem; - struct mutex mutex; - bool running; - void *private; -}; - -struct vdec_post_task_parms_s { - struct list_head recycle; - struct task_struct *task; - struct completion park; - post_task_handler func; - void *private; - int scheduled; -}; - -#define MAX_USERDATA_CHANNEL_NUM 9 - -typedef struct { - struct mutex mutex; - wait_queue_head_t userdata_wait; - u32 video_id; - u32 set_id_flag; - u32 ready_flag[MAX_USERDATA_CHANNEL_NUM]; - int used[MAX_USERDATA_CHANNEL_NUM]; - u32 id[MAX_USERDATA_CHANNEL_NUM]; -} st_userdata; - /* common decoder vframe provider name to use default vfm path */ #define VFM_DEC_PROVIDER_NAME "decoder" #define VFM_DEC_DVBL_PROVIDER_NAME "dvbldec" #define VFM_DEC_DVEL_PROVIDER_NAME "dveldec" -#define VFM_DEC_DVBL_PROVIDER_NAME2 "dvbldec2" -#define VFM_DEC_DVEL_PROVIDER_NAME2 "dveldec2" - #define hw_to_vdec(hw) ((struct vdec_s *) \ (platform_get_drvdata(hw->platform_dev))) @@ -469,24 +352,6 @@ #define vdec_secure(vdec) \ (((vdec)->port_flag & PORT_FLAG_DRM)) -#define PR_INIT(s) \ - int __len = 0, __size = s; \ - u8 __buf[s] = {0} - -#define PR_FILL(args...) \ - do { \ - if ((__size - __len) <= 0) break; \ - __len += snprintf(__buf + __len, \ - __size - __len, ##args); \ - } while (0) - -#define PR_INFO(id) \ - do { \ - if (__len == 0) break; \ - pr_info("[%d] %s\n", id, __buf); \ - __len = 0; \ - } while (0) - /* construct vdec strcture */ extern struct vdec_s *vdec_create(struct stream_port_s *port, struct vdec_s *master); @@ -519,9 +384,6 @@ /* prepare decoder input */ extern int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p); -extern u32 vdec_offset_prepare_input(struct vdec_s *vdec, u32 consume_byte, - u32 data_offset, u32 data_size); - /* clean decoder input */ extern void vdec_clean_input(struct vdec_s *vdec); @@ -560,13 +422,14 @@ extern int vdec_reset(struct vdec_s *vdec); extern int vdec_v4l2_reset(struct vdec_s *vdec, int flag); + extern void vdec_set_status(struct vdec_s *vdec, int status); extern void vdec_set_next_status(struct vdec_s *vdec, int status); extern int vdec_set_decinfo(struct vdec_s *vdec, struct dec_sysinfo *p); -extern int vdec_init(struct vdec_s *vdec, int is_4k, bool is_v4l); +extern int vdec_init(struct vdec_s *vdec, int is_4k); extern void vdec_release(struct vdec_s *vdec); @@ -621,9 +484,7 @@ #ifdef VDEC_DEBUG_SUPPORT extern void vdec_set_step_mode(void); #endif - extern void hevc_mmu_dma_check(struct vdec_s *vdec); - int vdec_read_user_data(struct vdec_s *vdec, struct userdata_param_t *p_userdata_param); @@ -635,6 +496,12 @@ struct vdec_s *vdec_get_vdec_by_id(int vdec_id); +#ifdef VDEC_FCC_SUPPORT +int vdec_wakeup_fcc_poll(struct vdec_s *vdec); +int vdec_has_get_fcc_new_msg(struct vdec_s *vdec); +int fcc_debug_enable(void); +#endif + #ifdef VDEC_DEBUG_SUPPORT extern void vdec_set_step_mode(void); #endif @@ -642,12 +509,12 @@ void VDEC_PRINT_FUN_LINENO(const char *fun, int line); + unsigned char is_mult_inc(unsigned int); int vdec_get_status(struct vdec_s *vdec); void vdec_set_timestamp(struct vdec_s *vdec, u64 timestamp); -void vdec_set_metadata(struct vdec_s *vdec, ulong meta_ptr); extern u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf); @@ -656,13 +523,12 @@ int show_stream_buffer_status(char *buf, int (*callback) (struct stream_buf_s *, char *)); -extern int get_double_write_ratio(int dw_mode); - bool is_support_no_parser(void); +extern u32 timestamp_avsync_counter_get(void); + int vdec_resource_checking(struct vdec_s *vdec); -void set_meta_data_to_vf(struct vframe_s *vf, u32 type, void *v4l2_ctx); void vdec_set_profile_level(struct vdec_s *vdec, u32 profile_idc, u32 level_idc); @@ -670,28 +536,4 @@ void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp); void vdec_config_vld_reg(struct vdec_s *vdec, u32 addr, u32 size); -extern u32 timestamp_avsync_counter_get(void); - -void vdec_canvas_unlock(unsigned long flags); - -unsigned long vdec_canvas_lock(void); - -int vdec_get_core_nr(void); - - -int vdec_post_task(post_task_handler func, void *args); - -void rdma_front_end_wrok(dma_addr_t ddr_phy_addr, u32 size); - -void rdma_back_end_work(dma_addr_t back_ddr_phy_addr, u32 size); - -int is_rdma_enable(void); - -st_userdata *get_vdec_userdata_ctx(void); - -void vdec_frame_rate_uevent(int dur); - -void vdec_sync_irq(enum vdec_irq_num num); - - #endif /* VDEC_H */
diff --git a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c b/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c deleted file mode 100644 index 46fc003..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c +++ /dev/null
@@ -1,415 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec_canvas_utils.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. - * - */ -#include <linux/types.h> -#include "vdec_canvas_utils.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" -#include <linux/amlogic/media/canvas/canvas.h> -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "vdec.h" - -static struct canvas_status_s canvas_stat[CANVAS_MAX_SIZE]; -static struct canvas_status_s mdec_cav_stat[MDEC_CAV_LUT_MAX]; -static struct canvas_config_s *mdec_cav_pool = NULL; - -extern u32 vdec_get_debug(void); - - -bool is_support_vdec_canvas(void) -{ - /* vdec canvas note: - * 1. canvas params config to display, do not use - * vf->canvasxAddr, should use vf->canvasxconfig[]. - * 2. the endian can not config with canvas. and hevc - * core should not config canvas. config endian in - * probe function like h265/vp9/av1/avs2. - */ - if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5W)) - return true; - return false; -} -EXPORT_SYMBOL(is_support_vdec_canvas); - -static int get_canvas(unsigned int index, unsigned int base) -{ - int start; - int canvas_index = index * base; - int ret = 0; - - if ((base > 4) || (base == 0)) - return -1; - - if ((AMVDEC_CANVAS_START_INDEX + canvas_index + base - 1) - <= AMVDEC_CANVAS_MAX1) { - start = AMVDEC_CANVAS_START_INDEX + base * index; - } else { - canvas_index -= (AMVDEC_CANVAS_MAX1 - - AMVDEC_CANVAS_START_INDEX + 1) / base * base; - if (canvas_index <= AMVDEC_CANVAS_MAX2) - start = canvas_index / base; - else - return -1; - } - - if (base == 1) { - ret = start; - } else if (base == 2) { - ret = ((start + 1) << 16) | ((start + 1) << 8) | start; - } else if (base == 3) { - ret = ((start + 2) << 16) | ((start + 1) << 8) | start; - } else if (base == 4) { - ret = (((start + 3) << 24) | (start + 2) << 16) | - ((start + 1) << 8) | start; - } - - return ret; -} - -static int get_canvas_ex(int type, int id) -{ - int i; - unsigned long flags; - - flags = vdec_canvas_lock(); - - for (i = 0; i < CANVAS_MAX_SIZE; i++) { - /*0x10-0x15 has been used by rdma*/ - if ((i >= 0x10) && (i <= 0x15)) - continue; - if ((canvas_stat[i].type == type) && - (canvas_stat[i].id & (1 << id)) == 0) { - canvas_stat[i].canvas_used_flag++; - canvas_stat[i].id |= (1 << id); - if (vdec_get_debug() & 4) - pr_debug("get used canvas %d\n", i); - vdec_canvas_unlock(flags); - if (i < AMVDEC_CANVAS_MAX2 + 1) - return i; - else - return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1); - } - } - - for (i = 0; i < CANVAS_MAX_SIZE; i++) { - /*0x10-0x15 has been used by rdma*/ - if ((i >= 0x10) && (i <= 0x15)) - continue; - if (canvas_stat[i].type == 0) { - canvas_stat[i].type = type; - canvas_stat[i].canvas_used_flag = 1; - canvas_stat[i].id = (1 << id); - if (vdec_get_debug() & 4) { - pr_debug("get canvas %d\n", i); - pr_debug("canvas_used_flag %d\n", - canvas_stat[i].canvas_used_flag); - pr_debug("canvas_stat[i].id %d\n", - canvas_stat[i].id); - } - vdec_canvas_unlock(flags); - if (i < AMVDEC_CANVAS_MAX2 + 1) - return i; - else - return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1); - } - } - vdec_canvas_unlock(flags); - - pr_info("cannot get canvas\n"); - - return -1; -} - -static void free_canvas_ex(int index, int id) -{ - unsigned long flags; - int offset; - - flags = vdec_canvas_lock(); - if (index >= 0 && - index < AMVDEC_CANVAS_MAX2 + 1) - offset = index; - else if ((index >= AMVDEC_CANVAS_START_INDEX) && - (index <= AMVDEC_CANVAS_MAX1)) - offset = index + AMVDEC_CANVAS_MAX2 + 1 - AMVDEC_CANVAS_START_INDEX; - else { - vdec_canvas_unlock(flags); - return; - } - - if ((canvas_stat[offset].canvas_used_flag > 0) && - (canvas_stat[offset].id & (1 << id))) { - canvas_stat[offset].canvas_used_flag--; - canvas_stat[offset].id &= ~(1 << id); - if (canvas_stat[offset].canvas_used_flag == 0) { - canvas_stat[offset].type = 0; - canvas_stat[offset].id = 0; - } - if (vdec_get_debug() & 4) { - pr_debug("free index %d used_flag %d, type = %d, id = %d\n", - offset, - canvas_stat[offset].canvas_used_flag, - canvas_stat[offset].type, - canvas_stat[offset].id); - } - } - vdec_canvas_unlock(flags); - - return; -} - - -static int get_internal_cav_lut(unsigned int index, unsigned int base) -{ - int start; - int canvas_index = index * base; - int ret = 0; - - if ((base > 4) || (base == 0)) - return -1; - - if (canvas_index + base - 1 < MDEC_CAV_LUT_MAX) - start = canvas_index; - else - return -1; - - if (base == 1) { - ret = start; - } else if (base == 2) { - ret = ((start + 1) << 16) | ((start + 1) << 8) | start; - } else if (base == 3) { - ret = ((start + 2) << 16) | ((start + 1) << 8) | start; - } else if (base == 4) { - ret = (((start + 3) << 24) | (start + 2) << 16) | - ((start + 1) << 8) | start; - } - - return ret; -} - -static int get_internal_cav_lut_ex(int type, int id) -{ - int i; - unsigned long flags; - - flags = vdec_canvas_lock(); - - for (i = 0; i < MDEC_CAV_LUT_MAX; i++) { - if ((mdec_cav_stat[i].type == type) && - (mdec_cav_stat[i].id & (1 << id)) == 0) { - mdec_cav_stat[i].canvas_used_flag++; - mdec_cav_stat[i].id |= (1 << id); - if (vdec_get_debug() & 4) - pr_debug("get used cav lut %d\n", i); - vdec_canvas_unlock(flags); - return i; - } - } - - for (i = 0; i < MDEC_CAV_LUT_MAX; i++) { - if (mdec_cav_stat[i].type == 0) { - mdec_cav_stat[i].type = type; - mdec_cav_stat[i].canvas_used_flag = 1; - mdec_cav_stat[i].id = (1 << id); - if (vdec_get_debug() & 4) - pr_debug("get cav lut %d\n", i); - vdec_canvas_unlock(flags); - return i; - } - } - vdec_canvas_unlock(flags); - - pr_info("cannot get cav lut\n"); - - return -1; -} - -static void free_internal_cav_lut(int index, int id) -{ - unsigned long flags; - int offset; - - flags = vdec_canvas_lock(); - if (index > 0 && index < MDEC_CAV_LUT_MAX) - offset = index; - else { - vdec_canvas_unlock(flags); - return; - } - if ((mdec_cav_stat[offset].canvas_used_flag > 0) && - (mdec_cav_stat[offset].id & (1 << id))) { - mdec_cav_stat[offset].canvas_used_flag--; - mdec_cav_stat[offset].id &= ~(1 << id); - if (mdec_cav_stat[offset].canvas_used_flag == 0) { - mdec_cav_stat[offset].type = 0; - mdec_cav_stat[offset].id = 0; - } - if (vdec_get_debug() & 4) { - pr_debug("free index %d used_flag %d, type = %d, id = %d\n", - offset, - mdec_cav_stat[offset].canvas_used_flag, - mdec_cav_stat[offset].type, - mdec_cav_stat[offset].id); - } - } - vdec_canvas_unlock(flags); - - return; -} - -unsigned long vdec_cav_get_addr(int index) -{ - if (index < 0 || index >= MDEC_CAV_LUT_MAX) { - pr_err("%s, error index %d\n", __func__, index); - return -1; - } - - return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].phy_addr; -} -EXPORT_SYMBOL(vdec_cav_get_addr); - -unsigned int vdec_cav_get_width(int index) -{ - if (index < 0 || index >= MDEC_CAV_LUT_MAX) { - pr_err("%s, error index %d\n", __func__, index); - return -1; - } - - return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].width; -} -EXPORT_SYMBOL(vdec_cav_get_width); - -unsigned int vdec_cav_get_height(int index) -{ - if (index < 0 || index >= MDEC_CAV_LUT_MAX) { - pr_err("%s, error index %d\n", __func__, index); - return -1; - } - return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].height; -} -EXPORT_SYMBOL(vdec_cav_get_height); - -void cav_lut_info_store(u32 index, ulong addr, u32 width, - u32 height, u32 wrap, u32 blkmode, u32 endian) -{ - struct canvas_config_s *pool = NULL; - - if (index < 0 || index >= MDEC_CAV_LUT_MAX) { - pr_err("%s, error index %d\n", __func__, index); - return; - } - if (mdec_cav_pool == NULL) - mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s) - * (MDEC_CAV_LUT_MAX + 1)); - - if (mdec_cav_pool == NULL) { - pr_err("%s failed, mdec_cav_pool null\n", __func__); - return; - } - pool = &mdec_cav_pool[index]; - pool->width = width; - pool->height = height; - pool->block_mode = blkmode; - pool->endian = endian; - pool->phy_addr = addr; -} - -void config_cav_lut_ex(u32 index, ulong addr, u32 width, - u32 height, u32 wrap, u32 blkmode, - u32 endian, enum vdec_type_e core) -{ - unsigned long datah_temp, datal_temp; - - if (!is_support_vdec_canvas()) { - canvas_config_ex(index, addr, width, height, wrap, blkmode, endian); - if (vdec_get_debug() & 0x40000000) { - pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n", - __func__, index, addr, width, height, blkmode, endian); - } - } else { - /* - datal_temp = (cav_lut.start_addr & 0x1fffffff) | - ((cav_lut.cav_width & 0x7 ) << 29 ); - datah_temp = ((cav_lut.cav_width >> 3) & 0x1ff) | - (( cav_lut.cav_hight & 0x1fff) <<9 ) | - ((cav_lut.x_wrap_en & 1) << 22 ) | - (( cav_lut.y_wrap_en & 1) << 23) | - (( cav_lut.blk_mode & 0x3) << 24); - */ - u32 addr_bits_l = ((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) << CAV_WADDR_LBIT); - u32 width_l = ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CAV_WIDTH_LBIT); - u32 width_h = ((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) << CAV_WIDTH_HBIT); - u32 height_h = (height & CANVAS_HEIGHT_MASK) << CAV_HEIGHT_HBIT; - u32 blkmod_h = (blkmode & CANVAS_BLKMODE_MASK) << CAV_BLKMODE_HBIT; - u32 switch_bits_ctl = (endian & 0xf) << CAV_ENDIAN_HBIT; - u32 wrap_h = (0 << 23); - datal_temp = addr_bits_l | width_l; - datah_temp = width_h | height_h | wrap_h | blkmod_h | switch_bits_ctl; - - if (core == VDEC_1) { - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T3) && (endian == 7)) - WRITE_VREG(MDEC_CAV_CFG0, 0x1ff << 17); - else - WRITE_VREG(MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode - WRITE_VREG(MDEC_CAV_LUT_DATAL, datal_temp); - WRITE_VREG(MDEC_CAV_LUT_DATAH, datah_temp); - WRITE_VREG(MDEC_CAV_LUT_ADDR, index); - } - - cav_lut_info_store(index, addr, width, height, wrap, blkmode, endian); - - if (vdec_get_debug() & 0x40000000) { - pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n", - __func__, index, addr, width, height, blkmode, endian); - pr_info("data(h,l): 0x%8lx, 0x%8lx\n", datah_temp, datal_temp); - } - } -} -EXPORT_SYMBOL(config_cav_lut_ex); - -void config_cav_lut(int index, struct canvas_config_s *cfg, - enum vdec_type_e core) -{ - config_cav_lut_ex(index, - cfg->phy_addr, - cfg->width, - cfg->height, - CANVAS_ADDR_NOWRAP, - cfg->block_mode, - cfg->endian, - core); -} -EXPORT_SYMBOL(config_cav_lut); - - -void vdec_canvas_port_register(struct vdec_s *vdec) -{ - if (is_support_vdec_canvas()) { - vdec->get_canvas = get_internal_cav_lut; - vdec->get_canvas_ex = get_internal_cav_lut_ex; - vdec->free_canvas_ex = free_internal_cav_lut; - if (mdec_cav_pool == NULL) { - mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s) - * (MDEC_CAV_LUT_MAX + 1)); - } - } else { - vdec->get_canvas = get_canvas; - vdec->get_canvas_ex = get_canvas_ex; - vdec->free_canvas_ex = free_canvas_ex; - } -} -EXPORT_SYMBOL(vdec_canvas_port_register);
diff --git a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h b/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h deleted file mode 100644 index add83cf..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h +++ /dev/null
@@ -1,70 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec_canvas_utils.h - * - * 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. - * - */ -#ifndef __CANVAS_UTILS_H__ -#define __CANVAS_UTILS_H__ - -#include "vdec.h" - -/* external canvas */ -struct canvas_status_s { - int type; - int canvas_used_flag; - int id; -}; - -#define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1) - - -/* internal canvas */ -#define CANVAS_ADDR_LMASK 0x1fffffff -#define CANVAS_WIDTH_LMASK 0x7 -#define CANVAS_WIDTH_LWID 3 -#define CANVAS_HEIGHT_MASK 0x1fff -#define CANVAS_BLKMODE_MASK 3 - -#define CAV_WADDR_LBIT 0 -#define CAV_WIDTH_LBIT 29 -#define CAV_WIDTH_HBIT 0 -#define CAV_HEIGHT_HBIT (41 - 32) -#define CAV_WRAPX_HBIT (54 - 32) -#define CAV_WRAPY_HBIT (55 - 32) -#define CAV_BLKMODE_HBIT (56 - 32) -#define CAV_ENDIAN_HBIT (58 - 32) - -#define MDEC_CAV_LUT_MAX 128 -#define MDEC_CAV_INDEX_MASK 0x7f - -enum vdec_type_e; - -void config_cav_lut(int index, struct canvas_config_s *cfg, enum vdec_type_e core); - -void config_cav_lut_ex(u32 index, ulong addr, u32 width, - u32 height, u32 wrap, u32 blkmode, - u32 endian, enum vdec_type_e core); - -unsigned int vdec_cav_get_width(int index); - -unsigned int vdec_cav_get_height(int index); - -unsigned long vdec_cav_get_addr(int index); - -bool is_support_vdec_canvas(void); - -void vdec_canvas_port_register(struct vdec_s *vdec); - -#endif -
diff --git a/drivers/frame_provider/decoder/utils/vdec_feature.c b/drivers/frame_provider/decoder/utils/vdec_feature.c deleted file mode 100644 index ea3a75d..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_feature.c +++ /dev/null
@@ -1,522 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/amports/amstream_profile.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. - * - */ - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/utils/vformat.h> -#include "../../../common/chips/decoder_cpu_ver_info.h" -#include "vdec.h" - - - -//static const struct codec_profile_t *vcodec_feature[SUPPORT_VDEC_NUM] = { 0 }; - -struct vcodec_feature { - int format; - int is_v4l; -}; - -static struct vcodec_feature feature[SUPPORT_VDEC_NUM]; - -static int vcodec_feature_idx; -static ulong last_time; -u8 buf[4096]; - - -static const char * const format_name[] = { - "ammvdec_mpeg12", - "ammvdec_mpeg4", - "ammvdec_h264", - "ammvdec_mjpeg", - "ammvdec_real", - "ammjpegdec", - "ammvdec_vc1", - "ammvdec_avs", - "ammvdec_yuv", - "ammvdec_h264mvc", - "ammvdec_h264_4k2k", - "ammvdec_h265", - "amvenc_avc", - "jpegenc", - "ammvdec_vp9", - "ammvdec_avs2", - "ammvdec_av1", -}; - -static int vcodec_feature_CC(u8 *buf, int size, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - - if (!is_v4l) { - switch (vformat) { - case VFORMAT_MPEG12: - case VFORMAT_H264: - case VFORMAT_AVS: - pbuf += snprintf(pbuf, size, " \"CC subtitle\" : \"true\"\n"); - break; - default: - break; - } - } - - return pbuf - buf; -} - -static int vcodec_feature_report_information(u8 *buf, int size, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - - if (!is_v4l) { - pbuf += snprintf(pbuf, size, " \"Decoder information report\" : \"true\"\n"); - } - - return pbuf - buf; -} - -static int vcodec_feature_i_only_mode(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_MPEG12: - case VFORMAT_H264: - case VFORMAT_MPEG4: - case VFORMAT_HEVC: - case VFORMAT_AVS2: - pbuf += snprintf(pbuf, size, " \"I only mode\" : \"true\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_dolbyVison(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_H264: - case VFORMAT_HEVC: - case VFORMAT_AV1: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) && - (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_S4)) - pbuf += snprintf(pbuf, size, " \"DolbyVision\" : \"true\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_HDR(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_H264: - case VFORMAT_HEVC: - case VFORMAT_AV1: - case VFORMAT_AVS2: - case VFORMAT_VP9: - pbuf += snprintf(pbuf, size, " \"HDR\" : \"true\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - - -static int vcodec_feature_doublewrite(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - int tsize = 0; - int s; - - switch (vformat) { - case VFORMAT_HEVC: - case VFORMAT_VP9: - case VFORMAT_AVS2: - case VFORMAT_AV1: - s = snprintf(pbuf, size - tsize, " \"DoubleWrite\" "); - tsize += s; - pbuf += s; - if ((get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T7) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T3)) { - s = snprintf(pbuf, size - tsize, "[ \"0\", \"1\", \"2\", \"3\", \"4\", \"0x10\", \"0x10000\", \"0x20000\"]\n"); - tsize += s; - pbuf += s; - } - else { - s = snprintf(pbuf, size - tsize, "[ \"0\", \"1\", \"2\", \"3\", \"4\", \"8\", \"0x10\", \"0x10000\", \"0x20000\"]\n"); - tsize += s; - pbuf += s; - } - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_vdec_fence(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_H264: - case VFORMAT_HEVC: - case VFORMAT_VP9: - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) - pbuf += snprintf(pbuf, size, " \"GameMode\" : \"true\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_bitdepth(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_HEVC: - case VFORMAT_VP9: - case VFORMAT_AVS2: - case VFORMAT_AV1: - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) - pbuf += snprintf(pbuf, size, " \"BitDepth\" : \"10\"\n"); - else - pbuf += snprintf(pbuf, size, " \"BitDepth\" : \"8\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - - -static int vcodec_feature_MaxResolution(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_HEVC: - case VFORMAT_VP9: - case VFORMAT_AVS2: - case VFORMAT_AV1: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"8k\"\n"); - else if (vdec_is_support_4k() && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"4k60\"\n"); - else - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n"); - break; - case VFORMAT_H264: - if (vdec_is_support_4k()) - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"4k30\"\n"); - else - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n"); - break; - case VFORMAT_MPEG12: - case VFORMAT_MPEG4: - case VFORMAT_MJPEG: - case VFORMAT_VC1: - case VFORMAT_AVS: - pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_clock(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - switch (vformat) { - case VFORMAT_HEVC: - case VFORMAT_VP9: - case VFORMAT_AVS2: - case VFORMAT_AV1: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12B) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_GXLX2) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) - pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"800MHZ\"\n"); - else - pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"667MHZ\"\n"); - break; - case VFORMAT_H264: - case VFORMAT_MPEG12: - case VFORMAT_MPEG4: - case VFORMAT_MJPEG: - case VFORMAT_VC1: - case VFORMAT_AVS: - 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_GXLX2) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) - pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"800MHZ\"\n"); - else - pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"667MHZ\"\n"); - break; - default: - break; - } - - return pbuf - buf; -} - -static int vcodec_feature_support_format(int vformat) -{ - - switch (vformat) { - case VFORMAT_VP9: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5)) - return 1; - else - return 0; - case VFORMAT_AVS2: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) - return 1; - else - return 0; - case VFORMAT_AV1: - if (((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && - is_cpu_tm2_revb()) || - ((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5))) - return 1; - else - return 0; - case VFORMAT_AVS: - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)) - return 1; - else - return 0; - case VFORMAT_MJPEG: - case VFORMAT_VC1: - case VFORMAT_MPEG4: - case VFORMAT_MPEG12: - case VFORMAT_H264: - case VFORMAT_HEVC: - return 1; - default: - break; - } - - return 0; -} - -static int vcodec_feature_FCC(u8 *buf, int size, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - - if (!is_v4l) { - switch (vformat) { - case VFORMAT_HEVC: - case VFORMAT_H264: - case VFORMAT_MPEG12: - pbuf += snprintf(pbuf, size, " \"Decoder FCC support\" : \"true\"\n"); - break; - default: - break; - } - } - - return pbuf - buf; -} - -static int vcodec_feature_RDMA(u8 *buf, int size, int vformat) -{ - u8 *pbuf = buf; - - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) - pbuf += snprintf(pbuf, size, " \"Decoder RDMA support\" : \"true\"\n"); - - return pbuf - buf; -} - -static int vcodec_feature_v4ldec_nr(u8 *buf, int size, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - - if (is_v4l) { - pbuf += snprintf(pbuf, size, " \"V4ldec nr\" : \"true\"\n"); - } - - return pbuf - buf; -} - -static int vcodec_feature_ge2d_wrapper(u8 *buf, int size, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - - if (is_v4l && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)) { - pbuf += snprintf(pbuf, size, " \"Ge2d wrapper\" : \"true\"\n"); - } - - return pbuf - buf; -} - - - -int vcodec_feature_get_feature(u8 *buf, int vformat, int is_v4l) -{ - u8 *pbuf = buf; - int size = PAGE_SIZE; - int tsize = 0; - int s; - - s = snprintf(pbuf, size - tsize, " \"%s%s\": ", format_name[vformat], is_v4l ? "_v4l" : ""); - tsize += s; - pbuf += s; - - s = snprintf(pbuf, size - tsize, "{\n"); - tsize += s; - pbuf += s; - - s = vcodec_feature_CC(pbuf, size - tsize, vformat, is_v4l); - tsize += s; - pbuf += s; - - s = vcodec_feature_report_information(pbuf, size - tsize, vformat, is_v4l); - tsize += s; - pbuf += s; - - s = vcodec_feature_vdec_fence(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_i_only_mode(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_dolbyVison(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_HDR(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_doublewrite(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_bitdepth(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_MaxResolution(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_clock(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_FCC(pbuf, size - tsize, vformat, is_v4l); - tsize += s; - pbuf += s; - - s = vcodec_feature_RDMA(pbuf, size - tsize, vformat); - tsize += s; - pbuf += s; - - s = vcodec_feature_v4ldec_nr(pbuf, size - tsize, vformat, is_v4l); - tsize += s; - pbuf += s; - - s = vcodec_feature_ge2d_wrapper(pbuf, size - tsize, vformat, is_v4l); - tsize += s; - pbuf += s; - - s = snprintf(pbuf, size - tsize, " \"UcodeVersionRequest\" : \"0.3.10\"\n"); - tsize += s; - pbuf += s; - - s = snprintf(pbuf, size - tsize, " }\n"); - tsize += s; - pbuf += s; - - return pbuf - buf; -} - - -ssize_t vcodec_feature_read(char *buf) -{ - static int read_count; - char *pbuf = buf; - - if (jiffies - last_time > 5 * HZ) { - read_count = 0; - /*timeout :not continue dump,dump from first. */ - } - - if (vcodec_feature_idx > 0) { - if (read_count == 0) - pbuf += snprintf(pbuf, PAGE_SIZE - (pbuf - buf), "{\n"); - pbuf += vcodec_feature_get_feature(pbuf, feature[read_count].format, feature[read_count].is_v4l); - read_count++; - if (read_count >= vcodec_feature_idx) { - read_count = 0; - pbuf += snprintf(pbuf, PAGE_SIZE - (pbuf - buf), "}"); - } - } - last_time = jiffies; - return pbuf - buf; -} -EXPORT_SYMBOL(vcodec_feature_read); - - -int vcodec_feature_register(int vformat, int is_v4l) -{ - if ((vcodec_feature_idx < SUPPORT_VDEC_NUM) && vcodec_feature_support_format(vformat)) { - feature[vcodec_feature_idx].format = vformat; - feature[vcodec_feature_idx].is_v4l = is_v4l; - vcodec_feature_idx++; - //pr_debug("regist %s codec profile\n", vdec_profile->name); - } - - return 0; -} -EXPORT_SYMBOL(vcodec_feature_register); - - -
diff --git a/drivers/frame_provider/decoder/utils/vdec_feature.h b/drivers/frame_provider/decoder/utils/vdec_feature.h deleted file mode 100644 index a2918fd..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_feature.h +++ /dev/null
@@ -1,27 +0,0 @@ -/* - * drivers/amlogic/amports/vdec_profile.h - * - * 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. - * -*/ - -#ifndef VDEC_FEATURE_H -#define VDEC_FEATURE_H - -int vcodec_feature_register(int vformat, int is_v4l); - -ssize_t vcodec_feature_read(char *buf); - - - -#endif /* VDEC_FEATURE_H */
diff --git a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c b/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c deleted file mode 100644 index 08cd0d7..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c +++ /dev/null
@@ -1,487 +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/types.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/amlogic/media/ge2d/ge2d.h> -#include <linux/amlogic/media/canvas/canvas_mgr.h> -#include "vdec.h" -#include "vdec_ge2d_utils.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" - -static u32 vdec_ge2d_debug = 0; - -#ifndef CONFIG_AMLOGIC_MEDIA_GE2D -inline struct ge2d_context_s *create_ge2d_work_queue(void) { return NULL; } -inline int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { return -1; } -#endif - -enum videocom_source_type { - DECODER_8BIT_NORMAL = 0, - DECODER_8BIT_BOTTOM, - DECODER_8BIT_TOP, - DECODER_10BIT_NORMAL, - DECODER_10BIT_BOTTOM, - DECODER_10BIT_TOP -}; - -static void vdec_canvas_cache_free(struct vdec_canvas_cache *canche) -{ - int i = -1; - - for (i = 0; i < ARRAY_SIZE(canche->res); i++) { - if (canche->res[i].cid > 0) { - if (vdec_ge2d_debug) - pr_info("canvas-free, name:%s, canvas id:%d\n", - canche->res[i].name, - canche->res[i].cid); - - canvas_pool_map_free_canvas(canche->res[i].cid); - - canche->res[i].cid = 0; - } - } -} - -static void vdec_canvas_cache_put(struct vdec_ge2d *ge2d) -{ - struct vdec_canvas_cache *canche = &ge2d->canche; - - mutex_lock(&canche->lock); - - pr_info("canvas-put, ref:%d\n", canche->ref); - - canche->ref--; - - if (canche->ref == 0) { - vdec_canvas_cache_free(canche); - } - - mutex_unlock(&canche->lock); -} - -static int vdec_canvas_cache_get(struct vdec_ge2d *ge2d, char *usr) -{ - struct vdec_canvas_cache *canche = &ge2d->canche; - int i; - - mutex_lock(&canche->lock); - - canche->ref++; - - for (i = 0; i < ARRAY_SIZE(canche->res); i++) { - if (canche->res[i].cid <= 0) { - snprintf(canche->res[i].name, 32, "%s-%d", usr, i); - canche->res[i].cid = - canvas_pool_map_alloc_canvas(canche->res[i].name); - } - - if (vdec_ge2d_debug) - pr_info("canvas-alloc, name:%s, canvas id:%d\n", - canche->res[i].name, - canche->res[i].cid); - - if (canche->res[i].cid <= 0) { - pr_err("canvas-fail, name:%s, canvas id:%d.\n", - canche->res[i].name, - canche->res[i].cid); - - mutex_unlock(&canche->lock); - goto err; - } - } - - if (vdec_ge2d_debug) - pr_info("canvas-get, ref:%d\n", canche->ref); - - mutex_unlock(&canche->lock); - return 0; -err: - vdec_canvas_cache_put(ge2d); - return -1; -} - -static int vdec_canvas_cache_init(struct vdec_ge2d *ge2d) -{ - ge2d->canche.ref = 0; - mutex_init(&ge2d->canche.lock); - - pr_info("canvas-init, ref:%d\n", ge2d->canche.ref); - - return 0; -} - -static int get_source_type(struct vframe_s *vf) -{ - enum videocom_source_type ret; - int interlace_mode; - - interlace_mode = vf->type & VIDTYPE_TYPEMASK; - - if ((vf->bitdepth & BITDEPTH_Y10) && - (!(vf->type & VIDTYPE_COMPRESS)) && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) { - if (interlace_mode == VIDTYPE_INTERLACE_TOP) - ret = DECODER_10BIT_TOP; - else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM) - ret = DECODER_10BIT_BOTTOM; - else - ret = DECODER_10BIT_NORMAL; - } else { - if (interlace_mode == VIDTYPE_INTERLACE_TOP) - ret = DECODER_8BIT_TOP; - else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM) - ret = DECODER_8BIT_BOTTOM; - else - ret = DECODER_8BIT_NORMAL; - } - - return ret; -} - -static int get_input_format(struct vframe_s *vf) -{ - int format = GE2D_FORMAT_M24_YUV420; - enum videocom_source_type soure_type; - - soure_type = get_source_type(vf); - - switch (soure_type) { - case DECODER_8BIT_NORMAL: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422; - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21; - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12; - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444; - else - format = GE2D_FORMAT_M24_YUV420; - break; - case DECODER_8BIT_BOTTOM: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422 - | (GE2D_FORMAT_S16_YUV422B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21 - | (GE2D_FORMAT_M24_NV21B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12 - | (GE2D_FORMAT_M24_NV12B & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444 - | (GE2D_FORMAT_S24_YUV444B & (3 << 3)); - else - format = GE2D_FORMAT_M24_YUV420 - | (GE2D_FMT_M24_YUV420B & (3 << 3)); - break; - case DECODER_8BIT_TOP: - if (vf->type & VIDTYPE_VIU_422) - format = GE2D_FORMAT_S16_YUV422 - | (GE2D_FORMAT_S16_YUV422T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV21) - format = GE2D_FORMAT_M24_NV21 - | (GE2D_FORMAT_M24_NV21T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_NV12) - format = GE2D_FORMAT_M24_NV12 - | (GE2D_FORMAT_M24_NV12T & (3 << 3)); - else if (vf->type & VIDTYPE_VIU_444) - format = GE2D_FORMAT_S24_YUV444 - | (GE2D_FORMAT_S24_YUV444T & (3 << 3)); - else - format = GE2D_FORMAT_M24_YUV420 - | (GE2D_FMT_M24_YUV420T & (3 << 3)); - break; - case DECODER_10BIT_NORMAL: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422; - else - format = GE2D_FORMAT_S16_12BIT_YUV422; - } - break; - case DECODER_10BIT_BOTTOM: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422 - | (GE2D_FORMAT_S16_10BIT_YUV422B - & (3 << 3)); - else - format = GE2D_FORMAT_S16_12BIT_YUV422 - | (GE2D_FORMAT_S16_12BIT_YUV422B - & (3 << 3)); - } - break; - case DECODER_10BIT_TOP: - if (vf->type & VIDTYPE_VIU_422) { - if (vf->bitdepth & FULL_PACK_422_MODE) - format = GE2D_FORMAT_S16_10BIT_YUV422 - | (GE2D_FORMAT_S16_10BIT_YUV422T - & (3 << 3)); - else - format = GE2D_FORMAT_S16_12BIT_YUV422 - | (GE2D_FORMAT_S16_12BIT_YUV422T - & (3 << 3)); - } - break; - default: - format = GE2D_FORMAT_M24_YUV420; - } - return format; -} - -int vdec_ge2d_init(struct vdec_ge2d** ge2d_handle, int mode) -{ - int ret; - struct vdec_ge2d *ge2d; - - if (!ge2d_handle) - return -EINVAL; - - ge2d = kzalloc(sizeof(*ge2d), GFP_KERNEL); - if (!ge2d) - return -ENOMEM; - - vdec_canvas_cache_init(ge2d); - - ge2d->work_mode = mode; - if (!ge2d->work_mode) { - ge2d->work_mode = GE2D_MODE_CONVERT_LE; - } - pr_info("vdec_ge2d_init work_mode:%d\n", ge2d->work_mode); - - ge2d->ge2d_context = create_ge2d_work_queue(); - if (!ge2d->ge2d_context) { - pr_err("ge2d_create_instance fail\n"); - ret = -EINVAL; - goto error; - } - - if (vdec_canvas_cache_get(ge2d, "vdec-ge2d-dec") < 0) { - pr_err("canvas pool alloc fail. src(%d, %d, %d) dst(%d, %d, %d).\n", - ge2d->canche.res[0].cid, - ge2d->canche.res[1].cid, - ge2d->canche.res[2].cid, - ge2d->canche.res[3].cid, - ge2d->canche.res[4].cid, - ge2d->canche.res[5].cid); - ret = -ENOMEM; - goto error1; - } - - *ge2d_handle = ge2d; - - return 0; -error1: - destroy_ge2d_work_queue(ge2d->ge2d_context); -error: - kfree(ge2d); - - return ret; -} -EXPORT_SYMBOL(vdec_ge2d_init); - -int vdec_ge2d_copy_data(struct vdec_ge2d *ge2d, struct vdec_ge2d_info *ge2d_info) -{ - struct config_para_ex_s ge2d_config; - u32 src_fmt = 0, dst_fmt = 0; - struct canvas_s cd; - - if (!ge2d) - return -1; - - if (vdec_ge2d_debug) - pr_info("vdec_ge2d_copy_data start\n"); - - memset(&ge2d_config, 0, sizeof(ge2d_config)); - - src_fmt = get_input_format(ge2d_info->dst_vf); - if (ge2d_info->src_canvas0_config[0].endian == 7) - src_fmt |= GE2D_BIG_ENDIAN; - else - src_fmt |= GE2D_LITTLE_ENDIAN; - - /* negotiate format of destination */ - dst_fmt = get_input_format(ge2d_info->dst_vf); - if (ge2d->work_mode & GE2D_MODE_CONVERT_NV12) - dst_fmt |= GE2D_FORMAT_M24_NV12; - else if (ge2d->work_mode & GE2D_MODE_CONVERT_NV21) - dst_fmt |= GE2D_FORMAT_M24_NV21; - - if (ge2d->work_mode & GE2D_MODE_CONVERT_LE) - dst_fmt |= GE2D_LITTLE_ENDIAN; - else - dst_fmt |= GE2D_BIG_ENDIAN; - - if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV12) { - ge2d_info->dst_vf->type |= VIDTYPE_VIU_NV12; - ge2d_info->dst_vf->type &= ~VIDTYPE_VIU_NV21; - } else if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV21) { - ge2d_info->dst_vf->type |= VIDTYPE_VIU_NV21; - ge2d_info->dst_vf->type &= ~VIDTYPE_VIU_NV12; - } - if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_LITTLE_ENDIAN) { - ge2d_info->dst_vf->canvas0_config[0].endian = 0; - ge2d_info->dst_vf->canvas0_config[1].endian = 0; - ge2d_info->dst_vf->canvas0_config[2].endian = 0; - } else if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_BIG_ENDIAN){ - ge2d_info->dst_vf->canvas0_config[0].endian = 7; - ge2d_info->dst_vf->canvas0_config[1].endian = 7; - ge2d_info->dst_vf->canvas0_config[2].endian = 7; - } - - ge2d_info->dst_vf->mem_sec = ge2d_info->dst_vf->flag & VFRAME_FLAG_VIDEO_SECURE ? 1 : 0; - - mutex_lock(&ge2d->canche.lock); - - /* src canvas configure. */ - if ((ge2d_info->dst_vf->canvas0Addr == 0) || - (ge2d_info->dst_vf->canvas0Addr == (u32)-1)) { - canvas_config_config(ge2d->canche.res[0].cid, &ge2d_info->src_canvas0_config[0]); - canvas_config_config(ge2d->canche.res[1].cid, &ge2d_info->src_canvas0_config[1]); - canvas_config_config(ge2d->canche.res[2].cid, &ge2d_info->src_canvas0_config[2]); - ge2d_config.src_para.canvas_index = - ge2d->canche.res[0].cid | - ge2d->canche.res[1].cid << 8 | - ge2d->canche.res[2].cid << 16; - - ge2d_config.src_planes[0].addr = - ge2d_info->src_canvas0_config[0].phy_addr; - ge2d_config.src_planes[0].w = - ge2d_info->src_canvas0_config[0].width; - ge2d_config.src_planes[0].h = - ge2d_info->src_canvas0_config[0].height; - ge2d_config.src_planes[1].addr = - ge2d_info->src_canvas0_config[1].phy_addr; - ge2d_config.src_planes[1].w = - ge2d_info->src_canvas0_config[1].width; - ge2d_config.src_planes[1].h = - ge2d_info->src_canvas0_config[1].height; - ge2d_config.src_planes[2].addr = - ge2d_info->src_canvas0_config[2].phy_addr; - ge2d_config.src_planes[2].w = - ge2d_info->src_canvas0_config[2].width; - ge2d_config.src_planes[2].h = - ge2d_info->src_canvas0_config[2].height; - } else { - ge2d_config.src_para.canvas_index = ge2d_info->src_canvas0Addr; - } - ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.src_para.format = src_fmt; - ge2d_config.src_para.fill_color_en = 0; - ge2d_config.src_para.fill_mode = 0; - ge2d_config.src_para.x_rev = 0; - ge2d_config.src_para.y_rev = 0; - ge2d_config.src_para.color = 0xffffffff; - ge2d_config.src_para.top = 0; - ge2d_config.src_para.left = 0; - ge2d_config.src_para.width = ge2d_info->dst_vf->width; - if (ge2d_info->dst_vf->type & VIDTYPE_INTERLACE) - ge2d_config.src_para.height = ge2d_info->dst_vf->height >> 1; - else - ge2d_config.src_para.height = ge2d_info->dst_vf->height; - - /* dst canvas configure. */ - canvas_config_config(ge2d->canche.res[3].cid, &ge2d_info->dst_vf->canvas0_config[0]); - if ((ge2d_config.src_para.format & 0xfffff) == GE2D_FORMAT_M24_YUV420) { - ge2d_info->dst_vf->canvas0_config[1].width <<= 1; - } - canvas_config_config(ge2d->canche.res[4].cid, &ge2d_info->dst_vf->canvas0_config[1]); - canvas_config_config(ge2d->canche.res[5].cid, &ge2d_info->dst_vf->canvas0_config[2]); - ge2d_config.dst_para.canvas_index = - ge2d->canche.res[3].cid | - ge2d->canche.res[4].cid << 8; - canvas_read(ge2d->canche.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->canche.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; - - ge2d_config.dst_para.format = dst_fmt; - ge2d_config.dst_para.width = ge2d_info->dst_vf->width; - ge2d_config.dst_para.height = ge2d_info->dst_vf->height; - ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.dst_para.fill_color_en = 0; - ge2d_config.dst_para.fill_mode = 0; - ge2d_config.dst_para.x_rev = 0; - ge2d_config.dst_para.y_rev = 0; - ge2d_config.dst_para.color = 0; - ge2d_config.dst_para.top = 0; - ge2d_config.dst_para.left = 0; - - /* other ge2d parameters configure. */ - ge2d_config.src_key.key_enable = 0; - ge2d_config.src_key.key_mask = 0; - ge2d_config.src_key.key_mode = 0; - ge2d_config.alu_const_color = 0; - ge2d_config.bitmask_en = 0; - 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 = ge2d_info->dst_vf->flag & VFRAME_FLAG_VIDEO_SECURE ? 1 : 0; - - if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) { - pr_err("vdec_ge2d_context_config_ex error.\n"); - mutex_unlock(&ge2d->canche.lock); - return -1; - } - - if (!(ge2d_info->dst_vf->type & VIDTYPE_V4L_EOS)) { - if (ge2d_info->dst_vf->type & VIDTYPE_INTERLACE) { - stretchblt_noalpha(ge2d->ge2d_context, - 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height / 2, - 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height); - } else { - stretchblt_noalpha(ge2d->ge2d_context, - 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height, - 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height); - } - } - mutex_unlock(&ge2d->canche.lock); - if (vdec_ge2d_debug) - pr_info("vdec_ge2d_copy_data done\n"); - - return 0; -} -EXPORT_SYMBOL(vdec_ge2d_copy_data); - -int vdec_ge2d_destroy(struct vdec_ge2d *ge2d) -{ - if (!ge2d) - return -1; - - pr_info("vdec ge2d destroy begin\n"); - - destroy_ge2d_work_queue(ge2d->ge2d_context); - vdec_canvas_cache_put(ge2d); - kfree(ge2d); - - pr_info("vdec ge2d destroy done\n"); - - return 0; -} -EXPORT_SYMBOL(vdec_ge2d_destroy); - -module_param(vdec_ge2d_debug, int, 0664); -MODULE_PARM_DESC(vdec_ge2d_debug, "\n vdec_ge2d_debug\n");
diff --git a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h b/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h deleted file mode 100644 index 31018f7..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h +++ /dev/null
@@ -1,69 +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 __GE2D_UTILS_H__ -#define __GE2D_UTILS_H__ - -//#include "../../../amvdec_ports/aml_vcodec_drv.h" -#include <linux/amlogic/media/vfm/vframe.h> - - -/* define ge2d work mode. */ -#define GE2D_MODE_CONVERT_NV12 (1 << 0) -#define GE2D_MODE_CONVERT_NV21 (1 << 1) -#define GE2D_MODE_CONVERT_LE (1 << 2) -#define GE2D_MODE_CONVERT_BE (1 << 3) -#define GE2D_MODE_SEPARATE_FIELD (1 << 4) -#define GE2D_MODE_422_TO_420 (1 << 5) - -struct vdec_canvas_res { - int cid; - u8 name[32]; -}; - -struct vdec_canvas_cache { - int ref; - struct vdec_canvas_res res[6]; - struct mutex lock; -}; - -struct vdec_ge2d { - u32 work_mode; /* enum ge2d_work_mode */ - struct ge2d_context_s *ge2d_context; /* handle of GE2D */ - struct aml_vcodec_ctx *ctx; - struct vdec_canvas_cache canche; - void *hw; -}; - -struct vdec_ge2d_info { - struct vframe_s *dst_vf; - u32 src_canvas0Addr; - u32 src_canvas1Addr;; - struct canvas_config_s src_canvas0_config[3]; - struct canvas_config_s src_canvas1_config[3]; -}; - -int vdec_ge2d_init(struct vdec_ge2d** ge2d_handle, int mode); - -int vdec_ge2d_copy_data(struct vdec_ge2d *ge2d, struct vdec_ge2d_info *ge2d_info); - -int vdec_ge2d_destroy(struct vdec_ge2d *ge2d); - -#endif -
diff --git a/drivers/frame_provider/decoder/utils/vdec_input.c b/drivers/frame_provider/decoder/utils/vdec_input.c index 6fec0ad..5deb374 100644 --- a/drivers/frame_provider/decoder/utils/vdec_input.c +++ b/drivers/frame_provider/decoder/utils/vdec_input.c
@@ -20,12 +20,15 @@ #include <linux/slab.h> #include <linux/dma-mapping.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> + #include "../../../stream_input/amports/amports_priv.h" #include "vdec.h" #include "vdec_input.h" + #include <asm/cacheflush.h> #include <linux/crc32.h> + #define VFRAME_BLOCK_SIZE (512 * SZ_1K)/*512 for 1080p default init.*/ #define VFRAME_BLOCK_SIZE_4K (2 * SZ_1M) /*2M for 4K default.*/ #define VFRAME_BLOCK_SIZE_MAX (4 * SZ_1M) @@ -61,7 +64,7 @@ { int ret =0; - if (likely(access_ok(from, n))) + if (likely(access_ok(VERIFY_READ, from, n))) ret = copy_from_user(to, from, n); else memcpy(to, from, n); @@ -345,7 +348,6 @@ char sbuf[512]; int tsize = 0; int s; - if (!pbuf) { pbuf = sbuf; size = 512; @@ -432,7 +434,6 @@ s += vdec_input_dump_block_locked(block, lbuf, size - s); } vdec_input_unlock(input, flags); - return s; } @@ -445,7 +446,6 @@ char sbuf[512]; int tsize = 0; int s; - if (!pbuf) { pbuf = sbuf; size = 512; @@ -492,7 +492,6 @@ if (size <= 0) return 0; - if (!bufs) lbuf = sbuf; s = snprintf(lbuf + s, size - s, @@ -523,7 +522,6 @@ break; } vdec_input_unlock(input, flags); - return s; } @@ -551,7 +549,6 @@ if (input->swap_page_phys == 0) return -ENOMEM; - return 0; } EXPORT_SYMBOL(vdec_input_set_buffer); @@ -791,7 +788,6 @@ struct vframe_chunk_s *chunk; struct vdec_s *vdec = input->vdec; struct vframe_block_list_s *block; - int need_pading_size = MIN_FRAME_PADDING_SIZE; if (vdec_secure(vdec)) { @@ -1216,3 +1212,5 @@ return handle; } EXPORT_SYMBOL(vdec_input_get_freed_handle); + +
diff --git a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c index e43c45a..9057a80 100644 --- a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c +++ b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c
@@ -19,10 +19,8 @@ #include "vdec_power_ctrl.h" #include <linux/amlogic/media/utils/vdec_reg.h> #include <linux/amlogic/power_ctrl.h> -//#include <dt-bindings/power/sc2-pd.h> -//#include <linux/amlogic/pwr_ctrl.h> -#include <linux/amlogic/power_domain.h> #include <dt-bindings/power/sc2-pd.h> +#include <linux/amlogic/pwr_ctrl.h> #include <linux/amlogic/media/codec_mm/codec_mm.h> #include "../../../common/media_clock/switch/amports_gate.h" #include "../../../common/chips/decoder_cpu_ver_info.h" @@ -31,12 +29,6 @@ #define HEVC_TEST_LIMIT (100) #define GXBB_REV_A_MINOR (0xa) -#define PDID_DSP 0 -#define PDID_DOS_HCODEC 1 -#define PDID_DOS_HEVC 2 -#define PDID_DOS_VDEC 3 -#define PDID_DOS_WAVE 4 - extern int no_powerdown; extern int hevc_max_reset_count; @@ -144,20 +136,14 @@ hcodec_clock_enable(); } else if (id == VDEC_HEVC) { /* enable hevc clock */ - 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)) + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) amports_switch_gate("clk_hevcf_mux", 1); else amports_switch_gate("clk_hevc_mux", 1); - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - !is_hevc_front_back_clk_combined()) + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) amports_switch_gate("clk_hevcb_mux", 1); - hevc_clock_hi_enable(); - - if (!is_hevc_front_back_clk_combined()) - hevc_back_clock_hi_enable(); + hevc_back_clock_hi_enable(); } } @@ -170,8 +156,7 @@ } else if (id == VDEC_HEVC) { /* disable hevc clock */ hevc_clock_off(); - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - !is_hevc_front_back_clk_combined()) + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) hevc_back_clock_off(); } } @@ -708,6 +693,7 @@ pm_vdec_clock_on(id); pwr_ctrl_psci_smc(pd_id, PWR_ON); + } static void pm_vdec_pd_sec_api_power_off(struct device *dev, int id) @@ -734,7 +720,7 @@ #if 0 int pd_id = (id == VDEC_1) ? PM_DOS_VDEC : (id == VDEC_HEVC) ? PM_DOS_HEVC : - PM_DOS_HCODEC; + PM_DOS_HCODEC; pm_vdec_clock_on(id); power_domain_switch(pd_id, PWR_ON);
diff --git a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h index e7ab77e..53545f8 100644 --- a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h +++ b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h
@@ -90,10 +90,10 @@ #define DL_FLAG_RPM_ACTIVE BIT(3) #define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4) -struct device_link { - u32 flags; - /* ... */ -}; +//struct device_link { +// u32 flags; +// /* ... */ +//}; static inline struct device *dev_pm_domain_attach_by_name(struct device *dev, const char *name)
diff --git a/drivers/frame_provider/decoder/utils/vdec_profile.c b/drivers/frame_provider/decoder/utils/vdec_profile.c index dfffeb1..94f8b8f 100644 --- a/drivers/frame_provider/decoder/utils/vdec_profile.c +++ b/drivers/frame_provider/decoder/utils/vdec_profile.c
@@ -20,12 +20,14 @@ #include <linux/types.h> #include <linux/debugfs.h> #include <linux/moduleparam.h> -#include <linux/sched/clock.h> + + #include <linux/amlogic/media/utils/vdec_reg.h> #include <trace/events/meson_atrace.h> #include "vdec_profile.h" #include "vdec.h" + #define ISA_TIMERE 0x2662 #define ISA_TIMERE_HI 0x2663 @@ -110,7 +112,11 @@ static u64 get_us_time_system(void) { - return div64_u64(local_clock(), 1000); + struct timeval tv; + + do_gettimeofday(&tv); + + return div64_u64(timeval_to_ns(&tv), 1000); } static void vdec_profile_update_alloc_time(
diff --git a/drivers/frame_provider/decoder/utils/vdec_sync.c b/drivers/frame_provider/decoder/utils/vdec_sync.c index b4192f6..314a4f0 100644 --- a/drivers/frame_provider/decoder/utils/vdec_sync.c +++ b/drivers/frame_provider/decoder/utils/vdec_sync.c
@@ -21,24 +21,15 @@ #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/slab.h> -#include <linux/sched/clock.h> #include <linux/sync_file.h> #include "vdec_sync.h" #define VDEC_DBG_ENABLE_FENCE (0x100) -#define VDEC_SYNC_COUNT 32 -struct vdec_sync_core_s { - struct vdec_sync s_vdec_sync[VDEC_SYNC_COUNT]; - spinlock_t vdec_sync_lock; -}; +extern u32 debug; -static struct vdec_sync_core_s vdec_sync_core; - -extern u32 vdec_get_debug(void); - -static const struct dma_fence_ops timeline_fence_ops; -static inline struct sync_pt *fence_to_sync_pt(struct dma_fence *fence) +static const struct fence_ops timeline_fence_ops; +static inline struct sync_pt *fence_to_sync_pt(struct fence *fence) { if (fence->ops != &timeline_fence_ops) return NULL; @@ -61,7 +52,7 @@ return NULL; kref_init(&obj->kref); - obj->context = dma_fence_context_alloc(1); + obj->context = fence_context_alloc(1); obj->timestamp = local_clock(); strlcpy(obj->name, name, sizeof(obj->name)); INIT_LIST_HEAD(&obj->active_list_head); @@ -75,12 +66,9 @@ { struct sync_timeline *obj = container_of(kref, struct sync_timeline, kref); - struct vdec_sync *sync = obj->parent_sync; pr_info("[VDEC-FENCE] free timeline: %lx\n", (ulong) obj); kfree(obj); - atomic_set(&sync->use_flag, 0); - sync->timeline = NULL; } static void sync_timeline_get(struct sync_timeline *obj) @@ -93,21 +81,21 @@ kref_put(&obj->kref, sync_timeline_free); } -static const char *timeline_fence_get_driver_name(struct dma_fence *fence) +static const char *timeline_fence_get_driver_name(struct fence *fence) { struct sync_timeline *parent = fence_parent(fence); return parent->name; } -static const char *timeline_fence_get_timeline_name(struct dma_fence *fence) +static const char *timeline_fence_get_timeline_name(struct fence *fence) { struct sync_timeline *parent = fence_parent(fence); return parent->name; } -static void timeline_fence_release(struct dma_fence *fence) +static void timeline_fence_release(struct fence *fence) { struct sync_pt *pt = fence_to_sync_pt(fence); struct sync_timeline *parent = fence_parent(fence); @@ -121,15 +109,15 @@ list_del(&pt->active_list); spin_unlock_irqrestore(fence->lock, flags); sync_timeline_put(parent); - dma_fence_free(fence); + fence_free(fence); } -static bool timeline_fence_signaled(struct dma_fence *fence) +static bool timeline_fence_signaled(struct fence *fence) { struct sync_timeline *parent = fence_parent(fence); struct sync_pt *pt = get_sync_pt(fence); - if (__dma_fence_is_later(fence->seqno, parent->value, fence->ops)) + if (__fence_is_later(fence->seqno, parent->value)) return false; if (pt->timestamp > parent->timestamp) @@ -138,7 +126,7 @@ return true; } -static bool timeline_fence_enable_signaling(struct dma_fence *fence) +static bool timeline_fence_enable_signaling(struct fence *fence) { struct sync_pt *pt = container_of(fence, struct sync_pt, fence); struct sync_timeline *parent = fence_parent(fence); @@ -150,22 +138,20 @@ return true; } -#if 0 -static void timeline_fence_disable_signaling(struct dma_fence *fence) +static void timeline_fence_disable_signaling(struct fence *fence) { struct sync_pt *pt = container_of(fence, struct sync_pt, fence); list_del_init(&pt->active_list); } -#endif -static void timeline_fence_value_str(struct dma_fence *fence, +static void timeline_fence_value_str(struct fence *fence, char *str, int size) { - snprintf(str, size, "%llu", fence->seqno); + snprintf(str, size, "%d", fence->seqno); } -static void timeline_fence_timeline_value_str(struct dma_fence *fence, +static void timeline_fence_timeline_value_str(struct fence *fence, char *str, int size) { struct sync_timeline *parent = fence_parent(fence); @@ -173,13 +159,13 @@ snprintf(str, size, "%d", parent->value); } -static const struct dma_fence_ops timeline_fence_ops = { +static const struct fence_ops timeline_fence_ops = { .get_driver_name = timeline_fence_get_driver_name, .get_timeline_name = timeline_fence_get_timeline_name, .enable_signaling = timeline_fence_enable_signaling, - //.disable_signaling = timeline_fence_disable_signaling, + .disable_signaling = timeline_fence_disable_signaling, .signaled = timeline_fence_signaled, - .wait = dma_fence_default_wait, + .wait = fence_default_wait, .release = timeline_fence_release, .fence_value_str = timeline_fence_value_str, .timeline_value_str = timeline_fence_timeline_value_str, @@ -202,7 +188,7 @@ obj->value += inc; list_for_each_entry_safe(pt, next, &obj->active_list_head, active_list) { - if (dma_fence_is_signaled_locked(&pt->fence)) + if (fence_is_signaled(&pt->fence)) list_del_init(&pt->active_list); } spin_unlock_irqrestore(&obj->lock, flags); @@ -229,7 +215,7 @@ return NULL; spin_lock_irqsave(&obj->lock, flags); sync_timeline_get(obj); - dma_fence_init(&pt->fence, &timeline_fence_ops, &obj->lock, + fence_init(&pt->fence, &timeline_fence_ops, &obj->lock, obj->context, value); list_add_tail(&pt->link, &obj->pt_list); INIT_LIST_HEAD(&pt->active_list); @@ -252,7 +238,7 @@ } static int timeline_create_fence(struct vdec_sync *sync, int usage, - struct dma_fence **fence, int *fd, u32 value) + struct fence **fence, int *fd, u32 value) { int ret; struct sync_pt *pt; @@ -270,7 +256,7 @@ if (usage == FENCE_USE_FOR_APP) { *fd = get_unused_fd_flags(O_CLOEXEC); if (*fd < 0) { - return -EBADF; + ret = -EBADF; goto err; } @@ -283,16 +269,16 @@ fd_install(*fd, sync_file->file); /* decreases refcnt. */ - dma_fence_put(&pt->fence); + fence_put(&pt->fence); } *fence = &pt->fence; pt->timestamp = local_clock(); - if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE) + if (debug & VDEC_DBG_ENABLE_FENCE) pr_info("[VDEC-FENCE]: create fence: %lx, fd: %d, ref: %d, usage: %d\n", - (ulong) &pt->fence, *fd, atomic_read(&pt->fence.refcount.refcount.refs), usage); + (ulong) &pt->fence, *fd, atomic_read(&pt->fence.refcount.refcount), usage); return 0; err: put_unused_fd(*fd); @@ -302,64 +288,35 @@ return ret; } -struct dma_fence *vdec_fence_get(int fd) +struct fence *vdec_fence_get(int fd) { return sync_file_get_fence(fd); } EXPORT_SYMBOL(vdec_fence_get); -void vdec_fence_put(struct dma_fence *fence) +void vdec_fence_put(struct fence *fence) { - if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE) + if (debug & VDEC_DBG_ENABLE_FENCE) pr_info("[VDEC-FENCE]: the fence (%px) cost time: %lld ns\n", fence, local_clock() - get_sync_pt(fence)->timestamp); - dma_fence_put(fence); + fence_put(fence); } EXPORT_SYMBOL(vdec_fence_put); -int vdec_fence_wait(struct dma_fence *fence, long timeout) +int vdec_fence_wait(struct fence *fence, long timeout) { - if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE) + if (debug & VDEC_DBG_ENABLE_FENCE) pr_info("[VDEC-FENCE]: wait fence %lx.\n", (ulong) fence); - return dma_fence_wait_timeout(fence, false, timeout); + return fence_wait_timeout(fence, false, timeout); } EXPORT_SYMBOL(vdec_fence_wait); -struct vdec_sync *vdec_sync_get(void) -{ - int i; - struct vdec_sync_core_s *core = &vdec_sync_core; - ulong flags; - - spin_lock_irqsave(&core->vdec_sync_lock, flags); - - for (i = 0; i < VDEC_SYNC_COUNT; i++) { - if (atomic_read(&core->s_vdec_sync[i].use_flag) == 0) { - int j; - atomic_set(&core->s_vdec_sync[i].use_flag, 1); - for (j = 0; j < 64; j++) { - core->s_vdec_sync[i].release_callback[j].func = vdec_fence_buffer_count_decrease; - core->s_vdec_sync[i].release_callback[j].private_data = (void *)&core->s_vdec_sync[i]; - } - spin_unlock_irqrestore(&core->vdec_sync_lock, flags); - return &core->s_vdec_sync[i]; - } - } - spin_unlock_irqrestore(&core->vdec_sync_lock, flags); - return 0; -} -EXPORT_SYMBOL(vdec_sync_get); - void vdec_timeline_create(struct vdec_sync *sync, u8 *name) { - struct sync_timeline *obj; snprintf(sync->name, sizeof(sync->name), "%s", name); - obj = sync_timeline_create(sync->name); - obj->parent_sync = sync; - sync->timeline = (void *)obj; - + sync->timeline = (void *)sync_timeline_create(sync->name); if (sync->timeline) pr_info("[VDEC-FENCE]: create timeline %lx, name: %s\n", (ulong) sync->timeline, sync->name); @@ -380,12 +337,13 @@ spin_lock_irqsave(&obj->lock, flags); + pt = list_last_entry(&obj->pt_list, struct sync_pt, link); value = obj->value + 1; if (!list_empty(&obj->pt_list)) { pt = list_last_entry(&obj->pt_list, struct sync_pt, link); - if (value <= pt->fence.seqno) { - value = pt->fence.seqno + 1; + if (value == pt->fence.seqno) { + value++; } } spin_unlock_irqrestore(&obj->lock, flags); @@ -407,7 +365,7 @@ obj->timestamp = local_clock(); - if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE) + if (debug & VDEC_DBG_ENABLE_FENCE) pr_info("[VDEC-FENCE]: update timeline %d.\n", obj->value + value); @@ -415,15 +373,6 @@ } EXPORT_SYMBOL(vdec_timeline_increase); -void vdec_timeline_get(struct vdec_sync *sync) -{ - struct sync_timeline *obj = sync->timeline; - - sync_timeline_get(obj); -} -EXPORT_SYMBOL(vdec_timeline_get); - - void vdec_timeline_put(struct vdec_sync *sync) { struct sync_timeline *obj = sync->timeline; @@ -432,15 +381,15 @@ } EXPORT_SYMBOL(vdec_timeline_put); -void vdec_fence_status_set(struct dma_fence *fence, int status) +void vdec_fence_status_set(struct fence *fence, int status) { fence->error = status; } EXPORT_SYMBOL(vdec_fence_status_set); -int vdec_fence_status_get(struct dma_fence *fence) +int vdec_fence_status_get(struct fence *fence) { - return dma_fence_get_status(fence); + return fence_get_status(fence); } EXPORT_SYMBOL(vdec_fence_status_get); @@ -460,72 +409,19 @@ int vdec_clean_all_fence(struct vdec_sync *sync) { - /*struct sync_timeline *obj = sync->timeline; + struct sync_timeline *obj = sync->timeline; struct sync_pt *pt, *next; spin_lock_irq(&obj->lock); list_for_each_entry_safe(pt, next, &obj->pt_list, link) { - dma_fence_set_error(&pt->fence, -ENOENT); - dma_fence_signal_locked(&pt->fence); + fence_set_error(&pt->fence, -ENOENT); + fence_signal_locked(&pt->fence); } - spin_unlock_irq(&obj->lock);*/ - - struct sync_pt *pt, *next; - struct sync_timeline *obj = sync->timeline; - - list_for_each_entry_safe(pt, next, &obj->pt_list, link) { - pr_err("vdec_clean_all_fence %px\n" , obj->parent_sync); - vdec_fence_put(&pt->fence); - } - - sync_timeline_put(obj); + spin_unlock_irq(&obj->lock); return 0; } EXPORT_SYMBOL(vdec_clean_all_fence); -void vdec_fence_buffer_count_increase(ulong fence) -{ - struct vdec_sync *sync = (struct vdec_sync *)fence; - struct sync_timeline *obj = sync->timeline; - - spin_lock_irq(&obj->lock); - - if (atomic_read(&sync->buffer_count) == 0) { - sync_timeline_get(obj); - } - - atomic_inc(&sync->buffer_count); - - spin_unlock_irq(&obj->lock); -} -EXPORT_SYMBOL(vdec_fence_buffer_count_increase); - -void vdec_fence_buffer_count_decrease(struct codec_mm_s *mm, struct codec_mm_cb_s *cb) -{ - struct vdec_sync *sync = (struct vdec_sync *)cb->private_data; - struct sync_pt *pt, *next; - struct sync_timeline *obj = sync->timeline; - - atomic_dec(&sync->buffer_count); - - if (atomic_read(&sync->buffer_count) == 0) { - sync_timeline_put(obj); - list_for_each_entry_safe(pt, next, &obj->pt_list, link) { - vdec_fence_put(&pt->fence); - } - return; - } - return ; -} -EXPORT_SYMBOL(vdec_fence_buffer_count_decrease); - -void vdec_sync_core_init(void) -{ - spin_lock_init(&vdec_sync_core.vdec_sync_lock); -} -EXPORT_SYMBOL(vdec_sync_core_init); - -
diff --git a/drivers/frame_provider/decoder/utils/vdec_sync.h b/drivers/frame_provider/decoder/utils/vdec_sync.h index 6637b42..0622341 100644 --- a/drivers/frame_provider/decoder/utils/vdec_sync.h +++ b/drivers/frame_provider/decoder/utils/vdec_sync.h
@@ -20,11 +20,9 @@ #include <linux/list.h> #include <linux/rbtree.h> #include <linux/spinlock.h> -#include <linux/dma-fence.h> +#include <linux/fence.h> #include <linux/sync_file.h> #include <uapi/linux/sync_file.h> -#include <linux/device.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> #define FENCE_USE_FOR_DRIVER (0) #define FENCE_USE_FOR_APP (1) @@ -42,11 +40,10 @@ spinlock_t lock; u64 timestamp; - struct vdec_sync *parent_sync; }; struct sync_pt { - struct dma_fence fence; + struct fence fence; struct list_head link; struct list_head active_list; u64 timestamp; @@ -57,27 +54,24 @@ void *timeline; int usage; int fd; - struct dma_fence *fence; - atomic_t buffer_count; - atomic_t use_flag; - struct codec_mm_cb_s release_callback[64]; + struct fence *fence; }; -static inline struct sync_timeline *fence_parent(struct dma_fence *fence) +static inline struct sync_timeline *fence_parent(struct fence *fence) { return container_of(fence->lock, struct sync_timeline, lock); } -static inline struct sync_pt *get_sync_pt(struct dma_fence *fence) +static inline struct sync_pt *get_sync_pt(struct fence *fence) { return container_of(fence, struct sync_pt, fence); } -struct dma_fence *vdec_fence_get(int fd); +struct fence *vdec_fence_get(int fd); -void vdec_fence_put(struct dma_fence *fence); +void vdec_fence_put(struct fence *fence); -int vdec_fence_wait(struct dma_fence *fence, long timeout); +int vdec_fence_wait(struct fence *fence, long timeout); void vdec_timeline_create(struct vdec_sync *sync, u8 *name); @@ -85,23 +79,13 @@ void vdec_timeline_increase(struct vdec_sync *sync, u32 value); -void vdec_timeline_get(struct vdec_sync *sync); - void vdec_timeline_put(struct vdec_sync *sync); -int vdec_fence_status_get(struct dma_fence *fence); +int vdec_fence_status_get(struct fence *fence); -void vdec_fence_status_set(struct dma_fence *fence, int status); +void vdec_fence_status_set(struct fence *fence, int status); bool check_objs_all_signaled(struct vdec_sync *sync); int vdec_clean_all_fence(struct vdec_sync *sync); -void vdec_fence_buffer_count_increase(ulong fence); - -void vdec_fence_buffer_count_decrease(struct codec_mm_s *mm, struct codec_mm_cb_s *cb); - -struct vdec_sync *vdec_sync_get(void); - -void vdec_sync_core_init(void); -
diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c index 34bc21a..e892127 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
@@ -21,6 +21,21 @@ #include <media/v4l2-mem2mem.h> #include <linux/printk.h> +int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx, + struct vdec_v4l2_buffer **out) +{ + int ret = -1; + + if (ctx->drv_handle == 0) + return -EIO; + + ret = ctx->dec_if->get_param(ctx->drv_handle, + GET_PARAM_FREE_FRAME_BUFFER, out); + + return ret; +} +EXPORT_SYMBOL(vdec_v4l_get_buffer); + int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx, struct vdec_pic_info *pic) { @@ -36,21 +51,6 @@ } EXPORT_SYMBOL(vdec_v4l_get_pic_info); -int vdec_v4l_set_cfg_infos(struct aml_vcodec_ctx *ctx, - struct aml_vdec_cfg_infos *cfg) -{ - int ret = 0; - - if (ctx->drv_handle == 0) - return -EIO; - - ret = ctx->dec_if->set_param(ctx->drv_handle, - SET_PARAM_CFG_INFO, cfg); - - return ret; -} -EXPORT_SYMBOL(vdec_v4l_set_cfg_infos); - int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps) { @@ -66,22 +66,6 @@ } EXPORT_SYMBOL(vdec_v4l_set_ps_infos); -int vdec_v4l_set_comp_buf_info(struct aml_vcodec_ctx *ctx, - struct vdec_comp_buf_info *info) -{ - int ret = 0; - - if (ctx->drv_handle == 0) - return -EIO; - - ret = ctx->dec_if->set_param(ctx->drv_handle, - SET_PARAM_COMP_BUF_INFO, info); - - return ret; - -} -EXPORT_SYMBOL(vdec_v4l_set_comp_buf_info); - int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx, struct aml_vdec_hdr_infos *hdr) { @@ -97,10 +81,50 @@ } EXPORT_SYMBOL(vdec_v4l_set_hdr_infos); +static void aml_wait_dpb_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)) { + pr_err("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->dpb_size) + ctx->v4l_codec_dpb_ready = true; + } +} + void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx) { - if (ctx != NULL) - ctx->vdec_pic_info_update(ctx); + unsigned int dpbsize = 0; + int ret; + + if (ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) { + pr_err("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) { + pr_err("Cannot get correct pic info\n"); + return; + } + + ret = ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_DPB_SIZE, &dpbsize); + if (dpbsize == 0) + pr_err("Incorrect dpb size, ret=%d\n", ret); + + /* update picture information */ + ctx->dpb_size = dpbsize; + ctx->picinfo = ctx->last_decoded_picinfo; } int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event) @@ -126,6 +150,9 @@ if (ctx->drv_handle == 0) return -EIO; + /* wait the DPB state to be ready. */ + aml_wait_dpb_ready(ctx); + aml_vdec_pic_info_update(ctx); mutex_lock(&ctx->state_lock); @@ -136,9 +163,8 @@ mutex_unlock(&ctx->state_lock); - while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) { - v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); - } + ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true; + v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx); return ret; } @@ -159,17 +185,3 @@ } EXPORT_SYMBOL(vdec_v4l_write_frame_sync); -int vdec_v4l_get_dw_mode(struct aml_vcodec_ctx *ctx, - unsigned int *dw_mode) -{ - int ret = -1; - - if (ctx->drv_handle == 0) - return -EIO; - - ret = ctx->dec_if->get_param(ctx->drv_handle, - GET_PARAM_DW_MODE, dw_mode); - - return ret; -} -EXPORT_SYMBOL(vdec_v4l_get_dw_mode);
diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h index 98513d9..1494f10 100644 --- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h +++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
@@ -23,22 +23,18 @@ #include "../../../amvdec_ports/vdec_drv_base.h" #include "../../../amvdec_ports/aml_vcodec_adapt.h" +int vdec_v4l_get_buffer( + struct aml_vcodec_ctx *ctx, + struct vdec_v4l2_buffer **out); + int vdec_v4l_get_pic_info( struct aml_vcodec_ctx *ctx, struct vdec_pic_info *pic); -int vdec_v4l_set_cfg_infos( - struct aml_vcodec_ctx *ctx, - struct aml_vdec_cfg_infos *cfg); - int vdec_v4l_set_ps_infos( struct aml_vcodec_ctx *ctx, struct aml_vdec_ps_infos *ps); -int vdec_v4l_set_comp_buf_info( - struct aml_vcodec_ctx *ctx, - struct vdec_comp_buf_info *info); - int vdec_v4l_set_hdr_infos( struct aml_vcodec_ctx *ctx, struct aml_vdec_hdr_infos *hdr); @@ -53,8 +49,4 @@ int vdec_v4l_res_ch_event( struct aml_vcodec_ctx *ctx); -int vdec_v4l_get_dw_mode( - struct aml_vcodec_ctx *ctx, - unsigned int *dw_mode); - #endif
diff --git a/drivers/frame_provider/decoder/vav1/av1_bufmgr.c b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c index 1e45320..41a522f 100644 --- a/drivers/frame_provider/decoder/vav1/av1_bufmgr.c +++ b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c
@@ -530,23 +530,16 @@ void av1_bufmgr_ctx_reset(AV1Decoder *pbi, BufferPool *const pool, AV1_COMMON *cm) { - u32 save_w, save_h; - if (!pbi || !pool || !cm) return; reset_frame_buffers(pbi); memset(pbi, 0, sizeof(*pbi)); - /*save w,h for resolution change after seek */ - save_w = cm->width; - save_h = cm->height; memset(cm, 0, sizeof(*cm)); cm->current_frame.frame_number = 0; cm->seq_params.bit_depth = AOM_BITS_8; cm->error.setjmp = 0; - cm->width = save_w; - cm->height = save_h; pbi->bufmgr_proc_count = 0; pbi->need_resync = 1; @@ -592,17 +585,6 @@ } } -void clear_frame_buf_ref_count(AV1Decoder *pbi) -{ - int i; - - for (i = 0; i < pbi->num_output_frames; i++) { - decrease_ref_count(pbi, pbi->output_frames[i], - pbi->common->buffer_pool); - } - pbi->num_output_frames = 0; -} - static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) { int ref_index = 0, mask; AV1_COMMON *const cm = pbi->common; @@ -976,10 +958,9 @@ #ifdef ORI_CODE fail: -#endif // clear the mi_* values to force a realloc on resync av1_set_mb_mi(cm, 0, 0); -#ifdef ORI_CODE + av1_free_context_buffers(cm); #endif return 1; @@ -2035,7 +2016,6 @@ // See if this frame can be used as show_existing_frame in future cm->showable_frame = params->p.showable_frame;//aom_rb_read_bit(rb); } - cm->cur_frame->show_frame = cm->show_frame; cm->cur_frame->showable_frame = cm->showable_frame; cm->error_resilient_mode = frame_is_sframe(cm) || @@ -2946,14 +2926,6 @@ // TODO(wtc): Verify that the frame_header_obu is identical to the // original frame_header_obu. For now just skip frame_header_size // bytes in the bit buffer. - if (frame_header_size > payload_size) { - cm->error.error_code = AOM_CODEC_CORRUPT_FRAME; - return -1; - } - assert(rb.bit_offset == 0); -#ifdef ORI_CODE - rb.bit_offset = 8 * frame_header_size; -#endif } decoded_payload_size = frame_header_size; @@ -3012,6 +2984,7 @@ } } } + return i; }
diff --git a/drivers/frame_provider/decoder/vav1/av1_global.h b/drivers/frame_provider/decoder/vav1/av1_global.h index e12b224..75af688 100644 --- a/drivers/frame_provider/decoder/vav1/av1_global.h +++ b/drivers/frame_provider/decoder/vav1/av1_global.h
@@ -52,6 +52,13 @@ #define AOMMIN(x, y) (((x) < (y)) ? (x) : (y)) #define AOMMAX(x, y) (((x) > (y)) ? (x) : (y)) +//typedef char int8_t; +//#ifndef BUFMGR_FOR_SIM +typedef unsigned char uint8_t; +//#endif +typedef unsigned int uint32_t; +//typedef int int32_t; +//typedef long long int64_t; #ifdef AML #define AOM_AV1_MMU @@ -101,12 +108,9 @@ } BuffInfo_t; #endif -#if 0 #define va_start(v,l) __builtin_va_start(v,l) #define va_end(v) __builtin_va_end(v) #define va_arg(v,l) __builtin_va_arg(v,l) -#endif - /* mem.h */ @@ -1318,9 +1322,8 @@ int min_mv; int avg_mv; #endif - u64 timestamp; - u32 hw_decode_time; - u32 frame_size2; // For frame base mode + bool vframe_bound; + u64 timestamp; } PIC_BUFFER_CONFIG; /* @@ -1561,7 +1564,6 @@ FRAME_CONTEXT frame_context; #endif - int show_frame; } RefCntBuffer; typedef struct BufferPool_s { @@ -2225,9 +2227,7 @@ unsigned short seg_lf_info_c[8]; unsigned short video_signal_type; unsigned short color_description; - unsigned short mmu_used_num; - unsigned short dw_mmu_used_num; - unsigned short seq_flags_2; + /*ucode end*/ /*other*/ unsigned short enable_superres; @@ -2317,7 +2317,6 @@ #define AV1_DEBUG_DUMP_DATA 0x800000 #define AV1_DEBUG_CACHE 0x1000000 #define AV1_DEBUG_CACHE_HIT_RATE 0x2000000 -#define AV1_DEBUG_SEI_DETAIL 0x4000000 #define IGNORE_PARAM_FROM_CONFIG 0x8000000 #if 1 /*def MULTI_INSTANCE_SUPPORT*/
diff --git a/drivers/frame_provider/decoder/vav1/vav1.c b/drivers/frame_provider/decoder/vav1/vav1.c index c67757a..8379316 100644 --- a/drivers/frame_provider/decoder/vav1/vav1.c +++ b/drivers/frame_provider/decoder/vav1/vav1.c
@@ -25,7 +25,6 @@ #include <linux/timer.h> #include <linux/kfifo.h> #include <linux/kthread.h> -#include <linux/sched/clock.h> #include <linux/spinlock.h> #include <linux/platform_device.h> #include <linux/amlogic/media/vfm/vframe.h> @@ -74,7 +73,6 @@ #include <media/v4l2-mem2mem.h> #endif #include "../../../amvdec_ports/utils/common.h" -#include "../utils/vdec_feature.h" #define AML #include "aom_av1_define.h" @@ -90,8 +88,6 @@ #define USE_DEC_PIC_END -#define SANITY_CHECK -#define CO_MV_COMPRESS #include "vav1.h" @@ -172,7 +168,6 @@ #define AOM_AV1_DUMP_LMEM 7 #define AOM_AV1_FGS_PARAM_CONT 8 #define AOM_AV1_DISCARD_NAL 0x10 -#define AOM_AV1_RESULT_NEED_MORE_BUFFER 0x11 /*status*/ #define AOM_AV1_DEC_PIC_END 0xe0 @@ -197,6 +192,7 @@ #define AOM_EOS 0x24 #define AOM_NAL_DECODE_DONE 0x25 + #define VF_POOL_SIZE 32 #undef pr_info @@ -269,8 +265,8 @@ #ifdef AOM_AV1_MMU_DW static unsigned int dw_mmu_enable[MAX_DECODE_INSTANCE_NUM]; #endif - -static u32 decode_timeout_val = 600; +/* disable timeout for av1 mosaic JIRA SWPL-23326 */ +static u32 decode_timeout_val = 0; static int start_decode_buf_level = 0x8000; //static u32 work_buf_size; static u32 force_pts_unstable; @@ -285,10 +281,9 @@ * 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; + * 5, (1/2):(1/2) ratio, with both compressed frame included * 0x10, double write only - * 0x20, mmu double write + * 0x20, mmu double write * 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; @@ -314,7 +309,7 @@ #define DUR2PTS(x) ((x)*90/96) #define PTS2DUR(x) ((x)*96/90) -#define PTS2DUR_u64(x) (div_u64((x)*96, 90)) + struct AV1HW_s; static int vav1_vf_states(struct vframe_states *states, void *); @@ -331,7 +326,7 @@ #endif static void vav1_prot_init(struct AV1HW_s *hw, u32 mask); static int vav1_local_init(struct AV1HW_s *hw); -static void vav1_put_timer_func(struct timer_list *timer); +static void vav1_put_timer_func(unsigned long arg); static void dump_data(struct AV1HW_s *hw, int size); static unsigned int get_data_check_sum (struct AV1HW_s *hw, int size); @@ -376,8 +371,6 @@ static u32 video_signal_type; static u32 on_no_keyframe_skiped; static u32 without_display_mode; -static u32 v4l_bitstream_id_enable = 1; - #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION static u32 force_dv_enable; #endif @@ -439,6 +432,10 @@ #define LOSLESS_COMPRESS_MODE #endif +typedef unsigned int u32; +typedef unsigned short u16; + + static u32 get_picture_qos; static u32 debug; @@ -537,7 +534,6 @@ //#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4) #define MAX_SIZE_8K (8192 * 4608) #define MAX_SIZE_4K (4096 * 2304) -#define MAX_SIZE_2K (1920 * 1088) #define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K) #define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088)) @@ -599,7 +595,7 @@ static int compute_losless_comp_body_size(int width, int height, uint8_t is_bit_depth_10); -void clear_frame_buf_ref_count(AV1Decoder *pbi); + #ifdef MULTI_INSTANCE_SUPPORT #define DEC_RESULT_NONE 0 @@ -756,10 +752,23 @@ u32 video_signal_type; u32 pts_unstable; - u32 last_chunk_pts; - u32 pts_diff_count; - u64 pts_diff_sum; + bool av1_first_pts_ready; + bool dur_recalc_flag; + u8 first_pts_index; + u32 frame_mode_pts_save[FRAME_BUFFERS]; + u64 frame_mode_pts64_save[FRAME_BUFFERS]; + u64 frame_mode_timestamp_save[FRAME_BUFFERS]; + u64 timestamp_duration; + int last_pts; + u64 last_pts_us64; + u64 last_timestamp; + 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; @@ -852,23 +861,17 @@ int buffer_wrap[FRAME_BUFFERS]; int sidebind_type; int sidebind_channel_id; - u32 cur_obu_type; - u32 multi_frame_cnt; - u32 endian; - u32 run_ready_min_buf_num; - int one_package_frame_cnt; - ulong fb_token; - dma_addr_t rdma_phy_adr; - unsigned *rdma_adr; - struct trace_decoder_name trace; + char vdec_name[32]; + char pts_name[32]; + char new_q_name[32]; + char disp_q_name[32]; }; - static void av1_dump_state(struct vdec_s *vdec); int av1_print(struct AV1HW_s *hw, int flag, const char *fmt, ...) { -#define HEVC_PRINT_BUF 512 +#define HEVC_PRINT_BUF 256 unsigned char buf[HEVC_PRINT_BUF]; int len = 0; @@ -918,9 +921,6 @@ int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? MAX_SIZE_8K : MAX_SIZE_4K; - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) - max = MAX_SIZE_2K; - if (w <= 0 || h <= 0) return true; @@ -1015,16 +1015,48 @@ u32 dw = ((double_write_mode & 0x80000000) == 0) ? hw->double_write_mode : (double_write_mode & 0x7fffffff); - if (dw & 0x20) { - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3) - && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) { - pr_info("MMU doueble write 1:4 not supported !!!\n"); - dw = 0; - } + if ((dw & 0x20) && + ((dw & 0xf) == 2 || (dw & 0xf) == 3)) { + pr_info("MMU doueble write 1:4 not supported !!!\n"); + dw = 0; } return dw; } +static int v4l_parser_get_double_write_mode(struct AV1HW_s *hw) +{ + u32 valid_dw_mode = get_valid_double_write_mode(hw); + u32 dw; + int w, h; + + /* mask for supporting double write value bigger than 0x100 */ + if (valid_dw_mode & 0xffffff00) { + w = hw->frame_width; + h = hw->frame_height; + + 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: + break; + } + return dw; + } + + return valid_dw_mode; +} + static int get_double_write_mode(struct AV1HW_s *hw) { u32 valid_dw_mode = get_valid_double_write_mode(hw); @@ -1035,15 +1067,6 @@ if (!cm->cur_frame) return 1;/*no valid frame,*/ - - if (hw->is_used_v4l) { - unsigned int out; - - vdec_v4l_get_dw_mode(hw->v4l2_ctx, &out); - dw = out; - return dw; - } - cur_pic_config = &cm->cur_frame->buf; w = cur_pic_config->y_crop_width; h = cur_pic_config->y_crop_height; @@ -1099,6 +1122,19 @@ } #endif +static int get_double_write_ratio(struct AV1HW_s *hw, + int dw_mode) +{ + int ratio = 1; + int dw_mode_ratio = dw_mode & 0xf; + if ((dw_mode_ratio == 2) || + (dw_mode_ratio == 3)) + ratio = 4; + else if (dw_mode_ratio == 4) + ratio = 2; + return ratio; +} + /* return page number */ static int av1_mmu_page_num(struct AV1HW_s *hw, int w, int h, int save_mode) @@ -1123,32 +1159,6 @@ return cur_mmu_4k_number; } -static struct internal_comp_buf* v4lfb_to_icomp_buf( - struct AV1HW_s *hw, - struct vdec_v4l2_buffer *fb) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - -static struct internal_comp_buf* index_to_icomp_buf( - struct AV1HW_s *hw, int index) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; - - fb = (struct vdec_v4l2_buffer *) - hw->m_BUF[index].v4l_ref_buf_addr; - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - //#define MAX_4K_NUM 0x1200 int av1_alloc_mmu( struct AV1HW_s *hw, @@ -1162,6 +1172,11 @@ int bit_depth_10 = (bit_depth == AOM_BITS_10); int cur_mmu_4k_number; + if (!hw->mmu_box) { + pr_err("error no mmu box!\n"); + return -1; + } + if (hw->double_write_mode & 0x10) return 0; @@ -1178,22 +1193,11 @@ if (cur_mmu_4k_number < 0) return -1; - if (hw->is_used_v4l) { - struct internal_comp_buf *ibuf = - index_to_icomp_buf(hw, cur_buf_idx); - - ret = decoder_mmu_box_alloc_idx( - ibuf->mmu_box, - ibuf->index, - ibuf->frame_buffer_size, - mmu_index_adr); - } else { - ret = decoder_mmu_box_alloc_idx( - hw->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); - } + ret = decoder_mmu_box_alloc_idx( + hw->mmu_box, + hw->buffer_wrap[cur_buf_idx], + cur_mmu_4k_number, + mmu_index_adr); return ret; } @@ -1241,7 +1245,7 @@ } ret = decoder_mmu_box_alloc_idx( hw->mmu_box_dw, - cur_buf_idx, + hw->buffer_wrap[cur_buf_idx], cur_mmu_4k_number, mmu_index_adr); return ret; @@ -1274,13 +1278,6 @@ int i, int size) { int ret = 0; - - if (hw->m_mv_BUF[i].start_adr && - size > hw->m_mv_BUF[i].size) { - dealloc_mv_bufs(hw); - } else if (hw->m_mv_BUF[i].start_adr) - return 0; - if (decoder_bmmu_box_alloc_buf_phy (hw->bmmu_box, MV_BUFFER_IDX(i), size, @@ -1356,7 +1353,10 @@ __func__, size); if ((hw->is_used_v4l) && !IS_8K_SIZE(pic_width, pic_height)) { - size = 0x100000; + if (vdec_is_support_4k()) + size = 0xb0000; + else + size = 0x30000; } if (hw->init_pic_w > 4096 && hw->init_pic_h > 2048) @@ -1502,26 +1502,6 @@ static void init_pic_list_hw(struct AV1HW_s *pbi); -static void update_hide_frame_timestamp(struct AV1HW_s *hw) -{ - RefCntBuffer *const frame_bufs = hw->common.buffer_pool->frame_bufs; - int i; - - for (i = 0; i < hw->used_buf_num; ++i) { - if ((!frame_bufs[i].show_frame) && - (frame_bufs[i].showable_frame) && - (!frame_bufs[i].buf.vf_ref) && - (frame_bufs[i].buf.BUF_index != -1)) { - frame_bufs[i].buf.timestamp = hw->chunk->timestamp; - frame_bufs[i].buf.pts = hw->chunk->pts; - frame_bufs[i].buf.pts64 = hw->chunk->pts64; - av1_print(hw, AV1_DEBUG_OUT_PTS, - "%s, update %d hide frame ts: %lld, pts %d, pts64 %lld\n", - __func__, i, frame_bufs[i].buf.timestamp, hw->chunk->pts, hw->chunk->pts64); - } - } -} - static int get_free_fb_idx(AV1_COMMON *cm) { int i; @@ -1533,7 +1513,7 @@ break; } - return (i != FRAME_BUFFERS) ? i : -1; + return i; } static int v4l_get_free_fb(struct AV1HW_s *hw) @@ -1565,9 +1545,6 @@ break; case V4L_CAP_BUFF_IN_M2M: idx = get_free_fb_idx(cm); - if (idx < 0) - break; - pic = &frame_bufs[idx].buf; pic->y_crop_width = hw->frame_width; pic->y_crop_height = hw->frame_height; @@ -1601,30 +1578,8 @@ } } - if (free_pic && hw->chunk) { - free_pic->timestamp = hw->chunk->timestamp; - update_hide_frame_timestamp(hw); - } - unlock_buffer_pool(cm->buffer_pool, flags); - if (free_pic) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *) - hw->m_BUF[free_pic->index].v4l_ref_buf_addr; - - fb->status = FB_ST_DECODER; - } - - if (debug & AV1_DEBUG_OUT_PTS) { - if (free_pic) { - pr_debug("%s, idx: %d, ts: %lld\n", - __func__, free_pic->index, free_pic->timestamp); - } else { - pr_debug("%s, av1 get free pic null\n", __func__); - } - } - return free_pic ? free_pic->index : INVALID_IDX; } @@ -1664,25 +1619,7 @@ i = INVALID_IDX; } - if (i != INVALID_IDX) { - struct PIC_BUFFER_CONFIG_s *pic = &frame_bufs[i].buf; - struct AV1HW_s *hw = container_of(cm, struct AV1HW_s, common); - - if (pic && hw->chunk) { - pic->timestamp = hw->chunk->timestamp; - pic->pts = hw->chunk->pts; - pic->pts64 = hw->chunk->pts64; - update_hide_frame_timestamp(hw); - } - - if (pic) - av1_print(hw, AV1_DEBUG_OUT_PTS, - "%s, idx: %d, ts: %lld, pts %d, pts64 %lld\n", - __func__, i, pic->timestamp, pic->pts, pic->pts64); - } - unlock_buffer_pool(cm->buffer_pool, flags); - return i; } @@ -1697,42 +1634,14 @@ { struct AV1_Common_s *const cm = &hw->common; struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - int i, free_buf_count = 0; - - if (hw->is_used_v4l) { - for (i = 0; i < hw->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - frame_bufs[i].buf.cma_alloc_addr) { - free_buf_count++; - } - } - - if (ctx->cap_pool.dec < hw->used_buf_num) { - free_buf_count += - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - } - /* trigger to parse head data. */ - if (!hw->v4l_params_parsed) { - free_buf_count = hw->run_ready_min_buf_num; - } - if ((debug & AV1_DEBUG_BUFMGR_MORE) && - (free_buf_count <= 0)) { - pr_info("%s, free count %d, m2m_ready %d\n", - __func__, - free_buf_count, - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)); - } - } else { - for (i = 0; i < hw->used_buf_num; ++i) - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.index != -1)) { - free_buf_count++; - } - } - + int i; + int free_buf_count = 0; + for (i = 0; i < hw->used_buf_num; ++i) + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.vf_ref == 0) && + (frame_bufs[i].buf.index != -1) + ) + free_buf_count++; return free_buf_count; } @@ -1778,13 +1687,18 @@ hw->wait_buf = 0; hw->error_flag = 0; + hw->last_pts = 0; + hw->last_pts_us64 = 0; + hw->last_timestamp = 0; + hw->shift_byte_count = 0; + hw->shift_byte_count_lo = 0; + hw->shift_byte_count_hi = 0; + hw->pts_mode_switching_count = 0; + hw->pts_mode_recovery_count = 0; + hw->buf_num = 0; hw->pic_num = 0; - hw->last_chunk_pts = 0; - hw->pts_diff_count = 0; - hw->pts_diff_sum = 0; - return 0; } @@ -1826,14 +1740,7 @@ 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) - +static u32 endian = 0xff0; static u32 multi_frames_in_one_pack = 1; #ifdef ERROR_HANDLE_DEBUG static u32 dbg_nal_skip_flag; @@ -2025,12 +1932,9 @@ #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. fix case1440 dec timeout */ -#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE)) - #define WORK_BUF_SPEC_NUM 3 -static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM] = { +static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM] = { { //8M bytes .max_width = 1920, .max_height = 1088, @@ -2713,73 +2617,82 @@ { void *mem_start_virt; - buf_spec->ipp.buf_start = - WORKBUF_ALIGN(buf_spec->start_adr); - buf_spec->sao_abv.buf_start = - WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); - 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->vps.buf_start = - WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size); - buf_spec->seg_map.buf_start = - WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size); - buf_spec->daala_top.buf_start = - WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size); - buf_spec->sao_up.buf_start = - WORKBUF_ALIGN(buf_spec->daala_top.buf_start + buf_spec->daala_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->cdf_buf.buf_start = - WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size); - buf_spec->gmc_buf.buf_start = - WORKBUF_ALIGN(buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size); - buf_spec->scalelut.buf_start = - WORKBUF_ALIGN(buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.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->cdef_data.buf_start = - WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size); - buf_spec->ups_data.buf_start = - WORKBUF_ALIGN(buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size); - buf_spec->fgs_table.buf_start = - WORKBUF_ALIGN(buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size); + buf_spec->ipp.buf_start = + buf_spec->start_adr; + buf_spec->sao_abv.buf_start = + buf_spec->ipp.buf_start + buf_spec->ipp.buf_size; + + buf_spec->sao_vb.buf_start = + buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size; + buf_spec->short_term_rps.buf_start = + buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size; + buf_spec->vps.buf_start = + buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size; + buf_spec->seg_map.buf_start = + buf_spec->vps.buf_start + buf_spec->vps.buf_size; + buf_spec->daala_top.buf_start = + buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size; + buf_spec->sao_up.buf_start = + buf_spec->daala_top.buf_start + buf_spec->daala_top.buf_size; + buf_spec->swap_buf.buf_start = + buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size; + buf_spec->cdf_buf.buf_start = + buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size; + buf_spec->gmc_buf.buf_start = + buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size; + buf_spec->scalelut.buf_start = + buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.buf_size; + buf_spec->dblk_para.buf_start = + buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size; + buf_spec->dblk_data.buf_start = + buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size; + buf_spec->cdef_data.buf_start = + buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; + buf_spec->ups_data.buf_start = + buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size; + buf_spec->fgs_table.buf_start = + buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size; #ifdef AOM_AV1_MMU - buf_spec->mmu_vbh.buf_start = - WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size); - buf_spec->cm_header.buf_start = - WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size); + buf_spec->mmu_vbh.buf_start = + buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size; + buf_spec->cm_header.buf_start = + buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size; #ifdef AOM_AV1_MMU_DW - buf_spec->mmu_vbh_dw.buf_start = - WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size); - buf_spec->cm_header_dw.buf_start = - WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size); - buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size); + buf_spec->mmu_vbh_dw.buf_start = + buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; + buf_spec->cm_header_dw.buf_start = + buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size; + buf_spec->mpred_above.buf_start = + buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size; #else - buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size); + buf_spec->mpred_above.buf_start = + buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; #endif #else - buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size); + buf_spec->mpred_above.buf_start = + buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size; #endif + #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->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); + 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); + 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->rpm.buf_start + + buf_spec->rpm.buf_size; buf_spec->end_adr = - WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size); + buf_spec->lmem.buf_start + + buf_spec->lmem.buf_size; if (!hw) return; @@ -2867,13 +2780,64 @@ } } +static bool v4l_is_there_vframe_bound(struct AV1HW_s *hw) +{ + int i; + struct AV1_Common_s *const cm = &hw->common; + struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; + for (i = 0; i < hw->used_buf_num; ++i) { + if (frame_bufs[i].buf.vframe_bound) + return true; + } + + return false; +} + +static void v4l_mmu_buffer_release(struct AV1HW_s *hw) +{ + struct AV1_Common_s *const cm = &hw->common; + struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; + int i; + + /* release workspace */ + if (hw->bmmu_box) + decoder_bmmu_box_free_idx(hw->bmmu_box, + WORK_SPACE_BUF_ID); + /* + * it's only when vframe get back to driver, right now we can be sure + * that vframe and fd are related. if the playback exits, the capture + * requires the upper app to release when the fd is closed, and others + * buffers drivers are released by driver. + */ + for (i = 0; i < hw->used_buf_num; ++i) { + if (!frame_bufs[i].buf.vframe_bound) { + if (hw->bmmu_box) + decoder_bmmu_box_free_idx(hw->bmmu_box, + HEADER_BUFFER_IDX(hw->buffer_wrap[i])); + if (hw->mmu_box) + decoder_mmu_box_free_idx(hw->mmu_box, hw->buffer_wrap[i]); + + av1_print(hw, PRINT_FLAG_V4L_DETAIL, + "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n", + __func__, i, hw->bmmu_box, hw->mmu_box); + } + } +} static void uninit_mmu_buffers(struct AV1HW_s *hw) { #ifndef MV_USE_FIXED_BUF dealloc_mv_bufs(hw); #endif + if (hw->is_used_v4l && + v4l_is_there_vframe_bound(hw)) { + if (get_double_write_mode(hw) != 0x10) { + v4l_mmu_buffer_release(hw); + return; + } + } + if (hw->mmu_box) decoder_mmu_box_free(hw->mmu_box); hw->mmu_box = NULL; @@ -2900,33 +2864,6 @@ return pic_width_lcu * pic_height_lcu; } -/* return in MB */ -static int av1_max_mmu_buf_size(int max_w, int max_h) -{ - int buf_size = 48; - - if ((max_w * max_h > 1280*736) && - (max_w * max_h <= 1920*1088)) { - buf_size = 12; - } else if ((max_w * max_h > 0) && - (max_w * max_h <= 1280*736)) { - buf_size = 4; - } - - return buf_size; -} - -static int av1_get_header_size(int w, int h) -{ - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - IS_8K_SIZE(w, h)) - return MMU_COMPRESS_HEADER_SIZE_8K; - if (IS_4K_SIZE(w, h)) - return MMU_COMPRESS_HEADER_SIZE_4K; - - return MMU_COMPRESS_HEADER_SIZE_1080P; -} - static int v4l_alloc_and_config_pic(struct AV1HW_s *hw, struct PIC_BUFFER_CONFIG_s *pic) { @@ -2945,24 +2882,21 @@ int32_t mv_buffer_size = hw->max_one_mv_buffer_size; //#endif #endif - struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hw->v4l2_ctx; struct vdec_v4l2_buffer *fb = NULL; if (i < 0) return ret; - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb); if (ret < 0) { - av1_print(hw, 0, "[%d] AV1 get buffer fail.\n", ctx->id); + av1_print(hw, 0, "[%d] AV1 get buffer fail.\n", + ((struct aml_vcodec_ctx *) (hw->v4l2_ctx))->id); return ret; } - fb->status = FB_ST_DECODER; - if (hw->mmu_enable) { - struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hw, fb); - - hw->m_BUF[i].header_addr = ibuf->header_addr; + hw->m_BUF[i].header_addr = decoder_bmmu_box_get_phy_addr( + hw->bmmu_box, HEADER_BUFFER_IDX(hw->buffer_wrap[i])); if (debug & AV1_DEBUG_BUFMGR_MORE) { pr_info("MMU header_adr %d: %ld\n", i, hw->m_BUF[i].header_addr); @@ -3094,9 +3028,9 @@ if (dw_mode && (dw_mode & 0x20) == 0) { int pic_width_dw = pic_width / - get_double_write_ratio(dw_mode & 0xf); + get_double_write_ratio(hw, dw_mode); int pic_height_dw = pic_height / - get_double_write_ratio(dw_mode & 0xf); + get_double_write_ratio(hw, dw_mode); int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f); int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f); @@ -3139,26 +3073,26 @@ /*!USE_SPEC_BUF_FOR_MMU_HEAD*/ if (hw->mmu_enable) { pic_config->header_adr = decoder_bmmu_box_get_phy_addr( - hw->bmmu_box, HEADER_BUFFER_IDX(pic_config->index)); + hw->bmmu_box, HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index])); #ifdef AOM_AV1_MMU_DW if (hw->dw_mmu_enable) { pic_config->header_dw_adr = decoder_bmmu_box_get_phy_addr( - hw->bmmu_box, DW_HEADER_BUFFER_IDX(pic_config->index)); + hw->bmmu_box, DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index])); } if (debug & AV1_DEBUG_BUFMGR_MORE) { pr_info("MMU dw header_adr (%d, %d) %d: %d\n", hw->dw_mmu_enable, - DW_HEADER_BUFFER_IDX(pic_config->index), - pic_config->index, + DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index]), + hw->buffer_wrap[pic_config->index], pic_config->header_dw_adr); } #endif if (debug & AV1_DEBUG_BUFMGR_MORE) { pr_info("MMU header_adr %d: %d\n", - pic_config->index, pic_config->header_adr); + hw->buffer_wrap[pic_config->index], pic_config->header_adr); } } #endif @@ -3172,13 +3106,13 @@ #endif if (buf_size > 0) { ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, - VF_BUFFER_IDX(i), + VF_BUFFER_IDX(hw->buffer_wrap[i]), buf_size, DRIVER_NAME, &pic_config->cma_alloc_addr); if (ret < 0) { pr_info( "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n", - VF_BUFFER_IDX(i), + VF_BUFFER_IDX(hw->buffer_wrap[i]), buf_size ); return ret; @@ -3189,7 +3123,7 @@ else { pr_info( "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n", - VF_BUFFER_IDX(i), + VF_BUFFER_IDX(hw->buffer_wrap[i]), buf_size ); return -1; @@ -3622,10 +3556,8 @@ seg_map_size = ((frame_width + 127) >> 7) * ((frame_height + 127) >> 7) * 384 ; */ - if (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T3) { - WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, - (frame_height << 16) | frame_width); - } + WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, + (frame_height << 16) | frame_width); #ifdef DUAL_DECODE #else WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ, @@ -3898,15 +3830,7 @@ cur_pic_config->index, last_frame_pic_config->index);*/ //WRITE_VREG(HEVC_MPRED_CTRL3,0x24122412); -#ifdef CO_MV_COMPRESS - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - WRITE_VREG(HEVC_MPRED_CTRL3,0x10151015); // 'd10, 'd21 for AV1 - } else { - WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1 - } -#else - WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1 -#endif + WRITE_VREG(HEVC_MPRED_CTRL3, 0x13151315); // 'd19, 'd21 for AV1 WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, hw->pbi->work_space_buf->mpred_above.buf_start); @@ -3932,19 +3856,11 @@ "WRITE_VREG(HEVC_MPRED_CTRL4, 0x%x)\n", data32); } #if 1 - data32 = ((cm->seq_params.order_hint_info.enable_order_hint << 27) | + data32 = ( + (cm->seq_params.order_hint_info.enable_order_hint << 27) | (cm->seq_params.order_hint_info.order_hint_bits_minus_1 << 24) | - (cm->cur_frame->order_hint << 16 )); -#ifdef CO_MV_COMPRESS - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - data32 |= (0x10 << 8) | (0x10 << 0); - } else { - data32 |= (0x13 << 8) | (0x13 << 0); - } -#else - data32 |= (0x13 << 8) | (0x13 << 0); -#endif - + (cm->cur_frame->order_hint <<16 ) | + (0x13 << 8) | (0x13 << 0)); #else data32 = READ_VREG(HEVC_MPRED_L0_REF00_POC); data32 &= (~(0xff << 16)); @@ -4073,7 +3989,7 @@ WRITE_VREG(HEVC_MPRED_MV_WPTR, cur_pic_config->mpred_mv_wr_start_addr); - if (inter_flag) { + if ((inter_flag) && (mv_cal_tpl_count <= 3)) { for (i = 0; i < mv_cal_tpl_count; i++) { PIC_BUFFER_CONFIG *pic_config = av1_get_ref_frame_spec_buf(cm, mv_ref_id[i]); @@ -4094,9 +4010,6 @@ pic_config->mpred_mv_wr_start_addr); WRITE_VREG(HEVC_MPRED_MV_RPTR_2, pic_config->mpred_mv_wr_start_addr); - } else { - av1_print(hw, AOM_DEBUG_HW_MORE, - "%s: mv_ref_id error\n", __func__); } } } @@ -4136,7 +4049,7 @@ !!!!!!!!!!!!!!!!!!!!!!!!!TODO .... !!!!!!!!!!! mem_map_mode, endian, get_double_write_mode */ - AV1_COMMON *cm = &hw->common; + AV1_COMMON *cm = &hw->common; PIC_BUFFER_CONFIG* pic_config = &cm->cur_frame->buf; uint32_t data32; int32_t lcu_size = @@ -4243,7 +4156,7 @@ #ifdef DOS_PROJECT data32 = READ_VREG(HEVC_SAO_CTRL1); data32 &= (~0x3000); - data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 + 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); @@ -4254,13 +4167,13 @@ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); data32 &= (~0x30); - data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 + data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); #else // m8baby test1902 data32 = READ_VREG(HEVC_SAO_CTRL1); data32 &= (~0x3000); - data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 + data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 data32 &= (~0xff0); //data32 |= 0x670; // Big-Endian per 64-bit data32 |= 0x880; // Big-Endian per 64-bit @@ -4274,7 +4187,7 @@ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); data32 &= (~0x30); - data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 + data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32 data32 &= (~0xF); data32 |= 0x8; // Big-Endian per 64-bit WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); @@ -4283,14 +4196,19 @@ /*CHANGE_DONE nnn*/ data32 = READ_VREG(HEVC_SAO_CTRL1); data32 &= (~0x3000); - data32 |= (hw->mem_map_mode << 12); /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */ + data32 |= (mem_map_mode << + 12); + +/* [13:12] axi_aformat, 0-Linear, + * 1-32x32, 2-64x32 + */ data32 &= (~0xff0); /* data32 |= 0x670; // Big-Endian per 64-bit */ #ifdef AOM_AV1_MMU_DW if (hw->dw_mmu_enable == 0) - data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */ + data32 |= endian; /* Big-Endian per 64-bit */ #else - data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */ + data32 |= endian; /* Big-Endian per 64-bit */ #endif data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ if (get_double_write_mode(hw) == 0) @@ -4318,8 +4236,7 @@ else data32 |= (1 << 8); /* NV12 */ } - data32 &= (~(3 << 14)); - data32 |= (2 << 14); + /* * [31:24] ar_fifo1_axi_thred * [23:16] ar_fifo0_axi_thred @@ -4345,14 +4262,9 @@ 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 ((get_double_write_mode(hw) & 0xf) == 8) { - WRITE_VREG(HEVC_SAO_CTRL26, 0xf); - data32 |= (0xff << 16); - } else if ((get_double_write_mode(hw) & 0xf) == 2 || + if ((get_double_write_mode(hw) & 0xf) == 2 || (get_double_write_mode(hw) & 0xf) == 3) data32 |= (0xff<<16); else if ((get_double_write_mode(hw) & 0xf) == 4 || @@ -4364,9 +4276,11 @@ data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); data32 &= (~0x30); /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */ - data32 |= (hw->mem_map_mode << 4); - data32 &= (~0xf); - data32 |= (hw->endian & 0xf); /* valid only when double write only */ + data32 |= (mem_map_mode << + 4); + data32 &= (~0xF); + data32 |= 0xf; /* valid only when double write only */ + /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ /* swap uv */ if (hw->is_used_v4l) { @@ -4376,8 +4290,7 @@ else data32 &= ~(1 << 12); /* NV12 */ } - data32 &= (~(3 << 8)); - data32 |= (2 << 8); + /* * [3:0] little_endian * [5:4] address_format 00:linear 01:32x32 10:64x32 @@ -4942,7 +4855,7 @@ lf->sharpness_level = hw->aom_param.p.loop_filter_sharpness_level; if (((hw->aom_param.p.loop_filter_mode_ref_delta_enabled)&3) == 3) { // enabled but and update - if (cm->prev_frame <= 0) { + if (cm->prev_frame == NULL) { // already initialized in Microcode lf->ref_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7); lf->ref_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7); @@ -4988,7 +4901,7 @@ } } //else if (hw->aom_param.p.loop_filter_mode_ref_delta_enabled == 1) { // enabled but no update else { // match c code -- not enabled, still need to copy prev to used for next - if ((cm->prev_frame <= 0) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) { + if ((cm->prev_frame == NULL) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) { av1_print(hw, AOM_DEBUG_HW_MORE, "[test.c] mode_ref_delta set to default\n"); lf->ref_deltas[0] = conv2int8((uint8_t)1,7); @@ -5004,16 +4917,18 @@ } else { av1_print(hw, AOM_DEBUG_HW_MORE, "[test.c] mode_ref_delta copy from prev_frame\n"); - lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0]; - lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1]; - lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2]; - lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3]; - lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4]; - lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5]; - lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6]; - lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7]; - lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0]; - lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1]; + if (cm->prev_frame) { + lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0]; + lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1]; + lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2]; + lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3]; + lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4]; + lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5]; + lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6]; + lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7]; + lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0]; + lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1]; + } } } lf->filter_level[0] = hw->aom_param.p.loop_filter_level_0; @@ -5021,23 +4936,24 @@ lf->filter_level_u = hw->aom_param.p.loop_filter_level_u; lf->filter_level_v = hw->aom_param.p.loop_filter_level_v; - cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0]; - cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1]; - cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2]; - cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3]; - cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4]; - cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5]; - cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6]; - cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7]; - cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0]; - cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1]; + if (cm->cur_frame) { + cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0]; + cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1]; + cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2]; + cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3]; + cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4]; + cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5]; + cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6]; + cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7]; + cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0]; + cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1]; - // get seg_4lf parameters from parser - seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1; - cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1; - cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1; - cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1; - + // get seg_4lf parameters from parser + seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1; + cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1; + cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1; + cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1; + } if (hw->aom_param.p.segmentation_enabled & 1) { // segmentation_enabled if (hw->aom_param.p.segmentation_enabled & 2) { // segmentation_update_data for (i = 0; i < MAX_SEGMENTS; i++) { @@ -5050,7 +4966,7 @@ } } // segmentation_update_data else { // no segmentation_update_data - if (cm->prev_frame <= 0) { + if (cm->prev_frame == NULL) { for (i=0;i<MAX_SEGMENTS;i++) { seg_4lf->seg_lf_info_y[i] = 0; seg_4lf->seg_lf_info_c[i] = 0; @@ -5106,7 +5022,7 @@ av1_print(hw, AOM_DEBUG_HW_MORE, "[test.c] cur_frame : %p prev_frame : %p - %p \n", cm->cur_frame, cm->prev_frame, av1_get_primary_ref_frame_buf(cm)); - if (cm->cur_frame <= 0) { + if (cm->cur_frame == NULL) { WRITE_VREG(AOM_AV1_CDF_BUFFER_W, buf_spec->cdf_buf.buf_start); WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W, buf_spec->seg_map.buf_start); } @@ -5121,7 +5037,7 @@ } cm->cur_frame->seg_mi_rows = cm->cur_frame->mi_rows; cm->cur_frame->seg_mi_cols = cm->cur_frame->mi_cols; - if (cm->prev_frame <= 0) { + if (cm->prev_frame == NULL) { WRITE_VREG(AOM_AV1_CDF_BUFFER_R, buf_spec->cdf_buf.buf_start); WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R, buf_spec->seg_map.buf_start); } else { @@ -5406,13 +5322,6 @@ } #endif #endif -#ifdef CO_MV_COMPRESS - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - data32 = READ_VREG(HEVC_MPRED_CTRL4); - data32 |= (1 << 1); - WRITE_VREG(HEVC_MPRED_CTRL4, data32); - } -#endif } config_aux_buf(hw); @@ -5518,13 +5427,10 @@ if (mask & HW_MASK_BACK) { /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/ - if (is_rdma_enable()) - rdma_back_end_work(hw->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); - } + + WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/ + for (i = 0; i < 1024; i++) + WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); } if (mask & HW_MASK_FRONT) { @@ -5852,14 +5758,25 @@ buf_alloc_width = 8192; buf_alloc_height = 4608; } - +#if 0 + hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w : + (buf_alloc_width ? buf_alloc_width : + (hw->vav1_amstream_dec_info.width ? + hw->vav1_amstream_dec_info.width : + hw->work_space_buf->max_width)); + hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h : + (buf_alloc_height ? buf_alloc_height : + (hw->vav1_amstream_dec_info.height ? + hw->vav1_amstream_dec_info.height : + hw->work_space_buf->max_height)); +#else hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w : (hw->vav1_amstream_dec_info.width ? hw->vav1_amstream_dec_info.width : (buf_alloc_width ? buf_alloc_width : hw->work_space_buf->max_width)); hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h : (hw->vav1_amstream_dec_info.height ? hw->vav1_amstream_dec_info.height : (buf_alloc_height ? buf_alloc_height : hw->work_space_buf->max_height)); - +#endif hw->pbi->frame_width = hw->init_pic_w; hw->pbi->frame_height = hw->init_pic_h; @@ -5872,9 +5789,9 @@ (hw->vav1_amstream_dec_info.width % 64) != 0)) { if (hw_to_vdec(hw)->canvas_mode != CANVAS_BLKMODE_LINEAR) - hw->mem_map_mode = 2; + mem_map_mode = 2; else { - hw->mem_map_mode = 0; + mem_map_mode = 0; av1_print(hw, AOM_DEBUG_HW_MORE, "vdec blkmod linear, force mem_map_mode 0\n"); } } @@ -5978,7 +5895,6 @@ } memset(hw->count_buffer_addr, 0, COUNT_BUF_SIZE); - vdec_set_vframe_comm(hw_to_vdec(hw), DRIVER_NAME); ret = vav1_mmu_map_alloc(hw); if (ret < 0) goto dma_alloc_fail; @@ -6003,18 +5919,20 @@ struct vdec_s *vdec = hw_to_vdec(hw); int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4; int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4; - int blkmode = hw->mem_map_mode; + int blkmode = mem_map_mode; /*CANVAS_BLKMODE_64X32*/ if (pic_config->double_write_mode) { canvas_w = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); canvas_h = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); - /* sao ctrl1 config aligned with 64, so aligned with 64 same */ - canvas_w = ALIGN(canvas_w, 64); + if (mem_map_mode == 0) + canvas_w = ALIGN(canvas_w, 32); + else + canvas_w = ALIGN(canvas_w, 64); canvas_h = ALIGN(canvas_h, 32); if (vdec->parallel_dec == 1) { @@ -6029,12 +5947,12 @@ pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1; } - config_cav_lut_ex(pic_config->y_canvas_index, + canvas_config_ex(pic_config->y_canvas_index, pic_config->dw_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC); - config_cav_lut_ex(pic_config->uv_canvas_index, + CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7); + canvas_config_ex(pic_config->uv_canvas_index, pic_config->dw_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7); #ifdef MULTI_INSTANCE_SUPPORT pic_config->canvas_config[0].phy_addr = @@ -6143,11 +6061,10 @@ if (kfifo_get(&hw->display_q, &vf)) { struct vframe_s *next_vf = NULL; uint8_t index = vf->index & 0xff; - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); + ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q)); if (index < hw->used_buf_num || (vf->type & VIDTYPE_V4L_EOS)) { hw->vf_get_count++; - vf->index_disp = hw->vf_get_count; if (debug & AOM_DEBUG_VFRAME) { struct BufferPool_s *pool = hw->common.buffer_pool; struct PIC_BUFFER_CONFIG_s *pic = @@ -6193,14 +6110,16 @@ static void vav1_vf_put(struct vframe_s *vf, void *op_arg) { struct AV1HW_s *hw = (struct AV1HW_s *)op_arg; - uint8_t index = vf->index & 0xff; + uint8_t index; unsigned long flags; if ((vf == NULL) || (hw == NULL)) return; + index = vf->index & 0xff; + kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); + ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q)); hw->vf_put_count++; if (debug & AOM_DEBUG_VFRAME) { lock_buffer_pool(hw->common.buffer_pool, flags); @@ -6222,6 +6141,10 @@ if (pool->frame_bufs[index].buf.vf_ref > 0) pool->frame_bufs[index].buf.vf_ref--; } + + if (hw->is_used_v4l) + pool->frame_bufs[index].buf.vframe_bound = true; + if (hw->wait_buf) WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1); @@ -6402,27 +6325,27 @@ (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) { vf->mem_handle = decoder_mmu_box_get_mem_handle( - hw->mmu_box_dw, pic->index); + hw->mmu_box_dw, hw->buffer_wrap[pic->index]); vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( hw->bmmu_box, - DW_HEADER_BUFFER_IDX(pic->BUF_index)); + DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index])); vf->mem_dw_handle = NULL; } else #endif { vf->mem_handle = decoder_mmu_box_get_mem_handle( - hw->mmu_box, pic->index); + hw->mmu_box, hw->buffer_wrap[pic->index]); vf->mem_head_handle = decoder_bmmu_box_get_mem_handle( hw->bmmu_box, - HEADER_BUFFER_IDX(pic->BUF_index)); + HEADER_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index])); if (hw->double_write_mode == 3) vf->mem_dw_handle = decoder_bmmu_box_get_mem_handle( hw->bmmu_box, - VF_BUFFER_IDX(pic->BUF_index)); + VF_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index])); else vf->mem_dw_handle = NULL; } @@ -6432,7 +6355,7 @@ } else { vf->mem_handle = decoder_bmmu_box_get_mem_handle( - hw->bmmu_box, VF_BUFFER_IDX(pic->BUF_index)); + hw->bmmu_box, VF_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index])); vf->mem_head_handle = NULL; vf->mem_dw_handle = NULL; /*vf->mem_head_handle = @@ -6442,47 +6365,22 @@ } } -static inline void av1_update_gvs(struct AV1HW_s *hw, struct vframe_s *vf, - struct PIC_BUFFER_CONFIG_s *pic_config) -{ - if (hw->gvs->frame_height != pic_config->y_crop_height) { - hw->gvs->frame_width = pic_config->y_crop_width; - hw->gvs->frame_height = pic_config->y_crop_height; - } - if (hw->gvs->frame_dur != hw->frame_dur) { - hw->gvs->frame_dur = hw->frame_dur; - if (hw->frame_dur != 0) - hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ? - 96000 / hw->frame_dur : (96000 / hw->frame_dur +1); - else - hw->gvs->frame_rate = -1; - } - if (vf && hw->gvs->ratio_control != vf->ratio_control) - hw->gvs->ratio_control = vf->ratio_control; - - hw->gvs->status = hw->stat | hw->fatal_error; - hw->gvs->error_count = hw->gvs->error_frame_count; - -} - static int prepare_display_buf(struct AV1HW_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config) { struct vframe_s *vf = NULL; - struct vdec_info tmp4x; int stream_offset = pic_config->stream_offset; struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; ulong nv_order = VIDTYPE_VIU_NV21; u32 pts_valid = 0, pts_us64_valid = 0; - u32 frame_size; + u32 frame_size = 0; + int i, reclac_flag = 0; av1_print(hw, AOM_DEBUG_VFRAME, "%s index = %d\r\n", __func__, pic_config->index); if (kfifo_get(&hw->newframe_q, &vf) == 0) { av1_print(hw, 0, "fatal error, no available buffer slot."); return -1; } - /* swap uv */ if (hw->is_used_v4l) { if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || @@ -6496,10 +6394,49 @@ display_frame_count[hw->index]++; if (vf) { + if (!force_pts_unstable && (hw->av1_first_pts_ready)) { + if (hw->is_used_v4l) { + if ((pic_config->timestamp == 0) || (pic_config->timestamp <= hw->last_timestamp)) { + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + if (hw->last_timestamp == hw->frame_mode_timestamp_save[i]) { + pic_config->timestamp = hw->frame_mode_timestamp_save[i - 1]; + break; + } + } + + if ((i == 0) || (pic_config->timestamp <= hw->last_timestamp)) { + av1_print(hw, AV1_DEBUG_OUT_PTS, + "no found timestamp %d, set 0. %lld, %lld\n", + i, pic_config->timestamp, hw->last_timestamp); + pic_config->timestamp = 0; + } + } + } else { + if ((pic_config->pts == 0) || ((pic_config->pts <= hw->last_pts) && + (pic_config->pts64 <= hw->last_pts_us64))) { + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + if ((hw->last_pts == hw->frame_mode_pts_save[i]) || + (hw->last_pts_us64 == hw->frame_mode_pts64_save[i])) { + pic_config->pts = hw->frame_mode_pts_save[i - 1]; + pic_config->pts64 = hw->frame_mode_pts64_save[i - 1]; + break; + } + } + + if ((i == 0) || (pic_config->pts <= hw->last_pts)) { + av1_print(hw, AV1_DEBUG_OUT_PTS, + "no found pts %d, set 0. %d, %d\n", + i, pic_config->pts, hw->last_pts); + pic_config->pts = 0; + pic_config->pts64 = 0; + } + } + } + } + if (hw->is_used_v4l) { vf->v4l_mem_handle = hw->m_BUF[pic_config->BUF_index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; if (hw->mmu_enable) { vf->mm_box.bmmu_box = hw->bmmu_box; vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->BUF_index]); @@ -6512,12 +6449,7 @@ if (vdec_frame_based(hw_to_vdec(hw))) { vf->pts = pic_config->pts; vf->pts_us64 = pic_config->pts64; - - if (hw->is_used_v4l && v4l_bitstream_id_enable) - vf->timestamp = pic_config->timestamp; - else - vf->timestamp = pic_config->pts64; - + vf->timestamp = pic_config->timestamp; if (vf->pts != 0 || vf->pts_us64 != 0) { pts_valid = 1; pts_us64_valid = 1; @@ -6545,6 +6477,68 @@ pts_valid = 1; pts_us64_valid = 1; } + + if (hw->av1_first_pts_ready) { + if (hw->is_used_v4l) { + if (hw->frame_dur && (vf->timestamp == 0)) { + vf->timestamp = hw->last_timestamp + + hw->timestamp_duration; + } + + if (!close_to(vf->timestamp, (hw->last_timestamp + + hw->timestamp_duration), 100)) { + vf->timestamp = hw->last_timestamp + + hw->timestamp_duration; + } + } else { + if (hw->frame_dur && ((vf->pts == 0) || (vf->pts_us64 == 0))) { + vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur); + vf->pts_us64 = hw->last_pts_us64 + + (DUR2PTS(hw->frame_dur) * 100 / 9); + reclac_flag = 1; + } + + if (!close_to(vf->pts, (hw->last_pts + DUR2PTS(hw->frame_dur)), 100)) { + vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur); + vf->pts_us64 = hw->last_pts_us64 + + (DUR2PTS(hw->frame_dur) * 100 / 9); + reclac_flag = 2; + } + } + + /* try find the closed pts in saved pts pool */ + if (reclac_flag) { + for (i = 0; i < FRAME_BUFFERS - 1; i++) { + if ((hw->frame_mode_pts_save[i] > vf->pts) && + (hw->frame_mode_pts_save[i + 1] < vf->pts)) { + if ((hw->frame_mode_pts_save[i] - vf->pts) > + (vf->pts - hw->frame_mode_pts_save[i + 1])) { + vf->pts = hw->frame_mode_pts_save[i + 1]; + vf->pts_us64 = hw->frame_mode_pts64_save[i + 1]; + } else { + vf->pts = hw->frame_mode_pts_save[i]; + vf->pts_us64 = hw->frame_mode_pts64_save[i]; + } + break; + } + } + if (i == (FRAME_BUFFERS - 1)) + hw->dur_recalc_flag = 1; + } + } else { + av1_print(hw, AV1_DEBUG_OUT_PTS, + "first pts %d change to save[%d] %d, ts: %llu\n", + vf->pts, hw->first_pts_index - 1, + hw->frame_mode_pts_save[hw->first_pts_index - 1], + hw->frame_mode_timestamp_save[hw->first_pts_index - 1]); + vf->pts = hw->frame_mode_pts_save[hw->first_pts_index - 1]; + vf->pts_us64 = hw->frame_mode_pts64_save[hw->first_pts_index - 1]; + vf->timestamp = hw->frame_mode_timestamp_save[hw->first_pts_index - 1]; + } + hw->last_pts = vf->pts; + hw->last_pts_us64 = vf->pts_us64; + hw->last_timestamp = vf->timestamp; + hw->av1_first_pts_ready = true; av1_print(hw, AV1_DEBUG_OUT_PTS, "av1 output slice type %d, dur %d, pts %d, pts64 %lld, ts: %llu\n", pic_config->slice_type, hw->frame_dur, vf->pts, vf->pts_us64, vf->timestamp); @@ -6575,10 +6569,10 @@ vf->dwHeadAddr = pic_config->header_dw_adr; else if ((mode == 1 || mode == 2 || mode == 4) && (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) { - vf->compHeadAddr = pic_config->header_dw_adr; - vf->fgs_valid = 0; - av1_print(hw, 0, - "Use dw mmu for display\n"); + vf->compHeadAddr = pic_config->header_dw_adr; + vf->fgs_valid = 0; + av1_print(hw, AOM_DEBUG_VFRAME, + "Use dw mmu for display\n"); } } #endif @@ -6594,7 +6588,7 @@ (pic_config->double_write_mode & 0x20) == 0) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= nv_order; + vf->type |= VIDTYPE_VIU_NV21; if ((pic_config->double_write_mode == 3 || pic_config->double_write_mode == 5) && (!IS_8K_SIZE(pic_config->y_crop_width, @@ -6655,11 +6649,11 @@ vf->width,vf->height, pic_config->width, pic_config->height); */ vf->width = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); vf->height = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); if (force_w_h != 0) { vf->width = (force_w_h >> 16) & 0xffff; vf->height = force_w_h & 0xffff; @@ -6668,11 +6662,11 @@ ((pic_config->double_write_mode & 0xf) == 2 || (pic_config->double_write_mode & 0xf) == 4)) { vf->compWidth = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); vf->compHeight = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(hw, + pic_config->double_write_mode); } else { vf->compWidth = pic_config->y_crop_width; vf->compHeight = pic_config->y_crop_height; @@ -6692,60 +6686,20 @@ decoder_do_frame_check(hw_to_vdec(hw), vf); vdec_vframe_ready(hw_to_vdec(hw), vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.pts_name, vf->pts); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); + 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)); hw->vf_pre_count++; +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC /*count info*/ - hw->gvs->frame_dur = hw->frame_dur; - vdec_count_info(hw->gvs, 0, stream_offset); - - hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id); - -#ifdef AUX_DATA_CRC - decoder_do_aux_data_check(hw_to_vdec(hw), pic_config->aux_data_buf, - pic_config->aux_data_size); + gvs->frame_dur = hw->frame_dur; + vdec_count_info(gvs, 0, stream_offset); #endif - - av1_print(hw, AV1_DEBUG_SEI_DETAIL, "%s aux_data_size = %d\n", - __func__, pic_config->aux_data_size); - - if (debug & AV1_DEBUG_SEI_DETAIL) { - int i = 0; - PR_INIT(128); - for (i = 0; i < pic_config->aux_data_size; i++) { - PR_FILL("%02x ", pic_config->aux_data_buf[i]); - if (((i + 1) & 0xf) == 0) - PR_INFO(hw->index); - } - PR_INFO(hw->index); - } - - if (hw->is_used_v4l) { - update_vframe_src_fmt(vf, - pic_config->aux_data_buf, - pic_config->aux_data_size, - false, hw->provider_name, NULL); - } - - av1_update_gvs(hw, vf, pic_config); - memcpy(&tmp4x, hw->gvs, sizeof(struct vdec_info)); - tmp4x.bit_depth_luma = bit_depth_luma; - tmp4x.bit_depth_chroma = bit_depth_chroma; - tmp4x.double_write_mode = pic_config->double_write_mode; - vdec_fill_vdec_frame(hw_to_vdec(hw), &hw->vframe_qos, &tmp4x, vf, pic_config->hw_decode_time); + hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id); if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vav1_vf_put(vav1_vf_get(hw), hw); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(hw->provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } else vav1_vf_put(vav1_vf_get(hw), hw); } @@ -6779,8 +6733,7 @@ } if (index == INVALID_IDX) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { + if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) { pr_err("[%d] EOS get free buff fail.\n", ctx->id); return -1; } @@ -6792,18 +6745,14 @@ vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb : hw->m_BUF[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - - av1_print(hw, 0, "[%d] AV1 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); + av1_print(hw, PRINT_FLAG_V4L_DETAIL, + "[%d] AV1 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } return 0; @@ -6844,21 +6793,10 @@ if (check_dma) hevc_mmu_dma_check(hw_to_vdec(hw)); - if (hw->is_used_v4l) { - int index = cm->cur_fb_idx_mmu; - struct internal_comp_buf *ibuf = - index_to_icomp_buf(hw, index); - - decoder_mmu_box_free_idx_tail( - ibuf->mmu_box, - ibuf->index, - hw->used_4k_num); - } else { - decoder_mmu_box_free_idx_tail( - hw->mmu_box, - cm->cur_fb_idx_mmu, - hw->used_4k_num); - } + decoder_mmu_box_free_idx_tail( + hw->mmu_box, + hw->buffer_wrap[cm->cur_fb_idx_mmu], + hw->used_4k_num); cm->cur_fb_idx_mmu = INVALID_IDX; hw->used_4k_num = -1; @@ -6893,7 +6831,7 @@ return; if (cm->cur_fb_idx_mmu != INVALID_IDX) { decoder_mmu_box_free_idx(hw->mmu_box, - cm->cur_fb_idx_mmu); + hw->buffer_wrap[cm->cur_fb_idx_mmu]); cm->cur_fb_idx_mmu = INVALID_IDX; hw->used_4k_num = -1; @@ -7164,12 +7102,12 @@ av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : %d\n", hitrate); hitrate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt; av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : %d\n", hitrate); + mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt; + mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt; } else { av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : na\n"); av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : na\n"); } - mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt; - mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt; return; } @@ -7199,7 +7137,7 @@ if ( raw_mcr_cnt != 0 ) { hitrate = 100*hit_mcr_cnt/raw_mcr_cnt; - av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %.2f\%\n", hitrate); + av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %d\n", hitrate); } else { av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : na\n"); } @@ -7399,36 +7337,9 @@ #endif -#if 0 -void release_unused_4k_ext(MMU_BUFF_MGR *mmumgr, int32_t cur_buf_idx, long used_4k_num) -{ - int32_t release_4k_position; - int32_t i; - - if(mmumgr->mmu_pic_count < 0) return; - - mmumgr->mmu_offset_seed = used_4k_num & 0xff; - if(used_4k_num > mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number) { - printk("[MMU MEM ERROR] : Use more 4K Page than allocated %d > ([%d] = %d)!!\r\n", used_4k_num, cur_buf_idx, mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number); - } - else printk("[MMU MEM RELEASE] : P%d(buffer %d) used %d of %d 4k buffer (%d%c)\r\n", mmumgr->mmu_pic_count, cur_buf_idx, used_4k_num, mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number, used_4k_num*100/mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number, '%'); - - for(i = used_4k_num; i<mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number; i++){ - release_4k_position = mmumgr->mmu_buf[cur_buf_idx].mmu_4k_index[i] - mmumgr->MC_BUFFER_START_4K_ADR; - printk("[MMU MEM RELEASE DEBUG] release_4k_position[%d] : 0x%x\n", i, release_4k_position+mmumgr->MC_BUFFER_START_4K_ADR); - mmumgr->mmu_4k_status[release_4k_position] = 0; - } - mmumgr->cur_mem_usage -= (mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number - used_4k_num)*4096; - mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number = used_4k_num; -} -#endif - int av1_continue_decoding(struct AV1HW_s *hw, int obu_type) { - int ret = 0; -#ifdef SANITY_CHECK - param_t* params = &hw->aom_param; -#endif + int ret; #if 1 //def CHANGE_DONE AV1Decoder *pbi = hw->pbi; @@ -7472,70 +7383,18 @@ } else { hw->new_compressed_data = 0; } -#ifdef SEND_MMU_USED_NUM - if (cm->prev_fb_idx != INVALID_IDX) { - long used_4k_num = aom_param.p.mmu_used_num; - if (used_4k_num != 0) { - printk("mmu free tail, index %d used_num 0x%x\n", - cm->prev_fb_idx, used_4k_num); - release_unused_4k_ext(&av1_mmumgr_m, cm->prev_fb_idx, used_4k_num); - } - -#ifdef AOM_AV1_MMU_DW - used_4k_num = aom_param.p.dw_mmu_used_num; - if (used_4k_num != 0) { - release_unused_4k_ext(&av1_mmumgr_dw, cm->prev_fb_idx, used_4k_num); - printk("dw mmu free tail, index %d used_num 0x%x\n", - cm->prev_fb_idx, used_4k_num); - } -#endif - } - cm->prev_fb_idx = INVALID_IDX; - -#endif -#ifdef SANITY_CHECK - ret = 0; + ret = av1_bufmgr_process(pbi, &hw->aom_param, + hw->new_compressed_data, obu_type); av1_print(hw, AOM_DEBUG_HW_MORE, - "Check Picture size, max (%d, %d), width/height (%d, %d), dec_width %d\n", - params->p.max_frame_width, - params->p.max_frame_height, - params->p.frame_width_scaled, - params->p.frame_height, - params->p.dec_frame_width - ); + "%s: pbi %p cm %p cur_frame %p\n", + __func__, pbi, cm, cm->cur_frame); - if (/*params->p.max_frame_width > MAX_PIC_WIDTH || - params->p.max_frame_height > MAX_PIC_HEIGHT ||*/ - (params->p.frame_width_scaled * params->p.frame_height) > MAX_SIZE_8K || - (params->p.dec_frame_width * params->p.frame_height) > MAX_SIZE_8K || - params->p.frame_width_scaled <= 0 || - params->p.dec_frame_width <= 0 || - params->p.frame_height <= 0) { - av1_print(hw, 0, "!!Picture size error, max (%d, %d), width/height (%d, %d), dec_width %d\n", - params->p.max_frame_width, - params->p.max_frame_height, - params->p.frame_width_scaled, - params->p.frame_height, - params->p.dec_frame_width - ); - ret = -1; - } -#endif - if (ret >= 0) { - ret = av1_bufmgr_process(pbi, &hw->aom_param, - hw->new_compressed_data, obu_type); - if (ret < 0) - return -1; - av1_print(hw, AOM_DEBUG_HW_MORE, - "%s: pbi %p cm %p cur_frame %p\n", - __func__, pbi, cm, cm->cur_frame); + av1_print(hw, AOM_DEBUG_HW_MORE, + "1+++++++++++++++++++++++++++++++++++%d %p\n", + ret, cm->cur_frame); + if (hw->new_compressed_data) + WRITE_VREG(PIC_END_LCU_COUNT, 0); - av1_print(hw, AOM_DEBUG_HW_MORE, - "1+++++++++++++++++++++++++++++++++++%d %p\n", - ret, cm->cur_frame); - if (hw->new_compressed_data) - WRITE_VREG(PIC_END_LCU_COUNT, 0); - } if (ret > 0) { /* the case when cm->show_existing_frame is 1 */ /*case 3016*/ @@ -7557,16 +7416,16 @@ av1_print(hw, AOM_DEBUG_HW_MORE, "aom_bufmgr_process=> %d,decode done, AOM_AV1_SEARCH_HEAD\r\n", ret); - WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); pbi->decode_idx++; pbi->bufmgr_proc_count++; hw->frame_decoded = 1; return 0; - } else if (ret < 0) { + } + else if (ret < 0) { hw->frame_decoded = 1; av1_print(hw, AOM_DEBUG_HW_MORE, - "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r. %d, AOM_AV1_SEARCH_HEAD\r\n", - ret, cm->error.error_code); + "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r., AOM_AV1_SEARCH_HEAD\r\n", ret); WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); return 0; } @@ -7628,25 +7487,18 @@ pbi->bufmgr_proc_count); pbi->decode_idx++; hw->frame_count++; -#ifdef SEND_MMU_USED_NUM - cm->prev_fb_idx = cm->cur_fb_idx_mmu; - cm->cur_fb_idx_mmu = cm->cur_frame->buf.index; -#endif cur_pic_config->slice_type = cm->cur_frame->frame_type; if (hw->chunk) { av1_print(hw, AV1_DEBUG_OUT_PTS, - "%s, config pic pts %d, pts64 %lld, ts: %lld\n", - __func__, hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp); + "%s, config pic pts %d, pts64 %lld\n", + __func__, hw->chunk->pts, hw->chunk->pts64); cur_pic_config->pts = hw->chunk->pts; cur_pic_config->pts64 = hw->chunk->pts64; cur_pic_config->timestamp = hw->chunk->timestamp; - - if (hw->is_used_v4l && !v4l_bitstream_id_enable) { - cur_pic_config->pts64 = hw->chunk->timestamp; - hw->chunk->timestamp = 0; - } + hw->chunk->pts = 0; + hw->chunk->pts64 = 0; + hw->chunk->timestamp = 0; } - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START); #ifdef DUAL_DECODE #else config_pic_size(hw, hw->aom_param.p.bit_depth); @@ -7659,14 +7511,12 @@ } if (ret >= 0 && hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) { - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); ret = av1_alloc_mmu(hw, cm->cur_frame->buf.index, cur_pic_config->y_crop_width, cur_pic_config->y_crop_height, hw->aom_param.p.bit_depth, hw->frame_mmu_map_addr); - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); if (ret >= 0) cm->cur_fb_idx_mmu = cm->cur_frame->buf.index; else @@ -7717,16 +7567,6 @@ config_dblk_hw(hw); - /* store segment_feature before shared sub-module run to fix mosaic on t5d */ - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) - WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index)); - else - WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index)); - if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled - WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO)); - else - WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0); - av1_print(hw, AOM_DEBUG_HW_MORE, "HEVC_DEC_STATUS_REG <= AOM_AV1_DECODE_SLICE\n"); WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE); @@ -7740,13 +7580,15 @@ cm->cur_frame->segment_feature[i] = (0x80000000 | (i << 22)); } } - } else { - av1_print(hw, AOM_DEBUG_HW_MORE, "Sequence head, Search next start code\n"); - cm->prev_fb_idx = INVALID_IDX; - //skip, search next start code - WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index)); + else + WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index)); + if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled + WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO)); + else + WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0); } - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END); return ret; #else @@ -7951,7 +7793,7 @@ frame->min_mv = a[0]; av1_print(hw, AV1_DEBUG_QOS_INFO, - "mv data %x a[0]= %x a[1]= %x a[2]= %x\n", + "mv data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); data = READ_VREG(HEVC_QP_INFO); @@ -7978,7 +7820,7 @@ frame->min_qp = a[0]; av1_print(hw, AV1_DEBUG_QOS_INFO, - "qp data %x a[0]= %x a[1]= %x a[2]= %x\n", + "qp data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); data = READ_VREG(HEVC_SKIP_INFO); @@ -8005,7 +7847,7 @@ frame->min_skip = a[0]; av1_print(hw, AV1_DEBUG_QOS_INFO, - "skip data %x a[0]= %x a[1]= %x a[2]= %x\n", + "skip data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); } else { uint32_t blk88_y_count; @@ -8341,20 +8183,19 @@ //printf("Error, dec_status of 0x%x, not supported!!!\n", dec_status); return -1; } - av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type); - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START); - if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) { - get_rpm_param(params); - } - else { - for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { - int32_t ii; - for (ii = 0; ii < 4; ii++) { - params->l.data[i+ii]=hw->rpm_ptr[i+3-ii]; + av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type); + + if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) { + get_rpm_param(params); + } + else { + for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { + int32_t ii; + for (ii = 0; ii < 4; ii++) { + params->l.data[i+ii]=hw->rpm_ptr[i+3-ii]; + } } } - } - ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END); params->p.enable_ref_frame_mvs = (params->p.seq_flags >> 7) & 0x1; params->p.enable_superres = (params->p.seq_flags >> 15) & 0x1; @@ -8381,29 +8222,14 @@ return av1_bufmgr_postproc(hw->pbi, hw->frame_decoded); } -static void vav1_get_comp_buf_info(struct AV1HW_s *hw, - struct vdec_comp_buf_info *info) -{ - u16 bit_depth = hw->param.p.bit_depth; - - info->max_size = av1_max_mmu_buf_size( - hw->max_pic_w, - hw->max_pic_h); - info->header_size = av1_get_header_size( - hw->frame_width, - hw->frame_height); - info->frame_buffer_size = av1_mmu_page_num( - hw, hw->frame_width, - hw->frame_height, - bit_depth == 0); -} - static int vav1_get_ps_info(struct AV1HW_s *hw, struct aml_vdec_ps_infos *ps) { - ps->visible_width = hw->frame_width; - ps->visible_height = hw->frame_height; - ps->coded_width = ALIGN(hw->frame_width, 64); - ps->coded_height = ALIGN(hw->frame_height, 64); + int dw_mode = v4l_parser_get_double_write_mode(hw); + + ps->visible_width = hw->frame_width / get_double_write_ratio(hw, dw_mode); + ps->visible_height = hw->frame_height / get_double_write_ratio(hw, dw_mode); + ps->coded_width = ALIGN(hw->frame_width, 32) / get_double_write_ratio(hw, dw_mode); + ps->coded_height = ALIGN(hw->frame_height, 32) / get_double_write_ratio(hw, dw_mode); ps->dpb_size = hw->used_buf_num; return 0; @@ -8420,7 +8246,6 @@ if (ctx->param_sets_from_ucode && hw->res_ch_flag == 0) { struct aml_vdec_ps_infos ps; - struct vdec_comp_buf_info comp; if ((cm->width != 0 && cm->height != 0) && @@ -8431,11 +8256,6 @@ "%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, cm->height, hw->frame_width, hw->frame_height); - if (get_valid_double_write_mode(hw) != 16) { - vav1_get_comp_buf_info(hw, &comp); - vdec_v4l_set_comp_buf_info(ctx, &comp); - } - vav1_get_ps_info(hw, &ps); vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); @@ -8459,16 +8279,9 @@ int obu_type; int ret = 0; - if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE || - dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE || - dec_status == AOM_AV1_FRAME_PARSER_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START); - } - else if (dec_status == AOM_AV1_DEC_PIC_END || - dec_status == AOM_NAL_DECODE_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START); - } - + /*if (hw->wait_buf) + * pr_info("set wait_buf to 0\r\n"); + */ if (hw->eos) return IRQ_HANDLED; hw->wait_buf = 0; @@ -8482,7 +8295,6 @@ dec_again_process(hw); else { hw->dec_result = DEC_RESULT_DONE; - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); vdec_schedule_work(&hw->work); } } @@ -8490,8 +8302,6 @@ return IRQ_HANDLED; } else if (dec_status == AOM_AV1_DEC_PIC_END) { struct AV1_Common_s *const cm = &hw->common; - struct PIC_BUFFER_CONFIG_s *frame = &cm->cur_frame->buf; - struct vdec_s *vdec = hw_to_vdec(hw); #if 1 u32 fg_reg0, fg_reg1, num_y_points, num_cb_points, num_cr_points; WRITE_VREG(HEVC_FGS_IDX, 0); @@ -8521,12 +8331,6 @@ #ifdef USE_DEC_PIC_END if (READ_VREG(PIC_END_LCU_COUNT) != 0) { hw->frame_decoded = 1; - if (cm->cur_frame && vdec->mvfrm && frame) { - frame->hw_decode_time = - local_clock() - vdec->mvfrm->hw_decode_start; - frame->frame_size2 = vdec->mvfrm->frame_size; - } - hw->gvs->frame_count = hw->frame_count; /* In c module, multi obus are put in one packet, which is decoded with av1_receive_compressed_data(). @@ -8557,27 +8361,17 @@ if (cm->cur_frame != NULL) { hevc_mmu_dma_check(hw_to_vdec(hw)); - av1_print(hw, AOM_DEBUG_HW_MORE, "mmu free tail, index %d used_num 0x%x\n", + av1_print(hw, AOM_DEBUG_HW_MORE, "mmu free tail, index %d used_num 0x%lx\n", cm->cur_frame->buf.index, used_4k_num); - if (hw->is_used_v4l) { - struct internal_comp_buf *ibuf = - index_to_icomp_buf(hw, cm->cur_fb_idx_mmu); - - decoder_mmu_box_free_idx_tail( - ibuf->mmu_box, - ibuf->index, - used_4k_num); - } else { - decoder_mmu_box_free_idx_tail(hw->mmu_box, - cm->cur_frame->buf.index, used_4k_num); - } + decoder_mmu_box_free_idx_tail(hw->mmu_box, + hw->buffer_wrap[cm->cur_frame->buf.index], used_4k_num); #ifdef AOM_AV1_MMU_DW if (hw->dw_mmu_enable) { used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16); decoder_mmu_box_free_idx_tail(hw->mmu_box_dw, - cm->cur_frame->buf.index, used_4k_num); - av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%x\n", + hw->buffer_wrap[cm->cur_frame->buf.index], used_4k_num); + av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%lx\n", cm->cur_frame->buf.index, used_4k_num); } #endif @@ -8599,7 +8393,7 @@ hw->frame_decoded && READ_VREG(HEVC_SHIFT_BYTE_COUNT) < hw->data_size) { #ifdef DEBUG_CRC_ERROR - if ((crc_debug_flag & 0x40) && cm->cur_frame) + if (crc_debug_flag & 0x40) dump_mv_buffer(hw, &cm->cur_frame->buf); #endif WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); @@ -8608,10 +8402,9 @@ hw->fgs_valid); if (hw->config_next_ref_info_flag) config_next_ref_info_hw(hw); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); } else { #ifdef DEBUG_CRC_ERROR - if ((crc_debug_flag & 0x40) && cm->cur_frame) + if (crc_debug_flag & 0x40) dump_mv_buffer(hw, &cm->cur_frame->buf); #endif hw->dec_result = DEC_RESULT_DONE; @@ -8620,13 +8413,13 @@ if (mcrcc_cache_alg_flag) dump_hit_rate(hw); #endif - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); vdec_schedule_work(&hw->work); } } else { av1_print(hw, AOM_DEBUG_HW_MORE, "PIC_END, fgs_valid %d search head ...\n", hw->fgs_valid); + WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); #ifdef USE_DEC_PIC_END if (READ_VREG(PIC_END_LCU_COUNT) != 0) { hw->frame_decoded = 1; @@ -8637,13 +8430,11 @@ we assume each packet must and only include one picture of data (LCUs) or cm->show_existing_frame is 1 */ - if (cm->cur_frame) - av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", - cm->cur_frame? cm->cur_frame->buf.index:-1); + av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", + cm->cur_frame? cm->cur_frame->buf.index:-1); config_next_ref_info_hw(hw); } #endif - WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); /* if (debug & AV1_DEBUG_BUFMGR_MORE) @@ -8721,9 +8512,8 @@ hw->mv_buf_margin = hw->used_buf_num - REF_FRAMES_4K + 1; if (((hw->max_pic_w % 64) != 0) && (hw_to_vdec(hw)->canvas_mode != CANVAS_BLKMODE_LINEAR)) - hw->mem_map_mode = 2; - av1_print(hw, 0, - "force 8k double write 4, mem_map_mode %d\n", hw->mem_map_mode); + mem_map_mode = 2; + av1_print(hw, 0, "force 8k double write 4, mem_map_mode %d\n", mem_map_mode); } vav1_mmu_map_alloc(hw); if (hw->mmu_enable) @@ -8736,15 +8526,6 @@ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0); } #endif - - /*v4l2 alloc new mv when max size changed */ - if (hw->is_used_v4l) { - /* now less than 8k use fix mv buf size */ - if (IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h) && hw->pic_list_init_done) { - if (init_mv_buf_list(hw) < 0) - pr_err("%s: !!!!Error, reinit_mv_buf_list fail\n", __func__); - } - } } bit_depth_luma = hw->aom_param.p.bit_depth; bit_depth_chroma = hw->aom_param.p.bit_depth; @@ -8782,7 +8563,6 @@ "AOM_AV1_SEQ_HEAD_PARSER_DONE, search head ...\n"); WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD); hw->process_busy = 0; - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); return IRQ_HANDLED; } #ifndef USE_DEC_PIC_END @@ -8797,9 +8577,8 @@ we assume each packet must and only include one picture of data (LCUs) or cm->show_existing_frame is 1 */ - if (cm->cur_frame) - av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", - cm->cur_frame? cm->cur_frame->buf.index:-1); + av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n", + cm->cur_frame? cm->cur_frame->buf.index:-1); } } #endif @@ -8849,14 +8628,8 @@ if (!v4l_res_change(hw)) { if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) { struct aml_vdec_ps_infos ps; - struct vdec_comp_buf_info comp; pr_info("set ucode parse\n"); - if (get_valid_double_write_mode(hw) != 16) { - vav1_get_comp_buf_info(hw, &comp); - vdec_v4l_set_comp_buf_info(ctx, &comp); - } - vav1_get_ps_info(hw, &ps); /*notice the v4l2 codec.*/ vdec_v4l_set_ps_infos(ctx, &ps); @@ -8874,18 +8647,6 @@ } } - if (hw->one_package_frame_cnt) { - if (get_free_buf_count(hw) <= 0) { - hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER; - hw->cur_obu_type = obu_type; - hw->process_busy = 0; - vdec_schedule_work(&hw->work); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); - return IRQ_HANDLED; - } - } - hw->one_package_frame_cnt++; - ret = av1_continue_decoding(hw, obu_type); hw->postproc_done = 0; hw->process_busy = 0; @@ -8899,7 +8660,7 @@ vdec_schedule_work(&hw->work); } } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); + return IRQ_HANDLED; } @@ -8914,16 +8675,6 @@ WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); dec_status = READ_VREG(HEVC_DEC_STATUS_REG) & 0xff; - - if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE || - dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE || - dec_status == AOM_AV1_FRAME_PARSER_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE); - } - else if (dec_status == AOM_AV1_DEC_PIC_END || - dec_status == AOM_NAL_DECODE_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE); - } if (!hw) return IRQ_HANDLED; if (hw->init_flag == 0) @@ -9048,20 +8799,19 @@ hw->process_busy = 0; return IRQ_HANDLED; } - if (get_free_buf_count(hw) <= 0) { - /* - if (hw->wait_buf == 0) - pr_info("set wait_buf to 1\r\n"); - */ - hw->wait_buf = 1; - hw->process_busy = 0; - av1_print(hw, AV1_DEBUG_BUFMGR, - "free buf not enough = %d\n", - get_free_buf_count(hw)); - return IRQ_HANDLED; - } } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END); + if (get_free_buf_count(hw) <= 0) { + /* + if (hw->wait_buf == 0) + pr_info("set wait_buf to 1\r\n"); + */ + hw->wait_buf = 1; + hw->process_busy = 0; + av1_print(hw, AV1_DEBUG_BUFMGR, + "free buf not enough = %d\n", + get_free_buf_count(hw)); + return IRQ_HANDLED; + } return IRQ_WAKE_THREAD; } @@ -9077,10 +8827,10 @@ frame_height * fps; } -static void vav1_put_timer_func(struct timer_list *timer) +static void vav1_put_timer_func(unsigned long arg) { - struct AV1HW_s *hw = container_of(timer, - struct AV1HW_s, timer); + struct AV1HW_s *hw = (struct AV1HW_s *)arg; + struct timer_list *timer = &hw->timer; uint8_t empty_flag; unsigned int buf_level; @@ -9286,18 +9036,19 @@ vstatus->error_count = 0; vstatus->status = av1->stat | av1->fatal_error; vstatus->frame_dur = av1->frame_dur; -//#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC - vstatus->bit_rate = av1->gvs->bit_rate; - vstatus->frame_data = av1->gvs->frame_data; - vstatus->total_data = av1->gvs->total_data; - vstatus->frame_count = av1->gvs->frame_count; - vstatus->error_frame_count = av1->gvs->error_frame_count; - vstatus->drop_frame_count = av1->gvs->drop_frame_count; - vstatus->samp_cnt = av1->gvs->samp_cnt; - vstatus->offset = av1->gvs->offset; +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + vstatus->bit_rate = gvs->bit_rate; + 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); -//#endif +#endif return 0; } @@ -9441,6 +9192,9 @@ hw->saved_resolution = 0; hw->get_frame_dur = false; on_no_keyframe_skiped = 0; + hw->first_pts_index = 0; + hw->dur_recalc_flag = 0; + hw->av1_first_pts_ready = false; width = hw->vav1_amstream_dec_info.width; height = hw->vav1_amstream_dec_info.height; hw->frame_dur = @@ -9521,10 +9275,12 @@ fw->len = fw_size; INIT_WORK(&hw->set_clk_work, av1_set_clk); - timer_setup(&hw->timer, vav1_put_timer_func, 0); + init_timer(&hw->timer); #ifdef MULTI_INSTANCE_SUPPORT if (hw->m_ins_flag) { + hw->timer.data = (ulong) hw; + hw->timer.function = vav1_put_timer_func; hw->timer.expires = jiffies + PUT_INTERVAL; /*add_timer(&hw->timer); @@ -9574,18 +9330,16 @@ #endif hw->provider_name = PROVIDER_NAME; #ifdef MULTI_INSTANCE_SUPPORT - if (!hw->is_used_v4l) { - vf_provider_init(&vav1_vf_prov, hw->provider_name, - &vav1_vf_provider, hw); - vf_reg_provider(&vav1_vf_prov); - vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL); - if (hw->frame_dur != 0) { - if (!is_reset) - vf_notify_receiver(hw->provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long)hw->frame_dur)); - } + vf_provider_init(&vav1_vf_prov, hw->provider_name, + &vav1_vf_provider, hw); + vf_reg_provider(&vav1_vf_prov); + vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL); + if (hw->frame_dur != 0) { + if (!is_reset) + vf_notify_receiver(hw->provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)hw->frame_dur)); } #else vf_provider_init(&vav1_vf_prov, hw->provider_name, &vav1_vf_provider, @@ -9598,10 +9352,13 @@ #endif hw->stat |= STAT_VF_HOOK; + hw->timer.data = (ulong)hw; + hw->timer.function = vav1_put_timer_func; hw->timer.expires = jiffies + PUT_INTERVAL; - add_timer(&hw->timer); hw->stat |= STAT_VDEC_RUN; + + add_timer(&hw->timer); hw->stat |= STAT_TIMER_ARM; amhevc_start(); @@ -9630,7 +9387,7 @@ hw->stat &= ~STAT_TIMER_ARM; } - if (!hw->is_used_v4l && (hw->stat & STAT_VF_HOOK)) { + if (hw->stat & STAT_VF_HOOK) { if (!is_reset) vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -9674,7 +9431,7 @@ hw->stat &= ~STAT_TIMER_ARM; } - if (!hw->is_used_v4l && (hw->stat & STAT_VF_HOOK)) { + if (hw->stat & STAT_VF_HOOK) { if (!is_reset) vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -9715,7 +9472,7 @@ } hw->need_cache_size = buf_size * SZ_1M; hw->sc_start_time = get_jiffies_64(); - if (hw->mmu_enable && !hw->is_used_v4l) { + if (hw->mmu_enable) { int count = FRAME_BUFFERS; hw->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, hw->index /* * 2*/, count, @@ -9775,12 +9532,13 @@ #ifndef MULTI_INSTANCE_SUPPORT int i; #endif - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TM2) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) || - ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && !is_meson_rev_b())) { - pr_err("av1 unsupported on cpu %d, is_tm2_revb %d\n", + pr_debug("%s\n", __func__); + + if (!(is_cpu_tm2_revb() || + (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2))) { + pr_err("unsupport av1, cpu %d, is_tm2_revb %d\n", get_cpu_major_id(), is_cpu_tm2_revb()); - return -EINVAL; + return -EFAULT; } mutex_lock(&vav1_mutex); @@ -9932,12 +9690,6 @@ cma_dev = pdata->cma_dev; #endif - hw->endian = HEVC_CONFIG_LITTLE_ENDIAN; - if (is_support_vdec_canvas()) - hw->endian = HEVC_CONFIG_BIG_ENDIAN; - if (endian) - hw->endian = endian; - #ifdef MULTI_INSTANCE_SUPPORT pdata->private = hw; pdata->dec_status = vav1_dec_status; @@ -10110,12 +9862,6 @@ /* finished decoding one frame or error, * notify vdec core to switch context */ - if (hw->dec_result != AOM_AV1_RESULT_NEED_MORE_BUFFER) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START); - - if (hw->dec_result == DEC_RESULT_AGAIN) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN); - av1_print(hw, PRINT_FLAG_VDEC_DETAIL, "%s dec_result %d %x %x %x\n", __func__, @@ -10123,21 +9869,6 @@ READ_VREG(HEVC_STREAM_LEVEL), READ_VREG(HEVC_STREAM_WR_PTR), READ_VREG(HEVC_STREAM_RD_PTR)); - - if (hw->dec_result == AOM_AV1_RESULT_NEED_MORE_BUFFER) { - reset_process_time(hw); - if (get_free_buf_count(hw) <= 0) { - hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER; - vdec_schedule_work(&hw->work); - } else { - av1_release_bufs(hw); - av1_continue_decoding(hw, hw->cur_obu_type); - hw->postproc_done = 0; - start_process_time(hw); - } - return; - } - if (((hw->dec_result == DEC_RESULT_GET_DATA) || (hw->dec_result == DEC_RESULT_GET_DATA_RETRY)) && (hw_to_vdec(hw)->next_status != @@ -10160,7 +9891,7 @@ } if (get_free_buf_count(hw) >= - hw->run_ready_min_buf_num) { + run_ready_min_buf_num) { int r; int decode_size; r = vdec_prepare_input(vdec, &hw->chunk); @@ -10273,7 +10004,6 @@ del_timer_sync(&hw->timer); hw->stat &= ~STAT_TIMER_ARM; } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END); /* mark itself has all HW resource released and input released */ if (vdec->parallel_dec == 1) vdec_core_finish_run(vdec, CORE_MASK_HEVC); @@ -10288,35 +10018,6 @@ vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK); return 0; } - -static bool is_avaliable_buffer(struct AV1HW_s *hw) -{ - AV1_COMMON *cm = &hw->common; - RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - int i, free_count = 0; - - if (ctx->cap_pool.dec < hw->used_buf_num) { - free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - if (free_count && - !ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) { - return false; - } - } - - for (i = 0; i < hw->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.index >= 0) && - frame_bufs[i].buf.cma_alloc_addr) { - free_count++; - } - } - - return free_count < hw->run_ready_min_buf_num ? 0 : 1; -} - static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct AV1HW_s *hw = @@ -10329,17 +10030,8 @@ return ret; if (!hw->first_sc_checked && hw->mmu_enable) { - int size; - void * mmu_box; + int size = decoder_mmu_box_sc_check(hw->mmu_box, tvp); - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - mmu_box = ctx->mmu_box; - } else - mmu_box = hw->mmu_box; - - size = decoder_mmu_box_sc_check(mmu_box, tvp); hw->first_sc_checked = 1; av1_print(hw, 0, "av1 cached=%d need_size=%d speed= %d ms\n", size, (hw->need_cache_size >> PAGE_SHIFT), @@ -10353,7 +10045,7 @@ } if (get_free_buf_count(hw) >= - hw->run_ready_min_buf_num) { + run_ready_min_buf_num) { if (vdec->parallel_dec == 1) ret = CORE_MASK_HEVC; else @@ -10366,19 +10058,17 @@ if (ctx->param_sets_from_ucode) { if (hw->v4l_params_parsed) { - if (ctx->cap_pool.dec < hw->used_buf_num) { - if (is_avaliable_buffer(hw)) - ret = CORE_MASK_HEVC; - else - ret = 0; - } + if ((ctx->cap_pool.in < hw->used_buf_num) && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + run_ready_min_buf_num) + ret = 0; } else { if (ctx->v4l_resolution_change) ret = 0; } } else if (ctx->cap_pool.in < ctx->dpb_size) { if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < - hw->run_ready_min_buf_num) + run_ready_min_buf_num) ret = 0; } } @@ -10394,30 +10084,105 @@ return ret; } -static void av1_frame_mode_cal_dur(struct AV1HW_s *hw) +static void av1_frame_mode_pts_save(struct AV1HW_s *hw) { + u64 i, valid_pts_diff_cnt, pts_diff_sum; + u64 in_pts_diff, last_valid_pts_diff, calc_dur; + if (hw->chunk == NULL) - return; - av1_print(hw, AV1_DEBUG_OUT_PTS, - "run_front: pts %d, pts64 %lld, ts: %llu\n", - hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp); + return; + /* no return when first pts is 0 */ + if (hw->first_pts_index) { + /* filtration pts 0 and continuous same pts */ + if ((hw->chunk->pts == 0) || + (hw->frame_mode_pts_save[0] == hw->chunk->pts)) + return; - if (hw->pts_diff_count > FRAME_BUFFERS) - return ; + /* fps change, frame dur change to lower or higher, + * can't find closed pts in saved pool */ + if ((hw->dur_recalc_flag) || + (hw->last_pts > hw->chunk->pts)) { + hw->av1_first_pts_ready = 0; + hw->first_pts_index = 0; + hw->get_frame_dur = 0; + hw->dur_recalc_flag = 0; + memset(hw->frame_mode_pts_save, 0, + sizeof(hw->frame_mode_pts_save)); + memset(hw->frame_mode_pts64_save, 0, + sizeof(hw->frame_mode_pts64_save)); + /*v4l use*/ + memset(hw->frame_mode_timestamp_save, 0, + sizeof(hw->frame_mode_timestamp_save)); + } + } + av1_print(hw, AV1_DEBUG_OUT_PTS, + "run_front: pts %d, pts64 %lld, ts: %llu\n", + hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp); - if ((hw->chunk->pts > hw->last_chunk_pts) && (hw->last_chunk_pts > 0)) { - hw->pts_diff_count++; - hw->pts_diff_sum = hw->pts_diff_sum + (hw->chunk->pts - hw->last_chunk_pts); - if (hw->pts_diff_count > FRAME_BUFFERS) { - u32 calc_dur = (u32)div_u64(div_u64(hw->pts_diff_sum, hw->pts_diff_count)*96, 90); - if ((calc_dur <= 16000) && (calc_dur >= 800)) { - av1_print(hw, 0, "change to calc dur %d, old dur %d\n", calc_dur, hw->frame_dur); - hw->frame_dur = calc_dur; - } - } + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + hw->frame_mode_pts_save[i] = hw->frame_mode_pts_save[i - 1]; + hw->frame_mode_pts64_save[i] = hw->frame_mode_pts64_save[i - 1]; + hw->frame_mode_timestamp_save[i] = hw->frame_mode_timestamp_save[i - 1]; + } + hw->frame_mode_pts_save[0] = hw->chunk->pts; + hw->frame_mode_pts64_save[0] = hw->chunk->pts64; + hw->frame_mode_timestamp_save[0] = hw->chunk->timestamp; + if (hw->first_pts_index < ARRAY_SIZE(hw->frame_mode_pts_save)) + hw->first_pts_index++; + /* frame duration check, vdec_secure return for nts problem */ + if ((!hw->first_pts_index) || hw->get_frame_dur || vdec_secure(hw_to_vdec(hw))) + return; + valid_pts_diff_cnt = 0; + pts_diff_sum = 0; + + for (i = 0; i < FRAME_BUFFERS - 1; i++) { + if (hw->is_used_v4l) { + if ((hw->frame_mode_timestamp_save[i] > hw->frame_mode_timestamp_save[i + 1]) && + (hw->frame_mode_timestamp_save[i + 1] != 0)) + in_pts_diff = hw->frame_mode_timestamp_save[i] + - hw->frame_mode_timestamp_save[i + 1]; + else + in_pts_diff = 0; + } else { + if ((hw->frame_mode_pts_save[i] > hw->frame_mode_pts_save[i + 1]) && + (hw->frame_mode_pts_save[i + 1] != 0)) + in_pts_diff = hw->frame_mode_pts_save[i] + - hw->frame_mode_pts_save[i + 1]; + else + in_pts_diff = 0; } - hw->last_chunk_pts = hw->chunk->pts; + if (in_pts_diff < 100 || + (valid_pts_diff_cnt && (!close_to(in_pts_diff, last_valid_pts_diff, 100)))) + in_pts_diff = 0; + else { + last_valid_pts_diff = in_pts_diff; + valid_pts_diff_cnt++; + } + + pts_diff_sum += in_pts_diff; + } + + if (!valid_pts_diff_cnt) { + av1_print(hw, 0, "checked no avaliable pts\n"); + return; + } + + calc_dur = PTS2DUR(pts_diff_sum / valid_pts_diff_cnt); + if ((!close_to(calc_dur, hw->frame_dur, 10)) && + (calc_dur < 9601) && (calc_dur > 800)) { + av1_print(hw, 0, "change to calc dur %lld, old dur %d\n", calc_dur, hw->frame_dur); + hw->frame_dur = calc_dur; + hw->get_frame_dur = true; + } else { + if (hw->frame_count > FRAME_BUFFERS) + hw->get_frame_dur = true; + } + + if (hw->is_used_v4l) { + hw->timestamp_duration = + pts_diff_sum / valid_pts_diff_cnt; + } } static void run_front(struct vdec_s *vdec) @@ -10446,8 +10211,7 @@ hw->dec_result = DEC_RESULT_NONE; hw->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT); - av1_frame_mode_cal_dur(hw); - + av1_frame_mode_pts_save(hw); if (debug & PRINT_FLAG_VDEC_STATUS) { if (vdec_frame_based(vdec) && hw->chunk && !vdec_secure(vdec)) { u8 *data = NULL; @@ -10494,7 +10258,6 @@ hw->start_shift_bytes); } } - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START); if (vdec->mc_loaded) { /*firmware have load before, and not changes to another. @@ -10522,14 +10285,12 @@ vdec->mc_type = VFORMAT_AV1; #endif } - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END); - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START); if (av1_hw_ctx_restore(hw) < 0) { vdec_schedule_work(&hw->work); return; } - ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END); + vdec_enable_input(vdec); WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); @@ -10541,8 +10302,6 @@ WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); size = hw->chunk->size + (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1)); - if (vdec->mvfrm) - vdec->mvfrm->frame_size = hw->chunk->size; } hw->data_size = size; WRITE_VREG(HEVC_DECODE_SIZE, size); @@ -10575,19 +10334,14 @@ struct AV1HW_s *hw = (struct AV1HW_s *)vdec->private; - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START); av1_print(hw, PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n", __func__, mask); run_count[hw->index]++; - if (vdec->mvfrm) - vdec->mvfrm->hw_decode_start = local_clock(); hw->vdec_cb_arg = arg; hw->vdec_cb = callback; - hw->one_package_frame_cnt = 0; run_front(vdec); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END); } static void av1_decode_ctx_reset(struct AV1HW_s *hw) @@ -10608,6 +10362,11 @@ for (i = 0; i < MV_BUFFER_NUM; i++) { if (hw->m_mv_BUF[i].start_adr) { + if (mv_buf_dynamic_alloc) { + decoder_bmmu_box_free_idx(hw->bmmu_box, MV_BUFFER_IDX(i)); + hw->m_mv_BUF[i].start_adr = 0; + hw->m_mv_BUF[i].size = 0; + } hw->m_mv_BUF[i].used_flag = 0; } } @@ -10700,7 +10459,7 @@ hw->no_head ); - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -10722,14 +10481,14 @@ hw->vf_get_count, hw->vf_put_count, get_free_buf_count(hw), - hw->run_ready_min_buf_num + run_ready_min_buf_num ); dump_pic_list(hw); for (i = 0; i < MAX_BUF_NUM; i++) { av1_print(hw, 0, - "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n", + "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n", i, hw->m_mv_BUF[i].start_adr, hw->m_mv_BUF[i].size, @@ -10821,19 +10580,20 @@ 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; u32 work_buf_size; struct BuffInfo_s *p_buf_info; - struct AV1HW_s *hw = NULL; - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TM2) || - (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) || - ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && !is_meson_rev_b())) { - pr_err("av1 unsupported on cpu %d, is_tm2_revb %d\n", + struct BUF_s BUF[MAX_BUF_NUM]; + struct AV1HW_s *hw = NULL; + pr_debug("%s\n", __func__); + + if (!(is_cpu_tm2_revb() || + (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2))) { + pr_err("unsupport av1, cpu %d, is_tm2_revb %d\n", get_cpu_major_id(), is_cpu_tm2_revb()); - return -EINVAL; + return -EFAULT; } if (pdata == NULL) { @@ -10876,35 +10636,19 @@ pdata->threaded_irq_handler = av1_threaded_irq_cb; pdata->dump_state = av1_dump_state; + memcpy(&BUF[0], &hw->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + memcpy(&hw->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + hw->index = pdev->id; - if (is_rdma_enable()) { - hw->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hw->rdma_phy_adr, GFP_KERNEL); - for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) { - hw->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff; - hw->rdma_adr[i * 4 + 1] = i; - hw->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff; - hw->rdma_adr[i * 4 + 3] = 0; - if (i == SCALELUT_DATA_WRITE_NUM - 1) { - hw->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000; - } - } - } - snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name), + + snprintf(hw->vdec_name, sizeof(hw->vdec_name), "av1-%d", hw->index); - snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name), - "%s-pts", hw->trace.vdec_name); - snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name), - "%s-newframe_q", hw->trace.vdec_name); - snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name), - "%s-dispframe_q", hw->trace.vdec_name); - snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name), - "decoder_time%d", pdev->id); - snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name), - "decoder_run_time%d", pdev->id); - snprintf(hw->trace.decode_header_memory_time_name, sizeof(hw->trace.decode_header_memory_time_name), - "decoder_header_time%d", pdev->id); - snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name), - "decoder_work_time%d", pdev->id); + snprintf(hw->pts_name, sizeof(hw->pts_name), + "%s-pts", hw->vdec_name); + snprintf(hw->new_q_name, sizeof(hw->new_q_name), + "%s-newframe_q", hw->vdec_name); + snprintf(hw->disp_q_name, sizeof(hw->disp_q_name), + "%s-dispframe_q", hw->vdec_name); if (pdata->use_vfm_path) snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, VFM_DEC_PROVIDER_NAME); @@ -10926,12 +10670,18 @@ hevc_pair = (struct AV1HW_s *)pdata->master->private; else if (pdata->slave) hevc_pair = (struct AV1HW_s *)pdata->slave->private; + + if (hevc_pair) + hw->shift_byte_count_lo = hevc_pair->shift_byte_count_lo; } #endif else snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vav1_vf_provider, hw); + hw->provider_name = pdata->vf_provider_name; platform_set_drvdata(pdev, pdata); @@ -11069,38 +10819,25 @@ } hw->vf_dp = vf_dp; } else { - u32 force_w, force_h; - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) { - force_w = 1920; - force_h = 1088; - } else { - force_w = 8192; - force_h = 4608; - } + /*hw->vav1_amstream_dec_info.width = 0; + hw->vav1_amstream_dec_info.height = 0; + hw->vav1_amstream_dec_info.rate = 30;*/ if (hw->vav1_amstream_dec_info.width) hw->max_pic_w = hw->vav1_amstream_dec_info.width; else - hw->max_pic_w = force_w; + hw->max_pic_w = 8192; if (hw->vav1_amstream_dec_info.height) hw->max_pic_h = hw->vav1_amstream_dec_info.height; else - hw->max_pic_h = force_h; + hw->max_pic_h = 4608; hw->double_write_mode = double_write_mode; } - hw->endian = HEVC_CONFIG_LITTLE_ENDIAN; if (!hw->is_used_v4l) { - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vav1_vf_provider, hw); + hw->mem_map_mode = mem_map_mode; } - hw->mem_map_mode = mem_map_mode; - if (is_support_vdec_canvas()) - hw->endian = HEVC_CONFIG_BIG_ENDIAN; - if (endian) - hw->endian = endian; - if (is_oversize(hw->max_pic_w, hw->max_pic_h)) { pr_err("over size: %dx%d, probe failed\n", hw->max_pic_w, hw->max_pic_h); @@ -11168,8 +10905,8 @@ #endif av1_print(hw, 0, - "no_head %d low_latency %d, signal_type 0x%x\n", - hw->no_head, hw->low_latency_flag, hw->video_signal_type); + "no_head %d low_latency %d\n", + hw->no_head, hw->low_latency_flag); #if 0 hw->buf_start = pdata->mem_start; hw->buf_size = pdata->mem_end - pdata->mem_start + 1; @@ -11201,7 +10938,6 @@ hw->first_sc_checked = 0; hw->fatal_error = 0; hw->show_frame_num = 0; - hw->run_ready_min_buf_num = run_ready_min_buf_num; if (debug) { av1_print(hw, AOM_DEBUG_HW_MORE, "===AV1 decoder mem resource 0x%lx size 0x%x\n", @@ -11219,11 +10955,6 @@ pdata->dec_status = NULL; return -ENODEV; } - -#ifdef AUX_DATA_CRC - vdec_aux_data_check_init(pdata); -#endif - vdec_set_prepare_level(pdata, start_decode_buf_level); hevc_source_changed(VFORMAT_AV1, 4096, 2048, 60); @@ -11246,10 +10977,6 @@ if (debug) av1_print(hw, AOM_DEBUG_HW_MORE, "amvdec_av1_remove\n"); -#ifdef AUX_DATA_CRC - vdec_aux_data_check_exit(vdec); -#endif - vmav1_stop(hw); if (vdec->parallel_dec == 1) @@ -11275,8 +11002,6 @@ hw->pts_missed, hw->pts_hit, hw->frame_dur); #endif /* devm_kfree(&pdev->dev, (void *)hw); */ - if (is_rdma_enable()) - dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hw->rdma_adr, hw->rdma_phy_adr); vfree(hw->pbi); release_dblk_struct(hw); vfree((void *)hw); @@ -11343,10 +11068,7 @@ #endif /* if (vdec_is_support_4k()) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) - p_buf_info = &aom_workbuff_spec[1]; - else - p_buf_info = &aom_workbuff_spec[1]; + p_buf_info = &aom_workbuff_spec[1]; } else p_buf_info = &aom_workbuff_spec[0]; @@ -11380,13 +11102,10 @@ pr_err("failed to register amvdec_av1 driver\n"); return -ENODEV; } - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) { + + if ((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) || is_cpu_tm2_revb()) { amvdec_av1_profile.profile = - "10bit, dwrite, compressed, no_head, v4l-uvm"; - } else if (((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) || is_cpu_tm2_revb()) - && (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5)) { - amvdec_av1_profile.profile = - "8k, 10bit, dwrite, compressed, no_head, frame_dv, v4l-uvm"; + "8k, 10bit, dwrite, compressed, no_head, frame_dv"; } else { amvdec_av1_profile.name = "av1_unsupport"; } @@ -11406,7 +11125,6 @@ INIT_REG_NODE_CONFIGS("media.decoder", &av1_node, "av1", av1_configs, CONFIG_FOR_RW); #endif - vcodec_feature_register(VFORMAT_AV1, 0); return 0; } @@ -11645,9 +11363,6 @@ module_param(without_display_mode, uint, 0664); MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n"); -module_param(v4l_bitstream_id_enable, uint, 0664); -MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n"); - module_init(amvdec_av1_driver_init_module); module_exit(amvdec_av1_driver_remove_module);
diff --git a/drivers/frame_provider/decoder/vc1/vvc1.c b/drivers/frame_provider/decoder/vc1/vvc1.c index 1f0dfa9..aa215a9 100644 --- a/drivers/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/frame_provider/decoder/vc1/vvc1.c
@@ -30,6 +30,7 @@ #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/vdec_reg.h> #include "../utils/amvdec.h" #include "../utils/vdec.h" @@ -40,11 +41,10 @@ #include <linux/amlogic/media/codec_mm/codec_mm.h> #include <linux/amlogic/media/codec_mm/configs.h> #include "../utils/firmware.h" -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> +#include <linux/amlogic/tee.h> #include <linux/delay.h> #include "../../../common/chips/decoder_cpu_ver_info.h" -#include "../utils/vdec_feature.h" + #define DRIVER_NAME "amvdec_vc1" #define MODULE_NAME "amvdec_vc1" @@ -146,7 +146,6 @@ static bool is_reset; static struct work_struct set_clk_work; static struct work_struct error_wd_work; -static struct canvas_config_s vc1_canvas_config[DECODE_BUFFER_NUM_MAX][3]; spinlock_t vc1_rp_lock; @@ -517,9 +516,9 @@ } if (next_pts_us64 != 0) { next_pts_us64 += - div_u64((u64)((vf->duration) - + (u64)((vf->duration) - ((vf->duration) >> 4)) * - 100, 9); + 100 / 9; } } else { vf->duration = @@ -551,17 +550,6 @@ decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - if (is_support_vdec_canvas()) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0]; - vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1]; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2]; - vf->plane_num = 3; -#endif - } kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -594,8 +582,8 @@ ((vf->duration) >> 4)); } if (next_pts_us64 != 0) { - next_pts_us64 += div_u64((u64)((vf->duration) - - ((vf->duration) >> 4)) * 100, 9); + next_pts_us64 += (u64)((vf->duration) - + ((vf->duration) >> 4)) * 100 / 9; } } else { vf->duration = @@ -626,18 +614,6 @@ decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - - if (is_support_vdec_canvas()) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0]; - vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1]; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2]; - vf->plane_num = 3; -#endif - } kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -697,9 +673,9 @@ } if (next_pts_us64 != 0) { next_pts_us64 += - div_u64((u64)((vf->duration) - + (u64)((vf->duration) - ((vf->duration) >> 4)) * - 100, 9); + 100 / 9; } } else { vf->duration = @@ -733,17 +709,7 @@ decoder_bmmu_box_get_mem_handle( mm_blk_handle, buffer_index); - if (is_support_vdec_canvas()) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0]; - vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1]; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2]; - vf->plane_num = 3; -#endif - } + kfifo_put(&display_q, (const struct vframe_s *)vf); ATRACE_COUNTER(MODULE_NAME, vf->pts); @@ -927,57 +893,30 @@ } #ifdef NV21 - config_cav_lut_ex(2 * i + 0, + canvas_config(2 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - vc1_canvas_config[i][0].endian = 0; - vc1_canvas_config[i][0].width = canvas_width; - vc1_canvas_config[i][0].height = canvas_height; - vc1_canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32; - vc1_canvas_config[i][0].phy_addr = buf_start; - - config_cav_lut_ex(2 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(2 * i + 1, buf_start + decbuf_y_size, canvas_width, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32, 0, VDEC_1); - vc1_canvas_config[i][1].endian = 0; - vc1_canvas_config[i][1].width = canvas_width; - vc1_canvas_config[i][1].height = canvas_height >> 1; - vc1_canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32; - vc1_canvas_config[i][1].phy_addr = buf_start + decbuf_y_size; + CANVAS_BLKMODE_32X32); #else - config_cav_lut_ex(3 * i + 0, + canvas_config(3 * i + 0, buf_start, canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1); - vc1_canvas_config[i][0].endian = 0; - vc1_canvas_config[i][0].width = canvas_width; - vc1_canvas_config[i][0].height = canvas_height; - vc1_canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32; - vc1_canvas_config[i][0].phy_addr = buf_start; - config_cav_lut_ex(3 * i + 1, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); + canvas_config(3 * i + 1, buf_start + decbuf_y_size, canvas_width / 2, canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32, 0, VDEC_1); - vc1_canvas_config[i][1].endian = 0; - vc1_canvas_config[i][1].width = canvas_width >> 1; - vc1_canvas_config[i][1].height = canvas_height >> 1; - vc1_canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32; - vc1_canvas_config[i][1].phy_addr = buf_start + decbuf_y_size; - config_cav_lut_ex(3 * i + 2, + CANVAS_BLKMODE_32X32); + canvas_config(3 * 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); - vc1_canvas_config[i][2].endian = 0; - vc1_canvas_config[i][2].width = canvas_width >> 1; - vc1_canvas_config[i][2].height = canvas_height >> 1; - vc1_canvas_config[i][2].block_mode = CANVAS_BLKMODE_32X32; - vc1_canvas_config[i][2].phy_addr = buf_start + - decbuf_y_size + decbuf_uv_size; + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); #endif } @@ -1055,8 +994,6 @@ #ifdef NV21 SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); #endif - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - return r; } @@ -1163,8 +1100,11 @@ amvdec_start(); } -static void vvc1_put_timer_func(struct timer_list *timer) + +static void vvc1_put_timer_func(unsigned long arg) { + struct timer_list *timer = (struct timer_list *)arg; + if (READ_VREG(VC1_SOS_COUNT) > 10) schedule_work(&error_wd_work); @@ -1202,7 +1142,7 @@ return -ENOMEM; pr_info("vvc1_init, format %d\n", vvc1_amstream_dec_info.format); - timer_setup(&recycle_timer, vvc1_put_timer_func, 0); + init_timer(&recycle_timer); stat |= STAT_TIMER_INIT; @@ -1276,7 +1216,10 @@ stat |= STAT_VF_HOOK; + recycle_timer.data = (ulong)&recycle_timer; + recycle_timer.function = vvc1_put_timer_func; recycle_timer.expires = jiffies + PUT_INTERVAL; + add_timer(&recycle_timer); stat |= STAT_TIMER_ARM; @@ -1384,16 +1327,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int vc1_suspend(struct device *dev) +{ + amvdec_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int vc1_resume(struct device *dev) +{ + amvdec_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops vc1_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(vc1_suspend, vc1_resume) +}; +#endif static struct platform_driver amvdec_vc1_driver = { .probe = amvdec_vc1_probe, .remove = amvdec_vc1_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &vc1_pm_ops, +#endif } }; @@ -1418,7 +1377,6 @@ return -ENODEV; } vcodec_profile_register(&amvdec_vc1_profile); - vcodec_feature_register(VFORMAT_VC1, 0); return 0; }
diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index e6a47fd..fa75afb 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c
@@ -37,15 +37,14 @@ #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 <linux/amlogic/tee.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" #define MEM_NAME "codec_vp9" +/* #include <mach/am_regs.h> */ #include <linux/amlogic/media/utils/vdec_reg.h> #include "../utils/vdec.h" #include "../utils/amvdec.h" @@ -60,17 +59,16 @@ #include "../../../common/chips/decoder_cpu_ver_info.h" #include "../utils/vdec_v4l2_buffer_ops.h" #include <media/v4l2-mem2mem.h> -#include "../utils/vdec_feature.h" #define MIX_STREAM_SUPPORT #include "vvp9.h" -#define VP9_10B_MMU_DW + /*#define SUPPORT_FB_DECODING*/ /*#define FB_DECODING_TEST_SCHEDULE*/ -#define CO_MV_COMPRESS + #define HW_MASK_FRONT 0x1 #define HW_MASK_BACK 0x2 @@ -83,21 +81,11 @@ #define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464 #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_MV_INFO 0x310d #define HEVC_QP_INFO 0x3137 #define HEVC_SKIP_INFO 0x3136 -#define HEVC_SAO_CTRL9 0x362d -#define HEVC_CM_HEADER_START_ADDR2 0x364a -#define HEVC_SAO_MMU_DMA_CTRL2 0x364c -#define HEVC_SAO_MMU_VH0_ADDR2 0x364d -#define HEVC_SAO_MMU_VH1_ADDR2 0x364e -#define HEVC_SAO_MMU_STATUS2 0x3650 -#define HEVC_DW_VH0_ADDDR 0x365e -#define HEVC_DW_VH1_ADDDR 0x365f - #define VP9_10B_DEC_IDLE 0 #define VP9_10B_DEC_FRAME_HEADER 1 #define VP9_10B_DEC_SLICE_SEGMENT 2 @@ -160,7 +148,6 @@ #ifdef MULTI_INSTANCE_SUPPORT #define MAX_DECODE_INSTANCE_NUM 9 #define MULTI_DRIVER_NAME "ammvdec_vp9" - static unsigned int max_decode_instance_num = MAX_DECODE_INSTANCE_NUM; static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM]; @@ -187,7 +174,6 @@ * 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; @@ -225,7 +211,7 @@ #endif static void vvp9_prot_init(struct VP9Decoder_s *pbi, u32 mask); static int vvp9_local_init(struct VP9Decoder_s *pbi); -static void vvp9_put_timer_func(struct timer_list *timer); +static void vvp9_put_timer_func(unsigned long arg); static void dump_data(struct VP9Decoder_s *pbi, int size); static unsigned char get_data_check_sum (struct VP9Decoder_s *pbi, int size); @@ -237,15 +223,7 @@ int pic_height, unsigned short bit_depth, unsigned int *mmu_index_adr); -#ifdef VP9_10B_MMU_DW -int vp9_alloc_mmu_dw( - struct VP9Decoder_s *pbi, - int cur_buf_idx, - int pic_width, - int pic_height, - unsigned short bit_depth, - unsigned int *mmu_index_adr); -#endif + static const char vvp9_dec_id[] = "vvp9-dev"; @@ -278,20 +256,6 @@ #define MAX_FRAME_8K_NUM 0x4800 #define HEVC_ASSIST_MMU_MAP_ADDR 0x3009 -// bit[31:20] -- fb_read_lcu_y -// READ only// bit[19:8] -- fb_read_lcu_x -// READ only// bit[7] -- fb_read_lcu_latch -// bit[6:5] -- reserved -// bit[4] -- fb_disable_wr_iqit_buf -// bit[3] -- fb_read_avs2_enable -// bit[2] -- fb_read_vp9_enable -// bit[1] -- fb_avs2_enable -// bit[0] -- fb_vp9_enable -#define HEVC_ASSIST_HED_FB_CTL 0x300c -// [31:16] height// [15:0] width -#define HEVC_ASSIST_PIC_SIZE_FB_READ 0x300d -#define HEVC_ASSIST_MMU_MAP_ADDR2 0x300e - #ifdef SUPPORT_FB_DECODING /* register define */ @@ -305,7 +269,6 @@ #define MAX_STAGE_PAGE_NUM 0x1200 #define STAGE_MMU_MAP_SIZE (MAX_STAGE_PAGE_NUM * 4) #endif - static inline int div_r32(int64_t m, int n) { /* @@ -374,6 +337,11 @@ #define DOUBLE_WRITE_YSTART_TEMP 0x02000000 #define DOUBLE_WRITE_CSTART_TEMP 0x02900000 + + +typedef unsigned int u32; +typedef unsigned short u16; + #define VP9_DEBUG_BUFMGR 0x01 #define VP9_DEBUG_BUFMGR_MORE 0x02 #define VP9_DEBUG_BUFMGR_DETAIL 0x04 @@ -433,8 +401,6 @@ static u32 without_display_mode; -static u32 v4l_bitstream_id_enable = 1; - /* *[3:0] 0: default use config from omx. * 1: force enable fence. @@ -475,12 +441,9 @@ //#define MMU_COMPRESS_8K_HEADER_SIZE (MMU_COMPRESS_HEADER_SIZE * 4) #define MMU_COMPRESS_HEADER_SIZE 0x48000 -#define MMU_COMPRESS_HEADER_SIZE_DW 0x48000 -#define MMU_COMPRESS_8K_HEADER_SIZE (MMU_COMPRESS_HEADER_SIZE * 4) - +#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4) #define MAX_SIZE_8K (8192 * 4608) #define MAX_SIZE_4K (4096 * 2304) -#define MAX_SIZE_2K (1920 * 1088) #define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K) #define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088)) @@ -584,9 +547,6 @@ int slice_idx; /*buffer*/ unsigned long header_adr; -#ifdef VP9_10B_MMU_DW - unsigned long header_dw_adr; -#endif unsigned long mpred_mv_wr_start_addr; int mv_size; /*unsigned long mc_y_adr; @@ -594,8 +554,6 @@ */ unsigned int dw_y_adr; unsigned int dw_u_v_adr; - u32 luma_size; - u32 chroma_size; int mc_canvas_y; int mc_canvas_u_v; @@ -650,9 +608,10 @@ u32 hw_decode_time; u32 frame_size2; // For frame base mode + bool vframe_bound; /* vdec sync. */ - struct dma_fence *fence; + struct fence *fence; /* hdr10 plus data */ u32 hdr10p_data_size; @@ -748,8 +707,6 @@ */ int row; int col; - - int show_frame; } RefCntBuffer; struct RefBuffer_s { @@ -903,6 +860,7 @@ struct BufferPool_s *buffer_pool; int above_context_alloc_cols; + }; static void set_canvas(struct VP9Decoder_s *pbi, @@ -1000,10 +958,6 @@ struct buff_s seg_map; struct buff_s mmu_vbh; struct buff_s cm_header; -#ifdef VP9_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; @@ -1063,11 +1017,6 @@ #endif #endif -struct vp9_fence_vf_t { - u32 used_size; - struct vframe_s *fence_vf[VF_POOL_SIZE]; -}; - struct VP9Decoder_s { #ifdef MULTI_INSTANCE_SUPPORT unsigned char index; @@ -1135,10 +1084,7 @@ void *frame_mmu_map_addr; dma_addr_t frame_mmu_map_phy_addr; -#ifdef VP9_10B_MMU_DW - void *frame_mmu_dw_map_addr; - dma_addr_t frame_mmu_dw_map_phy_addr; -#endif + unsigned int use_cma_flag; struct BUF_s m_BUF[MAX_BUF_NUM]; @@ -1155,6 +1101,7 @@ int pic_num; int lcu_size_log2; unsigned int losless_comp_body_size; + u32 video_signal_type; int pts_mode; @@ -1232,10 +1179,6 @@ void *mmu_box; void *bmmu_box; int mmu_enable; -#ifdef VP9_10B_MMU_DW - void *mmu_box_dw; - int dw_mmu_enable; -#endif struct vframe_master_display_colour_s vf_dp; struct firmware_s *fw; int max_pic_w; @@ -1294,24 +1237,18 @@ u64 frame_mode_pts64_save[FRAME_BUFFERS]; int run_ready_min_buf_num; int one_package_frame_cnt; - int buffer_wrap[FRAME_BUFFERS]; - int last_width; - int last_height; u32 error_frame_width; u32 error_frame_height; - u32 endian; - ulong fb_token; - struct vp9_fence_vf_t fence_vf_s; - struct mutex fence_mutex; - dma_addr_t rdma_phy_adr; - unsigned *rdma_adr; - struct trace_decoder_name trace; + char vdec_name[32]; + char pts_name[32]; + char new_q_name[32]; + char disp_q_name[32]; }; static int vp9_print(struct VP9Decoder_s *pbi, int flag, const char *fmt, ...) { -#define HEVC_PRINT_BUF 512 +#define HEVC_PRINT_BUF 256 unsigned char buf[HEVC_PRINT_BUF]; int len = 0; @@ -1335,9 +1272,6 @@ int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)? MAX_SIZE_8K : MAX_SIZE_4K; - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) - max = MAX_SIZE_2K; - if (w <= 0 || h <= 0) return true; @@ -1347,26 +1281,6 @@ return false; } -static int vvp9_mmu_compress_header_size(int w, int h) -{ - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - IS_8K_SIZE(w, h)) - return (MMU_COMPRESS_HEADER_SIZE_8K); - if (IS_4K_SIZE(w, h)) - return (MMU_COMPRESS_HEADER_SIZE_4K); - return (MMU_COMPRESS_HEADER_SIZE_1080P); -} - -/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/ -static int vvp9_frame_mmu_map_size(struct VP9Decoder_s *pbi) -{ - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h)) - return (MAX_FRAME_8K_NUM << 2); - - return (MAX_FRAME_4K_NUM << 2); -} - static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi, struct PIC_BUFFER_CONFIG_s *pic); @@ -1379,9 +1293,8 @@ pbi->vp9_first_pts_ready = 0; pbi->duration_from_pts_done = 0; } - pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, - cm->width, cm->height, - width, height); + pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, + cm->height, width, height); cm->width = width; cm->height = height; } @@ -1417,7 +1330,6 @@ struct VP9Decoder_s *pbi, struct VP9_Common_s *cm, union param_u *params, unsigned int *mmu_index_adr, - unsigned int *mmu_dw_index_adr, int print_header_info) { int width, height; struct BufferPool_s * const pool = cm->buffer_pool; @@ -1461,19 +1373,7 @@ } cm->cur_fb_idx_mmu = cm->new_fb_idx; } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable && (mmu_dw_index_adr != NULL)) { - ret = vp9_alloc_mmu_dw(pbi, cm->new_fb_idx, - params->p.width, params->p.height, - params->p.bit_depth, mmu_dw_index_adr); - if (ret != 0) { - pr_err("can't alloc need mmu1 dw,idx %d ret =%d\n", - cm->new_fb_idx, - ret); - return ret; - } - } -#endif + resize_context_buffers(pbi, cm, width, height); setup_display_size(cm, params, print_header_info); #if 0 @@ -1516,7 +1416,6 @@ struct VP9_Common_s *cm, union param_u *params, unsigned int *mmu_index_adr, - unsigned int *mmu_dw_index_adr, int print_header_info) { int width, height; @@ -1602,18 +1501,7 @@ } cm->cur_fb_idx_mmu = cm->new_fb_idx; } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable && (mmu_dw_index_adr != NULL)) { - ret = vp9_alloc_mmu_dw(pbi, cm->new_fb_idx, - params->p.width, params->p.height, - params->p.bit_depth, mmu_dw_index_adr); - if (ret != 0) { - pr_err("can't alloc need mmu dw,idx %d\r\n", - cm->new_fb_idx); - return ret; - } - } -#endif + /*Check to make sure at least one of frames that this frame references *has valid dimensions. */ @@ -1756,19 +1644,46 @@ static u32 get_valid_double_write_mode(struct VP9Decoder_s *pbi) { - u32 dw = ((double_write_mode & 0x80000000) == 0) ? + return ((double_write_mode & 0x80000000) == 0) ? pbi->double_write_mode : (double_write_mode & 0x7fffffff); - if (dw & 0x20) { - if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3) - && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) { - pr_info("MMU doueble write 1:4 not supported !!!\n"); - dw = 0; - } - } - return dw; } +static int v4l_parser_get_double_write_mode(struct VP9Decoder_s *pbi) +{ + u32 valid_dw_mode = get_valid_double_write_mode(pbi); + u32 dw; + int w, h; + + /* mask for supporting double write value bigger than 0x100 */ + if (valid_dw_mode & 0xffffff00) { + w = pbi->frame_width; + h = pbi->frame_height; + + 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: + break; + } + return dw; + } + + return valid_dw_mode; +} + + static int get_double_write_mode(struct VP9Decoder_s *pbi) { u32 valid_dw_mode = get_valid_double_write_mode(pbi); @@ -1777,14 +1692,6 @@ struct VP9_Common_s *cm = &pbi->common; struct PIC_BUFFER_CONFIG_s *cur_pic_config; - if (pbi->is_used_v4l) { - unsigned int out; - - vdec_v4l_get_dw_mode(pbi->v4l2_ctx, &out); - dw = out; - return dw; - } - /* mask for supporting double write value bigger than 0x100 */ if (valid_dw_mode & 0xffffff00) { if (!cm->cur_frame) @@ -1846,53 +1753,20 @@ } #endif +static int get_double_write_ratio(struct VP9Decoder_s *pbi, + int dw_mode) +{ + int ratio = 1; + if ((dw_mode == 2) || + (dw_mode == 3)) + ratio = 4; + else if (dw_mode == 4) + ratio = 2; + return ratio; +} + //#define MAX_4K_NUM 0x1200 -/* return page number */ -static int vp9_mmu_page_num(struct VP9Decoder_s *pbi, - int w, int h, int save_mode) -{ - int picture_size; - int cur_mmu_4k_number, max_frame_num; - - picture_size = compute_losless_comp_body_size(w, h, save_mode); - cur_mmu_4k_number = ((picture_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT); - - max_frame_num = (vvp9_frame_mmu_map_size(pbi) >> 2); - - 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; -} - -static struct internal_comp_buf* v4lfb_to_icomp_buf( - struct VP9Decoder_s *pbi, - struct vdec_v4l2_buffer *fb) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx; - - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - -static struct internal_comp_buf* index_to_icomp_buf( - struct VP9Decoder_s *pbi, int index) -{ - struct aml_video_dec_buf *aml_fb = NULL; - struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; - - fb = (struct vdec_v4l2_buffer *) - pbi->m_BUF[index].v4l_ref_buf_addr; - aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer); - return &v4l2_ctx->comp_bufs[aml_fb->internal_index]; -} - int vp9_alloc_mmu( struct VP9Decoder_s *pbi, int cur_buf_idx, @@ -1901,90 +1775,42 @@ unsigned short bit_depth, unsigned int *mmu_index_adr) { - int ret; int bit_depth_10 = (bit_depth == VPX_BITS_10); - int cur_mmu_4k_number; - + int picture_size; + int cur_mmu_4k_number, max_frame_num; + if (!pbi->mmu_box) { + pr_err("error no mmu box!\n"); + return -1; + } if (get_double_write_mode(pbi) == 0x10) return 0; - if (bit_depth >= VPX_BITS_12) { pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW; pr_err("fatal_error, un support bit depth 12!\n\n"); return -1; } + picture_size = compute_losless_comp_body_size(pic_width, pic_height, + bit_depth_10); + cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12); - cur_mmu_4k_number = vp9_mmu_page_num(pbi, - pic_width, - pic_height, - bit_depth_10); - if (cur_mmu_4k_number < 0) - return -1; + 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 (pbi->is_used_v4l) { - struct internal_comp_buf *ibuf = - index_to_icomp_buf(pbi, cur_buf_idx); - - ret = decoder_mmu_box_alloc_idx( - ibuf->mmu_box, - ibuf->index, - ibuf->frame_buffer_size, - mmu_index_adr); - } else { - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); - ret = decoder_mmu_box_alloc_idx( - pbi->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } - - return ret; -} - -#ifdef VP9_10B_MMU_DW -int vp9_alloc_mmu_dw( - struct VP9Decoder_s *pbi, - int cur_buf_idx, - int pic_width, - int pic_height, - unsigned short bit_depth, - unsigned int *mmu_index_adr) -{ - int ret; - int bit_depth_10 = (bit_depth == VPX_BITS_10); - int cur_mmu_4k_number; - - if (pbi->is_used_v4l) - return -1; - - if (get_double_write_mode(pbi) == 0x10) - return 0; - - if (bit_depth >= VPX_BITS_12) { - pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW; - pr_err("fatal_error, un support bit depth 12!\n\n"); + 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 -1; } - cur_mmu_4k_number = vp9_mmu_page_num(pbi, - pic_width, - pic_height, - bit_depth_10); - if (cur_mmu_4k_number < 0) - return -1; - - ret = decoder_mmu_box_alloc_idx( - pbi->mmu_box_dw, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); - - return ret; + return decoder_mmu_box_alloc_idx( + pbi->mmu_box, + cur_buf_idx, + cur_mmu_4k_number, + mmu_index_adr); } -#endif #ifndef MV_USE_FIXED_BUF static void dealloc_mv_bufs(struct VP9Decoder_s *pbi) @@ -2032,7 +1858,7 @@ ret = 0; if (debug) { pr_info( - "MV Buffer %d: start_adr %px size %x\n", + "MV Buffer %d: start_adr %p size %x\n", i, (void *)pbi->m_mv_BUF[i].start_adr, pbi->m_mv_BUF[i].size); @@ -2156,7 +1982,7 @@ pic_config->mv_size = pbi->m_mv_BUF[ret].size; if (debug & VP9_DEBUG_BUFMGR_MORE) pr_info( - "%s => %d (%lx) size 0x%x\n", + "%s => %d (%ld) size 0x%x\n", __func__, ret, pic_config->mpred_mv_wr_start_addr, pic_config->mv_size); @@ -2216,18 +2042,10 @@ struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; int i; for (i = 0; i < pbi->used_buf_num; ++i) { -#if 0 if ((frame_bufs[i].ref_count == 0) && (frame_bufs[i].buf.index != -1) && (frame_bufs[i].buf.mv_buf_index >= 0) ) -#else - if ((&frame_bufs[i] != cm->prev_frame) && - (frame_bufs[i].buf.index != -1) && - (frame_bufs[i].buf.mv_buf_index >= 0) - ) -#endif - put_mv_buf(pbi, &frame_bufs[i].buf.mv_buf_index); } } @@ -2508,8 +2326,7 @@ for (i = 0; i < pbi->used_buf_num; ++i) { if ((frame_bufs[i].ref_count == 0) && (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.index != -1) && - (cm->cur_frame != &frame_bufs[i]) + (frame_bufs[i].buf.index != -1) ) break; } @@ -2527,39 +2344,6 @@ return i; } -static void update_hide_frame_timestamp(struct VP9Decoder_s *pbi) -{ - struct RefCntBuffer_s *const frame_bufs = - pbi->common.buffer_pool->frame_bufs; - int i; - - for (i = 0; i < pbi->used_buf_num; ++i) { - if ((!frame_bufs[i].show_frame) && - (!frame_bufs[i].buf.vf_ref) && - (frame_bufs[i].buf.BUF_index != -1)) { - frame_bufs[i].buf.timestamp = pbi->chunk->timestamp; - vp9_print(pbi, VP9_DEBUG_OUT_PTS, - "%s, update %d hide frame ts: %lld\n", - __func__, i, frame_bufs[i].buf.timestamp); - } - } -} - -static int get_free_fb_idx(struct VP9Decoder_s *pbi) -{ - int i; - struct VP9_Common_s *const cm = &pbi->common; - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - - for (i = 0; i < pbi->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0)) - break; - } - - return i; -} - static int v4l_get_free_fb(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; @@ -2567,9 +2351,8 @@ struct aml_vcodec_ctx * v4l = pbi->v4l2_ctx; struct v4l_buff_pool *pool = &v4l->cap_pool; struct PIC_BUFFER_CONFIG_s *pic = NULL; - struct PIC_BUFFER_CONFIG_s *free_pic = NULL; + int i, idx = INVALID_IDX; ulong flags; - int idx, i; lock_buffer_pool(cm->buffer_pool, flags); @@ -2584,92 +2367,47 @@ (pic->vf_ref == 0) && (pic->index != -1) && pic->cma_alloc_addr) { - free_pic = pic; + idx = i; } break; case V4L_CAP_BUFF_IN_M2M: - idx = get_free_fb_idx(pbi); - pic = &frame_bufs[idx].buf; + pic = &frame_bufs[index].buf; pic->y_crop_width = pbi->frame_width; pic->y_crop_height = pbi->frame_height; - pbi->buffer_wrap[idx] = index; if (!v4l_alloc_and_config_pic(pbi, pic)) { set_canvas(pbi, pic); init_pic_list_hw(pbi); - free_pic = pic; + idx = index; } break; default: + pr_err("v4l buffer state err %d.\n", state); break; } - if (free_pic) { - frame_bufs[i].ref_count = 1; + if (idx != INVALID_IDX) { + frame_bufs[idx].ref_count = 1; break; } } - if (free_pic && pbi->chunk) { - free_pic->timestamp = pbi->chunk->timestamp; - update_hide_frame_timestamp(pbi); - } - unlock_buffer_pool(cm->buffer_pool, flags); - if (free_pic) { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *) - pbi->m_BUF[i].v4l_ref_buf_addr; - - fb->status = FB_ST_DECODER; - } - - if (debug & VP9_DEBUG_OUT_PTS) { - if (free_pic) { - pr_debug("%s, idx: %d, ts: %lld\n", - __func__, free_pic->index, free_pic->timestamp); - } else { - pr_debug("%s, vp9 get free pic null\n", __func__); - } - } - - return free_pic ? free_pic->index : INVALID_IDX; + return idx; } static int get_free_buf_count(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - int i, free_buf_count = 0; - - if (pbi->is_used_v4l) { - for (i = 0; i < pbi->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - frame_bufs[i].buf.cma_alloc_addr) { - free_buf_count++; - } - } - - if (ctx->cap_pool.dec < pbi->used_buf_num) { - free_buf_count += - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - } - - /* trigger to parse head data. */ - if (!pbi->v4l_params_parsed) { - free_buf_count = pbi->run_ready_min_buf_num; - } - } else { - for (i = 0; i < pbi->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.index != -1)) - free_buf_count++; - } - } - + int i; + int free_buf_count = 0; + for (i = 0; i < pbi->used_buf_num; ++i) + if ((frame_bufs[i].ref_count == 0) && + (frame_bufs[i].buf.vf_ref == 0) && + (frame_bufs[i].buf.index != -1) + ) + free_buf_count++; return free_buf_count; } @@ -2790,11 +2528,9 @@ pbi->ready_for_new_data = 0; - if ((pbi->has_keyframe == 0) && - (params->p.frame_type != KEY_FRAME) && - (!params->p.intra_only)){ + if (pbi->has_keyframe == 0 && + params->p.frame_type != KEY_FRAME){ on_no_keyframe_skiped++; - pr_info("vp9_bufmgr_process no key frame return\n"); return -2; } pbi->has_keyframe = 1; @@ -2895,7 +2631,6 @@ pbi->refresh_frame_flags = 0; /*cm->lf.filter_level = 0;*/ cm->show_frame = 1; - cm->cur_frame->show_frame = 1; /* *if (pbi->frame_parallel_decode) { @@ -2911,7 +2646,7 @@ cm->show_frame = params->p.show_frame; cm->bit_depth = params->p.bit_depth; cm->error_resilient_mode = params->p.error_resilient_mode; - cm->cur_frame->show_frame = cm->show_frame; + if (cm->frame_type == KEY_FRAME) { pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1; @@ -2920,19 +2655,10 @@ cm->frame_refs[i].idx = INVALID_IDX; cm->frame_refs[i].buf = NULL; } -#ifdef VP9_10B_MMU_DW + ret = setup_frame_size(pbi, - cm, params, - pbi->frame_mmu_map_addr, - pbi->frame_mmu_dw_map_addr, - print_header_info); -#else - ret = setup_frame_size(pbi, - cm, params, - pbi->frame_mmu_map_addr, - NULL, - print_header_info); -#endif + cm, params, pbi->frame_mmu_map_addr, + print_header_info); if (ret) return -1; if (pbi->need_resync) { @@ -2991,21 +2717,11 @@ * pr_info("*%d-bits refresh_frame read:0x%x\n", * REF_FRAMES, pbi->refresh_frame_flags); */ -#ifdef VP9_10B_MMU_DW ret = setup_frame_size(pbi, cm, params, pbi->frame_mmu_map_addr, - pbi->frame_mmu_dw_map_addr, print_header_info); -#else - ret = setup_frame_size(pbi, - cm, - params, - pbi->frame_mmu_map_addr, - NULL, - print_header_info); -#endif if (ret) return -1; if (pbi->need_resync) { @@ -3051,23 +2767,13 @@ */ } -#ifdef VP9_10B_MMU_DW + ret = setup_frame_size_with_refs( pbi, cm, params, pbi->frame_mmu_map_addr, - pbi->frame_mmu_dw_map_addr, print_header_info); -#else - ret = setup_frame_size_with_refs( - pbi, - cm, - params, - pbi->frame_mmu_map_addr, - NULL, - print_header_info); -#endif if (ret) return -1; for (i = 0; i < REFS_PER_FRAME; ++i) { @@ -3135,11 +2841,11 @@ struct vdec_s *vdec = hw_to_vdec(pbi); /* create fence for each buffers. */ - ret = vdec_timeline_create_fence(vdec->sync); + ret = vdec_timeline_create_fence(&vdec->sync); if (ret < 0) return ret; - pic->fence = vdec->sync->fence; + pic->fence = vdec->sync.fence; pic->bit_depth = cm->bit_depth; pic->slice_type = cm->frame_type; pic->stream_offset = pbi->pre_stream_offset; @@ -3301,9 +3007,6 @@ } cm->last_width = cm->width; cm->last_height = cm->height; - pbi->last_width = cm->width; - pbi->last_height = cm->height; - if (cm->show_frame) cm->current_video_frame++; @@ -3312,32 +3015,8 @@ sd.stream_offset = pbi->pre_stream_offset; if (pbi->enable_fence) { - int i, j, used_size, ret; - int signed_count = 0; - struct vframe_s *signed_fence[VF_POOL_SIZE]; /* notify signal to wake up wq of fence. */ - vdec_timeline_increase(vdec->sync, 1); - mutex_lock(&pbi->fence_mutex); - used_size = pbi->fence_vf_s.used_size; - if (used_size) { - for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) { - if (pbi->fence_vf_s.fence_vf[i] != NULL) { - ret = dma_fence_get_status(pbi->fence_vf_s.fence_vf[i]->fence); - if (ret == 1) { - signed_fence[signed_count] = pbi->fence_vf_s.fence_vf[i]; - pbi->fence_vf_s.fence_vf[i] = NULL; - pbi->fence_vf_s.used_size--; - signed_count++; - } - j++; - } - } - } - mutex_unlock(&pbi->fence_mutex); - if (signed_count != 0) { - for (i = 0; i < signed_count; i++) - vvp9_vf_put(signed_fence[i], vdec); - } + vdec_timeline_increase(&vdec->sync, 1); } else { prepare_display_buf(pbi, &sd); } @@ -3366,9 +3045,6 @@ #define HEVC_CM_HEADER_LENGTH 0x3629 #define HEVC_CM_HEADER_OFFSET 0x362b -#define HEVC_CM_BODY_LENGTH2 0x3663 -#define HEVC_CM_HEADER_OFFSET2 0x3664 -#define HEVC_CM_HEADER_LENGTH2 0x3665 #define LOSLESS_COMPRESS_MODE /*#define DECOMP_HEADR_SURGENT*/ @@ -3390,15 +3066,7 @@ 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) - +static u32 endian = 0xff0; #ifdef ERROR_HANDLE_DEBUG static u32 dbg_nal_skip_flag; /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */ @@ -3408,10 +3076,18 @@ static u32 decode_pic_begin; static uint slice_parse_begin; static u32 step; -static u32 vp9_max_pic_w; -static u32 vp9_max_pic_h; -static u32 dynamic_buf_num_margin; +#ifdef MIX_STREAM_SUPPORT +static u32 buf_alloc_width = 4096; +static u32 buf_alloc_height = 2304; +static u32 vp9_max_pic_w = 4096; +static u32 vp9_max_pic_h = 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 static u32 buf_alloc_depth = 10; static u32 buf_alloc_size; /* @@ -3557,10 +3233,7 @@ #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 +#define WORK_BUF_SPEC_NUM 3 static struct BuffInfo_s amvvp9_workbuff_spec[WORK_BUF_SPEC_NUM] = { { /* 8M bytes */ @@ -3570,292 +3243,6 @@ /* IPP work space calculation : * 4096 * (Y+CbCr+Flags) = 12k, round to 16k */ - .buf_size = 0x4000, - }, - .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, - }, - .vps = { - /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, - * total 0x0800 bytes - */ - .buf_size = 0x800, - }, - .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 = { - .buf_size = 0x80000, - }, - .seg_map = { - /*4096x2304/64/64 *24 = 0xd800 Bytes*/ - .buf_size = 0xd800, - }, - .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 - .mpred_above = { - .buf_size = 0x10000, /* 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, - }, - .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, - }, - .vps = { - /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, - * total 0x0800 bytes - */ - .buf_size = 0x800, - }, - .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 = { - .buf_size = 0x80000, - }, - .seg_map = { - /*4096x2304/64/64 *24 = 0xd800 Bytes*/ - .buf_size = 0xd800, - }, - .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 - .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, - }, - .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, - }, - .vps = { - // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes - .buf_size = 0x800, - }, - .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*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 = { - // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000) - .buf_size = 0x80000*2, - }, - .dblk_data = { - .buf_size = 0x80000*2, - }, - .seg_map = { - /*4096x2304/64/64 *24 = 0xd800 Bytes*/ - .buf_size = 0xd800*4, - }, - .mmu_vbh = { - .buf_size = 0x5000*2, //2*16*(more than 2304)/4, 4K - }, -#if 0 - .cm_header = { - //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - .buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif - .mpred_above = { - .buf_size = 0x10000*2, /* 2 * size of hevc*/ - }, -#ifdef MV_USE_FIXED_BUF - .mpred_mv = { - //4k2k , 0x100000 per buffer */ - /* 4096x2304 , 0x120000 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, - .max_height = 1088, - .ipp = { - /* IPP work space calculation : - * 4096 * (Y+CbCr+Flags) = 12k, round to 16k - */ .buf_size = 0x1e00, }, .sao_abv = { @@ -3934,16 +3321,6 @@ /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */ }, #endif -#ifdef VP9_10B_MMU_DW - .mmu_vbh_dw = { - .buf_size = DW_VBH_BUF_SIZE_1080P, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K - }, -#if 0 - .cm_header_dw = { - .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = { .buf_size = 0x2200, //0x21c0, /* 2 * size of hevc*/ }, @@ -4044,16 +3421,6 @@ /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */ }, #endif -#ifdef VP9_10B_MMU_DW - .mmu_vbh_dw = { - .buf_size = DW_VBH_BUF_SIZE_4K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K - }, -#if 0 - .cm_header_dw = { - .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = { .buf_size = 0x4800, /* 2 * size of hevc*/ }, @@ -4137,16 +3504,6 @@ .buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) }, #endif -#ifdef VP9_10B_MMU_DW - .mmu_vbh_dw = { - .buf_size = DW_VBH_BUF_SIZE_8K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K - }, -#if 0 - .cm_header_dw = { - .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) - }, -#endif -#endif .mpred_above = { .buf_size = 0x9000, }, @@ -4168,7 +3525,7 @@ /*Losless compression body buffer size 4K per 64x32 (jt)*/ -static int compute_losless_comp_body_size(int width, int height, +int compute_losless_comp_body_size(int width, int height, uint8_t is_bit_depth_10) { int width_x64; @@ -4189,7 +3546,7 @@ } /* Losless compression header buffer size 32bytes per 128x64 (jt)*/ -static int compute_losless_comp_header_size(int width, int height) +static int compute_losless_comp_header_size(int width, int height) { int width_x128; int height_x64; @@ -4214,69 +3571,66 @@ { void *mem_start_virt; - buf_spec->ipp.buf_start = - WORKBUF_ALIGN(buf_spec->start_adr); + buf_spec->ipp.buf_start = buf_spec->start_adr; buf_spec->sao_abv.buf_start = - WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); + buf_spec->ipp.buf_start + buf_spec->ipp.buf_size; + buf_spec->sao_vb.buf_start = - WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size); + 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->sao_vb.buf_start + buf_spec->sao_vb.buf_size; buf_spec->vps.buf_start = - WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size); + buf_spec->short_term_rps.buf_start + + buf_spec->short_term_rps.buf_size; buf_spec->sps.buf_start = - WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size); + buf_spec->vps.buf_start + buf_spec->vps.buf_size; buf_spec->pps.buf_start = - WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size); + 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->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->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->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->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->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_para.buf_start + buf_spec->dblk_para.buf_size; buf_spec->seg_map.buf_start = - WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size); + buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; if (pbi == NULL || pbi->mmu_enable) { buf_spec->mmu_vbh.buf_start = - WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size); -#ifdef VP9_10B_MMU_DW - if (pbi == NULL || pbi->dw_mmu_enable) { - 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); - } -#else + buf_spec->seg_map.buf_start + + buf_spec->seg_map.buf_size; buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size); -#endif + buf_spec->mmu_vbh.buf_start + + buf_spec->mmu_vbh.buf_size; } else { buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size); + buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size; } #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->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); + 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); + 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->rpm.buf_start + + buf_spec->rpm.buf_size; buf_spec->end_adr = - WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size); + buf_spec->lmem.buf_start + + buf_spec->lmem.buf_size; if (!pbi) return; @@ -4347,16 +3701,6 @@ if (pbi->mmu_enable) { pr_info("mmu_vbh.buf_start :%x\n", buf_spec->mmu_vbh.buf_start); -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - pr_info("mmu_vbh_dw.buf_start :%x", - buf_spec->mmu_vbh_dw.buf_start); -#if 0 - pr_info("cm_header_dw.buf_start :%x", - buf_spec->mmu_vbh_dw.buf_start); -#endif - } -#endif } pr_info("mpred_above.buf_start :%x\n", buf_spec->mpred_above.buf_start); @@ -5554,25 +4898,71 @@ } +static bool v4l_is_there_vframe_bound(struct VP9Decoder_s *pbi) +{ + int i; + struct VP9_Common_s *const cm = &pbi->common; + struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; + + for (i = 0; i < pbi->used_buf_num; ++i) { + if (frame_bufs[i].buf.vframe_bound) + return true; + } + + return false; +} + +static void v4l_mmu_buffer_release(struct VP9Decoder_s *pbi) +{ + struct VP9_Common_s *const cm = &pbi->common; + struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; + int i; + + /* release workspace */ + if (pbi->bmmu_box) + decoder_bmmu_box_free_idx(pbi->bmmu_box, + WORK_SPACE_BUF_ID); + /* + * it's only when vframe get back to driver, right now we can be sure + * that vframe and fd are related. if the playback exits, the capture + * requires the upper app to release when the fd is closed, and others + * buffers drivers are released by driver. + */ + for (i = 0; i < pbi->used_buf_num; ++i) { + if (!frame_bufs[i].buf.vframe_bound) { + if (pbi->bmmu_box) + decoder_bmmu_box_free_idx(pbi->bmmu_box, + HEADER_BUFFER_IDX(i)); + if (pbi->mmu_box) + decoder_mmu_box_free_idx(pbi->mmu_box, i); + + vp9_print(pbi, PRINT_FLAG_V4L_DETAIL, + "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n", + __func__, i, pbi->bmmu_box, pbi->mmu_box); + } + } +} + static void uninit_mmu_buffers(struct VP9Decoder_s *pbi) { #ifndef MV_USE_FIXED_BUF dealloc_mv_bufs(pbi); #endif - if (pbi->mmu_box) { + if (pbi->is_used_v4l && + v4l_is_there_vframe_bound(pbi)) { + if (get_double_write_mode(pbi) != 0x10) { + v4l_mmu_buffer_release(pbi); + return; + } + } + + if (pbi->mmu_box) decoder_mmu_box_free(pbi->mmu_box); - pbi->mmu_box = NULL; - } -#ifdef VP9_10B_MMU_DW - if (pbi->mmu_box_dw) { - decoder_mmu_box_free(pbi->mmu_box_dw); - pbi->mmu_box_dw = NULL; - } -#endif - if (pbi->bmmu_box) { + pbi->mmu_box = NULL; + + if (pbi->bmmu_box) decoder_bmmu_box_free(pbi->bmmu_box); - pbi->bmmu_box = NULL; - } + pbi->bmmu_box = NULL; } static int calc_luc_quantity(u32 w, u32 h) @@ -5588,22 +4978,6 @@ return pic_width_lcu * pic_height_lcu; } -/* return in MB */ -static int vp9_max_mmu_buf_size(int max_w, int max_h) -{ - int buf_size = 48; - - if ((max_w * max_h > 1280*736) && - (max_w * max_h <= 1920*1088)) { - buf_size = 12; - } else if ((max_w * max_h > 0) && - (max_w * max_h <= 1280*736)) { - buf_size = 4; - } - - return buf_size; -} - static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi, struct PIC_BUFFER_CONFIG_s *pic) { @@ -5616,25 +4990,21 @@ pbi->work_space_buf->mpred_mv.buf_size; int mv_size = cal_mv_buf_size(pbi, pbi->frame_width, pbi->frame_height); #endif - struct aml_vcodec_ctx * ctx = (struct aml_vcodec_ctx *)pbi->v4l2_ctx; struct vdec_v4l2_buffer *fb = NULL; if (i < 0) return ret; - ret = ctx->fb_ops.alloc(&ctx->fb_ops, pbi->fb_token, &fb, AML_FB_REQ_DEC); + ret = vdec_v4l_get_buffer(pbi->v4l2_ctx, &fb); if (ret < 0) { vp9_print(pbi, 0, "[%d] VP9 get buffer fail.\n", ((struct aml_vcodec_ctx *) (pbi->v4l2_ctx))->id); return ret; } - fb->status = FB_ST_DECODER; - if (pbi->mmu_enable) { - struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(pbi, fb); - - pbi->m_BUF[i].header_addr = ibuf->header_addr; + pbi->m_BUF[i].header_addr = decoder_bmmu_box_get_phy_addr( + pbi->bmmu_box, HEADER_BUFFER_IDX(i)); if (debug & VP9_DEBUG_BUFMGR_MORE) { pr_info("MMU header_adr %d: %ld\n", i, pbi->m_BUF[i].header_addr); @@ -5655,8 +5025,6 @@ fb->m.mem[0].bytes_used = fb->m.mem[0].size; pic->dw_y_adr = pbi->m_BUF[i].start_adr; pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size; - pic->luma_size = fb->m.mem[0].offset; - pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset; } else if (fb->num_planes == 2) { pbi->m_BUF[i].start_adr = fb->m.mem[0].addr; pbi->m_BUF[i].size = fb->m.mem[0].size; @@ -5666,8 +5034,6 @@ fb->m.mem[1].bytes_used = fb->m.mem[1].size; pic->dw_y_adr = pbi->m_BUF[i].start_adr; pic->dw_u_v_adr = pbi->m_BUF[i].chroma_addr; - pic->luma_size = fb->m.mem[0].size; - pic->chroma_size = fb->m.mem[1].size; } /* config frame buffer */ @@ -5744,15 +5110,14 @@ int mc_buffer_size_u_v = 0; int mc_buffer_size_u_v_h = 0; int dw_mode = get_double_write_mode_init(pbi); - struct vdec_s *vdec = hw_to_vdec(pbi); pbi->lcu_total = lcu_total; - if (dw_mode && (dw_mode & 0x20) == 0) { + if (dw_mode) { int pic_width_dw = pic_width / - get_double_write_ratio(dw_mode & 0xf); + get_double_write_ratio(pbi, dw_mode); int pic_height_dw = pic_height / - get_double_write_ratio(dw_mode & 0xf); + get_double_write_ratio(pbi, dw_mode); int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f); int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f); @@ -5783,19 +5148,8 @@ pr_info("MMU header_adr %d: %ld\n", pic_config->index, pic_config->header_adr); } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - pic_config->header_dw_adr = pic_config->header_adr + - vvp9_mmu_compress_header_size(pbi->init_pic_w, pbi->init_pic_h); - - if (debug & VP9_DEBUG_BUFMGR_MORE) { - pr_info("MMU header_dw_adr %d: %ld size 0x%x\n", - pic_config->index, pic_config->header_dw_adr, - vvp9_mmu_compress_header_size(pbi->init_pic_w, pbi->init_pic_h)); - } - } -#endif } + i = pic_config->index; #ifdef MV_USE_FIXED_BUF if ((pbi->work_space_buf->mpred_mv.buf_start + @@ -5817,13 +5171,6 @@ return ret; } - if (pbi->enable_fence) { - //mm->fence_ref_release = vdec_fence_buffer_count_decrease; - vdec_fence_buffer_count_increase((ulong)vdec->sync); - INIT_LIST_HEAD(&vdec->sync->release_callback[VF_BUFFER_IDX(i)].node); - decoder_bmmu_box_add_callback_func(pbi->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[VF_BUFFER_IDX(i)]); - } - if (pic_config->cma_alloc_addr) y_adr = pic_config->cma_alloc_addr; else { @@ -5855,7 +5202,7 @@ (pic_config->index << 1); pic_config->mc_canvas_u_v = (pic_config->index << 1) + 1; - } else if (dw_mode && ((dw_mode & 0x20) == 0)) { + } else if (dw_mode) { pic_config->dw_y_adr = y_adr; pic_config->dw_u_v_adr = pic_config->dw_y_adr + ((mc_buffer_size_u_v_h << 16) << 1); @@ -5890,6 +5237,24 @@ return ret; } +static int vvp9_mmu_compress_header_size(struct VP9Decoder_s *pbi) +{ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h)) + return (MMU_COMPRESS_8K_HEADER_SIZE); + + return (MMU_COMPRESS_HEADER_SIZE); +} + +/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/ +static int vvp9_frame_mmu_map_size(struct VP9Decoder_s *pbi) +{ + if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && + IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h)) + return (MAX_FRAME_8K_NUM * 4); + + return (MAX_FRAME_4K_NUM * 4); +} static void init_pic_list(struct VP9Decoder_s *pbi) { @@ -5899,13 +5264,8 @@ u32 header_size; struct vdec_s *vdec = hw_to_vdec(pbi); - if (!pbi->is_used_v4l && pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) { - header_size = vvp9_mmu_compress_header_size( - pbi->max_pic_w, pbi->max_pic_h); -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) - header_size <<= 1; -#endif + if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) { + header_size = vvp9_mmu_compress_header_size(pbi); /*alloc VP9 compress header first*/ for (i = 0; i < pbi->used_buf_num; i++) { unsigned long buf_addr; @@ -5919,12 +5279,6 @@ pbi->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; return; } - if (pbi->enable_fence) { - vdec_fence_buffer_count_increase((ulong)vdec->sync); - INIT_LIST_HEAD(&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)].node); - decoder_bmmu_box_add_callback_func(pbi->bmmu_box, HEADER_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)]); - //mm->fence_ref_release = vdec_fence_buffer_count_decrease; - } } } for (i = 0; i < pbi->used_buf_num; i++) { @@ -5949,8 +5303,7 @@ break; } - if (pic_config->double_write_mode && - (pic_config->double_write_mode & 0x20) == 0) { + if (pic_config->double_write_mode) { set_canvas(pbi, pic_config); } } @@ -5978,12 +5331,14 @@ WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2)); + for (i = 0; i < pbi->used_buf_num; i++) { pic_config = &cm->buffer_pool->frame_bufs[i].buf; if (pic_config->index < 0) break; if (pbi->mmu_enable && ((pic_config->double_write_mode & 0x10) == 0)) { + WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic_config->header_adr >> 5); } else { @@ -6017,6 +5372,7 @@ WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0); } + static void dump_pic_list(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; @@ -6025,7 +5381,7 @@ for (i = 0; i < FRAME_BUFFERS; i++) { pic_config = &cm->buffer_pool->frame_bufs[i].buf; vp9_print(pbi, 0, - "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr: %x\n", + "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr%ld\n", i, pic_config->index, #ifndef MV_USE_FIXED_BUF @@ -6096,14 +5452,6 @@ #else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); #endif -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - /*losless_comp_header_size_dw same as losless_comp_header_size*/ - 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); - } -#endif return 0; } @@ -6248,45 +5596,26 @@ (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/ struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx; - if (get_double_write_mode(pbi) && - (get_double_write_mode(pbi) & 0x20) == 0) { + if (get_double_write_mode(pbi)) { WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->dw_y_adr); WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->dw_u_v_adr); WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->dw_y_adr); WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->dw_u_v_adr); } else { - if (!pbi->dw_mmu_enable) { - WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); - WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff); - } + WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); + WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff); } if (pbi->mmu_enable) WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->header_adr); - if (pbi->is_used_v4l) { - WRITE_VREG(HEVC_SAO_Y_LENGTH, pic_config->luma_size); - WRITE_VREG(HEVC_SAO_C_LENGTH, pic_config->chroma_size); - if (debug & PRINT_FLAG_V4L_DETAIL) { - pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n", - v4l2_ctx->id, pic_config->index, - pic_config->dw_y_adr, pic_config->luma_size, - pic_config->dw_u_v_adr, pic_config->chroma_size); - } - } else { -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic_config->header_dw_adr); - } -#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, pic_config->lcu_total);*/ + 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, pic_config->lcu_total); + */ + WRITE_VREG(HEVC_SAO_Y_LENGTH, data32); - WRITE_VREG(HEVC_SAO_Y_LENGTH, data32); - - data32 = (mc_buffer_size_u_v_h << 16); - WRITE_VREG(HEVC_SAO_C_LENGTH, data32); - } + data32 = (mc_buffer_size_u_v_h << 16); + WRITE_VREG(HEVC_SAO_C_LENGTH, data32); #ifdef VP9_10B_NV21 #ifdef DOS_PROJECT @@ -6339,21 +5668,17 @@ #endif #else data32 = READ_VREG(HEVC_SAO_CTRL1); - data32 &= (~(3 << 14)); - data32 |= (2 << 14); /* line align with 64*/ - data32 &= (~0x3000); - /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */ - data32 |= (pbi->mem_map_mode << 12); + data32 |= (pbi->mem_map_mode << + 12); +/* [13:12] axi_aformat, 0-Linear, + * 1-32x32, 2-64x32 + */ data32 &= (~0xff0); -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable == 0) - data32 |= ((pbi->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */ -#else - data32 |= ((pbi->endian >> 8) & 0xfff); -#endif - data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ + /* data32 |= 0x670; // Big-Endian per 64-bit */ + data32 |= endian; /* Big-Endian per 64-bit */ + data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ if (get_double_write_mode(pbi) == 0) data32 |= 0x2; /*disable double write*/ else if (get_double_write_mode(pbi) & 0x10) @@ -6405,29 +5730,24 @@ 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 ((get_double_write_mode(pbi) & 0xf) == 8 || - (get_double_write_mode(pbi) & 0xf) == 9) { - data32 |= (0xff << 16); - WRITE_VREG(HEVC_SAO_CTRL26, 0xf); - } else if ((get_double_write_mode(pbi) & 0xf) == 2 || - (get_double_write_mode(pbi) & 0xf) == 3) - data32 |= (0xff << 16); - else if ((get_double_write_mode(pbi) & 0xf) == 4) - data32 |= (0x33 << 16); + if (get_double_write_mode(pbi) == 2 || + get_double_write_mode(pbi) == 3) + data32 |= (0xff<<16); + else if (get_double_write_mode(pbi) == 4) + data32 |= (0x33<<16); WRITE_VREG(HEVC_SAO_CTRL5, data32); } data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); data32 &= (~0x30); /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */ - data32 |= (pbi->mem_map_mode << 4); - data32 &= (~0xf); - data32 |= (pbi->endian & 0xf); /* valid only when double write only */ + data32 |= (pbi->mem_map_mode << + 4); + data32 &= (~0xF); + data32 |= 0xf; /* valid only when double write only */ + /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ /* swap uv */ if (pbi->is_used_v4l) { @@ -6437,8 +5757,7 @@ else data32 &= ~(1 << 12); /* NV12 */ } - data32 &= (~(3 << 8)); - data32 |= (2 << 8); /* line align with 64 for dw only */ + /* * [3:0] little_endian * [5:4] address_format 00:linear 01:32x32 10:64x32 @@ -6455,7 +5774,7 @@ static void vp9_config_work_space_hw(struct VP9Decoder_s *pbi, u32 mask) { struct BuffInfo_s *buf_spec = pbi->work_space_buf; - unsigned int data32, data_tmp; + unsigned int data32; int losless_comp_header_size, losless_comp_body_size; if (debug && pbi->init_flag == 0) @@ -6493,32 +5812,29 @@ } - if ((mask & HW_MASK_BACK) == 0) - return; - + if (mask & HW_MASK_BACK) { #ifdef LOSLESS_COMPRESS_MODE - losless_comp_header_size = - compute_losless_comp_header_size(pbi->init_pic_w, - pbi->init_pic_h); - losless_comp_body_size = - compute_losless_comp_body_size(pbi->init_pic_w, - pbi->init_pic_h, buf_alloc_depth == 10); + losless_comp_header_size = + compute_losless_comp_header_size(pbi->init_pic_w, + pbi->init_pic_h); + losless_comp_body_size = + compute_losless_comp_body_size(pbi->init_pic_w, + pbi->init_pic_h, buf_alloc_depth == 10); #endif - WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, - buf_spec->ipp.buf_start); - //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start); - //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - /* cfg_addr_adp*/ - WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start); - if (debug & VP9_DEBUG_BUFMGR_MORE) - pr_info("Write HEVC_DBLK_CFGE\n"); - } - /* 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(HEVCD_IPP_LINEBUFF_BASE, + buf_spec->ipp.buf_start); + //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start); + //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { + /* cfg_addr_adp*/ + WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start); + if (debug & VP9_DEBUG_BUFMGR_MORE) + pr_info("Write HEVC_DBLK_CFGE\n"); + } + /* 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); if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { /* @@ -6558,7 +5874,6 @@ 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); - if (get_double_write_mode(pbi) & 0x10) WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); #else @@ -6578,76 +5893,20 @@ data32 |= (1<<10); WRITE_VREG(HEVC_SAO_CTRL5, data32); } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - 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)); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - if (get_double_write_mode(pbi) & 0x20) { - WRITE_VREG(HEVC_DW_VH0_ADDDR, - buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec) * 2); - WRITE_VREG(HEVC_DW_VH1_ADDDR, - buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec) * 3); - } - } - data32 = READ_VREG(HEVC_SAO_CTRL5); - /* use HEVC_CM_HEADER_START_ADDR */ - data32 |= (1<<15); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - } -#endif - - /* config mpred axi burst threshold */ - WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412); - -#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 - - WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start); + WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start); WRITE_VREG(LMEM_DUMP_ADR, (u32)pbi->lmem_phy_addr); - - WRITE_VREG(VP9_PROB_SWAP_BUFFER, pbi->prob_buffer_phy_addr); - WRITE_VREG(VP9_COUNT_SWAP_BUFFER, pbi->count_buffer_phy_addr); - if (pbi->mmu_enable) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) - WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, pbi->frame_mmu_map_phy_addr); - else - WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr); - } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, pbi->frame_mmu_dw_map_phy_addr); - //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, pbi->frame_mmu_dw_map_phy_addr); - } else { - WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, pbi->frame_mmu_dw_map_phy_addr); + /**/ + WRITE_VREG(VP9_PROB_SWAP_BUFFER, pbi->prob_buffer_phy_addr); + WRITE_VREG(VP9_COUNT_SWAP_BUFFER, pbi->count_buffer_phy_addr); + if (pbi->mmu_enable) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) + WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, pbi->frame_mmu_map_phy_addr); + else + WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr); } - WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0); - WRITE_VREG(HEVC_SAO_C_START_ADDR, 0); -#ifdef VP9_10B_HED_FB - WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR2, FB_FRAME_MMU_MAP_ADDR); - #ifdef VP9_10B_HED_SAME_FB - WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR2, FB_FRAME_MMU_MAP_ADDR); - #endif -#endif } -#endif } @@ -7018,13 +6277,10 @@ if (mask & HW_MASK_BACK) { /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/ - if (is_rdma_enable()) - rdma_back_end_work(pbi->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); - } + + WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/ + for (i = 0; i < 1024; i++) + WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); } if (mask & HW_MASK_FRONT) { @@ -7412,30 +6668,21 @@ pbi->lmem_phy_addr); pbi->lmem_addr = NULL; } - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - (vdec_secure(hw_to_vdec(pbi)))) { - tee_vp9_prob_free((u32)pbi->prob_buffer_phy_addr); - pbi->prob_buffer_phy_addr = 0; - pbi->count_buffer_phy_addr = 0; + if (pbi->prob_buffer_addr) { + if (pbi->prob_buffer_phy_addr) + dma_free_coherent(amports_get_dma_device(), + PROB_BUF_SIZE, pbi->prob_buffer_addr, + pbi->prob_buffer_phy_addr); + pbi->prob_buffer_addr = NULL; + } + if (pbi->count_buffer_addr) { + if (pbi->count_buffer_phy_addr) + dma_free_coherent(amports_get_dma_device(), + COUNT_BUF_SIZE, pbi->count_buffer_addr, + pbi->count_buffer_phy_addr); + pbi->count_buffer_addr = NULL; - } else { - if (pbi->prob_buffer_addr) { - if (pbi->prob_buffer_phy_addr) - dma_free_coherent(amports_get_dma_device(), - PROB_BUF_SIZE, pbi->prob_buffer_addr, - pbi->prob_buffer_phy_addr); - - pbi->prob_buffer_addr = NULL; - } - if (pbi->count_buffer_addr) { - if (pbi->count_buffer_phy_addr) - dma_free_coherent(amports_get_dma_device(), - COUNT_BUF_SIZE, pbi->count_buffer_addr, - pbi->count_buffer_phy_addr); - - pbi->count_buffer_addr = NULL; - } } if (pbi->mmu_enable) { u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi); @@ -7448,21 +6695,6 @@ pbi->frame_mmu_map_addr = NULL; } } - -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - u32 dw_mmu_map_size = vvp9_frame_mmu_map_size(pbi); - if (pbi->frame_mmu_dw_map_addr) { - if (pbi->frame_mmu_dw_map_phy_addr) - dma_free_coherent(amports_get_dma_device(), - dw_mmu_map_size, - pbi->frame_mmu_dw_map_addr, - pbi->frame_mmu_dw_map_phy_addr); - pbi->frame_mmu_dw_map_addr = NULL; - } - } -#endif - #ifdef SUPPORT_FB_DECODING if (pbi->stage_mmu_map_addr) { if (pbi->stage_mmu_map_phy_addr) @@ -7499,41 +6731,58 @@ memcpy(cur_buf_info, &amvvp9_workbuff_spec[force_bufspec & 0xf], sizeof(struct BuffInfo_s)); 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) { - memcpy(cur_buf_info, &amvvp9_workbuff_spec[2], /* 8k */ - sizeof(struct BuffInfo_s)); - } else - memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k */ - sizeof(struct BuffInfo_s)); - } else - memcpy(cur_buf_info, &amvvp9_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()) { - memcpy(cur_buf_info, &amvvp9_workbuff_spec[5], /* 8k */ - sizeof(struct BuffInfo_s)); - } else - memcpy(cur_buf_info, &amvvp9_workbuff_spec[3],/* 1080p */ - sizeof(struct BuffInfo_s)); - } - } + } else if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + memcpy(cur_buf_info, &amvvp9_workbuff_spec[2], /* 8k */ + sizeof(struct BuffInfo_s)); + } else + memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k */ + sizeof(struct BuffInfo_s)); + } else + memcpy(cur_buf_info, &amvvp9_workbuff_spec[0],/* 1080p */ + sizeof(struct BuffInfo_s)); cur_buf_info->start_adr = pbi->buf_start; if (!pbi->mmu_enable) pbi->mc_buf_spec.buf_end = pbi->buf_start + pbi->buf_size; + +#else +/*! MULTI_INSTANCE_SUPPORT*/ + if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + cur_buf_info = &amvvp9_workbuff_spec[2];/* 8k work space */ + else + cur_buf_info = &amvvp9_workbuff_spec[1];/* 4k2k work space */ + } else + cur_buf_info = &amvvp9_workbuff_spec[0];/* 1080p work space */ + #endif init_buff_spec(pbi, cur_buf_info); vp9_bufmgr_init(pbi, cur_buf_info, NULL); - /* vp9_max_pic_w/h for debug */ - pbi->init_pic_w = (vp9_max_pic_w) ? vp9_max_pic_w: - ((pbi->max_pic_w) ? pbi->max_pic_w : pbi->work_space_buf->max_width); - pbi->init_pic_h = (vp9_max_pic_h) ? vp9_max_pic_h: - ((pbi->max_pic_h) ? pbi->max_pic_h : pbi->work_space_buf->max_height); + if (!vdec_is_support_4k() + && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) { + buf_alloc_width = 1920; + buf_alloc_height = 1088; + if (pbi->max_pic_w > 1920 && pbi->max_pic_h > 1088) { + pbi->max_pic_w = 1920; + pbi->max_pic_h = 1088; + } + } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + buf_alloc_width = 8192; + buf_alloc_height = 4608; + } + pbi->init_pic_w = pbi->max_pic_w ? pbi->max_pic_w : + (buf_alloc_width ? buf_alloc_width : + (pbi->vvp9_amstream_dec_info.width ? + pbi->vvp9_amstream_dec_info.width : + pbi->work_space_buf->max_width)); + pbi->init_pic_h = pbi->max_pic_h ? pbi->max_pic_h : + (buf_alloc_height ? buf_alloc_height : + (pbi->vvp9_amstream_dec_info.height ? + pbi->vvp9_amstream_dec_info.height : + pbi->work_space_buf->max_height)); /* video is not support unaligned with 64 in tl1 ** vdec canvas mode will be linear when dump yuv is set @@ -7552,11 +6801,9 @@ } #ifndef MV_USE_FIXED_BUF - if (!pbi->is_used_v4l) { - if (init_mv_buf_list(pbi) < 0) { - pr_err("%s: init_mv_buf_list fail\n", __func__); - return -1; - } + if (init_mv_buf_list(pbi) < 0) { + pr_err("%s: init_mv_buf_list fail\n", __func__); + return -1; } #endif if (pbi->save_buffer_mode) @@ -7595,38 +6842,24 @@ pr_err("%s: failed to alloc lmem buffer\n", __func__); return -1; } - pbi->lmem_ptr = pbi->lmem_addr; + pbi->lmem_ptr = pbi->lmem_addr; - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - (vdec_secure(hw_to_vdec(pbi)))) { - u32 prob_addr, id; - id = tee_vp9_prob_malloc(&prob_addr); - if (prob_addr <= 0) - pr_err("%s, tee[%d] malloc prob buf failed\n", __func__, id); - else { - pbi->prob_buffer_phy_addr = prob_addr; - pbi->count_buffer_phy_addr = pbi->prob_buffer_phy_addr + PROB_BUF_SIZE; - } - pbi->prob_buffer_addr = NULL; - pbi->count_buffer_addr = NULL; - } else { - pbi->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), - PROB_BUF_SIZE, - &pbi->prob_buffer_phy_addr, GFP_KERNEL); - if (pbi->prob_buffer_addr == NULL) { - pr_err("%s: failed to alloc prob_buffer\n", __func__); - return -1; - } - memset(pbi->prob_buffer_addr, 0, PROB_BUF_SIZE); - pbi->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), - COUNT_BUF_SIZE, - &pbi->count_buffer_phy_addr, GFP_KERNEL); - if (pbi->count_buffer_addr == NULL) { - pr_err("%s: failed to alloc count_buffer\n", __func__); - return -1; - } - memset(pbi->count_buffer_addr, 0, COUNT_BUF_SIZE); + pbi->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), + PROB_BUF_SIZE, + &pbi->prob_buffer_phy_addr, GFP_KERNEL); + if (pbi->prob_buffer_addr == NULL) { + pr_err("%s: failed to alloc prob_buffer\n", __func__); + return -1; } + memset(pbi->prob_buffer_addr, 0, PROB_BUF_SIZE); + pbi->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(), + COUNT_BUF_SIZE, + &pbi->count_buffer_phy_addr, GFP_KERNEL); + if (pbi->count_buffer_addr == NULL) { + pr_err("%s: failed to alloc count_buffer\n", __func__); + return -1; + } + memset(pbi->count_buffer_addr, 0, COUNT_BUF_SIZE); if (pbi->mmu_enable) { u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi); @@ -7640,20 +6873,6 @@ } memset(pbi->frame_mmu_map_addr, 0, COUNT_BUF_SIZE); } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) { - u32 dw_mmu_map_size = vvp9_frame_mmu_map_size(pbi); - pbi->frame_mmu_dw_map_addr = - dma_alloc_coherent(amports_get_dma_device(), - dw_mmu_map_size, - &pbi->frame_mmu_dw_map_phy_addr, GFP_KERNEL); - if (pbi->frame_mmu_dw_map_addr == NULL) { - pr_err("%s: failed to alloc count_buffer mmu dw\n", __func__); - return -1; - } - memset(pbi->frame_mmu_dw_map_addr, 0, COUNT_BUF_SIZE); - } -#endif #ifdef SUPPORT_FB_DECODING if (pbi->m_ins_flag && stage_buf_num > 0) { pbi->stage_mmu_map_addr = @@ -7706,14 +6925,16 @@ /*CANVAS_BLKMODE_64X32*/ if (pic_config->double_write_mode) { canvas_w = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(pbi, + pic_config->double_write_mode); canvas_h = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(pbi, + pic_config->double_write_mode); - /* sao ctrl1 reg alignline with 64, align with 64 */ - canvas_w = ALIGN(canvas_w, 64); + if (pbi->mem_map_mode == 0) + canvas_w = ALIGN(canvas_w, 32); + else + canvas_w = ALIGN(canvas_w, 64); canvas_h = ALIGN(canvas_h, 32); if (vdec->parallel_dec == 1) { @@ -7728,12 +6949,12 @@ pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1; } - config_cav_lut_ex(pic_config->y_canvas_index, + canvas_config_ex(pic_config->y_canvas_index, pic_config->dw_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC); - config_cav_lut_ex(pic_config->uv_canvas_index, + CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7); + canvas_config_ex(pic_config->uv_canvas_index, pic_config->dw_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC); + CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7); #ifdef MULTI_INSTANCE_SUPPORT pic_config->canvas_config[0].phy_addr = @@ -7783,42 +7004,37 @@ memset(&hdr, 0, sizeof(hdr)); hdr.signal_type = vf->signal_type; hdr.color_parms = pbi->vf_dp; - - hdr.color_parms.luminance[0] = hdr.color_parms.luminance[0] / 10000; - vdec_v4l_set_hdr_infos(ctx, &hdr); } if ((pbi->chunk != NULL) && (pbi->chunk->hdr10p_data_buf != NULL) && (pbi->chunk->hdr10p_data_size != 0)) { - if (pbi->chunk->hdr10p_data_size <= 128) { - char *new_buf; - int i = 0; - new_buf = kzalloc(pbi->chunk->hdr10p_data_size, GFP_ATOMIC); + char *new_buf; + int i = 0; + new_buf = vzalloc(pbi->chunk->hdr10p_data_size); - if (new_buf) { - memcpy(new_buf, pbi->chunk->hdr10p_data_buf, pbi->chunk->hdr10p_data_size); - if (debug & VP9_DEBUG_BUFMGR_MORE) { + if (new_buf) { + memcpy(new_buf, pbi->chunk->hdr10p_data_buf, pbi->chunk->hdr10p_data_size); + if (debug & VP9_DEBUG_BUFMGR_MORE) { + vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, + "hdr10p data: (size %d)\n", + pbi->chunk->hdr10p_data_size); + for (i = 0; i < pbi->chunk->hdr10p_data_size; i++) { vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, - "hdr10p data: (size %d)\n", - pbi->chunk->hdr10p_data_size); - for (i = 0; i < pbi->chunk->hdr10p_data_size; i++) { - vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, - "%02x ", pbi->chunk->hdr10p_data_buf[i]); - if (((i + 1) & 0xf) == 0) - vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n"); - } - vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n"); + "%02x ", pbi->chunk->hdr10p_data_buf[i]); + if (((i + 1) & 0xf) == 0) + vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n"); } - - vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size; - vf->hdr10p_data_buf = new_buf; - } else { - vp9_print(pbi, 0, "%s:hdr10p data vzalloc size(%d) fail\n", - __func__, pbi->chunk->hdr10p_data_size); - vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size; - vf->hdr10p_data_buf = new_buf; + vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n"); } + + vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size; + vf->hdr10p_data_buf = new_buf; + } else { + vp9_print(pbi, 0, "%s:hdr10p data vzalloc size(%d) fail\n", + __func__, pbi->chunk->hdr10p_data_size); + vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size; + vf->hdr10p_data_buf = new_buf; } vfree(pbi->chunk->hdr10p_data_buf); @@ -7883,18 +7099,17 @@ if (kfifo_get(&pbi->display_q, &vf)) { struct vframe_s *next_vf = NULL; uint8_t index = vf->index & 0xff; - ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q)); + ATRACE_COUNTER(pbi->disp_q_name, kfifo_len(&pbi->display_q)); if (index < pbi->used_buf_num || (vf->type & VIDTYPE_V4L_EOS)) { vf->index_disp = pbi->vf_get_count; pbi->vf_get_count++; if (debug & VP9_DEBUG_BUFMGR) - pr_info("%s idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n", - __func__, index, vf->type, + pr_info("%s type 0x%x w/h %d/%d, pts %d, %lld\n", + __func__, vf->type, vf->width, vf->height, vf->pts, - vf->pts_us64, - vf->timestamp); + vf->pts_us64); if (kfifo_peek(&pbi->display_q, &next_vf) && next_vf) { vf->next_vf_pts_valid = true; @@ -7905,7 +7120,6 @@ return vf; } } - return NULL; } @@ -7920,24 +7134,6 @@ if (!vf) return; - if (pbi->enable_fence && vf->fence) { - int ret, i; - - mutex_lock(&pbi->fence_mutex); - ret = dma_fence_get_status(vf->fence); - if (ret == 0) { - for (i = 0; i < VF_POOL_SIZE; i++) { - if (pbi->fence_vf_s.fence_vf[i] == NULL) { - pbi->fence_vf_s.fence_vf[i] = vf; - pbi->fence_vf_s.used_size++; - mutex_unlock(&pbi->fence_mutex); - return; - } - } - } - mutex_unlock(&pbi->fence_mutex); - } - index = vf->index & 0xff; if (pbi->enable_fence && vf->fence) { @@ -7946,23 +7142,14 @@ } if (vf->hdr10p_data_buf) { - kfree(vf->hdr10p_data_buf); + vfree(vf->hdr10p_data_buf); vf->hdr10p_data_buf = NULL; vf->hdr10p_data_size = 0; } kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q)); + ATRACE_COUNTER(pbi->new_q_name, kfifo_len(&pbi->newframe_q)); pbi->vf_put_count++; - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("%s idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n", - __func__, index, vf->type, - vf->width, vf->height, - vf->pts, - vf->pts_us64, - vf->timestamp); - if (index < pbi->used_buf_num) { struct VP9_Common_s *cm = &pbi->common; struct BufferPool_s *pool = cm->buffer_pool; @@ -7972,6 +7159,9 @@ if (pool->frame_bufs[index].buf.vf_ref > 0) pool->frame_bufs[index].buf.vf_ref--; + if (pbi->is_used_v4l) + pool->frame_bufs[index].buf.vframe_bound = true; + if (pbi->wait_buf) WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1); @@ -8100,29 +7290,11 @@ static void update_vf_memhandle(struct VP9Decoder_s *pbi, struct vframe_s *vf, struct PIC_BUFFER_CONFIG_s *pic) { - vf->mem_handle = NULL; - vf->mem_head_handle = NULL; - vf->mem_dw_handle = NULL; - - /* keeper not needed for v4l solution */ - if (pbi->is_used_v4l) - return; - - if (vf->type & VIDTYPE_SCATTER) { - -#ifdef VP9_10B_MMU_DW - if (pic->double_write_mode & 0x20) { - vf->mem_handle = - decoder_mmu_box_get_mem_handle( - pbi->mmu_box_dw, pic->index); - vf->mem_head_handle = - decoder_bmmu_box_get_mem_handle( - pbi->bmmu_box, - HEADER_BUFFER_IDX(pic->BUF_index)); - vf->mem_dw_handle = NULL; - } else -#endif - { + if (pic->index < 0) { + vf->mem_handle = NULL; + vf->mem_head_handle = NULL; + vf->mem_dw_handle = NULL; + } else if (vf->type & VIDTYPE_SCATTER) { vf->mem_handle = decoder_mmu_box_get_mem_handle( pbi->mmu_box, pic->index); @@ -8137,7 +7309,6 @@ VF_BUFFER_IDX(pic->BUF_index)); else vf->mem_dw_handle = NULL; - } } else { vf->mem_handle = decoder_bmmu_box_get_mem_handle( @@ -8151,12 +7322,11 @@ } } -static inline void pbi_update_gvs(struct VP9Decoder_s *pbi, - struct PIC_BUFFER_CONFIG_s *pic_config) +static inline void pbi_update_gvs(struct VP9Decoder_s *pbi) { - if (pbi->gvs->frame_height != pic_config->y_crop_height) { - pbi->gvs->frame_width = pic_config->y_crop_width; - pbi->gvs->frame_height = pic_config->y_crop_height; + if (pbi->gvs->frame_height != frame_height) { + pbi->gvs->frame_width = frame_width; + pbi->gvs->frame_height = frame_height; } if (pbi->gvs->frame_dur != pbi->frame_dur) { pbi->gvs->frame_dur = pbi->frame_dur; @@ -8177,7 +7347,6 @@ int stream_offset = pic_config->stream_offset; unsigned short slice_type = pic_config->slice_type; struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; ulong nv_order = VIDTYPE_VIU_NV21; u32 pts_valid = 0, pts_us64_valid = 0; u32 pts_save; @@ -8192,7 +7361,6 @@ pr_info("fatal error, no available buffer slot."); return -1; } - /* swap uv */ if (pbi->is_used_v4l) { if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || @@ -8200,8 +7368,7 @@ nv_order = VIDTYPE_VIU_NV12; } - if (pic_config->double_write_mode && - (pic_config->double_write_mode & 0x20) == 0) + if (pic_config->double_write_mode) set_canvas(pbi, pic_config); display_frame_count[pbi->index]++; @@ -8209,20 +7376,20 @@ if (!force_pts_unstable) { if ((pic_config->pts == 0) || ((pic_config->pts <= pbi->last_pts) && (pic_config->pts64 <= pbi->last_pts_us64))) { - for (i = (FRAME_BUFFERS - 1); i > 0; i--) { - if ((pbi->last_pts == pbi->frame_mode_pts_save[i]) || - (pbi->last_pts_us64 == pbi->frame_mode_pts64_save[i])) { - pic_config->pts = pbi->frame_mode_pts_save[i - 1]; - pic_config->pts64 = pbi->frame_mode_pts64_save[i - 1]; - break; - } + for (i = (FRAME_BUFFERS - 1); i > 0; i--) { + if ((pbi->last_pts == pbi->frame_mode_pts_save[i]) || + (pbi->last_pts_us64 == pbi->frame_mode_pts64_save[i])) { + pic_config->pts = pbi->frame_mode_pts_save[i - 1]; + pic_config->pts64 = pbi->frame_mode_pts64_save[i - 1]; + break; + } } if ((i == 0) || (pic_config->pts <= pbi->last_pts)) { - vp9_print(pbi, VP9_DEBUG_OUT_PTS, - "no found pts %d, set 0. %d, %d\n", - i, pic_config->pts, pbi->last_pts); - pic_config->pts = 0; - pic_config->pts64 = 0; + vp9_print(pbi, VP9_DEBUG_OUT_PTS, + "no found pts %d, set 0. %d, %d\n", + i, pic_config->pts, pbi->last_pts); + pic_config->pts = 0; + pic_config->pts64 = 0; } } } @@ -8230,12 +7397,11 @@ if (pbi->is_used_v4l) { vf->v4l_mem_handle = pbi->m_BUF[pic_config->BUF_index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; if (pbi->mmu_enable) { vf->mm_box.bmmu_box = pbi->bmmu_box; - vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(pbi->buffer_wrap[pic_config->BUF_index]); + vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(pic_config->BUF_index); vf->mm_box.mmu_box = pbi->mmu_box; - vf->mm_box.mmu_idx = pbi->buffer_wrap[pic_config->index]; + vf->mm_box.mmu_idx = pic_config->index; } } @@ -8249,12 +7415,7 @@ if (vdec_frame_based(pvdec)) { vf->pts = pic_config->pts; vf->pts_us64 = pic_config->pts64; - - if (pbi->is_used_v4l && v4l_bitstream_id_enable) - vf->timestamp = pic_config->timestamp; - else - vf->timestamp = pic_config->pts64; - + vf->timestamp = pic_config->timestamp; if (vf->pts != 0 || vf->pts_us64 != 0) { pts_valid = 1; pts_us64_valid = 1; @@ -8292,7 +7453,7 @@ pts_save = vf->pts; pts_us64_save = vf->pts_us64; - if (pbi->is_used_v4l || pbi->pts_unstable) { + if (pbi->pts_unstable) { frame_duration_adapt(pbi, vf, pts_valid); if (pbi->duration_from_pts_done) { pbi->pts_mode = PTS_NONE_REF_USE_DURATION; @@ -8364,28 +7525,10 @@ /* double write only */ vf->compBodyAddr = 0; vf->compHeadAddr = 0; -#ifdef VP9_10B_MMU_DW - vf->dwBodyAddr = 0; - vf->dwHeadAddr = 0; -#endif } else { if (pbi->mmu_enable) { vf->compBodyAddr = 0; vf->compHeadAddr = pic_config->header_adr; -#ifdef VP9_10B_MMU_DW - vf->dwBodyAddr = 0; - vf->dwHeadAddr = 0; - if (pic_config->double_write_mode & 0x20) { - u32 mode = pic_config->double_write_mode & 0xf; - if (mode == 5 || mode == 3) - vf->dwHeadAddr = pic_config->header_dw_adr; - else if ((mode == 1 || mode == 2 || mode == 4) - && (debug & VP9_DEBUG_OUT_PTS) == 0) { - vf->compHeadAddr = pic_config->header_dw_adr; - pr_debug("Use dw mmu for display\n"); - } - } -#endif } else { /*vf->compBodyAddr = pic_config->mc_y_adr; *vf->compHeadAddr = pic_config->mc_y_adr + @@ -8394,13 +7537,11 @@ } vf->canvas0Addr = vf->canvas1Addr = 0; } - if (pic_config->double_write_mode && - (pic_config->double_write_mode & 0x20) == 0) { + if (pic_config->double_write_mode) { vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; vf->type |= nv_order; - if ((pic_config->double_write_mode == 3 || - pic_config->double_write_mode == 5) && + if ((pic_config->double_write_mode == 3) && (!IS_8K_SIZE(pic_config->y_crop_width, pic_config->y_crop_height))) { vf->type |= VIDTYPE_COMPRESS; @@ -8452,29 +7593,24 @@ if (pic_config->bit_depth == VPX_BITS_8) vf->bitdepth |= BITDEPTH_SAVING_MODE; + /* if((vf->width!=pic_config->width)| + * (vf->height!=pic_config->height)) + */ + /* pr_info("aaa: %d/%d, %d/%d\n", + vf->width,vf->height, pic_config->width, + pic_config->height); */ vf->width = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(pbi, + pic_config->double_write_mode); vf->height = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); + get_double_write_ratio(pbi, + pic_config->double_write_mode); if (force_w_h != 0) { vf->width = (force_w_h >> 16) & 0xffff; vf->height = force_w_h & 0xffff; } - if ((pic_config->double_write_mode & 0x20) && - ((pic_config->double_write_mode & 0xf) == 2 || - (pic_config->double_write_mode & 0xf) == 4)) { - vf->compWidth = pic_config->y_crop_width / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); - vf->compHeight = pic_config->y_crop_height / - get_double_write_ratio( - pic_config->double_write_mode & 0xf); - } else { - vf->compWidth = pic_config->y_crop_width; - vf->compHeight = pic_config->y_crop_height; - } + vf->compWidth = pic_config->y_crop_width; + vf->compHeight = pic_config->y_crop_height; set_frame_info(pbi, vf); if (force_fps & 0x100) { u32 rate = force_fps & 0xff; @@ -8491,10 +7627,9 @@ } if ((debug & VP9_DEBUG_OUT_PTS) != 0) { pr_info - ("VP9 dec out pts: pts_mode=%d,dur=%d,pts(%d,%lld,%lld)(%d,%lld)\n", + ("VP9 dec out pts: pts_mode=%d,dur=%d,pts(%d,%lld)(%d,%lld)\n", pbi->pts_mode, pbi->frame_dur, vf->pts, - vf->pts_us64, vf->timestamp, pts_save, - pts_us64_save); + vf->pts_us64, pts_save, pts_us64_save); } if (!(pic_config->y_crop_width == 196 && pic_config->y_crop_height == 196 @@ -8506,11 +7641,11 @@ decoder_do_frame_check(pvdec, vf); vdec_vframe_ready(pvdec, vf); kfifo_put(&pbi->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(pbi->trace.pts_name, vf->pts); - ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q)); - ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q)); + ATRACE_COUNTER(pbi->pts_name, vf->pts); + ATRACE_COUNTER(pbi->new_q_name, kfifo_len(&pbi->newframe_q)); + ATRACE_COUNTER(pbi->disp_q_name, kfifo_len(&pbi->display_q)); pbi->vf_pre_count++; - pbi_update_gvs(pbi, pic_config); + pbi_update_gvs(pbi); /*count info*/ vdec_count_info(pbi->gvs, 0, stream_offset); if (stream_offset) { @@ -8525,21 +7660,13 @@ memcpy(&tmp4x, pbi->gvs, sizeof(struct vdec_info)); tmp4x.bit_depth_luma = pbi->vp9_param.p.bit_depth; tmp4x.bit_depth_chroma = pbi->vp9_param.p.bit_depth; - tmp4x.double_write_mode = pic_config->double_write_mode; + tmp4x.double_write_mode = get_double_write_mode(pbi); vdec_fill_vdec_frame(pvdec, &pbi->vframe_qos, &tmp4x, vf, pic_config->hw_decode_time); pvdec->vdec_fps_detec(pvdec->id); if (without_display_mode == 0) { - if (pbi->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vvp9_vf_put(vvp9_vf_get(pbi), pbi); - } else { - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else { - vf_notify_receiver(pbi->provider_name, + vf_notify_receiver(pbi->provider_name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } } else vvp9_vf_put(vvp9_vf_get(pbi), pbi); } else { @@ -8573,8 +7700,7 @@ } if (index == INVALID_IDX) { - ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token); - if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) { + if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) { pr_err("[%d] EOS get free buff fail.\n", ctx->id); return -1; } @@ -8586,16 +7712,11 @@ vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb : hw->m_BUF[index].v4l_ref_buf_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; vdec_vframe_ready(vdec, vf); kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - if (hw->is_used_v4l) - fb->task->submit(fb->task, TASK_TYPE_DEC); - else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + vf_notify_receiver(vdec->vf_provider_name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); pr_info("[%d] VP9 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id); } @@ -8693,43 +7814,6 @@ } -static int recycle_mmu_buf_tail(struct VP9Decoder_s *pbi, - bool check_dma) -{ - struct VP9_Common_s *const cm = &pbi->common; - - if (pbi->used_4k_num == -1) { - pbi->used_4k_num = - READ_VREG(HEVC_SAO_MMU_STATUS) >> 16; - } - vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, - "pic index %d page_start %d\n", - cm->cur_fb_idx_mmu, pbi->used_4k_num); - - if (check_dma) - hevc_mmu_dma_check(hw_to_vdec(pbi)); - - if (pbi->is_used_v4l) { - int index = cm->cur_fb_idx_mmu; - struct internal_comp_buf *ibuf = - index_to_icomp_buf(pbi, index); - - decoder_mmu_box_free_idx_tail( - ibuf->mmu_box, - ibuf->index, - pbi->used_4k_num); - } else { - decoder_mmu_box_free_idx_tail( - pbi->mmu_box, - cm->cur_fb_idx_mmu, - pbi->used_4k_num); - } - - cm->cur_fb_idx_mmu = INVALID_IDX; - pbi->used_4k_num = -1; - - return 0; -} static void vp9_recycle_mmu_buf_tail(struct VP9Decoder_s *pbi) { @@ -8737,9 +7821,16 @@ if (pbi->double_write_mode & 0x10) return; if (cm->cur_fb_idx_mmu != INVALID_IDX) { - recycle_mmu_buf_tail(pbi, - ((pbi->used_4k_num == -1) && - pbi->m_ins_flag) ? 1 : 0); + if (pbi->used_4k_num == -1) { + pbi->used_4k_num = + (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); + if (pbi->m_ins_flag) + hevc_mmu_dma_check(hw_to_vdec(pbi)); + } + decoder_mmu_box_free_idx_tail(pbi->mmu_box, + cm->cur_fb_idx_mmu, pbi->used_4k_num); + cm->cur_fb_idx_mmu = INVALID_IDX; + pbi->used_4k_num = -1; } } @@ -8747,10 +7838,6 @@ static void vp9_recycle_mmu_buf(struct VP9Decoder_s *pbi) { struct VP9_Common_s *const cm = &pbi->common; - - if (pbi->is_used_v4l) - return; - if (pbi->double_write_mode & 0x10) return; if (cm->cur_fb_idx_mmu != INVALID_IDX) { @@ -8803,6 +7890,7 @@ if (pbi->is_used_v4l && ctx->param_sets_from_ucode) pbi->res_ch_flag = 0; + bit_depth_luma = pbi->vp9_param.p.bit_depth; bit_depth_chroma = pbi->vp9_param.p.bit_depth; @@ -8833,22 +7921,6 @@ pr_err("can't alloc need mmu1,idx %d ret =%d\n", cm->new_fb_idx, ret); - -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) { - ret = vp9_alloc_mmu_dw(pbi, - cm->new_fb_idx, - params->p.width, - params->p.height, - params->p.bit_depth, - pbi->frame_mmu_dw_map_addr); - if (ret < 0) - pr_err("can't alloc need dw mmu1,idx %d ret =%d\n", - cm->new_fb_idx, - ret); - } -#endif - } else { ret = 0; } @@ -8860,11 +7932,8 @@ ret); WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL); cm->show_frame = 0; - if (pbi->mmu_enable) { - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); + if (pbi->mmu_enable) vp9_recycle_mmu_buf(pbi); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } #ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) { pbi->dec_result = DEC_RESULT_DONE; @@ -8891,14 +7960,11 @@ if (pbi->chunk) { cur_pic_config->pts = pbi->chunk->pts; cur_pic_config->pts64 = pbi->chunk->pts64; - - if (pbi->is_used_v4l && !v4l_bitstream_id_enable) - cur_pic_config->pts64 = pbi->chunk->timestamp; + cur_pic_config->timestamp = pbi->chunk->timestamp; } #endif } /*pr_info("Decode Frame Data %d\n", pbi->frame_count);*/ - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START); config_pic_size(pbi, pbi->vp9_param.p.bit_depth); if ((pbi->common.frame_type != KEY_FRAME) @@ -8914,7 +7980,6 @@ #endif clear_mpred_hw(pbi); } - #ifdef MCRCC_ENABLE if (mcrcc_cache_alg_flag) config_mcrcc_axi_hw_new(pbi); @@ -8980,28 +8045,11 @@ if ((frame_bufs[i].ref_count == 0) && (frame_bufs[i].buf.vf_ref == 0) && (frame_bufs[i].buf.index != -1)) { - if (pbi->is_used_v4l) { - struct internal_comp_buf *ibuf = - index_to_icomp_buf(pbi, i); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); - decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } else { - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); - decoder_mmu_box_free_idx(pbi->mmu_box, i); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable) - decoder_mmu_box_free_idx(pbi->mmu_box_dw, i); -#endif - - } + decoder_mmu_box_free_idx(pbi->mmu_box, i); } pbi->last_put_idx = -1; } } - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END); return ret; } @@ -9103,7 +8151,7 @@ frame->min_mv = a[0]; vp9_print(pbi, VP9_DEBUG_QOS_INFO, - "mv data %x a[0]= %x a[1]= %x a[2]= %x\n", + "mv data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); data = READ_VREG(HEVC_QP_INFO); @@ -9130,7 +8178,7 @@ frame->min_qp = a[0]; vp9_print(pbi, VP9_DEBUG_QOS_INFO, - "qp data %x a[0]= %x a[1]= %x a[2]= %x\n", + "qp data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); data = READ_VREG(HEVC_SKIP_INFO); @@ -9157,7 +8205,7 @@ frame->min_skip = a[0]; vp9_print(pbi, VP9_DEBUG_QOS_INFO, - "skip data %x a[0]= %x a[1]= %x a[2]= %x\n", + "skip data %lx a[0]= %x a[1]= %x a[2]= %x\n", data, a[0], a[1], a[2]); } else { uint32_t blk88_y_count; @@ -9476,29 +8524,14 @@ } } -static void vvp9_get_comp_buf_info(struct VP9Decoder_s *pbi, - struct vdec_comp_buf_info *info) -{ - u16 bit_depth = pbi->param.p.bit_depth; - - info->max_size = vp9_max_mmu_buf_size( - pbi->max_pic_w, - pbi->max_pic_h); - info->header_size = vvp9_mmu_compress_header_size( - pbi->frame_width, - pbi->frame_height); - info->frame_buffer_size = vp9_mmu_page_num( - pbi, pbi->frame_width, - pbi->frame_height, - bit_depth == 0); -} - static int vvp9_get_ps_info(struct VP9Decoder_s *pbi, struct aml_vdec_ps_infos *ps) { - ps->visible_width = pbi->frame_width; - ps->visible_height = pbi->frame_height; - ps->coded_width = ALIGN(pbi->frame_width, 64); - ps->coded_height = ALIGN(pbi->frame_height, 64); + int dw_mode = v4l_parser_get_double_write_mode(pbi); + + ps->visible_width = pbi->frame_width / get_double_write_ratio(pbi, dw_mode); + ps->visible_height = pbi->frame_height / get_double_write_ratio(pbi, dw_mode); + ps->coded_width = ALIGN(pbi->frame_width, 32) / get_double_write_ratio(pbi, dw_mode); + ps->coded_height = ALIGN(pbi->frame_height, 32) / get_double_write_ratio(pbi, dw_mode); ps->dpb_size = pbi->used_buf_num; return 0; @@ -9509,34 +8542,22 @@ { struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); + struct VP9_Common_s *const cm = &pbi->common; int ret = 0; if (ctx->param_sets_from_ucode && pbi->res_ch_flag == 0) { struct aml_vdec_ps_infos ps; - struct vdec_comp_buf_info comp; + if ((cm->width != 0 && + cm->height != 0) && + (pbi->frame_width != cm->width || + pbi->frame_height != cm->height)) { - if ((pbi->last_width != 0 && - pbi->last_height != 0) && - (pbi->frame_width != pbi->last_width || - pbi->frame_height != pbi->last_height)) { - - vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, pbi->last_width, - pbi->last_height, pbi->frame_width, pbi->frame_height); - - if (get_valid_double_write_mode(pbi) != 16) { - vvp9_get_comp_buf_info(pbi, &comp); - vdec_v4l_set_comp_buf_info(ctx, &comp); - } - + vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, + cm->height, pbi->frame_width, pbi->frame_height); vvp9_get_ps_info(pbi, &ps); vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); - - pbi->init_pic_w = pbi->frame_width; - pbi->init_pic_h = pbi->frame_height; - init_mv_buf_list(pbi); - pbi->v4l_params_parsed = false; pbi->res_ch_flag = 1; ctx->v4l_resolution_change = 1; @@ -9561,14 +8582,6 @@ /*if (pbi->wait_buf) * pr_info("set wait_buf to 0\r\n"); */ - - if (dec_status == VP9_HEAD_PARSER_DONE) { - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START); - } - else if (dec_status == HEVC_DECPIC_DATA_DONE) { - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START); - } - if (pbi->eos) return IRQ_HANDLED; pbi->wait_buf = 0; @@ -9604,15 +8617,8 @@ if (!vdec_frame_based(hw_to_vdec(pbi))) dec_again_process(pbi); else { - if (pbi->common.show_existing_frame) { - pbi->dec_result = DEC_RESULT_DONE; - amhevc_stop(); - vdec_schedule_work(&pbi->work); - } - else { - pbi->dec_result = DEC_RESULT_GET_DATA; - vdec_schedule_work(&pbi->work); - } + pbi->dec_result = DEC_RESULT_GET_DATA; + vdec_schedule_work(&pbi->work); } } pbi->process_busy = 0; @@ -9643,7 +8649,6 @@ amhevc_stop(); if (mcrcc_cache_alg_flag) dump_hit_rate(pbi); - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_EDN); vdec_schedule_work(&pbi->work); } } else { @@ -9728,11 +8733,9 @@ && pbi->used_stage_buf_num == 0 #endif ) { - if (pbi->mmu_enable) { - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START); + if (pbi->mmu_enable) vp9_recycle_mmu_buf_tail(pbi); - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END); - } + if (pbi->frame_count > 0) vp9_bufmgr_postproc(pbi); @@ -9791,14 +8794,12 @@ } else #endif { - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START); for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { int ii; for (ii = 0; ii < 4; ii++) pbi->vp9_param.l.data[i + ii] = pbi->rpm_ptr[i + 3 - ii]; } - ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END); } } @@ -9821,22 +8822,11 @@ if (!v4l_res_change(pbi)) { if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) { struct aml_vdec_ps_infos ps; - struct vdec_comp_buf_info comp; pr_debug("set ucode parse\n"); - if (get_valid_double_write_mode(pbi) != 16) { - vvp9_get_comp_buf_info(pbi, &comp); - vdec_v4l_set_comp_buf_info(ctx, &comp); - } - vvp9_get_ps_info(pbi, &ps); /*notice the v4l2 codec.*/ vdec_v4l_set_ps_infos(ctx, &ps); - - pbi->init_pic_w = pbi->frame_width; - pbi->init_pic_h = pbi->frame_height; - init_mv_buf_list(pbi); - pbi->v4l_params_parsed = true; pbi->postproc_done = 0; pbi->process_busy = 0; @@ -9859,7 +8849,7 @@ if (pbi->m_ins_flag) start_process_time(pbi); #endif - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); + return IRQ_HANDLED; } @@ -9869,25 +8859,22 @@ unsigned int dec_status; struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data; unsigned int adapt_prob_status; + struct VP9_Common_s *const cm = &pbi->common; uint debug_tag; WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - if (dec_status == VP9_HEAD_PARSER_DONE) { - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_HEAD_DONE); - } - else if (dec_status == HEVC_DECPIC_DATA_DONE) { - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_PIC_DONE); - } - adapt_prob_status = READ_VREG(VP9_ADAPT_PROB_REG); if (!pbi) return IRQ_HANDLED; if (pbi->init_flag == 0) return IRQ_HANDLED; - if (pbi->process_busy)/*on process.*/ + if (pbi->process_busy) {/*on process.*/ + vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, + "%s: process_busy isr return\n", __func__); return IRQ_HANDLED; + } pbi->dec_status = dec_status; pbi->process_busy = 1; if (debug & VP9_DEBUG_BUFMGR) @@ -9977,44 +8964,34 @@ } #endif if ((adapt_prob_status & 0xff) == 0xfd) { - struct VP9_Common_s *const cm = &pbi->common; - int pre_fc = 0; - + /*VP9_REQ_ADAPT_PROB*/ + int pre_fc = (cm->frame_type == KEY_FRAME) ? 1 : 0; + uint8_t *prev_prob_b = + ((uint8_t *)pbi->prob_buffer_addr) + + ((adapt_prob_status >> 8) * 0x1000); + uint8_t *cur_prob_b = + ((uint8_t *)pbi->prob_buffer_addr) + 0x4000; + uint8_t *count_b = (uint8_t *)pbi->count_buffer_addr; +#ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) - reset_process_time(pbi); + reset_process_time(pbi); +#endif + adapt_coef_probs(pbi->pic_count, + (cm->last_frame_type == KEY_FRAME), + pre_fc, (adapt_prob_status >> 8), + (unsigned int *)prev_prob_b, + (unsigned int *)cur_prob_b, (unsigned int *)count_b); - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) && - (vdec_secure(hw_to_vdec(pbi)))) { - pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only)) ? 0 : 1; - tee_vp9_prob_process(pre_fc, cm->last_frame_type, - adapt_prob_status, (unsigned int)pbi->prob_buffer_phy_addr); - } else { - uint8_t *prev_prob_b, *cur_prob_b, *count_b; - - /*VP9_REQ_ADAPT_PROB*/ - pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only)); - prev_prob_b = ((uint8_t *)pbi->prob_buffer_addr) + - ((adapt_prob_status >> 8) * 0x1000); - cur_prob_b = ((uint8_t *)pbi->prob_buffer_addr) + 0x4000; - count_b = (uint8_t *)pbi->count_buffer_addr; - - adapt_coef_probs(pbi->pic_count, - (cm->last_frame_type == KEY_FRAME), - pre_fc, (adapt_prob_status >> 8), - (unsigned int *)prev_prob_b, - (unsigned int *)cur_prob_b, (unsigned int *)count_b); - - memcpy(prev_prob_b, cur_prob_b, PROB_SIZE); - } - + memcpy(prev_prob_b, cur_prob_b, PROB_SIZE); WRITE_VREG(VP9_ADAPT_PROB_REG, 0); pbi->pic_count += 1; #ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) start_process_time(pbi); #endif + + /*return IRQ_HANDLED;*/ } - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_END); return IRQ_WAKE_THREAD; } @@ -10030,14 +9007,15 @@ frame_height * fps; } -static void vvp9_put_timer_func(struct timer_list *timer) +static void vvp9_put_timer_func(unsigned long arg) { - struct VP9Decoder_s *pbi = container_of(timer, - struct VP9Decoder_s, timer); - enum receviver_start_e state = RECEIVER_INACTIVE; + struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)arg; + struct timer_list *timer = &pbi->timer; uint8_t empty_flag; unsigned int buf_level; + enum receviver_start_e state = RECEIVER_INACTIVE; + if (pbi->m_ins_flag) { if (hw_to_vdec(pbi)->next_status == VDEC_STATUS_DISCONNECTED && @@ -10539,10 +9517,12 @@ fw->len = fw_size; INIT_WORK(&pbi->set_clk_work, vp9_set_clk); - timer_setup(&pbi->timer, vvp9_put_timer_func, 0); + init_timer(&pbi->timer); #ifdef MULTI_INSTANCE_SUPPORT if (pbi->m_ins_flag) { + pbi->timer.data = (ulong) pbi; + pbi->timer.function = vvp9_put_timer_func; pbi->timer.expires = jiffies + PUT_INTERVAL; /*add_timer(&pbi->timer); @@ -10599,18 +9579,16 @@ pbi->provider_name = PROVIDER_NAME; #ifdef MULTI_INSTANCE_SUPPORT - if (!pbi->is_used_v4l) { - vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME, - &vvp9_vf_provider, pbi); - vf_reg_provider(&vvp9_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); - if (pbi->frame_dur != 0) { - if (!is_reset) - vf_notify_receiver(pbi->provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *) - ((unsigned long)pbi->frame_dur)); - } + vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME, + &vvp9_vf_provider, pbi); + vf_reg_provider(&vvp9_vf_prov); + vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); + if (pbi->frame_dur != 0) { + if (!is_reset) + vf_notify_receiver(pbi->provider_name, + VFRAME_EVENT_PROVIDER_FR_HINT, + (void *) + ((unsigned long)pbi->frame_dur)); } #else vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME, &vvp9_vf_provider, @@ -10623,11 +9601,14 @@ #endif pbi->stat |= STAT_VF_HOOK; + pbi->timer.data = (ulong)pbi; + pbi->timer.function = vvp9_put_timer_func; pbi->timer.expires = jiffies + PUT_INTERVAL; - add_timer(&pbi->timer); pbi->stat |= STAT_VDEC_RUN; + add_timer(&pbi->timer); + pbi->stat |= STAT_TIMER_ARM; amhevc_start(); @@ -10656,7 +9637,7 @@ pbi->stat &= ~STAT_TIMER_ARM; } - if (!pbi->is_used_v4l && (pbi->stat & STAT_VF_HOOK)) { + if (pbi->stat & STAT_VF_HOOK) { if (!is_reset) vf_notify_receiver(pbi->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -10705,7 +9686,7 @@ pbi->stat &= ~STAT_TIMER_ARM; } - if (!pbi->is_used_v4l && (pbi->stat & STAT_VF_HOOK)) { + if (pbi->stat & STAT_VF_HOOK) { if (!is_reset) vf_notify_receiver(pbi->provider_name, VFRAME_EVENT_PROVIDER_FR_END_HINT, @@ -10736,16 +9717,22 @@ pbi->fw = NULL; return 0; } - static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi) { int tvp_flag = vdec_secure(hw_to_vdec(pbi)) ? CODEC_MM_FLAGS_TVP : 0; - int buf_size = vp9_max_mmu_buf_size(pbi->max_pic_w, pbi->max_pic_h); + int buf_size = 48; + if ((pbi->max_pic_w * pbi->max_pic_h > 1280*736) && + (pbi->max_pic_w * pbi->max_pic_h <= 1920*1088)) { + buf_size = 12; + } else if ((pbi->max_pic_w * pbi->max_pic_h > 0) && + (pbi->max_pic_w * pbi->max_pic_h <= 1280*736)) { + buf_size = 4; + } pbi->need_cache_size = buf_size * SZ_1M; pbi->sc_start_time = get_jiffies_64(); - if (pbi->mmu_enable && !pbi->is_used_v4l) { + if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) { pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, pbi->index, FRAME_BUFFERS, pbi->need_cache_size, @@ -10756,18 +9743,6 @@ return -1; } } -#ifdef VP9_10B_MMU_DW - if (pbi->dw_mmu_enable && !pbi->is_used_v4l) { - pbi->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME, - pbi->index, FRAME_BUFFERS, - pbi->need_cache_size, - tvp_flag - ); - if (!pbi->mmu_box_dw) { - pr_err("vp9 alloc mmu dw box failed!!\n"); - } - } -#endif pbi->bmmu_box = decoder_bmmu_box_alloc_box( DRIVER_NAME, pbi->index, @@ -10794,16 +9769,10 @@ #ifndef MULTI_INSTANCE_SUPPORT int i; #endif - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) { - pr_info("vp9 unsupported on cpu 0x%x\n", get_cpu_major_id()); - return -EINVAL; - } pr_debug("%s\n", __func__); mutex_lock(&vvp9_mutex); - pbi = vzalloc(sizeof(struct VP9Decoder_s)); + pbi = vmalloc(sizeof(struct VP9Decoder_s)); if (pbi == NULL) { pr_info("\namvdec_vp9 device data allocation failed\n"); mutex_unlock(&vvp9_mutex); @@ -10817,29 +9786,12 @@ pbi->init_flag = 0; pbi->first_sc_checked= 0; - - if (!vdec_is_support_4k()) { - pbi->max_pic_w = 1920; - pbi->max_pic_h = 1088; - } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) { - pbi->max_pic_w = 4096; - pbi->max_pic_h = 2304; - } else { - pbi->max_pic_w = 8192; - pbi->max_pic_h = 4608; + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { + vp9_max_pic_w = 8192; + vp9_max_pic_h = 4608; } - if (pdata->sys_info) { - pbi->vvp9_amstream_dec_info = *pdata->sys_info; - if ((pbi->vvp9_amstream_dec_info.width != 0) && - (pbi->vvp9_amstream_dec_info.height != 0)) { - pbi->max_pic_w = pbi->vvp9_amstream_dec_info.width; - pbi->max_pic_h = pbi->vvp9_amstream_dec_info.height; - } - } else { - pbi->vvp9_amstream_dec_info.width = 0; - pbi->vvp9_amstream_dec_info.height = 0; - pbi->vvp9_amstream_dec_info.rate = 30; - } + pbi->max_pic_w = vp9_max_pic_w; + pbi->max_pic_h = vp9_max_pic_h; #ifdef MULTI_INSTANCE_SUPPORT pbi->eos = 0; @@ -10861,14 +9813,6 @@ #endif pbi->double_write_mode = double_write_mode; pbi->mmu_enable = 1; -#ifdef VP9_10B_MMU_DW - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - pbi->dw_mmu_enable = - (get_double_write_mode(pbi) & 0x20) ? 1 : 0; - } else { - pbi->dw_mmu_enable = 0; - } -#endif if (amvdec_vp9_mmu_init(pbi) < 0) { vfree(pbi); mutex_unlock(&vvp9_mutex); @@ -10901,18 +9845,20 @@ pr_info("===VP9 decoder mem resource 0x%lx size 0x%x\n", pdata->mem_start, pbi->buf_size); } + + if (pdata->sys_info) + pbi->vvp9_amstream_dec_info = *pdata->sys_info; + else { + pbi->vvp9_amstream_dec_info.width = 0; + pbi->vvp9_amstream_dec_info.height = 0; + pbi->vvp9_amstream_dec_info.rate = 30; + } pbi->no_head = no_head; #ifdef MULTI_INSTANCE_SUPPORT pbi->cma_dev = pdata->cma_dev; #else cma_dev = pdata->cma_dev; #endif - /* config endian */ - pbi->endian = HEVC_CONFIG_LITTLE_ENDIAN; - if (is_support_vdec_canvas()) - pbi->endian = HEVC_CONFIG_BIG_ENDIAN; - if (endian) - pbi->endian = endian; #ifdef MULTI_INSTANCE_SUPPORT pdata->private = pbi; @@ -10943,6 +9889,7 @@ struct vdec_sync *sync) { ulong expires; + int i; /* notify signal to wake up all fences. */ vdec_timeline_increase(sync, VF_POOL_SIZE); @@ -10955,6 +9902,15 @@ } } + for (i = 0; i < VF_POOL_SIZE; i++) { + struct vframe_s *vf = &pbi->vfpool[i]; + + if (vf->fence) { + vdec_fence_put(vf->fence); + vf->fence = NULL; + } + } + /* decreases refcnt of timeline. */ vdec_timeline_put(sync); } @@ -10990,7 +9946,7 @@ mem_map_mode = 0; if (pbi->enable_fence) - vdec_fence_release(pbi, vdec->sync); + vdec_fence_release(pbi, &vdec->sync); vfree(pbi); mutex_unlock(&vvp9_mutex); @@ -10999,16 +9955,32 @@ } /****************************************/ +#ifdef CONFIG_PM +static int vp9_suspend(struct device *dev) +{ + amhevc_suspend(to_platform_device(dev), dev->power.power_state); + return 0; +} + +static int vp9_resume(struct device *dev) +{ + amhevc_resume(to_platform_device(dev)); + return 0; +} + +static const struct dev_pm_ops vp9_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(vp9_suspend, vp9_resume) +}; +#endif static struct platform_driver amvdec_vp9_driver = { .probe = amvdec_vp9_probe, .remove = amvdec_vp9_remove, -#ifdef CONFIG_PM - .suspend = amhevc_suspend, - .resume = amhevc_resume, -#endif .driver = { .name = DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &vp9_pm_ops, +#endif } }; @@ -11026,9 +9998,6 @@ int sum = 0; u8 *data = NULL; - if (vdec_secure(hw_to_vdec(pbi))) - return 0; - if (!pbi->chunk->block->is_mapped) data = codec_mm_vmap(pbi->chunk->block->start + pbi->chunk->offset, size); @@ -11039,20 +10008,6 @@ for (jj = 0; jj < size; jj++) sum += data[jj]; - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", - __func__, size, sum, - (size < 1) ? 0 : data[0], - (size < 2) ? 0 : data[1], - (size < 3) ? 0 : data[2], - (size < 4) ? 0 : data[3], - (size < 5) ? 0 : data[4], - (size < 6) ? 0 : data[5], - (size < 4) ? 0 : data[size - 4], - (size < 3) ? 0 : data[size - 3], - (size < 2) ? 0 : data[size - 2], - (size < 1) ? 0 : data[size - 1]); - if (!pbi->chunk->block->is_mapped) codec_mm_unmap_phyaddr(data); return sum; @@ -11109,9 +10064,6 @@ /* finished decoding one frame or error, * notify vdec core to switch context */ - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_START); - if (pbi->dec_result == DEC_RESULT_AGAIN) - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_AGAIN); vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, "%s dec_result %d %x %x %x\n", __func__, @@ -11129,6 +10081,7 @@ if (pbi->dec_result == DEC_RESULT_NEED_MORE_BUFFER) { reset_process_time(pbi); if (!get_free_buf_count(pbi)) { + pbi->process_busy = 0; pbi->dec_result = DEC_RESULT_NEED_MORE_BUFFER; vdec_schedule_work(&pbi->work); } else { @@ -11309,7 +10262,6 @@ pbi->stat &= ~STAT_TIMER_ARM; } /* mark itself has all HW resource released and input released */ - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_END); #ifdef SUPPORT_FB_DECODING if (pbi->used_stage_buf_num > 0) vdec_core_finish_run(hw_to_vdec(pbi), CORE_MASK_HEVC_BACK); @@ -11344,34 +10296,6 @@ #endif return 0; } - -static bool is_avaliable_buffer(struct VP9Decoder_s *pbi) -{ - struct VP9_Common_s *const cm = &pbi->common; - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - int i, free_count = 0; - - if (ctx->cap_pool.dec < pbi->used_buf_num) { - free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - if (free_count && - !ctx->fb_ops.query(&ctx->fb_ops, &pbi->fb_token)) { - return false; - } - } - - for (i = 0; i < pbi->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - frame_bufs[i].buf.cma_alloc_addr) { - free_count++; - } - } - - return free_count < pbi->run_ready_min_buf_num ? 0 : 1; -} - static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) { struct VP9Decoder_s *pbi = @@ -11383,17 +10307,7 @@ if (!(pbi->pic_list_init_done && pbi->pic_list_init_done2) || pbi->eos) return ret; if (!pbi->first_sc_checked && pbi->mmu_enable) { - int size; - void * mmu_box; - - if (pbi->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(pbi->v4l2_ctx); - mmu_box = ctx->mmu_box; - } else - mmu_box = pbi->mmu_box; - - size = decoder_mmu_box_sc_check(mmu_box, tvp); + int size = decoder_mmu_box_sc_check(pbi->mmu_box, tvp); pbi->first_sc_checked = 1; vp9_print(pbi, 0, "vp9 cached=%d need_size=%d speed= %d ms\n", size, (pbi->need_cache_size >> PAGE_SHIFT), @@ -11463,12 +10377,10 @@ if (ctx->param_sets_from_ucode) { if (pbi->v4l_params_parsed) { - if (ctx->cap_pool.dec < pbi->used_buf_num) { - if (is_avaliable_buffer(pbi)) - ret = CORE_MASK_HEVC; - else - ret = 0; - } + if ((ctx->cap_pool.in < pbi->used_buf_num) && + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < + pbi->run_ready_min_buf_num) + ret = 0; } else { if (ctx->v4l_resolution_change) ret = 0; @@ -11499,17 +10411,13 @@ if (pbi->chunk == NULL) return; vp9_print(pbi, VP9_DEBUG_OUT_PTS, - "run front: pts %d, pts64 %lld, ts: %lld\n", - pbi->chunk->pts, pbi->chunk->pts64, pbi->chunk->timestamp); + "run front: pts %d, pts64 %lld\n", pbi->chunk->pts, pbi->chunk->pts64); for (i = (FRAME_BUFFERS - 1); i > 0; i--) { - pbi->frame_mode_pts_save[i] = pbi->frame_mode_pts_save[i - 1]; - pbi->frame_mode_pts64_save[i] = pbi->frame_mode_pts64_save[i - 1]; + pbi->frame_mode_pts_save[i] = pbi->frame_mode_pts_save[i - 1]; + pbi->frame_mode_pts64_save[i] = pbi->frame_mode_pts64_save[i - 1]; } pbi->frame_mode_pts_save[0] = pbi->chunk->pts; pbi->frame_mode_pts64_save[0] = pbi->chunk->pts64; - - if (pbi->is_used_v4l && !v4l_bitstream_id_enable) - pbi->frame_mode_pts64_save[0] = pbi->chunk->timestamp; } static void run_front(struct vdec_s *vdec) @@ -11567,9 +10475,7 @@ READ_VREG(HEVC_STREAM_WR_PTR), READ_VREG(HEVC_STREAM_RD_PTR), pbi->start_shift_bytes); - - if (!vdec_secure(hw_to_vdec(pbi)) && - vdec_frame_based(vdec) && pbi->chunk) { + if (vdec_frame_based(vdec) && pbi->chunk) { u8 *data = NULL; if (!pbi->chunk->block->is_mapped) @@ -11590,7 +10496,6 @@ } vp9_print_cont(pbi, 0, "\r\n"); } - ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START); if (vdec->mc_loaded) { /*firmware have load before, and not changes to another. @@ -11610,14 +10515,12 @@ vdec->mc_loaded = 1; vdec->mc_type = VFORMAT_VP9; } - ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END); - ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START); if (vp9_hw_ctx_restore(pbi) < 0) { vdec_schedule_work(&pbi->work); return; } - ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END); + vdec_enable_input(vdec); WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); @@ -11791,7 +10694,7 @@ { struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)vdec->private; - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_START); + vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n", __func__, mask); @@ -11813,36 +10716,23 @@ #else run_front(vdec); #endif - ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_END); } -static void vp9_decoder_ctx_reset(struct VP9Decoder_s *pbi) +static void init_frame_bufs(struct VP9Decoder_s *pbi) { struct vdec_s *vdec = hw_to_vdec(pbi); struct VP9_Common_s *const cm = &pbi->common; struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - struct BufferPool_s *buffer_pool = cm->buffer_pool; int i; - cm->buffer_pool = buffer_pool; - - for (i = 0; i < FRAME_BUFFERS; ++i) { - frame_bufs[i].buf.index = i; - frame_bufs[i].ref_count = 0; - frame_bufs[i].buf.vf_ref = 0; - frame_bufs[i].buf.decode_idx = 0; + for (i = 0; i < pbi->used_buf_num; ++i) { + frame_bufs[i].ref_count = 0; + frame_bufs[i].buf.vf_ref = 0; + frame_bufs[i].buf.decode_idx = 0; frame_bufs[i].buf.cma_alloc_addr = 0; - frame_bufs[i].buf.BUF_index = -1; - frame_bufs[i].buf.slice_type = 0; - } - - for (i = 0; i < MV_BUFFER_NUM; ++i) { - pbi->m_mv_BUF[i].used_flag = 0; - } - - for (i = 0; i < FRAME_BUFFERS; i++) { - pbi->buffer_wrap[i] = i; + frame_bufs[i].buf.index = i; + frame_bufs[i].buf.vframe_bound = 0; } if (vdec->parallel_dec == 1) { @@ -11855,12 +10745,6 @@ vdec->id); } } - - pbi->init_flag = 0; - pbi->first_sc_checked = 0; - pbi->fatal_error = 0; - pbi->show_frame_num = 0; - pbi->eos = 0; } static void reset(struct vdec_s *vdec) @@ -11868,7 +10752,6 @@ struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)vdec->private; - cancel_work_sync(&pbi->set_clk_work); cancel_work_sync(&pbi->work); if (pbi->stat & STAT_VDEC_RUN) { amhevc_stop(); @@ -11879,16 +10762,16 @@ del_timer_sync(&pbi->timer); pbi->stat &= ~STAT_TIMER_ARM; } - + pbi->dec_result = DEC_RESULT_NONE; reset_process_time(pbi); - vp9_local_uninit(pbi); if (vvp9_local_init(pbi) < 0) - vp9_print(pbi, 0, "%s local_init failed \r\n", __func__); + vp9_print(pbi, 0, "%s local_init failed \r\n", __func__); + init_frame_bufs(pbi); - vp9_decoder_ctx_reset(pbi); + pbi->eos = 0; - vp9_print(pbi, 0, "%s\r\n", __func__); + vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); } static irqreturn_t vp9_irq_cb(struct vdec_s *vdec, int irq) @@ -11935,7 +10818,7 @@ pbi->no_head ); - if (!pbi->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { + if (vf_get_receiver(vdec->vf_provider_name)) { enum receviver_start_e state = vf_notify_receiver(vdec->vf_provider_name, VFRAME_EVENT_PROVIDER_QUREY_STATE, @@ -11964,7 +10847,7 @@ for (i = 0; i < MAX_BUF_NUM; i++) { vp9_print(pbi, 0, - "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n", + "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n", i, pbi->m_mv_BUF[i].start_adr, pbi->m_mv_BUF[i].size, @@ -12059,15 +10942,9 @@ int transfer_val; struct vframe_content_light_level_s content_light_level; struct vframe_master_display_colour_s vf_dp; - struct VP9Decoder_s *pbi = NULL; - int i; - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) { - pr_info("vp9 unsupported on cpu 0x%x\n", get_cpu_major_id()); - return -EINVAL; - } + struct BUF_s BUF[MAX_BUF_NUM]; + struct VP9Decoder_s *pbi = NULL; pr_debug("%s\n", __func__); if (pdata == NULL) { @@ -12097,35 +10974,19 @@ pdata->threaded_irq_handler = vp9_threaded_irq_cb; pdata->dump_state = vp9_dump_state; + memcpy(&BUF[0], &pbi->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + memcpy(&pbi->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); + pbi->index = pdev->id; - if (is_rdma_enable()) { - pbi->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &pbi->rdma_phy_adr, GFP_KERNEL); - for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) { - pbi->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff; - pbi->rdma_adr[i * 4 + 1] = i; - pbi->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff; - pbi->rdma_adr[i * 4 + 3] = 0; - if (i == SCALELUT_DATA_WRITE_NUM - 1) { - pbi->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000; - } - } - } - - snprintf(pbi->trace.vdec_name, sizeof(pbi->trace.vdec_name), + snprintf(pbi->vdec_name, sizeof(pbi->vdec_name), "vp9-%d", pbi->index); - snprintf(pbi->trace.pts_name, sizeof(pbi->trace.pts_name), - "%s-pts", pbi->trace.vdec_name); - snprintf(pbi->trace.new_q_name, sizeof(pbi->trace.new_q_name), - "%s-newframe_q", pbi->trace.vdec_name); - snprintf(pbi->trace.disp_q_name, sizeof(pbi->trace.disp_q_name), - "%s-dispframe_q", pbi->trace.vdec_name); - snprintf(pbi->trace.decode_time_name, sizeof(pbi->trace.decode_time_name), - "decoder_time%d", pdev->id); - snprintf(pbi->trace.decode_run_time_name, sizeof(pbi->trace.decode_run_time_name), - "decoder_run_time%d", pdev->id); - snprintf(pbi->trace.decode_header_memory_time_name, sizeof(pbi->trace.decode_header_memory_time_name), - "decoder_header_time%d", pdev->id); + snprintf(pbi->pts_name, sizeof(pbi->pts_name), + "%s-pts", pbi->vdec_name); + snprintf(pbi->new_q_name, sizeof(pbi->new_q_name), + "%s-newframe_q", pbi->vdec_name); + snprintf(pbi->disp_q_name, sizeof(pbi->disp_q_name), + "%s-dispframe_q", pbi->vdec_name); if (pdata->use_vfm_path) snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, @@ -12134,23 +10995,26 @@ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); + vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, + &vvp9_vf_provider, pbi); + pbi->provider_name = pdata->vf_provider_name; platform_set_drvdata(pdev, pdata); pbi->platform_dev = pdev; pbi->video_signal_type = 0; pbi->m_ins_flag = 1; - if (!vdec_is_support_4k()) { - pbi->max_pic_w = 1920; - pbi->max_pic_h = 1088; - } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) { - pbi->max_pic_w = 4096; - pbi->max_pic_h = 2304; - } else { + if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX) + pbi->stat |= VP9_TRIGGER_FRAME_ENABLE; + + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { pbi->max_pic_w = 8192; pbi->max_pic_h = 4608; + } else { + pbi->max_pic_w = 4096; + pbi->max_pic_h = 2304; } - +#if 1 if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) { #ifdef MULTI_INSTANCE_SUPPORT @@ -12193,7 +11057,6 @@ &config_val) == 0) { pbi->max_pic_h = config_val; } - if ((pbi->max_pic_w * pbi->max_pic_h) < (vp9_buf_width * vp9_buf_height)) { pbi->max_pic_w = vp9_buf_width; @@ -12242,8 +11105,6 @@ if (get_config_int(pdata->config, "HDRStaticInfo", &vf_dp.present_flag) == 0 && vf_dp.present_flag == 1) { - get_config_int(pdata->config, "signal_type", - &pbi->video_signal_type); get_config_int(pdata->config, "mG.x", &vf_dp.primaries[0][0]); get_config_int(pdata->config, "mG.y", @@ -12279,18 +11140,18 @@ vp9_print(pbi, 0, "transfer_val=%d\n",transfer_val); vf_dp.content_light_level = content_light_level; - if (!pbi->video_signal_type) { - pbi->video_signal_type = (1 << 29) + pbi->video_signal_type = (1 << 29) | (5 << 26) /* unspecified */ | (0 << 25) /* limit */ | (1 << 24) /* color available */ | (9 << 16) /* 2020 */ | (transfer_val << 8) /* 2084 */ | (9 << 0); /* 2020 */ - } } pbi->vf_dp = vf_dp; - } else { + } else +#endif + { if (pdata->sys_info) { pbi->vvp9_amstream_dec_info = *pdata->sys_info; if ((pbi->vvp9_amstream_dec_info.width != 0) && @@ -12305,29 +11166,14 @@ pbi->double_write_mode = double_write_mode; } - if (!pbi->is_used_v4l) { - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vvp9_vf_provider, pbi); - } - if (no_head & 0x10) { pbi->no_head = (no_head & 0xf); } - pbi->endian = HEVC_CONFIG_LITTLE_ENDIAN; if (!pbi->is_used_v4l) { pbi->mem_map_mode = mem_map_mode; - if (is_support_vdec_canvas()) - pbi->endian = HEVC_CONFIG_BIG_ENDIAN; } - if (endian) - pbi->endian = endian; - - if (pbi->is_used_v4l) - pbi->run_ready_min_buf_num = run_ready_min_buf_num - 1 ; - else - pbi->run_ready_min_buf_num = run_ready_min_buf_num; - + pbi->run_ready_min_buf_num = run_ready_min_buf_num; if (is_oversize(pbi->max_pic_w, pbi->max_pic_h)) { pr_err("over size: %dx%d, probe failed\n", pbi->max_pic_w, pbi->max_pic_h); @@ -12344,20 +11190,10 @@ pbi->enable_fence, pbi->fence_usage); } - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL || - pbi->double_write_mode == 0x10) - pbi->mmu_enable = 0; - else - pbi->mmu_enable = 1; + if (pbi->enable_fence) + pdata->sync.usage = pbi->fence_usage; -#ifdef VP9_10B_MMU_DW - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) { - pbi->dw_mmu_enable = - (get_double_write_mode(pbi) & 0x20) ? 1 : 0; - } else { - pbi->dw_mmu_enable = 0; - } -#endif + pbi->mmu_enable = 1; video_signal_type = pbi->video_signal_type; if (pdata->sys_info) { @@ -12370,8 +11206,8 @@ pbi->low_latency_flag = 1; vp9_print(pbi, 0, - "no_head %d low_latency %d, signal_type 0x%x\n", - pbi->no_head, pbi->low_latency_flag, pbi->video_signal_type); + "no_head %d low_latency %d\n", + pbi->no_head, pbi->low_latency_flag); #if 0 pbi->buf_start = pdata->mem_start; pbi->buf_size = pdata->mem_end - pdata->mem_start + 1; @@ -12411,27 +11247,8 @@ } pbi->cma_dev = pdata->cma_dev; - - mutex_init(&pbi->fence_mutex); - - if (pbi->enable_fence) { - pdata->sync = vdec_sync_get(); - if (!pdata->sync) { - vp9_print(pbi, 0, "alloc fence timeline error\n"); - vp9_local_uninit(pbi); - uninit_mmu_buffers(pbi); - /* devm_kfree(&pdev->dev, (void *)pbi); */ - vfree((void *)pbi); - pdata->dec_status = NULL; - return -1; - } - pdata->sync->usage = pbi->fence_usage; - vdec_timeline_create(pdata->sync, DRIVER_NAME); - } - if (vvp9_init(pdata) < 0) { pr_info("\namvdec_vp9 init failed.\n"); - vdec_timeline_put(pdata->sync); vp9_local_uninit(pbi); uninit_mmu_buffers(pbi); /* devm_kfree(&pdev->dev, (void *)pbi); */ @@ -12459,6 +11276,11 @@ #endif pbi->pic_list_init_done2 = true; + if (pbi->enable_fence) { + /* creat timeline. */ + vdec_timeline_create(&pdata->sync, DRIVER_NAME); + } + return 0; } @@ -12497,7 +11319,7 @@ } if (pbi->enable_fence) - vdec_fence_release(pbi, vdec->sync); + vdec_fence_release(pbi, &vdec->sync); #ifdef DEBUG_PTS pr_info("pts missed %ld, pts hit %ld, duration %d\n", @@ -12506,8 +11328,6 @@ mem_map_mode = 0; /* devm_kfree(&pdev->dev, (void *)pbi); */ - if (is_rdma_enable()) - dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, pbi->rdma_adr, pbi->rdma_phy_adr); vfree((void *)pbi); return 0; } @@ -12515,12 +11335,11 @@ static struct platform_driver ammvdec_vp9_driver = { .probe = ammvdec_vp9_probe, .remove = ammvdec_vp9_remove, -#ifdef CONFIG_PM - .suspend = amhevc_suspend, - .resume = amhevc_resume, -#endif .driver = { .name = MULTI_DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &vp9_pm_ops, +#endif } }; #endif @@ -12542,6 +11361,8 @@ 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), @@ -12567,20 +11388,13 @@ 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 = &amvvp9_workbuff_spec[2]; - else - p_buf_info = &amvvp9_workbuff_spec[1]; - } else - p_buf_info = &amvvp9_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 = &amvvp9_workbuff_spec[5]; + if (vdec_is_support_4k()) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) + p_buf_info = &amvvp9_workbuff_spec[2]; else - p_buf_info = &amvvp9_workbuff_spec[4]; - } + p_buf_info = &amvvp9_workbuff_spec[1]; + } else + p_buf_info = &amvvp9_workbuff_spec[0]; init_buff_spec(NULL, p_buf_info); work_buf_size = @@ -12610,21 +11424,20 @@ return -ENODEV; } - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL || - get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) { - amvdec_vp9_profile.name = "vp9_unsupport"; - } else if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) { + if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { amvdec_vp9_profile.profile = - "8k, 10bit, dwrite, compressed, fence, v4l-uvm"; + "8k, 10bit, dwrite, compressed, fence"; + } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL + /*&& get_cpu_major_id() != MESON_CPU_MAJOR_ID_GXLX*/ + && get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TXL) { + if (vdec_is_support_4k()) + amvdec_vp9_profile.profile = + "4k, 10bit, dwrite, compressed, fence"; + else + amvdec_vp9_profile.profile = + "10bit, dwrite, compressed, fence"; } else { - if (vdec_is_support_4k()) - amvdec_vp9_profile.profile = - "4k, 10bit, dwrite, compressed, fence, v4l-uvm"; - else - amvdec_vp9_profile.profile = - "10bit, dwrite, compressed, fence, v4l-uvm"; + amvdec_vp9_profile.name = "vp9_unsupport"; } if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) @@ -12636,7 +11449,6 @@ vcodec_profile_register(&amvdec_vp9_profile_mult); INIT_REG_NODE_CONFIGS("media.decoder", &vp9_node, "vp9", vp9_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_VP9, 0); return 0; } @@ -12706,6 +11518,12 @@ module_param(error_handle_policy, uint, 0664); MODULE_PARM_DESC(error_handle_policy, "\n amvdec_vp9 error_handle_policy\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"); @@ -12829,9 +11647,6 @@ module_param(force_pts_unstable, uint, 0664); MODULE_PARM_DESC(force_pts_unstable, "\n force_pts_unstable\n"); -module_param(v4l_bitstream_id_enable, uint, 0664); -MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n"); - module_init(amvdec_vp9_driver_init_module); module_exit(amvdec_vp9_driver_remove_module);
diff --git a/drivers/frame_provider/decoder_v4l/Makefile b/drivers/frame_provider/decoder_v4l/Makefile deleted file mode 100644 index 43e94df..0000000 --- a/drivers/frame_provider/decoder_v4l/Makefile +++ /dev/null
@@ -1,9 +0,0 @@ -obj-y += mpeg12/ -obj-y += mpeg4/ -obj-y += h264_multi/ -obj-y += h265/ -obj-y += vp9/ -obj-y += mjpeg/ -obj-y += avs2/ -obj-y += avs_multi/ -obj-y += vav1/
diff --git a/drivers/frame_provider/decoder_v4l/avs2/Makefile b/drivers/frame_provider/decoder_v4l/avs2/Makefile deleted file mode 100644 index 9995065..0000000 --- a/drivers/frame_provider/decoder_v4l/avs2/Makefile +++ /dev/null
@@ -1,2 +0,0 @@ -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += amvdec_avs2_v4l.o -amvdec_avs2_v4l-objs += vavs2.o avs2_bufmgr.o
diff --git a/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c deleted file mode 100644 index 91c3132..0000000 --- a/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c +++ /dev/null
@@ -1,2205 +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/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/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 "../../decoder/utils/decoder_mmu_box.h" -#include "../../decoder/utils/decoder_bmmu_box.h" -#include "avs2_global.h" - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../decoder/utils/vdec.h" -#include "../../decoder/utils/amvdec.h" - -#undef pr_info -#define pr_info printk - -#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;*/ - - /*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, - "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"); - /*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*/ -#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); - - - 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 Check_Bitstream - /*assert(hd->gop_size<=32);*/ -#endif - - 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"); - } -#else - /*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"); - /*if (predict) {*/ - 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.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"); - } - /*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, - "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; - - - /*u_v(32, "bbv delay");*/ - - 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.referd_by_others = - get_param( - rpm_param->p.referd_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"); - } - /*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, - "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 - /*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, - "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) - - { - 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].framenum -= 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; - /* -int32_t img_height = (hd->vertical_size + img->auto_crop_bottom); - */ - 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]; - - /*//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; - 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]; - /*///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->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); - /*img->BLCUidx = (int32_t*) calloc( - img->iNumCUsInFrame, sizeof(int32_t));*/ - /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/ -#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 - 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]->refered_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->refered_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); - /*img->BLCUidx = (int32_t*) calloc( - img->iNumCUsInFrame, sizeof(int32_t));*/ - /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/ -#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->refered_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; - /* int32_t poc = hc->f_rec->imgtr_fwRefDistance; - fred.chiu@mediatek.com*/ - - 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'; - } -} - -void 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; - struct avs2_frame_s *tmp_fref; - - /*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; - -#if 1 - /*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); - } - } -#endif - - 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)) { - - 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 !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 -#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--; - } - - 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->error_mark = 0; - hc->f_rec->decoded_lcu = 0; - hc->f_rec->slice_type = img->type; -#endif - hc->f_rec->refered_by_others = hd->curr_RPS.referd_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; - } - } -#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", - 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]->is_output, - avs2_dec->fref[ii]->bg_flag, - avs2_dec->fref[ii]->vf_ref, - 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] - ); - } - } -#endif -} - -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 { - prepare_RefInfo(avs2_dec); -#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]->refered_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; - 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->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; - /*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); -#if 0 /*def ORI*/ - write_frame(hd->p_out, - avs2_dec->outprint.stdoutdata[pos].tr); -#endif - 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 1 /*def ORI*/ - 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); - } -#endif - 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]->refered_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 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) { - 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*/ - /*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) - == hd->next_IDRtr) { -#if !RD170_FIX_BG - if (hd->vec_flag) /**/ -#endif - { - hd->vec_flag = 0; - /*fprintf(stdout, "Video Edit - Code\n");*/ - } - } - - 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 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++; -} - -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); - /*fprintf(stdout, - "Non-conformance - stream: sequence - header cannot change - !!\n");*/ -#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) { - 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 - 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) { - int32_t k; - if (is_avs2_print_bufmgr_detail()) - 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); -#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; - /*fprintf(stdout, " I - %3d\t\tDIDSCARD!!\n", - img->tr);*/ - 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; - - 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; - } - - 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) { - /*fprintf(stdout, " B - %3d\t\tDIDSCARD!!\n", - img->tr);*/ - 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"); - /*video_edit_code_data(Buf, startcodepos, length);*/ - 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; - /*pr_info("%s\n", __func__);*/ - { - 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) { -#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; - } - if (img->new_sequence_flag) { - hd->next_IDRtr = img->tr; - 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); - - 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); - - /*pr_info("%s\n", __func__);*/ - 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]->refered_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; - } - - /* - 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; - 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_v4l/avs2/avs2_global.h b/drivers/frame_provider/decoder_v4l/avs2/avs2_global.h deleted file mode 100644 index d9f85bd..0000000 --- a/drivers/frame_provider/decoder_v4l/avs2/avs2_global.h +++ /dev/null
@@ -1,1687 +0,0 @@ -/* 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. - * - */ - -#ifndef _GLOBAL_H_ -#define _GLOBAL_H_ - -/* #include <stdio.h> //!< for FILE */ -/* #include <stdlib.h> */ - -#define AML -#define SANITY_CHECK -#undef NO_DISPLAY - -/* #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 */ - - -/* 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_FUCTION 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 CameraParamters_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 refered_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; - 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; - int 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 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; - - u32 hw_decode_time; - u32 frame_size; // For frame base mode - - char *cuva_data_buf; - int cuva_data_size; -}; - - -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 orginal 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 framenum; - 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 CameraParamters_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 referd_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 - -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 referd_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 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]; -#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 -}; - - -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); -#endif -
diff --git a/drivers/frame_provider/decoder_v4l/avs2/vavs2.c b/drivers/frame_provider/decoder_v4l/avs2/vavs2.c deleted file mode 100644 index ce5ffde..0000000 --- a/drivers/frame_provider/decoder_v4l/avs2/vavs2.c +++ /dev/null
@@ -1,8375 +0,0 @@ - /* - * drivers/amlogic/amports/avs2.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/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 "../../decoder/utils/decoder_mmu_box.h" -#include "../../decoder/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 "../../decoder/utils/vdec.h" -#include "../../decoder/utils/amvdec.h" - -#include <linux/amlogic/media/video_sink/video.h> -#include <linux/amlogic/media/codec_mm/configs.h> -#include "../../decoder/utils/config_parser.h" -#include "../../decoder/utils/firmware.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" -#include "../../decoder/utils/vdec_feature.h" - - -#define I_ONLY_SUPPORT -#define MIX_STREAM_SUPPORT -#define G12A_BRINGUP_DEBUG -#define CONSTRAIN_MAX_BUF_NUM - -#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 - - -/* - * 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 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_avs2_v4l" - -#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]; -static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM]; -static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM]; - -#ifdef G12A_BRINGUP_DEBUG -static u32 decode_timeout_val = 200; -#else -static u32 decode_timeout_val = 200; -#endif -static int start_decode_buf_level = 0x8000; -#ifdef AVS2_10B_MMU -static u32 work_buf_size; /* = 24 * 1024 * 1024*/; -#else -static u32 work_buf_size = 32 * 1024 * 1024; -#endif - -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; - */ -static u32 double_write_mode; -static u32 without_display_mode; - -static u32 mv_buf_dynamic_alloc; -#define DRIVER_NAME "amvdec_avs2_v4l" -#define DRIVER_HEADER_NAME "amvdec_avs2_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_THREASHOLD 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 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 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) -{ -/* -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 { - AVS2_BITS_8 = 8, /**< 8 bits */ - AVS2_BITS_10 = 10, /**< 10 bits */ - AVS2_BITS_12 = 12, /**< 12 bits */ -}; - -/*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 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 DOUBLE_WRITE_YSTART_TEMP 0x02000000 -#define DOUBLE_WRITE_CSTART_TEMP 0x02900000 - -#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_HDR_DATA 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_LOAD_UCODE_FROM_FILE 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 debug; - -static u32 debug_again; - -bool is_avs2_print_param(void) -{ - bool ret = false; - if (debug & AVS2_DBG_PRINT_PARAM) - ret = true; - return ret; -} - -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 (debug & AVS2_DBG_REG) - pr_info("%s(%x, %x)\n", __func__, adr, val); - if (adr != 0) - WRITE_VREG(adr, val); -} - -#undef WRITE_VREG -#define WRITE_VREG WRITE_VREG_DBG2 -#endif - - -//#ifdef AVS2_10B_MMU -//#define MMU_COMPRESS_HEADER_SIZE 0x48000 -//#define MMU_COMPRESS_8K_HEADER_SIZE 0x48000*4 -//#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*/ -#undef MV_USE_FIXED_BUF -#ifdef MV_USE_FIXED_BUF -#define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1) -#define VF_BUFFER_IDX(n) (n) -#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1) -#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1) -#else -#define MAX_BMMU_BUFFER_NUM (((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1) -#define VF_BUFFER_IDX(n) (n) -#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) -#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; - u32 buf_size; - u32 buf_end; -}; - -struct BuffInfo_s { - u32 max_width; - u32 max_height; - u32 start_adr; - u32 end_adr; - struct buff_s ipp; - 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 - 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 - -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; - unsigned char index; - spinlock_t buffer_lock; - struct device *cma_dev; - struct platform_device *platform_dev; - void (*vdec_cb)(struct vdec_s *, void *); - 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; - 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 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; - - u32 cuva_size; - void *cuva_addr; - dma_addr_t cuva_phy_addr; - -#if 1 - /*AVS2_10B_MMU*/ - void *frame_mmu_map_addr; - dma_addr_t 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]; - atomic_t vf_pre_count; - atomic_t vf_get_count; - atomic_t 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; - /*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 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; - char vdec_name[32]; - char pts_name[32]; - char new_q_name[32]; - char disp_q_name[32]; - dma_addr_t rdma_phy_adr; - unsigned *rdma_adr; - int hdr_flag; -}; - -static int compute_losless_comp_body_size( - struct AVS2Decoder_s *dec, int width, int height, - uint8_t is_bit_depth_10); - -static int avs2_print(struct AVS2Decoder_s *dec, - int flag, const char *fmt, ...) -{ -#define HEVC_PRINT_BUF 256 - unsigned char buf[HEVC_PRINT_BUF]; - int len = 0; - 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; -} - -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 & flag)) { - va_list args; - va_start(args, fmt); - vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - 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)) - -static int get_frame_mmu_map_size(struct AVS2Decoder_s *dec) -{ - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - (IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h))) - return (MAX_FRAME_8K_NUM * 4); - return (MAX_FRAME_4K_NUM * 4); -} - -static int get_compress_header_size(struct AVS2Decoder_s *dec) -{ - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) && - (IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h))) - return MMU_COMPRESS_HEADER_SIZE_8K; - else if (IS_4K_SIZE(dec->init_pic_w, dec->init_pic_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_decoder *avs2_dec = &dec->avs2_dec; - struct avs2_frame_s *cur_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; - dec->dec_result = DEC_RESULT_DONE; - update_decoded_pic(dec); - reset_process_time(dec); - vdec_schedule_work(&dec->work); -} - -static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec) -{ - return (dec->m_ins_flag && - ((double_write_mode & 0x80000000) == 0)) ? - dec->double_write_mode : - (double_write_mode & 0x7fffffff); -} - -static int get_double_write_mode(struct AVS2Decoder_s *dec) -{ - u32 valid_dw_mode = get_valid_double_write_mode(dec); - 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 > 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; -} - -/* 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 > 720) - dw = 0x4; /*1:2*/ - break; - default: - dw = valid_dw_mode; - break; - } - return dw; -} - -//#define MAX_4K_NUM 0x1200 -#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 picture_size; - int cur_mmu_4k_number, max_frame_num; -#ifdef DYNAMIC_ALLOC_HEAD - unsigned long buf_addr; - struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic; - if (pic->header_adr == 0) { - if (decoder_bmmu_box_alloc_buf_phy - (dec->bmmu_box, - HEADER_BUFFER_IDX(cur_buf_idx), - get_compress_header_size(dec), - DRIVER_HEADER_NAME, - &buf_addr) < 0){ - avs2_print(dec, 0, - "%s malloc compress header failed %d\n", - DRIVER_HEADER_NAME, cur_buf_idx); - dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; - return -1; - } else - pic->header_adr = buf_addr; - } -#endif - - picture_size = compute_losless_comp_body_size( - 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; - 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 -1; - } - return decoder_mmu_box_alloc_idx( - dec->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); -} -#endif - -#if 0 -/*ndef MV_USE_FIXED_BUF*/ -static void dealloc_mv_bufs(struct AVS2Decoder_s *dec) -{ - int i; - for (i = 0; i < FRAME_BUFFERS; i++) { - if (dec->m_mv_BUF[i].start_adr) { - if (debug) - pr_info( - "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n", - i, dec->m_mv_BUF[i].start_adr, - dec->m_mv_BUF[i].size, - dec->m_mv_BUF[i].used_flag); - decoder_bmmu_box_free_idx( - dec->bmmu_box, - MV_BUFFER_IDX(i)); - dec->m_mv_BUF[i].start_adr = 0; - dec->m_mv_BUF[i].size = 0; - dec->m_mv_BUF[i].used_flag = 0; - } - } -} - -static int alloc_mv_buf(struct AVS2Decoder_s *dec, - int i, int size) -{ - int ret = 0; - if (decoder_bmmu_box_alloc_buf_phy - (dec->bmmu_box, - MV_BUFFER_IDX(i), size, - DRIVER_NAME, - &dec->m_mv_BUF[i].start_adr) < 0) { - dec->m_mv_BUF[i].start_adr = 0; - ret = -1; - } else { - dec->m_mv_BUF[i].size = size; - dec->m_mv_BUF[i].used_flag = 0; - ret = 0; - if (debug) { - pr_info( - "MV Buffer %d: start_adr %p size %x\n", - i, - (void *)dec->m_mv_BUF[i].start_adr, - dec->m_mv_BUF[i].size); - } - } - return ret; -} - -static int init_mv_buf_list(struct AVS2Decoder_s *dec) -{ - int i; - int ret = 0; - int count = FRAME_BUFFERS; - int pic_width = dec->init_pic_w; - int pic_height = dec->init_pic_h; - int lcu_size = 64; /*fixed 64*/ - 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 size = ((lcu_total * MV_MEM_UNIT) + 0xffff) & - (~0xffff); - if (mv_buf_margin > 0) - count = dec->avs2_dec.ref_maxbuffer + mv_buf_margin; - for (i = 0; i < count; i++) { - if (alloc_mv_buf(dec, i, size) < 0) { - ret = -1; - break; - } - } - return ret; -} -#if 0 - -static int get_mv_buf(struct AVS2Decoder_s *dec, - struct avs2_frame_s *pic) -{ - int i; - int ret = -1; - for (i = 0; i < FRAME_BUFFERS; i++) { - if (dec->m_mv_BUF[i].start_adr && - dec->m_mv_BUF[i].used_flag == 0) { - dec->m_mv_BUF[i].used_flag = 1; - ret = i; - break; - } - } - - if (ret >= 0) { - pic->mv_buf_index = ret; - pic->mpred_mv_wr_start_addr = - (dec->m_mv_BUF[ret].start_adr + 0xffff) & - (~0xffff); - if (debug & AVS2_DBG_BUFMGR_MORE) - pr_info( - "%s => %d (%d) size 0x%x\n", - __func__, ret, - pic->mpred_mv_wr_start_addr, - dec->m_mv_BUF[ret].size); - } else { - pr_info( - "%s: Error, mv buf is not enough\n", - __func__); - } - return ret; -} - -static void put_mv_buf(struct AVS2Decoder_s *dec, - struct avs2_frame_s *pic) -{ - int i = pic->mv_buf_index; - if (i >= FRAME_BUFFERS) { - if (debug & AVS2_DBG_BUFMGR_MORE) - pr_info( - "%s: index %d beyond range\n", - __func__, i); - return; - } - if (debug & AVS2_DBG_BUFMGR_MORE) - pr_info( - "%s(%d): used_flag(%d)\n", - __func__, i, - dec->m_mv_BUF[i].used_flag); - - pic->mv_buf_index = -1; - if (dec->m_mv_BUF[i].start_adr && - dec->m_mv_BUF[i].used_flag) - dec->m_mv_BUF[i].used_flag = 0; -} - -static void put_un_used_mv_bufs(struct AVS2Decoder_s *dec) -{ - struct VP9_Common_s *const cm = &dec->common; - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - int i; - for (i = 0; i < dec->used_buf_num; ++i) { - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.index != -1) && - (frame_bufs[i].buf.mv_buf_index >= 0) - ) - put_mv_buf(dec, &frame_bufs[i].buf); - } -} -#endif - -#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 -#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 - ) { - 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 -#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 - ) { - count++; - } - } - - return count; -} - -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 -#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 - ) { - 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 - - - /* 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; - /*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->bufmgr_error_count = 0; - 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 avs2_version = 201602101; -static u32 debug; -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) - -#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: 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 parser_sei_enable = 1;*/ - -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 -//#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 HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D -#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_DECODE_COUNT HEVC_ASSIST_SCRATCH_M -#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N -#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 - -#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, - }, - .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*/ - }, -#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*/ - }, -#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, - }, - .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*/ - }, -#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*/ - }, -#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, - }, - .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*/ - }, -#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, - }, -#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, - .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 = 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 = 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 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 -#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 = 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, - }, -#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 -#endif - .mpred_above = { - .buf_size = 0x4000, /* 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 = 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, - }, -#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 -#endif - .mpred_above = { - .buf_size = 0x8000, - }, -#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 = 0x400 * 2, - } - } -}; - -#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 - -/*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); - buf_spec->sao_abv.buf_start = - WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size); - 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); - buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size); -#else - buf_spec->mpred_above.buf_start = - WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size); -#endif -#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); - 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 - 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) -{ -#if 0 -/*ndef MV_USE_FIXED_BUF*/ - dealloc_mv_bufs(dec); -#endif - decoder_mmu_box_free(dec->mmu_box); - dec->mmu_box = NULL; - - 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; - dec->used_buf_num = max_buf_num; - - 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; -#ifndef AVS2_10B_MMU - 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); -#endif - } - dec->buf_num = i; -} -#endif - -static int config_pic(struct AVS2Decoder_s *dec, - struct avs2_frame_s *pic, int32_t lcu_size_log2) -{ - 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; - 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; -#if 0 - int32_t MV_MEM_UNIT = - (lcu_size_log2 == 6) ? 0x200 : - ((lcu_size_log2 == 5) ? 0x80 : 0x20); -#endif -#ifdef MV_USE_FIXED_BUF - u32 mpred_mv_end = dec->work_space_buf->mpred_mv.buf_start + - dec->work_space_buf->mpred_mv.buf_size; -#endif - 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, 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 mc_buffer_size_u_v = 0; - int mc_buffer_size_u_v_h = 0; - 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 pic_width_64_dw = (pic_width_dw + 63) & (~0x3f); - int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f); - int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ? - pic_width_64_dw / lcu_size + 1 - : pic_width_64_dw / lcu_size; - int pic_height_lcu_dw = (pic_height_32_dw % lcu_size) ? - pic_height_32_dw / lcu_size + 1 - : pic_height_32_dw / lcu_size; - int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw; - - mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2; - 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); - buf_size = ((buf_size + 0xffff) >> 16) << 16; - } - if (mc_buffer_size & 0xffff) /*64k alignment*/ - mc_buffer_size_h += 1; -#ifndef AVS2_10B_MMU - if ((dw_mode & 0x10) == 0) - buf_size += (mc_buffer_size_h << 16); -#endif - -#ifdef AVS2_10B_MMU -#ifndef DYNAMIC_ALLOC_HEAD - pic->header_adr = decoder_bmmu_box_get_phy_addr( - dec->bmmu_box, HEADER_BUFFER_IDX(pic->index)); - - avs2_print(dec, AVS2_DBG_BUFMGR_MORE, - "buf_size %d, MMU header_adr %d: %ld\n", - buf_size, pic->index, pic->header_adr); -#endif -#endif - - i = pic->index; -#ifdef MV_USE_FIXED_BUF -#ifdef G12A_BRINGUP_DEBUG - if (1) { -#else - if ((dec->work_space_buf->mpred_mv.buf_start + - (((i + 1) * lcu_total) * MV_MEM_UNIT)) - <= mpred_mv_end - ) { -#endif -#endif -#ifndef AVS2_10B_MMU - if (debug) { - pr_err("start %x .size=%d\n", - dec->mc_buf_spec.buf_start + i * buf_size, - buf_size); - } -#endif -#ifndef AVS2_10B_MMU - 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 ((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 - ); - return ret; - } - - if (pic->cma_alloc_addr) - y_adr = pic->cma_alloc_addr; - 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*/ - pic->BUF_index = i; - pic->lcu_total = lcu_total; - - pic->comp_body_size = losless_comp_body_size; - pic->buf_size = buf_size; -#ifndef AVS2_10B_MMU - pic->mc_y_adr = y_adr; -#endif - pic->mc_canvas_y = pic->index; - pic->mc_canvas_u_v = pic->index; -#ifndef AVS2_10B_MMU - if (dw_mode & 0x10) { - pic->mc_u_v_adr = y_adr + - ((mc_buffer_size_u_v_h << 16) << 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) { - pic->dw_y_adr = y_adr -#ifndef AVS2_10B_MMU - + (mc_buffer_size_h << 16) -#endif - ; - pic->dw_u_v_adr = pic->dw_y_adr + - ((mc_buffer_size_u_v_h << 16) << 1); -#ifdef AVS2_10B_MMU - pic->mc_y_adr = pic->dw_y_adr; - pic->mc_u_v_adr = pic->dw_u_v_adr; -#endif - } -#ifdef MV_USE_FIXED_BUF -#ifdef G12A_BRINGUP_DEBUG - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) { - pic->mpred_mv_wr_start_addr = - dec->work_space_buf->mpred_mv.buf_start + - (pic->index * 0x120000 * 4); - } else { - pic->mpred_mv_wr_start_addr = - dec->work_space_buf->mpred_mv.buf_start + - (pic->index * 0x120000); - } -#else - pic->mpred_mv_wr_start_addr = - dec->work_space_buf->mpred_mv.buf_start + - ((pic->index * lcu_total) - * MV_MEM_UNIT); -#endif -#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\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, - pic->dw_u_v_adr); - } - ret = 0; - } -#ifdef MV_USE_FIXED_BUF - } else { - avs2_print(dec, 0, - "mv buffer alloc fail %x > %x\n", - dec->work_space_buf->mpred_mv.buf_start + - (((i + 1) * lcu_total) * MV_MEM_UNIT), - mpred_mv_end); - } -#endif - return ret; -} - -static void init_pic_list(struct AVS2Decoder_s *dec, - int32_t lcu_size_log2) -{ - int i; - struct avs2_decoder *avs2_dec = &dec->avs2_dec; - struct avs2_frame_s *pic; -#ifdef AVS2_10B_MMU - unsigned long buf_addr1; - /*alloc AVS2 compress header first*/ - if (decoder_bmmu_box_alloc_buf_phy - (dec->bmmu_box, - HEADER_BUFFER_IDX(-1), get_compress_header_size(dec), - DRIVER_HEADER_NAME, - &buf_addr1) < 0){ - avs2_print(dec, 0, - "%s malloc compress header failed %d\n", - DRIVER_HEADER_NAME, -1); - dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM; - return; - } -#ifndef DYNAMIC_ALLOC_HEAD - for (i = 0; i < dec->used_buf_num; i++) { - unsigned long buf_addr; - if (decoder_bmmu_box_alloc_buf_phy - (dec->bmmu_box, - HEADER_BUFFER_IDX(i), get_compress_header_size(dec), - 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; - } - } -#endif -#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]; - pic->index = i; - pic->BUF_index = -1; - pic->mv_buf_index = -1; - if (config_pic(dec, pic, lcu_size_log2) < 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_init_flag = 1; -} - - -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; - /*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; - else - pic = avs2_dec->fref[i]; - 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)); - -#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 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)\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]->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] - ); - } - return; -} - -static int config_mc_buffer(struct AVS2Decoder_s *dec) -{ - int32_t i; - struct avs2_decoder *avs2_dec = &dec->avs2_dec; - 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, - (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 (avs2_dec->img.type == I_IMG) - return 0; - - if (avs2_dec->img.type == P_IMG) { - 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]; - 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]; - 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); - } - 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); - - 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); - } - 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) -{ - 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 (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 */ - 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*/ - - 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 ((get_double_write_mode(dec) & 0x10) == 0) - WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr); -#endif - if (get_double_write_mode(dec)) { - 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 AVS2_10B_MMU - WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr); -#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); - WRITE_VREG(HEVC_SAO_C_LENGTH, data32); - -#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); - data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */ - 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 - * [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 (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); - } 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 (get_double_write_mode(dec) == 8 || - get_double_write_mode(dec) == 9) { - data32 |= (0xff<<16); - WRITE_VREG(HEVC_SAO_CTRL26, 0xf); - } else if (get_double_write_mode(dec) == 2 || - get_double_write_mode(dec) == 3) - data32 |= (0xff<<16); - else if (get_double_write_mode(dec) == 4) - data32 |= (0x33<<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 |= (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 -} - -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]; - /*pr_info("[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->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]);*/ - } -} - -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); - 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 - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); -#endif -} - -static u32 init_cuva_size; -static int cuva_data_is_avaible(struct AVS2Decoder_s *dec) -{ - u32 reg_val; - - reg_val = READ_VREG(AVS2_CUVA_DATA_SIZE); - 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; -} - -static 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_avaible(dec)) { - avs2_print(dec, AVS2_DBG_HDR_INFO, - "%s:pic 0x%p or data not avaible\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, - "cuva: (size %d)\n", - pic->cuva_data_size); - if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) { - 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; -#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, buf_alloc_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); - //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 - WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start); -#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) - 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); -#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*/ - 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 - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); -#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)); - /*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 1 - if (debug & AVS2_DBG_FORCE_UNCOMPRESS) - data32 |= 0x80; -#endif - WRITE_VREG(HEVC_SAO_CTRL5, data32); - -#endif - - WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr); -#if 1 -/*MULTI_INSTANCE_SUPPORT*/ - /*new added in simulation???*/ - WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start); -#endif -#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; - - /*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 | - (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); - - /*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 - /*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*/ - - 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*/ - ); -#if 0 -/*AVS2_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 |= (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 void avs2_local_uninit(struct AVS2Decoder_s *dec) -{ - dec->rpm_ptr = NULL; - dec->lmem_ptr = NULL; - if (dec->rpm_addr) { - dma_free_coherent(amports_get_dma_device(), - 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(), - dec->cuva_size, dec->cuva_addr, - dec->cuva_phy_addr); - dec->cuva_addr = NULL; - } - - if (dec->lmem_addr) { - if (dec->lmem_phy_addr) - dma_free_coherent(amports_get_dma_device(), - 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) - dma_free_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(dec), dec->frame_mmu_map_addr, - dec->frame_mmu_map_phy_addr); - dec->frame_mmu_map_addr = NULL; - } -#endif - if (dec->gvs) - vfree(dec->gvs); - dec->gvs = NULL; -} - -static int avs2_local_init(struct AVS2Decoder_s *dec) -{ - int ret = -1; - /*int losless_comp_header_size, losless_comp_body_size;*/ - - 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)); - 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) - memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */ - sizeof(struct BuffInfo_s)); - else - memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */ - sizeof(struct BuffInfo_s)); - } else - 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()) { - memcpy(cur_buf_info, &amvavs2_workbuff_spec[5], /* 8k */ - sizeof(struct BuffInfo_s)); - } else - memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */ - sizeof(struct BuffInfo_s)); - } - } - - 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 (!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 = 8192; - buf_alloc_height = 4608; - } - 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); -#if 0 -/*ndef MV_USE_FIXED_BUF*/ - if (init_mv_buf_list(dec) < 0) { - pr_err("%s: init_mv_buf_list fail\n", __func__); - return -1; - } -#endif - -#ifndef AVS2_10B_MMU - init_buf_list(dec); -#else - dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin; - 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; - /*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(), - RPM_BUF_SIZE, - &dec->rpm_phy_addr, GFP_KERNEL); - 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 = dma_alloc_coherent(amports_get_dma_device(), - dec->cuva_size, &dec->cuva_phy_addr, GFP_KERNEL); - 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 = dma_alloc_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, - &dec->lmem_phy_addr, GFP_KERNEL); - 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_phy_addr = dma_map_single(amports_get_dma_device(), - dec->lmem_addr, LMEM_BUF_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - dec->lmem_phy_addr)) { - pr_err("%s: failed to map lmem buffer\n", __func__); - kfree(dec->lmem_addr); - dec->lmem_addr = NULL; - return -1; - } -*/ - dec->lmem_ptr = dec->lmem_addr; - - -#ifdef AVS2_10B_MMU - dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(), - get_frame_mmu_map_size(dec), - &dec->frame_mmu_map_phy_addr, GFP_KERNEL); - 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(dec)); -/* dec->frame_mmu_map_phy_addr = dma_map_single(amports_get_dma_device(), - dec->frame_mmu_map_addr, FRAME_MMU_MAP_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - dec->frame_mmu_map_phy_addr)) { - pr_err("%s: failed to map count_buffer\n", __func__); - kfree(dec->frame_mmu_map_addr); - dec->frame_mmu_map_addr = NULL; - return -1; - }*/ -#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[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; -#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); - #endif - } -} - -static void set_frame_info(struct AVS2Decoder_s *dec, struct vframe_s *vf) -{ - unsigned int ar; - - 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_typesignal_type 0x%x \n", - vf->signal_type); - - ar = min_t(u32, dec->frame_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; - - 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_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.fref[i]->index == index) - pic = dec->avs2_dec.fref[i]; - } - } - return pic; -} - -static struct vframe_s *vavs2_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg; - 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; - } - - if (kfifo_get(&dec->display_q, &vf)) { - uint8_t index = vf->index & 0xff; - 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); - 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; - return NULL; - } - vf->index_disp = atomic_read(&dec->vf_get_count); - atomic_add(1, &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); - return vf; - } - } - return NULL; -} - -static void vavs2_vf_put(struct vframe_s *vf, void *op_arg) -{ - struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg; - uint8_t index; - - if (vf == (&dec->vframe_dummy)) - return; - - if (!vf) - return; - - index = vf->index & 0xff; - - kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(dec->new_q_name, kfifo_len(&dec->newframe_q)); - atomic_add(1, &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) { - unsigned long flags; - struct avs2_frame_s *pic; - - lock_buffer(dec, flags); - 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(HEVC_ASSIST_MBOX0_IRQ_REG, - 0x1); - dec->last_put_idx = index; - dec->new_frame_displayed++; - unlock_buffer(dec, flags); - } - -} - -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; - - if (!req->vf) { - req->aux_size = atomic_read(&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 vframe_qos_s *vframe_qos = &dec->vframe_qos; - - if (pic->slice_type == I_IMG) - vframe_qos->type = 1; - else if (pic->slice_type == P_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 - vframe_qos->size = framesize; - vframe_qos->pts = pts; -#ifdef SHOW_QOS_INFO - 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); -#endif - - vframe_qos->max_qp = pic->max_qp; - vframe_qos->avg_qp = pic->avg_qp; - 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); -#endif - - vframe_qos->max_skip = pic->max_skip; - vframe_qos->avg_skip = pic->avg_skip; - 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); -#endif - - vframe_qos->num++; - -} - -static void set_vframe(struct AVS2Decoder_s *dec, - struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy) -{ - unsigned long flags; - int 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, - pic->imgtr_fwRefDistance); - - if (pic->double_write_mode) - 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.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { - /* 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; - - 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_THREASHOLD; - 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 1 - 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); -#endif - dec->last_pts = vf->pts; - - if (vf->pts_us64 != 0) - dec->last_lookup_pts_us64 = vf->pts_us64; - -#if 1 - 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); - } -#endif - 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; - - 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; -#else - vf->compBodyAddr = pic->mc_y_adr; /*body adr*/ - vf->compHeadAddr = pic->mc_y_adr + - pic->comp_body_size; - /*head adr*/ -#endif - } - if (pic->double_write_mode) { - 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((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->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; - } - vf->compWidth = pic->pic_w; - vf->compHeight = pic->pic_h; - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } -#ifdef AVS2_10B_MMU - if (vf->type & VIDTYPE_SCATTER) { - vf->mem_handle = decoder_mmu_box_get_mem_handle( - dec->mmu_box, - 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)); - 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 - if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) { - vf->pts_us64 = stream_offset; - vf->pts = 0; - } - if (!dummy) { - lock_buffer(dec, flags); - pic->vf_ref = 1; - unlock_buffer(dec, flags); - } - atomic_add(1, &dec->vf_pre_count); -} - -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 (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) { - struct vdec_info tmp4x; - int stream_offset = pic->stream_offset; - set_vframe(dec, vf, pic, 0); - decoder_do_frame_check(pvdec, vf); - vdec_vframe_ready(pvdec, vf); - kfifo_put(&dec->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(dec->pts_name, vf->timestamp); - ATRACE_COUNTER(dec->new_q_name, kfifo_len(&dec->newframe_q)); - ATRACE_COUNTER(dec->disp_q_name, kfifo_len(&dec->display_q)); - - 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++; - } - } - memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info)); - tmp4x.bit_depth_luma = bit_depth_luma; - tmp4x.bit_depth_chroma = bit_depth_chroma; - tmp4x.double_write_mode = pic->double_write_mode; - vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, &tmp4x, vf, pic->hw_decode_time); - pvdec->vdec_fps_detec(pvdec->id); - if (without_display_mode == 0) { - 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); - /*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) - 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; - pr_info("avs2_param: (%d)\n", dec->avs2_dec.img.number); - for (i = 0; i < (RPM_END-RPM_BEGIN); i++) { - pr_info("%04x ", dec->avs2_dec.param.l.data[i]); - if (((i + 1) & 0xf) == 0) - pr_info("\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); - 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) -{ - 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 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->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; - /*avs2_print(dec, 0, "avs2 frame_dur:%d,progressive:%d\n", dec->frame_dur, params->p.progressive_sequence);*/ - return 0; -} - - -#define HEVC_MV_INFO 0x310d -#define HEVC_QP_INFO 0x3137 -#define HEVC_SKIP_INFO 0x3136 - -/* 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) -{ - struct avs2_frame_s *picture = dec->avs2_dec.hc.cur_pic; - struct vdec_s *vdec = hw_to_vdec(dec); - if (!picture) { - avs2_print(dec, AVS2_DBG_BUFMGR_MORE, - "%s decode picture is none exist\n"); - - return; - } - if (vdec->mvfrm) { - picture->frame_size = vdec->mvfrm->frame_size; - picture->hw_decode_time = - 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; - 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->max_mv = a[2]; - picture->avg_mv = a[1]; - picture->min_mv = a[0]; -#ifdef DEBUG_QOS - avs2_print(dec, 0, "mv data %x a[0]= %x a[1]= %x a[2]= %x\n", - data, a[0], a[1], a[2]); -#endif - - 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->max_qp = a[2]; - picture->avg_qp = a[1]; - picture->min_qp = a[0]; -#ifdef DEBUG_QOS - 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; - 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->max_skip = a[2]; - picture->avg_skip = a[1]; - picture->min_skip = a[0]; - -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "skip data %x a[0]= %x a[1]= %x a[2]= %x\n", - data, a[0], a[1], a[2]); -#endif - } else { - 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; -#ifdef DEBUG_QOS - int pic_number = 0; -#endif - - picture->max_mv = 0; - picture->avg_mv = 0; - picture->min_mv = 0; - - picture->max_skip = 0; - picture->avg_skip = 0; - picture->min_skip = 0; - - 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, - pic_number); -#endif - /* set rd_idx to 0 */ - WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0); - - blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA); - if (blk88_y_count == 0) { -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] NO Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); - return; - } - /* qp_y_sum */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n", - pic_number, rdata32/blk88_y_count, - rdata32, blk88_y_count); -#endif - picture->avg_qp = rdata32/blk88_y_count; - /* intra_y_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] Y intra rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_y_count, - '%', rdata32); -#endif - /* skipped_y_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] Y skipped rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_y_count, - '%', rdata32); -#endif - picture->avg_skip = rdata32*100/blk88_y_count; - /* coeff_non_zero_y_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n", - pic_number, (100 - rdata32*100/(blk88_y_count*1)), - '%', rdata32); -#endif - /* blk66_c_count */ - blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA); - if (blk88_c_count == 0) { -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] NO Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); - return; - } - /* qp_c_sum */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] C QP AVG : %d (%d/%d)\n", - pic_number, rdata32/blk88_c_count, - rdata32, blk88_c_count); -#endif - /* intra_c_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] C intra rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_c_count, - '%', rdata32); -#endif - /* skipped_cu_c_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] C skipped rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_c_count, - '%', rdata32); -#endif - /* coeff_non_zero_c_count */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n", - pic_number, (100 - rdata32*100/(blk88_c_count*1)), - '%', rdata32); -#endif - - /* 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(HEVC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - avs2_print(dec, 0, "[Picture %d Quality] Y QP min : %d\n", - pic_number, (rdata32>>0)&0xff); -#endif - 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); -#endif - 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); - avs2_print(dec, 0, "[Picture %d Quality] C QP max : %d\n", - pic_number, (rdata32>>24)&0xff); -#endif - - /* blk22_mv_count */ - blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA); - if (blk22_mv_count == 0) { -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] NO MV Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (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(HEVC_PIC_QUALITY_DATA); - /* should all be 0x00 or 0xff */ -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] MV AVG High Bits: 0x%X\n", - pic_number, rdata32); -#endif - 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(HEVC_PIC_QUALITY_DATA); - 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, blk22_mv_count); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n", - pic_number, (int)value, - value, blk22_mv_count); -#endif - picture->avg_mv = value; - - /* mvy_L0_count[31:0] */ - rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* mvx_L1_count[31:0] */ - rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* mvy_L1_count[31:0] */ - rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS - avs2_print(dec, 0, "[Picture %d Quality] MVX_L0 MAX : %d\n", - pic_number, mv_hi); -#endif - picture->max_mv = mv_hi; - - mv_lo = (rdata32>>0)&0xffff; - if (mv_lo & 0x8000) - mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS - avs2_print(dec, 0, "[Picture %d Quality] MVX_L0 MIN : %d\n", - pic_number, mv_lo); -#endif - picture->min_mv = mv_lo; - -#ifdef DEBUG_QOS - /* {mvy_L0_max, mvy_L0_min} */ - rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - 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; - - 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; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - - 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; - - 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; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - - avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n", - pic_number, mv_hi); - - mv_lo = (rdata32>>0)&0xffff; - if (mv_lo & 0x8000) - mv_lo = 0x8000 - mv_lo; - - avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n", - pic_number, mv_lo); -#endif - - rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL); -#ifdef DEBUG_QOS - avs2_print(dec, 0, - "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n", - pic_number, rdata32); -#endif - /* reset all counts */ - WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8)); - } -} - -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; - - /*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, - 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); - amhevc_stop(); - vdec_schedule_work(&dec->work); - } - } - goto irq_handled_exit; - } else if (dec_status == HEVC_DECPIC_DATA_DONE) { - PRINT_LINE(); - dec->start_decoding_flag |= 0x3; - if (dec->m_ins_flag) { - set_cuva_data(dec); - update_decoded_pic(dec); - 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"); - 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); - 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); - 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); - 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); - 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) { - int32_t ii; -#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) - dump_pic_list(dec); - - avs2_prepare_display_buf(dec); - dec->avs2_dec.hc.cur_pic = NULL; - 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) { - if (pic->refered_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); -#ifdef DYNAMIC_ALLOC_HEAD - decoder_bmmu_box_free_idx( - dec->bmmu_box, - HEADER_BUFFER_IDX(pic->index)); - pic->header_adr = 0; -#endif -#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 - } - /* - decoder_bmmu_box_free_idx( - dec->bmmu_box, - VF_BUFFER_IDX(pic->index)); - dec->cma_alloc_addr = 0;*/ - } - } - } - } - - 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 { - - for (i = 0; i < (RPM_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]; - } - } -#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 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)) { - union param_u *pPara; - - avs2_print(dec, 0, - "avs2 HDR meta data present\n"); - pPara = &dec->avs2_dec.param; - - /*clean this flag*/ - pPara->p.video_signal_type - &= ~(1<<30); - - 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]; - avs2_print(dec, AVS2_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]; - 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); - } -#endif - - - 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; - } - } -#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); - - 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); - } 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_hw(dec); - } - ret = avs2_process_header(&dec->avs2_dec); - if (!dec->m_ins_flag) - dec->slice_idx++; - - if (dec->m_ins_flag && ret - && 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 -#ifdef AVS2_10B_MMU - if (ret >= 0) { - 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 - -#ifndef MV_USE_FIXED_BUF - 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 (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 - dec->avs2_dec.hc.cur_pic-> - mpred_mv_wr_start_addr - = buf_addr; - } -#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 - avs2_recycle_mmu_buf(dec); - #endif - if (dec->m_ins_flag) { - dec->dec_result = DEC_RESULT_DONE; - 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; - */ - if (!dec->m_ins_flag) { - 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; - } - /**/ - 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); -decode_slice: - PRINT_LINE(); - - config_mc_buffer(dec); - 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); - - 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); - goto irq_handled_exit; - } - - dec->process_state = PROC_STATE_DECODING; - - WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); - - } - - if (dec->m_ins_flag) - start_process_time(dec); - } -irq_handled_exit: - PRINT_LINE(); - 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; - - WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1); - - dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - - 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) - avs2_print(dec, 0, - "avs2 isr dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %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) - ); - - 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\n", READ_HREG(DEBUG_REG1), - READ_HREG(DEBUG_REG2), - READ_VREG(HEVC_PARSER_LCU_START)); - 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) { - /* - 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) - avs2_print(dec, 0, "wait_buf\n"); - return IRQ_HANDLED; - } else if (force_disp_pic_index) { - dec->process_busy = 0; - return IRQ_HANDLED; - } - } - return IRQ_WAKE_THREAD; -} - -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 receviver_start_e state = RECEIVER_INACTIVE; - if (dec->m_ins_flag) { - if (hw_to_vdec(dec)->next_status - == VDEC_STATUS_DISCONNECTED) { - dec->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&dec->work); - avs2_print(dec, AVS2_DBG_BUFMGR, - "vdec requested to be disconnected\n"); - return; - } - } - 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 - (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; - 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(HEVC_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 (debug & AVS2_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_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) -{ - unsigned int data32; - - avs2_config_work_space_hw(dec); - if (dec->pic_list_init_flag) - init_pic_list_hw(dec); - - avs2_init_decoder_hw(dec); - -#if 1 - avs2_print(dec, AVS2_DBG_BUFMGR_MORE, - "%s\n", __func__); - data32 = READ_VREG(HEVC_STREAM_CONTROL); - 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); - - /* enable mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(HEVC_PSCALE_CTRL, 0); - - 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); -} - -#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->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; -/* -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); - - 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; - struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private; - - timer_setup(&dec->timer, vavs2_put_timer_func, 0); - - dec->stat |= STAT_TIMER_INIT; - if (vavs2_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; - - 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; - - /*add_timer(&dec->timer); - - dec->stat |= STAT_TIMER_ARM; - dec->stat |= STAT_ISR_REG;*/ - - INIT_WORK(&dec->work, avs2_work); - 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", - 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->stat |= STAT_KTHREAD; */ - 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; - } - - 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); - uninit_mmu_buffers(dec); - if (dec->fw) { - vfree(dec->fw); - dec->fw = NULL; - } - - 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; - -#ifdef AVS2_10B_MMU - dec->need_cache_size = buf_size * SZ_1M; - dec->sc_start_time = get_jiffies_64(); - 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; - } -#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); - if (!dec->bmmu_box) { - pr_err("avs2 alloc bmmu box failed!!\n"); - return -1; - } - return 0; -} - -/****************************************/ -static struct codec_profile_t amvdec_avs2_profile = { - .name = "AVS2-V4L", - .profile = "" -}; - -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 (!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(dec, - 0, - "\n"); - - if (!dec->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); -} - -static void avs2_work(struct work_struct *work) -{ - struct AVS2Decoder_s *dec = container_of(work, - struct AVS2Decoder_s, work); - struct vdec_s *vdec = hw_to_vdec(dec); - /* 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 (((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_vh265: 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_vh265: Insufficient data\n"); - - vdec_schedule_work(&dec->work); - } - return; - } else if (dec->dec_result == DEC_RESULT_DONE) { - /* 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; - -#ifdef AVS2_10B_MMU - dec->used_4k_num = - (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); -#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; - } - } 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) { - 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__); - 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(HEVC_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; - } - /* 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); -} - -static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec) -{ - /* new to do ... */ - vavs2_prot_init(dec); - return 0; -} - -static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) -{ - struct AVS2Decoder_s *dec = - (struct AVS2Decoder_s *)vdec->private; - 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_PIC_LEAK_WAIT) - return ret; - - if (dec->eos) - return ret; - if (!dec->first_sc_checked) { - int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp); - 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 (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; -#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) - return ret ? CORE_MASK_HEVC : 0; - else - return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0; -} - -static void run(struct vdec_s *vdec, unsigned long mask, - void (*callback)(struct vdec_s *, void *), void *arg) -{ - struct AVS2Decoder_s *dec = - (struct AVS2Decoder_s *)vdec->private; - int r; - - 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)) { - 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_vh265: Insufficient data\n"); - - vdec_schedule_work(&dec->work); - return; - } - input_empty[dec->index] = 0; - dec->dec_result = DEC_RESULT_NONE; - 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"); - } - if (vdec->mc_loaded) { - /*firmware have load before, - and not changes to another. - ignore reload. - */ - } 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__); - dec->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&dec->work); - return; - } else { - vdec->mc_loaded = 1; - vdec->mc_type = VFORMAT_AVS2; - } - - - if (avs2_hw_ctx_restore(dec) < 0) { - vdec_schedule_work(&dec->work); - return; - } - - 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); - - WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); - 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)\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(); - amhevc_start(); - dec->stat |= STAT_VDEC_RUN; -} - -static void reset(struct vdec_s *vdec) -{ - - struct AVS2Decoder_s *dec = - (struct AVS2Decoder_s *)vdec->private; - - atomic_set(&dec->vf_pre_count, 0); - atomic_set(&dec->vf_get_count, 0); - atomic_set(&dec->vf_put_count, 0); - - 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; - avs2_print(dec, 0, "====== %s\n", __func__); - - avs2_print(dec, 0, - "width/height (%d/%d), used_buf_num %d\n", - dec->avs2_dec.img.width, - dec->avs2_dec.img.height, - 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", - 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 receviver_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)\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); - - 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); - } - } - -} - -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 BUF_s BUF[MAX_BUF_NUM];*/ - struct AVS2Decoder_s *dec = NULL; - - 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; - } - /*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 = vmalloc(sizeof(struct AVS2Decoder_s)); - memset(dec, 0, 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; - pdata->reset = reset; - pdata->irq_handler = avs2_irq_cb; - 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; - - if (is_rdma_enable()) { - dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE , &dec->rdma_phy_adr, GFP_KERNEL); - 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->vdec_name, sizeof(dec->vdec_name), - "avs2-%d", dec->index); - snprintf(dec->pts_name, sizeof(dec->pts_name), - "%s-timestamp", dec->vdec_name); - snprintf(dec->new_q_name, sizeof(dec->new_q_name), - "%s-newframe_q", dec->vdec_name); - snprintf(dec->disp_q_name, sizeof(dec->disp_q_name), - "%s-dispframe_q", dec->vdec_name); - - 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); - - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vavs2_vf_provider, 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 1 - if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && - pdata->config_len) { - /*use ptr config for doubel_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; - - 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 -#endif - { - /*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; - } - video_signal_type = dec->video_signal_type; - -#if 0 - dec->buf_start = pdata->mem_start; - dec->buf_size = pdata->mem_end - pdata->mem_start + 1; -#else - 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; - } - 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; - } - dec->buf_start = dec->cma_alloc_addr; - dec->buf_size = work_buf_size; -#endif - 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 (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) - dec->endian = HEVC_CONFIG_BIG_ENDIAN; - 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); - /* 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); - if (pdata->parallel_dec == 1) - 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) - 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()) - dma_free_coherent(amports_get_dma_device(), 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_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"); - 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_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); - - INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node, - "avs2-v4l", avs2_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_AVS2, 1); - - return 0; -} - -static void __exit amvdec_avs2_driver_remove_module(void) -{ - pr_debug("amvdec_avs2 module remove.\n"); - platform_driver_unregister(&ammvdec_avs2_driver); -} - -/****************************************/ - -module_param(bit_depth_luma, uint, 0664); -MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\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"); - -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_h265 force_bufspec\n"); - -module_param(udebug_flag, uint, 0664); -MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 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_h265 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_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_v4l/avs2/vavs2.h b/drivers/frame_provider/decoder_v4l/avs2/vavs2.h deleted file mode 100644 index 6b51f61..0000000 --- a/drivers/frame_provider/decoder_v4l/avs2/vavs2.h +++ /dev/null
@@ -1,26 +0,0 @@ -/* - * drivers/amlogic/amports/vavs2.h - * - * 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. - * -*/ - -#ifndef VAVS2_H -#define VAVS2_H - -#define AVS2_10B_MMU -#define MV_USE_FIXED_BUF - -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_v4l/avs_multi/Makefile b/drivers/frame_provider/decoder_v4l/avs_multi/Makefile deleted file mode 100644 index 10da3ab..0000000 --- a/drivers/frame_provider/decoder_v4l/avs_multi/Makefile +++ /dev/null
@@ -1,2 +0,0 @@ -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs_v4l.o -amvdec_mavs_v4l-objs += avs_multi.o
diff --git a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c b/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c deleted file mode 100644 index 3ad9385..0000000 --- a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c +++ /dev/null
@@ -1,5016 +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. - * - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/semaphore.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 "../../decoder/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 "../../decoder/utils/decoder_mmu_box.h" -#include "../../decoder/utils/decoder_bmmu_box.h" -#include "../../decoder/utils/firmware.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" -#include <linux/amlogic/tee.h> -#include "../../decoder/utils/vdec_feature.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 - -#define DRIVER_NAME "ammvdec_avs_v4l" - - -#define MULTI_DRIVER_NAME "ammvdec_avs_v4l" - -#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 -#define DEBUG_PTS - -#define CHECK_INTERVAL (HZ/100) - -#define I_PICTURE 0 -#define P_PICTURE 1 -#define B_PICTURE 2 - -#define LMEM_BUF_SIZE (0x500 * 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 DECODE_PIC_COUNT AV_SCRATCH_G - -#define DECODE_MODE AV_SCRATCH_6 -#define DECODE_MODE_SINGLE 0x0 -#define DECODE_MODE_MULTI_FRAMEBASE 0x1 -#define DECODE_MODE_MULTI_STREAMBASE 0x2 -#define DECODE_MODE_MULTI_STREAMBASE_CONT 0x3 - -#define DECODE_STATUS AV_SCRATCH_H -#define DECODE_STATUS_PIC_DONE 0x1 -#define DECODE_STATUS_DECODE_BUF_EMPTY 0x2 -#define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3 -#define DECODE_STATUS_SKIP_PIC_DONE 0x4 -#define DECODE_SEARCH_HEAD 0xff - -#define DECODE_STOP_POS AV_SCRATCH_J - -#define DECODE_LMEM_BUF_ADR AV_SCRATCH_I - -#define DECODE_CFG AV_SCRATCH_K - -#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[] = { - AV_SCRATCH_0, - AV_SCRATCH_1, - AV_SCRATCH_2, - AV_SCRATCH_3, - AV_SCRATCH_7, /*AVS_SOS_COUNT*/ - AV_SCRATCH_D, /*DEBUG_REG2*/ - AV_SCRATCH_E, /*DEBUG_REG1*/ - AV_SCRATCH_M /*user_data_poc_number*/ -}; -#endif - -#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; -static unsigned int debug_mask = 0xff; - -/*for debug*/ -/* - udebug_flag: - bit 0, enable ucode print - bit 1, enable ucode more print - bit 3, enable ucdode 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 -*/ -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 udebug_pause_ins_id; - -static u32 force_fps; - -#ifdef DEBUG_MULTI_FRAME_INS -static u32 delay; -#endif - -static u32 step; - -static u32 start_decoding_delay; - -#define AVS_DEV_NUM 9 -static unsigned int max_decode_instance_num = AVS_DEV_NUM; -static unsigned int max_process_time[AVS_DEV_NUM]; -static unsigned int max_get_frame_interval[AVS_DEV_NUM]; -static unsigned int run_count[AVS_DEV_NUM]; -static unsigned int ins_udebug_flag[AVS_DEV_NUM]; -#ifdef DEBUG_MULTI_FRAME_INS -static unsigned int max_run_count[AVS_DEV_NUM]; -#endif -/* -error_handle_policy: -*/ -static unsigned int error_handle_policy = 3; - -static u32 again_threshold = 0; /*0x40;*/ - -static unsigned int decode_timeout_val = 200; -static unsigned int start_decode_buf_level = 0x8000; - -/******************************** -firmware_sel - 0: use avsp_trans long cabac ucode; - 1: not use avsp_trans long cabac ucode - in ucode: - #define USE_EXT_BUFFER_ASSIGNMENT - #undef USE_DYNAMIC_BUF_NUM -********************************/ -static int firmware_sel; -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 *); -static int vavs_vf_states(struct vframe_states *states, void *); -static int vavs_event_cb(int type, void *data, void *private_data); - -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 -#ifdef DEBUG_MULTI_FRAME_INS -#define WORKSPACE_SIZE (16 * SZ_1M) -#else -#define WORKSPACE_SIZE (4 * SZ_1M) -#endif -#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 - -/* 4 buffers not enough for multi inc*/ -static u32 vf_buf_num = 8; -/*static u32 vf_buf_num_used;*/ -static u32 canvas_base = 128; -#ifdef NV21 -static int canvas_num = 2; /*NV21*/ -#else -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; -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 - -#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] = { - 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 -}; - -#define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX -#define PIC_PTS_NUM 64 -struct buf_pool_s { - unsigned detached; - struct vframe_s vf; -}; - -#define buf_of_vf(vf) container_of(vf, struct buf_pool_s, vf) - -struct pic_pts_s { - u32 pts; - u64 pts64; - u64 timestamp; - unsigned short decode_pic_count; -}; - -struct vdec_avs_hw_s { - spinlock_t lock; - unsigned char m_ins_flag; - struct platform_device *platform_dev; - DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); - struct buf_pool_s vfpool[VF_POOL_SIZE]; - s32 vfbuf_use[VF_BUF_NUM_MAX]; - unsigned char again_flag; - unsigned char recover_flag; - u32 frame_width; - u32 frame_height; - u32 frame_dur; - u32 frame_prog; - u32 saved_resolution; - u32 avi_flag; - u32 vavs_ratio; - u32 pic_type; - - u32 vf_buf_num_used; - u32 total_frame; - u32 next_pts; - unsigned char throw_pb_flag; - struct pic_pts_s pic_pts[PIC_PTS_NUM]; - int pic_pts_wr_pos; - -#ifdef DEBUG_PTS - u32 pts_hit; - u32 pts_missed; - u32 pts_i_hit; - u32 pts_i_missed; -#endif -#ifdef ENABLE_USER_DATA - struct work_struct userdata_push_work; - void *user_data_buffer; - dma_addr_t user_data_buffer_phys; -#endif - dma_addr_t lmem_addr; - ulong lmem_phy_addr; - - u32 buf_offset; - - struct dec_sysinfo vavs_amstream_dec_info; - struct vdec_info *gvs; - u32 fr_hint_status; - struct work_struct set_clk_work; - bool is_reset; - - /*debug*/ - u32 ucode_pause_pos; - /**/ - u32 decode_pic_count; - u8 reset_decode_flag; - u32 display_frame_count; - u32 buf_status; - u32 pre_parser_wr_ptr; - /* - buffer_status &= ~buf_recycle_status - */ - u32 buf_recycle_status; - u32 seqinfo; - u32 ctx_valid; - u32 dec_control; - void *mm_blk_handle; - struct vframe_chunk_s *chunk; - u32 stat; - u8 init_flag; - unsigned long buf_start; - u32 buf_size; - - u32 reg_scratch_0; - u32 reg_scratch_1; - u32 reg_scratch_2; - u32 reg_scratch_3; - u32 reg_scratch_4; - u32 reg_scratch_5; - u32 reg_scratch_6; - u32 reg_scratch_7; - u32 reg_scratch_8; - u32 reg_scratch_9; - u32 reg_scratch_A; - u32 reg_scratch_B; - u32 reg_scratch_C; - u32 reg_scratch_D; - u32 reg_scratch_E; - u32 reg_scratch_F; - u32 reg_scratch_G; - u32 reg_scratch_H; - u32 reg_scratch_I; - u32 reg_mb_width; - u32 reg_viff_bit_cnt; - u32 reg_canvas_addr; - u32 reg_dbkr_canvas_addr; - u32 reg_dbkw_canvas_addr; - u32 reg_anc2_canvas_addr; - u32 reg_anc0_canvas_addr; - u32 reg_anc1_canvas_addr; - u32 reg_anc3_canvas_addr; - u32 reg_anc4_canvas_addr; - u32 reg_anc5_canvas_addr; - u32 slice_ver_pos_pic_type; - u32 vc1_control_reg; - u32 avs_co_mb_wr_addr; - u32 slice_start_byte_01; - u32 slice_start_byte_23; - u32 vcop_ctrl_reg; - u32 iqidct_control; - u32 rv_ai_mb_count; - u32 slice_qp; - u32 dc_scaler; - u32 avsp_iq_wq_param_01; - u32 avsp_iq_wq_param_23; - u32 avsp_iq_wq_param_45; - u32 avs_co_mb_rd_addr; - u32 dblk_mb_wid_height; - u32 mc_pic_w_h; - u32 avs_co_mb_rw_ctl; - u32 vld_decode_control; - - struct timer_list check_timer; - u32 decode_timeout_count; - unsigned long int start_process_time; - u32 last_vld_level; - u32 eos; - u32 canvas_spec[DECODE_BUFFER_NUM_MAX]; - struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2]; - - s32 refs[2]; - int dec_result; - struct timer_list recycle_timer; - struct work_struct work; - 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_arg; -/* for error handling */ - u32 run_count; - u32 not_run_ready; - u32 input_empty; - atomic_t prepare_num; - atomic_t put_num; - atomic_t peek_num; - atomic_t get_num; - u32 drop_frame_count; - u32 buffer_not_ready; - int frameinfo_enable; - struct firmware_s *fw; - u32 old_udebug_flag; - u32 decode_status_skip_pic_done_flag; - u32 decode_decode_cont_start_code; - int vdec_pg_enable_flag; - char vdec_name[32]; - char pts_name[32]; - char new_q_name[32]; - char disp_q_name[32]; -}; - -static void reset_process_time(struct vdec_avs_hw_s *hw); -static void start_process_time(struct vdec_avs_hw_s *hw); -static void vavs_save_regs(struct vdec_avs_hw_s *hw); - -struct vdec_avs_hw_s *ghw; - -#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs" - -#define DEC_RESULT_NONE 0 -#define DEC_RESULT_DONE 1 -#define DEC_RESULT_AGAIN 2 -#define DEC_RESULT_ERROR 3 -#define DEC_RESULT_FORCE_EXIT 4 -#define DEC_RESULT_EOS 5 -#define DEC_RESULT_GET_DATA 6 -#define DEC_RESULT_GET_DATA_RETRY 7 -#define DEC_RESULT_USERDATA 8 - -#define DECODE_ID(hw) (hw->m_ins_flag? hw_to_vdec(hw)->id : 0) - -#define PRINT_FLAG_ERROR 0x0 -#define PRINT_FLAG_RUN_FLOW 0X0001 -#define PRINT_FLAG_DECODING 0x0002 -#define PRINT_FLAG_PTS 0x0004 -#define PRINT_FLAG_VFRAME_DETAIL 0x0010 -#define PRINT_FLAG_VLD_DETAIL 0x0020 -#define PRINT_FLAG_DEC_DETAIL 0x0040 -#define PRINT_FLAG_BUFFER_DETAIL 0x0080 -#define PRINT_FLAG_FORCE_DONE 0x0100 -#define PRINT_FLAG_COUNTER 0X0200 -#define PRINT_FRAMEBASE_DATA 0x0400 -#define PRINT_FLAG_PARA_DATA 0x1000 -#define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000 -#define DEBUG_FLAG_PRINT_REG 0x4000 -#define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000 -#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) -{ - if (debug & DEBUG_FLAG_PRINT_REG) - pr_info("%s(%x, %x)\n", __func__, adr, val); - if (adr != 0) - WRITE_VREG(adr, val); -} - -#undef WRITE_VREG -#define WRITE_VREG WRITE_VREG_DBG2 -#endif - -#undef pr_info -#define pr_info printk -static int debug_print(struct vdec_avs_hw_s *hw, - int flag, const char *fmt, ...) -{ -#define AVS_PRINT_BUF 256 - unsigned char buf[AVS_PRINT_BUF]; - int len = 0; - int index = 0; - if (hw) - index = hw->m_ins_flag ? DECODE_ID(hw) : 0; - if (hw == NULL || - (flag == 0) || - ((debug_mask & - (1 << index)) - && (debug & flag))) { - va_list args; - - va_start(args, fmt); - if (hw) - len = sprintf(buf, "[%d]", index); - vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - va_end(args); - } - return 0; -} - -static int debug_print_cont(struct vdec_avs_hw_s *hw, - int flag, const char *fmt, ...) -{ - unsigned char buf[AVS_PRINT_BUF]; - int len = 0; - int index = 0; - if (hw) - index = hw->m_ins_flag ? DECODE_ID(hw) : 0; - if (hw == NULL || - (flag == 0) || - ((debug_mask & - (1 << index)) - && (debug & flag))) { - va_list args; - - va_start(args, fmt); - vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - va_end(args); - } - return 0; -} - -static void avs_pts_check_in(struct vdec_avs_hw_s *hw, - unsigned short decode_pic_count, struct vframe_chunk_s *chunk) -{ - if (chunk) - debug_print(hw, PRINT_FLAG_PTS, - "%s %d (wr pos %d), pts %d pts64 %ld timestamp %ld\n", - __func__, decode_pic_count, hw->pic_pts_wr_pos, - chunk->pts, (u64)(chunk->pts64), (u64)(chunk->timestamp)); - else - debug_print(hw, PRINT_FLAG_PTS, - "%s %d, chunk is null\n", - __func__, decode_pic_count); - - if (chunk) { - hw->pic_pts[hw->pic_pts_wr_pos].pts = chunk->pts; - hw->pic_pts[hw->pic_pts_wr_pos].pts64 = chunk->pts64; - hw->pic_pts[hw->pic_pts_wr_pos].timestamp = chunk->timestamp; - } else { - hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; - hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; - hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; - } - hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count - = decode_pic_count; - hw->pic_pts_wr_pos++; - if (hw->pic_pts_wr_pos >= PIC_PTS_NUM) - hw->pic_pts_wr_pos = 0; - return; -} - -static void clear_pts_buf(struct vdec_avs_hw_s *hw) -{ - int i; - debug_print(hw, PRINT_FLAG_PTS, - "%s\n", __func__); - hw->pic_pts_wr_pos = 0; - for (i = 0; i < PIC_PTS_NUM; i++) { - hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; - hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; - hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; - hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count = 0; - } -} - -static int set_vframe_pts(struct vdec_avs_hw_s *hw, - unsigned short decode_pic_count, struct vframe_s *vf) -{ - int i; - int ret = -1; - for (i = 0; i < PIC_PTS_NUM; i++) { - if (hw->pic_pts[i].decode_pic_count == decode_pic_count) { - vf->pts = hw->pic_pts[i].pts; - vf->pts_us64 = hw->pic_pts[i].pts64; - vf->timestamp = hw->pic_pts[i].timestamp; - ret = 0; - debug_print(hw, PRINT_FLAG_PTS, - "%s %d (rd pos %d), pts %d pts64 %ld timestamp %ld\n", - __func__, decode_pic_count, i, - vf->pts, vf->pts_us64, vf->timestamp); - - break; - } - } - return ret; -} - -static void avs_vf_notify_receiver(struct vdec_avs_hw_s *hw, - const char *provider_name, int event_type, void *data) -{ - if (hw->m_ins_flag) - vf_notify_receiver(hw_to_vdec(hw)->vf_provider_name, - event_type, data); - else - vf_notify_receiver(provider_name, event_type, data); -} - -static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, - unsigned int *duration) -{ - int ar = 0; - - unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO); - atomic_add(1, &hw->prepare_num); -#ifndef USE_AVS_SEQ_INFO - if (hw->vavs_amstream_dec_info.width > 0 - && hw->vavs_amstream_dec_info.height > 0) { - vf->width = hw->vavs_amstream_dec_info.width; - vf->height = hw->vavs_amstream_dec_info.height; - } else -#endif - { - vf->width = READ_VREG(AVS_PIC_WIDTH); - vf->height = READ_VREG(AVS_PIC_HEIGHT); - 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 - if (hw->vavs_amstream_dec_info.rate > 0) - *duration = hw->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); */ - hw->frame_dur = *duration; - schedule_work(&hw->notify_work); - } - - if (hw->vavs_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 * hw->vavs_ratio) / vf->width; - break; - case 2: - vf->sar_width = 4; - vf->sar_height = 3; - ar = (vf->height * 3 * hw->vavs_ratio) / (vf->width * 4); - break; - case 3: - vf->sar_width = 16; - vf->sar_height = 9; - ar = (vf->height * 9 * hw->vavs_ratio) / (vf->width * 16); - break; - case 4: - vf->sar_width = 221; - vf->sar_height = 100; - ar = (vf->height * 100 * hw->vavs_ratio) / (vf->width * - 221); - break; - default: - vf->sar_width = 1; - vf->sar_height = 1; - ar = (vf->height * hw->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; - buf_of_vf(vf)->detached = 0; - -} - -#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; - 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(), - hw->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 *)hw->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 *)hw->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 *)hw->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)hw->user_data_buffer, - USER_DATA_SIZE, user_data_length); -*/ -} - -static void userdata_push_do_work(struct work_struct *work) -{ - struct vdec_avs_hw_s *hw = - container_of(work, struct vdec_avs_hw_s, userdata_push_work); - userdata_push_process(hw); -} - -static u8 UserDataHandler(struct vdec_avs_hw_s *hw) -{ - unsigned int user_data_flags; - - user_data_flags = READ_VREG(AV_SCRATCH_N); - if (user_data_flags & (1 << 15)) { /* data ready */ - if (hw->m_ins_flag) { - hw->dec_result = DEC_RESULT_USERDATA; - vdec_schedule_work(&hw->work); - return 1; - } else - schedule_work(&hw->userdata_push_work); - } - return 0; -} -#endif - - -static inline void avs_update_gvs(struct vdec_avs_hw_s *hw) -{ - if (hw->gvs->frame_height != hw->frame_height) { - hw->gvs->frame_width = hw->frame_width; - hw->gvs->frame_height = hw->frame_height; - } - if (hw->gvs->frame_dur != hw->frame_dur) { - hw->gvs->frame_dur = hw->frame_dur; - if (hw->frame_dur != 0) - hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ? - 96000 / hw->frame_dur : (96000 / hw->frame_dur +1); - else - hw->gvs->frame_rate = -1; - } - - hw->gvs->status = hw->stat; - hw->gvs->error_count = READ_VREG(AV_SCRATCH_C); - hw->gvs->drop_frame_count = hw->drop_frame_count; - -} - -#ifdef HANDLE_AVS_IRQ -static irqreturn_t vavs_isr(int irq, void *dev_id) -#else -static void vavs_isr(void) -#endif -{ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - 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) -{ - struct vframe_s *vf; - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)op_arg; - atomic_add(1, &hw->peek_num); - if (step == 2) - return NULL; - if (hw->recover_flag) - return NULL; - - if (kfifo_peek(&hw->display_q, &vf)) { - if (vf) { - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } - - } - return vf; - } - - return NULL; - -} - -static struct vframe_s *vavs_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)op_arg; - unsigned long flags; - - if (hw->recover_flag) - return NULL; - - if (step == 2) - return NULL; - else if (step == 1) - step = 2; - - spin_lock_irqsave(&lock, flags); - if (kfifo_get(&hw->display_q, &vf)) { - if (vf) { - vf->index_disp = atomic_read(&hw->get_num); - atomic_add(1, &hw->get_num); - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } - - debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x detached %d\n", - __func__, - vf->index, - vf->width, - vf->height, - vf->type, - buf_of_vf(vf)->detached); - } - spin_unlock_irqrestore(&lock, flags); - return vf; - } - spin_unlock_irqrestore(&lock, flags); - - return NULL; - -} - -static void vavs_vf_put(struct vframe_s *vf, void *op_arg) -{ - int i; - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)op_arg; - - if (vf) { - atomic_add(1, &hw->put_num); - debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s, index = %d, w %d h %d, type 0x%x detached 0x%x\n", - __func__, - vf->index, - vf->width, - vf->height, - vf->type, - buf_of_vf(vf)->detached); - } - if (hw->recover_flag) - return; - - for (i = 0; i < VF_POOL_SIZE; i++) { - if (vf == &hw->vfpool[i].vf) - break; - } - if (i < VF_POOL_SIZE) - - kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf); - -} - -static int vavs_event_cb(int type, void *data, void *private_data) -{ - struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_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(hw)); - else - req->req_result[0] = 0xffffffff; - } - - return 0; -} - -static int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) -{ - 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; - - vstatus->frame_width = hw->frame_width; - vstatus->frame_height = hw->frame_height; - if (hw->frame_dur != 0) - vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ? - 96000 / hw->frame_dur : (96000 / hw->frame_dur +1); - else - vstatus->frame_rate = -1; - vstatus->error_count = READ_VREG(AV_SCRATCH_C); - vstatus->status = hw->stat; - vstatus->bit_rate = hw->gvs->bit_rate; - vstatus->frame_dur = hw->frame_dur; - vstatus->frame_data = hw->gvs->frame_data; - vstatus->total_data = hw->gvs->total_data; - vstatus->frame_count = hw->gvs->frame_count; - vstatus->error_frame_count = hw->gvs->error_frame_count; - vstatus->drop_frame_count = hw->gvs->drop_frame_count; - vstatus->i_decoded_frames = hw->gvs->i_decoded_frames; - vstatus->i_lost_frames = hw->gvs->i_lost_frames; - vstatus->i_concealed_frames = hw->gvs->i_concealed_frames; - vstatus->p_decoded_frames = hw->gvs->p_decoded_frames; - vstatus->p_lost_frames = hw->gvs->p_lost_frames; - vstatus->p_concealed_frames = hw->gvs->p_concealed_frames; - vstatus->b_decoded_frames = hw->gvs->b_decoded_frames; - vstatus->b_lost_frames = hw->gvs->b_lost_frames; - vstatus->b_concealed_frames = hw->gvs->b_concealed_frames; - vstatus->total_data = hw->gvs->total_data; - vstatus->samp_cnt = hw->gvs->samp_cnt; - vstatus->offset = hw->gvs->offset; - snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), - "%s", DRIVER_NAME); - - return 0; -} - -static int vavs_set_isreset(struct vdec_s *vdec, int isreset) -{ - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)vdec->private; - - hw->is_reset = isreset; - return 0; -} - -static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw) -{ - - hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); - if (NULL == hw->gvs) { - pr_info("the struct of vdec status malloc failed.\n"); - return -ENOMEM; - } - - return 0; -} -/****************************************/ -static int vavs_canvas_init(struct vdec_avs_hw_s *hw) -{ - 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; - struct vdec_s *vdec = NULL; - - if (hw->m_ins_flag) - vdec = hw_to_vdec(hw); - - 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 = hw->vf_buf_num_used + 2; -#else - need_alloc_buf_num = hw->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(hw->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) - hw->buf_offset = buf_start - - RV_AI_BUFF_START_ADDR; - else - hw->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 (hw->m_ins_flag) { - 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; - } - - 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); -#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); -#endif - debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "canvas config %d, addr %p\n", i, - (void *)buf_start); - } - } - return 0; -} - -static void vavs_recover(struct vdec_avs_hw_s *hw) -{ - vavs_canvas_init(hw); - - 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); - - 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); - } - - - if (firmware_sel == 0) { - /* fixed canvas index */ - WRITE_VREG(AV_SCRATCH_0, canvas_base); - WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); - } else { - int ii; -#ifndef USE_DYNAMIC_BUF_NUM - 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) - ); - } -#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) - ); - } -#endif - } - - /* notify ucode the buffer offset */ - WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - -#ifndef USE_DYNAMIC_BUF_NUM - WRITE_VREG(AVS_SOS_COUNT, 0); -#endif - 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); -#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ - WRITE_VREG(AV_SCRATCH_D, 0); -#endif - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - -#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_5, 0); - -} - -#define MBY_MBX MB_MOTION_MODE /*0xc07*/ -#define AVS_CO_MB_WR_ADDR 0xc38 -#define AVS_CO_MB_RW_CTL 0xc3d -#define AVS_CO_MB_RD_ADDR 0xc39 -#define AVSP_IQ_WQ_PARAM_01 0x0e19 -#define AVSP_IQ_WQ_PARAM_23 0x0e1a -#define AVSP_IQ_WQ_PARAM_45 0x0e1b - -static void vavs_save_regs(struct vdec_avs_hw_s *hw) -{ - hw->reg_scratch_0 = READ_VREG(AV_SCRATCH_0); - 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); - hw->reg_scratch_F = READ_VREG(AV_SCRATCH_F); - hw->reg_scratch_G = READ_VREG(AV_SCRATCH_G); - hw->reg_scratch_H = READ_VREG(AV_SCRATCH_H); - hw->reg_scratch_I = READ_VREG(AV_SCRATCH_I); - - hw->reg_mb_width = READ_VREG(MB_WIDTH); - hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT); - - hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR); - hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); - hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); - hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); - hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); - hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); - hw->reg_anc3_canvas_addr = READ_VREG(ANC3_CANVAS_ADDR); - hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR); - hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR); - - hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); - - hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); - hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); - hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); - hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); - hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); - hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); - hw->slice_qp = READ_VREG(SLICE_QP); - - hw->dc_scaler = READ_VREG(DC_SCALER); - hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); - hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); - hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); - hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); - hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); - hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); - hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); - - hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); -} - -static void vavs_restore_regs(struct vdec_avs_hw_s *hw) -{ - debug_print(hw, PRINT_FLAG_DECODING, - "%s scratch_8 (AVS_BUFFERIN) 0x%x, decode_pic_count = %d\n", - __func__, hw->reg_scratch_8, hw->decode_pic_count); - - WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0); - 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); - WRITE_VREG(AV_SCRATCH_F, hw->reg_scratch_F); - WRITE_VREG(AV_SCRATCH_G, hw->reg_scratch_G); - WRITE_VREG(AV_SCRATCH_H, hw->reg_scratch_H); - WRITE_VREG(AV_SCRATCH_I, hw->reg_scratch_I); - - WRITE_VREG(MB_WIDTH, hw->reg_mb_width); - 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(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); - WRITE_VREG(SLICE_START_BYTE_23, hw->slice_start_byte_23); - WRITE_VREG(VCOP_CTRL_REG, hw->vcop_ctrl_reg); - WRITE_VREG(IQIDCT_CONTROL, hw->iqidct_control); - WRITE_VREG(RV_AI_MB_COUNT, hw->rv_ai_mb_count); - WRITE_VREG(SLICE_QP, hw->slice_qp); - - WRITE_VREG(DC_SCALER, hw->dc_scaler); - WRITE_VREG(AVSP_IQ_WQ_PARAM_01, hw->avsp_iq_wq_param_01); - WRITE_VREG(AVSP_IQ_WQ_PARAM_23, hw->avsp_iq_wq_param_23); - WRITE_VREG(AVSP_IQ_WQ_PARAM_45, hw->avsp_iq_wq_param_45); - WRITE_VREG(AVS_CO_MB_RD_ADDR, hw->avs_co_mb_rd_addr); - WRITE_VREG(DBLK_MB_WID_HEIGHT, hw->dblk_mb_wid_height); - WRITE_VREG(MC_PIC_W_H, hw->mc_pic_w_h); - WRITE_VREG(AVS_CO_MB_RW_CTL, hw->avs_co_mb_rw_ctl); - - WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_decode_control); - -} - -static int vavs_prot_init(struct vdec_avs_hw_s *hw) -{ - int r = 0; -#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); - - 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 -#if DEBUG_MULTI_FLAG > 0 - } -#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); - /*************************************************************/ - if (hw->m_ins_flag) { - int i; - if (hw->decode_pic_count == 0) { - r = vavs_canvas_init(hw); -#ifndef USE_DYNAMIC_BUF_NUM - for (i = 0; i < 4; i++) { - WRITE_VREG(AV_SCRATCH_0 + i, - hw->canvas_spec[i] - ); - } -#else - for (i = 0; i < hw->vf_buf_num_used; i++) - WRITE_VREG(buf_spec_reg[i], 0); - for (i = 0; i < hw->vf_buf_num_used; i += 2) { - WRITE_VREG(buf_spec_reg[i >> 1], - (hw->canvas_spec[i] & 0xffff) | - ((hw->canvas_spec[i + 1] & 0xffff) - << 16) - ); - debug_print(hw, PRINT_FLAG_DECODING, - "%s WRITE_VREG(0x%x, 0x%x)\n", - __func__, buf_spec_reg[i >> 1], READ_VREG(buf_spec_reg[i >> 1])); - } -#endif - } else - 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); - - 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); -#ifdef NV21 - if (firmware_sel == 0) { - /* fixed canvas index */ - WRITE_VREG(AV_SCRATCH_0, canvas_base); - WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); - } else { - int ii; -#ifndef USE_DYNAMIC_BUF_NUM - 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) - ); - } -#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) - ); - } -#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 */ - 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 */ - if (hw->decode_pic_count == 0) - WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - if (hw->decode_pic_count == 0) { -#ifndef USE_DYNAMIC_BUF_NUM - WRITE_VREG(AVS_SOS_COUNT, 0); -#endif - 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); -#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ - if (hw->decode_pic_count == 0) - WRITE_VREG(AV_SCRATCH_D, 0); -#endif - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - /* V4L2_PIX_FMT_NV21 V4L2_PIX_FMT_NV21M */ - SET_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); - WRITE_VREG(LONG_CABAC_REQ, 0); - WRITE_VREG(LONG_CABAC_PIC_SIZE, 0); - WRITE_VREG(LONG_CABAC_SRC_ADDR, 0); - } -#endif - -#ifdef ENABLE_USER_DATA - if (hw->decode_pic_count == 0) { - WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); - pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); - } else - WRITE_VREG(AV_SCRATCH_N, 0); -#endif - if (hw->m_ins_flag) { - if (vdec_frame_based(hw_to_vdec(hw))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else { - if (hw->decode_status_skip_pic_done_flag) { - WRITE_VREG(DECODE_CFG, hw->decode_decode_cont_start_code); - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE_CONT); - } else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); - } - WRITE_VREG(DECODE_LMEM_BUF_ADR, (u32)hw->lmem_phy_addr); - } else - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - - if (ins_udebug_flag[DECODE_ID(hw)] && - (ins_udebug_flag[DECODE_ID(hw)] >> 16) == hw->decode_pic_count) { - WRITE_VREG(DECODE_STOP_POS, - ins_udebug_flag[DECODE_ID(hw)] & 0xffff); - } - else - WRITE_VREG(DECODE_STOP_POS, udebug_flag); - hw->old_udebug_flag = udebug_flag; - - return r; -} - - -#ifdef AVSP_LONG_CABAC -static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); -#endif -static void vavs_local_init(struct vdec_avs_hw_s *hw) -{ - int i; - - hw->vf_buf_num_used = vf_buf_num; - - hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio; - - hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param; - - hw->frame_width = hw->frame_height = hw->frame_dur = hw->frame_prog = 0; - - hw->throw_pb_flag = 1; - - hw->total_frame = 0; - hw->saved_resolution = 0; - hw->next_pts = 0; - -#ifdef DEBUG_PTS - hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0; -#endif - INIT_KFIFO(hw->display_q); - INIT_KFIFO(hw->recycle_q); - INIT_KFIFO(hw->newframe_q); - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &hw->vfpool[i].vf; - - hw->vfpool[i].vf.index = hw->vf_buf_num_used; - hw->vfpool[i].vf.bufWidth = 1920; - hw->vfpool[i].detached = 0; - kfifo_put(&hw->newframe_q, vf); - } - for (i = 0; i < hw->vf_buf_num_used; i++) - hw->vfbuf_use[i] = 0; - - /*cur_vfpool = vfpool;*/ - - if (hw->recover_flag == 1) - return; - - if (hw->mm_blk_handle) { - pr_info("decoder_bmmu_box_free\n"); - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } - - hw->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); - if (hw->mm_blk_handle == NULL) - pr_info("Error, decoder_bmmu_box_alloc_box fail\n"); - -} - -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; - - - spin_lock_irqsave(&lock, flags); - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&hw->newframe_q); - states->buf_avail_num = kfifo_len(&hw->display_q); - states->buf_recycle_num = kfifo_len(&hw->recycle_q); - if (step == 2) - states->buf_avail_num = 0; - 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(ghw); - - pr_info("vavs: vf_ppmgr_reset\n"); -} -#endif - -static void vavs_local_reset(struct vdec_avs_hw_s *hw) -{ - mutex_lock(&vavs_mutex); - hw->recover_flag = 1; - pr_info("error, local reset\n"); - amvdec_stop(); - msleep(100); - avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - vavs_local_init(hw); - vavs_recover(hw); - -#ifdef ENABLE_USER_DATA - reset_userdata_fifo(1); -#endif - - 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 = - container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work); - 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(hw); - vf_reg_provider(&vavs_vf_prov); -#endif - vavs_recover(hw); - amvdec_start(); - mutex_unlock(&vavs_mutex); - } else { - pr_info("avs fatal_error_handler\n"); - vavs_local_reset(hw); - } - atomic_set(&hw->error_handler_run, 0); -} - -static void vavs_notify_work(struct work_struct *work) -{ - struct vdec_avs_hw_s *hw = - container_of(work, struct vdec_avs_hw_s, notify_work); - if (hw->fr_hint_status == VDEC_NEED_HINT) { - avs_vf_notify_receiver(hw, PROVIDER_NAME , - VFRAME_EVENT_PROVIDER_FR_HINT , - (void *)((unsigned long)hw->frame_dur)); - hw->fr_hint_status = VDEC_HINTED; - } - return; -} - -static void avs_set_clk(struct work_struct *work) -{ - struct vdec_avs_hw_s *hw = - container_of(work, struct vdec_avs_hw_s, set_clk_work); - if (hw->frame_dur > 0 && hw->saved_resolution != - hw->frame_width * hw->frame_height * (96000 / hw->frame_dur)) { - int fps = 96000 / hw->frame_dur; - - 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); - } else { - vdec_source_changed(VFORMAT_AVS, - hw->frame_width, hw->frame_height, fps); - } - - } -} - -#ifdef DEBUG_MULTI_WITH_AUTOMODE -int delay_count = 0; -#endif -static void vavs_put_timer_func(struct timer_list *arg) -{ - struct vdec_avs_hw_s *hw = container_of(arg, - struct vdec_avs_hw_s, recycle_timer); - struct timer_list *timer = &hw->recycle_timer; - -#ifndef HANDLE_AVS_IRQ - vavs_isr(); -#endif -#ifdef DEBUG_MULTI_WITH_AUTOMODE - if (delay_count > 0) { - if (delay_count == 1) - amvdec_start(); - delay_count--; - } -#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", - 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(&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); - 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 ((hw->ucode_pause_pos != 0) && - (hw->ucode_pause_pos != 0xffffffff) && - udebug_pause_pos != hw->ucode_pause_pos) { - hw->ucode_pause_pos = 0; - WRITE_VREG(DEBUG_REG1, 0); - } - - if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) { - struct vframe_s *vf; - - if (kfifo_get(&hw->recycle_q, &vf)) { - if ((vf->index < hw->vf_buf_num_used) && - (--hw->vfbuf_use[vf->index] == 0)) { - debug_print(hw, PRINT_FLAG_DECODING, - "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n", - __func__, - ~(1 << vf->index), vf->index); - WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); - vf->index = hw->vf_buf_num_used; - } - kfifo_put(&hw->newframe_q, - (const struct vframe_s *)vf); - } - - } - - schedule_work(&hw->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; - 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)) { - 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(&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); - } - -} -#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(struct vdec_avs_hw_s *hw) -{ - 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); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) - size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); - else { - if (firmware_sel == 1) - size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); -#ifdef AVSP_LONG_CABAC - else { - init_avsp_long_cabac_buf(); - size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); - } -#endif - } - - if (size < 0) { - amvdec_disable(); - pr_err("get firmware fail."); - vfree(fw); - return -1; - } - - fw->len = size; - hw->fw = fw; - - 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); - - hw->fw = fw; - return 0; - } - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) - ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data); - else if (firmware_sel == 1) - ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", fw->data); - else - ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data); - - 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);*/ - - hw->stat |= STAT_MC_LOAD; - - - /* enable AMRISC side protocol */ - ret = vavs_prot_init(hw); - if (ret < 0) - return ret; - -#ifdef HANDLE_AVS_IRQ - if (vdec_request_irq(VDEC_IRQ_1, vavs_isr, - "vavs-irq", (void *)hw)) { - amvdec_disable(); - pr_info("vavs irq register error.\n"); - return -ENOENT; - } -#endif - - hw->stat |= STAT_ISR_REG; - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); - vf_reg_provider(&vavs_vf_prov); - avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); - vf_reg_provider(&vavs_vf_prov); -#endif - - if (hw->vavs_amstream_dec_info.rate != 0) { - if (!hw->is_reset) - avs_vf_notify_receiver(hw, PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long) - hw->vavs_amstream_dec_info.rate)); - hw->fr_hint_status = VDEC_HINTED; - } else - hw->fr_hint_status = VDEC_NEED_HINT; - - hw->stat |= STAT_VF_HOOK; - - timer_setup(&hw->recycle_timer, vavs_put_timer_func, 0); - //hw->recycle_timer.data = (ulong)(hw); - //hw->recycle_timer.function = vavs_put_timer_func; - hw->recycle_timer.expires = jiffies + PUT_INTERVAL; - - add_timer(&hw->recycle_timer); - - hw->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); -#ifdef DEBUG_MULTI_WITH_AUTOMODE - if (start_decoding_delay == 0) - amvdec_start(); - else - delay_count = start_decoding_delay/10; -#else - amvdec_start(); -#endif - hw->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; - struct vdec_avs_hw_s *hw = NULL; - - if (pdata == NULL) { - pr_info("amvdec_avs memory resource undefined.\n"); - return -EFAULT; - } - - hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s)); - if (hw == NULL) { - pr_info("\nammvdec_avs decoder driver alloc failed\n"); - return -ENOMEM; - } - pdata->private = hw; - ghw = hw; - atomic_set(&hw->error_handler_run, 0); - hw->m_ins_flag = 0; - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) - firmware_sel = 1; - - if (firmware_sel == 1) { -#ifndef USE_DYNAMIC_BUF_NUM - vf_buf_num = 4; -#endif - canvas_base = 0; - canvas_num = 3; - } else { - - canvas_base = 128; - canvas_num = 2; /*NV21*/ - } - - - if (pdata->sys_info) - hw->vavs_amstream_dec_info = *pdata->sys_info; - - pr_info("%s (%d,%d) %d\n", __func__, hw->vavs_amstream_dec_info.width, - hw->vavs_amstream_dec_info.height, hw->vavs_amstream_dec_info.rate); - - pdata->dec_status = vavs_dec_status; - pdata->set_isreset = vavs_set_isreset; - hw->is_reset = 0; - - pdata->user_data_read = NULL; - pdata->reset_userdata_fifo = NULL; - - vavs_vdec_info_init(hw); - -#ifdef ENABLE_USER_DATA - if (NULL == hw->user_data_buffer) { - hw->user_data_buffer = - dma_alloc_coherent(amports_get_dma_device(), - USER_DATA_SIZE, - &hw->user_data_buffer_phys, GFP_KERNEL); - if (!hw->user_data_buffer) { - pr_info("%s: Can not allocate hw->user_data_buffer\n", - __func__); - return -ENOMEM; - } - pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", - hw->user_data_buffer, (u32)hw->user_data_buffer_phys); - } -#endif - INIT_WORK(&hw->set_clk_work, avs_set_clk); - if (vavs_init(hw) < 0) { - pr_info("amvdec_avs init failed.\n"); - kfree(hw->gvs); - hw->gvs = NULL; - pdata->dec_status = NULL; - if (hw->fw) - vfree(hw->fw); - hw->fw = NULL; - return -ENODEV; - } - /*vdec = pdata;*/ - - INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); - atomic_set(&hw->error_handler_run, 0); -#ifdef ENABLE_USER_DATA - INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); -#endif - INIT_WORK(&hw->notify_work, vavs_notify_work); - - return 0; -} - -static int amvdec_avs_remove(struct platform_device *pdev) -{ - struct vdec_avs_hw_s *hw = ghw; - - cancel_work_sync(&hw->fatal_error_wd_work); - atomic_set(&hw->error_handler_run, 0); -#ifdef ENABLE_USER_DATA - cancel_work_sync(&hw->userdata_push_work); -#endif - cancel_work_sync(&hw->notify_work); - cancel_work_sync(&hw->set_clk_work); - if (hw->stat & STAT_VDEC_RUN) { - amvdec_stop(); - hw->stat &= ~STAT_VDEC_RUN; - } - - if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); - hw->stat &= ~STAT_ISR_REG; - } - - if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->recycle_timer); - hw->stat &= ~STAT_TIMER_ARM; - } -#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 (hw->stat & STAT_VF_HOOK) { - if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) - avs_vf_notify_receiver(hw, PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - hw->fr_hint_status = VDEC_NO_NEED_HINT; - vf_unreg_provider(&vavs_vf_prov); - hw->stat &= ~STAT_VF_HOOK; - } - -#ifdef ENABLE_USER_DATA - if (hw->user_data_buffer != NULL) { - dma_free_coherent( - amports_get_dma_device(), - USER_DATA_SIZE, - hw->user_data_buffer, - hw->user_data_buffer_phys); - hw->user_data_buffer = NULL; - hw->user_data_buffer_phys = 0; - } -#endif - - if (hw->fw) { - vfree(hw->fw); - hw->fw = NULL; - } - - //amvdec_disable(); - //vdec_disable_DMC(NULL); - - hw->pic_type = 0; - if (hw->mm_blk_handle) { - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } -#ifdef DEBUG_PTS - pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, - hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); - pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, - hw->vavs_amstream_dec_info.rate); -#endif - kfree(hw->gvs); - hw->gvs = NULL; - vfree(hw); - return 0; -} - -/****************************************/ -#if 0 -static struct platform_driver amvdec_avs_driver = { - .probe = amvdec_avs_probe, - .remove = amvdec_avs_remove, - .driver = { - .name = DRIVER_NAME, - } -}; -#endif - -static void recycle_frames(struct vdec_avs_hw_s *hw); - -static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) -{ - 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]) - return 0; - - if ((DECODE_ID(hw) == 1) && run_count[1] >= run_count[0] && - run_count[0] < max_run_count[0]) - return 0; - - if (max_run_count[DECODE_ID(hw)] > 0 && - run_count[DECODE_ID(hw)] >= max_run_count[DECODE_ID(hw)]) - return 0; -#endif - if (vdec_stream_based(vdec) && (hw->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) { - hw->not_run_ready++; - return 0; - } - } - - 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; - } - - if (again_threshold > 0 && - hw->pre_parser_wr_ptr != 0 && - hw->again_flag && - (!vdec_frame_based(vdec))) { - u32 parser_wr_ptr = - STBUF_READ(&vdec->vbuf, get_rp); - if (parser_wr_ptr >= hw->pre_parser_wr_ptr && - (parser_wr_ptr - hw->pre_parser_wr_ptr) < - again_threshold) { - int r = vdec_sync_input(vdec); - debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, - "%s buf lelvel:%x\n", __func__, r); - ret = 0; - } - } - - if (ret) - hw->not_run_ready = 0; - else - hw->not_run_ready++; - - if (ret != 0) { - if (vdec->parallel_dec == 1) - return (unsigned long)(CORE_MASK_VDEC_1); - else - return (unsigned long)(CORE_MASK_VDEC_1 | CORE_MASK_HEVC); - } else - return 0; -} - -static void vavs_work(struct work_struct *work) -{ - struct vdec_avs_hw_s *hw = - container_of(work, struct vdec_avs_hw_s, work); - struct vdec_s *vdec = hw_to_vdec(hw); - if (hw->dec_result != DEC_RESULT_AGAIN) - debug_print(hw, PRINT_FLAG_RUN_FLOW, - "ammvdec_avs: vavs_work,result=%d,status=%d\n", - hw->dec_result, hw_to_vdec(hw)->next_status); - hw->again_flag = 0; - if (hw->dec_result == DEC_RESULT_USERDATA) { - userdata_push_process(hw); - return; - } else if (hw->dec_result == DEC_RESULT_DONE) { - - if (!hw->ctx_valid) - hw->ctx_valid = 1; -#ifdef DEBUG_MULTI_FRAME_INS - msleep(delay); -#endif - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - } else if (hw->dec_result == DEC_RESULT_AGAIN - && (hw_to_vdec(hw)->next_status != - VDEC_STATUS_DISCONNECTED)) { - /* - stream base: stream buf empty or timeout - frame base: vdec_prepare_input fail - */ - hw->again_flag = 1; - if (!vdec_has_more_input(hw_to_vdec(hw))) { - hw->dec_result = DEC_RESULT_EOS; - vdec_schedule_work(&hw->work); - return; - } - } else if (hw->dec_result == DEC_RESULT_GET_DATA - && (hw_to_vdec(hw)->next_status != - VDEC_STATUS_DISCONNECTED)) { - if (!vdec_has_more_input(hw_to_vdec(hw))) { - hw->dec_result = DEC_RESULT_EOS; - vdec_schedule_work(&hw->work); - return; - } - debug_print(hw, PRINT_FLAG_VLD_DETAIL, - "%s DEC_RESULT_GET_DATA %x %x %x\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP)); - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - vdec_clean_input(hw_to_vdec(hw)); - return; - } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) { - debug_print(hw, PRINT_FLAG_ERROR, - "%s: force exit\n", __func__); - if (hw->stat & STAT_ISR_REG) { - amvdec_stop(); - /*disable mbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 0); - vdec_free_irq(VDEC_IRQ_1, (void *)hw); - hw->stat &= ~STAT_ISR_REG; - } - } else if (hw->dec_result == DEC_RESULT_EOS) { - debug_print(hw, PRINT_FLAG_DECODING, - "%s: end of stream\n", __func__); - if (hw->stat & STAT_VDEC_RUN) { - amvdec_stop(); - hw->stat &= ~STAT_VDEC_RUN; - } - hw->eos = 1; - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - vdec_clean_input(hw_to_vdec(hw)); - } - if (hw->stat & STAT_VDEC_RUN) { -#if DEBUG_MULTI_FLAG == 1 -#else - amvdec_stop(); -#endif - hw->stat &= ~STAT_VDEC_RUN; - } - /*wait_vmmpeg12_search_done(hw);*/ - if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->check_timer); - hw->stat &= ~STAT_TIMER_ARM; - } - if (hw->dec_result == DEC_RESULT_DONE) - hw->buf_recycle_status = 0; - debug_print(hw, PRINT_FLAG_RUN_FLOW, "work end %d\n", hw->dec_result); - if (vdec->parallel_dec == 1) - vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1); - else - 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); - debug_print(hw, 0x80000, - "%s:\n", __func__); - } -} - - -static void reset_process_time(struct vdec_avs_hw_s *hw) -{ - if (!hw->m_ins_flag) - return; - if (hw->start_process_time) { - unsigned process_time = - 1000 * (jiffies - hw->start_process_time) / HZ; - hw->start_process_time = 0; - if (process_time > max_process_time[DECODE_ID(hw)]) - max_process_time[DECODE_ID(hw)] = process_time; - } -} -static void start_process_time(struct vdec_avs_hw_s *hw) -{ - hw->decode_timeout_count = 2; - hw->start_process_time = jiffies; -} - -static void handle_decoding_error(struct vdec_avs_hw_s *hw) -{ - int i; - unsigned long flags; - struct vframe_s *vf; - spin_lock_irqsave(&lock, flags); - for (i = 0; i < VF_POOL_SIZE; i++) { - vf = &hw->vfpool[i].vf; - if (vf->index < hw->vf_buf_num_used) { - hw->vfpool[i].detached = 1; - hw->vfbuf_use[vf->index] = 0; - } - } - if (error_handle_policy & 0x2) { - while (!kfifo_is_empty(&hw->display_q)) { - if (kfifo_get(&hw->display_q, &vf)) { - if (buf_of_vf(vf)->detached !=0) { - debug_print(hw, PRINT_FLAG_DECODING, - "%s recycle %d => newframe_q\n", - __func__, - vf->index); - vf->index = hw->vf_buf_num_used; - buf_of_vf(vf)->detached = 0; - kfifo_put(&hw->newframe_q, - (const struct vframe_s *)vf); - } - } - - } - } - clear_pts_buf(hw); - hw->decode_pic_count = 0; - hw->reset_decode_flag = 1; - hw->pre_parser_wr_ptr = 0; - hw->buf_status = 0; - hw->throw_pb_flag = 1; - spin_unlock_irqrestore(&lock, flags); -} - -static void timeout_process(struct vdec_avs_hw_s *hw) -{ - struct vdec_s *vdec = hw_to_vdec(hw); - amvdec_stop(); - if (error_handle_policy & 0x1) { - handle_decoding_error(hw); - } else { - vavs_save_regs(hw); - - //if (hw->decode_pic_count == 0) - hw->decode_pic_count++; - if ((hw->decode_pic_count & 0xffff) == 0) { - /*make ucode do not handle it as first picture*/ - hw->decode_pic_count++; - } - } - hw->dec_result = DEC_RESULT_DONE; - - debug_print(hw, PRINT_FLAG_ERROR, - "%s decoder timeout, status=%d, level=%d, bit_cnt=0x%x\n", - __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VIFF_BIT_CNT)); - reset_process_time(hw); - vdec_schedule_work(&hw->work); -} - - -static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) -{ - if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) { - struct vframe_s *vf; - - if (kfifo_get(&hw->recycle_q, &vf)) { - if (buf_of_vf(vf)->detached) { - debug_print(hw, 0, - "%s recycle detached vf, index=%d detched %d used %d\n", - __func__, vf->index, - buf_of_vf(vf)->detached, - hw->vfbuf_use[vf->index]); - } - if ((vf->index < hw->vf_buf_num_used) && - (buf_of_vf(vf)->detached == 0) && - (--hw->vfbuf_use[vf->index] == 0)) { - hw->buf_recycle_status |= (1 << vf->index); - WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); - debug_print(hw, PRINT_FLAG_DECODING, - "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d => buf_recycle_status 0x%x\n", - __func__, - READ_VREG(AVS_BUFFERIN), vf->index, - hw->buf_recycle_status); - } - vf->index = hw->vf_buf_num_used; - buf_of_vf(vf)->detached = 0; - kfifo_put(&hw->newframe_q, - (const struct vframe_s *)vf); - } - - } - -} - -static void recycle_frames(struct vdec_avs_hw_s *hw) -{ - while (!kfifo_is_empty(&hw->recycle_q)) { - struct vframe_s *vf; - - if (kfifo_get(&hw->recycle_q, &vf)) { - if (buf_of_vf(vf)->detached) { - debug_print(hw, 0, - "%s recycle detached vf, index=%d detched %d used %d\n", - __func__, vf->index, - buf_of_vf(vf)->detached, - hw->vfbuf_use[vf->index]); - } - - - if ((vf->index < hw->vf_buf_num_used) && - (buf_of_vf(vf)->detached == 0) && - (--hw->vfbuf_use[vf->index] == 0)) { - 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", - __func__, - vf->index, - hw->buf_recycle_status); - } - vf->index = hw->vf_buf_num_used; - buf_of_vf(vf)->detached = 0; - kfifo_put(&hw->newframe_q, - (const struct vframe_s *)vf); - } - - } - -} - - -static void check_timer_func(struct timer_list *timer) -{ - struct vdec_avs_hw_s *hw = container_of(timer, - struct vdec_avs_hw_s, check_timer); - struct vdec_s *vdec = hw_to_vdec(hw); - unsigned int timeout_val = decode_timeout_val; - unsigned long flags; - - if (hw->m_ins_flag && - (debug & - DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && - vdec->next_status == - VDEC_STATUS_DISCONNECTED) { - hw->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&hw->work); - debug_print(hw, - 0, "vdec requested to be disconnected\n"); - return; - } - - /*recycle*/ - if (!hw->m_ins_flag) { - spin_lock_irqsave(&lock, flags); - recycle_frame_bufferin(hw); - spin_unlock_irqrestore(&lock, flags); - } - - if (hw->m_ins_flag) { - if ((READ_VREG(AV_SCRATCH_5) & 0xf) != 0 && - (READ_VREG(AV_SCRATCH_5) & 0xff00) != 0){ - /*ucode buffer empty*/ - if ((kfifo_len(&hw->recycle_q) == 0) && - (kfifo_len(&hw->display_q) == 0)) { - debug_print(hw, - 0, "AV_SCRATCH_5=0x%x, recover ucode buffer_status\n", - READ_VREG(AV_SCRATCH_5)); - WRITE_VREG(AV_SCRATCH_5, 0x10); - /*let ucode to recover buffer_status*/ - } - } - } - 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 (udebug_flag != hw->old_udebug_flag) { - WRITE_VREG(DECODE_STOP_POS, udebug_flag); - hw->old_udebug_flag = udebug_flag; - } - if (dbg_cmd != 0) { - if (dbg_cmd == 1) { - int r = vdec_sync_input(vdec); - dbg_cmd = 0; - pr_info( - "vdec_sync_input=>0x%x, (lev %x, wp %x rp %x, prp %x, pwp %x)\n", - r, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - STBUF_READ(&vdec->vbuf, get_rp), - STBUF_READ(&vdec->vbuf, get_wp)); - } - } - - if ((debug & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && - (timeout_val > 0) && - (hw->start_process_time > 0) && - ((1000 * (jiffies - hw->start_process_time) / HZ) - > timeout_val)) { - if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) { - if (hw->decode_timeout_count > 0) - hw->decode_timeout_count--; - if (hw->decode_timeout_count == 0) - timeout_process(hw); - } - hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); - } - - if (READ_VREG(AVS_SOS_COUNT)) { - if (!error_recovery_mode) { - amvdec_stop(); - if (error_handle_policy & 0x1) { - handle_decoding_error(hw); - } else { - vavs_save_regs(hw); - - //if (hw->decode_pic_count == 0) - hw->decode_pic_count++; - if ((hw->decode_pic_count & 0xffff) == 0) { - /*make ucode do not handle it as first picture*/ - hw->decode_pic_count++; - } - } - hw->dec_result = DEC_RESULT_DONE; - - debug_print(hw, PRINT_FLAG_ERROR, - "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n", - __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(AVS_SOS_COUNT)); - reset_process_time(hw); - vdec_schedule_work(&hw->work); - } - } - - if ((hw->ucode_pause_pos != 0) && - (hw->ucode_pause_pos != 0xffffffff) && - udebug_pause_pos != hw->ucode_pause_pos) { - hw->ucode_pause_pos = 0; - WRITE_VREG(DEBUG_REG1, 0); - } - - if (vdec->next_status == VDEC_STATUS_DISCONNECTED) { - hw->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&hw->work); - pr_info("vdec requested to be disconnected\n"); - return; - } - - mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); -} - -static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw) -{ - /*int r = 0;*/ - vavs_prot_init(hw); - - return 0; -} - -static unsigned char get_data_check_sum - (struct vdec_avs_hw_s *hw, int size) -{ - int jj; - int sum = 0; - u8 *data = NULL; - - if (!hw->chunk->block->is_mapped) - data = codec_mm_vmap(hw->chunk->block->start + - hw->chunk->offset, size); - else - data = ((u8 *)hw->chunk->block->start_virt) + - hw->chunk->offset; - - for (jj = 0; jj < size; jj++) - sum += data[jj]; - - if (!hw->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); - return sum; -} - -static void run(struct vdec_s *vdec, unsigned long mask, -void (*callback)(struct vdec_s *, void *), - void *arg) -{ - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)vdec->private; - int save_reg; - int size, ret; - if (!hw->vdec_pg_enable_flag) { - hw->vdec_pg_enable_flag = 1; - amvdec_enable(); - } - save_reg = READ_VREG(POWER_CTL_VLD); - /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/ - debug_print(hw, PRINT_FLAG_RUN_FLOW,"run in\n"); - if (vdec_stream_based(vdec)) { - hw->pre_parser_wr_ptr = - STBUF_READ(&vdec->vbuf, get_wp); - } -#if 1 -#if DEBUG_MULTI_FLAG > 0 - if (hw->decode_pic_count == 0) { -#endif - WRITE_VREG(DOS_SW_RESET0, 0xfffffff0); - WRITE_VREG(DOS_SW_RESET0, 0); - WRITE_VREG(POWER_CTL_VLD, save_reg); - hw->run_count++; - run_count[DECODE_ID(hw)] = hw->run_count; - vdec_reset_core(vdec); -#if DEBUG_MULTI_FLAG > 0 - } -#endif -#else - vdec_reset_core(vdec); -#endif - hw->vdec_cb_arg = arg; - hw->vdec_cb = callback; - - size = vdec_prepare_input(vdec, &hw->chunk); - if (debug & DEBUG_FLAG_PREPARE_MORE_INPUT) { - if (size < start_decode_buf_level) { - /*debug_print(hw, PRINT_FLAG_VLD_DETAIL, - "DEC_RESULT_AGAIN %x %x %x\n", - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP));*/ - - hw->input_empty++; - hw->dec_result = DEC_RESULT_AGAIN; - vdec_schedule_work(&hw->work); - return; - } - } else { - if (size < 0) { - hw->input_empty++; - hw->dec_result = DEC_RESULT_AGAIN; - vdec_schedule_work(&hw->work); - return; - } - } - if (input_frame_based(vdec)) { - u8 *data = NULL; - - if (!hw->chunk->block->is_mapped) - data = codec_mm_vmap(hw->chunk->block->start + - hw->chunk->offset, size); - else - data = ((u8 *)hw->chunk->block->start_virt) + - hw->chunk->offset; - - if (debug & PRINT_FLAG_RUN_FLOW - ) { - debug_print(hw, 0, - "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", - __func__, hw->decode_pic_count, - hw->buf_recycle_status, - size, get_data_check_sum(hw, size), - data[0], data[1], data[2], data[3], - data[4], data[5], data[size - 4], - data[size - 3], data[size - 2], - data[size - 1]); - } - if (debug & PRINT_FRAMEBASE_DATA - ) { - int jj; - - for (jj = 0; jj < size; jj++) { - if ((jj & 0xf) == 0) - debug_print(hw, - PRINT_FRAMEBASE_DATA, - "%06x:", jj); - debug_print(hw, - PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - debug_print(hw, - PRINT_FRAMEBASE_DATA, - "\n"); - } - } - - if (!hw->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); - } else - debug_print(hw, PRINT_FLAG_RUN_FLOW, - "%s decode_pic_count %d buf_recycle_status 0x%x: %x %x %x %x %x size 0x%x\n", - __func__, - hw->decode_pic_count, - hw->buf_recycle_status, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - STBUF_READ(&vdec->vbuf, get_rp), - STBUF_READ(&vdec->vbuf, get_wp), - size); - - - hw->input_empty = 0; - debug_print(hw, PRINT_FLAG_RUN_FLOW, - "%s,%d, size=%d\n", __func__, __LINE__, size); - - /*vdec_enable_input(vdec); - need run after VC1_CONTROL_REG is configured - */ - hw->init_flag = 1; - - if (hw->chunk) - debug_print(hw, PRINT_FLAG_RUN_FLOW, - "input chunk offset %d, size %d\n", - hw->chunk->offset, hw->chunk->size); - - hw->dec_result = DEC_RESULT_NONE; - /*vdec->mc_loaded = 0;*/ - if (vdec->mc_loaded) { - /*firmware have load before, - and not changes to another. - ignore reload. - */ - } else { - ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_AVS, "avs_multi", vdec, - 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->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&hw->work); - return; - } - vdec->mc_loaded = 1; - vdec->mc_type = VFORMAT_AVS; - } - 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); - return; - } - - /* - This configureation 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 - */ -#define DISABLE_DBLK_HCMD 0 -#define DISABLE_MC_HCMD 0 - WRITE_VREG(VC1_CONTROL_REG, (DISABLE_DBLK_HCMD<<6) | - (DISABLE_MC_HCMD<<5) | (1 << 7) | (0xc <<8) | (1<<14)); - if (vdec_frame_based(vdec)) { - size = hw->chunk->size + - (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1)); - } - - - vdec_enable_input(vdec); - /**/ - - /*wmb();*/ - hw->stat |= STAT_MC_LOAD; - hw->last_vld_level = 0; - - debug_print(hw, PRINT_FLAG_DECODING, - "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n", - __func__, READ_VREG(AVS_BUFFERIN), - kfifo_len(&hw->recycle_q)); - - WRITE_VREG(VIFF_BIT_CNT, size * 8); - if (hw->reset_decode_flag) - WRITE_VREG(DECODE_STATUS, 0); - else { - recycle_frames(hw); - avs_pts_check_in(hw, - hw->decode_pic_count & 0xffff, - hw->chunk); - - WRITE_VREG(DECODE_STATUS, - (hw->decode_pic_count & 0xffff) | - ((~hw->buf_recycle_status) << 16)); - } - - hw->reset_decode_flag = 0; - //hw->decode_status_skip_pic_done_flag = 0; - start_process_time(hw); -#if DEBUG_MULTI_FLAG == 1 - if (hw->decode_pic_count > 0) - WRITE_VREG(DECODE_STATUS, 0xff); - else -#endif - amvdec_start(); - hw->stat |= STAT_VDEC_RUN; - - hw->stat |= STAT_TIMER_ARM; - - mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); -} - -static void reset(struct vdec_s *vdec) -{ -} - -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; - 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_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) { - debug_print(hw, 1, - "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n", - debug_tag, - READ_VREG(DEBUG_REG2), - buffer_status_debug, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VIFF_BIT_CNT), - READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL)); - - 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_ins_id == 0 || - DECODE_ID(hw) == (udebug_pause_ins_id -1))) { - udebug_pause_pos &= 0xffff; - hw->ucode_pause_pos = udebug_pause_pos; - if (debug & DEBUG_PIC_DONE_WHEN_UCODE_PAUSE) { - hw->decode_pic_count++; - if ((hw->decode_pic_count & 0xffff) == 0) { - /*make ucode do not handle it as first picture*/ - hw->decode_pic_count++; - } - reset_process_time(hw); - hw->dec_result = DEC_RESULT_DONE; - amvdec_stop(); - vavs_save_regs(hw); - debug_print(hw, PRINT_FLAG_DECODING, - "%s ucode pause, force done, decode_pic_count = %d, bit_cnt=0x%x\n", - __func__, - hw->decode_pic_count, - READ_VREG(VIFF_BIT_CNT)); - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } - if (hw->ucode_pause_pos) - reset_process_time(hw); - else - WRITE_VREG(DEBUG_REG1, 0); - return IRQ_HANDLED; - } else { - debug_print(hw, PRINT_FLAG_DECODING, - "%s decode_status 0x%x, buffer_status 0x%x\n", - __func__, - READ_VREG(DECODE_STATUS), - buffer_status_debug); - } - -#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 - -#ifdef ENABLE_USER_DATA - if (UserDataHandler(hw)) - return IRQ_HANDLED; -#endif - reg = READ_VREG(AVS_BUFFEROUT); - if (reg) { - unsigned short decode_pic_count - = READ_VREG(DECODE_PIC_COUNT); - debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n", - reg, decode_pic_count); - 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 (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts, - &frame_size, 0, &pts_us64) == 0) { - pts_valid = 1; -#ifdef DEBUG_PTS - hw->pts_hit++; -#endif - } else { -#ifdef DEBUG_PTS - hw->pts_missed++; -#endif - } - } - } - - repeat_count = READ_VREG(AVS_REPEAT_COUNT); -#ifdef USE_DYNAMIC_BUF_NUM - buffer_index = - ((reg & 0x7) + - (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; -#else - if (firmware_sel == 0) - buffer_index = - ((reg & 0x7) + - (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; - else - buffer_index = - ((reg & 0x7) - 1) & 3; -#endif - 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) - 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); - - 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; - } - 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)) { - vf->pts_us64 = - (((u64)vf->duration << 32) & 0xffffffff00000000) | offset; - vf->pts = 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); - vdec_vframe_ready(vdec, vf); - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->pts_name, vf->timestamp); - 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)) { - 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->timestamp); - 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->timestamp); - 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); - - /* 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; - if (hw->dec_result == DEC_RESULT_DONE || - hw->dec_result == DEC_RESULT_AGAIN) { - debug_print(hw, PRINT_FLAG_DECODING, - "%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", - __func__, status_reg, decode_status, - hw->buf_status, - hw->dec_result, hw->decode_pic_count, - READ_VREG(VIFF_BIT_CNT)); - return IRQ_HANDLED; - } else if (decode_status == DECODE_STATUS_PIC_DONE || - decode_status == DECODE_STATUS_SKIP_PIC_DONE) { - hw->buf_status = (status_reg >> 16) & 0xffff; - if (decode_status == DECODE_STATUS_SKIP_PIC_DONE) { - hw->decode_status_skip_pic_done_flag = 1; - hw->decode_decode_cont_start_code = (status_reg >> 8) & 0xff; - } else - hw->decode_status_skip_pic_done_flag = 0; - hw->decode_pic_count++; - if ((hw->decode_pic_count & 0xffff) == 0) { - /*make ucode do not handle it as first picture*/ - hw->decode_pic_count++; - } - reset_process_time(hw); - hw->dec_result = DEC_RESULT_DONE; -#if DEBUG_MULTI_FLAG == 1 - WRITE_VREG(DECODE_STATUS, 0); -#else - amvdec_stop(); -#endif - vavs_save_regs(hw); - 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", - __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)); - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY || - decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) { - hw->buf_status = (status_reg >> 16) & 0xffff; - reset_process_time(hw); -#if DEBUG_MULTI_FLAG == 1 - WRITE_VREG(DECODE_STATUS, 0); -#else - amvdec_stop(); -#endif - if (vdec_frame_based(hw_to_vdec(hw))) { - hw->dec_result = DEC_RESULT_DONE; - //if (hw->decode_pic_count == 0) { - hw->decode_pic_count++; - //} - if ((hw->decode_pic_count & 0xffff) == 0) { - /*make ucode do not handle it as first picture*/ - hw->decode_pic_count++; - } - vavs_save_regs(hw); - } 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", - __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); - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } - - -#ifdef HANDLE_AVS_IRQ - return IRQ_HANDLED; -#else - return; -#endif -} - -static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq) -{ - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - return IRQ_WAKE_THREAD; - //return vavs_isr(0, hw); - -} - -static void vmavs_dump_state(struct vdec_s *vdec) -{ - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)vdec->private; - int i; - debug_print(hw, 0, - "====== %s\n", __func__); - - debug_print(hw, 0, - "width/height (%d/%d), dur %d\n", - hw->frame_width, - hw->frame_height, - hw->frame_dur - ); - - 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", - vdec_frame_based(vdec), - READ_VREG(DECODE_STATUS) & 0xff, - hw->buf_status, - hw->buf_recycle_status, - hw->throw_pb_flag, - hw->eos, - hw->stat, - hw->dec_result, - hw->decode_pic_count, - hw->display_frame_count, - hw->run_count, - hw->not_run_ready, - hw->input_empty - ); - - if (vf_get_receiver(vdec->vf_provider_name)) { - enum receviver_start_e state = - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_QUREY_STATE, - NULL); - debug_print(hw, 0, - "\nreceiver(%s) state %d\n", - vdec->vf_provider_name, - state); - } - - debug_print(hw, 0, - "%s, newq(%d/%d), dispq(%d/%d)recycleq(%d/%d) drop %d vf peek %d, prepare/get/put (%d/%d/%d)\n", - __func__, - kfifo_len(&hw->newframe_q), - VF_POOL_SIZE, - kfifo_len(&hw->display_q), - VF_POOL_SIZE, - kfifo_len(&hw->recycle_q), - VF_POOL_SIZE, - hw->drop_frame_count, - hw->peek_num, - hw->prepare_num, - hw->get_num, - hw->put_num - ); - - debug_print(hw, 0, "vfbuf_use:\n"); - 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, - "DECODE_STATUS=0x%x\n", - READ_VREG(DECODE_STATUS)); - debug_print(hw, 0, - "MPC_E=0x%x\n", - READ_VREG(MPC_E)); - debug_print(hw, 0, - "DECODE_MODE=0x%x\n", - READ_VREG(DECODE_MODE)); - debug_print(hw, 0, - "wait_buf_status, AV_SCRATCH_5=0x%x\n", - READ_VREG(AV_SCRATCH_5)); - debug_print(hw, 0, - "MBY_MBX=0x%x\n", - READ_VREG(MBY_MBX)); - debug_print(hw, 0, - "VIFF_BIT_CNT=0x%x\n", - READ_VREG(VIFF_BIT_CNT)); - debug_print(hw, 0, - "VLD_MEM_VIFIFO_LEVEL=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - debug_print(hw, 0, - "VLD_MEM_VIFIFO_WP=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_WP)); - debug_print(hw, 0, - "VLD_MEM_VIFIFO_RP=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - debug_print(hw, 0, - "PARSER_VIDEO_RP=0x%x\n", - STBUF_READ(&vdec->vbuf, get_rp)); - debug_print(hw, 0, - "PARSER_VIDEO_WP=0x%x\n", - STBUF_READ(&vdec->vbuf, get_wp)); - - if (vdec_frame_based(vdec) && - (debug & PRINT_FRAMEBASE_DATA) - ) { - int jj; - if (hw->chunk && hw->chunk->block && - hw->chunk->size > 0) { - u8 *data = NULL; - - if (!hw->chunk->block->is_mapped) - data = codec_mm_vmap(hw->chunk->block->start + - hw->chunk->offset, hw->chunk->size); - else - data = ((u8 *)hw->chunk->block->start_virt) - + hw->chunk->offset; - - debug_print(hw, 0, - "frame data size 0x%x\n", - hw->chunk->size); - for (jj = 0; jj < hw->chunk->size; jj++) { - if ((jj & 0xf) == 0) - debug_print(hw, - PRINT_FRAMEBASE_DATA, - "%06x:", jj); - debug_print_cont(hw, - PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - debug_print_cont(hw, - PRINT_FRAMEBASE_DATA, - "\n"); - } - - if (!hw->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); - } - } - -} - - int ammvdec_avs_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct vdec_avs_hw_s *hw = NULL; - int r = 0; - - if (vdec_get_debug_flags() & 0x8) - return amvdec_avs_probe(pdev); - - pr_info("ammvdec_avs probe start.\n"); - - if (pdata == NULL) { - pr_info("ammvdec_avs platform data undefined.\n"); - return -EFAULT; - } - - hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s)); - if (hw == NULL) { - pr_info("\nammvdec_avs decoder driver alloc failed\n"); - return -ENOMEM; - } - /*atomic_set(&hw->error_handler_run, 0);*/ - hw->m_ins_flag = 1; - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) - firmware_sel = 1; - - if (firmware_sel == 1) { -#ifndef USE_DYNAMIC_BUF_NUM - vf_buf_num = 4; -#endif - canvas_base = 0; - canvas_num = 3; - } else { - pr_info("Error, do not support longcabac work around!!!"); - r = -ENOMEM; - goto error1; - } - - if (pdata->sys_info) - hw->vavs_amstream_dec_info = *pdata->sys_info; - - hw->is_reset = 0; - pdata->user_data_read = NULL; - pdata->reset_userdata_fifo = NULL; - - pdata->private = hw; - pdata->dec_status = vavs_dec_status; - pdata->set_isreset = vavs_set_isreset; - pdata->run_ready = run_ready; - pdata->run = run; - pdata->reset = reset; - pdata->irq_handler = vmavs_isr; - pdata->threaded_irq_handler = vmavs_isr_thread_fn; - pdata->dump_state = vmavs_dump_state; - - snprintf(hw->vdec_name, sizeof(hw->vdec_name), - "avs-%d", pdev->id); - snprintf(hw->pts_name, sizeof(hw->pts_name), - "%s-timestamp", hw->vdec_name); - snprintf(hw->new_q_name, sizeof(hw->new_q_name), - "%s-newframe_q", hw->vdec_name); - snprintf(hw->disp_q_name, sizeof(hw->disp_q_name), - "%s-dispframe_q", hw->vdec_name); - - vavs_vdec_info_init(hw); - -#ifdef ENABLE_USER_DATA - if (NULL == hw->user_data_buffer) { - hw->user_data_buffer = - dma_alloc_coherent(amports_get_dma_device(), - USER_DATA_SIZE, - &hw->user_data_buffer_phys, GFP_KERNEL); - if (!hw->user_data_buffer) { - pr_info("%s: Can not allocate hw->user_data_buffer\n", - __func__); - r = -ENOMEM; - goto error2; - } - pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", - hw->user_data_buffer, (u32)hw->user_data_buffer_phys); - } -#endif - /*hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); - if (hw->lmem_addr == NULL) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - return -1; - } - hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), - hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hw->lmem_phy_addr)) { - pr_err("%s: failed to map lmem buffer\n", __func__); - kfree(hw->lmem_addr); - hw->lmem_addr = NULL; - 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); - if (hw->lmem_addr == 0) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - r = -1; - goto error3; - } - - if (vavs_init(hw) < 0) { - pr_info("amvdec_avs init failed.\n"); - r = -ENODEV; - goto error4; - } - - /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); - atomic_set(&hw->error_handler_run, 0);*/ -#if 0 -#ifdef ENABLE_USER_DATA - INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); -#endif -#endif - INIT_WORK(&hw->notify_work, vavs_notify_work); - - if (pdata->use_vfm_path) { - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - hw->frameinfo_enable = 1; - } - else - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); - if (pdata->parallel_dec == 1) { - int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - hw->canvas_spec[i] = 0xffffff; - } - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vavs_vf_provider, hw); - - platform_set_drvdata(pdev, pdata); - - hw->platform_dev = pdev; - - vdec_set_prepare_level(pdata, start_decode_buf_level); - - vdec_set_vframe_comm(pdata, DRIVER_NAME); - - if (pdata->parallel_dec == 1) - vdec_core_request(pdata, CORE_MASK_VDEC_1); - else { - vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC - | CORE_MASK_COMBINE); - } - - /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ - - return 0; - -error4: - dma_free_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, (void *)hw->lmem_addr, - hw->lmem_phy_addr); -error3: - dma_free_coherent( - amports_get_dma_device(), - USER_DATA_SIZE, - hw->user_data_buffer, - hw->user_data_buffer_phys); -error2: - kfree(hw->gvs); - hw->gvs = NULL; - pdata->dec_status = NULL; -error1: - vfree(hw); - return r; -} - - int ammvdec_avs_remove(struct platform_device *pdev) -{ - - if (vdec_get_debug_flags() & 0x8) - return amvdec_avs_remove(pdev); - else { - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - struct vdec_s *vdec = hw_to_vdec(hw); - int i; - - if (hw->stat & STAT_VDEC_RUN) { - amvdec_stop(); - hw->stat &= ~STAT_VDEC_RUN; - } - - if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)hw); - hw->stat &= ~STAT_ISR_REG; - } - - if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->check_timer); - hw->stat &= ~STAT_TIMER_ARM; - } - - cancel_work_sync(&hw->work); - cancel_work_sync(&hw->notify_work); - - if (hw->mm_blk_handle) { - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } - if (vdec->parallel_dec == 1) - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); - else - vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); - - if (vdec->parallel_dec == 1) { - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); - vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); - } - } - #ifdef ENABLE_USER_DATA - if (hw->user_data_buffer != NULL) { - dma_free_coherent( - amports_get_dma_device(), - USER_DATA_SIZE, - hw->user_data_buffer, - hw->user_data_buffer_phys); - hw->user_data_buffer = NULL; - hw->user_data_buffer_phys = 0; - } - #endif - /*if (hw->lmem_addr) { - dma_unmap_single(amports_get_dma_device(), - hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - kfree(hw->lmem_addr); - hw->lmem_addr = NULL; - }*/ - if (hw->lmem_addr) { - dma_free_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, (void *)hw->lmem_addr, - hw->lmem_phy_addr); - hw->lmem_addr = 0; - } - - if (hw->fw) { - vfree(hw->fw); - hw->fw = NULL; - } - - pr_info("ammvdec_avs removed.\n"); - if (hw->gvs) { - kfree(hw->gvs); - hw->gvs = NULL; - } - - vfree(hw); - return 0; - } -} - - -#ifdef DEBUG_MULTI_WITH_AUTOMODE -struct stream_buf_s *get_vbuf(void); -s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec); - - -static s32 vavs_init2(struct vdec_avs_hw_s *hw) -{ - int size = -1; - struct firmware_s *fw; - u32 fw_size = 0x1000 * 16; - - fw = vmalloc(sizeof(struct firmware_s) + fw_size); - if (IS_ERR_OR_NULL(fw)) - return -ENOMEM; - - pr_info("vavs_init\n"); - - amvdec_enable(); - - - vavs_local_init(hw); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) - size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); - else { - if (firmware_sel == 1) - size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); -#ifdef AVSP_LONG_CABAC - else { - init_avsp_long_cabac_buf(); - size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); - } -#endif - } - - if (size < 0) { - amvdec_disable(); - pr_err("get firmware fail."); - /*vfree(buf);*/ - return -1; - } - - fw->len = size; - hw->fw = fw; - if (hw->m_ins_flag) { - 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); - - hw->fw = fw; - } - return 0; -} - -unsigned int debug_flag2; -static int vavs_prot_init2(struct vdec_avs_hw_s *hw, unsigned char post_flag) -{ - int r = 0; - /* - * 2: assist - * 3: vld_reset - * 4: vld_part_reset - * 5: vfifo reset - * 6: iqidct - * 7: mc - * 8: dblk - * 9: pic_dc - * 10: psc - * 11: mcpu - * 12: ccpu - * 13: ddr - * 14: afifo - */ - unsigned char run_flag; -#ifdef OOO - 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); -#endif - /***************** reset vld **********************************/ -#ifdef OOO - 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); -#endif - if (start_decoding_delay & 0x80000) - msleep(start_decoding_delay&0xffff); - -if (debug_flag2 & 0x1) - run_flag = post_flag; -else - run_flag = !post_flag; -if (run_flag) { - if (hw->m_ins_flag) { - int i; - if (hw->decode_pic_count == 0) { - r = vavs_canvas_init(hw); -#ifndef USE_DYNAMIC_BUF_NUM - for (i = 0; i < 4; i++) { - WRITE_VREG(AV_SCRATCH_0 + i, - hw->canvas_spec[i] - ); - } -#else - for (i = 0; i < hw->vf_buf_num_used; i += 2) { - WRITE_VREG(buf_spec_reg[i >> 1], - (hw->canvas_spec[i] & 0xffff) | - ((hw->canvas_spec[i + 1] & 0xffff) - << 16) - ); - } -#endif - } else - 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); - - 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); - } - } -} - -if (debug_flag2 & 0x2) - run_flag = post_flag; -else - run_flag = !post_flag; -if (run_flag) { - - /* notify ucode the buffer offset */ - if (hw->decode_pic_count == 0) - WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); -#ifdef OOO - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); -#endif - } - if (start_decoding_delay & 0x40000) - msleep(start_decoding_delay&0xffff); - - if (debug_flag2 & 0x4) - run_flag = post_flag; - else - run_flag = !post_flag; - if (run_flag) { - if (hw->decode_pic_count == 0) { -#ifndef USE_DYNAMIC_BUF_NUM - WRITE_VREG(AVS_SOS_COUNT, 0); -#endif - 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 (debug_flag2 & 0x8) - run_flag = post_flag; -else - run_flag = !post_flag; -if (run_flag) { - -#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ - if (hw->decode_pic_count == 0) - WRITE_VREG(AV_SCRATCH_D, 0); -#endif - if (start_decoding_delay & 0x10000) - msleep(start_decoding_delay&0xffff); -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - /* V4L2_PIX_FMT_NV21 V4L2_PIX_FMT_NV21M */ - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - - if (start_decoding_delay & 0x20000) - msleep(start_decoding_delay&0xffff); - - -#ifdef PIC_DC_NEED_CLEAR - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); -#endif -} -if (debug_flag2 & 0x10) - run_flag = post_flag; -else - run_flag = !post_flag; -if (run_flag) { -#ifdef ENABLE_USER_DATA - if (firmware_sel == 0) { - pr_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! firmware_sel is 0\n"); - WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); - pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); - } -#endif -} - -if (debug_flag2 & 0x20) - run_flag = post_flag; -else - run_flag = !post_flag; -if (run_flag) { - if (hw->m_ins_flag) { - if (vdec_frame_based(hw_to_vdec(hw))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); - WRITE_VREG(DECODE_LMEM_BUF_ADR, (u32)hw->lmem_phy_addr); - } else - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(DECODE_STOP_POS, udebug_flag); - hw->old_udebug_flag = udebug_flag; -} - return r; -} - -static void init_hw(struct vdec_s *vdec) -{ - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)vdec->private; - int ret; - pr_info("%s, %d\n", __func__, __LINE__); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) - ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); - else if (firmware_sel == 1) - ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", hw->fw->data); - else - ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); - - if (ret < 0) { - amvdec_disable(); - /*vfree(buf);*/ - pr_err("AVS: the %s fw loading failed, err: %x\n", - tee_enabled() ? "TEE" : "local", ret); - } - pr_info("%s, %d\n", __func__, __LINE__); - - /*vfree(buf);*/ - - hw->stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - ret = vavs_prot_init2(hw, 0); - if (ret < 0) - return; - pr_info("%s, %d\n", __func__, __LINE__); - -} - - -static unsigned long run_ready2(struct vdec_s *vdec, unsigned long mask) -{ - return 1; -} - -static void run2(struct vdec_s *vdec, unsigned long mask, -void (*callback)(struct vdec_s *, void *), - void *arg) -{ - struct vdec_avs_hw_s *hw = - (struct vdec_avs_hw_s *)vdec->private; - pr_info("%s, %d\n", __func__, __LINE__); - - vavs_prot_init2(hw, 1); - - vdec_source_changed(VFORMAT_AVS, - 1920, 1080, 30); - - amvdec_start(); - - hw->stat |= STAT_VDEC_RUN; - pr_info("%s %d\n", __func__, __LINE__); - -} - -static int ammvdec_avs_probe2(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct vdec_avs_hw_s *hw = NULL; - - pr_info("ammvdec_avs probe start.\n"); - - if (pdata == NULL) { - pr_info("ammvdec_avs platform data undefined.\n"); - return -EFAULT; - } - pr_info("%s %d\n", __func__, __LINE__); - - hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s)); - if (hw == NULL) { - pr_info("\nammvdec_avs decoder driver alloc failed\n"); - return -ENOMEM; - } - pr_info("%s %d\n", __func__, __LINE__); - /*atomic_set(&hw->error_handler_run, 0);*/ - hw->m_ins_flag = 1; - pr_info("%s %d\n", __func__, __LINE__); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) - firmware_sel = 1; - pr_info("%s %d\n", __func__, __LINE__); - - if (firmware_sel == 1) { -#ifndef USE_DYNAMIC_BUF_NUM - vf_buf_num = 4; -#endif - canvas_base = 0; - canvas_num = 3; - } else { - pr_info("Error, do not support longcabac work around!!!"); - return -ENOMEM; - } - pr_info("%s %d\n", __func__, __LINE__); - - if (pdata->sys_info) - hw->vavs_amstream_dec_info = *pdata->sys_info; - pr_info("%s %d\n", __func__, __LINE__); - - hw->is_reset = 0; - pdata->user_data_read = NULL; - pdata->reset_userdata_fifo = NULL; - - pr_info("%s %d\n", __func__, __LINE__); - - pdata->private = hw; - pdata->dec_status = vavs_dec_status; - pdata->set_isreset = vavs_set_isreset; - pdata->run_ready = run_ready2; - pdata->run = run2; - pdata->reset = reset; - pdata->irq_handler = vmavs_isr; - pdata->threaded_irq_handler = vmavs_isr_thread_fn; - pdata->dump_state = vmavs_dump_state; - - pr_info("%s %d\n", __func__, __LINE__); - - vavs_vdec_info_init(hw); - - pr_info("%s %d\n", __func__, __LINE__); - -#ifdef ENABLE_USER_DATA - if (NULL == hw->user_data_buffer) { - hw->user_data_buffer = - dma_alloc_coherent(amports_get_dma_device(), - USER_DATA_SIZE, - &hw->user_data_buffer_phys, GFP_KERNEL); - if (!hw->user_data_buffer) { - pr_info("%s: Can not allocate hw->user_data_buffer\n", - __func__); - return -ENOMEM; - } - pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", - hw->user_data_buffer, (u32)hw->user_data_buffer_phys); - } -#endif - hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); - if (hw->lmem_addr == NULL) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - return -1; - } - hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), - hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hw->lmem_phy_addr)) { - pr_err("%s: failed to map lmem buffer\n", __func__); - kfree(hw->lmem_addr); - hw->lmem_addr = NULL; - return -1; - } - - pr_info("%s %d\n", __func__, __LINE__); - - /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/ - - pr_info("%s %d\n", __func__, __LINE__); - - if (vavs_init2(hw) < 0) { - pr_info("amvdec_avs init failed.\n"); - kfree(hw->gvs); - hw->gvs = NULL; - pdata->dec_status = NULL; - return -ENODEV; - } - /*vdec = pdata;*/ - pr_info("%s, %d\n", __func__, __LINE__); - -if (hw->m_ins_flag) { - INIT_WORK(&hw->notify_work, vavs_notify_work); -#if 1 - if (pdata->use_vfm_path) { - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - hw->frameinfo_enable = 1; - } - else - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); - if (pdata->parallel_dec == 1) { - int i; - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - hw->canvas_spec[i] = 0xffffff; - } - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vavs_vf_provider, hw); - - platform_set_drvdata(pdev, pdata); - - hw->platform_dev = pdev; - - vdec_set_prepare_level(pdata, start_decode_buf_level); - - if (pdata->parallel_dec == 1) - vdec_core_request(pdata, CORE_MASK_VDEC_1); - else { - vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC - | CORE_MASK_COMBINE); - } - pr_info("%s, %d\n", __func__, __LINE__); -#endif -}else{ - /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); - atomic_set(&hw->error_handler_run, 0);*/ -#ifdef ENABLE_USER_DATA - INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); -#endif - INIT_WORK(&hw->notify_work, vavs_notify_work); -} - - init_hw(pdata); - return 0; -} - -static int ammvdec_avs_remove2(struct platform_device *pdev) -{ - struct vdec_avs_hw_s *hw = ghw; - - cancel_work_sync(&hw->fatal_error_wd_work); - atomic_set(&hw->error_handler_run, 0); -#ifdef ENABLE_USER_DATA - cancel_work_sync(&hw->userdata_push_work); -#endif - cancel_work_sync(&hw->notify_work); - cancel_work_sync(&hw->set_clk_work); - if (hw->stat & STAT_VDEC_RUN) { - amvdec_stop(); - hw->stat &= ~STAT_VDEC_RUN; - } - - if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); - hw->stat &= ~STAT_ISR_REG; - } - - if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->recycle_timer); - hw->stat &= ~STAT_TIMER_ARM; - } -#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 (hw->stat & STAT_VF_HOOK) { - if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) - avs_vf_notify_receiver(hw, PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - hw->fr_hint_status = VDEC_NO_NEED_HINT; - vf_unreg_provider(&vavs_vf_prov); - hw->stat &= ~STAT_VF_HOOK; - } - -#ifdef ENABLE_USER_DATA - if (hw->user_data_buffer != NULL) { - dma_free_coherent( - amports_get_dma_device(), - USER_DATA_SIZE, - hw->user_data_buffer, - hw->user_data_buffer_phys); - hw->user_data_buffer = NULL; - hw->user_data_buffer_phys = 0; - } -#endif - - if (hw->fw) { - vfree(hw->fw); - hw->fw = NULL; - } - - amvdec_disable(); - /*vdec_disable_DMC(NULL);*/ - - hw->pic_type = 0; - if (hw->mm_blk_handle) { - decoder_bmmu_box_free(hw->mm_blk_handle); - hw->mm_blk_handle = NULL; - } -#ifdef DEBUG_PTS - pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, - hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); - pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, - hw->vavs_amstream_dec_info.rate); -#endif - kfree(hw->gvs); - hw->gvs = NULL; - vfree(hw); - return 0; -} -#endif - -static struct platform_driver ammvdec_avs_driver = { -#ifdef DEBUG_MULTI_WITH_AUTOMODE - .probe = ammvdec_avs_probe2, - .remove = ammvdec_avs_remove2, -#else - .probe = ammvdec_avs_probe, - .remove = ammvdec_avs_remove, -#endif -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif - .driver = { - .name = MULTI_DRIVER_NAME, - } -}; - -static struct codec_profile_t ammvdec_avs_profile = { - .name = "AVS-V4L", - .profile = "" -}; - -static struct mconfig mavs_configs[] = { - /*MC_PU32("stat", &stat), - MC_PU32("debug_flag", &debug_flag), - MC_PU32("error_recovery_mode", &error_recovery_mode), - MC_PU32("hw->pic_type", &hw->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 mavs_node; - - -static int __init ammvdec_avs_driver_init_module(void) -{ - pr_debug("ammvdec_avs module init\n"); - - if (platform_driver_register(&ammvdec_avs_driver)) { - pr_err("failed to register ammvdec_avs driver\n"); - return -ENODEV; - } - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) - ammvdec_avs_profile.profile = "mavs+"; - - vcodec_profile_register(&ammvdec_avs_profile); - INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node, - "mavs-v4l", mavs_configs, CONFIG_FOR_RW); - vcodec_feature_register(VFORMAT_AVS, 1); - return 0; -} - - - -static void __exit ammvdec_avs_driver_remove_module(void) -{ - pr_debug("ammvdec_avs module remove.\n"); - - platform_driver_unregister(&ammvdec_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(step, uint, 0664); -MODULE_PARM_DESC(step, "\n step\n"); - -module_param(debug, uint, 0664); -MODULE_PARM_DESC(debug, "\n debug\n"); - -module_param(debug_mask, uint, 0664); -MODULE_PARM_DESC(debug_mask, "\n debug_mask\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(dbg_cmd, uint, 0664); -MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\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(start_decode_buf_level, int, 0664); -MODULE_PARM_DESC(start_decode_buf_level, - "\n avs start_decode_buf_level\n"); - -module_param(decode_timeout_val, uint, 0664); -MODULE_PARM_DESC(decode_timeout_val, - "\n avs decode_timeout_val\n"); - -module_param(error_handle_policy, uint, 0664); -MODULE_PARM_DESC(error_handle_policy, - "\n avs error_handle_policy\n"); - -module_param(again_threshold, uint, 0664); -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_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(udebug_pause_ins_id, uint, 0664); -MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n"); - -module_param(start_decoding_delay, uint, 0664); -MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n"); - -module_param(pre_decode_buf_level, int, 0664); -MODULE_PARM_DESC(pre_decode_buf_level, - "\n ammvdec_mavs pre_decode_buf_level\n"); - - -#ifdef DEBUG_MULTI_WITH_AUTOMODE -module_param(debug_flag2, uint, 0664); -MODULE_PARM_DESC(debug_flag2, "\n debug_flag2\n"); -#endif -module_param(force_fps, uint, 0664); -MODULE_PARM_DESC(force_fps, "\n force_fps\n"); - -#ifdef DEBUG_MULTI_FRAME_INS -module_param(delay, uint, 0664); -MODULE_PARM_DESC(delay, "\n delay\n"); - -module_param_array(max_run_count, uint, &max_decode_instance_num, 0664); - -#endif - -module_param_array(ins_udebug_flag, 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(max_get_frame_interval, uint, - &max_decode_instance_num, 0664); - - -module_init(ammvdec_avs_driver_init_module); -module_exit(ammvdec_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_v4l/avs_multi/avs_multi.h b/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.h deleted file mode 100644 index 8922b40..0000000 --- a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.h +++ /dev/null
@@ -1,90 +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_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_v4l/h264_multi/Makefile b/drivers/frame_provider/decoder_v4l/h264_multi/Makefile deleted file mode 100644 index 48f2c5a..0000000 --- a/drivers/frame_provider/decoder_v4l/h264_multi/Makefile +++ /dev/null
@@ -1,2 +0,0 @@ -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI) += amvdec_mh264_v4l.o -amvdec_mh264_v4l-objs += vmh264.o h264_dpb.o
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c deleted file mode 100644 index 8ab097e..0000000 --- a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c +++ /dev/null
@@ -1,6036 +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: -*/ -#define DEBUG -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../decoder/utils/vdec.h" -#include "../../decoder/utils/amvdec.h" - -#include "h264_dpb.h" - -#define FRAME_NUM_MAX_SIZE 0x10000 - -#undef pr_info -#define pr_info printk -int dpb_print(int index, int debug_flag, const char *fmt, ...) -{ - if (((h264_debug_flag & debug_flag) && - ((1 << index) & h264_debug_mask)) - || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); - int len = 0; - va_list args; - - if (!buf) - return 0; - - va_start(args, fmt); - len = sprintf(buf, "%d: ", index); - vsnprintf(buf + len, 512-len, fmt, args); - pr_debug("%s", buf); - va_end(args); - kfree(buf); - } - return 0; -} - -int dpb_print_cont(int index, int debug_flag, const char *fmt, ...) -{ - if (((h264_debug_flag & debug_flag) && - ((1 << index) & h264_debug_mask)) - || (debug_flag == PRINT_FLAG_ERROR)) { - unsigned char *buf = kzalloc(512, GFP_ATOMIC); - int len = 0; - va_list args; - - if (!buf) - return 0; - - va_start(args, fmt); - vsnprintf(buf + len, 512-len, fmt, args); - pr_info("%s", buf); - va_end(args); - kfree(buf); - } - return 0; -} - -unsigned char dpb_is_debug(int index, int debug_flag) -{ - if (((h264_debug_flag & debug_flag) && - ((1 << index) & h264_debug_mask)) - || (debug_flag == PRINT_FLAG_ERROR)) - return 1; - return 0; -} - -#define CHECK_VALID(list_size, mark) {\ - if (list_size > MAX_LIST_SIZE || list_size < 0) { \ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_ERROR, \ - "%s(%d): listXsize[%d] %d is larger than max size\r\n",\ - __func__, __LINE__, mark, list_size);\ - list_size = 0; \ - p_H264_Dpb->dpb_error_flag = __LINE__;\ - } \ - } - -static struct DecRefPicMarking_s - dummy_dec_ref_pic_marking_buffer - [DEC_REF_PIC_MARKING_BUFFER_NUM_MAX]; -static struct StorablePicture dummy_pic; -static struct FrameStore dummy_fs; -static struct StorablePicture *get_new_pic( - struct h264_dpb_stru *p_H264_Dpb, - enum PictureStructure structure, unsigned char is_output); - - -static void init_dummy_fs(void) -{ - dummy_fs.frame = &dummy_pic; - dummy_fs.top_field = &dummy_pic; - dummy_fs.bottom_field = &dummy_pic; - - dummy_pic.top_field = &dummy_pic; - dummy_pic.bottom_field = &dummy_pic; - dummy_pic.frame = &dummy_pic; - - dummy_pic.dec_ref_pic_marking_buffer = - &dummy_dec_ref_pic_marking_buffer[0]; -} - -enum { - LIST_0 = 0, - LIST_1 = 1, - BI_PRED = 2, - BI_PRED_L0 = 3, - BI_PRED_L1 = 4 -}; - -void ref_pic_list_reordering(struct h264_dpb_stru *p_H264_Dpb, - struct Slice *currSlice) -{ - /* struct VideoParameters *p_Vid = currSlice->p_Vid; - * byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; - * DataPartition *partition = &(currSlice->partArr[dP_nr]); - * Bitstream *currStream = partition->bitstream; - */ - int i, j, val; - unsigned short *reorder_cmd = - &p_H264_Dpb->dpb_param.mmco.l0_reorder_cmd[0]; - /* alloc_ref_pic_list_reordering_buffer(currSlice); */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - if (currSlice->slice_type != I_SLICE && - currSlice->slice_type != SI_SLICE) { - /* val = currSlice->ref_pic_list_reordering_flag[LIST_0] = - * read_u_1 ("SH: ref_pic_list_reordering_flag_l0", - * currStream, &p_Dec->UsedBits); - */ - if (reorder_cmd[0] != 3) { - val = currSlice-> - ref_pic_list_reordering_flag[LIST_0] = 1; - } else { - val = currSlice-> - ref_pic_list_reordering_flag[LIST_0] = 0; - } - if (val) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%s, ref_pic_list_reordering_flag[LIST_0] is 1\n", - __func__); - - j = 0; - i = 0; - do { - val = currSlice-> - modification_of_pic_nums_idc[LIST_0][i] = - reorder_cmd[j++]; - /* read_ue_v( - * "SH: modification_of_pic_nums_idc_l0", - * currStream, &p_Dec->UsedBits); - */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%d(%d):val %x\n", i, j, val); - if (j >= 66) { - currSlice-> - ref_pic_list_reordering_flag[LIST_0] = - 0; /* by rain */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s error\n", __func__); - break; - } - if (val == 0 || val == 1) { - currSlice-> - abs_diff_pic_num_minus1[LIST_0][i] = - reorder_cmd[j++]; - /* read_ue_v("SH: " - *"abs_diff_pic_num_minus1_l0", - *currStream, &p_Dec->UsedBits); - */ - } else { - if (val == 2) { - currSlice-> - long_term_pic_idx[LIST_0][i] = - reorder_cmd[j++]; - /* read_ue_v( - *"SH: long_term_pic_idx_l0", - *currStream, - *&p_Dec->UsedBits); - */ - } - } - i++; - /* assert (i>currSlice-> - * num_ref_idx_active[LIST_0]); - */ - if ( - -/* - * i>currSlice->num_ref_idx_active[LIST_0] || - */ - i >= REORDERING_COMMAND_MAX_SIZE) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%s error %d %d\n", - __func__, i, - currSlice-> - num_ref_idx_active[LIST_0]); - currSlice-> - ref_pic_list_reordering_flag[LIST_0] = - 0; /* by rain */ - break; - } - if (j >= 66) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, "%s error\n", - __func__); - currSlice-> - ref_pic_list_reordering_flag[LIST_0] = - 0; /* by rain */ - break; - } - - } while (val != 3); - } - } - - if (currSlice->slice_type == B_SLICE) { - reorder_cmd = &p_H264_Dpb->dpb_param.mmco.l1_reorder_cmd[0]; - /* val = currSlice->ref_pic_list_reordering_flag[LIST_1] - *= read_u_1 ("SH: ref_pic_list_reordering_flag_l1", - *currStream, - *&p_Dec->UsedBits); - */ - - if (reorder_cmd[0] != 3) { - val = - currSlice->ref_pic_list_reordering_flag[LIST_1] = 1; - } else { - val = - currSlice->ref_pic_list_reordering_flag[LIST_1] = 0; - } - - if (val) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%s, ref_pic_list_reordering_flag[LIST_1] is 1\n", - __func__); - - j = 0; - i = 0; - do { - val = currSlice-> - modification_of_pic_nums_idc[LIST_1][i] = - reorder_cmd[j++]; - /* read_ue_v( - *"SH: modification_of_pic_nums_idc_l1", - *currStream, - *&p_Dec->UsedBits); - */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%d(%d):val %x\n", - i, j, val); - if (j >= 66) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, "%s error\n", - __func__); - currSlice-> - ref_pic_list_reordering_flag[LIST_1] = - 0; /* by rain */ - break; - } - if (val == 0 || val == 1) { - currSlice-> - abs_diff_pic_num_minus1[LIST_1][i] = - reorder_cmd[j++]; - /* read_ue_v( - *"SH: abs_diff_pic_num_minus1_l1", - *currStream, &p_Dec->UsedBits); - */ - } else { - if (val == 2) { - currSlice-> - long_term_pic_idx[LIST_1][i] = - reorder_cmd[j++]; - /* read_ue_v( - *"SH: long_term_pic_idx_l1", - *currStream, - *&p_Dec->UsedBits); - */ - } - } - i++; - /* assert(i>currSlice-> - * num_ref_idx_active[LIST_1]); - */ - if ( - /*i>currSlice->num_ref_idx_active[LIST_1] || */ - i >= REORDERING_COMMAND_MAX_SIZE) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%s error %d %d\n", - __func__, i, - currSlice-> - num_ref_idx_active[LIST_0]); - currSlice-> - ref_pic_list_reordering_flag[LIST_1] = - 0; /* by rain */ - break; - } - if (j >= 66) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s error\n", __func__); - break; - } - } while (val != 3); - } - } - - /* set reference index of redundant slices. */ - /* - *if (currSlice->redundant_pic_cnt && - *(currSlice->slice_type != I_SLICE)) - *{ - * currSlice->redundant_slice_ref_idx = - * currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1; - *} - */ -} - -void slice_prepare(struct h264_dpb_stru *p_H264_Dpb, - struct DecodedPictureBuffer *p_Dpb, - struct VideoParameters *p_Vid, - struct SPSParameters *sps, struct Slice *pSlice) -{ - int i, j; - /* p_Vid->active_sps = sps; */ - unsigned short *mmco_cmd = &p_H264_Dpb->dpb_param.mmco.mmco_cmd[0]; - /* for decode_poc */ - sps->pic_order_cnt_type = - p_H264_Dpb->dpb_param.l.data[PIC_ORDER_CNT_TYPE]; - sps->log2_max_pic_order_cnt_lsb_minus4 = - p_H264_Dpb->dpb_param.l.data[LOG2_MAX_PIC_ORDER_CNT_LSB] - 4; - sps->num_ref_frames_in_pic_order_cnt_cycle = - p_H264_Dpb-> - dpb_param.l.data[NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE]; - for (i = 0; i < 128; i++) - sps->offset_for_ref_frame[i] = - (short) p_H264_Dpb-> - dpb_param.mmco.offset_for_ref_frame_base[i]; - sps->offset_for_non_ref_pic = - (short) p_H264_Dpb->dpb_param.l.data[OFFSET_FOR_NON_REF_PIC]; - sps->offset_for_top_to_bottom_field = - (short) p_H264_Dpb->dpb_param.l.data - [OFFSET_FOR_TOP_TO_BOTTOM_FIELD]; - - pSlice->frame_num = p_H264_Dpb->dpb_param.dpb.frame_num; - pSlice->idr_flag = - (p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f) - == 5 ? 1 : 0; - pSlice->nal_reference_idc = - (p_H264_Dpb->dpb_param.dpb.NAL_info_mmco >> 5) - & 0x3; - pSlice->pic_order_cnt_lsb = - p_H264_Dpb->dpb_param.dpb.pic_order_cnt_lsb; - pSlice->field_pic_flag = 0; - pSlice->bottom_field_flag = 0; - pSlice->delta_pic_order_cnt_bottom = val( - p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_bottom); - pSlice->delta_pic_order_cnt[0] = val( - p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_0); - pSlice->delta_pic_order_cnt[1] = val( - p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_1); - - p_Vid->last_has_mmco_5 = 0; - /* last memory_management_control_operation is 5 */ - p_Vid->last_pic_bottom_field = 0; - p_Vid->max_frame_num = 1 << - (p_H264_Dpb->dpb_param.l.data[LOG2_MAX_FRAME_NUM]); - - /**/ - pSlice->structure = (p_H264_Dpb-> - dpb_param.l.data[NEW_PICTURE_STRUCTURE] == 3) ? - FRAME : p_H264_Dpb->dpb_param.l.data[NEW_PICTURE_STRUCTURE]; - if (pSlice->structure == FRAME) { - pSlice->field_pic_flag = 0; - pSlice->bottom_field_flag = 0; - } else { - pSlice->field_pic_flag = 1; - if (pSlice->structure == TOP_FIELD) - pSlice->bottom_field_flag = 0; - else - pSlice->bottom_field_flag = 1; - } - pSlice->pic_struct = p_H264_Dpb->dpb_param.l.data[PICTURE_STRUCT]; - - sps->num_ref_frames = p_H264_Dpb-> - dpb_param.l.data[MAX_REFERENCE_FRAME_NUM]; - sps->profile_idc = - (p_H264_Dpb->dpb_param.l.data[PROFILE_IDC_MMCO] >> 8) & 0xff; - /*sps->max_dpb_size = p_H264_Dpb->dpb_param.l.data[MAX_DPB_SIZE];*/ - if (pSlice->idr_flag) { - pSlice->long_term_reference_flag = mmco_cmd[0] & 1; - pSlice->no_output_of_prior_pics_flag = (mmco_cmd[0] >> 1) & 1; - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "IDR: long_term_reference_flag %d no_output_of_prior_pics_flag %d\r\n", - pSlice->long_term_reference_flag, - pSlice->no_output_of_prior_pics_flag); - - p_H264_Dpb->long_term_reference_flag = pSlice->long_term_reference_flag; - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "idr set pre_frame_num(%d) to frame_num (%d)\n", - p_Vid->pre_frame_num, pSlice->frame_num); - - p_Vid->pre_frame_num = pSlice->frame_num; - } else if (p_H264_Dpb->mDPB.first_pic_done == 0) { - /* by rain - handle the case when first slice is I instead of IDR - */ - p_Vid->pre_frame_num = pSlice->frame_num; - } - /* pSlice->adaptive_ref_pic_buffering_flag; */ - sps->log2_max_frame_num_minus4 = - p_H264_Dpb->dpb_param.l.data[LOG2_MAX_FRAME_NUM] - 4; - sps->frame_num_gap_allowed = p_H264_Dpb->dpb_param.l.data[FRAME_NUM_GAP_ALLOWED]; - - p_Vid->non_conforming_stream = - p_H264_Dpb->dpb_param.l.data[NON_CONFORMING_STREAM]; - p_Vid->recovery_point = - p_H264_Dpb->dpb_param.l.data[RECOVERY_POINT]; - switch (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE]) { - case I_Slice: - pSlice->slice_type = I_SLICE; - break; - case P_Slice: - pSlice->slice_type = P_SLICE; - break; - case B_Slice: - pSlice->slice_type = B_SLICE; - break; - default: - pSlice->slice_type = NUM_SLICE_TYPES; - break; - } - - pSlice->num_ref_idx_active[LIST_0] = - p_H264_Dpb->dpb_param.dpb.num_ref_idx_l0_active_minus1 + - 1; - /* p_H264_Dpb->dpb_param.l.data[PPS_NUM_REF_IDX_L0_ACTIVE_MINUS1]; */ - pSlice->num_ref_idx_active[LIST_1] = - p_H264_Dpb->dpb_param.dpb.num_ref_idx_l1_active_minus1 + - 1; - /* p_H264_Dpb->dpb_param.l.data[PPS_NUM_REF_IDX_L1_ACTIVE_MINUS1]; */ - - pSlice->p_Vid = p_Vid; - pSlice->p_Dpb = p_Dpb; - /* - p_H264_Dpb->colocated_buf_size = - p_H264_Dpb->dpb_param.l.data[FRAME_SIZE_IN_MB] * 96;*/ - pSlice->first_mb_in_slice = - p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]; - pSlice->mode_8x8_flags = p_H264_Dpb->dpb_param.l.data[MODE_8X8_FLAGS]; - pSlice->picture_structure_mmco = - p_H264_Dpb->dpb_param.dpb.picture_structure_mmco; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s slice_type is %d, num_ref_idx_active[0,1]=%d,%d nal_reference_idc %d pic struct 0x%x(mmco stru 0x%x)\n", - __func__, pSlice->slice_type, - pSlice->num_ref_idx_active[LIST_0], - pSlice->num_ref_idx_active[LIST_1], - pSlice->nal_reference_idc, - pSlice->structure, - pSlice->picture_structure_mmco); -#ifdef ERROR_CHECK - if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE) { - pSlice->num_ref_idx_active[LIST_0] = MAX_LIST_SIZE - 1; - p_H264_Dpb->dpb_error_flag = __LINE__; - } - if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) { - pSlice->num_ref_idx_active[LIST_1] = MAX_LIST_SIZE - 1; - p_H264_Dpb->dpb_error_flag = __LINE__; - } -#endif - -#if 1 - /* dec_ref_pic_marking_buffer */ - pSlice->adaptive_ref_pic_buffering_flag = 0; - if (pSlice->nal_reference_idc) { - for (i = 0, j = 0; i < 44; j++) { - unsigned short val; - struct DecRefPicMarking_s *tmp_drpm = - &pSlice->dec_ref_pic_marking_buffer[j]; - memset(tmp_drpm, 0, sizeof(struct DecRefPicMarking_s)); - val = tmp_drpm-> - memory_management_control_operation = - mmco_cmd[i++]; - tmp_drpm->Next = NULL; - if (j > 0) { - pSlice-> - dec_ref_pic_marking_buffer[j - 1].Next = - tmp_drpm; - } - if (val == 0 || i >= 44) - break; - pSlice->adaptive_ref_pic_buffering_flag = 1; - if ((val == 1) || (val == 3)) { - tmp_drpm->difference_of_pic_nums_minus1 = - mmco_cmd[i++]; - } - if (val == 2) - tmp_drpm->long_term_pic_num = mmco_cmd[i++]; - if (i >= 44) - break; - if ((val == 3) || (val == 6)) - tmp_drpm->long_term_frame_idx = mmco_cmd[i++]; - if (val == 4) { - tmp_drpm->max_long_term_frame_idx_plus1 = - mmco_cmd[i++]; - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "dec_ref_pic_marking_buffer[%d]:operation %x diff_pic_minus1 %x long_pic_num %x long_frame_idx %x max_long_frame_idx_plus1 %x\n", - j, - tmp_drpm->memory_management_control_operation, - tmp_drpm->difference_of_pic_nums_minus1, - tmp_drpm->long_term_pic_num, - tmp_drpm->long_term_frame_idx, - tmp_drpm->max_long_term_frame_idx_plus1); - } - } - - ref_pic_list_reordering(p_H264_Dpb, pSlice); -#endif - - /*VUI*/ - p_H264_Dpb->vui_status = p_H264_Dpb->dpb_param.l.data[VUI_STATUS]; - p_H264_Dpb->aspect_ratio_idc = - p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_IDC]; - p_H264_Dpb->aspect_ratio_sar_width = - p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_SAR_WIDTH]; - p_H264_Dpb->aspect_ratio_sar_height = - p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_SAR_HEIGHT]; - - p_H264_Dpb->fixed_frame_rate_flag = p_H264_Dpb->dpb_param.l.data[ - FIXED_FRAME_RATE_FLAG]; - p_H264_Dpb->num_units_in_tick = - p_H264_Dpb->dpb_param.l.data[NUM_UNITS_IN_TICK]; - p_H264_Dpb->time_scale = p_H264_Dpb->dpb_param.l.data[TIME_SCALE] | - (p_H264_Dpb->dpb_param.l.data[TIME_SCALE + 1] << 16); - - p_H264_Dpb->bitstream_restriction_flag = - (p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1; - p_H264_Dpb->num_reorder_frames = - p_H264_Dpb->dpb_param.l.data[NUM_REORDER_FRAMES]; - p_H264_Dpb->max_dec_frame_buffering = - p_H264_Dpb->dpb_param.l.data[MAX_BUFFER_FRAME]; - - /**/ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s return\n", __func__); -} - -static void decode_poc(struct VideoParameters *p_Vid, struct Slice *pSlice) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid, - struct h264_dpb_stru, mVideo); - struct SPSParameters *active_sps = p_Vid->active_sps; - int i; - /* for POC mode 0: */ - unsigned int MaxPicOrderCntLsb = (1 << - (active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4)); - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DEBUG_POC, - "%s:pic_order_cnt_type %d, idr_flag %d last_has_mmco_5 %d last_pic_bottom_field %d pic_order_cnt_lsb %d PrevPicOrderCntLsb %d\r\n", - __func__, - active_sps->pic_order_cnt_type, - pSlice->idr_flag, - p_Vid->last_has_mmco_5, - p_Vid->last_pic_bottom_field, - pSlice->pic_order_cnt_lsb, - p_Vid->PrevPicOrderCntLsb - ); - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DEBUG_POC, - "%s:field_pic_flag %d, bottom_field_flag %d frame_num %d PreviousFrameNum %d PreviousFrameNumOffset %d ax_frame_num %d num_ref_frames_in_pic_order_cnt_cycle %d offset_for_non_ref_pic %d\r\n", - __func__, - pSlice->field_pic_flag, - pSlice->bottom_field_flag, - pSlice->frame_num, - p_Vid->PreviousFrameNum, - p_Vid->PreviousFrameNumOffset, - p_Vid->max_frame_num, - active_sps->num_ref_frames_in_pic_order_cnt_cycle, - active_sps->offset_for_non_ref_pic - ); - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DEBUG_POC, - "%s: delta_pic_order_cnt %d %d nal_reference_idc %d\r\n", - __func__, - pSlice->delta_pic_order_cnt[0], pSlice->delta_pic_order_cnt[1], - pSlice->nal_reference_idc - ); - - - switch (active_sps->pic_order_cnt_type) { - case 0: /* POC MODE 0 */ - /* 1st */ - if (pSlice->idr_flag) { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = 0; - } else { - if (p_Vid->last_has_mmco_5) { - if (p_Vid->last_pic_bottom_field) { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = 0; - } else { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = - pSlice->toppoc; - } - } - } - /* Calculate the MSBs of current picture */ - if (pSlice->pic_order_cnt_lsb < p_Vid->PrevPicOrderCntLsb && - (p_Vid->PrevPicOrderCntLsb - pSlice->pic_order_cnt_lsb) >= - (MaxPicOrderCntLsb / 2)) - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb + - MaxPicOrderCntLsb; - else if (pSlice->pic_order_cnt_lsb > - p_Vid->PrevPicOrderCntLsb && - (pSlice->pic_order_cnt_lsb - - p_Vid->PrevPicOrderCntLsb) > - (MaxPicOrderCntLsb / 2)) - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb - - MaxPicOrderCntLsb; - else - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb; - - /* 2nd */ - if (pSlice->field_pic_flag == 0) { - /* frame pix */ - pSlice->toppoc = pSlice->PicOrderCntMsb + - pSlice->pic_order_cnt_lsb; - pSlice->bottompoc = pSlice->toppoc + - pSlice->delta_pic_order_cnt_bottom; - pSlice->ThisPOC = pSlice->framepoc = - (pSlice->toppoc < pSlice->bottompoc) ? - pSlice->toppoc : pSlice->bottompoc; - /* POC200301 */ - } else if (pSlice->bottom_field_flag == 0) { - /* top field */ - pSlice->ThisPOC = pSlice->toppoc = - pSlice->PicOrderCntMsb + - pSlice->pic_order_cnt_lsb; - } else { - /* bottom field */ - pSlice->ThisPOC = pSlice->bottompoc = - pSlice->PicOrderCntMsb + - pSlice->pic_order_cnt_lsb; - } - pSlice->framepoc = pSlice->ThisPOC; - - p_Vid->ThisPOC = pSlice->ThisPOC; - - /* if ( pSlice->frame_num != p_Vid->PreviousFrameNum) - * Seems redundant - */ - p_Vid->PreviousFrameNum = pSlice->frame_num; - - if (pSlice->nal_reference_idc) { - p_Vid->PrevPicOrderCntLsb = pSlice->pic_order_cnt_lsb; - p_Vid->PrevPicOrderCntMsb = pSlice->PicOrderCntMsb; - } - - break; - - case 1: /* POC MODE 1 */ - /* 1st */ - if (pSlice->idr_flag) { - p_Vid->FrameNumOffset = 0; /* first pix of IDRGOP */ - if (pSlice->frame_num) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "frame_num not equal to zero in IDR picture %d", - -1020); - } else { - if (p_Vid->last_has_mmco_5) { - p_Vid->PreviousFrameNumOffset = 0; - p_Vid->PreviousFrameNum = 0; - } - if (pSlice->frame_num < p_Vid->PreviousFrameNum) { - /* not first pix of IDRGOP */ - p_Vid->FrameNumOffset = - p_Vid->PreviousFrameNumOffset + - p_Vid->max_frame_num; - } else { - p_Vid->FrameNumOffset = - p_Vid->PreviousFrameNumOffset; - } - } - - /* 2nd */ - if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) - pSlice->AbsFrameNum = - p_Vid->FrameNumOffset + pSlice->frame_num; - else - pSlice->AbsFrameNum = 0; - if ((!pSlice->nal_reference_idc) && pSlice->AbsFrameNum > 0) - pSlice->AbsFrameNum--; - - /* 3rd */ - p_Vid->ExpectedDeltaPerPicOrderCntCycle = 0; - - if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) - for (i = 0; i < (int) active_sps-> - num_ref_frames_in_pic_order_cnt_cycle; i++) { - p_Vid->ExpectedDeltaPerPicOrderCntCycle += - active_sps->offset_for_ref_frame[i]; - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DEBUG_POC, - "%s: offset_for_ref_frame %d\r\n", - __func__, - active_sps-> - offset_for_ref_frame[i]); - } - - if (pSlice->AbsFrameNum) { - p_Vid->PicOrderCntCycleCnt = - (pSlice->AbsFrameNum - 1) / - active_sps-> - num_ref_frames_in_pic_order_cnt_cycle; - p_Vid->FrameNumInPicOrderCntCycle = - (pSlice->AbsFrameNum - 1) % - active_sps-> - num_ref_frames_in_pic_order_cnt_cycle; - p_Vid->ExpectedPicOrderCnt = - p_Vid->PicOrderCntCycleCnt * - p_Vid->ExpectedDeltaPerPicOrderCntCycle; - for (i = 0; i <= (int)p_Vid-> - FrameNumInPicOrderCntCycle; i++) { - p_Vid->ExpectedPicOrderCnt += - active_sps->offset_for_ref_frame[i]; - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DEBUG_POC, - "%s: offset_for_ref_frame %d\r\n", - __func__, - active_sps-> - offset_for_ref_frame[i]); - } - } else - p_Vid->ExpectedPicOrderCnt = 0; - - if (!pSlice->nal_reference_idc) - p_Vid->ExpectedPicOrderCnt += - active_sps->offset_for_non_ref_pic; - - if (pSlice->field_pic_flag == 0) { - /* frame pix */ - pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + - pSlice->delta_pic_order_cnt[0]; - pSlice->bottompoc = pSlice->toppoc + - active_sps->offset_for_top_to_bottom_field + - pSlice->delta_pic_order_cnt[1]; - pSlice->ThisPOC = pSlice->framepoc = - (pSlice->toppoc < pSlice->bottompoc) ? - pSlice->toppoc : pSlice->bottompoc; - /* POC200301 */ - } else if (pSlice->bottom_field_flag == 0) { - /* top field */ - pSlice->ThisPOC = pSlice->toppoc = - p_Vid->ExpectedPicOrderCnt + - pSlice->delta_pic_order_cnt[0]; - } else { - /* bottom field */ - pSlice->ThisPOC = pSlice->bottompoc = - p_Vid->ExpectedPicOrderCnt + - active_sps->offset_for_top_to_bottom_field + - pSlice->delta_pic_order_cnt[0]; - } - pSlice->framepoc = pSlice->ThisPOC; - - p_Vid->PreviousFrameNum = pSlice->frame_num; - p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; - - break; - - - case 2: /* POC MODE 2 */ - if (pSlice->idr_flag) { /* IDR picture */ - p_Vid->FrameNumOffset = 0; /* first pix of IDRGOP */ - pSlice->ThisPOC = pSlice->framepoc = pSlice->toppoc = - pSlice->bottompoc = 0; - if (pSlice->frame_num) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "frame_num not equal to zero in IDR picture %d", - -1020); - } else { - if (p_Vid->last_has_mmco_5) { - p_Vid->PreviousFrameNum = 0; - p_Vid->PreviousFrameNumOffset = 0; - } - if (pSlice->frame_num < p_Vid->PreviousFrameNum) - p_Vid->FrameNumOffset = - p_Vid->PreviousFrameNumOffset + - p_Vid->max_frame_num; - else - p_Vid->FrameNumOffset = - p_Vid->PreviousFrameNumOffset; - - pSlice->AbsFrameNum = p_Vid->FrameNumOffset + - pSlice->frame_num; - if (!pSlice->nal_reference_idc) - pSlice->ThisPOC = - (2 * pSlice->AbsFrameNum - 1); - else - pSlice->ThisPOC = (2 * pSlice->AbsFrameNum); - - if (pSlice->field_pic_flag == 0) - pSlice->toppoc = pSlice->bottompoc = - pSlice->framepoc = pSlice->ThisPOC; - else if (pSlice->bottom_field_flag == 0) - pSlice->toppoc = pSlice->framepoc = - pSlice->ThisPOC; - else - pSlice->bottompoc = pSlice->framepoc = - pSlice->ThisPOC; - } - - p_Vid->PreviousFrameNum = pSlice->frame_num; - p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; - break; - - - default: - /* error must occurs */ - /* assert( 1==0 ); */ - break; - } -} - -void fill_frame_num_gap(struct VideoParameters *p_Vid, struct Slice *currSlice) -{ - struct h264_dpb_stru *p_H264_Dpb = - container_of(p_Vid, struct h264_dpb_stru, mVideo); - struct SPSParameters *active_sps = p_Vid->active_sps; - int CurrFrameNum; - int UnusedShortTermFrameNum; - struct StorablePicture *picture = NULL; - int tmp1 = currSlice->delta_pic_order_cnt[0]; - int tmp2 = currSlice->delta_pic_order_cnt[1]; - int ret; - - currSlice->delta_pic_order_cnt[0] = - currSlice->delta_pic_order_cnt[1] = 0; - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "A gap in frame number is found, try to fill it.(pre_frame_num %d, max_frame_num %d\n", - p_Vid->pre_frame_num, p_Vid->max_frame_num - ); - - UnusedShortTermFrameNum = (p_Vid->pre_frame_num + 1) - % p_Vid->max_frame_num; - CurrFrameNum = currSlice->frame_num; /*p_Vid->frame_num;*/ - - while (CurrFrameNum != UnusedShortTermFrameNum) { - /*pr_err("CurrFrameNum = %d, UnusedShortTermFrameNum = %d\n", CurrFrameNum, UnusedShortTermFrameNum);*/ - /*picture = alloc_storable_picture - *(p_Vid, FRAME, p_Vid->width, - *p_Vid->height, - *p_Vid->width_cr, - *p_Vid->height_cr, 1); - */ - picture = get_new_pic(p_H264_Dpb, - p_H264_Dpb->mSlice.structure, - /*p_Vid->width, p_Vid->height, - *p_Vid->width_cr, - p_Vid->height_cr,*/ 1); - - if (picture == NULL) { - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s Error: get_new_pic return NULL\r\n", - __func__); - /*h264_debug_flag |= PRINT_FLAG_DUMP_DPB;*/ - dump_dpb(p_Dpb, 0); - return; - } - - picture->colocated_buf_index = -1; - picture->buf_spec_num = -1; - picture->buf_spec_is_alloced = 0; - - picture->coded_frame = 1; - picture->pic_num = UnusedShortTermFrameNum; - picture->frame_num = UnusedShortTermFrameNum; - picture->non_existing = 1; - picture->is_output = 1; - picture->used_for_reference = 1; - picture->adaptive_ref_pic_buffering_flag = 0; - #if (MVC_EXTENSION_ENABLE) - picture->view_id = currSlice->view_id; - #endif - - currSlice->frame_num = UnusedShortTermFrameNum; - if (active_sps->pic_order_cnt_type != 0) { - /*decode_poc(p_Vid, p_Vid->ppSliceList[0]);*/ - decode_poc(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice); - } - picture->top_poc = currSlice->toppoc; - picture->bottom_poc = currSlice->bottompoc; - picture->frame_poc = currSlice->framepoc; - picture->poc = currSlice->framepoc; - - ret = store_picture_in_dpb(p_H264_Dpb, picture, 0); - if (ret == -1) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s Error: store_picture_in_dpb failed, break\n", - __func__); - release_picture(p_H264_Dpb, picture); - bufmgr_force_recover(p_H264_Dpb); - return; - } else if (ret == -2) - release_picture(p_H264_Dpb, picture); - - picture = NULL; - p_Vid->pre_frame_num = UnusedShortTermFrameNum; - UnusedShortTermFrameNum = - (UnusedShortTermFrameNum + 1) % - p_Vid->max_frame_num; - } - currSlice->delta_pic_order_cnt[0] = tmp1; - currSlice->delta_pic_order_cnt[1] = tmp2; - currSlice->frame_num = CurrFrameNum; -} - -void dpb_init_global(struct h264_dpb_stru *p_H264_Dpb, - int id, int actual_dpb_size, int max_reference_size) -{ - int i; - - init_dummy_fs(); - - memset(&p_H264_Dpb->mDPB, 0, sizeof(struct DecodedPictureBuffer)); - - memset(&p_H264_Dpb->mSlice, 0, sizeof(struct Slice)); - memset(&p_H264_Dpb->mVideo, 0, sizeof(struct VideoParameters)); - memset(&p_H264_Dpb->mSPS, 0, sizeof(struct SPSParameters)); - - for (i = 0; i < DPB_SIZE_MAX; i++) { - memset(&(p_H264_Dpb->mFrameStore[i]), 0, - sizeof(struct FrameStore)); - } - - for (i = 0; i < MAX_PIC_BUF_NUM; i++) { - memset(&(p_H264_Dpb->m_PIC[i]), 0, - sizeof(struct StorablePicture)); - p_H264_Dpb->m_PIC[i].index = i; - } - p_H264_Dpb->decoder_index = id; - - /* make sure dpb_init_global - *can be called during decoding - *(in DECODE_STATE_IDLE or DECODE_STATE_READY state) - */ - p_H264_Dpb->mDPB.size = actual_dpb_size; - p_H264_Dpb->max_reference_size = max_reference_size; - p_H264_Dpb->poc_even_odd_flag = 0; -} - -static void init_picture(struct h264_dpb_stru *p_H264_Dpb, - struct Slice *currSlice, - struct StorablePicture *dec_picture) -{ - /* struct VideoParameters *p_Vid = &(p_H264_Dpb->mVideo); */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s dec_picture %p\n", __func__, dec_picture); - dec_picture->top_poc = currSlice->toppoc; - dec_picture->bottom_poc = currSlice->bottompoc; - dec_picture->frame_poc = currSlice->framepoc; - switch (currSlice->structure) { - case TOP_FIELD: { - dec_picture->poc = currSlice->toppoc; - /* p_Vid->number *= 2; */ - break; - } - case BOTTOM_FIELD: { - dec_picture->poc = currSlice->bottompoc; - /* p_Vid->number = p_Vid->number * 2 + 1; */ - break; - } - case FRAME: { - dec_picture->poc = currSlice->framepoc; - break; - } - default: - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "p_Vid->structure not initialized %d\n", 235); - } - - /* dec_picture->slice_type = p_Vid->type; */ - dec_picture->used_for_reference = (currSlice->nal_reference_idc != 0); - dec_picture->idr_flag = currSlice->idr_flag; - dec_picture->no_output_of_prior_pics_flag = - currSlice->no_output_of_prior_pics_flag; - dec_picture->long_term_reference_flag = - currSlice->long_term_reference_flag; -#if 1 - dec_picture->adaptive_ref_pic_buffering_flag = - currSlice->adaptive_ref_pic_buffering_flag; - dec_picture->dec_ref_pic_marking_buffer = - &currSlice->dec_ref_pic_marking_buffer[0]; -#endif - /* currSlice->dec_ref_pic_marking_buffer = NULL; */ - - /* dec_picture->mb_aff_frame_flag = currSlice->mb_aff_frame_flag; */ - /* dec_picture->PicWidthInMbs = p_Vid->PicWidthInMbs; */ - - /* p_Vid->get_mb_block_pos = - * dec_picture->mb_aff_frame_flag ? get_mb_block_pos_mbaff : - * get_mb_block_pos_normal; - */ - /* p_Vid->getNeighbour = - * dec_picture->mb_aff_frame_flag ? getAffNeighbour : - * getNonAffNeighbour; - */ - - dec_picture->pic_num = currSlice->frame_num; - dec_picture->frame_num = currSlice->frame_num; - - /* dec_picture->recovery_frame = - * (unsigned int) ((int) currSlice->frame_num == - * p_Vid->recovery_frame_num); - */ - - dec_picture->coded_frame = (currSlice->structure == FRAME); - - /* dec_picture->chroma_format_idc = active_sps->chroma_format_idc; */ - - /* dec_picture->frame_mbs_only_flag = - * active_sps->frame_mbs_only_flag; - */ - /* dec_picture->frame_cropping_flag = - * active_sps->frame_cropping_flag; - */ - - if ((currSlice->picture_structure_mmco & 0x3) == 3) { - dec_picture->mb_aff_frame_flag = 1; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s, picture_structure_mmco is %x, set mb_aff_frame_flag to 1\n", - __func__, - currSlice->picture_structure_mmco); - } - - if (currSlice->pic_struct < PIC_INVALID) { - dec_picture->pic_struct = currSlice->pic_struct; - } else { - dec_picture->pic_struct = PIC_INVALID; - } - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s pic_struct = %d\n", __func__, dec_picture->pic_struct); -} - -void dump_pic(struct h264_dpb_stru *p_H264_Dpb) -{ - int ii; - struct StorablePicture *pic; - for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) { - pic = &(p_H264_Dpb->m_PIC[ii]); - if (pic->is_used) { - dpb_print(p_H264_Dpb->decoder_index, 0, - "pic(%d,%d) poc %d is_used %d bufspec %d colbuf %d for_ref %d long_term %d pre_out %d output %d nonexist %d data_flag 0x%x\n", - ii, pic->index, - pic->poc, - pic->is_used, - pic->buf_spec_num, - pic->colocated_buf_index, - pic->used_for_reference, - pic->is_long_term, - pic->pre_output, - pic->is_output, - pic->non_existing, - pic->data_flag); - } - } -} - -/* -static void is_pic_used_by_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - unsigned i; - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->top_field == pic || - p_Dpb->fs[i]->bottom_field == pic || - p_Dpb->fs[i]->frame == pic - ) - break; - } - if (i < p_Dpb->used_size) - return 1; - return 0; -} -*/ - -static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb, - enum PictureStructure structure, unsigned char is_output) -{ - struct StorablePicture *s = NULL; - struct StorablePicture *pic; - struct VideoParameters *p_Vid = &(p_H264_Dpb->mVideo); - /* recycle un-used pic */ - int ii = 0; - - for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) { - pic = &(p_H264_Dpb->m_PIC[ii]); - if (pic->is_used == 0) { - pic->is_used = 1; - s = pic; - break; - } - } - - if (s) { - s->buf_spec_is_alloced = 0; - s->pic_num = 0; - s->frame_num = 0; - s->long_term_frame_idx = 0; - s->long_term_pic_num = 0; - s->used_for_reference = 0; - s->is_long_term = 0; - s->non_existing = 0; - s->is_output = 0; - s->pre_output = 0; - s->max_slice_id = 0; - s->data_flag &= ~(ERROR_FLAG | NODISP_FLAG); -#if (MVC_EXTENSION_ENABLE) - s->view_id = -1; -#endif - - s->structure = structure; - -#if 0 - s->size_x = size_x; - s->size_y = size_y; - s->size_x_cr = size_x_cr; - s->size_y_cr = size_y_cr; - s->size_x_m1 = size_x - 1; - s->size_y_m1 = size_y - 1; - s->size_x_cr_m1 = size_x_cr - 1; - s->size_y_cr_m1 = size_y_cr - 1; - - s->top_field = p_Vid->no_reference_picture; - s->bottom_field = p_Vid->no_reference_picture; - s->frame = p_Vid->no_reference_picture; -#endif - /* s->dec_ref_pic_marking_buffer = NULL; */ - - s->coded_frame = 0; - s->mb_aff_frame_flag = 0; - - s->top_poc = s->bottom_poc = s->poc = 0; - s->seiHasTone_mapping = 0; - s->frame_mbs_only_flag = p_Vid->active_sps->frame_mbs_only_flag; - - if (!p_Vid->active_sps->frame_mbs_only_flag && - structure != FRAME) { - int i, j; - - for (j = 0; j < MAX_NUM_SLICES; j++) { - for (i = 0; i < 2; i++) { - /* s->listX[j][i] = - *calloc(MAX_LIST_SIZE, - *sizeof (struct StorablePicture *)); - *+1 for reordering ??? - - *if (NULL == s->listX[j][i]) - *no_mem_exit("alloc_storable_picture: - *s->listX[i]"); - */ - } - } - } - } else - p_H264_Dpb->buf_alloc_fail = 1; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s %p\n", __func__, s); - return s; -} - -static void free_picture(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic) -{ - if (pic == NULL || pic->index < 0 || - pic->index >= MAX_PIC_BUF_NUM) - return; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s %p %d\n", __func__, pic, pic->index); - /* assert(pic->index<MAX_PIC_BUF_NUM); */ - p_H264_Dpb->m_PIC[pic->index].is_used = 0; -} - -static void gen_field_ref_ids(struct VideoParameters *p_Vid, - struct StorablePicture *p) -{ - int i, j; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid, - struct h264_dpb_stru, mVideo); - /* ! Generate Frame parameters from field information. */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - /* copy the list; */ - for (j = 0; j < p_Vid->iSliceNumOfCurrPic; j++) { - if (p->listX[j][LIST_0]) { - p->listXsize[j][LIST_0] = - p_Vid->ppSliceList[j]->listXsize[LIST_0]; - for (i = 0; i < p->listXsize[j][LIST_0]; i++) - p->listX[j][LIST_0][i] = - p_Vid->ppSliceList[j]->listX[LIST_0][i]; - } - if (p->listX[j][LIST_1]) { - p->listXsize[j][LIST_1] = - p_Vid->ppSliceList[j]->listXsize[LIST_1]; - for (i = 0; i < p->listXsize[j][LIST_1]; i++) - p->listX[j][LIST_1][i] = - p_Vid->ppSliceList[j]->listX[LIST_1][i]; - } - } -} - -static void init_dpb(struct h264_dpb_stru *p_H264_Dpb, int type) -{ - unsigned int i; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - struct SPSParameters *active_sps = &p_H264_Dpb->mSPS; - - p_Vid->active_sps = active_sps; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - p_Dpb->p_Vid = p_Vid; - if (p_Dpb->init_done) { - /* free_dpb(p_Dpb); */ - if (p_Vid->no_reference_picture) { - free_picture(p_H264_Dpb, p_Vid->no_reference_picture); - p_Vid->no_reference_picture = NULL; - } - p_Dpb->init_done = 0; - } - - /* p_Dpb->size = 10; //active_sps->max_dpb_size; //16; - * getDpbSize(p_Vid, active_sps) + - * p_Vid->p_Inp->dpb_plus[type==2? 1: 0]; - * p_Dpb->size = active_sps->max_dpb_size; //16; - * getDpbSize(p_Vid, active_sps) + - * p_Vid->p_Inp->dpb_plus[type==2? 1: 0]; - * p_Dpb->size initialzie in vh264.c - */ - p_Dpb->num_ref_frames = active_sps->num_ref_frames; - /* p_Dpb->num_ref_frames initialzie in vh264.c */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s dpb_size is %d num_ref_frames = %d (%d)\n", - __func__, p_Dpb->size, - p_Dpb->num_ref_frames, - active_sps->num_ref_frames); - if (active_sps->num_ref_frames == 0xffff) { - dpb_print(p_H264_Dpb->decoder_index, 0, - "!!!Warning, num_ref_frames = %d is invalid\n", - active_sps->num_ref_frames); - } - -#if 0 - /* ??? */ -#if (MVC_EXTENSION_ENABLE) - if ((unsigned int)active_sps->max_dec_frame_buffering < - active_sps->num_ref_frames) { -#else - if (p_Dpb->size < active_sps->num_ref_frames) { -#endif - error( - "DPB size at specified level is smaller than the specified number of reference frames. This is not allowed.\n", - 1000); - } -#endif - - p_Dpb->used_size = 0; - p_Dpb->last_picture = NULL; - - p_Dpb->ref_frames_in_buffer = 0; - p_Dpb->ltref_frames_in_buffer = 0; - -#if 0 - p_Dpb->fs = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (NULL == p_Dpb->fs) - no_mem_exit("init_dpb: p_Dpb->fs"); - - p_Dpb->fs_ref = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (NULL == p_Dpb->fs_ref) - no_mem_exit("init_dpb: p_Dpb->fs_ref"); - - p_Dpb->fs_ltref = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (NULL == p_Dpb->fs_ltref) - no_mem_exit("init_dpb: p_Dpb->fs_ltref"); -#endif - -#if (MVC_EXTENSION_ENABLE) - p_Dpb->fs_ilref = calloc(1, sizeof(struct FrameStore *)); - if (NULL == p_Dpb->fs_ilref) - no_mem_exit("init_dpb: p_Dpb->fs_ilref"); -#endif - - for (i = 0; i < p_Dpb->size; i++) { - p_Dpb->fs[i] = &(p_H264_Dpb->mFrameStore[i]); - /* alloc_frame_store(); */ - p_Dpb->fs[i]->index = i; - p_Dpb->fs_ref[i] = NULL; - p_Dpb->fs_ltref[i] = NULL; - p_Dpb->fs[i]->layer_id = 0; /* MVC_INIT_VIEW_ID; */ -#if (MVC_EXTENSION_ENABLE) - p_Dpb->fs[i]->view_id = MVC_INIT_VIEW_ID; - p_Dpb->fs[i]->inter_view_flag[0] = - p_Dpb->fs[i]->inter_view_flag[1] = 0; - p_Dpb->fs[i]->anchor_pic_flag[0] = - p_Dpb->fs[i]->anchor_pic_flag[1] = 0; -#endif - } -#if (MVC_EXTENSION_ENABLE) - if (type == 2) { - p_Dpb->fs_ilref[0] = alloc_frame_store(); - /* These may need some cleanups */ - p_Dpb->fs_ilref[0]->view_id = MVC_INIT_VIEW_ID; - p_Dpb->fs_ilref[0]->inter_view_flag[0] = - p_Dpb->fs_ilref[0]->inter_view_flag[1] = 0; - p_Dpb->fs_ilref[0]->anchor_pic_flag[0] = - p_Dpb->fs_ilref[0]->anchor_pic_flag[1] = 0; - /* given that this is in a different buffer, - * do we even need proc_flag anymore? - */ - } else - p_Dpb->fs_ilref[0] = NULL; -#endif - - /* - *for (i = 0; i < 6; i++) - *{ - *currSlice->listX[i] = - * calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *)); - * +1 for reordering - *if (NULL == currSlice->listX[i]) - *no_mem_exit("init_dpb: currSlice->listX[i]"); - *} - */ - /* allocate a dummy storable picture */ - if (!p_Vid->no_reference_picture) { - p_Vid->no_reference_picture = get_new_pic(p_H264_Dpb, - FRAME, - /*p_Vid->width, p_Vid->height, - *p_Vid->width_cr, p_Vid->height_cr, - */ - 1); - p_Vid->no_reference_picture->top_field = - p_Vid->no_reference_picture; - p_Vid->no_reference_picture->bottom_field = - p_Vid->no_reference_picture; - p_Vid->no_reference_picture->frame = - p_Vid->no_reference_picture; - } - p_Dpb->last_output_poc = INT_MIN; - -#if (MVC_EXTENSION_ENABLE) - p_Dpb->last_output_view_id = -1; -#endif - - p_Vid->last_has_mmco_5 = 0; - - init_colocate_buf(p_H264_Dpb, p_H264_Dpb->max_reference_size); - - p_Dpb->init_done = 1; - -#if 0 -/* ??? */ - /* picture error concealment */ - if (p_Vid->conceal_mode != 0 && !p_Vid->last_out_fs) - p_Vid->last_out_fs = alloc_frame_store(); -#endif -} - -static void dpb_split_field(struct h264_dpb_stru *p_H264_Dpb, - struct FrameStore *fs) -{ - struct StorablePicture *fs_top = NULL, *fs_btm = NULL; - struct StorablePicture *frame = fs->frame; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s %p %p\n", __func__, fs, frame); - - fs->poc = frame->poc; - - if (!frame->frame_mbs_only_flag) { - fs_top = fs->top_field = get_new_pic(p_H264_Dpb, - TOP_FIELD, - /* frame->size_x, frame->size_y, - *frame->size_x_cr, frame->size_y_cr, - */ - 1); - fs_btm = fs->bottom_field = get_new_pic(p_H264_Dpb, - BOTTOM_FIELD, - /*frame->size_x, frame->size_y, - *frame->size_x_cr, frame->size_y_cr, - */ - 1); - if (fs_top == NULL || fs_btm == NULL) - return; -#if 1 -/* rain */ - fs_top->buf_spec_num = frame->buf_spec_num; - fs_btm->buf_spec_num = frame->buf_spec_num; - - fs_top->colocated_buf_index = frame->colocated_buf_index; - fs_btm->colocated_buf_index = frame->colocated_buf_index; - - fs_top->data_flag = frame->data_flag; - fs_btm->data_flag = frame->data_flag; -#endif - fs_top->poc = frame->top_poc; - fs_btm->poc = frame->bottom_poc; - -#if (MVC_EXTENSION_ENABLE) - fs_top->view_id = frame->view_id; - fs_btm->view_id = frame->view_id; -#endif - - fs_top->frame_poc = frame->frame_poc; - - fs_top->bottom_poc = fs_btm->bottom_poc = frame->bottom_poc; - fs_top->top_poc = fs_btm->top_poc = frame->top_poc; - fs_btm->frame_poc = frame->frame_poc; - - fs_top->used_for_reference = fs_btm->used_for_reference - = frame->used_for_reference; - fs_top->is_long_term = fs_btm->is_long_term - = frame->is_long_term; - fs->long_term_frame_idx = fs_top->long_term_frame_idx - = fs_btm->long_term_frame_idx - = frame->long_term_frame_idx; - - fs_top->coded_frame = fs_btm->coded_frame = 1; - fs_top->mb_aff_frame_flag = fs_btm->mb_aff_frame_flag - = frame->mb_aff_frame_flag; - - frame->top_field = fs_top; - frame->bottom_field = fs_btm; - frame->frame = frame; - fs_top->bottom_field = fs_btm; - fs_top->frame = frame; - fs_top->top_field = fs_top; - fs_btm->top_field = fs_top; - fs_btm->frame = frame; - fs_btm->bottom_field = fs_btm; - -#if (MVC_EXTENSION_ENABLE) - fs_top->view_id = fs_btm->view_id = fs->view_id; - fs_top->inter_view_flag = fs->inter_view_flag[0]; - fs_btm->inter_view_flag = fs->inter_view_flag[1]; -#endif - - fs_top->chroma_format_idc = fs_btm->chroma_format_idc = - frame->chroma_format_idc; - fs_top->iCodingType = fs_btm->iCodingType = frame->iCodingType; - } else { - fs->top_field = NULL; - fs->bottom_field = NULL; - frame->top_field = NULL; - frame->bottom_field = NULL; - frame->frame = frame; - } - -} - - -static void dpb_combine_field(struct h264_dpb_stru *p_H264_Dpb, - struct FrameStore *fs) -{ - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - if (!fs->frame) { - fs->frame = get_new_pic(p_H264_Dpb, - FRAME, - /* fs->top_field->size_x, fs->top_field->size_y*2, - *fs->top_field->size_x_cr, fs->top_field->size_y_cr*2, - */ - 1); - } - if (!fs->frame) - return; -#if 1 -/* rain */ - fs->frame->buf_spec_num = fs->top_field->buf_spec_num; - fs->frame->colocated_buf_index = fs->top_field->colocated_buf_index; - fs->frame->data_flag = fs->top_field->data_flag; - fs->frame->slice_type = fs->top_field->slice_type; - if (fs->bottom_field) - fs->frame->data_flag |= (fs->bottom_field->data_flag & 0xf0); -#endif - - if (fs->bottom_field) { - fs->poc = fs->frame->poc = fs->frame->frame_poc = imin( - fs->top_field->poc, fs->bottom_field->poc); - - fs->bottom_field->frame_poc = fs->top_field->frame_poc = fs->frame->poc; - - fs->bottom_field->top_poc = fs->frame->top_poc = fs->top_field->poc; - fs->top_field->bottom_poc = fs->frame->bottom_poc = - fs->bottom_field->poc; - - fs->frame->used_for_reference = (fs->top_field->used_for_reference && - fs->bottom_field->used_for_reference); - fs->frame->is_long_term = (fs->top_field->is_long_term && - fs->bottom_field->is_long_term); - } - - if (fs->frame->is_long_term) - fs->frame->long_term_frame_idx = fs->long_term_frame_idx; - - fs->frame->top_field = fs->top_field; - if (fs->bottom_field) - fs->frame->bottom_field = fs->bottom_field; - fs->frame->frame = fs->frame; - - fs->frame->coded_frame = 0; - - fs->frame->chroma_format_idc = fs->top_field->chroma_format_idc; - fs->frame->frame_cropping_flag = fs->top_field->frame_cropping_flag; - if (fs->frame->frame_cropping_flag) { - fs->frame->frame_crop_top_offset = - fs->top_field->frame_crop_top_offset; - fs->frame->frame_crop_bottom_offset = - fs->top_field->frame_crop_bottom_offset; - fs->frame->frame_crop_left_offset = - fs->top_field->frame_crop_left_offset; - fs->frame->frame_crop_right_offset = - fs->top_field->frame_crop_right_offset; - } - if (fs->bottom_field) { - fs->top_field->frame = fs->bottom_field->frame = fs->frame; - fs->top_field->top_field = fs->top_field; - fs->top_field->bottom_field = fs->bottom_field; - fs->bottom_field->top_field = fs->top_field; - fs->bottom_field->bottom_field = fs->bottom_field; - } - - /**/ -#if (MVC_EXTENSION_ENABLE) - fs->frame->view_id = fs->view_id; -#endif - fs->frame->iCodingType = fs->top_field->iCodingType; - if (fs->bottom_field && fs->top_field->poc < fs->bottom_field->poc) { - fs->pts = fs->top_field->pts; - fs->pts64 = fs->top_field->pts64; - /*SWPL-7105 fix */ - if ((fs->frame->slice_type == B_SLICE) - && (!fs->bottom_field->pts) &&(!fs->bottom_field->pts64)) { - fs->pts = 0; - fs->pts64 = 0; - } - fs->offset_delimiter = fs->top_field->offset_delimiter; - fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size; - } else if (fs->bottom_field) { - fs->pts = fs->bottom_field->pts; - fs->pts64 = fs->bottom_field->pts64; - fs->offset_delimiter = fs->bottom_field->offset_delimiter; - fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size; - } - /* FIELD_CODING ;*/ -} - -static void calculate_frame_no(struct VideoParameters *p_Vid, - struct StorablePicture *p) -{ -#if 0 -/* ??? */ - InputParameters *p_Inp = p_Vid->p_Inp; - /* calculate frame number */ - int psnrPOC = p_Vid->active_sps->mb_adaptive_frame_field_flag ? - p->poc / (p_Inp->poc_scale) : p->poc / (p_Inp->poc_scale); - - if (psnrPOC == 0) { /* && p_Vid->psnr_number) */ - p_Vid->idr_psnr_number = - p_Vid->g_nFrame * p_Vid->ref_poc_gap / (p_Inp->poc_scale); - } - p_Vid->psnr_number = imax(p_Vid->psnr_number, - p_Vid->idr_psnr_number + psnrPOC); - - p_Vid->frame_no = p_Vid->idr_psnr_number + psnrPOC; -#endif -} - -static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct FrameStore *fs, - struct StorablePicture *p, - unsigned char data_flag) -{ - struct vdec_frames_s *mvfrm = p_H264_Dpb->vdec->mvfrm; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - /* InputParameters *p_Inp = p_Vid->p_Inp; - * dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - * "insert (%s) pic with frame_num #%d, poc %d\n", - * (p->structure == FRAME)?"FRAME": - * (p->structure == TOP_FIELD)?"TOP_FIELD": - * "BOTTOM_FIELD", p->pic_num, p->poc); - * assert (p!=NULL); - * assert (fs!=NULL); - */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s %p %p\n", __func__, fs, p); - p_H264_Dpb->dpb_frame_count++; - fs->dpb_frame_count = p_H264_Dpb->dpb_frame_count; -#if 1 -/* rain */ -/* p->buf_spec_num = fs->index; */ - p->data_flag = data_flag; - fs->data_flag |= data_flag; - fs->buf_spec_num = p->buf_spec_num; - fs->colocated_buf_index = p->colocated_buf_index; -#endif - p->slice_type = p_H264_Dpb->mSlice.slice_type; - switch (p->structure) { - case FRAME: - fs->frame = p; - fs->is_used = 3; - fs->slice_type = p->slice_type; - fs->frame_size = p->frame_size; - fs->offset_delimiter = p->offset_delimiter; - fs->decoded_frame_size = p->pic_size; - if (p->used_for_reference) { - fs->is_reference = 3; - fs->is_orig_reference = 3; - if (p->is_long_term) { - fs->is_long_term = 3; - fs->long_term_frame_idx = - p->long_term_frame_idx; - } - } - fs->pts = p->pts; - fs->pts64 = p->pts64; - fs->layer_id = p->layer_id; -#if (MVC_EXTENSION_ENABLE) - fs->view_id = p->view_id; - fs->inter_view_flag[0] = fs->inter_view_flag[1] = - p->inter_view_flag; - fs->anchor_pic_flag[0] = fs->anchor_pic_flag[1] = - p->anchor_pic_flag; -#endif - /* generate field views */ - /* return; */ - dpb_split_field(p_H264_Dpb, fs); - /* return; */ - break; - case TOP_FIELD: - fs->top_field = p; - fs->is_used |= 1; - fs->layer_id = p->layer_id; - if (fs->frame_size == 0) { - fs->slice_type = p->slice_type; -// fs->pts = p->pts; -// fs->pts64 = p->pts64; - } - fs->frame_size += p->frame_size; -#if (MVC_EXTENSION_ENABLE) - fs->view_id = p->view_id; - fs->inter_view_flag[0] = p->inter_view_flag; - fs->anchor_pic_flag[0] = p->anchor_pic_flag; -#endif - if (p->used_for_reference) { - fs->is_reference |= 1; - fs->is_orig_reference |= 1; - if (p->is_long_term) { - fs->is_long_term |= 1; - fs->long_term_frame_idx = - p->long_term_frame_idx; - } - } - if (fs->is_used == 3) { - /* generate frame view */ - dpb_combine_field(p_H264_Dpb, fs); - } else { - fs->poc = p->poc; - } - gen_field_ref_ids(p_Vid, p); - break; - case BOTTOM_FIELD: - fs->bottom_field = p; - fs->is_used |= 2; - fs->layer_id = p->layer_id; - if (fs->frame_size == 0) { - fs->slice_type = p->slice_type; -// fs->pts = p->pts; -// fs->pts64 = p->pts64; - } - fs->frame_size += p->frame_size; -#if (MVC_EXTENSION_ENABLE) - fs->view_id = p->view_id; - fs->inter_view_flag[1] = p->inter_view_flag; - fs->anchor_pic_flag[1] = p->anchor_pic_flag; -#endif - if (p->used_for_reference) { - fs->is_reference |= 2; - fs->is_orig_reference |= 2; - if (p->is_long_term) { - fs->is_long_term |= 2; - fs->long_term_frame_idx = - p->long_term_frame_idx; - } - } - if (fs->is_used == 3) { - /* generate frame view */ - dpb_combine_field(p_H264_Dpb, fs); - } else { - fs->poc = p->poc; - } - gen_field_ref_ids(p_Vid, p); - break; - } - fs->frame_num = p->pic_num; - fs->recovery_frame = p->recovery_frame; - - fs->is_output = p->is_output; - fs->pre_output = p->pre_output; - - /* picture qos infomation*/ - fs->max_mv = p->max_mv; - fs->avg_mv = p->avg_mv; - fs->min_mv = p->min_mv; - - fs->max_qp = p->max_qp; - fs->avg_qp = p->avg_qp; - fs->min_qp = p->min_qp; - - fs->max_skip = p->max_skip; - fs->avg_skip = p->avg_skip; - fs->min_skip = p->min_skip; - - if (fs->is_used == 3) { - calculate_frame_no(p_Vid, p); -#if 0 -/* ??? */ - if (-1 != p_Vid->p_ref && !p_Inp->silent) - find_snr(p_Vid, fs->frame, &p_Vid->p_ref); -#endif - //fs->pts = p->pts; - //fs->pts64 = p->pts64; - } - if ((fs->frame != NULL) && - ((fs->bottom_field != NULL) || (fs->top_field != NULL))) { - fs->last_field_timestamp = fs->timestamp; - fs->timestamp = p->timestamp; - } else { - fs->timestamp = p->timestamp; - } - if (mvfrm) { - fs->frame_size2 = mvfrm->frame_size; - fs->hw_decode_time = mvfrm->hw_decode_time; - } -} - -void reset_frame_store(struct h264_dpb_stru *p_H264_Dpb, - struct FrameStore *f) -{ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - if (f) { - if (f->frame) { - free_picture(p_H264_Dpb, f->frame); - f->frame = NULL; - } - if (f->top_field) { - free_picture(p_H264_Dpb, f->top_field); - f->top_field = NULL; - } - if (f->bottom_field) { - free_picture(p_H264_Dpb, f->bottom_field); - f->bottom_field = NULL; - } - - /**/ - f->is_used = 0; - f->is_reference = 0; - f->is_long_term = 0; - f->is_orig_reference = 0; - - f->is_output = 0; - f->pre_output = 0; - f->show_frame = false; - - f->frame = NULL; - f->top_field = NULL; - f->bottom_field = NULL; - - /* free(f); */ - } -} - -void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb, - struct FrameStore *fs) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s %p %p %p %p\n", __func__, - fs, fs->frame, fs->top_field, fs->bottom_field); - /* return; */ - if (fs->is_used & 1) { - if (fs->top_field) - fs->top_field->used_for_reference = 0; - } - if (fs->is_used & 2) { - if (fs->bottom_field) - fs->bottom_field->used_for_reference = 0; - } - if (fs->is_used == 3) { - if (fs->top_field && fs->bottom_field) { - fs->top_field->used_for_reference = 0; - fs->bottom_field->used_for_reference = 0; - } - fs->frame->used_for_reference = 0; - } - - fs->is_reference = 0; - -} - -static void unmark_for_long_term_reference(struct FrameStore *fs) -{ - if (fs->is_used & 1) { - if (fs->top_field) { - fs->top_field->used_for_reference = 0; - fs->top_field->is_long_term = 0; - } - } - if (fs->is_used & 2) { - if (fs->bottom_field) { - fs->bottom_field->used_for_reference = 0; - fs->bottom_field->is_long_term = 0; - } - } - if (fs->is_used == 3) { - if (fs->top_field && fs->bottom_field) { - fs->top_field->used_for_reference = 0; - fs->top_field->is_long_term = 0; - fs->bottom_field->used_for_reference = 0; - fs->bottom_field->is_long_term = 0; - } - fs->frame->used_for_reference = 0; - fs->frame->is_long_term = 0; - } - - fs->is_reference = 0; - fs->is_long_term = 0; -} - -int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb, - int buf_spec_num) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - unsigned int i; - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->buf_spec_num == buf_spec_num) - return p_Dpb->fs[i]->is_long_term; - } - return -1; -} - -static void update_pic_num(struct h264_dpb_stru *p_H264_Dpb) -{ - unsigned int i; - struct Slice *currSlice = &p_H264_Dpb->mSlice; - struct VideoParameters *p_Vid = currSlice->p_Vid; - struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb; - struct SPSParameters *active_sps = p_Vid->active_sps; - int add_top = 0, add_bottom = 0; - int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4); - - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame-> - used_for_reference) && - (!p_Dpb->fs_ref[i]->frame-> - is_long_term)) { - if (p_Dpb->fs_ref[i]->frame_num > - currSlice->frame_num) { - p_Dpb->fs_ref[i]-> - frame_num_wrap = - p_Dpb->fs_ref[i]->frame_num - - max_frame_num; - } else { - p_Dpb->fs_ref[i]-> - frame_num_wrap = - p_Dpb->fs_ref[i]->frame_num; - } - p_Dpb->fs_ref[i]->frame->pic_num = - p_Dpb->fs_ref[i]->frame_num_wrap; - } - } - } - /* update long_term_pic_num */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i] == NULL || - p_Dpb->fs_ltref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame->is_long_term) { - p_Dpb->fs_ltref[i]->frame-> - long_term_pic_num = - p_Dpb->fs_ltref[i]->frame-> - long_term_frame_idx; - } - } - } - } else { - if (currSlice->structure == TOP_FIELD) { - add_top = 1; - add_bottom = 0; - } else { - add_top = 0; - add_bottom = 1; - } - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference) { - if (p_Dpb->fs_ref[i]->frame_num > currSlice-> - frame_num) { - p_Dpb->fs_ref[i]->frame_num_wrap = - p_Dpb->fs_ref[i]->frame_num - - max_frame_num; - } else { - p_Dpb->fs_ref[i]->frame_num_wrap = - p_Dpb->fs_ref[i]->frame_num; - } - if (p_Dpb->fs_ref[i]->is_reference & 1) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field - == NULL) { - p_H264_Dpb->dpb_error_flag = - __LINE__; - continue; - } -#endif - p_Dpb->fs_ref[i]->top_field-> - pic_num = (2 * p_Dpb->fs_ref[i]-> - frame_num_wrap) + add_top; - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field - == NULL) { - p_H264_Dpb->dpb_error_flag = - __LINE__; - continue; - } -#endif - p_Dpb->fs_ref[i]->bottom_field-> - pic_num = (2 * p_Dpb->fs_ref[i]-> - frame_num_wrap) + add_bottom; - } - } - } - /* update long_term_pic_num */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ltref[i]->is_long_term & 1) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i]->top_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - p_Dpb->fs_ltref[i]->top_field-> - long_term_pic_num = 2 * - p_Dpb->fs_ltref[i]->top_field-> - long_term_frame_idx + add_top; - } - if (p_Dpb->fs_ltref[i]->is_long_term & 2) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ltref[i]->bottom_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - p_Dpb->fs_ltref[i]->bottom_field-> - long_term_pic_num = 2 * - p_Dpb->fs_ltref[i]->bottom_field-> - long_term_frame_idx + add_bottom; - } - } - } -} - -static void remove_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb, int pos) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - struct FrameStore *fs = p_Dpb->fs[pos]; - struct FrameStore *tmp; - unsigned int i; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s pos %d %p\n", __func__, pos, fs); - - /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - * "remove frame with frame_num #%d\n", fs->frame_num); - */ - switch (fs->is_used) { - case 3: - free_picture(p_H264_Dpb, fs->frame); - free_picture(p_H264_Dpb, fs->top_field); - free_picture(p_H264_Dpb, fs->bottom_field); - fs->frame = NULL; - fs->top_field = NULL; - fs->bottom_field = NULL; - break; - case 2: - free_picture(p_H264_Dpb, fs->bottom_field); - fs->bottom_field = NULL; - break; - case 1: - free_picture(p_H264_Dpb, fs->top_field); - fs->top_field = NULL; - break; - case 0: - break; - default: - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "invalid frame store type %x", 500); - } - fs->data_flag = 0; - fs->is_used = 0; - fs->is_long_term = 0; - fs->is_reference = 0; - fs->is_orig_reference = 0; - fs->frame_size = 0; - /* move empty framestore to end of buffer */ - tmp = p_Dpb->fs[pos]; - - for (i = pos; i < p_Dpb->used_size - 1; i++) - p_Dpb->fs[i] = p_Dpb->fs[i + 1]; - p_Dpb->fs[p_Dpb->used_size - 1] = tmp; - - if (p_Dpb->used_size) - p_Dpb->used_size--; -} - -int is_used_for_reference(struct FrameStore *fs) -{ - if (fs->is_reference) - return 1; - - if (fs->is_used == 3) { /* frame */ - if (fs->frame->used_for_reference) - return 1; - } - - if (fs->is_used & 1) { /* top field */ - if (fs->top_field) { - if (fs->top_field->used_for_reference) - return 1; - } - } - - if (fs->is_used & 2) { /* bottom field */ - if (fs->bottom_field) { - if (fs->bottom_field->used_for_reference) - return 1; - } - } - return 0; -} - -static int remove_unused_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb) -{ - unsigned int i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - /* check for frames that were already output and no longer - * used for reference - */ - for (i = 0; i < p_Dpb->used_size; i++) { - if ((!is_used_for_reference(p_Dpb->fs[i])) && - (p_Dpb->fs[i]->colocated_buf_index >= 0)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "release_colocate_buf[%d] for fs[%d]\n", - p_Dpb->fs[i]->colocated_buf_index, i); - - release_colocate_buf(p_H264_Dpb, - p_Dpb->fs[i]->colocated_buf_index); /* rain */ - p_Dpb->fs[i]->colocated_buf_index = -1; - } - } - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->is_output && - (!is_used_for_reference(p_Dpb->fs[i]))) { - release_buf_spec_num(p_H264_Dpb->vdec, - p_Dpb->fs[i]->buf_spec_num); - p_Dpb->fs[i]->buf_spec_num = -1; - remove_frame_from_dpb(p_H264_Dpb, i); - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%s[%d]\n", - __func__, i); - - return 1; - } - } - return 0; -} - -static int unmark_one_error_out_frame(struct h264_dpb_stru *p_H264_Dpb) -{ - int ret = 0; - unsigned i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->is_output && - ((p_Dpb->fs[i]->data_flag & ERROR_FLAG) || - (p_Dpb->fs[i]->data_flag & NULL_FLAG)) - ) { - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - - ret = 1; - break; - } - } - return ret; -} - -static int unmark_one_out_frame(struct h264_dpb_stru *p_H264_Dpb) -{ - int ret = 0; - unsigned i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->is_output) { - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - - ret = 1; - } - } - return ret; -} -/* - force_flag, - 1, remove one error buf (is_out is 1) if there is no un-used buf - 2, remove one buf (is_out is 1) if there is no un-used buf -*/ -void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb, - u8 force_flag) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - int ret = 0; - unsigned char removed_flag = 0; - do { - ret = remove_unused_frame_from_dpb(p_H264_Dpb); - if (ret != 0) - removed_flag = 1; - } while (ret != 0); - if (removed_flag) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%s\r\n", __func__); - dump_dpb(p_Dpb, 0); - } else if (force_flag == 2) { - if (unmark_one_out_frame(p_H264_Dpb)) { - dpb_print(p_H264_Dpb->decoder_index, - 0, "%s, Warnning, force unmark one frame\r\n", - __func__); - update_ref_list(p_Dpb); - remove_unused_frame_from_dpb(p_H264_Dpb); - dump_dpb(p_Dpb, 0); - } - } else if (force_flag == 1) { - if (unmark_one_error_out_frame(p_H264_Dpb)) { - dpb_print(p_H264_Dpb->decoder_index, - 0, "%s, unmark error frame\r\n", - __func__); - update_ref_list(p_Dpb); - remove_unused_frame_from_dpb(p_H264_Dpb); - dump_dpb(p_Dpb, 0); - } - } -} - -#ifdef OUTPUT_BUFFER_IN_C -int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned int i; - - /* check for frames that were already output and no longer - * used for reference - */ - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->is_output && - (!is_used_for_reference(p_Dpb->fs[i]))) { - return 1; - } - } - return 0; -} -#endif - -static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc, - int *pos) -{ - unsigned int i; - unsigned long flags; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - struct vdec_s *vdec= (struct vdec_s *)p_H264_Dpb->vdec; - void *p = vh264_get_bufspec_lock(vdec); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%s\n", __func__); - if (p_Dpb->used_size < 1) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "Cannot determine smallest POC, DPB empty. %d\n", - 150); - } - - *pos = -1; - *poc = INT_MAX; - if (p == NULL) - return; - spin_lock_irqsave(p, flags); - for (i = 0; i < p_Dpb->used_size; i++) { -#ifdef OUTPUT_BUFFER_IN_C - /* rain */ - if ((*poc > p_Dpb->fs[i]->poc) && - (!p_Dpb->fs[i]->is_output) && - (!p_Dpb->fs[i]->pre_output)) { -#else - if ((*poc > p_Dpb->fs[i]->poc) && (!p_Dpb->fs[i]->is_output)) { -#endif - *poc = p_Dpb->fs[i]->poc; - *pos = i; - } - } - spin_unlock_irqrestore(p, flags); -} - -int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag) -{ - int poc, pos; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - int i; - int none_displayed_num = 0; - unsigned char fast_output_flag = 0; - - /* - * When the sei data(dv data) after the PIC done and no flush, - * it is necessary to output a frame of data until - * the number of frames not displayed is greater than the reorder. - */ - if ((p_H264_Dpb->wait_aux_data_flag) && (!flush_flag)) { - int no_output_num = 0; - - for (i = 0; i < p_Dpb->used_size; i++) { - if ((!p_Dpb->fs[i]->is_output) && - (!p_Dpb->fs[i]->pre_output) && - ((p_Dpb->fs[i]->is_used == 3) || - (p_Dpb->fs[i]->data_flag & ERROR_FLAG))) - no_output_num++; - } - - if (no_output_num <= p_H264_Dpb->reorder_output) - return 0; - } - - if (!flush_flag) { - for (i = 0; i < p_Dpb->used_size; i++) { - if ((!p_Dpb->fs[i]->is_output) && - (!p_Dpb->fs[i]->pre_output) &&((p_Dpb->fs[i]->is_used == 3 - ||p_Dpb->fs[i]->data_flag & ERROR_FLAG ))) { - none_displayed_num++; - if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE || - p_H264_Dpb->first_insert_frame == FirstInsertFrm_RESET) - && (p_Dpb->fs[i]->is_used == 3) - && (p_Dpb->last_output_poc == INT_MIN)) { - if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE) - fast_output_flag = 1; - p_H264_Dpb->first_insert_frame = FirstInsertFrm_OUT; - p_H264_Dpb->first_output_poc = p_Dpb->fs[i]->poc; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s first insert frame i %d poc %d frame_num %x\n", - __func__, i, p_Dpb->fs[i]->poc, p_Dpb->fs[i]->frame_num); - } - - /*check poc even/odd*/ - if (p_H264_Dpb->poc_even_odd_flag == 0 && - p_H264_Dpb->decode_pic_count >= 3) - p_H264_Dpb->poc_even_odd_flag = 2; - if (p_Dpb->fs[i]->poc & 0x1) - p_H264_Dpb->poc_even_odd_flag = 1; - /**/ - - if ((p_H264_Dpb->fast_output_enable & 0x1) && - (p_Dpb->fs[i]->data_flag & IDR_FLAG)) - fast_output_flag = 1; - if ((p_H264_Dpb->fast_output_enable & 0x2) && - ((p_Dpb->fs[i]->poc - - p_Dpb->last_output_poc) - == 1)) - fast_output_flag = 1; - if ((p_H264_Dpb->fast_output_enable & 0x4) && - (p_H264_Dpb->poc_even_odd_flag == 2) && - (p_Dpb->fs[i]->is_used == 3) && - ((p_Dpb->fs[i]->poc - - p_Dpb->last_output_poc) - == 2)) - fast_output_flag = 1; - } - } - if (fast_output_flag) - ; - else if (none_displayed_num < - p_H264_Dpb->reorder_output) - return 0; - } - - get_smallest_poc(p_Dpb, &poc, &pos); - - if (pos == -1) - return 0; -#if 0 - if (is_used_for_reference(p_Dpb->fs[pos])) - return 0; -#endif - if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s pos %d pos->poc %d first_output_poc %d \n", - __func__, pos, p_Dpb->fs[pos]->poc, p_H264_Dpb->first_output_poc); - - if (p_Dpb->fs[pos]->poc < p_H264_Dpb->first_output_poc) - p_Dpb->fs[pos]->data_flag |= NODISP_FLAG; - else if (p_Dpb->last_output_poc != INT_MIN) - p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s first_insert_frame %d \n", __func__, p_H264_Dpb->first_insert_frame); - } - if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) { - if (!p_H264_Dpb->without_display_mode && - p_Dpb->fs[pos]->show_frame != false) - p_Dpb->fs[pos]->pre_output = 1; - } else { - if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) { - dpb_print(p_H264_Dpb->decoder_index, 0, - "%s[%d] poc:%d last_output_poc:%d poc_even_odd_flag:%d\n", - __func__, pos, poc, - p_Dpb->last_output_poc, - p_H264_Dpb->poc_even_odd_flag); - dump_dpb(p_Dpb, 1); - } - return 0; - } - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n", - __func__, pos, poc, - p_Dpb->last_output_poc, - p_H264_Dpb->poc_even_odd_flag); - - p_Dpb->last_output_poc = poc; - return 1; - -} - - -void flush_dpb(struct h264_dpb_stru *p_H264_Dpb) -{ - /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - unsigned int i; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - /* diagnostics */ - /* dpb_print(p_H264_Dpb->decoder_index, - *PRINT_FLAG_DPB_DETAIL, - *"Flush remaining frames from the dpb." - *"p_Dpb->size = %d, p_Dpb->used_size = %d\n", - *p_Dpb->size, p_Dpb->used_size); - */ - - if (!p_Dpb->init_done) - return; -/* if(p_Vid->conceal_mode == 0) */ -#if 0 -/* ??? */ - if (p_Vid->conceal_mode != 0) - conceal_non_ref_pics(p_Dpb, 0); -#endif - /* mark all frames unused */ - for (i = 0; i < p_Dpb->used_size; i++) { -#if MVC_EXTENSION_ENABLE - assert(p_Dpb->fs[i]->view_id == p_Dpb->layer_id); -#endif - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - - } - - while (remove_unused_frame_from_dpb(p_H264_Dpb)) - ; - - /* output frames in POC order */ - while (output_frames(p_H264_Dpb, 1)) - ; - - - p_Dpb->last_output_poc = INT_MIN; -} - -static int is_short_term_reference(struct DecodedPictureBuffer *p_Dpb, - struct FrameStore *fs) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - if (fs->is_used == 3) { /* frame */ - if ((fs->frame->used_for_reference) && - (!fs->frame->is_long_term)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "[[%s 1]]", - __func__); - return 1; - } - } - - if (fs->is_used & 1) { /* top field */ - if (fs->top_field) { - if ((fs->top_field->used_for_reference) && - (!fs->top_field->is_long_term)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "[[%s 2]]", - __func__); - return 1; - } - } - } - - if (fs->is_used & 2) { /* bottom field */ - if (fs->bottom_field) { - if ((fs->bottom_field->used_for_reference) && - (!fs->bottom_field->is_long_term)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "[[%s 3]]", - __func__); - return 1; - } - } - } - return 0; -} - -static int is_long_term_reference(struct FrameStore *fs) -{ - - if (fs->is_used == 3) { /* frame */ - if ((fs->frame->used_for_reference) && - (fs->frame->is_long_term)) { - return 1; - } - } - - if (fs->is_used & 1) { /* top field */ - if (fs->top_field) { - if ((fs->top_field->used_for_reference) && - (fs->top_field->is_long_term)) { - return 1; - } - } - } - - if (fs->is_used & 2) { /* bottom field */ - if (fs->bottom_field) { - if ((fs->bottom_field->used_for_reference) && - (fs->bottom_field->is_long_term)) { - return 1; - } - } - } - return 0; -} - -void update_ref_list(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned int i, j; - - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s (%d, %d)\n", __func__, p_Dpb->size, p_Dpb->used_size); - for (i = 0, j = 0; i < p_Dpb->used_size; i++) { -#if 1 - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "fs[%d]: fs %p frame %p is_reference %d %d %d\n", - i, p_Dpb->fs[i], p_Dpb->fs[i]->frame, - p_Dpb->fs[i]->frame != NULL ? - p_Dpb->fs[i]->frame->used_for_reference : 0, - p_Dpb->fs[i]->top_field != NULL ? - p_Dpb->fs[i]->top_field->used_for_reference : - 0, - p_Dpb->fs[i]->bottom_field != NULL ? - p_Dpb->fs[i]->bottom_field->used_for_reference : 0); -#endif - if (is_short_term_reference(p_Dpb, p_Dpb->fs[i])) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "fs_ref[%d]=fs[%d]: fs %p\n", j, i, p_Dpb->fs[i]); - p_Dpb->fs_ref[j++] = p_Dpb->fs[i]; - } - } - - p_Dpb->ref_frames_in_buffer = j; - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s dpb size is %d, %d\n", __func__, p_Dpb->size, j); - while (j < p_Dpb->size) { - /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - *"fs_ref[%d]=null\n", j); - */ - p_Dpb->fs_ref[j++] = NULL; - } -#ifdef ERROR_CHECK - for (i = 0; i < DPB_SIZE_MAX; i++) { - if (p_Dpb->fs_ref[i] == NULL) - p_Dpb->fs_ref[i] = &dummy_fs; - } -#endif -} - -static void update_ltref_list(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned int i, j; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - for (i = 0, j = 0; i < p_Dpb->used_size; i++) { - if (is_long_term_reference(p_Dpb->fs[i])) - p_Dpb->fs_ltref[j++] = p_Dpb->fs[i]; - } - - p_Dpb->ltref_frames_in_buffer = j; - - while (j < p_Dpb->size) - p_Dpb->fs_ltref[j++] = NULL; -#ifdef ERROR_CHECK - for (i = 0; i < DPB_SIZE_MAX; i++) { - if (p_Dpb->fs_ltref[i] == NULL) - p_Dpb->fs_ltref[i] = &dummy_fs; - } -#endif -} - -static void idr_memory_management(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s ref_frames_in_buffer %d ltref_frames_in_buffer %d\n", - __func__, p_Dpb->ref_frames_in_buffer, - p_Dpb->ltref_frames_in_buffer); - - - if (p->no_output_of_prior_pics_flag) { - int i; - for (i = 0; i < p_Dpb->used_size; i++) { - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - if (p_Dpb->fs[i]->is_long_term) - unmark_for_long_term_reference(p_Dpb->fs[i]); - if (!p_Dpb->fs[i]->is_output && !p_Dpb->fs[i]->pre_output) - set_frame_output_flag(p_H264_Dpb, i); - } -#if 0 - /*???*/ - /* free all stored pictures */ - int i; - - for (i = 0; i < p_Dpb->used_size; i++) { - /* reset all reference settings - * free_frame_store(p_Dpb->fs[i]); - * p_Dpb->fs[i] = alloc_frame_store(); - */ - reset_frame_store(p_H264_Dpb, p_Dpb->fs[i]); /* ??? */ - } - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) - p_Dpb->fs_ref[i] = NULL; - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) - p_Dpb->fs_ltref[i] = NULL; - p_Dpb->used_size = 0; -#endif - } else { - flush_dpb(p_H264_Dpb); - } - p_Dpb->last_picture = NULL; - - update_ref_list(p_Dpb); - update_ltref_list(p_Dpb); - p_Dpb->last_output_poc = INT_MIN; - - if (p->long_term_reference_flag) { - p_Dpb->max_long_term_pic_idx = 0; - p->is_long_term = 1; - p->long_term_frame_idx = 0; - } else { - p_Dpb->max_long_term_pic_idx = -1; - p->is_long_term = 0; - } - -#if (MVC_EXTENSION_ENABLE) - p_Dpb->last_output_view_id = -1; -#endif - -} - -static void sliding_window_memory_management( - struct DecodedPictureBuffer *p_Dpb, - struct StorablePicture *p) -{ - unsigned int i; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - unsigned char slide_flag = 0; - unsigned int sliding_margin = imax( - 1, p_Dpb->num_ref_frames) - p_Dpb->ltref_frames_in_buffer; - /* assert (!p->idr_flag); */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s ref_frames_in_buffer %d ltref_frames_in_buffer %d\n", - __func__, p_Dpb->ref_frames_in_buffer, - p_Dpb->ltref_frames_in_buffer); - /* if this is a reference pic with sliding window, - unmark first ref frame */ - if (p_Dpb->ref_frames_in_buffer == sliding_margin) - slide_flag = 1; - /*else if ((h264_error_proc_policy & 0x8) && - (p_Dpb->ref_frames_in_buffer > sliding_margin)) - slide_flag = 1;*/ - - if (slide_flag) { - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->is_reference && - (!(p_Dpb->fs[i]->is_long_term))) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "unmark %d\n", i); - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - update_ref_list(p_Dpb); - break; - } - } - } - - p->is_long_term = 0; -} - -static void check_num_ref(struct DecodedPictureBuffer *p_Dpb) -{ - if ((int)(p_Dpb->ltref_frames_in_buffer + - p_Dpb->ref_frames_in_buffer) > - imax(1, p_Dpb->num_ref_frames)) { - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "Max. number of reference frames exceeded. Invalid stream. lt %d ref %d mum_ref %d\n", - p_Dpb->ltref_frames_in_buffer, - p_Dpb->ref_frames_in_buffer, - p_Dpb->num_ref_frames); - } -} - -void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force) -{ - unsigned int i; - unsigned char *buf = NULL; - unsigned int buf_size = 512, len = 0; - struct h264_dpb_stru *p_H264_Dpb = - container_of(p_Dpb, struct h264_dpb_stru, mDPB); - -#define DPB_STRCAT(args...) do { \ - len += snprintf(buf + len, \ - buf_size - len, ##args);\ - } while (0) - - if ((h264_debug_flag & PRINT_FLAG_DUMP_DPB) == 0 && - force == 0) - return; - - buf = kzalloc(buf_size, GFP_ATOMIC); - if (buf == NULL) - return; - - for (i = 0; i < p_Dpb->used_size; i++) { - len = 0; - memset(buf, 0, buf_size); - DPB_STRCAT("fn=%d is_used %d ", - p_Dpb->fs[i]->frame_num, - p_Dpb->fs[i]->is_used); - - if (p_Dpb->fs[i]->is_used & 1) { - if (p_Dpb->fs[i]->top_field) - DPB_STRCAT("T: poc=%d pic_num=%d ", - p_Dpb->fs[i]->top_field->poc, - p_Dpb->fs[i]->top_field->pic_num); - else - DPB_STRCAT("T: poc=%d ", - p_Dpb->fs[i]->frame->top_poc); - } - if (p_Dpb->fs[i]->is_used & 2) { - if (p_Dpb->fs[i]->bottom_field) - DPB_STRCAT("B: poc=%d pic_num=%d ", - p_Dpb->fs[i]->bottom_field->poc, - p_Dpb->fs[i]->bottom_field->pic_num); - else - DPB_STRCAT("B: poc=%d ", - p_Dpb->fs[i]->frame->bottom_poc); - } - if (p_Dpb->fs[i]->is_used == 3) { - if (p_Dpb->fs[i]->frame != NULL) - DPB_STRCAT("F: poc=%d pic_num=%d ", - p_Dpb->fs[i]->frame->poc, - p_Dpb->fs[i]->frame->pic_num); - else - DPB_STRCAT("fs[%d] frame is null ", i); - } - DPB_STRCAT("G: poc=%d) ", p_Dpb->fs[i]->poc); - if (p_Dpb->fs[i]->is_reference) - DPB_STRCAT("ref (%d) ", p_Dpb->fs[i]->is_reference); - if (p_Dpb->fs[i]->is_long_term) - DPB_STRCAT("lt_ref (%d) ", p_Dpb->fs[i]->is_reference); - if (p_Dpb->fs[i]->is_output) - DPB_STRCAT("out(displayed) "); - if (p_Dpb->fs[i]->pre_output) - DPB_STRCAT("pre_output(in dispq or displaying) "); - if (p_Dpb->fs[i]->is_used == 3) { - if (p_Dpb->fs[i]->frame != NULL && p_Dpb->fs[i]->frame->non_existing) - DPB_STRCAT("non_existing "); - else - DPB_STRCAT("fs[%d] frame is null ", i); - } - DPB_STRCAT("dpb_frame_count %d ", - p_Dpb->fs[i]->dpb_frame_count); - -#if (MVC_EXTENSION_ENABLE) - if (p_Dpb->fs[i]->is_reference) - DPB_STRCAT("view_id (%d) ", p_Dpb->fs[i]->view_id); -#endif - if (p_Dpb->fs[i]->data_flag) { - DPB_STRCAT("data_flag(0x%x)", - p_Dpb->fs[i]->data_flag); - } - DPB_STRCAT(" bufspec %d\n", - p_Dpb->fs[i]->buf_spec_num); - dpb_print(p_H264_Dpb->decoder_index, 0, "%s", buf); - } - - kfree(buf); -} - -/*! - ************************************************************************ - * \brief - * adaptive memory management - * - ************************************************************************ - */ - -static int get_pic_num_x(struct StorablePicture *p, - int difference_of_pic_nums_minus1) -{ - int currPicNum; - - if (p->structure == FRAME) - currPicNum = p->frame_num; - else - currPicNum = 2 * p->frame_num + 1; - - return currPicNum - (difference_of_pic_nums_minus1 + 1); -} - -/*! - ************************************************************************ - * \brief - * Adaptive Memory Management: Mark short term picture unused - ************************************************************************ - */ -static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer - *p_Dpb, struct StorablePicture *p, - int difference_of_pic_nums_minus1) -{ - struct h264_dpb_stru *p_H264_Dpb = - container_of(p_Dpb, struct h264_dpb_stru, mDPB); - int picNumX; - - unsigned int i; - - picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1); - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p->structure == FRAME) { - if ((p_Dpb->fs_ref[i]->is_reference == 3) && - (p_Dpb->fs_ref[i]->is_long_term == 0)) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->frame->pic_num == - picNumX) { - unmark_for_reference(p_Dpb, - p_Dpb->fs_ref[i]); - return; - } - } - } else { - if ((p_Dpb->fs_ref[i]->is_reference & 1) && - (!(p_Dpb->fs_ref[i]->is_long_term & 1))) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->top_field->pic_num == - picNumX) { - p_Dpb->fs_ref[i]-> - top_field->used_for_reference = 0; - p_Dpb->fs_ref[i]->is_reference &= 2; - if ((p_Dpb->fs_ref[i]->is_used == 3) -#ifdef ERROR_CHECK - && p_Dpb->fs_ref[i]->frame -#endif - ) { - p_Dpb->fs_ref[i]->frame-> - used_for_reference = 0; - } - return; - } - } - if ((p_Dpb->fs_ref[i]->is_reference & 2) && - (!(p_Dpb->fs_ref[i]->is_long_term & 2))) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->bottom_field->pic_num == - picNumX) { - p_Dpb->fs_ref[i]->bottom_field-> - used_for_reference = 0; - p_Dpb->fs_ref[i]->is_reference &= 1; - if ((p_Dpb->fs_ref[i]->is_used == 3) -#ifdef ERROR_CHECK - && p_Dpb->fs_ref[i]->frame -#endif - ) { - p_Dpb->fs_ref[i]->frame-> - used_for_reference = 0; - } - return; - } - } - } - } -} - -/*! - ************************************************************************ - * \brief - * Adaptive Memory Management: Mark long term picture unused - ************************************************************************ - */ -static void mm_unmark_long_term_for_reference(struct DecodedPictureBuffer - *p_Dpb, struct StorablePicture *p, int long_term_pic_num) -{ - unsigned int i; - - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p->structure == FRAME) { - if ((p_Dpb->fs_ltref[i]->is_reference == 3) && - (p_Dpb->fs_ltref[i]->is_long_term == 3)) { - if (p_Dpb->fs_ltref[i]->frame-> - long_term_pic_num == - long_term_pic_num) { - unmark_for_long_term_reference( - p_Dpb->fs_ltref[i]); - } - } - } else { - if ((p_Dpb->fs_ltref[i]->is_reference & 1) && - ((p_Dpb->fs_ltref[i]->is_long_term & 1))) { - if (p_Dpb->fs_ltref[i]->top_field-> - long_term_pic_num == - long_term_pic_num) { - p_Dpb->fs_ltref[i]->top_field-> - used_for_reference = 0; - p_Dpb->fs_ltref[i]->top_field-> - is_long_term = 0; - p_Dpb->fs_ltref[i]->is_reference &= 2; - p_Dpb->fs_ltref[i]->is_long_term &= 2; - if (p_Dpb->fs_ltref[i]->is_used == 3) { - p_Dpb->fs_ltref[i]->frame-> - used_for_reference = 0; - p_Dpb->fs_ltref[i]->frame-> - is_long_term = 0; - } - return; - } - } - if ((p_Dpb->fs_ltref[i]->is_reference & 2) && - ((p_Dpb->fs_ltref[i]->is_long_term & 2))) { - if (p_Dpb->fs_ltref[i]->bottom_field-> - long_term_pic_num == - long_term_pic_num) { - p_Dpb->fs_ltref[i]->bottom_field-> - used_for_reference = 0; - p_Dpb->fs_ltref[i]->bottom_field-> - is_long_term = 0; - p_Dpb->fs_ltref[i]->is_reference &= 1; - p_Dpb->fs_ltref[i]->is_long_term &= 1; - if (p_Dpb->fs_ltref[i]->is_used == 3) { - p_Dpb->fs_ltref[i]->frame-> - used_for_reference = 0; - p_Dpb->fs_ltref[i]->frame-> - is_long_term = 0; - } - return; - } - } - } - } -} - - -/*! - ************************************************************************ - * \brief - * Mark a long-term reference frame or complementary - * field pair unused for referemce - ************************************************************************ - */ -static void unmark_long_term_frame_for_reference_by_frame_idx( - struct DecodedPictureBuffer *p_Dpb, int long_term_frame_idx) -{ - unsigned int i; - - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->long_term_frame_idx == - long_term_frame_idx) - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - } -} - - -static void unmark1(struct DecodedPictureBuffer *p_Dpb, - unsigned int curr_frame_num, int i) -{ - if (p_Dpb->last_picture) { - /*if ((p_Dpb->last_picture != p_Dpb->fs_ltref[i]) || - p_Dpb->last_picture->frame_num != curr_frame_num) {*/ - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - /*} else { - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - }*/ - } -} - -static void unmark2(struct DecodedPictureBuffer *p_Dpb, - int curr_pic_num, int i) -{ - if ((p_Dpb->fs_ltref[i]->frame_num) != - (unsigned int)(curr_pic_num >> 1)) - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); -} - -static void unmark3_top(struct DecodedPictureBuffer *p_Dpb, - unsigned int curr_frame_num, int curr_pic_num, int mark_current, int i) -{ - if (p_Dpb->fs_ltref[i]->is_long_term == 3) { - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - } else { - if (p_Dpb->fs_ltref[i]->is_long_term == 1) { - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - } else { - if (mark_current) - unmark1(p_Dpb, curr_frame_num, i); - else - unmark2(p_Dpb, curr_pic_num, i); - } - } -} - -static void unmark3_bottom(struct DecodedPictureBuffer *p_Dpb, - unsigned int curr_frame_num, int curr_pic_num, int mark_current, int i) -{ - if (p_Dpb->fs_ltref[i]->is_long_term == 2) { - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - } else { - if (mark_current) - unmark1(p_Dpb, curr_frame_num, i); - else - unmark2(p_Dpb, curr_pic_num, i); - } -} - -static void unmark_long_term_field_for_reference_by_frame_idx( - struct DecodedPictureBuffer *p_Dpb, enum PictureStructure structure, - int long_term_frame_idx, int mark_current, unsigned int curr_frame_num, - int curr_pic_num) -{ - struct VideoParameters *p_Vid = p_Dpb->p_Vid; - unsigned int i; - - /* assert(structure!=FRAME); */ - if (curr_pic_num < 0) - curr_pic_num += (2 * p_Vid->max_frame_num); - - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->long_term_frame_idx == - long_term_frame_idx) { - if (structure == TOP_FIELD) - unmark3_top(p_Dpb, curr_frame_num, - curr_pic_num, mark_current, i); - - if (structure == BOTTOM_FIELD) - unmark3_bottom(p_Dpb, curr_frame_num, - curr_pic_num, mark_current, i); - } - } -} - -/*! - ************************************************************************ - * \brief - * mark a picture as long-term reference - ************************************************************************ - */ -static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb, - struct StorablePicture *p, - int long_term_frame_idx, int picNumX) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - unsigned int i; - int add_top, add_bottom; - - if (p->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference == 3) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->frame-> - is_long_term) && - (p_Dpb->fs_ref[i]->frame->pic_num == - picNumX)) { - p_Dpb->fs_ref[i]-> - long_term_frame_idx = - p_Dpb->fs_ref[i]->frame-> - long_term_frame_idx = - long_term_frame_idx; - p_Dpb->fs_ref[i]->frame-> - long_term_pic_num = - long_term_frame_idx; - p_Dpb->fs_ref[i]->frame-> - is_long_term = 1; - - if (p_Dpb->fs_ref[i]->top_field && - p_Dpb->fs_ref[i]->bottom_field) { - p_Dpb->fs_ref[i]->top_field-> - long_term_frame_idx = - p_Dpb->fs_ref[i]-> - bottom_field-> - long_term_frame_idx = - long_term_frame_idx; - p_Dpb->fs_ref[i]->top_field-> - long_term_pic_num = - long_term_frame_idx; - p_Dpb->fs_ref[i]-> - bottom_field-> - long_term_pic_num = - long_term_frame_idx; - - p_Dpb->fs_ref[i]->top_field-> - is_long_term = - p_Dpb->fs_ref[i]-> - bottom_field-> - is_long_term - = 1; - - } - p_Dpb->fs_ref[i]->is_long_term = 3; - return; - } - } - } - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "Warning: reference frame for long term marking not found\n"); - } else { - if (p->structure == TOP_FIELD) { - add_top = 1; - add_bottom = 0; - } else { - add_top = 0; - add_bottom = 1; - } - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference & 1) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->top_field-> - is_long_term) && - (p_Dpb->fs_ref[i]->top_field->pic_num == - picNumX)) { - if ((p_Dpb->fs_ref[i]-> - is_long_term) && - (p_Dpb->fs_ref[i]-> - long_term_frame_idx != - long_term_frame_idx)) { - dpb_print(p_H264_Dpb-> - decoder_index, - PRINT_FLAG_DPB_DETAIL, - "Warning: assigning long_term_frame_idx different from other field\n"); - } - - p_Dpb->fs_ref[i]-> - long_term_frame_idx = - p_Dpb->fs_ref[i]->top_field-> - long_term_frame_idx - = long_term_frame_idx; - p_Dpb->fs_ref[i]->top_field-> - long_term_pic_num = - 2 * long_term_frame_idx + - add_top; - p_Dpb->fs_ref[i]->top_field-> - is_long_term = 1; - p_Dpb->fs_ref[i]->is_long_term |= 1; - if ((p_Dpb->fs_ref[i]->is_long_term - == 3) -#ifdef ERROR_CHECK - && p_Dpb->fs_ref[i]->frame -#endif - ) { - p_Dpb->fs_ref[i]->frame-> - is_long_term = 1; - p_Dpb->fs_ref[i]->frame-> - long_term_frame_idx = - p_Dpb->fs_ref[i]-> - frame-> - long_term_pic_num = - long_term_frame_idx; - } - return; - } - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->bottom_field-> - is_long_term) && - (p_Dpb->fs_ref[i]->bottom_field->pic_num - == picNumX)) { - if ((p_Dpb->fs_ref[i]-> - is_long_term) && - (p_Dpb->fs_ref[i]-> - long_term_frame_idx != - long_term_frame_idx)) { - dpb_print(p_H264_Dpb-> - decoder_index, - PRINT_FLAG_DPB_DETAIL, - "Warning: assigning long_term_frame_idx different from other field\n"); - } - - p_Dpb->fs_ref[i]-> - long_term_frame_idx = - p_Dpb->fs_ref[i]->bottom_field - ->long_term_frame_idx - = long_term_frame_idx; - p_Dpb->fs_ref[i]->bottom_field-> - long_term_pic_num = 2 * - long_term_frame_idx + - add_bottom; - p_Dpb->fs_ref[i]->bottom_field-> - is_long_term = 1; - p_Dpb->fs_ref[i]->is_long_term |= 2; - if ((p_Dpb->fs_ref[i]-> - is_long_term == 3) -#ifdef ERROR_CHECK - && p_Dpb->fs_ref[i]->frame -#endif - ) { - p_Dpb->fs_ref[i]->frame-> - is_long_term = 1; - p_Dpb->fs_ref[i]->frame-> - long_term_frame_idx = - p_Dpb->fs_ref[i]-> - frame-> - long_term_pic_num = - long_term_frame_idx; - } - return; - } - } - } - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "Warning: reference field for long term marking not found\n"); - } -} - - -/*! - ************************************************************************ - * \brief - * Assign a long term frame index to a short term picture - ************************************************************************ - */ -static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb, - struct StorablePicture *p, int difference_of_pic_nums_minus1, - int long_term_frame_idx) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - int picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1); - - /* remove frames/fields with same long_term_frame_idx */ - if (p->structure == FRAME) { - unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb, - long_term_frame_idx); - } else { - unsigned int i; - enum PictureStructure structure = FRAME; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference & 1) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->top_field-> - pic_num == picNumX) { - structure = TOP_FIELD; - break; - } - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->bottom_field-> - pic_num == picNumX) { - structure = BOTTOM_FIELD; - break; - } - } - } - if (structure == FRAME) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "field for long term marking not found %d", - 200); - } - - unmark_long_term_field_for_reference_by_frame_idx(p_Dpb, - structure, - long_term_frame_idx, 0, 0, picNumX); - } - - mark_pic_long_term(p_Dpb, p, long_term_frame_idx, picNumX); -} - -/*! - ************************************************************************ - * \brief - * Set new max long_term_frame_idx - ************************************************************************ - */ -static void mm_update_max_long_term_frame_idx(struct DecodedPictureBuffer - *p_Dpb, int max_long_term_frame_idx_plus1) -{ - unsigned int i; - - p_Dpb->max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1; - - /* check for invalid frames */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->long_term_frame_idx > - p_Dpb->max_long_term_pic_idx) { - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); - } - } -} - - -/*! - ************************************************************************ - * \brief - * Mark all long term reference pictures unused for reference - ************************************************************************ - */ -static void mm_unmark_all_long_term_for_reference(struct DecodedPictureBuffer - *p_Dpb) -{ - mm_update_max_long_term_frame_idx(p_Dpb, 0); -} - -/*! - ************************************************************************ - * \brief - * Mark all short term reference pictures unused for reference - ************************************************************************ - */ -static void mm_unmark_all_short_term_for_reference(struct DecodedPictureBuffer - *p_Dpb) -{ - unsigned int i; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) - unmark_for_reference(p_Dpb, p_Dpb->fs_ref[i]); - update_ref_list(p_Dpb); -} - - -/*! - ************************************************************************ - * \brief - * Mark the current picture used for long term reference - ************************************************************************ - */ -static void mm_mark_current_picture_long_term(struct DecodedPictureBuffer - *p_Dpb, struct StorablePicture *p, int long_term_frame_idx) -{ - /* remove long term pictures with same long_term_frame_idx */ - if (p->structure == FRAME) { - unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb, - long_term_frame_idx); - } else { - unmark_long_term_field_for_reference_by_frame_idx(p_Dpb, - p->structure, long_term_frame_idx, - 1, p->pic_num, 0); - } - - p->is_long_term = 1; - p->long_term_frame_idx = long_term_frame_idx; -} - -static void adaptive_memory_management(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - struct DecRefPicMarking_s *tmp_drpm; - struct VideoParameters *p_Vid = p_Dpb->p_Vid; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - p_Vid->last_has_mmco_5 = 0; - - /* assert (!p->idr_flag); */ - /* assert (p->adaptive_ref_pic_buffering_flag); */ - - while (p->dec_ref_pic_marking_buffer) { - tmp_drpm = p->dec_ref_pic_marking_buffer; - switch (tmp_drpm->memory_management_control_operation) { - case 0: - if (tmp_drpm->Next != NULL) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "error, memory_management_control_operation = 0 not last operation in buffer\n"); - break; - case 1: - mm_unmark_short_term_for_reference(p_Dpb, p, - tmp_drpm->difference_of_pic_nums_minus1); - update_ref_list(p_Dpb); - break; - case 2: - mm_unmark_long_term_for_reference(p_Dpb, p, - tmp_drpm->long_term_pic_num); - update_ltref_list(p_Dpb); - break; - case 3: - mm_assign_long_term_frame_idx(p_Dpb, p, - tmp_drpm->difference_of_pic_nums_minus1, - tmp_drpm->long_term_frame_idx); - update_ref_list(p_Dpb); - update_ltref_list(p_Dpb); - break; - case 4: - mm_update_max_long_term_frame_idx(p_Dpb, - tmp_drpm->max_long_term_frame_idx_plus1); - update_ltref_list(p_Dpb); - break; - case 5: - mm_unmark_all_short_term_for_reference(p_Dpb); - mm_unmark_all_long_term_for_reference(p_Dpb); - p_Vid->last_has_mmco_5 = 1; - break; - case 6: - mm_mark_current_picture_long_term(p_Dpb, p, - tmp_drpm->long_term_frame_idx); - check_num_ref(p_Dpb); - break; - default: - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "error, invalid memory_management_control_operation in buffer\n"); - } - p->dec_ref_pic_marking_buffer = tmp_drpm->Next; - /* free (tmp_drpm); */ - } - if (p_Vid->last_has_mmco_5) { - p->pic_num = p->frame_num = 0; - - switch (p->structure) { - case TOP_FIELD: { - /* p->poc = p->top_poc = p_Vid->toppoc =0; */ - p->poc = p->top_poc = 0; - break; - } - case BOTTOM_FIELD: { - /* p->poc = p->bottom_poc = p_Vid->bottompoc = 0; */ - p->poc = p->bottom_poc = 0; - break; - } - case FRAME: { - p->top_poc -= p->poc; - p->bottom_poc -= p->poc; - - /* p_Vid->toppoc = p->top_poc; */ - /* p_Vid->bottompoc = p->bottom_poc; */ - - p->poc = imin(p->top_poc, p->bottom_poc); - /* p_Vid->framepoc = p->poc; */ - break; - } - } - /* currSlice->ThisPOC = p->poc; */ -#if (MVC_EXTENSION_ENABLE) - if (p->view_id == 0) { - flush_dpb(p_Vid->p_Dpb_layer[0]); - flush_dpb(p_Vid->p_Dpb_layer[1]); - } else { - flush_dpb(p_Dpb); - } -#else - flush_dpb(p_H264_Dpb); -#endif - } -} - - -int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p, - unsigned char data_flag) -{ - /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */ - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - unsigned int i, frame_outside_count = 0; -#if 0 - int poc, pos; -#endif - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s p_Vid %p\n", __func__, p_Vid); - - /* picture error concealment */ - - /* diagnostics */ - /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - * "Storing (%s) non-ref pic with frame_num #%d\n", - * (p->type == FRAME)?"FRAME":(p->type == TOP_FIELD)? - * "TOP_FIELD":"BOTTOM_FIELD", p->pic_num); - */ - /* if frame, check for new store, */ - /* assert (p!=NULL); */ - - p_Vid->last_has_mmco_5 = 0; - p_Vid->last_pic_bottom_field = (p->structure == BOTTOM_FIELD); - if (p->idr_flag) { - idr_memory_management(p_H264_Dpb, p); - if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) - p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE; -#if 0 -/* ??? */ - /* picture error concealment */ - memset(p_Vid->pocs_in_dpb, 0, sizeof(int) * 100); -#endif - } else { -#if 1 -/* ??? */ - /* adaptive memory management */ - if (p->used_for_reference && - (p->adaptive_ref_pic_buffering_flag)) - adaptive_memory_management(p_H264_Dpb, p); -#endif - } - - if ((p->structure == TOP_FIELD) || (p->structure == BOTTOM_FIELD)) { - /* check for frame store with same pic_number */ - if (p_Dpb->last_picture) { - if ((int)p_Dpb->last_picture->frame_num == - p->pic_num) { - if (((p->structure == TOP_FIELD) && - (p_Dpb->last_picture->is_used == 2)) || - ((p->structure == BOTTOM_FIELD) && - (p_Dpb->last_picture->is_used == 1))) { - if ((p->used_for_reference && - (p_Dpb->last_picture-> - is_orig_reference != 0)) || - (!p->used_for_reference && - (p_Dpb->last_picture-> - is_orig_reference == 0))) { - insert_picture_in_dpb( - p_H264_Dpb, - p_Dpb->last_picture, - p, data_flag); - update_ref_list(p_Dpb); - update_ltref_list(p_Dpb); - dump_dpb(p_Dpb, 0); - p_Dpb->last_picture = NULL; - return 0; - } - } - } - } - } - /* this is a frame or a field which has no stored - * complementary field - */ - - /* sliding window, if necessary */ - if ((!p->idr_flag) && (p->used_for_reference && - (!p->adaptive_ref_pic_buffering_flag))) { - sliding_window_memory_management(p_Dpb, p); - } - - /* picture error concealment */ - if (p_Vid->conceal_mode != 0) { - for (i = 0; i < p_Dpb->size; i++) - if (p_Dpb->fs[i]->is_reference) - p_Dpb->fs[i]->concealment_reference = 1; - } - - while (remove_unused_frame_from_dpb(p_H264_Dpb)) - ; - - while (output_frames(p_H264_Dpb, 0)) - ; - - /* check for duplicate frame number in short term reference buffer */ - if ((p->used_for_reference) && (!p->is_long_term)) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) - continue; -#endif - if (p_Dpb->fs_ref[i]->frame_num == p->frame_num) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "duplicate frame_num in short-term reference picture buffer %d\n", - 500); - if (p_Dpb->fs_ref[i]->dpb_frame_count == p_H264_Dpb->dpb_frame_count) { - dpb_print(p_H264_Dpb->decoder_index, - 0, "duplicate frame, no insert to dpb\n"); - return -2; - } else { - dpb_print(p_H264_Dpb->decoder_index, - 0, "duplicate frame_num release defore ref\n"); - unmark_for_reference(p_Dpb, p_Dpb->fs_ref[i]); - update_ref_list(p_Dpb); - } - } - } - } - /* store at end of buffer */ - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s p_Dpb->used_size %d\n", __func__, p_Dpb->used_size); - if (p_Dpb->used_size >= p_Dpb->size) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s Error: used_sizd %d is large than dpb size\r\n", - __func__, p_Dpb->used_size); - /*h264_debug_flag |= PRINT_FLAG_DUMP_DPB;*/ - dump_dpb(p_Dpb, 0); - return -1; - } - - insert_picture_in_dpb(p_H264_Dpb, p_Dpb->fs[p_Dpb->used_size], - p, data_flag); - - /* picture error concealment */ - if (p->idr_flag) - p_Vid->earlier_missing_poc = 0; - - if (p->structure != FRAME) - p_Dpb->last_picture = p_Dpb->fs[p_Dpb->used_size]; - else - p_Dpb->last_picture = NULL; - - p_Dpb->used_size++; -#if 0 -/* ??? */ - if (p_Vid->conceal_mode != 0) - p_Vid->pocs_in_dpb[p_Dpb->used_size - 1] = p->poc; -#endif - update_ref_list(p_Dpb); - update_ltref_list(p_Dpb); - - check_num_ref(p_Dpb); - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->pre_output) - frame_outside_count++; - } - - if (p_H264_Dpb->fast_output_enable == H264_OUTPUT_MODE_FAST) - i = 1; - else - i = 0; - - if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)) { - while (output_frames(p_H264_Dpb, i)) - ; - } - - dump_dpb(p_Dpb, 0); - p_Dpb->first_pic_done = 1; /*by rain*/ - - return 0; -} - -void bufmgr_post(struct h264_dpb_stru *p_H264_Dpb) -{ - /*VideoParameters *p_Vid = p_Dpb->p_Vid;*/ - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - - if (p_Vid->last_has_mmco_5) - p_Vid->pre_frame_num = 0; -} -/********************************** - * - * Initialize reference lists - ********************************** - */ -#define __COMPARE(context, p1, p2) comp(p1, p2) -#define __SHORTSORT(lo, hi, width, comp, context) \ - shortsort(lo, hi, width, comp) -#define CUTOFF 8 /* testing shows that this is good value */ -#define STKSIZ (8*sizeof(void *) - 2) - -#undef swap -static void swap( - char *a, - char *b, - size_t width -) -{ - char tmp; - - if (a != b) - /* Do the swap one character at a time to avoid potential - * alignment problems. - */ - while (width--) { - tmp = *a; - *a++ = *b; - *b++ = tmp; - } -} - -static void shortsort( - char *lo, - char *hi, - size_t width, - int (*comp)(const void *, const void *) -) -{ - char *p, *max; - - /* Note: in assertions below, i and j are alway inside original - * bound of array to sort. - */ - - while (hi > lo) { - /* A[i] <= A[j] for i <= j, j > hi */ - max = lo; - for (p = lo + width; p <= hi; p += width) { - /* A[i] <= A[max] for lo <= i < p */ - if (__COMPARE(context, p, max) > 0) - max = p; - /* A[i] <= A[max] for lo <= i <= p */ - } - - /* A[i] <= A[max] for lo <= i <= hi */ - - swap(max, hi, width); - - /* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j, - * j >= hi - */ - - hi -= width; - - /* A[i] <= A[j] for i <= j, j > hi, loop top condition - * established - */ - } - /* A[i] <= A[j] for i <= j, j > lo, which implies A[i] <= A[j] - * for i < j, so array is sorted - */ -} - -static void qsort( - void *base, - size_t num, - size_t width, - int (*comp)(const void *, const void *) -) -{ - char *lo, *hi; /* ends of sub-array currently sorting */ - char *mid; /* points to middle of subarray */ - char *loguy, *higuy; /* traveling pointers for partition step */ - size_t size; /* size of the sub-array */ - char *lostk[STKSIZ], *histk[STKSIZ]; - int stkptr; - -/* stack for saving sub-array to be - * processed - */ -#if 0 - /* validation section */ - _VALIDATE_RETURN_VOID(base != NULL || num == 0, EINVAL); - _VALIDATE_RETURN_VOID(width > 0, EINVAL); - _VALIDATE_RETURN_VOID(comp != NULL, EINVAL); -#endif - if (num < 2) - return; /* nothing to do */ - - stkptr = 0; /* initialize stack */ - - lo = (char *)base; - hi = (char *)base + width * (num - 1); /* initialize limits */ - - /* this entry point is for pseudo-recursion calling: setting - * lo and hi and jumping to here is like recursion, but stkptr is - * preserved, locals aren't, so we preserve stuff on the stack - */ -recurse: - - size = (hi - lo) / width + 1; /* number of el's to sort */ - - /* below a certain size, it is faster to use a O(n^2) sorting method */ - if (size <= CUTOFF) { - __SHORTSORT(lo, hi, width, comp, context); - } else { - /* First we pick a partitioning element. The efficiency of - * the algorithm demands that we find one that is approximately - * the median of the values, but also that we select one fast. - * We choose the median of the first, middle, and last - * elements, to avoid bad performance in the face of already - * sorted data, or data that is made up of multiple sorted - * runs appended together. Testing shows that a - * median-of-three algorithm provides better performance than - * simply picking the middle element for the latter case. - */ - - mid = lo + (size / 2) * width; /* find middle element */ - - /* Sort the first, middle, last elements into order */ - if (__COMPARE(context, lo, mid) > 0) - swap(lo, mid, width); - if (__COMPARE(context, lo, hi) > 0) - swap(lo, hi, width); - if (__COMPARE(context, mid, hi) > 0) - swap(mid, hi, width); - - /* We now wish to partition the array into three pieces, one - * consisting of elements <= partition element, one of elements - * equal to the partition element, and one of elements > than - * it. This is done below; comments indicate conditions - * established at every step. - */ - - loguy = lo; - higuy = hi; - - /* Note that higuy decreases and loguy increases on every - * iteration, so loop must terminate. - */ - for (;;) { - /* lo <= loguy < hi, lo < higuy <= hi, - * A[i] <= A[mid] for lo <= i <= loguy, - * A[i] > A[mid] for higuy <= i < hi, - * A[hi] >= A[mid] - */ - - /* The doubled loop is to avoid calling comp(mid,mid), - * since some existing comparison funcs don't work - * when passed the same value for both pointers. - */ - - if (mid > loguy) { - do { - loguy += width; - } while (loguy < mid && - __COMPARE(context, loguy, mid) <= 0); - } - if (mid <= loguy) { - do { - loguy += width; - } while (loguy <= hi && - __COMPARE(context, loguy, mid) <= 0); - } - - /* lo < loguy <= hi+1, A[i] <= A[mid] for - * lo <= i < loguy, - * either loguy > hi or A[loguy] > A[mid] - */ - - do { - higuy -= width; - } while (higuy > mid && - __COMPARE(context, higuy, mid) > 0); - - /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi, - * either higuy == lo or A[higuy] <= A[mid] - */ - - if (higuy < loguy) - break; - - /* if loguy > hi or higuy == lo, then we would have - * exited, so A[loguy] > A[mid], A[higuy] <= A[mid], - * loguy <= hi, higuy > lo - */ - - swap(loguy, higuy, width); - - /* If the partition element was moved, follow it. - * Only need to check for mid == higuy, since before - * the swap, A[loguy] > A[mid] implies loguy != mid. - */ - - if (mid == higuy) - mid = loguy; - - /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition - * at top of loop is re-established - */ - } - - /* A[i] <= A[mid] for lo <= i < loguy, - * A[i] > A[mid] for higuy < i < hi, - * A[hi] >= A[mid] - * higuy < loguy - * implying: - * higuy == loguy-1 - * or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] - */ - - /* Find adjacent elements equal to the partition element. The - * doubled loop is to avoid calling comp(mid,mid), since some - * existing comparison funcs don't work when passed the same - * value for both pointers. - */ - - higuy += width; - if (mid < higuy) { - do { - higuy -= width; - } while (higuy > mid && - __COMPARE(context, higuy, mid) == 0); - } - if (mid >= higuy) { - do { - higuy -= width; - } while (higuy > lo && - __COMPARE(context, higuy, mid) == 0); - } - - /* OK, now we have the following: - * higuy < loguy - * lo <= higuy <= hi - * A[i] <= A[mid] for lo <= i <= higuy - * A[i] == A[mid] for higuy < i < loguy - * A[i] > A[mid] for loguy <= i < hi - * A[hi] >= A[mid] - */ - - /* We've finished the partition, now we want to sort the - * subarrays [lo, higuy] and [loguy, hi]. - * We do the smaller one first to minimize stack usage. - * We only sort arrays of length 2 or more. - */ - - if (higuy - lo >= hi - loguy) { - if (lo < higuy) { - lostk[stkptr] = lo; - histk[stkptr] = higuy; - ++stkptr; - } /* save big recursion for later */ - - if (loguy < hi) { - lo = loguy; - goto recurse; /* do small recursion */ - } - } else { - if (loguy < hi) { - lostk[stkptr] = loguy; - histk[stkptr] = hi; - ++stkptr; /* save big recursion for later */ - } - - if (lo < higuy) { - hi = higuy; - goto recurse; /* do small recursion */ - } - } - } - - /* We have sorted the array, except for any pending sorts on the stack. - * Check if there are any, and do them. - */ - - --stkptr; - if (stkptr >= 0) { - lo = lostk[stkptr]; - hi = histk[stkptr]; - goto recurse; /* pop subarray from stack */ - } else - return; /* all subarrays done */ -} - -/*! - ************************************************************************ - * \brief - * compares two stored pictures by picture number for qsort in - * descending order - * - ************************************************************************ - */ -static inline int compare_pic_by_pic_num_desc(const void *arg1, - const void *arg2) -{ - int pic_num1 = (*(struct StorablePicture **)arg1)->pic_num; - int pic_num2 = (*(struct StorablePicture **)arg2)->pic_num; - - if (pic_num1 < pic_num2) - return 1; - if (pic_num1 > pic_num2) - return -1; - else - return 0; -} - -/*! - ************************************************************************ - * \brief - * compares two stored pictures by picture number for qsort in - * descending order - * - ************************************************************************ - */ -static inline int compare_pic_by_lt_pic_num_asc(const void *arg1, - const void *arg2) -{ - int long_term_pic_num1 = - (*(struct StorablePicture **)arg1)->long_term_pic_num; - int long_term_pic_num2 = - (*(struct StorablePicture **)arg2)->long_term_pic_num; - - if (long_term_pic_num1 < long_term_pic_num2) - return -1; - if (long_term_pic_num1 > long_term_pic_num2) - return 1; - else - return 0; -} - -/*! - ************************************************************************ - * \brief - * compares two frame stores by pic_num for qsort in descending order - * - ************************************************************************ - */ -static inline int compare_fs_by_frame_num_desc(const void *arg1, - const void *arg2) -{ - int frame_num_wrap1 = (*(struct FrameStore **)arg1)->frame_num_wrap; - int frame_num_wrap2 = (*(struct FrameStore **)arg2)->frame_num_wrap; - - if (frame_num_wrap1 < frame_num_wrap2) - return 1; - if (frame_num_wrap1 > frame_num_wrap2) - return -1; - else - return 0; -} - - -/*! - ************************************************************************ - * \brief - * compares two frame stores by lt_pic_num for qsort in descending order - * - ************************************************************************ - */ -static inline int compare_fs_by_lt_pic_idx_asc(const void *arg1, - const void *arg2) -{ - int long_term_frame_idx1 = - (*(struct FrameStore **)arg1)->long_term_frame_idx; - int long_term_frame_idx2 = - (*(struct FrameStore **)arg2)->long_term_frame_idx; - - if (long_term_frame_idx1 < long_term_frame_idx2) - return -1; - else if (long_term_frame_idx1 > long_term_frame_idx2) - return 1; - else - return 0; -} - - -/*! - ************************************************************************ - * \brief - * compares two stored pictures by poc for qsort in ascending order - * - ************************************************************************ - */ -static inline int compare_pic_by_poc_asc(const void *arg1, const void *arg2) -{ - int poc1 = (*(struct StorablePicture **)arg1)->poc; - int poc2 = (*(struct StorablePicture **)arg2)->poc; - - if (poc1 < poc2) - return -1; - else if (poc1 > poc2) - return 1; - else - return 0; -} - - -/*! - ************************************************************************ - * \brief - * compares two stored pictures by poc for qsort in descending order - * - ************************************************************************ - */ -static inline int compare_pic_by_poc_desc(const void *arg1, const void *arg2) -{ - int poc1 = (*(struct StorablePicture **)arg1)->poc; - int poc2 = (*(struct StorablePicture **)arg2)->poc; - - if (poc1 < poc2) - return 1; - else if (poc1 > poc2) - return -1; - else - return 0; -} - - -/*! - ************************************************************************ - * \brief - * compares two frame stores by poc for qsort in ascending order - * - ************************************************************************ - */ -static inline int compare_fs_by_poc_asc(const void *arg1, const void *arg2) -{ - int poc1 = (*(struct FrameStore **)arg1)->poc; - int poc2 = (*(struct FrameStore **)arg2)->poc; - - if (poc1 < poc2) - return -1; - else if (poc1 > poc2) - return 1; - else - return 0; -} - - -/*! - ************************************************************************ - * \brief - * compares two frame stores by poc for qsort in descending order - * - ************************************************************************ - */ -static inline int compare_fs_by_poc_desc(const void *arg1, const void *arg2) -{ - int poc1 = (*(struct FrameStore **)arg1)->poc; - int poc2 = (*(struct FrameStore **)arg2)->poc; - - if (poc1 < poc2) - return 1; - else if (poc1 > poc2) - return -1; - else - return 0; -} - -/*! - ************************************************************************ - * \brief - * returns true, if picture is short term reference picture - * - ************************************************************************ - */ -static inline int is_short_ref(struct StorablePicture *s) -{ -#ifdef ERROR_CHECK - return (s && - (s->used_for_reference) && (!(s->is_long_term))); -#else - return (s->used_for_reference) && (!(s->is_long_term)); -#endif -} - - -/*! - ************************************************************************ - * \brief - * returns true, if picture is long term reference picture - * - ************************************************************************ - */ -static inline int is_long_ref(struct StorablePicture *s) -{ -#ifdef ERROR_CHECK - return (s && - s->used_for_reference) && (s->is_long_term); -#else - return (s->used_for_reference) && (s->is_long_term); -#endif -} - -/*! - ************************************************************************ - * \brief - * Initialize reference lists for a P Slice - * - ************************************************************************ - */ -/*! - ************************************************************************ - * \brief - * Generates a alternating field list from a given FrameStore list - * - ************************************************************************ - */ -static void gen_pic_list_from_frame_list(enum PictureStructure currStructure, - struct FrameStore **fs_list, int list_idx, - struct StorablePicture **list, - char *list_size, int long_term) -{ - int top_idx = 0; - int bot_idx = 0; - - int (*is_ref)(struct StorablePicture *s) = (long_term) ? is_long_ref : - is_short_ref; - - - if (currStructure == TOP_FIELD) { - while ((top_idx < list_idx) || (bot_idx < list_idx)) { - for (; top_idx < list_idx; top_idx++) { - if (fs_list[top_idx]->is_used & 1) { - if (is_ref(fs_list[top_idx]-> - top_field)) { - /* short term ref pic */ - list[(short) *list_size] = - fs_list[top_idx]->top_field; - (*list_size)++; - top_idx++; - break; - } - } - } - for (; bot_idx < list_idx; bot_idx++) { - if (fs_list[bot_idx]->is_used & 2) { - if (is_ref(fs_list[bot_idx]-> - bottom_field)) { - /* short term ref pic */ - list[(short) *list_size] = - fs_list[bot_idx]->bottom_field; - (*list_size)++; - bot_idx++; - break; - } - } - } - } - } - if (currStructure == BOTTOM_FIELD) { - while ((top_idx < list_idx) || (bot_idx < list_idx)) { - for (; bot_idx < list_idx; bot_idx++) { - if (fs_list[bot_idx]->is_used & 2) { - if (is_ref(fs_list[bot_idx]-> - bottom_field)) { - /* short term ref pic */ - list[(short) *list_size] = - fs_list[bot_idx]->bottom_field; - (*list_size)++; - bot_idx++; - break; - } - } - } - for (; top_idx < list_idx; top_idx++) { - if (fs_list[top_idx]->is_used & 1) { - if (is_ref(fs_list[top_idx]-> - top_field)) { - /* short term ref pic */ - list[(short) *list_size] = - fs_list[top_idx]->top_field; - (*list_size)++; - top_idx++; - break; - } - } - } - } - } -} - -static void init_lists_p_slice(struct Slice *currSlice) -{ - struct VideoParameters *p_Vid = currSlice->p_Vid; - struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - - unsigned int i; - - int list0idx = 0; - int listltidx = 0; - - struct FrameStore **fs_list0; - struct FrameStore **fs_listlt; - -#if (MVC_EXTENSION_ENABLE) - currSlice->listinterviewidx0 = 0; - currSlice->listinterviewidx1 = 0; -#endif - - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame-> - used_for_reference) && - (!p_Dpb->fs_ref[i]->frame-> - is_long_term)) { - currSlice->listX[0][list0idx++] = - p_Dpb->fs_ref[i]->frame; - } - } - } - /* order list 0 by PicNum */ - qsort((void *)currSlice->listX[0], list0idx, - sizeof(struct StorablePicture *), - compare_pic_by_pic_num_desc); - currSlice->listXsize[0] = (char) list0idx; - CHECK_VALID(currSlice->listXsize[0], 0); - if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "listX[0] (PicNum): "); - for (i = 0; i < list0idx; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[0][i]->pic_num); - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - } - /* long term handling */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame->is_long_term) { - currSlice->listX[0][list0idx++] = - p_Dpb->fs_ltref[i]->frame; - } - } - } - qsort((void *)&currSlice->listX[0][ - (short) currSlice->listXsize[0]], - list0idx - currSlice->listXsize[0], - sizeof(struct StorablePicture *), - compare_pic_by_lt_pic_num_asc); - currSlice->listXsize[0] = (char) list0idx; - CHECK_VALID(currSlice->listXsize[0], 0); - } else { -#if 0 - fs_list0 = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (fs_list0 == NULL) - no_mem_exit("init_lists: fs_list0"); - fs_listlt = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (fs_listlt == NULL) - no_mem_exit("init_lists: fs_listlt"); -#else - fs_list0 = &(p_Dpb->fs_list0[0]); - fs_listlt = &(p_Dpb->fs_listlt[0]); -#endif - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference) - fs_list0[list0idx++] = p_Dpb->fs_ref[i]; - } - - qsort((void *)fs_list0, list0idx, sizeof(struct FrameStore *), - compare_fs_by_frame_num_desc); - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "fs_list0 (FrameNum): "); - for (i = 0; i < list0idx; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - fs_list0[i]->frame_num_wrap); - } - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "\n"); - - currSlice->listXsize[0] = 0; - gen_pic_list_from_frame_list(currSlice->structure, fs_list0, - list0idx, currSlice->listX[0], - &currSlice->listXsize[0], 0); - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "listX[0] (PicNum): "); - for (i = 0; i < currSlice->listXsize[0]; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[0][i]->pic_num); - } - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "\n"); - - /* long term handling */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) - fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; - - qsort((void *)fs_listlt, listltidx, sizeof(struct FrameStore *), - compare_fs_by_lt_pic_idx_asc); - - gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, - listltidx, currSlice->listX[0], - &currSlice->listXsize[0], 1); - - /* free(fs_list0); */ - /* free(fs_listlt); */ - } - currSlice->listXsize[1] = 0; - - - /* set max size */ - currSlice->listXsize[0] = (char) imin(currSlice->listXsize[0], - currSlice->num_ref_idx_active[LIST_0]); - currSlice->listXsize[1] = (char) imin(currSlice->listXsize[1], - currSlice->num_ref_idx_active[LIST_1]); - CHECK_VALID(currSlice->listXsize[0], 0); - CHECK_VALID(currSlice->listXsize[1], 1); - - /* set the unused list entries to NULL */ - for (i = currSlice->listXsize[0]; i < (MAX_LIST_SIZE); i++) - currSlice->listX[0][i] = p_Vid->no_reference_picture; - for (i = currSlice->listXsize[1]; i < (MAX_LIST_SIZE); i++) - currSlice->listX[1][i] = p_Vid->no_reference_picture; - -#if PRINTREFLIST -#if (MVC_EXTENSION_ENABLE) - /* print out for h264_debug_flag purpose */ - if ((p_Vid->profile_idc == MVC_HIGH || - p_Vid->profile_idc == STEREO_HIGH) && - currSlice->current_slice_nr == 0) { - if (currSlice->listXsize[0] > 0) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (CurViewID:%d %d) %s Ref Pic List 0 ****\n", - currSlice->view_id, - currSlice->ThisPOC, - currSlice->structure == FRAME ? "FRM" : - (currSlice->structure == TOP_FIELD ? - "TOP" : "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[0]); i++) { /* ref list 0 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[0][i]->poc, - currSlice->listX[0][i]->pic_num, - currSlice->listX[0][i]->view_id); - } - } - } -#endif -#endif -} - - -/*! - ************************************************************************ - * \brief - * Initialize reference lists - * - ************************************************************************ - */ -static void init_mbaff_lists(struct h264_dpb_stru *p_H264_Dpb, - struct Slice *currSlice) -{ - unsigned int j; - int i; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - for (i = 2; i < 6; i++) { - for (j = 0; j < MAX_LIST_SIZE; j++) - currSlice->listX[i][j] = p_Vid->no_reference_picture; - currSlice->listXsize[i] = 0; - } - - for (i = 0; i < currSlice->listXsize[0]; i++) { -#ifdef ERROR_CHECK - if (currSlice->listX[0][i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - pr_info( - "error currSlice->listX[0][%d] is NULL\r\n", i); - break; - } -#endif - currSlice->listX[2][2 * i] = - currSlice->listX[0][i]->top_field; - currSlice->listX[2][2 * i + 1] = - currSlice->listX[0][i]->bottom_field; - currSlice->listX[4][2 * i] = - currSlice->listX[0][i]->bottom_field; - currSlice->listX[4][2 * i + 1] = - currSlice->listX[0][i]->top_field; - } - currSlice->listXsize[2] = currSlice->listXsize[4] = - currSlice->listXsize[0] * 2; - - for (i = 0; i < currSlice->listXsize[1]; i++) { -#ifdef ERROR_CHECK - if (currSlice->listX[1][i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - pr_info( - "error currSlice->listX[1][%d] is NULL\r\n", i); - break; - } -#endif - currSlice->listX[3][2 * i] = - currSlice->listX[1][i]->top_field; - currSlice->listX[3][2 * i + 1] = - currSlice->listX[1][i]->bottom_field; - currSlice->listX[5][2 * i] = - currSlice->listX[1][i]->bottom_field; - currSlice->listX[5][2 * i + 1] = - currSlice->listX[1][i]->top_field; - } - currSlice->listXsize[3] = currSlice->listXsize[5] = - currSlice->listXsize[1] * 2; -} - - - -static void init_lists_i_slice(struct Slice *currSlice) -{ - -#if (MVC_EXTENSION_ENABLE) - currSlice->listinterviewidx0 = 0; - currSlice->listinterviewidx1 = 0; -#endif - - currSlice->listXsize[0] = 0; - currSlice->listXsize[1] = 0; -} - -static void init_lists_b_slice(struct Slice *currSlice) -{ - struct VideoParameters *p_Vid = currSlice->p_Vid; - struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - - unsigned int i; - int j; - - int list0idx = 0; - int list0idx_1 = 0; - int listltidx = 0; - - struct FrameStore **fs_list0; - struct FrameStore **fs_list1; - struct FrameStore **fs_listlt; - -#if (MVC_EXTENSION_ENABLE) - currSlice->listinterviewidx0 = 0; - currSlice->listinterviewidx1 = 0; -#endif - - { - /* B-Slice */ - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((p_Dpb->fs_ref[i]->is_used == 3) && - ((p_Dpb->fs_ref[i]->frame-> - used_for_reference) && - (!p_Dpb->fs_ref[i]->frame-> - is_long_term)) && - (currSlice->framepoc >= - p_Dpb->fs_ref[i]->frame->poc)) { - /* !KS use >= for error - * concealment - */ - currSlice->listX[0][list0idx++] = - p_Dpb->fs_ref[i]->frame; - } - } - qsort((void *)currSlice->listX[0], list0idx, - sizeof(struct StorablePicture *), - compare_pic_by_poc_desc); - - /* get the backward reference picture - * (POC>current POC) in list0; - */ - list0idx_1 = list0idx; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL || - p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((p_Dpb->fs_ref[i]->is_used == 3) && - ((p_Dpb->fs_ref[i]->frame-> - used_for_reference) && - (!p_Dpb->fs_ref[i]->frame-> - is_long_term)) && - (currSlice->framepoc < - p_Dpb->fs_ref[i]->frame->poc)) { - currSlice-> - listX[0][list0idx++] = - p_Dpb->fs_ref[i]->frame; - } - } - qsort((void *)&currSlice->listX[0][list0idx_1], - list0idx - list0idx_1, - sizeof(struct StorablePicture *), - compare_pic_by_poc_asc); - - for (j = 0; j < list0idx_1; j++) { - currSlice-> - listX[1][list0idx - list0idx_1 + j] = - currSlice->listX[0][j]; - } - for (j = list0idx_1; j < list0idx; j++) { - currSlice->listX[1][j - list0idx_1] = - currSlice->listX[0][j]; - } - - currSlice->listXsize[0] = currSlice->listXsize[1] = - (char) list0idx; - CHECK_VALID(currSlice->listXsize[0], 0); - CHECK_VALID(currSlice->listXsize[1], 1); - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "listX[0] (PicNum): "); - for (i = 0; i < currSlice->listXsize[0]; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[0][i]->pic_num); - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "listX[1] (PicNum): "); - for (i = 0; i < currSlice->listXsize[1]; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[1][i]->pic_num); - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - /* dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "currSlice->listX[0] currPoc=%d (Poc): ", - * p_Vid->framepoc); - * for (i=0; i<currSlice->listXsize[0]; i++) { - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "%d ", currSlice->listX[0][i]->poc); - * } - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, "\n"); - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "currSlice->listX[1] currPoc=%d (Poc): ", - * p_Vid->framepoc); - * for (i=0; i<currSlice->listXsize[1]; i++) { - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "%d ", - * currSlice->listX[1][i]->poc); - * } - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, "\n"); - */ - - /* long term handling */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame-> - is_long_term) { - currSlice-> - listX[0][list0idx] = - p_Dpb->fs_ltref[i]->frame; - currSlice-> - listX[1][list0idx++] = - p_Dpb->fs_ltref[i]->frame; - } - } - } - qsort((void *)&currSlice-> - listX[0][(short) currSlice->listXsize[0]], - list0idx - currSlice->listXsize[0], - sizeof(struct StorablePicture *), - compare_pic_by_lt_pic_num_asc); - qsort((void *)&currSlice-> - listX[1][(short) currSlice->listXsize[0]], - list0idx - currSlice->listXsize[0], - sizeof(struct StorablePicture *), - compare_pic_by_lt_pic_num_asc); - currSlice->listXsize[0] = currSlice->listXsize[1] = - (char) list0idx; - CHECK_VALID(currSlice->listXsize[0], 0); - CHECK_VALID(currSlice->listXsize[1], 1); - } else { -#if 0 - fs_list0 = calloc(p_Dpb->size, - sizeof(struct FrameStore *)); - if (fs_list0 == NULL) - no_mem_exit("init_lists: fs_list0"); - fs_list1 = calloc(p_Dpb->size, - sizeof(struct FrameStore *)); - if (fs_list1 == NULL) - no_mem_exit("init_lists: fs_list1"); - fs_listlt = calloc(p_Dpb->size, - sizeof(struct FrameStore *)); - if (fs_listlt == NULL) - no_mem_exit("init_lists: fs_listlt"); -#else - fs_list0 = &(p_Dpb->fs_list0[0]); - fs_list1 = &(p_Dpb->fs_list1[0]); - fs_listlt = &(p_Dpb->fs_listlt[0]); - -#endif - currSlice->listXsize[0] = 0; - currSlice->listXsize[1] = 1; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_used) { - if (currSlice->ThisPOC >= - p_Dpb->fs_ref[i]->poc) { - fs_list0[list0idx++] = - p_Dpb->fs_ref[i]; - } - } - } - qsort((void *)fs_list0, list0idx, - sizeof(struct FrameStore *), - compare_fs_by_poc_desc); - list0idx_1 = list0idx; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_used) { - if (currSlice->ThisPOC < - p_Dpb->fs_ref[i]->poc) { - fs_list0[list0idx++] = - p_Dpb->fs_ref[i]; - } - } - } - qsort((void *)&fs_list0[list0idx_1], - list0idx - list0idx_1, - sizeof(struct FrameStore *), - compare_fs_by_poc_asc); - - for (j = 0; j < list0idx_1; j++) { - fs_list1[list0idx - list0idx_1 + j] = - fs_list0[j]; - } - for (j = list0idx_1; j < list0idx; j++) - fs_list1[j - list0idx_1] = fs_list0[j]; - - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "fs_list0 currPoc=%d (Poc): ", - currSlice->ThisPOC); - for (i = 0; i < list0idx; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - fs_list0[i]->poc); - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "fs_list1 currPoc=%d (Poc): ", - currSlice->ThisPOC); - for (i = 0; i < list0idx; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - fs_list1[i]->poc); - } - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - - currSlice->listXsize[0] = 0; - currSlice->listXsize[1] = 0; - gen_pic_list_from_frame_list(currSlice->structure, - fs_list0, list0idx, - currSlice->listX[0], - &currSlice->listXsize[0], 0); - gen_pic_list_from_frame_list(currSlice->structure, - fs_list1, list0idx, - currSlice->listX[1], - &currSlice->listXsize[1], 0); - - /* dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "currSlice->listX[0] currPoc=%d (Poc): ", - * p_Vid->framepoc); - * for (i=0; i<currSlice->listXsize[0]; i++) { - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, "%d ", - * currSlice->listX[0][i]->poc); - * } - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, "\n"); - */ - /* dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "currSlice->listX[1] currPoc=%d (Poc): ", - * p_Vid->framepoc); - * for (i=0; i<currSlice->listXsize[1]; i++) { - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, "%d ", - * currSlice->listX[1][i]->poc); - * } - * dpb_print(p_H264_Dpb->decoder_index, - * PRINT_FLAG_DPB_DETAIL, - * "\n"); - */ - - /* long term handling */ - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) - fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; - - qsort((void *)fs_listlt, listltidx, - sizeof(struct FrameStore *), - compare_fs_by_lt_pic_idx_asc); - - gen_pic_list_from_frame_list(currSlice->structure, - fs_listlt, listltidx, - currSlice->listX[0], - &currSlice->listXsize[0], 1); - gen_pic_list_from_frame_list(currSlice->structure, - fs_listlt, listltidx, - currSlice->listX[1], - &currSlice->listXsize[1], 1); - - /* free(fs_list0); */ - /* free(fs_list1); */ - /* free(fs_listlt); */ - } - } - - if ((currSlice->listXsize[0] == currSlice->listXsize[1]) && - (currSlice->listXsize[0] > 1)) { - /* check if lists are identical, - *if yes swap first two elements of currSlice->listX[1] - */ - int diff = 0; - - for (j = 0; j < currSlice->listXsize[0]; j++) { - if (currSlice->listX[0][j] != - currSlice->listX[1][j]) { - diff = 1; - break; - } - } - if (!diff) { - struct StorablePicture *tmp_s = - currSlice->listX[1][0]; - currSlice->listX[1][0] = currSlice->listX[1][1]; - currSlice->listX[1][1] = tmp_s; - } - } - - /* set max size */ - currSlice->listXsize[0] = (char) imin(currSlice->listXsize[0], - currSlice->num_ref_idx_active[LIST_0]); - currSlice->listXsize[1] = (char) imin(currSlice->listXsize[1], - currSlice->num_ref_idx_active[LIST_1]); - CHECK_VALID(currSlice->listXsize[0], 0); - CHECK_VALID(currSlice->listXsize[1], 1); - - /* set the unused list entries to NULL */ - for (i = currSlice->listXsize[0]; i < (MAX_LIST_SIZE); i++) - currSlice->listX[0][i] = p_Vid->no_reference_picture; - for (i = currSlice->listXsize[1]; i < (MAX_LIST_SIZE); i++) - currSlice->listX[1][i] = p_Vid->no_reference_picture; - -#if PRINTREFLIST -#if (MVC_EXTENSION_ENABLE) - /* print out for h264_debug_flag purpose */ - if ((p_Vid->profile_idc == MVC_HIGH || - p_Vid->profile_idc == STEREO_HIGH) && - currSlice->current_slice_nr == 0) { - if ((currSlice->listXsize[0] > 0) || - (currSlice->listXsize[1] > 0)) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - if (currSlice->listXsize[0] > 0) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (CurViewID:%d %d) %s Ref Pic List 0 ****\n", - currSlice->view_id, - currSlice->ThisPOC, - currSlice->structure == FRAME ? "FRM" : - (currSlice->structure == TOP_FIELD ? - "TOP" : "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[0]); i++) { /* ref list 0 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[0][i]->poc, - currSlice->listX[0][i]->pic_num, - currSlice->listX[0][i]->view_id); - } - } - if (currSlice->listXsize[1] > 0) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (CurViewID:%d %d) %s Ref Pic List 1 ****\n", - currSlice->view_id, - currSlice->ThisPOC, - currSlice->structure == FRAME ? "FRM" : - (currSlice->structure == TOP_FIELD ? "TOP" : - "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[1]); i++) { /* ref list 1 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[1][i]->poc, - currSlice->listX[1][i]->pic_num, - currSlice->listX[1][i]->view_id); - } - } - } -#endif -#endif -} - -static struct StorablePicture *get_short_term_pic(struct Slice *currSlice, - struct DecodedPictureBuffer *p_Dpb, int picNum) -{ - unsigned int i; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (currSlice->structure == FRAME) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference == 3) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->frame == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->frame-> - is_long_term) && - (p_Dpb->fs_ref[i]->frame-> - pic_num == picNum)) - return p_Dpb->fs_ref[i]->frame; - } - } else { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i] == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if (p_Dpb->fs_ref[i]->is_reference & 1) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->top_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->top_field-> - is_long_term) && - (p_Dpb->fs_ref[i]->top_field-> - pic_num == picNum)) - return p_Dpb->fs_ref[i]->top_field; - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { -#ifdef ERROR_CHECK - if (p_Dpb->fs_ref[i]->bottom_field == NULL) { - p_H264_Dpb->dpb_error_flag = __LINE__; - continue; - } -#endif - if ((!p_Dpb->fs_ref[i]->bottom_field-> - is_long_term) && - (p_Dpb->fs_ref[i]->bottom_field-> - pic_num == picNum)) - return p_Dpb->fs_ref[i]->bottom_field; - } - } - } - - return currSlice->p_Vid->no_reference_picture; -} - - -static void reorder_short_term(struct Slice *currSlice, int cur_list, - int num_ref_idx_lX_active_minus1, - int picNumLX, int *refIdxLX) -{ - struct h264_dpb_stru *p_H264_Dpb = container_of(currSlice->p_Vid, - struct h264_dpb_stru, mVideo); - - struct StorablePicture **RefPicListX = currSlice->listX[cur_list]; - int cIdx, nIdx; - - struct StorablePicture *picLX; - - picLX = get_short_term_pic(currSlice, currSlice->p_Dpb, picNumLX); - - for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; - cIdx--) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s: RefPicListX[ %d ] = RefPicListX[ %d ]\n", - __func__, cIdx, cIdx - 1); - RefPicListX[cIdx] = RefPicListX[cIdx - 1]; - } - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s: RefPicListX[ %d ] = pic %x (%d)\n", __func__, - *refIdxLX, picLX, picNumLX); - - RefPicListX[(*refIdxLX)++] = picLX; - - nIdx = *refIdxLX; - - for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; - cIdx++) { - if (RefPicListX[cIdx]) - if ((RefPicListX[cIdx]->is_long_term) || - (RefPicListX[cIdx]->pic_num != picNumLX)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "%s: RefPicListX[ %d ] = RefPicListX[ %d ]\n", - __func__, nIdx, cIdx); - RefPicListX[nIdx++] = RefPicListX[cIdx]; - } - } -} - - -static struct StorablePicture *get_long_term_pic(struct Slice *currSlice, - struct DecodedPictureBuffer *p_Dpb, int LongtermPicNum) -{ - unsigned int i; - - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (currSlice->structure == FRAME) { - if (p_Dpb->fs_ltref[i]->is_reference == 3) - if ((p_Dpb->fs_ltref[i]->frame) && - (p_Dpb->fs_ltref[i]->frame-> - is_long_term) && - (p_Dpb->fs_ltref[i]->frame-> - long_term_pic_num == - LongtermPicNum)) - return p_Dpb->fs_ltref[i]->frame; - } else { - if (p_Dpb->fs_ltref[i]->is_reference & 1) - if ((p_Dpb->fs_ltref[i]->top_field) && - (p_Dpb->fs_ltref[i]->top_field-> - is_long_term) && - (p_Dpb->fs_ltref[i]->top_field-> - long_term_pic_num == LongtermPicNum)) - return p_Dpb->fs_ltref[i]->top_field; - - if (p_Dpb->fs_ltref[i]->is_reference & 2) - if ((p_Dpb->fs_ltref[i]->bottom_field) && - (p_Dpb->fs_ltref[i]->bottom_field-> - is_long_term) && - (p_Dpb->fs_ltref[i]->bottom_field-> - long_term_pic_num == - LongtermPicNum)) - return p_Dpb->fs_ltref[i]-> - bottom_field; - } - } - return NULL; -} - -/*! - ************************************************************************ - * \brief - * Reordering process for long-term reference pictures - * - ************************************************************************ - */ -static void reorder_long_term(struct Slice *currSlice, - struct StorablePicture **RefPicListX, - int num_ref_idx_lX_active_minus1, - int LongTermPicNum, int *refIdxLX) -{ - int cIdx, nIdx; - - struct StorablePicture *picLX; - - picLX = get_long_term_pic(currSlice, currSlice->p_Dpb, LongTermPicNum); - - for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--) - RefPicListX[cIdx] = RefPicListX[cIdx - 1]; - - RefPicListX[(*refIdxLX)++] = picLX; - - nIdx = *refIdxLX; - - for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; - cIdx++) { - if (RefPicListX[cIdx]) { - if ((!RefPicListX[cIdx]->is_long_term) || - (RefPicListX[cIdx]->long_term_pic_num != - LongTermPicNum)) - RefPicListX[nIdx++] = RefPicListX[cIdx]; - } - } -} - -static void reorder_ref_pic_list(struct Slice *currSlice, int cur_list) -{ - int *modification_of_pic_nums_idc = - currSlice->modification_of_pic_nums_idc[cur_list]; - int *abs_diff_pic_num_minus1 = - currSlice->abs_diff_pic_num_minus1[cur_list]; - int *long_term_pic_idx = currSlice->long_term_pic_idx[cur_list]; - int num_ref_idx_lX_active_minus1 = - currSlice->num_ref_idx_active[cur_list] - 1; - - struct VideoParameters *p_Vid = currSlice->p_Vid; - int i; - - int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX; - int refIdxLX = 0; - - if (currSlice->structure == FRAME) { - maxPicNum = p_Vid->max_frame_num; - currPicNum = currSlice->frame_num; - } else { - maxPicNum = 2 * p_Vid->max_frame_num; - currPicNum = 2 * currSlice->frame_num + 1; - } - - picNumLXPred = currPicNum; - - for (i = 0; i < REORDERING_COMMAND_MAX_SIZE && - modification_of_pic_nums_idc[i] != 3; i++) { - if (modification_of_pic_nums_idc[i] > 3) { - struct h264_dpb_stru *p_H264_Dpb = - container_of(p_Vid, struct h264_dpb_stru, mVideo); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "error, Invalid modification_of_pic_nums_idc command\n"); - /*h264_debug_flag = 0x1f;*/ - break; - } - if (modification_of_pic_nums_idc[i] < 2) { - if (modification_of_pic_nums_idc[i] == 0) { - if (picNumLXPred - (abs_diff_pic_num_minus1[i] - + 1) < 0) - picNumLXNoWrap = picNumLXPred - - (abs_diff_pic_num_minus1[i] + 1) + - maxPicNum; - else - picNumLXNoWrap = picNumLXPred - - (abs_diff_pic_num_minus1[i] + 1); - } else { /* (modification_of_pic_nums_idc[i] == 1) */ - if (picNumLXPred + (abs_diff_pic_num_minus1[i] - + 1) >= maxPicNum) - picNumLXNoWrap = picNumLXPred + - (abs_diff_pic_num_minus1[i] + 1) - - maxPicNum; - else - picNumLXNoWrap = picNumLXPred + - (abs_diff_pic_num_minus1[i] + 1); - } - picNumLXPred = picNumLXNoWrap; - - if (picNumLXNoWrap > currPicNum) - picNumLX = picNumLXNoWrap - maxPicNum; - else - picNumLX = picNumLXNoWrap; - -#if (MVC_EXTENSION_ENABLE) - reorder_short_term(currSlice, cur_list, - num_ref_idx_lX_active_minus1, picNumLX, - &refIdxLX, -1); -#else - reorder_short_term(currSlice, cur_list, - num_ref_idx_lX_active_minus1, picNumLX, - &refIdxLX); -#endif - } else { /* (modification_of_pic_nums_idc[i] == 2) */ -#if (MVC_EXTENSION_ENABLE) - reorder_long_term(currSlice, currSlice->listX[cur_list], - num_ref_idx_lX_active_minus1, - long_term_pic_idx[i], &refIdxLX, -1); -#else - reorder_long_term(currSlice, currSlice->listX[cur_list], - num_ref_idx_lX_active_minus1, - long_term_pic_idx[i], &refIdxLX); -#endif - } - - } - /* that's a definition */ - currSlice->listXsize[cur_list] = - (char)(num_ref_idx_lX_active_minus1 + 1); -} - -static void reorder_lists(struct Slice *currSlice) -{ - struct VideoParameters *p_Vid = currSlice->p_Vid; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid, - struct h264_dpb_stru, mVideo); - int i; - - if ((currSlice->slice_type != I_SLICE) && - (currSlice->slice_type != SI_SLICE)) { - if (currSlice->ref_pic_list_reordering_flag[LIST_0]) - reorder_ref_pic_list(currSlice, LIST_0); - if (p_Vid->no_reference_picture == - currSlice-> - listX[0][currSlice->num_ref_idx_active[LIST_0] - 1]) { - if (p_Vid->non_conforming_stream) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "RefPicList0[ %d ] is equal to 'no reference picture'\n", - currSlice-> - num_ref_idx_active[LIST_0] - 1); - else - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "RefPicList0 [ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream %d\n", - 500); - } - /* that's a definition */ - currSlice->listXsize[0] = - (char) imin(currSlice->listXsize[0], - currSlice->num_ref_idx_active[LIST_0]); - CHECK_VALID(currSlice->listXsize[0], 0); - if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "listX[0] reorder (PicNum): "); - for (i = 0; i < currSlice->listXsize[0]; i++) { - dpb_print_cont(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[0][i]->pic_num); - } - dpb_print_cont(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - } - } - - if (currSlice->slice_type == B_SLICE) { - if (currSlice->ref_pic_list_reordering_flag[LIST_1]) - reorder_ref_pic_list(currSlice, LIST_1); - if (p_Vid->no_reference_picture == - currSlice->listX[1][currSlice-> - num_ref_idx_active[LIST_1] - 1]) { - if (p_Vid->non_conforming_stream) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "RefPicList1[ %d ] is equal to 'no reference picture'\n", - currSlice-> - num_ref_idx_active[LIST_1] - 1); - else - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "RefPicList1 [ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture', invalid bitstream %d\n", - 500); - } - /* that's a definition */ - currSlice->listXsize[1] = - (char)currSlice->num_ref_idx_active[LIST_1]; - if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "listX[1] reorder (PicNum): "); - for (i = 0; i < currSlice->listXsize[1]; i++) { - if (currSlice->listX[1][i]) - dpb_print_cont(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%d ", - currSlice->listX[1][i]->pic_num); - } - dpb_print_cont(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - } - } - - /* free_ref_pic_list_reordering_buffer(currSlice); */ - - if (currSlice->slice_type == P_SLICE) { -#if PRINTREFLIST - unsigned int i; -#if (MVC_EXTENSION_ENABLE) - /* print out for h264_debug_flag purpose */ - if ((p_Vid->profile_idc == MVC_HIGH || - p_Vid->profile_idc == STEREO_HIGH) && - currSlice->current_slice_nr == 0) { - if (currSlice->listXsize[0] > 0 - && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (FinalViewID:%d) %s Ref Pic List 0 ****\n", - currSlice->view_id, - currSlice->structure == FRAME ? - "FRM" : - (currSlice->structure == TOP_FIELD ? - "TOP" : "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[0]); i++) { /* ref list 0 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[0][i]->poc, - currSlice->listX[0][i]-> - pic_num, - currSlice->listX[0][i]-> - view_id); - } - } - } -#endif -#endif - } else if (currSlice->slice_type == B_SLICE) { -#if PRINTREFLIST - unsigned int i; -#if (MVC_EXTENSION_ENABLE) - /* print out for h264_debug_flag purpose */ - if ((p_Vid->profile_idc == MVC_HIGH || - p_Vid->profile_idc == STEREO_HIGH) && - currSlice->current_slice_nr == 0) { - if ((currSlice->listXsize[0] > 0) || - (currSlice->listXsize[1] > 0)) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "\n"); - if (currSlice->listXsize[0] > 0 - && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (FinalViewID:%d) %s Ref Pic List 0 ****\n", - currSlice->view_id, - currSlice->structure == FRAME ? - "FRM" : - (currSlice->structure == TOP_FIELD ? - "TOP" : "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[0]); i++) { /* ref list 0 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[0][i]->poc, - currSlice->listX[0][i]-> - pic_num, - currSlice->listX[0][i]-> - view_id); - } - } - if (currSlice->listXsize[1] > 0 - && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " ** (FinalViewID:%d) %s Ref Pic List 1 ****\n", - currSlice->view_id, - currSlice->structure == FRAME ? - "FRM" : - (currSlice->structure == TOP_FIELD ? - "TOP" : "BOT")); - for (i = 0; i < (unsigned int)(currSlice-> - listXsize[1]); i++) { /* ref list 1 */ - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - " %2d -> POC: %4d PicNum: %4d ViewID: %d\n", - i, - currSlice->listX[1][i]->poc, - currSlice->listX[1][i]-> - pic_num, - currSlice->listX[1][i]-> - view_id); - } - } - } -#endif - -#endif - } -} - -void init_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int count) -{ - p_H264_Dpb->colocated_buf_map = 0; - p_H264_Dpb->colocated_buf_count = count; -} - -int allocate_colocate_buf(struct h264_dpb_stru *p_H264_Dpb) -{ - int i; - - for (i = 0; i < p_H264_Dpb->colocated_buf_count; i++) { - if (((p_H264_Dpb->colocated_buf_map >> i) & 0x1) == 0) { - p_H264_Dpb->colocated_buf_map |= (1 << i); - break; - } - } - if (i == p_H264_Dpb->colocated_buf_count) { - i = -1; - p_H264_Dpb->buf_alloc_fail = 1; - } - return i; -} - -int release_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int index) -{ - if (index >= 0) { - if (index >= p_H264_Dpb->colocated_buf_count) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_ERROR, - "%s error, index %d is bigger than buf count %d\n", - __func__, index, - p_H264_Dpb->colocated_buf_count); - } else { - if (((p_H264_Dpb->colocated_buf_map >> - index) & 0x1) == 0x1) { - p_H264_Dpb->colocated_buf_map &= - (~(1 << index)); - } else { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_ERROR, - "%s error, index %d is not allocated\n", - __func__, index); - } - } - } - return 0; -} - -void set_frame_output_flag(struct h264_dpb_stru *p_H264_Dpb, int index) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - p_H264_Dpb->mFrameStore[index].is_output = 1; - p_H264_Dpb->mFrameStore[index].pre_output = 0; - p_H264_Dpb->mFrameStore[index].show_frame = false; - dump_dpb(p_Dpb, 0); -} - -#if 0 -void init_old_slice(OldSliceParams *p_old_slice) -{ - p_old_slice->field_pic_flag = 0; - p_old_slice->pps_id = INT_MAX; - p_old_slice->frame_num = INT_MAX; - p_old_slice->nal_ref_idc = INT_MAX; - p_old_slice->idr_flag = 0; - - p_old_slice->pic_oder_cnt_lsb = UINT_MAX; - p_old_slice->delta_pic_oder_cnt_bottom = INT_MAX; - - p_old_slice->delta_pic_order_cnt[0] = INT_MAX; - p_old_slice->delta_pic_order_cnt[1] = INT_MAX; -} - - -void copy_slice_info(struct Slice *currSlice, OldSliceParams *p_old_slice) -{ - struct VideoParameters *p_Vid = currSlice->p_Vid; - - p_old_slice->pps_id = currSlice->pic_parameter_set_id; - p_old_slice->frame_num = currSlice->frame_num; - /* p_Vid->frame_num; */ - p_old_slice->field_pic_flag = - currSlice->field_pic_flag; - /* p_Vid->field_pic_flag; */ - - if (currSlice->field_pic_flag) - p_old_slice->bottom_field_flag = currSlice->bottom_field_flag; - - p_old_slice->nal_ref_idc = currSlice->nal_reference_idc; - p_old_slice->idr_flag = (byte) currSlice->idr_flag; - - if (currSlice->idr_flag) - p_old_slice->idr_pic_id = currSlice->idr_pic_id; - - if (p_Vid->active_sps->pic_order_cnt_type == 0) { - p_old_slice->pic_oder_cnt_lsb = - currSlice->pic_order_cnt_lsb; - p_old_slice->delta_pic_oder_cnt_bottom = - currSlice->delta_pic_order_cnt_bottom; - } - - if (p_Vid->active_sps->pic_order_cnt_type == 1) { - p_old_slice->delta_pic_order_cnt[0] = - currSlice->delta_pic_order_cnt[0]; - p_old_slice->delta_pic_order_cnt[1] = - currSlice->delta_pic_order_cnt[1]; - } -#if (MVC_EXTENSION_ENABLE) - p_old_slice->view_id = currSlice->view_id; - p_old_slice->inter_view_flag = currSlice->inter_view_flag; - p_old_slice->anchor_pic_flag = currSlice->anchor_pic_flag; -#endif - p_old_slice->layer_id = currSlice->layer_id; -} - -int is_new_picture(StorablePicture *dec_picture, struct Slice *currSlice, - OldSliceParams *p_old_slice) -{ - struct VideoParameters *p_Vid = currSlice->p_Vid; - - int result = 0; - - result |= (dec_picture == NULL); - - result |= (p_old_slice->pps_id != currSlice->pic_parameter_set_id); - - result |= (p_old_slice->frame_num != currSlice->frame_num); - - result |= (p_old_slice->field_pic_flag != currSlice->field_pic_flag); - - if (currSlice->field_pic_flag && p_old_slice->field_pic_flag) { - result |= (p_old_slice->bottom_field_flag != - currSlice->bottom_field_flag); - } - - result |= (p_old_slice->nal_ref_idc != - currSlice->nal_reference_idc) && - ((p_old_slice->nal_ref_idc == 0) || - (currSlice->nal_reference_idc == 0)); - result |= (p_old_slice->idr_flag != currSlice->idr_flag); - - if (currSlice->idr_flag && p_old_slice->idr_flag) - result |= (p_old_slice->idr_pic_id != currSlice->idr_pic_id); - - if (p_Vid->active_sps->pic_order_cnt_type == 0) { - result |= (p_old_slice->pic_oder_cnt_lsb != - currSlice->pic_order_cnt_lsb); - if (p_Vid->active_pps-> - bottom_field_pic_order_in_frame_present_flag == 1 && - !currSlice->field_pic_flag) { - result |= (p_old_slice->delta_pic_oder_cnt_bottom != - currSlice->delta_pic_order_cnt_bottom); - } - } - - if (p_Vid->active_sps->pic_order_cnt_type == 1) { - if (!p_Vid->active_sps->delta_pic_order_always_zero_flag) { - result |= (p_old_slice->delta_pic_order_cnt[0] != - currSlice->delta_pic_order_cnt[0]); - if (p_Vid->active_pps-> - bottom_field_pic_order_in_frame_present_flag == 1 && - !currSlice->field_pic_flag) { - result |= (p_old_slice-> - delta_pic_order_cnt[1] != - currSlice->delta_pic_order_cnt[1]); - } - } - } - -#if (MVC_EXTENSION_ENABLE) - result |= (currSlice->view_id != p_old_slice->view_id); - result |= (currSlice->inter_view_flag != p_old_slice->inter_view_flag); - result |= (currSlice->anchor_pic_flag != p_old_slice->anchor_pic_flag); -#endif - result |= (currSlice->layer_id != p_old_slice->layer_id); - return result; -} -#else -int is_new_picture(struct StorablePicture *dec_picture, - struct h264_dpb_stru *p_H264_Dpb, - struct OldSliceParams *p_old_slice) -{ - int ret = 0; - - if (p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] == 0) - ret = 1; - return ret; -} - -#endif - -/* -* release bufspec and pic for picture not in dpb buf -*/ -int release_picture(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - if (p_Dpb->last_picture == NULL) { - if (pic->colocated_buf_index >= 0) { - release_colocate_buf(p_H264_Dpb, - pic->colocated_buf_index); - pic->colocated_buf_index = -1; - } - release_buf_spec_num(p_H264_Dpb->vdec, pic->buf_spec_num); - } else { - if (pic->buf_spec_is_alloced == 1) - release_buf_spec_num(p_H264_Dpb->vdec, - pic->buf_spec_num); - } - - free_picture(p_H264_Dpb, pic); - return 0; -} - -#ifdef ERROR_HANDLE_TEST -/* -* remove all pictures in dpb and release bufspec/pic of them -*/ -void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb) -{ - /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - struct Slice *currSlice = &p_H264_Dpb->mSlice; - unsigned i, j; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - if (!p_Dpb->init_done) - return; - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->colocated_buf_index >= 0) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "release_colocate_buf[%d] for fs[%d]\n", - p_Dpb->fs[i]->colocated_buf_index, i); - - release_colocate_buf(p_H264_Dpb, - p_Dpb->fs[i]->colocated_buf_index); /* rain */ - p_Dpb->fs[i]->colocated_buf_index = -1; - } - if (!p_Dpb->fs[i]->pre_output) { - release_buf_spec_num(p_H264_Dpb->vdec, - p_Dpb->fs[i]->buf_spec_num); - p_Dpb->fs[i]->buf_spec_num = -1; - } - remove_frame_from_dpb(p_H264_Dpb, i); - } - - for (i = 0; i < p_Dpb->used_size; i++) { - p_Dpb->fs_ref[i] = NULL; - p_Dpb->fs_ltref[i] = NULL; - p_Dpb->fs_list0[i] = NULL; - p_Dpb->fs_list1[i] = NULL; - p_Dpb->fs_listlt[i] = NULL; - } - for (i = 0; i < 2; i++) { - currSlice->listXsize[i] = 0; - for (j = 0; j < (MAX_LIST_SIZE * 2); j++) - currSlice->listX[i][j] = NULL; - } - p_Dpb->ref_frames_in_buffer = 0; - p_Dpb->ltref_frames_in_buffer = 0; - p_Dpb->last_output_poc = INT_MIN; -} -#endif - -static void check_frame_store_same_pic_num(struct DecodedPictureBuffer *p_Dpb, - struct StorablePicture *p, struct Slice *currSlice) -{ - if (p_Dpb->last_picture) { - if ((int)p_Dpb->last_picture->frame_num == p->pic_num) { - if (((p->structure == TOP_FIELD) && - (p_Dpb->last_picture->is_used == 2)) || - ((p->structure == BOTTOM_FIELD) && - (p_Dpb->last_picture->is_used == 1))) { - if ((p->used_for_reference && - (p_Dpb->last_picture-> - is_orig_reference != 0)) || - (!p->used_for_reference && - (p_Dpb->last_picture-> - is_orig_reference == 0))) { - p->buf_spec_num = - p_Dpb->last_picture-> - buf_spec_num; - p->buf_spec_is_alloced = 0; - p->colocated_buf_index = p_Dpb-> - last_picture-> - colocated_buf_index; - if (currSlice->structure == - TOP_FIELD) { - p->bottom_poc = - p_Dpb->last_picture-> - bottom_field->poc; - } else { - p->top_poc = - p_Dpb->last_picture-> - top_field->poc; - } - p->frame_poc = imin(p->bottom_poc, - p->top_poc); - } - } - } - } -} - -int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap) -{ - - int new_pic_flag = 0; - struct Slice *currSlice = &p_H264_Dpb->mSlice; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - struct DecodedPictureBuffer *p_Dpb = - &p_H264_Dpb->mDPB; -#if 0 - new_pic_flag = is_new_picture(p_H264_Dpb->mVideo.dec_picture, - p_H264_Dpb, - &p_H264_Dpb->mVideo.old_slice); - - if (new_pic_flag) { /* new picture */ - if (p_H264_Dpb->mVideo.dec_picture) { - store_picture_in_dpb(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture); - /* dump_dpb(&p_H264_Dpb->mDPB); */ - } - } -#else - new_pic_flag = (p_H264_Dpb->mVideo.dec_picture == NULL); -#endif - p_H264_Dpb->buf_alloc_fail = 0; - p_H264_Dpb->dpb_error_flag = 0; - slice_prepare(p_H264_Dpb, &p_H264_Dpb->mDPB, &p_H264_Dpb->mVideo, - &p_H264_Dpb->mSPS, &p_H264_Dpb->mSlice); - - if (p_Dpb->num_ref_frames != p_H264_Dpb->mSPS.num_ref_frames) { - dpb_print(p_H264_Dpb->decoder_index, 0, - "num_ref_frames change from %d to %d\r\n", - p_Dpb->num_ref_frames, p_H264_Dpb->mSPS.num_ref_frames); - p_Dpb->num_ref_frames = p_H264_Dpb->mSPS.num_ref_frames; - } - /* if (p_Vid->active_sps != sps) { */ - if (p_H264_Dpb->mDPB.init_done == 0) { - /*init_global_buffers(p_Vid, 0); - * ** * *if (!p_Vid->no_output_of_prior_pics_flag) - ** * *{ - ** * * flush_dpb(p_Vid->p_Dpb_layer[0]); - ** * *} - ** * *init_dpb(p_Vid, p_Vid->p_Dpb_layer[0], 0); - */ - init_dpb(p_H264_Dpb, 0); - } - - - if (new_pic_flag) { /* new picture */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "check frame_num gap: cur frame_num %d pre_frame_num %d max_frmae_num %d\r\n", - currSlice->frame_num, - p_Vid->pre_frame_num, - p_Vid->max_frame_num); - if (p_Vid->recovery_point == 0 && - p_Vid->max_frame_num <= FRAME_NUM_MAX_SIZE && - currSlice->frame_num != p_Vid->pre_frame_num && - currSlice->frame_num != - (p_Vid->pre_frame_num + 1) % p_Vid->max_frame_num) { - struct SPSParameters *active_sps = p_Vid->active_sps; - /*if (active_sps-> - *gaps_in_frame_num_value_allowed_flag - *== 0) { - * error("An unintentional - * loss of pictures occurs! Exit\n", - * 100); - *} - *if (p_Vid->conceal_mode == 0) - */ - if (active_sps->frame_num_gap_allowed) - fill_frame_num_gap(p_Vid, currSlice); - *frame_num_gap = 1; - } - - if (currSlice->nal_reference_idc) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "nal_reference_idc not 0, set pre_frame_num(%d) to frame_num (%d)\n", - p_Vid->pre_frame_num, currSlice->frame_num); - p_Vid->pre_frame_num = currSlice->frame_num; - } - - decode_poc(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice); - p_H264_Dpb->mVideo.dec_picture = get_new_pic(p_H264_Dpb, - p_H264_Dpb->mSlice.structure, - /*p_Vid->width, p_Vid->height, - * p_Vid->width_cr, - * p_Vid->height_cr, - */ - 1); - if (p_H264_Dpb->mVideo.dec_picture) { - u32 offset_lo, offset_hi; - struct DecodedPictureBuffer *p_Dpb = - &p_H264_Dpb->mDPB; - struct StorablePicture *p = - p_H264_Dpb->mVideo.dec_picture; - init_picture(p_H264_Dpb, &p_H264_Dpb->mSlice, - p_H264_Dpb->mVideo.dec_picture); -#if 1 - /* rain */ - offset_lo = - p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_LO]; - offset_hi = - p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_HI]; - p_H264_Dpb->mVideo.dec_picture->offset_delimiter = - (offset_lo | offset_hi << 16); - p_H264_Dpb->mVideo.dec_picture->buf_spec_num = -1; - p_H264_Dpb->mVideo.dec_picture-> - colocated_buf_index = -1; - update_pic_num(p_H264_Dpb); - - if ((currSlice->structure == TOP_FIELD) || - (currSlice->structure == BOTTOM_FIELD)) { - /* check for frame store with same - * pic_number - */ - check_frame_store_same_pic_num(p_Dpb, p, - currSlice); - } - - if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num == - -1) { - p_H264_Dpb->mVideo.dec_picture->buf_spec_num = - get_free_buf_idx(p_H264_Dpb->vdec); - if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num - < 0) { - p_H264_Dpb->buf_alloc_fail = 1; - p_H264_Dpb->mVideo.dec_picture-> - buf_spec_is_alloced = 0; - } else - p_H264_Dpb->mVideo.dec_picture-> - buf_spec_is_alloced = 1; - - if (p_H264_Dpb->mVideo.dec_picture-> - used_for_reference) { - p_H264_Dpb->mVideo.dec_picture-> - colocated_buf_index = - allocate_colocate_buf( - p_H264_Dpb); - } - } -#endif - if (post_picture_early(p_H264_Dpb->vdec, - p_H264_Dpb->mVideo.dec_picture->buf_spec_num)) - return -1; - } - } - - if (p_H264_Dpb->buf_alloc_fail) - return -1; - - if (p_H264_Dpb->mSlice.slice_type == P_SLICE) - init_lists_p_slice(&p_H264_Dpb->mSlice); - else if (p_H264_Dpb->mSlice.slice_type == B_SLICE) - init_lists_b_slice(&p_H264_Dpb->mSlice); - else - init_lists_i_slice(&p_H264_Dpb->mSlice); - - reorder_lists(&p_H264_Dpb->mSlice); - - if (p_H264_Dpb->mSlice.structure == FRAME) - init_mbaff_lists(p_H264_Dpb, &p_H264_Dpb->mSlice); - - if (new_pic_flag) - return 1; - - return 0; -} - -enum PictureStructure get_cur_slice_picture_struct( - struct h264_dpb_stru *p_H264_Dpb) -{ - struct Slice *currSlice = &p_H264_Dpb->mSlice; - return currSlice->structure; -} - -static unsigned char is_pic_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic) -{ - unsigned char ret = 0; - int i; - struct DecodedPictureBuffer *p_Dpb = - &p_H264_Dpb->mDPB; - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->top_field == pic || - p_Dpb->fs[i]->bottom_field == pic || - p_Dpb->fs[i]->frame == pic) { - ret = 1; - break; - } - } - return ret; -} - -int dpb_check_ref_list_error( - struct h264_dpb_stru *p_H264_Dpb) -{ - int i; - /*int j;*/ - struct Slice *currSlice = &p_H264_Dpb->mSlice; - /* in first output, ignore ref check */ - if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) && - (p_H264_Dpb->mVideo.dec_picture) && - p_H264_Dpb->first_output_poc > p_H264_Dpb->mVideo.dec_picture->poc) { - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "p_H264_Dpb->first_output_poc %d, p_H264_Dpb->mVideo.dec_picture->poc %d\n", - p_H264_Dpb->first_output_poc, p_H264_Dpb->mVideo.dec_picture->poc); - return 0; - } - if ((currSlice->slice_type != I_SLICE) && - (currSlice->slice_type != SI_SLICE)) { - for (i = 0; i < currSlice->listXsize[0]; i++) { - /*for (j = i + 1; j < currSlice->listXsize[0]; j++) { - if(currSlice->listX[0][i]->pic_num == - currSlice->listX[0][j]->pic_num) - return 1; - }*/ - if (currSlice->listX[0][i] == NULL) - return 5; - if (!is_pic_in_dpb(p_H264_Dpb, - currSlice->listX[0][i])) - return 1; - if (currSlice->listX[0][i]->frame && - currSlice->listX[0][i]->frame->non_existing) - return 3; - } - } - - if (currSlice->slice_type == B_SLICE) { - for (i = 0; i < currSlice->listXsize[1]; i++) { - /*for (j = i + 1; j < currSlice->listXsize[1]; j++) { - if(currSlice->listX[1][i]->pic_num == - currSlice->listX[1][j]->pic_num) - return 2; - } - for (j = 0; j < currSlice->listXsize[0]; j++) { - if(currSlice->listX[1][i]->pic_num == - currSlice->listX[0][j]->pic_num) - return 3; - }*/ - if (currSlice->listX[1][i] == NULL) - return 6; - if (!is_pic_in_dpb(p_H264_Dpb, - currSlice->listX[1][i])) - return 2; - if (currSlice->listX[1][i]->frame && - currSlice->listX[1][i]->frame->non_existing) - return 4; -#if 0 - if (currSlice->listXsize[0] == 1 && - currSlice->listXsize[1] == 1 && - currSlice->listX[1][0] == - currSlice->listX[0][0]) - return 3; -#endif - } - } - return 0; -} -
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h deleted file mode 100644 index e1d1ab4..0000000 --- a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h +++ /dev/null
@@ -1,1008 +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 H264_DPB_H_ -#define H264_DPB_H_ - -#define ERROR_CHECK - -#define OUTPUT_BUFFER_IN_C - -#define PRINT_FLAG_ERROR 0x0 -#define PRINT_FLAG_VDEC_STATUS 0X0001 -#define PRINT_FLAG_UCODE_EVT 0x0002 -#define PRINT_FLAG_MMU_DETAIL 0x0004 -#define PRINT_FLAG_ERRORFLAG_DBG 0x0008 -#define PRINT_FLAG_DPB_DETAIL 0x0010 -#define PRINT_FLAG_DEC_DETAIL 0x0020 -#define PRINT_FLAG_VDEC_DETAIL 0x0040 -#define PRINT_FLAG_DUMP_DPB 0x0080 -#define PRINT_FRAMEBASE_DATA 0x0100 -#define PRINT_FLAG_DEBUG_POC 0x0200 -#define RRINT_FLAG_RPM 0x0400 -#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800 -#define PRINT_FLAG_DUMP_BUFSPEC 0x1000 -#define PRINT_FLAG_FCC_STATUS 0x2000 -#define PRINT_FLAG_SEI_DETAIL 0x4000 -#define PRINT_FLAG_V4L_DETAIL 0x8000 -#define DISABLE_ERROR_HANDLE 0x10000 -#define DEBUG_DUMP_STAT 0x80000 -#define DEBUG_TIMEOUT_DEC_STAT 0x800000 - -/*setting canvas mode and endian. - if this flag is set, value of canvas mode - will according to the value of mem_map_mode. - endian will be forced set to 0 in - CANVAS_BLKMODE_LINEAR mode. - otherwise picture will display abnormal. - if this flag is not set, value of canvas mode - will be determined by the user speace config. - endian will be set 7 in CANVAS_BLKMODE_LINEAR mode. -*/ -#define IGNORE_PARAM_FROM_CONFIG 0x8000000 - -#define MVC_EXTENSION_ENABLE 0 -#define PRINTREFLIST 0 - -#define MAX_LIST_SIZE 33 - -#define H264_OUTPUT_MODE_NORMAL 0x4 -#define H264_OUTPUT_MODE_FAST 0x8 - -//#define FALSE 0 - -#define H264_SLICE_HEAD_DONE 0x01 -#define H264_PIC_DATA_DONE 0x02 -/*#define H264_SPS_DONE 0x03*/ -/*#define H264_PPS_DONE 0x04*/ -/*#define H264_SLICE_DATA_DONE 0x05*/ -/*#define H264_DATA_END 0x06*/ - -#define H264_CONFIG_REQUEST 0x11 -#define H264_DATA_REQUEST 0x12 -#define H264_WRRSP_REQUEST 0x13 -#define H264_WRRSP_DONE 0x14 - -#define H264_DECODE_BUFEMPTY 0x20 -#define H264_DECODE_TIMEOUT 0x21 -#define H264_SEARCH_BUFEMPTY 0x22 -#define H264_DECODE_OVER_SIZE 0x23 - -#define VIDEO_SIGNAL_LOW 0x26 -#define VIDEO_SIGNAL_HIGHT 0x27 - - -#define H264_FIND_NEXT_PIC_NAL 0x50 -#define H264_FIND_NEXT_DVEL_NAL 0x51 -#define H264_AUX_DATA_READY 0x52 - -#define H264_SEI_DATA_READY 0x53 -#define H264_SEI_DATA_DONE 0x54 - - /* 0x8x, search state*/ -#define H264_STATE_SEARCH_AFTER_SPS 0x80 -#define H264_STATE_SEARCH_AFTER_PPS 0x81 -#define H264_STATE_PARSE_SLICE_HEAD 0x82 -#define H264_STATE_SEARCH_HEAD 0x83 - /**/ -#define H264_ACTION_SEARCH_HEAD 0xf0 -#define H264_ACTION_DECODE_SLICE 0xf1 -#define H264_ACTION_CONFIG_DONE 0xf2 -#define H264_ACTION_DECODE_NEWPIC 0xf3 -#define H264_ACTION_DECODE_START 0xff - -#define RPM_BEGIN 0x0 -#define RPM_END 0x400 - -#define val(s) (s[0]|(s[1]<<16)) - -#define FRAME_IN_DPB 24 -#define DPB_OFFSET 0x100 -#define MMCO_OFFSET 0x200 -union param { -#if 0 -#define H_TIME_STAMP_START 0X00 -#define H_TIME_STAMP_END 0X17 -#define PTS_ZERO_0 0X18 -#define PTS_ZERO_1 0X19 -#endif -#define FIXED_FRAME_RATE_FLAG 0X21 - -#define OFFSET_DELIMITER_LO 0x2f -#define OFFSET_DELIMITER_HI 0x30 - - -#define SLICE_IPONLY_BREAK 0X5C -#define PREV_MAX_REFERENCE_FRAME_NUM 0X5D -#define EOS 0X5E -#define FRAME_PACKING_TYPE 0X5F -#define OLD_POC_PAR_1 0X60 -#define OLD_POC_PAR_2 0X61 -#define PREV_MBX 0X62 -#define PREV_MBY 0X63 -#define ERROR_SKIP_MB_NUM 0X64 -#define ERROR_MB_STATUS 0X65 -#define L0_PIC0_STATUS 0X66 -#define TIMEOUT_COUNTER 0X67 -#define BUFFER_SIZE 0X68 -#define BUFFER_SIZE_HI 0X69 -#define CROPPING_LEFT_RIGHT 0X6A -#define CROPPING_TOP_BOTTOM 0X6B -#if 1 - /* sps_flags2: - *bit 3, bitstream_restriction_flag - *bit 2, pic_struct_present_flag - *bit 1, vcl_hrd_parameters_present_flag - *bit 0, nal_hrd_parameters_present_flag - */ -#define SPS_FLAGS2 0x6c -#define NUM_REORDER_FRAMES 0x6d -#else -#define POC_SELECT_NEED_SWAP 0X6C -#define POC_SELECT_SWAP 0X6D -#endif -#define MAX_BUFFER_FRAME 0X6E - -#define NON_CONFORMING_STREAM 0X70 -#define RECOVERY_POINT 0X71 -#define POST_CANVAS 0X72 -#define POST_CANVAS_H 0X73 -#define SKIP_PIC_COUNT 0X74 -#define TARGET_NUM_SCALING_LIST 0X75 -#define FF_POST_ONE_FRAME 0X76 -#define PREVIOUS_BIT_CNT 0X77 -#define MB_NOT_SHIFT_COUNT 0X78 -#define PIC_STATUS 0X79 -#define FRAME_COUNTER 0X7A -#define NEW_SLICE_TYPE 0X7B -#define NEW_PICTURE_STRUCTURE 0X7C -#define NEW_FRAME_NUM 0X7D -#define NEW_IDR_PIC_ID 0X7E -#define IDR_PIC_ID 0X7F - -/* h264 LOCAL */ -#define NAL_UNIT_TYPE 0X80 -#define NAL_REF_IDC 0X81 -#define SLICE_TYPE 0X82 -#define LOG2_MAX_FRAME_NUM 0X83 -#define FRAME_MBS_ONLY_FLAG 0X84 -#define PIC_ORDER_CNT_TYPE 0X85 -#define LOG2_MAX_PIC_ORDER_CNT_LSB 0X86 -#define PIC_ORDER_PRESENT_FLAG 0X87 -#define REDUNDANT_PIC_CNT_PRESENT_FLAG 0X88 -#define PIC_INIT_QP_MINUS26 0X89 -#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG 0X8A -#define NUM_SLICE_GROUPS_MINUS1 0X8B -#define MODE_8X8_FLAGS 0X8C -#define ENTROPY_CODING_MODE_FLAG 0X8D -#define SLICE_QUANT 0X8E -#define TOTAL_MB_HEIGHT 0X8F -#define PICTURE_STRUCTURE 0X90 -#define TOP_INTRA_TYPE 0X91 -#define RV_AI_STATUS 0X92 -#define AI_READ_START 0X93 -#define AI_WRITE_START 0X94 -#define AI_CUR_BUFFER 0X95 -#define AI_DMA_BUFFER 0X96 -#define AI_READ_OFFSET 0X97 -#define AI_WRITE_OFFSET 0X98 -#define AI_WRITE_OFFSET_SAVE 0X99 -#define RV_AI_BUFF_START 0X9A -#define I_PIC_MB_COUNT 0X9B -#define AI_WR_DCAC_DMA_CTRL 0X9C -#define SLICE_MB_COUNT 0X9D -#define PICTYPE 0X9E -#define SLICE_GROUP_MAP_TYPE 0X9F -#define MB_TYPE 0XA0 -#define MB_AFF_ADDED_DMA 0XA1 -#define PREVIOUS_MB_TYPE 0XA2 -#define WEIGHTED_PRED_FLAG 0XA3 -#define WEIGHTED_BIPRED_IDC 0XA4 -/* bit 3:2 - PICTURE_STRUCTURE - * bit 1 - MB_ADAPTIVE_FRAME_FIELD_FLAG - * bit 0 - FRAME_MBS_ONLY_FLAG - */ -#define MBFF_INFO 0XA5 -#define TOP_INTRA_TYPE_TOP 0XA6 - -#define RV_AI_BUFF_INC 0xa7 - -#define DEFAULT_MB_INFO_LO 0xa8 - -/* 0 -- no need to read - * 1 -- need to wait Left - * 2 -- need to read Intra - * 3 -- need to read back MV - */ -#define NEED_READ_TOP_INFO 0xa9 -/* 0 -- idle - * 1 -- wait Left - * 2 -- reading top Intra - * 3 -- reading back MV - */ -#define READ_TOP_INFO_STATE 0xaa -#define DCAC_MBX 0xab -#define TOP_MB_INFO_OFFSET 0xac -#define TOP_MB_INFO_RD_IDX 0xad -#define TOP_MB_INFO_WR_IDX 0xae - -#define VLD_NO_WAIT 0 -#define VLD_WAIT_BUFFER 1 -#define VLD_WAIT_HOST 2 -#define VLD_WAIT_GAP 3 - -#define VLD_WAITING 0xaf - -#define MB_X_NUM 0xb0 -/* #define MB_WIDTH 0xb1 */ -#define MB_HEIGHT 0xb2 -#define MBX 0xb3 -#define TOTAL_MBY 0xb4 -#define INTR_MSK_SAVE 0xb5 - -/* #define has_time_stamp 0xb6 */ -#define NEED_DISABLE_PPE 0xb6 -#define IS_NEW_PICTURE 0XB7 -#define PREV_NAL_REF_IDC 0XB8 -#define PREV_NAL_UNIT_TYPE 0XB9 -#define FRAME_MB_COUNT 0XBA -#define SLICE_GROUP_UCODE 0XBB -#define SLICE_GROUP_CHANGE_RATE 0XBC -#define SLICE_GROUP_CHANGE_CYCLE_LEN 0XBD -#define DELAY_LENGTH 0XBE -#define PICTURE_STRUCT 0XBF -/* #define pre_picture_struct 0xc0 */ -#define DCAC_PREVIOUS_MB_TYPE 0xc1 - -#define TIME_STAMP 0XC2 -#define H_TIME_STAMP 0XC3 -#define VPTS_MAP_ADDR 0XC4 -#define H_VPTS_MAP_ADDR 0XC5 - -/*#define MAX_DPB_SIZE 0XC6*/ -#define PIC_INSERT_FLAG 0XC7 - -#define TIME_STAMP_START 0XC8 -#define TIME_STAMP_END 0XDF - -#define OFFSET_FOR_NON_REF_PIC 0XE0 -#define OFFSET_FOR_TOP_TO_BOTTOM_FIELD 0XE2 -#define MAX_REFERENCE_FRAME_NUM 0XE4 -#define FRAME_NUM_GAP_ALLOWED 0XE5 -#define NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE 0XE6 -#define PROFILE_IDC_MMCO 0XE7 -#define LEVEL_IDC_MMCO 0XE8 -#define FRAME_SIZE_IN_MB 0XE9 -#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG 0XEA -#define PPS_NUM_REF_IDX_L0_ACTIVE_MINUS1 0XEB -#define PPS_NUM_REF_IDX_L1_ACTIVE_MINUS1 0XEC -#define CURRENT_SPS_ID 0XED -#define CURRENT_PPS_ID 0XEE -/* bit 0 - sequence parameter set may change - * bit 1 - picture parameter set may change - * bit 2 - new dpb just inited - * bit 3 - IDR picture not decoded yet - * bit 5:4 - 0: mb level code loaded 1: picture - * level code loaded 2: slice level code loaded - */ -#define DECODE_STATUS 0XEF -#define FIRST_MB_IN_SLICE 0XF0 -#define PREV_MB_WIDTH 0XF1 -#define PREV_FRAME_SIZE_IN_MB 0XF2 -/*#define MAX_REFERENCE_FRAME_NUM_IN_MEM 0XF3*/ -/* bit 0 - aspect_ratio_info_present_flag - * bit 1 - timing_info_present_flag - * bit 2 - nal_hrd_parameters_present_flag - * bit 3 - vcl_hrd_parameters_present_flag - * bit 4 - pic_struct_present_flag - * bit 5 - bitstream_restriction_flag - */ -#define VUI_STATUS 0XF4 -#define ASPECT_RATIO_IDC 0XF5 -#define ASPECT_RATIO_SAR_WIDTH 0XF6 -#define ASPECT_RATIO_SAR_HEIGHT 0XF7 -#define NUM_UNITS_IN_TICK 0XF8 -#define TIME_SCALE 0XFA -#define CURRENT_PIC_INFO 0XFC -#define DPB_BUFFER_INFO 0XFD -#define REFERENCE_POOL_INFO 0XFE -#define REFERENCE_LIST_INFO 0XFF - struct{ - unsigned short data[RPM_END-RPM_BEGIN]; - } l; - struct{ - unsigned short dump[DPB_OFFSET]; - unsigned short dpb_base[FRAME_IN_DPB<<3]; - - unsigned short dpb_max_buffer_frame; - unsigned short actual_dpb_size; - - unsigned short colocated_buf_status; - - unsigned short num_forward_short_term_reference_pic; - unsigned short num_short_term_reference_pic; - unsigned short num_reference_pic; - - unsigned short current_dpb_index; - unsigned short current_decoded_frame_num; - unsigned short current_reference_frame_num; - - unsigned short l0_size; - unsigned short l1_size; - - /* [6:5] : nal_ref_idc */ - /* [4:0] : nal_unit_type */ - unsigned short NAL_info_mmco; - - /* [1:0] : 00 - top field, 01 - bottom field, - * 10 - frame, 11 - mbaff frame - */ - unsigned short picture_structure_mmco; - - unsigned short frame_num; - unsigned short pic_order_cnt_lsb; - - unsigned short num_ref_idx_l0_active_minus1; - unsigned short num_ref_idx_l1_active_minus1; - - unsigned short PrevPicOrderCntLsb; - unsigned short PreviousFrameNum; - - /* 32 bits variables */ - unsigned short delta_pic_order_cnt_bottom[2]; - unsigned short delta_pic_order_cnt_0[2]; - unsigned short delta_pic_order_cnt_1[2]; - - unsigned short PrevPicOrderCntMsb[2]; - unsigned short PrevFrameNumOffset[2]; - - unsigned short frame_pic_order_cnt[2]; - unsigned short top_field_pic_order_cnt[2]; - unsigned short bottom_field_pic_order_cnt[2]; - - unsigned short colocated_mv_addr_start[2]; - unsigned short colocated_mv_addr_end[2]; - unsigned short colocated_mv_wr_addr[2]; - - unsigned short frame_crop_left_offset; - unsigned short frame_crop_right_offset; - unsigned short frame_crop_top_offset; - unsigned short frame_crop_bottom_offset; - unsigned short chroma_format_idc; - } dpb; - struct { - unsigned short dump[MMCO_OFFSET]; - - /* array base address for offset_for_ref_frame */ - unsigned short offset_for_ref_frame_base[128]; - - /* 0 - Index in DPB - * 1 - Picture Flag - * [ 2] : 0 - short term reference, - * 1 - long term reference - * [ 1] : bottom field - * [ 0] : top field - * 2 - Picture Number (short term or long term) low 16 bits - * 3 - Picture Number (short term or long term) high 16 bits - */ - unsigned short reference_base[128]; - - /* command and parameter, until command is 3 */ - unsigned short l0_reorder_cmd[66]; - unsigned short l1_reorder_cmd[66]; - - /* command and parameter, until command is 0 */ - unsigned short mmco_cmd[44]; - - unsigned short l0_base[40]; - unsigned short l1_base[40]; - } mmco; - struct { - /* from ucode lmem, do not change this struct */ - } p; -}; - - -struct StorablePicture; -struct VideoParameters; -struct DecodedPictureBuffer; - -/* New enum for field processing */ -enum PictureStructure { - FRAME, - TOP_FIELD, - BOTTOM_FIELD -}; - -typedef enum { - PIC_SINGLE_FRAME = 0, - PIC_TOP, - PIC_BOT, - PIC_TOP_BOT, - PIC_BOT_TOP, - PIC_TOP_BOT_TOP = 5, - PIC_BOT_TOP_BOT, - PIC_DOUBLE_FRAME, - PIC_TRIPLE_FRAME, - PIC_INVALID, -} PicStruct_E; - -#define I_Slice 2 -#define P_Slice 5 -#define B_Slice 6 -#define P_Slice_0 0 -#define B_Slice_1 1 -#define I_Slice_7 7 - -enum SliceType { - P_SLICE = 0, - B_SLICE = 1, - I_SLICE = 2, - SP_SLICE = 3, - SI_SLICE = 4, - NUM_SLICE_TYPES = 5 -}; - -enum ProfileIDC { - FREXT_CAVLC444 = 44, /*!< YUV 4:4:4/14 "CAVLC 4:4:4"*/ - BASELINE = 66, /*!< YUV 4:2:0/8 "Baseline"*/ - MAIN = 77, /*!< YUV 4:2:0/8 "Main"*/ - EXTENDED = 88, /*!< YUV 4:2:0/8 "Extended"*/ - FREXT_HP = 100, /*!< YUV 4:2:0/8 "High"*/ - FREXT_Hi10P = 110, /*!< YUV 4:2:0/10 "High 10"*/ - FREXT_Hi422 = 122, /*!< YUV 4:2:2/10 "High 4:2:2"*/ - FREXT_Hi444 = 244, /*!< YUV 4:4:4/14 "High 4:4:4"*/ - MVC_HIGH = 118, /*!< YUV 4:2:0/8 "Multiview High"*/ - STEREO_HIGH = 128 /*!< YUV 4:2:0/8 "Stereo High"*/ -}; - -enum FirstInsertFrm_State { - FirstInsertFrm_IDLE = 0, - FirstInsertFrm_OUT = 1, - FirstInsertFrm_RESET = 2, - FirstInsertFrm_SKIPDONE = 3, -}; - - -struct SPSParameters { - unsigned int profile_idc; - unsigned int level_idc; - int pic_order_cnt_type; - int log2_max_pic_order_cnt_lsb_minus4; - int num_ref_frames_in_pic_order_cnt_cycle; - short offset_for_ref_frame[128]; - short offset_for_non_ref_pic; - short offset_for_top_to_bottom_field; - - /**/ - int frame_mbs_only_flag; - int num_ref_frames; - int max_dpb_size; - int log2_max_frame_num_minus4; - int frame_num_gap_allowed; -}; - -#define DEC_REF_PIC_MARKING_BUFFER_NUM_MAX 45 -struct DecRefPicMarking_s { - int memory_management_control_operation; - int difference_of_pic_nums_minus1; - int long_term_pic_num; - int long_term_frame_idx; - int max_long_term_frame_idx_plus1; - struct DecRefPicMarking_s *Next; -}; - -#define REORDERING_COMMAND_MAX_SIZE 33 -struct Slice { - int first_mb_in_slice; - int mode_8x8_flags; - int picture_structure_mmco; - - int frame_num; - int idr_flag; - int toppoc; - int bottompoc; - int framepoc; - int pic_order_cnt_lsb; - int PicOrderCntMsb; - unsigned char field_pic_flag; - unsigned char bottom_field_flag; - int ThisPOC; - int nal_reference_idc; - int AbsFrameNum; - int delta_pic_order_cnt_bottom; - int delta_pic_order_cnt[2]; - - /**/ - char listXsize[6]; - struct StorablePicture *listX[6][MAX_LIST_SIZE * 2]; - - /**/ - enum PictureStructure structure; - int long_term_reference_flag; - int no_output_of_prior_pics_flag; - int adaptive_ref_pic_buffering_flag; - - struct VideoParameters *p_Vid; - struct DecodedPictureBuffer *p_Dpb; - int num_ref_idx_active[2]; /* number of available list references */ - - /*modification*/ - int slice_type; /* slice type */ - int ref_pic_list_reordering_flag[2]; - int modification_of_pic_nums_idc[2][REORDERING_COMMAND_MAX_SIZE]; - int abs_diff_pic_num_minus1[2][REORDERING_COMMAND_MAX_SIZE]; - int long_term_pic_idx[2][REORDERING_COMMAND_MAX_SIZE]; - /**/ - unsigned char dec_ref_pic_marking_buffer_valid; - struct DecRefPicMarking_s - dec_ref_pic_marking_buffer[DEC_REF_PIC_MARKING_BUFFER_NUM_MAX]; - int pic_struct; -}; - -struct OldSliceParams { - unsigned int field_pic_flag; - unsigned int frame_num; - int nal_ref_idc; - unsigned int pic_oder_cnt_lsb; - int delta_pic_oder_cnt_bottom; - int delta_pic_order_cnt[2]; - unsigned char bottom_field_flag; - unsigned char idr_flag; - int idr_pic_id; - int pps_id; -#if (MVC_EXTENSION_ENABLE) - int view_id; - int inter_view_flag; - int anchor_pic_flag; -#endif - int layer_id; -}; - -struct VideoParameters { - int PrevPicOrderCntMsb; - int PrevPicOrderCntLsb; - unsigned char last_has_mmco_5; - unsigned char last_pic_bottom_field; - int ThisPOC; - int PreviousFrameNum; - int FrameNumOffset; - int PreviousFrameNumOffset; - int max_frame_num; - unsigned int pre_frame_num; - int ExpectedDeltaPerPicOrderCntCycle; - int PicOrderCntCycleCnt; - int FrameNumInPicOrderCntCycle; - int ExpectedPicOrderCnt; - - /**/ - struct SPSParameters *active_sps; - struct Slice **ppSliceList; - int iSliceNumOfCurrPic; - int conceal_mode; - int earlier_missing_poc; - int pocs_in_dpb[100]; - - struct OldSliceParams old_slice; - /**/ - struct StorablePicture *dec_picture; - struct StorablePicture *no_reference_picture; - - /*modification*/ - int non_conforming_stream; - int recovery_point; -}; - -static inline int imin(int a, int b) -{ - return ((a) < (b)) ? (a) : (b); -} - -static inline int imax(int a, int b) -{ - return ((a) > (b)) ? (a) : (b); -} - -#define MAX_PIC_BUF_NUM 128 -#define MAX_NUM_SLICES 50 - -struct StorablePicture { -/**/ - int width; - int height; - - int y_canvas_index; - int u_canvas_index; - int v_canvas_index; -/**/ - int index; - unsigned char is_used; - - enum PictureStructure structure; - - int poc; - int top_poc; - int bottom_poc; - int frame_poc; - unsigned int frame_num; - unsigned int recovery_frame; - - int pic_num; - int buf_spec_num; - int buf_spec_is_alloced; - int colocated_buf_index; - int long_term_pic_num; - int long_term_frame_idx; - - unsigned char is_long_term; - int used_for_reference; - int is_output; -#if 1 - /* rain */ - int pre_output; -#endif - int non_existing; - int separate_colour_plane_flag; - - short max_slice_id; - - int size_x, size_y, size_x_cr, size_y_cr; - int size_x_m1, size_y_m1, size_x_cr_m1, size_y_cr_m1; - int coded_frame; - int mb_aff_frame_flag; - unsigned int PicWidthInMbs; - unsigned int PicSizeInMbs; - int iLumaPadY, iLumaPadX; - int iChromaPadY, iChromaPadX; - - /* for mb aff, if frame for referencing the top field */ - struct StorablePicture *top_field; - /* for mb aff, if frame for referencing the bottom field */ - struct StorablePicture *bottom_field; - /* for mb aff, if field for referencing the combined frame */ - struct StorablePicture *frame; - - int slice_type; - int idr_flag; - int no_output_of_prior_pics_flag; - int long_term_reference_flag; - int adaptive_ref_pic_buffering_flag; - - int chroma_format_idc; - int frame_mbs_only_flag; - int frame_cropping_flag; - int frame_crop_left_offset; - int frame_crop_right_offset; - int frame_crop_top_offset; - int frame_crop_bottom_offset; - int qp; - int chroma_qp_offset[2]; - int slice_qp_delta; - /* stores the memory management control operations */ - struct DecRefPicMarking_s *dec_ref_pic_marking_buffer; - - /* picture error concealment */ - /*indicates if this is a concealed picture */ - int concealed_pic; - - /* variables for tone mapping */ - int seiHasTone_mapping; - int tone_mapping_model_id; - int tonemapped_bit_depth; - /* imgpel* tone_mapping_lut; tone mapping look up table */ - - int proc_flag; -#if (MVC_EXTENSION_ENABLE) - int view_id; - int inter_view_flag; - int anchor_pic_flag; -#endif - int iLumaStride; - int iChromaStride; - int iLumaExpandedHeight; - int iChromaExpandedHeight; - /* imgpel **cur_imgY; for more efficient get_block_luma */ - int no_ref; - int iCodingType; - - char listXsize[MAX_NUM_SLICES][2]; - struct StorablePicture **listX[MAX_NUM_SLICES][2]; - int layer_id; - u32 offset_delimiter; - u32 pts; - u64 pts64; - u64 timestamp; - unsigned char data_flag; - int pic_struct; - - /* picture qos infomation*/ - int frame_size; - 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; - u32 pic_size; -}; - -struct FrameStore { - /* rain */ - int buf_spec_num; - /* rain */ - int colocated_buf_index; - - /* 0=empty; 1=top; 2=bottom; 3=both fields (or frame) */ - int is_used; - /* 0=not used for ref; 1=top used; 2=bottom used; - * 3=both fields (or frame) used - */ - int is_reference; - /* 0=not used for ref; 1=top used; 2=bottom used; - * 3=both fields (or frame) used - */ - int is_long_term; - /* original marking by nal_ref_idc: 0=not used for ref; 1=top used; - * 2=bottom used; 3=both fields (or frame) used - */ - int is_orig_reference; - - int is_non_existent; - - unsigned int frame_num; - unsigned int recovery_frame; - - int frame_num_wrap; - int long_term_frame_idx; - int is_output; -#if 1 - /* rain */ - int pre_output; - /* index in gFrameStore */ - int index; -#define I_FLAG 0x01 -#define IDR_FLAG 0x02 -#define ERROR_FLAG 0x10 -#define NULL_FLAG 0x20 -#define NODISP_FLAG 0x80 - unsigned char data_flag; -#endif - int poc; - - /* picture error concealment */ - int concealment_reference; - - struct StorablePicture *frame; - struct StorablePicture *top_field; - struct StorablePicture *bottom_field; - -#if (MVC_EXTENSION_ENABLE) - int view_id; - int inter_view_flag[2]; - int anchor_pic_flag[2]; -#endif - int layer_id; - u32 offset_delimiter; - u32 pts; - u64 pts64; - u64 timestamp; - - - /* picture qos infomation*/ - int slice_type; - int frame_size; - - 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; - int dpb_frame_count; - u32 hw_decode_time; - u32 frame_size2; // For recording the chunk->size in frame mode - bool show_frame; - struct dma_fence *fence; - u32 decoded_frame_size; - u64 last_field_timestamp; -}; - -/* #define DPB_SIZE_MAX 16 */ -#define DPB_SIZE_MAX 32 -struct DecodedPictureBuffer { - struct VideoParameters *p_Vid; - /* InputParameters *p_Inp; ??? */ - struct FrameStore *fs[DPB_SIZE_MAX]; - struct FrameStore *fs_ref[DPB_SIZE_MAX]; - struct FrameStore *fs_ltref[DPB_SIZE_MAX]; - /* inter-layer reference (for multi-layered codecs) */ - struct FrameStore *fs_ilref[DPB_SIZE_MAX]; - /**/ - struct FrameStore *fs_list0[DPB_SIZE_MAX]; - struct FrameStore *fs_list1[DPB_SIZE_MAX]; - struct FrameStore *fs_listlt[DPB_SIZE_MAX]; - - /**/ - unsigned int size; - unsigned int used_size; - unsigned int ref_frames_in_buffer; - unsigned int ltref_frames_in_buffer; - int last_output_poc; -#if (MVC_EXTENSION_ENABLE) - int last_output_view_id; -#endif - int max_long_term_pic_idx; - - - int init_done; - int first_pic_done; /*by rain*/ - int num_ref_frames; - - struct FrameStore *last_picture; - unsigned int used_size_il; - int layer_id; - - /* DPB related function; */ -}; - -struct h264_dpb_stru { - struct vdec_s *vdec; - int decoder_index; - - union param dpb_param; - - int decode_idx; - int buf_num; - int curr_POC; - int reorder_pic_num; - unsigned int dec_dpb_size; - u8 fast_output_enable; - /*poc_even_flag: - 0, init; 1, odd; 2, even*/ - u8 poc_even_odd_flag; - u32 decode_pic_count; - /**/ - unsigned int max_reference_size; - - unsigned int colocated_buf_map; - unsigned int colocated_buf_count; - unsigned int colocated_mv_addr_start; - unsigned int colocated_mv_addr_end; - unsigned int colocated_buf_size; - - struct DecodedPictureBuffer mDPB; - struct Slice mSlice; - struct VideoParameters mVideo; - struct SPSParameters mSPS; - - struct StorablePicture m_PIC[MAX_PIC_BUF_NUM]; - struct FrameStore mFrameStore[DPB_SIZE_MAX]; - - /*vui*/ - unsigned int vui_status; - unsigned int num_units_in_tick; - unsigned int time_scale; - unsigned int fixed_frame_rate_flag; - unsigned int aspect_ratio_idc; - unsigned int aspect_ratio_sar_width; - unsigned int aspect_ratio_sar_height; - u8 bitstream_restriction_flag; - u16 num_reorder_frames; - u16 max_dec_frame_buffering; - - unsigned int frame_crop_left_offset; - unsigned int frame_crop_right_offset; - unsigned int frame_crop_top_offset; - unsigned int frame_crop_bottom_offset; - unsigned int chroma_format_idc; - - unsigned int dec_dpb_status; - unsigned int last_dpb_status; - unsigned char buf_alloc_fail; - unsigned int dpb_error_flag; - unsigned int reorder_output; - unsigned int first_insert_frame; - int first_output_poc; - int dpb_frame_count; - /* need wait aux data when there is data after pic done in dv stream */ - bool wait_aux_data_flag; - u32 without_display_mode; - int long_term_reference_flag; -}; - - -extern unsigned int h264_debug_flag; -extern unsigned int h264_debug_mask; - -int dpb_print(int indext, int debug_flag, const char *fmt, ...); - -int dpb_print_cont(int index, int debug_flag, const char *fmt, ...); - -unsigned char dpb_is_debug(int index, int debug_flag); - -int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame); - -int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num); - -void set_frame_output_flag(struct h264_dpb_stru *p_H264_Dpb, int index); - -int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb); - -int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap); - -void dpb_init_global(struct h264_dpb_stru *p_H264_Dpb, - int id, int actual_dpb_size, int max_reference_size); - -void init_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int count); - -int release_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int index); - -int get_free_buf_idx(struct vdec_s *vdec); - -int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p, unsigned char data_flag); - -int release_picture(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic); - -void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb); - -void bufmgr_post(struct h264_dpb_stru *p_H264_Dpb); - -void bufmgr_force_recover(struct h264_dpb_stru *p_H264_Dpb); - -int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb, - int buf_spec_num); - -void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb, - u8 force_flag); - -void flush_dpb(struct h264_dpb_stru *p_H264_Dpb); - -void print_pic_info(int decindex, const char *info, - struct StorablePicture *pic, - int slice_type); -void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force); - -void dump_pic(struct h264_dpb_stru *p_H264_Dpb); - -void * vh264_get_bufspec_lock(struct vdec_s *vdec); - -enum PictureStructure get_cur_slice_picture_struct( - struct h264_dpb_stru *p_H264_Dpb); - -int dpb_check_ref_list_error( - struct h264_dpb_stru *p_H264_Dpb); - -void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb, - struct FrameStore *fs); - -void update_ref_list(struct DecodedPictureBuffer *p_Dpb); - -int post_picture_early(struct vdec_s *vdec, int index); - -int is_used_for_reference(struct FrameStore *fs); - -#endif
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h b/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h deleted file mode 100644 index 6c8e4ad..0000000 --- a/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h +++ /dev/null
@@ -1,27 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/h264/vh264.h - * - * 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. - * - */ - -#ifndef VH264_H -#define VH264_H - -extern int query_video_status(int type, int *value); - -/* extern s32 vh264_init(void); */ - -extern s32 vh264_release(void); - -#endif /* VMPEG4_H */
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c b/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c deleted file mode 100644 index 78539de..0000000 --- a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c +++ /dev/null
@@ -1,11464 +0,0 @@ -/* - * drivers/amlogic/amports/vh264.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/platform_device.h> -#include <linux/random.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/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 <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> -#include "../../../stream_input/amports/amports_priv.h" -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include "../../decoder/utils/vdec_input.h" -//#include <linux/amlogic/tee.h> -#include <uapi/linux/tee.h> -#include <linux/sched/clock.h> -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../decoder/utils/vdec.h" -#include "../../decoder/utils/amvdec.h" -#include "vh264.h" -#include "../../../stream_input/amports/streambuf.h" -#include <linux/delay.h> -#include <linux/amlogic/media/codec_mm/configs.h> -#include "../../decoder/utils/decoder_mmu_box.h" -#include "../../decoder/utils/decoder_bmmu_box.h" -#include "../../decoder/utils/firmware.h" -#include <linux/uaccess.h> -#include "../../decoder/utils/config_parser.h" -#include "../../../common/chips/decoder_cpu_ver_info.h" -#include "../../decoder/utils/vdec_v4l2_buffer_ops.h" -#include <linux/crc32.h> -#include <media/v4l2-mem2mem.h> -#include "../../decoder/utils/vdec_feature.h" - -#define DETECT_WRONG_MULTI_SLICE - -/* -to enable DV of frame mode -#define DOLBY_META_SUPPORT in ucode -*/ - -#undef pr_info -#define pr_info printk -#define VDEC_DW -#define DEBUG_UCODE -#define MEM_NAME "codec_m264" -#define MULTI_INSTANCE_FRAMEWORK -/* #define ONE_COLOCATE_BUF_PER_DECODE_BUF */ -#include "h264_dpb.h" -/* #define SEND_PARAM_WITH_REG */ - -#define DRIVER_NAME "ammvdec_h264_v4l" -#define DRIVER_HEADER_NAME "ammvdec_h264_header" - -#define CHECK_INTERVAL (HZ/100) - -#define SEI_DATA_SIZE (8*1024) -#define SEI_ITU_DATA_SIZE (4*1024) - -#define RATE_MEASURE_NUM 8 -#define RATE_CORRECTION_THRESHOLD 5 -#define RATE_2397_FPS 4004 /* 23.97 */ -#define RATE_25_FPS 3840 /* 25 */ -#define RATE_2997_FPS 3203 /* 29.97 */ -#define RATE_5994_FPS 1601 /* 59.94 */ -#define RATE_11990_FPS 800 /* 119.90 */ -#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_IFRAME_NUM 2 - -#define FIX_FRAME_RATE_OFF 0 -#define FIX_FRAME_RATE_ON 1 -#define FIX_FRAME_RATE_SMOOTH_CHECKING 2 - -#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001 -#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002 -#define DEC_CONTROL_FLAG_FORCE_RATE_2397_FPS_FIX_FRAME_RATE 0x0010 -#define DEC_CONTROL_FLAG_FORCE_RATE_2997_FPS_FIX_FRAME_RATE 0x0020 - -#define DECODE_ID(hw) (hw_to_vdec(hw)->id) - -#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 ALIGN_WIDTH(x) (ALIGN((x), 64)) -#define ALIGN_HEIGHT(x) (ALIGN((x), 32)) - -#define H264_DEV_NUM 9 - -#define CONSTRAIN_MAX_BUF_NUM - -#define H264_MMU -#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000 -#define INVALID_IDX -1 /* Invalid buffer index.*/ - -static int mmu_enable; -/*mmu do not support mbaff*/ -static int force_enable_mmu = 0; -unsigned int h264_debug_flag; /* 0xa0000000; */ -unsigned int h264_debug_mask = 0xff; - /* - *h264_debug_cmd: - * 0x1xx, force decoder id of xx to be disconnected - */ -unsigned int h264_debug_cmd; - -static int ref_b_frame_error_max_count = 50; - -static unsigned int dec_control = - DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE | - DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE; - -static unsigned int force_rate_streambase; -static unsigned int force_rate_framebase; -static unsigned int force_disp_bufspec_num; -static unsigned int fixed_frame_rate_mode; -static unsigned int error_recovery_mode_in; -static int start_decode_buf_level = 0x4000; -static int pre_decode_buf_level = 0x1000; -static int stream_mode_start_num = 4; -static unsigned int colocate_old_cal; - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION -/*to make reorder size difference of bl and el not too big*/ -static unsigned int reorder_dpb_size_margin_dv = 16; -#endif -static unsigned int reorder_dpb_size_margin = 6; -static unsigned int reference_buf_margin = 4; - -#ifdef CONSTRAIN_MAX_BUF_NUM -static u32 run_ready_max_vf_only_num; -static u32 run_ready_display_q_num; - /*0: not check - 0xff: mDPB.size - */ -static u32 run_ready_max_buf_num = 0xff; -#endif - -static u32 run_ready_min_buf_num = 2; - -#define VDEC_ASSIST_CANVAS_BLK32 0x5 - - -static unsigned int max_alloc_buf_count; -static unsigned int decode_timeout_val = 100; -static unsigned int errordata_timeout_val = 50; -static unsigned int get_data_timeout_val = 2000; -#if 1 -/* H264_DATA_REQUEST does not work, disable it, -decode has error for data in none continuous address -*/ -static unsigned int frame_max_data_packet; -#else -static unsigned int frame_max_data_packet = 8; -#endif -static unsigned int radr; -static unsigned int rval; -static u32 endian = 0xff0; - -/* - udebug_flag: - bit 0, enable ucode print - bit 1, enable ucode detail print - bit 3, disable ucode watchdog - 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 unsigned int disp_vframe_valve_level; - -static unsigned int max_decode_instance_num = H264_DEV_NUM; -static unsigned int decode_frame_count[H264_DEV_NUM]; -static unsigned int display_frame_count[H264_DEV_NUM]; -static unsigned int max_process_time[H264_DEV_NUM]; -static unsigned int max_get_frame_interval[H264_DEV_NUM]; -static unsigned int run_count[H264_DEV_NUM]; -static unsigned int input_empty[H264_DEV_NUM]; -static unsigned int not_run_ready[H264_DEV_NUM]; -static unsigned int ref_frame_mark_flag[H264_DEV_NUM] = -{1, 1, 1, 1, 1, 1, 1, 1, 1}; - -#define VDEC_CLOCK_ADJUST_FRAME 30 -static unsigned int clk_adj_frame_count; - -/* - *bit[3:0]: 0, run ; 1, pause; 3, step - *bit[4]: 1, schedule run - */ -static unsigned int step[H264_DEV_NUM]; - -#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf)) -static u32 prefix_aux_buf_size = (16 * 1024); -static u32 suffix_aux_buf_size; - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION -static u32 dv_toggle_prov_name; - -static u32 dolby_meta_with_el; -#endif - -/* - bit[8] - 0: use sys_info[bit 3] - not 0:use i_only_flag[7:0] - bit[7:0]: - bit 0, 1: only display I picture; - bit 1, 1: only decode I picture; -*/ -static unsigned int i_only_flag; - -/* - error_proc_policy: - bit[0] send_error_frame_flag; - (valid when bit[31] is 1, otherwise use sysinfo) - bit[1] do not decode if config_decode_buf() fail - bit[2] force release buf if in deadlock - bit[3] force sliding window ref_frames_in_buffer > num_ref_frames - bit[4] check inactive of receiver - bit[5] reset buffmgr if in deadlock - bit[6] reset buffmgr if bufspec, collocate buf, pic alloc fail - bit[7] reset buffmgr if dpb error - - bit[8] check total mbx/mby of decoded frame - bit[9] check ERROR_STATUS_REG - bit[10] check reference list - bit[11] mark error if dpb error - bit[12] i_only when error happen - bit[13] 0: mark error according to last pic, 1: ignore mark error - bit[14] 0: result done when timeout from ucode. 1: reset bufmgr when timeout. - bit[15] 1: dpb_frame_count If the dpb_frame_count difference is large, it moves out of the DPB buffer. - bit[16] 1: check slice header number. - bit[17] 1: If the decoded Mb count is insufficient but greater than the threshold, it is considered the correct frame. - bit[18] 1: time out status, store pic to dpb buffer. - bit[19] 1: If a lot b frames are wrong consecutively, the DPB queue reset. - bit[20] 1: fixed some error stream will lead to the diffusion of the error, resulting playback stuck. - bit[21] 1: fixed DVB loop playback cause jetter issue. - bit[22] 1: In streaming mode, support for discarding data. - bit[23] 0: set error flag on frame number gap error and drop it, 1: ignore error. -*/ -static unsigned int error_proc_policy = 0x3fCfb6; /*0x1f14*/ - -static unsigned int v4l_error_policy = 0x8017C3B5; //default - -/* - error_skip_count: - bit[11:0] error skip frame count - bit[15:12] error skip i picture count -*/ -static unsigned int error_skip_count = (0x2 << 12) | 0x40; - -static unsigned int force_sliding_margin; -/* - bit[1:0]: - 0, start playing from any frame - 1, start playing from I frame - bit[15:8]: the count of skip frames after first I - 2, start playing from second I frame (decode from the first I) - bit[15:8]: the max count of skip frames after first I - 3, start playing from IDR -*/ -static unsigned int first_i_policy = 1; - -/* - fast_output_enable: - bit [0], output frame if there is IDR in list - bit [1], output frame if the current poc is 1 big than the previous poc - bit [2], if even poc only, output frame ifthe cuurent poc - is 2 big than the previous poc - bit [3], ip only -*/ -static unsigned int fast_output_enable = H264_OUTPUT_MODE_NORMAL; - -static unsigned int enable_itu_t35 = 1; - -static unsigned int frmbase_cont_bitlevel = 0x40; - -static unsigned int frmbase_cont_bitlevel2 = 0x1; - -static unsigned int check_slice_num = 30; - -static unsigned int mb_count_threshold = 5; /*percentage*/ - -#define MH264_USERDATA_ENABLE - -/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */ -/* hevc->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 - 0x10, double write only - 0x10000: vdec dw horizotal 1/2 - 0x20000: vdec dw horizotal/vertical 1/2 -*/ -static u32 double_write_mode; -static u32 without_display_mode; - -static int loop_playback_poc_threshold = 400; -static int poc_threshold = 50; - -static u32 lookup_check_conut = 30; - - -/* - *[3:0] 0: default use config from omx. - * 1: force enable fence. - * 2: disable fence. - *[7:4] 0: fence use for driver. - * 1: fence fd use for app. - */ -static u32 force_config_fence; - -static u32 adjust_dpb_size = 13; - -#define IS_VDEC_DW(hw) (hw->double_write_mode >> 16 & 0xf) - -static void vmh264_dump_state(struct vdec_s *vdec); - -#define is_in_parsing_state(status) \ - ((status == H264_ACTION_SEARCH_HEAD) || \ - ((status & 0xf0) == 0x80)) - -#define is_interlace(frame) \ - ((frame->frame &&\ - frame->top_field &&\ - frame->bottom_field &&\ - (!frame->frame->coded_frame)) || \ - (frame->frame && \ - frame->frame->coded_frame && \ - (!frame->frame->frame_mbs_only_flag) && \ - frame->frame->structure == FRAME)) - -static inline bool close_to(int a, int b, int m) -{ - return (abs(a - b) < m) ? true : false; -} - -#if 0 -#define h264_alloc_hw_stru(dev, size, opt) devm_kzalloc(dev, size, opt) -#define h264_free_hw_stru(dev, hw) devm_kfree(dev, hw) -#else -#define h264_alloc_hw_stru(dev, size, opt) vzalloc(size) -#define h264_free_hw_stru(dev, hw) vfree(hw) -#endif - -/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define NV21 -/* #endif */ - -/* 12M for L41 */ -#define MAX_DPB_BUFF_SIZE (12*1024*1024) -#define DEFAULT_MEM_SIZE (32*1024*1024) -#define AVIL_DPB_BUFF_SIZE 0x01ec2000 - -#define DEF_BUF_START_ADDR 0x00000000 -#define mem_sps_base 0x01c3c00 -#define mem_pps_base 0x01cbc00 -/*#define V_BUF_ADDR_OFFSET (0x13e000)*/ -u32 V_BUF_ADDR_OFFSET = 0x200000; -#define DCAC_READ_MARGIN (64 * 1024) - - -#define EXTEND_SAR 0xff -#define BUFSPEC_POOL_SIZE 64 -#define VF_POOL_SIZE 64 -#define VF_POOL_NUM 2 -#define MAX_VF_BUF_NUM 27 -#define BMMU_MAX_BUFFERS (BUFSPEC_POOL_SIZE + 3) -#define BMMU_REF_IDX (BUFSPEC_POOL_SIZE) -#define BMMU_DPB_IDX (BUFSPEC_POOL_SIZE + 1) -#define BMMU_EXTIF_IDX (BUFSPEC_POOL_SIZE + 2) -#define EXTIF_BUF_SIZE (0x10000 * 2) - -#define HEADER_BUFFER_IDX(n) (n) -#define VF_BUFFER_IDX(n) (n) - - -#define PUT_INTERVAL (HZ/100) -#define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL) - -#define MMU_MAX_BUFFERS BUFSPEC_POOL_SIZE -#define SWITCHING_STATE_OFF 0 -#define SWITCHING_STATE_ON_CMD3 1 -#define SWITCHING_STATE_ON_CMD1 2 - - - -#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 { - /* - used: - -1, none allocated - 0, allocated, free - 1, used by dpb - 2, in disp queue; - 3, in disp queue, isolated, - do not use for dpb when vf_put; - 4, to release - 5, in disp queue, isolated (but not to release) - do not use for dpb when vf_put; - */ - unsigned int used; - unsigned int info0; - unsigned int info1; - unsigned int info2; - unsigned int y_addr; - unsigned int u_addr; - unsigned int v_addr; - - int y_canvas_index; - int u_canvas_index; - int v_canvas_index; - -#ifdef VDEC_DW - unsigned int vdec_dw_y_addr; - unsigned int vdec_dw_u_addr; - unsigned int vdec_dw_v_addr; - - int vdec_dw_y_canvas_index; - int vdec_dw_u_canvas_index; - int vdec_dw_v_canvas_index; -#ifdef NV21 - struct canvas_config_s vdec_dw_canvas_config[2]; -#else - struct canvas_config_s vdec_dw_canvas_config[3]; -#endif -#endif - -#ifdef NV21 - struct canvas_config_s canvas_config[2]; -#else - struct canvas_config_s canvas_config[3]; -#endif - unsigned long cma_alloc_addr; - unsigned int buf_adr; -#ifdef H264_MMU - unsigned long alloc_header_addr; -#endif - char *aux_data_buf; - int aux_data_size; -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - unsigned char dv_enhance_exist; -#endif - int canvas_pos; - int vf_ref; - /*unsigned int comp_body_size;*/ - unsigned int dw_y_adr; - unsigned int dw_u_v_adr; - int fs_idx; - int ctx_buf_idx; -}; - -#define AUX_DATA_SIZE(pic) (hw->buffer_spec[pic->buf_spec_num].aux_data_size) -#define AUX_DATA_BUF(pic) (hw->buffer_spec[pic->buf_spec_num].aux_data_buf) -#define DEL_EXIST(h, p) (h->buffer_spec[p->buf_spec_num].dv_enhance_exist) - - -#define vdec_dw_spec2canvas(x) \ - (((x)->vdec_dw_v_canvas_index << 16) | \ - ((x)->vdec_dw_u_canvas_index << 8) | \ - ((x)->vdec_dw_y_canvas_index << 0)) - - -#define spec2canvas(x) \ - (((x)->v_canvas_index << 16) | \ - ((x)->u_canvas_index << 8) | \ - ((x)->y_canvas_index << 0)) - -#define FRAME_INDEX(vf_index) (vf_index & 0xff) -#define BUFSPEC_INDEX(vf_index) ((vf_index >> 8) & 0xff) -#define VF_INDEX(frm_idx, bufspec_idx) (frm_idx | (bufspec_idx << 8)) - -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_work(struct work_struct *work); -static void vh264_timeout_work(struct work_struct *work); -static void vh264_notify_work(struct work_struct *work); -#ifdef MH264_USERDATA_ENABLE -static void user_data_ready_notify_work(struct work_struct *work); -static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec); -#endif - -static const char vh264_dec_id[] = "vh264-dev"; - -#define PROVIDER_NAME "vdec.h264" - -static const struct vframe_operations_s 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, -}; - -#define DEC_RESULT_NONE 0 -#define DEC_RESULT_DONE 1 -#define DEC_RESULT_AGAIN 2 -#define DEC_RESULT_CONFIG_PARAM 3 -#define DEC_RESULT_GET_DATA 4 -#define DEC_RESULT_GET_DATA_RETRY 5 -#define DEC_RESULT_ERROR 6 -#define DEC_RESULT_EOS 7 -#define DEC_RESULT_FORCE_EXIT 8 -#define DEC_RESULT_TIMEOUT 9 -#define DEC_RESULT_NEED_MORE_BUFFER 10 - - -/* - *static const char *dec_result_str[] = { - * "DEC_RESULT_NONE ", - * "DEC_RESULT_DONE ", - * "DEC_RESULT_AGAIN ", - * "DEC_RESULT_CONFIG_PARAM", - * "DEC_RESULT_GET_DATA ", - * "DEC_RESULT_GET_DA_RETRY", - * "DEC_RESULT_ERROR ", - *}; - */ - -#define UCODE_IP_ONLY 2 -#define UCODE_IP_ONLY_PARAM 1 - -#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_OFFSET_MAIN 0x5000 - -#define MC_TOTAL_SIZE ((20+16)*SZ_1K) -#define MC_SWAP_SIZE (4*SZ_1K) -#define MODE_ERROR 0 -#define MODE_FULL 1 - -#define DFS_HIGH_THEASHOLD 3 - -#define INIT_FLAG_REG AV_SCRATCH_2 -#define HEAD_PADING_REG AV_SCRATCH_3 -#define UCODE_WATCHDOG_REG AV_SCRATCH_7 -#define LMEM_DUMP_ADR AV_SCRATCH_L -#define DEBUG_REG1 AV_SCRATCH_M -#define DEBUG_REG2 AV_SCRATCH_N -#define FRAME_COUNTER_REG AV_SCRATCH_I -#define RPM_CMD_REG AV_SCRATCH_A -#define H264_DECODE_SIZE AV_SCRATCH_E -#define H264_DECODE_MODE AV_SCRATCH_4 -#define H264_DECODE_SEQINFO AV_SCRATCH_5 -#define H264_AUX_ADR AV_SCRATCH_C -#define H264_AUX_DATA_SIZE AV_SCRATCH_H - -#define H264_DECODE_INFO M4_CONTROL_REG /* 0xc29 */ -#define DPB_STATUS_REG AV_SCRATCH_J -#define ERROR_STATUS_REG AV_SCRATCH_9 - /* - NAL_SEARCH_CTL: bit 0, enable itu_t35 - NAL_SEARCH_CTL: bit 1, enable mmu - NAL_SEARCH_CTL: bit 2, detect frame_mbs_only_flag whether switch resolution - NAL_SEARCH_CTL: bit 15,bitstream_restriction_flag - */ -#define NAL_SEARCH_CTL AV_SCRATCH_9 -#define MBY_MBX MB_MOTION_MODE /*0xc07*/ - -#define DECODE_MODE_SINGLE 0x0 -#define DECODE_MODE_MULTI_FRAMEBASE 0x1 -#define DECODE_MODE_MULTI_STREAMBASE 0x2 -#define DECODE_MODE_MULTI_DVBAL 0x3 -#define DECODE_MODE_MULTI_DVENL 0x4 -static DEFINE_MUTEX(vmh264_mutex); -static DEFINE_MUTEX(reset_mutex); - - - -#ifdef MH264_USERDATA_ENABLE - -struct mh264_userdata_record_t { - struct userdata_meta_info_t meta_info; - u32 rec_start; - u32 rec_len; -}; - -struct mh264_ud_record_wait_node_t { - struct list_head list; - struct mh264_userdata_record_t ud_record; -}; -#define USERDATA_FIFO_NUM 256 -#define MAX_FREE_USERDATA_NODES 5 - -struct mh264_userdata_info_t { - struct mh264_userdata_record_t records[USERDATA_FIFO_NUM]; - u8 *data_buf; - u8 *data_buf_end; - u32 buf_len; - u32 read_index; - u32 write_index; - u32 last_wp; -}; - - -#endif - -struct mh264_fence_vf_t { - u32 used_size; - struct vframe_s *fence_vf[VF_POOL_SIZE]; -}; - - -struct vdec_h264_hw_s { - spinlock_t lock; - spinlock_t bufspec_lock; - int id; - struct platform_device *platform_dev; - unsigned long cma_alloc_addr; - /* struct page *collocate_cma_alloc_pages; */ - unsigned long collocate_cma_alloc_addr; - - u32 prefix_aux_size; - u32 suffix_aux_size; - void *aux_addr; - dma_addr_t aux_phy_addr; - - /* buffer for store all sei data */ - void *sei_data_buf; - u32 sei_data_len; - - /* buffer for storing one itu35 recored */ - void *sei_itu_data_buf; - u32 sei_itu_data_len; - - /* recycle buffer for user data storing all itu35 records */ - void *sei_user_data_buffer; - u32 sei_user_data_wp; -#ifdef MH264_USERDATA_ENABLE - struct work_struct user_data_ready_work; -#endif - struct StorablePicture *last_dec_picture; - - ulong lmem_phy_addr; - dma_addr_t lmem_addr; - - void *bmmu_box; -#ifdef H264_MMU - void *mmu_box; - void *frame_mmu_map_addr; - dma_addr_t frame_mmu_map_phy_addr; - u32 hevc_cur_buf_idx; - u32 losless_comp_body_size; - u32 losless_comp_body_size_sao; - u32 losless_comp_header_size; - u32 mc_buffer_size_u_v; - u32 mc_buffer_size_u_v_h; - u32 is_idr_frame; - u32 is_new_pic; - u32 frame_done; - u32 frame_busy; - unsigned long extif_addr; - int double_write_mode; - int mmu_enable; -#endif - - DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - - int cur_pool; - struct vframe_s vfpool[VF_POOL_NUM][VF_POOL_SIZE]; - struct buffer_spec_s buffer_spec[BUFSPEC_POOL_SIZE]; - struct vframe_s switching_fense_vf; - struct h264_dpb_stru dpb; - u8 init_flag; - u8 first_sc_checked; - u8 has_i_frame; - u8 config_bufmgr_done; - u32 max_reference_size; - u32 decode_pic_count; - u32 reflist_error_count; - int start_search_pos; - u32 reg_iqidct_control; - bool reg_iqidct_control_init_flag; - u32 reg_vcop_ctrl_reg; - u32 reg_rv_ai_mb_count; - u32 vld_dec_control; - struct vframe_s vframe_dummy; - - unsigned char buffer_empty_flag; - - u32 frame_width; - u32 frame_height; - u32 frame_dur; - u32 frame_prog; - u32 frame_packing_type; - - struct vframe_chunk_s *chunk; - - u32 stat; - unsigned long buf_start; - u32 buf_offset; - u32 buf_size; - /* u32 ucode_map_start; */ - u32 pts_outside; - u32 sync_outside; - u32 vh264_ratio; - u32 vh264_rotation; - u32 use_idr_framerate; - - u32 seq_info; - u32 seq_info2; - u32 video_signal_from_vui; /*to do .. */ - u32 timing_info_present_flag; - u32 fixed_frame_rate_flag; - u32 bitstream_restriction_flag; - u32 num_reorder_frames; - u32 max_dec_frame_buffering; - u32 iframe_count; - u32 aspect_ratio_info; - u32 num_units_in_tick; - u32 time_scale; - u32 h264_ar; - bool h264_first_valid_pts_ready; - u32 h264pts1; - u32 h264pts2; - u32 pts_duration; - u32 h264_pts_count; - u32 duration_from_pts_done; - u32 pts_unstable; - u32 unstable_pts; - u32 last_checkout_pts; - u32 max_refer_buf; - - s32 vh264_stream_switching_state; - struct vframe_s *p_last_vf; - u32 last_pts; - u32 last_pts_remainder; - u32 last_duration; - u32 last_mb_width, last_mb_height; - bool check_pts_discontinue; - bool pts_discontinue; - u32 wait_buffer_counter; - u32 first_offset; - u32 first_pts; - u64 first_pts64; - bool first_pts_cached; - u64 last_pts64; -#if 0 - void *sei_data_buffer; - dma_addr_t sei_data_buffer_phys; -#endif - - uint error_recovery_mode; - uint mb_total; - uint mb_width; - uint mb_height; - - uint i_only; - int skip_frame_count; - bool no_poc_reorder_flag; - bool send_error_frame_flag; - dma_addr_t mc_dma_handle; - void *mc_cpu_addr; - int vh264_reset; - - atomic_t vh264_active; - - struct dec_sysinfo vh264_amstream_dec_info; - - int dec_result; - u32 timeout_processing; - struct work_struct work; - struct work_struct notify_work; - struct work_struct timeout_work; - void (*vdec_cb)(struct vdec_s *, void *); - void *vdec_cb_arg; - - struct timer_list check_timer; - - /**/ - unsigned int last_frame_time; - atomic_t vf_pre_count; - atomic_t vf_get_count; - atomic_t vf_put_count; - - /* timeout handle */ - unsigned long int start_process_time; - unsigned int last_mby_mbx; - unsigned int last_vld_level; - unsigned int decode_timeout_count; - unsigned int timeout_num; - unsigned int search_dataempty_num; - unsigned int decode_timeout_num; - unsigned int decode_dataempty_num; - unsigned int buffer_empty_recover_num; - - unsigned get_data_count; - unsigned get_data_start_time; - /**/ - - /*log*/ - unsigned int packet_write_success_count; - unsigned int packet_write_EAGAIN_count; - unsigned int packet_write_ENOMEM_count; - unsigned int packet_write_EFAULT_count; - unsigned int total_read_size_pre; - unsigned int total_read_size; - unsigned int frame_count_pre; -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - u8 switch_dvlayer_flag; - u8 got_valid_nal; -#endif - u8 eos; - u8 data_flag; - u32 no_error_count; - u32 no_error_i_count; - /* - NODISP_FLAG - */ - u8 dec_flag; - - u32 ucode_pause_pos; - - u8 reset_bufmgr_flag; - u32 reset_bufmgr_count; - ulong timeout; - u32 timeout_flag; - u32 cfg_param1; - u32 cfg_param2; - u32 cfg_param3; - u32 cfg_param4; - u32 cfg_bitstream_restriction_flag; - int valve_count; - u8 next_again_flag; - u32 pre_parser_wr_ptr; - struct firmware_s *fw; - struct firmware_s *fw_mmu; -#ifdef MH264_USERDATA_ENABLE - /*user data*/ - struct mutex userdata_mutex; - struct mh264_userdata_info_t userdata_info; - struct mh264_userdata_record_t ud_record; - int wait_for_udr_send; -#endif - u32 no_mem_count; - u32 canvas_mode; - bool is_used_v4l; - void *v4l2_ctx; - bool v4l_params_parsed; - wait_queue_head_t wait_q; - u32 reg_g_status; - struct mutex chunks_mutex; - int need_cache_size; - u64 sc_start_time; - u8 frmbase_cont_flag; - struct vframe_qos_s vframe_qos; - int frameinfo_enable; - bool first_head_check_flag; - unsigned int height_aspect_ratio; - unsigned int width_aspect_ratio; - unsigned int first_i_policy; - u32 reorder_dpb_size_margin; - bool wait_reset_done_flag; -#ifdef DETECT_WRONG_MULTI_SLICE - unsigned int multi_slice_pic_check_count; - /* multi_slice_pic_flag: - 0, unknown; - 1, single slice; - 2, multi slice - */ - unsigned int multi_slice_pic_flag; - unsigned int picture_slice_count; - unsigned int cur_picture_slice_count; - unsigned char force_slice_as_picture_flag; - unsigned int last_picture_slice_count; - unsigned int first_pre_frame_num; -#endif - u32 res_ch_flag; - u32 b_frame_error_count; - struct vdec_info gvs; - u32 kpi_first_i_comming; - u32 kpi_first_i_decoded; - int sidebind_type; - int sidebind_channel_id; - u32 low_latency_mode; - int ip_field_error_count; - int buffer_wrap[BUFSPEC_POOL_SIZE]; - int loop_flag; - int loop_last_poc; - bool enable_fence; - int fence_usage; - bool discard_dv_data; - u32 metadata_config_flag; - int vdec_pg_enable_flag; - u32 save_reg_f; - u32 start_bit_cnt; - u32 right_frame_count; - u32 wrong_frame_count; - u32 error_frame_width; - u32 error_frame_height; - ulong fb_token; - struct mh264_fence_vf_t fence_vf_s; - struct mutex fence_mutex; - u32 no_decoder_buffer_flag; - u32 video_signal_type; - bool need_free_aux_data; - u32 error_proc_policy; - struct trace_decoder_name trace; - int csd_change_flag; -}; - -static u32 again_threshold; - -static void timeout_process(struct vdec_h264_hw_s *hw); -static void dump_bufspec(struct vdec_h264_hw_s *hw, - const char *caller); -static void h264_reconfig(struct vdec_h264_hw_s *hw); -static void h264_reset_bufmgr_v4l(struct vdec_s *vdec, int flush_flag); -static void vh264_local_init(struct vdec_h264_hw_s *hw, bool is_reset); -static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw); -static int vh264_stop(struct vdec_h264_hw_s *hw); -static s32 vh264_init(struct vdec_h264_hw_s *hw); -static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf, - u32 index); -static void release_aux_data(struct vdec_h264_hw_s *hw, - int buf_spec_num); -#ifdef ERROR_HANDLE_TEST -static void h264_clear_dpb(struct vdec_h264_hw_s *hw); -#endif - -#define H265_PUT_SAO_4K_SET 0x03 -#define H265_ABORT_SAO_4K_SET 0x04 -#define H265_ABORT_SAO_4K_SET_DONE 0x05 - -#define SYS_COMMAND HEVC_ASSIST_SCRATCH_0 -#define H265_CHECK_AXI_INFO_BASE HEVC_ASSIST_SCRATCH_8 -#define H265_SAO_4K_SET_BASE HEVC_ASSIST_SCRATCH_9 -#define H265_SAO_4K_SET_COUNT HEVC_ASSIST_SCRATCH_A -#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464 - - -#define HEVC_CM_HEADER_START_ADDR 0x3628 -#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 HEVC_SAO_CTRL9 0x362d -#define HEVCD_MPP_DECOMP_CTL3 0x34c4 -#define HEVCD_MPP_VDEC_MCR_CTL 0x34c8 -#define HEVC_DBLK_CFGB 0x350b -#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009 - -#define H265_DW_NO_SCALE -#define H265_MEM_MAP_MODE 0 /*0:linear 1:32x32 2:64x32*/ -#define H265_LOSLESS_COMPRESS_MODE -#define MAX_FRAME_4K_NUM 0x1200 -#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4) - -/* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */ -static u32 mem_map_mode = H265_MEM_MAP_MODE; - -#define MAX_SIZE_4K (4096 * 2304) -#define MAX_SIZE_2K (1920 * 1088) - - - -static int is_oversize(int w, int h) -{ - int max = MAX_SIZE_4K; - - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) - max = MAX_SIZE_2K; - - if (w < 0 || h < 0) - return true; - - if (h != 0 && (w > max / h)) - return true; - - return false; -} - -static void vmh264_udc_fill_vpts(struct vdec_h264_hw_s *hw, - int frame_type, - u32 vpts, - u32 vpts_valid); -static int compute_losless_comp_body_size(int width, - int height, int bit_depth_10); -static int compute_losless_comp_header_size(int width, int height); - -static int hevc_alloc_mmu(struct vdec_h264_hw_s *hw, int pic_idx, - int pic_width, int pic_height, u16 bit_depth, - unsigned int *mmu_index_adr) { - int cur_buf_idx; - int bit_depth_10 = (bit_depth != 0x00); - int picture_size; - u32 cur_mmu_4k_number; - - WRITE_VREG(CURR_CANVAS_CTRL, pic_idx<<24); - cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL)&0xff; - picture_size = compute_losless_comp_body_size(pic_width, - pic_height, bit_depth_10); - cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "alloc_mmu new_fb_idx %d picture_size %d cur_mmu_4k_number %d\n", - cur_buf_idx, picture_size, cur_mmu_4k_number); - - if (cur_mmu_4k_number > MAX_FRAME_4K_NUM) { - pr_err("hevc_alloc_mmu cur_mmu_4k_number %d unsupport\n", - cur_mmu_4k_number); - return -1; - } - - return decoder_mmu_box_alloc_idx( - hw->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); -} - -static int compute_losless_comp_body_size(int width, - int height, int 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 H264_MMU - bsize = (bit_depth_10 ? 4096 : 3264) * width_x64*height_x32; -#else - bsize = (bit_depth_10 ? 4096 : 3072) * width_x64*height_x32; -#endif - return bsize; -} - -static int compute_losless_comp_header_size(int width, int height) -{ - int width_x64; - int width_x128; - int height_x64; - int hsize; - - width_x64 = width + 63; - width_x64 >>= 6; - - width_x128 = width + 127; - width_x128 >>= 7; - - height_x64 = height + 63; - height_x64 >>= 6; - -#ifdef H264_MMU - hsize = 128*width_x64*height_x64; -#else - hsize = 32*width_x128*height_x64; -#endif - return hsize; -} - -static int get_dw_size(struct vdec_h264_hw_s *hw, u32 *pdw_buffer_size_u_v_h) -{ - int pic_width, pic_height; - int lcu_size = 16; - int dw_buf_size; - u32 dw_buffer_size_u_v; - u32 dw_buffer_size_u_v_h; - int dw_mode = hw->double_write_mode; - - pic_width = hw->frame_width; - pic_height = hw->frame_height; - - if (dw_mode) { - int pic_width_dw = pic_width / - get_double_write_ratio(hw->double_write_mode); - int pic_height_dw = pic_height / - get_double_write_ratio(hw->double_write_mode); - - 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; - - - dw_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2; - dw_buffer_size_u_v_h = (dw_buffer_size_u_v + 0xffff) >> 16; - /*64k alignment*/ - dw_buf_size = ((dw_buffer_size_u_v_h << 16) * 3); - *pdw_buffer_size_u_v_h = dw_buffer_size_u_v_h; - } else { - *pdw_buffer_size_u_v_h = 0; - dw_buf_size = 0; - } - - return dw_buf_size; -} - - -static void hevc_mcr_config_canv2axitbl(struct vdec_h264_hw_s *hw, int restore) -{ - int i, size; - u32 canvas_addr; - unsigned long maddr; - int num_buff = hw->dpb.mDPB.size; - int dw_size = 0; - u32 dw_buffer_size_u_v_h; - u32 blkmode = hw->canvas_mode; - int dw_mode = hw->double_write_mode; - - canvas_addr = ANC0_CANVAS_ADDR; - for (i = 0; i < num_buff; i++) - WRITE_VREG((canvas_addr + i), i | (i << 8) | (i << 16)); - - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2)); - size = hw->losless_comp_body_size + hw->losless_comp_header_size; - - - dw_size = get_dw_size(hw, &dw_buffer_size_u_v_h); - size += dw_size; - if (size > 0) - size += 0x10000; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, - "dw_buffer_size_u_v_h = %d, dw_size = 0x%x, size = 0x%x\n", - dw_buffer_size_u_v_h, dw_size, size); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, - "body_size = %d, header_size = %d, body_size_sao = %d\n", - hw->losless_comp_body_size, - hw->losless_comp_header_size, - hw->losless_comp_body_size_sao); - - for (i = 0; i < num_buff; i++) { - if (!restore) { - if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, - HEADER_BUFFER_IDX(i), size, - DRIVER_HEADER_NAME, &maddr) < 0) { - dpb_print(DECODE_ID(hw), 0, - "%s malloc compress header failed %d\n", - DRIVER_HEADER_NAME, i); - return; - } - } else - maddr = hw->buffer_spec[i].alloc_header_addr; - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, maddr >> 5); - hw->buffer_spec[i].alloc_header_addr = maddr; - dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, - "%s : canvas: %d axiaddr:%x size 0x%x\n", - __func__, i, (u32)maddr, size); - - if (dw_mode) { - u32 addr; - int canvas_w; - int canvas_h; - - canvas_w = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); - canvas_h = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); - - if (hw->canvas_mode == 0) - canvas_w = ALIGN(canvas_w, 32); - else - canvas_w = ALIGN(canvas_w, 64); - canvas_h = ALIGN(canvas_h, 32); - - hw->buffer_spec[i].dw_y_adr = - maddr + hw->losless_comp_header_size; - - hw->buffer_spec[i].dw_y_adr = - ((hw->buffer_spec[i].dw_y_adr + 0xffff) >> 16) - << 16; - hw->buffer_spec[i].dw_u_v_adr = - hw->buffer_spec[i].dw_y_adr - + (dw_buffer_size_u_v_h << 16) * 2; - - - hw->buffer_spec[i].buf_adr - = hw->buffer_spec[i].dw_y_adr; - addr = hw->buffer_spec[i].buf_adr; - - - dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, - "dw_y_adr = 0x%x, dw_u_v_adr = 0x%x, y_addr = 0x%x, u_addr = 0x%x, v_addr = 0x%x, width = %d, height = %d\n", - hw->buffer_spec[i].dw_y_adr, - hw->buffer_spec[i].dw_u_v_adr, - hw->buffer_spec[i].y_addr, - hw->buffer_spec[i].u_addr, - hw->buffer_spec[i].v_addr, - canvas_w, - canvas_h); - - hw->buffer_spec[i].canvas_config[0].phy_addr = - hw->buffer_spec[i].dw_y_adr; - hw->buffer_spec[i].canvas_config[0].width = canvas_w; - hw->buffer_spec[i].canvas_config[0].height = canvas_h; - hw->buffer_spec[i].canvas_config[0].block_mode = - blkmode; - hw->buffer_spec[i].canvas_config[0].endian = 7; - - hw->buffer_spec[i].canvas_config[1].phy_addr = - hw->buffer_spec[i].dw_u_v_adr; - hw->buffer_spec[i].canvas_config[1].width = canvas_w; - hw->buffer_spec[i].canvas_config[1].height = canvas_h; - hw->buffer_spec[i].canvas_config[1].block_mode = - blkmode; - hw->buffer_spec[i].canvas_config[1].endian = 7; - } - } - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); - - 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); - return; -} -static void hevc_mcr_config_mc_ref(struct vdec_h264_hw_s *hw) -{ - u32 i; - u32 ref_canv; - struct Slice *pSlice = &(hw->dpb.mSlice); - /*REFLIST[0]*/ - for (i = 0; i < (unsigned int)(pSlice->listXsize[0]); i++) { - struct StorablePicture *ref = pSlice->listX[0][i]; - if (ref == NULL) - return; - WRITE_VREG(CURR_CANVAS_CTRL, ref->buf_spec_num<<24); - ref_canv = READ_VREG(CURR_CANVAS_CTRL)&0xffffff; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (ref->buf_spec_num & 0x3f) << 8); - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, ref_canv); - } - /*REFLIST[1]*/ - for (i = 0; i < (unsigned int)(pSlice->listXsize[1]); i++) { - struct StorablePicture *ref = pSlice->listX[1][i]; - if (ref == NULL) - return; - WRITE_VREG(CURR_CANVAS_CTRL, ref->buf_spec_num<<24); - ref_canv = READ_VREG(CURR_CANVAS_CTRL)&0xffffff; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (ref->buf_spec_num & 0x3f) << 8); - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, ref_canv); - } - return; -} - -static void hevc_mcr_config_mcrcc(struct vdec_h264_hw_s *hw) -{ - u32 rdata32; - u32 rdata32_2; - u32 slice_type; - struct StorablePicture *ref; - struct Slice *pSlice; - slice_type = hw->dpb.mSlice.slice_type; - pSlice = &(hw->dpb.mSlice); - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); - if (slice_type == I_SLICE) { - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0); - return; - } - if (slice_type == B_SLICE) { - ref = pSlice->listX[0][0]; - if (ref == NULL) - return; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - ((ref->buf_spec_num & 0x3f) << 8)); - rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR); - rdata32 = rdata32 & 0xffff; - rdata32 = rdata32 | (rdata32 << 16); - WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32); - - ref = pSlice->listX[1][0]; - if (ref == NULL) - return; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - ((ref->buf_spec_num & 0x3f) << 8)); - 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) { - ref = pSlice->listX[1][1]; - if (ref == NULL) - return; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - ((ref->buf_spec_num & 0x3f) << 8)); - 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*/ - ref = pSlice->listX[0][0]; - if (ref == NULL) - return; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - ((ref->buf_spec_num & 0x3f) << 8)); - rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR); - rdata32 = rdata32 & 0xffff; - rdata32 = rdata32 | (rdata32 << 16); - WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32); - - ref = pSlice->listX[0][1]; - if (ref == NULL) - return; - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - ((ref->buf_spec_num & 0x3f) << 8)); - 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); - return; -} - - -static void hevc_mcr_sao_global_hw_init(struct vdec_h264_hw_s *hw, - u32 width, u32 height) { - u32 data32; - u32 lcu_x_num, lcu_y_num; - u32 lcu_total; - u32 mc_buffer_size_u_v; - u32 mc_buffer_size_u_v_h; - int dw_mode = hw->double_write_mode; - - /*lcu_x_num = (width + 15) >> 4;*/ - // width need to be round to 64 pixel -- case0260 1/10/2020 - lcu_x_num = (((width + 63) >> 6) << 2); - lcu_y_num = (height + 15) >> 4; - lcu_total = lcu_x_num * lcu_y_num; - - hw->mc_buffer_size_u_v = mc_buffer_size_u_v = lcu_total*16*16/2; - hw->mc_buffer_size_u_v_h = - mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; - - hw->losless_comp_body_size = 0; - - hw->losless_comp_body_size_sao = - compute_losless_comp_body_size(width, height, 0); - hw->losless_comp_header_size = - compute_losless_comp_header_size(width, height); - - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1); /*sw reset ipp10b_top*/ - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x0); /*sw reset ipp10b_top*/ - - /* setup lcu_size = 16*/ - WRITE_VREG(HEVCD_IPP_TOP_LCUCONFIG, 16); /*set lcu size = 16*/ - /*pic_width/pic_height*/ - WRITE_VREG(HEVCD_IPP_TOP_FRMCONFIG, - (height & 0xffff) << 16 | (width & 0xffff)); - /* bitdepth_luma = 8*/ - /* bitdepth_chroma = 8*/ - WRITE_VREG(HEVCD_IPP_BITDEPTH_CONFIG, 0x0);/*set bit-depth 8 */ - -#ifdef H265_LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4)); - WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0); -#else - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); -#endif - data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); - data32 &= (~0x30); - data32 |= (hw->canvas_mode << 4); - WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); - - WRITE_VREG(HEVCD_MPP_DECOMP_CTL3, - (0x80 << 20) | (0x80 << 10) | (0xff)); - - WRITE_VREG(HEVCD_MPP_VDEC_MCR_CTL, 0x1 | (0x1 << 4)); - - /*comfig vdec:h264:mdec to use hevc mcr/mcrcc/decomp*/ - WRITE_VREG(MDEC_PIC_DC_MUX_CTRL, - READ_VREG(MDEC_PIC_DC_MUX_CTRL) | 0x1 << 31); - /* ipp_enable*/ - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1 << 1); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(HEVC_DBLK_CFG1, 0x2); // set ctusize==16 - WRITE_VREG(HEVC_DBLK_CFG2, ((height & 0xffff)<<16) | (width & 0xffff)); - if (dw_mode & 0x10) - WRITE_VREG(HEVC_DBLK_CFGB, 0x40405603); - else if (dw_mode) - WRITE_VREG(HEVC_DBLK_CFGB, 0x40405703); - else - WRITE_VREG(HEVC_DBLK_CFGB, 0x40405503); - } - - data32 = READ_VREG(HEVC_SAO_CTRL0); - data32 &= (~0xf); - data32 |= 0x4; - WRITE_VREG(HEVC_SAO_CTRL0, data32); - WRITE_VREG(HEVC_SAO_PIC_SIZE, (height & 0xffff) << 16 | - (width & 0xffff)); - data32 = ((lcu_x_num-1) | (lcu_y_num-1) << 16); - - WRITE_VREG(HEVC_SAO_PIC_SIZE_LCU, data32); - data32 = (lcu_x_num | lcu_y_num << 16); - WRITE_VREG(HEVC_SAO_TILE_SIZE_LCU, data32); - data32 = (mc_buffer_size_u_v_h << 16) << 1; - WRITE_VREG(HEVC_SAO_Y_LENGTH, data32); - data32 = (mc_buffer_size_u_v_h << 16); - WRITE_VREG(HEVC_SAO_C_LENGTH, data32); - - data32 = READ_VREG(HEVC_SAO_CTRL1); - data32 &= (~0x3000); - data32 &= (~0xff0); - data32 |= endian; /* Big-Endian per 64-bit */ - - if (hw->mmu_enable && (dw_mode & 0x10)) - data32 |= ((hw->canvas_mode << 12) |1); - else if (hw->mmu_enable && dw_mode) - data32 |= ((hw->canvas_mode << 12)); - else - data32 |= ((hw->canvas_mode << 12)|2); - - WRITE_VREG(HEVC_SAO_CTRL1, data32); - -#ifdef H265_DW_NO_SCALE - WRITE_VREG(HEVC_SAO_CTRL5, READ_VREG(HEVC_SAO_CTRL5) & ~(0xff << 16)); - if (hw->mmu_enable && dw_mode) { - data32 = READ_VREG(HEVC_SAO_CTRL5); - data32 &= (~(0xff << 16)); - if (dw_mode == 2 || - dw_mode == 3) - data32 |= (0xff<<16); - else if (dw_mode == 4) - data32 |= (0x33<<16); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - } - - -#endif - - -#ifdef H265_LOSLESS_COMPRESS_MODE - data32 = READ_VREG(HEVC_SAO_CTRL5); - data32 |= (1<<9); /*8-bit smem-mode*/ - WRITE_VREG(HEVC_SAO_CTRL5, data32); - - WRITE_VREG(HEVC_CM_BODY_LENGTH, hw->losless_comp_body_size_sao); - WRITE_VREG(HEVC_CM_HEADER_OFFSET, hw->losless_comp_body_size); - WRITE_VREG(HEVC_CM_HEADER_LENGTH, hw->losless_comp_header_size); -#endif - -#ifdef H265_LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVC_SAO_CTRL9, READ_VREG(HEVC_SAO_CTRL9) | (0x1 << 1)); - WRITE_VREG(HEVC_SAO_CTRL5, READ_VREG(HEVC_SAO_CTRL5) | (0x1 << 10)); -#endif - - WRITE_VREG(HEVC_SAO_CTRL9, READ_VREG(HEVC_SAO_CTRL9) | 0x1 << 7); - - memset(hw->frame_mmu_map_addr, 0, FRAME_MMU_MAP_SIZE); - - WRITE_VREG(MDEC_EXTIF_CFG0, hw->extif_addr); - WRITE_VREG(MDEC_EXTIF_CFG1, 0x80000000); - return; -} - -static void hevc_sao_set_slice_type(struct vdec_h264_hw_s *hw, - u32 is_new_pic, u32 is_idr) -{ - hw->is_new_pic = is_new_pic; - hw->is_idr_frame = is_idr; - return; -} - -static void hevc_sao_set_pic_buffer(struct vdec_h264_hw_s *hw, - struct StorablePicture *pic) { - u32 mc_y_adr; - u32 mc_u_v_adr; - u32 dw_y_adr; - u32 dw_u_v_adr; - u32 canvas_addr; - int ret; - int dw_mode = hw->double_write_mode; - if (hw->is_new_pic != 1) - return; - - if (hw->is_idr_frame) { - /* William TBD */ - memset(hw->frame_mmu_map_addr, 0, FRAME_MMU_MAP_SIZE); - } - - WRITE_VREG(CURR_CANVAS_CTRL, pic->buf_spec_num << 24); - canvas_addr = READ_VREG(CURR_CANVAS_CTRL)&0xffffff; - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x0 << 1) | - (0x0 << 2) | ((canvas_addr & 0xff) << 8)); - mc_y_adr = READ_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA) << 5; - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x0 << 1) | - (0x0 << 2) | (((canvas_addr >> 8) & 0xff) << 8)); - mc_u_v_adr = READ_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA) << 5; - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); - - - if (dw_mode) { - dw_y_adr = hw->buffer_spec[pic->buf_spec_num].dw_y_adr; - dw_u_v_adr = hw->buffer_spec[pic->buf_spec_num].dw_u_v_adr; - } else { - dw_y_adr = 0; - dw_u_v_adr = 0; - } -#ifdef H265_LOSLESS_COMPRESS_MODE - if (dw_mode) - WRITE_VREG(HEVC_SAO_Y_START_ADDR, dw_y_adr); - WRITE_VREG(HEVC_CM_BODY_START_ADDR, mc_y_adr); -#ifdef H264_MMU - WRITE_VREG(HEVC_CM_HEADER_START_ADDR, mc_y_adr); -#else - WRITE_VREG(HEVC_CM_HEADER_START_ADDR, - (mc_y_adr + hw->losless_comp_body_size)); -#endif -#else - WRITE_VREG(HEVC_SAO_Y_START_ADDR, mc_y_adr); -#endif - -#ifndef H265_LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVC_SAO_C_START_ADDR, mc_u_v_adr); -#else - if (dw_mode) - WRITE_VREG(HEVC_SAO_C_START_ADDR, dw_u_v_adr); -#endif - -#ifndef LOSLESS_COMPRESS_MODE - if (dw_mode) { - WRITE_VREG(HEVC_SAO_Y_WPTR, mc_y_adr); - WRITE_VREG(HEVC_SAO_C_WPTR, mc_u_v_adr); - } -#else - WRITE_VREG(HEVC_SAO_Y_WPTR, dw_y_adr); - WRITE_VREG(HEVC_SAO_C_WPTR, dw_u_v_adr); -#endif - - ret = hevc_alloc_mmu(hw, pic->buf_spec_num, - (hw->mb_width << 4), (hw->mb_height << 4), 0x0, - hw->frame_mmu_map_addr); - if (ret != 0) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, "can't alloc need mmu1,idx %d ret =%d\n", - pic->buf_spec_num, - ret); - return; - } - - /*Reset SAO + Enable SAO slice_start*/ - if (hw->mmu_enable && get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) - WRITE_VREG(HEVC_DBLK_CFG0, 0x1); // reset buffer32x4 in lpf for every picture - WRITE_VREG(HEVC_SAO_INT_STATUS, - READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 28); - WRITE_VREG(HEVC_SAO_INT_STATUS, - READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 31); - /*pr_info("hevc_sao_set_pic_buffer:mc_y_adr: %x\n", mc_y_adr);*/ - /*Send coommand to hevc-code to supply 4k buffers to sao*/ - - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(H265_SAO_4K_SET_BASE, (u32)hw->frame_mmu_map_phy_addr); - WRITE_VREG(H265_SAO_4K_SET_COUNT, MAX_FRAME_4K_NUM); - } else - WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, (u32)hw->frame_mmu_map_phy_addr); - WRITE_VREG(SYS_COMMAND, H265_PUT_SAO_4K_SET); - hw->frame_busy = 1; - return; -} - - -static void hevc_set_unused_4k_buff_idx(struct vdec_h264_hw_s *hw, - u32 buf_spec_num) { - WRITE_VREG(CURR_CANVAS_CTRL, buf_spec_num<<24); - hw->hevc_cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL)&0xff; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, " %s cur_buf_idx %d buf_spec_num %d\n", - __func__, hw->hevc_cur_buf_idx, buf_spec_num); - return; -} - - -static void hevc_set_frame_done(struct vdec_h264_hw_s *hw) -{ - ulong timeout = jiffies + HZ; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, "hevc_frame_done...set\n"); - while ((READ_VREG(HEVC_SAO_INT_STATUS) & 0x1) == 0) { - if (time_after(jiffies, timeout)) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, " %s..timeout!\n", __func__); - break; - } - } - timeout = jiffies + HZ; - while (READ_VREG(HEVC_CM_CORE_STATUS) & 0x1) { - if (time_after(jiffies, timeout)) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, " %s cm_core..timeout!\n", __func__); - break; - } - } - WRITE_VREG(HEVC_SAO_INT_STATUS, 0x1); - hw->frame_done = 1; - return; -} - -static void release_cur_decoding_buf(struct vdec_h264_hw_s *hw) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - if (p_H264_Dpb->mVideo.dec_picture) { - release_picture(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture); - p_H264_Dpb->mVideo.dec_picture->data_flag &= ~ERROR_FLAG; - p_H264_Dpb->mVideo.dec_picture = NULL; - if (hw->mmu_enable) - hevc_set_frame_done(hw); - } -} - -static void hevc_sao_wait_done(struct vdec_h264_hw_s *hw) -{ - ulong timeout = jiffies + HZ; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...start\n"); - while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31)) { - if (time_after(jiffies, timeout)) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "hevc_sao_wait_done...wait timeout!\n"); - break; - } - } - timeout = jiffies + HZ; - if ((hw->frame_busy == 1) && (hw->frame_done == 1) ) { - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET); - while ((READ_VREG(SYS_COMMAND) & 0xff) != - H265_ABORT_SAO_4K_SET_DONE) { - if (time_after(jiffies, timeout)) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "wait h265_abort_sao_4k_set_done timeout!\n"); - break; - } - } - } - amhevc_stop(); - hw->frame_busy = 0; - hw->frame_done = 0; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "sao wait done ,hevc stop!\n"); - } - return; -} -static void buf_spec_init(struct vdec_h264_hw_s *hw, bool buffer_reset_flag) -{ - int i; - unsigned long flags; - spin_lock_irqsave(&hw->bufspec_lock, flags); - - for (i = 0; i < VF_POOL_SIZE; i++) { - struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i]; - u32 ref_idx = BUFSPEC_INDEX(vf->index); - if ((vf->index != -1) && - (hw->buffer_spec[ref_idx].vf_ref == 0) && - (hw->buffer_spec[ref_idx].used != -1)) { - vf->index = -1; - } - } - - hw->cur_pool++; - if (hw->cur_pool >= VF_POOL_NUM) - hw->cur_pool = 0; - - for (i = 0; i < VF_POOL_SIZE; i++) { - struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i]; - u32 ref_idx = BUFSPEC_INDEX(vf->index); - if ((vf->index != -1) && - (hw->buffer_spec[ref_idx].vf_ref == 0) && - (hw->buffer_spec[ref_idx].used != -1)) { - vf->index = -1; - } - } - /* buffers are alloced when error reset, v4l must find buffer by buffer_wrap[] */ - if (hw->reset_bufmgr_flag && buffer_reset_flag) { - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].used == 1 || hw->buffer_spec[i].used == 2) - hw->buffer_spec[i].used = 0; - } - } else { - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - hw->buffer_spec[i].used = -1; - hw->buffer_spec[i].canvas_pos = -1; - hw->buffer_wrap[i] = -1; - } - } - - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - spin_unlock_irqrestore(&hw->bufspec_lock, flags); -} - - -/*is active in buf management */ -static unsigned char is_buf_spec_in_use(struct vdec_h264_hw_s *hw, - int buf_spec_num) -{ - unsigned char ret = 0; - if (hw->buffer_spec[buf_spec_num].used == 1 || - hw->buffer_spec[buf_spec_num].used == 2 || - hw->buffer_spec[buf_spec_num].used == 3 || - hw->buffer_spec[buf_spec_num].used == 5) - ret = 1; - return ret; -} - -static unsigned char is_buf_spec_in_disp_q(struct vdec_h264_hw_s *hw, - int buf_spec_num) -{ - unsigned char ret = 0; - if (hw->buffer_spec[buf_spec_num].used == 2 || - hw->buffer_spec[buf_spec_num].used == 3 || - hw->buffer_spec[buf_spec_num].used == 5) - ret = 1; - return ret; -} - -static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i) -{ - struct vdec_s *vdec = hw_to_vdec(hw); - if (hw->mmu_enable) { - if (hw->buffer_spec[i].alloc_header_addr) - return 0; - else - return -1; - } else { - - int buf_size = (hw->mb_total << 8) + (hw->mb_total << 7); - int addr; -#ifdef VDEC_DW - int orig_buf_size; - orig_buf_size = buf_size; - if (IS_VDEC_DW(hw) == 1) - buf_size += (hw->mb_total << 7) + (hw->mb_total << 6); - else if (IS_VDEC_DW(hw) == 2) - buf_size += (hw->mb_total << 6) + (hw->mb_total << 5); - else if (IS_VDEC_DW(hw) == 4) - buf_size += (hw->mb_total << 4) + (hw->mb_total << 3); - else if (IS_VDEC_DW(hw) == 8) - buf_size += (hw->mb_total << 2) + (hw->mb_total << 1); - if (IS_VDEC_DW(hw)) { - u32 align_size; - /* add align padding size for blk64x32: (mb_w<<4)*32, (mb_h<<4)*64 */ - align_size = ((hw->mb_width << 9) + (hw->mb_height << 10)) / IS_VDEC_DW(hw); - /* double align padding size for uv*/ - align_size <<= 1; - buf_size += align_size + PAGE_SIZE; - } -#endif - if (hw->buffer_spec[i].cma_alloc_addr) - return 0; - - if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i, - PAGE_ALIGN(buf_size), DRIVER_NAME, - &hw->buffer_spec[i].cma_alloc_addr) < 0) { - hw->buffer_spec[i].cma_alloc_addr = 0; - if (hw->no_mem_count++ > 3) { - hw->stat |= DECODER_FATAL_ERROR_NO_MEM; - hw->reset_bufmgr_flag = 1; - } - dpb_print(DECODE_ID(hw), 0, - "%s, fail to alloc buf for bufspec%d, try later\n", - __func__, i - ); - return -1; - } else { - hw->no_mem_count = 0; - hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM; - } - if (!vdec_secure(vdec)) { - /*init internal buf*/ - char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr); - if (tmpbuf) { - memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); - codec_mm_dma_flush(tmpbuf, - PAGE_ALIGN(buf_size), - DMA_TO_DEVICE); - } else { - tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size)); - if (tmpbuf) { - memset(tmpbuf, 0, PAGE_ALIGN(buf_size)); - codec_mm_dma_flush(tmpbuf, - PAGE_ALIGN(buf_size), - DMA_TO_DEVICE); - codec_mm_unmap_phyaddr(tmpbuf); - } - } - } - hw->buffer_spec[i].buf_adr = - hw->buffer_spec[i].cma_alloc_addr; - addr = hw->buffer_spec[i].buf_adr; - - - hw->buffer_spec[i].y_addr = addr; - addr += hw->mb_total << 8; - hw->buffer_spec[i].u_addr = addr; - hw->buffer_spec[i].v_addr = addr; - addr += hw->mb_total << 7; - - hw->buffer_spec[i].canvas_config[0].phy_addr = - hw->buffer_spec[i].y_addr; - hw->buffer_spec[i].canvas_config[0].width = - hw->mb_width << 4; - hw->buffer_spec[i].canvas_config[0].height = - hw->mb_height << 4; - hw->buffer_spec[i].canvas_config[0].block_mode = - hw->canvas_mode; - - hw->buffer_spec[i].canvas_config[1].phy_addr = - hw->buffer_spec[i].u_addr; - hw->buffer_spec[i].canvas_config[1].width = - hw->mb_width << 4; - hw->buffer_spec[i].canvas_config[1].height = - hw->mb_height << 3; - hw->buffer_spec[i].canvas_config[1].block_mode = - hw->canvas_mode; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, alloc buf for bufspec%d\n", - __func__, i); -#ifdef VDEC_DW - if (!IS_VDEC_DW(hw)) - return 0; - else { - int w_shift = 3, h_shift = 3; - - if (IS_VDEC_DW(hw) == 1) { - w_shift = 3; - h_shift = 4; - } else if (IS_VDEC_DW(hw) == 2) { - w_shift = 3; - h_shift = 3; - } else if (IS_VDEC_DW(hw) == 4) { - w_shift = 2; - h_shift = 2; - } else if (IS_VDEC_DW(hw) == 8) { - w_shift = 1; - h_shift = 1; - } - - addr = hw->buffer_spec[i].cma_alloc_addr + PAGE_ALIGN(orig_buf_size); - hw->buffer_spec[i].vdec_dw_y_addr = addr; - addr += ALIGN_WIDTH(hw->mb_width << w_shift) * ALIGN_HEIGHT(hw->mb_height << h_shift); - hw->buffer_spec[i].vdec_dw_u_addr = addr; - hw->buffer_spec[i].vdec_dw_v_addr = addr; - addr += hw->mb_total << (w_shift + h_shift - 1); - - hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr = - hw->buffer_spec[i].vdec_dw_y_addr; - hw->buffer_spec[i].vdec_dw_canvas_config[0].width = - ALIGN_WIDTH(hw->mb_width << w_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[0].height = - ALIGN_HEIGHT(hw->mb_height << h_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode = - hw->canvas_mode; - - hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr = - hw->buffer_spec[i].vdec_dw_u_addr; - hw->buffer_spec[i].vdec_dw_canvas_config[1].width = - ALIGN_WIDTH(hw->mb_width << w_shift); - hw->buffer_spec[i].vdec_dw_canvas_config[1].height = - ALIGN_HEIGHT(hw->mb_height << (h_shift - 1)); - hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode = - hw->canvas_mode; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, vdec_dw: alloc buf for bufspec%d blkmod %d\n", - __func__, i, hw->canvas_mode); - } -#endif - } - return 0; -} - -static void vh264_put_video_frame(void *vdec_ctx, struct vframe_s *vf) -{ - vh264_vf_put(vf, vdec_ctx); -} - -static void vh264_get_video_frame(void *vdec_ctx, struct vframe_s **vf) -{ - *vf = vh264_vf_get(vdec_ctx); -} - -static struct task_ops_s task_dec_ops = { - .type = TASK_TYPE_DEC, - .get_vframe = vh264_get_video_frame, - .put_vframe = vh264_put_video_frame, -}; - -static int alloc_one_buf_spec_from_queue(struct vdec_h264_hw_s *hw, int idx) -{ - int ret = 0; - struct aml_vcodec_ctx *ctx = NULL; - struct buffer_spec_s *bs = &hw->buffer_spec[idx]; - struct canvas_config_s *y_canvas_cfg = NULL; - struct canvas_config_s *c_canvas_cfg = NULL; - struct vdec_v4l2_buffer *fb = NULL; - unsigned int y_addr = 0, c_addr = 0; - - if (IS_ERR_OR_NULL(hw->v4l2_ctx)) { - pr_err("the v4l context has err.\n"); - return -1; - } - - if (bs->cma_alloc_addr) - return 0; - - ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), try alloc from v4l queue buf size: %d\n", - ctx->id, __func__, - (hw->mb_total << 8) + (hw->mb_total << 7)); - - ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC); - if (ret < 0) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] get fb fail.\n", ctx->id); - return ret; - } - - bs->cma_alloc_addr = (unsigned long)fb; - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), cma alloc addr: 0x%x, out %d dec %d\n", - ctx->id, __func__, bs->cma_alloc_addr, - ctx->cap_pool.out, ctx->cap_pool.dec); - - if (fb->num_planes == 1) { - y_addr = fb->m.mem[0].addr; - c_addr = fb->m.mem[0].addr + fb->m.mem[0].offset; - fb->m.mem[0].bytes_used = fb->m.mem[0].size; - } else if (fb->num_planes == 2) { - y_addr = fb->m.mem[0].addr; - c_addr = fb->m.mem[1].addr; - fb->m.mem[0].bytes_used = fb->m.mem[0].size; - fb->m.mem[1].bytes_used = fb->m.mem[1].size; - } - - fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hw)); - fb->status = FB_ST_DECODER; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), y_addr: %x, size: %u\n", - ctx->id, __func__, y_addr, fb->m.mem[0].size); - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), c_addr: %x, size: %u\n", - ctx->id, __func__, c_addr, fb->m.mem[1].size); - - bs->y_addr = y_addr; - bs->u_addr = c_addr; - bs->v_addr = c_addr; - - y_canvas_cfg = &bs->canvas_config[0]; - c_canvas_cfg = &bs->canvas_config[1]; - - y_canvas_cfg->phy_addr = y_addr; - y_canvas_cfg->width = hw->mb_width << 4; - y_canvas_cfg->height = hw->mb_height << 4; - y_canvas_cfg->block_mode = hw->canvas_mode; - //fb->m.mem[0].bytes_used = y_canvas_cfg->width * y_canvas_cfg->height; - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), y_w: %d, y_h: %d\n", ctx->id, __func__, - y_canvas_cfg->width,y_canvas_cfg->height); - - c_canvas_cfg->phy_addr = c_addr; - c_canvas_cfg->width = hw->mb_width << 4; - c_canvas_cfg->height = hw->mb_height << 3; - c_canvas_cfg->block_mode = hw->canvas_mode; - //fb->m.mem[1].bytes_used = c_canvas_cfg->width * c_canvas_cfg->height; - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), c_w: %d, c_h: %d\n", ctx->id, __func__, - c_canvas_cfg->width, c_canvas_cfg->height); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "[%d] %s(), alloc buf for bufspec%d\n", ctx->id, __func__, idx); - - return ret; -} - -static void config_decode_canvas(struct vdec_h264_hw_s *hw, int i) -{ - int blkmode = hw->canvas_mode; - int endian = 0; - - if (blkmode == CANVAS_BLKMODE_LINEAR) { - if ((h264_debug_flag & IGNORE_PARAM_FROM_CONFIG) == 0) - endian = 7; - else - endian = 0; - } - - if (hw->is_used_v4l) - endian = 7; - - config_cav_lut_ex(hw->buffer_spec[i]. - y_canvas_index, - hw->buffer_spec[i].y_addr, - hw->mb_width << 4, - hw->mb_height << 4, - CANVAS_ADDR_NOWRAP, - blkmode, - endian, - VDEC_1); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, - (1 << 11) | /* canvas_blk32_wr */ - (blkmode << 10) | /* canvas_blk32*/ - (1 << 8) | /* canvas_index_wr*/ - (hw->buffer_spec[i].y_canvas_index << 0) /* canvas index*/ - ); - } - - config_cav_lut_ex(hw->buffer_spec[i]. - u_canvas_index, - hw->buffer_spec[i].u_addr, - hw->mb_width << 4, - hw->mb_height << 3, - CANVAS_ADDR_NOWRAP, - blkmode, - endian, - VDEC_1); - - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, - (1 << 11) | - (blkmode << 10) | - (1 << 8) | - (hw->buffer_spec[i].u_canvas_index << 0)); - } - - WRITE_VREG(ANC0_CANVAS_ADDR + hw->buffer_spec[i].canvas_pos, - spec2canvas(&hw->buffer_spec[i])); - - -#ifdef VDEC_DW - if (!IS_VDEC_DW(hw)) - return; - else { - config_cav_lut_ex(hw->buffer_spec[i]. - vdec_dw_y_canvas_index, - hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr, - hw->buffer_spec[i].vdec_dw_canvas_config[0].width, - hw->buffer_spec[i].vdec_dw_canvas_config[0].height, - CANVAS_ADDR_NOWRAP, - blkmode, - endian, - VDEC_1); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, - (1 << 11) | - (blkmode << 10) | - (1 << 8) | - (hw->buffer_spec[i].vdec_dw_y_canvas_index << 0)); - } - - config_cav_lut_ex(hw->buffer_spec[i]. - vdec_dw_u_canvas_index, - hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr, - hw->buffer_spec[i].vdec_dw_canvas_config[1].width, - hw->buffer_spec[i].vdec_dw_canvas_config[1].height, - CANVAS_ADDR_NOWRAP, - blkmode, - endian, - VDEC_1); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { - WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32, - (1 << 11) | - (blkmode << 10) | - (1 << 8) | - (hw->buffer_spec[i].vdec_dw_u_canvas_index << 0)); - } - } -#endif -} - -static void config_decode_canvas_ex(struct vdec_h264_hw_s *hw, int i) -{ - u32 blkmode = hw->canvas_mode; - int canvas_w; - int canvas_h; - - canvas_w = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); - canvas_h = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); - - if (hw->canvas_mode == 0) - canvas_w = ALIGN(canvas_w, 32); - else - canvas_w = ALIGN(canvas_w, 64); - canvas_h = ALIGN(canvas_h, 32); - - config_cav_lut_ex(hw->buffer_spec[i]. - y_canvas_index, - hw->buffer_spec[i].dw_y_adr, - canvas_w, - canvas_h, - CANVAS_ADDR_NOWRAP, - blkmode, - 7, - VDEC_HEVC); - - config_cav_lut_ex(hw->buffer_spec[i]. - u_canvas_index, - hw->buffer_spec[i].dw_u_v_adr, - canvas_w, - canvas_h, - CANVAS_ADDR_NOWRAP, - blkmode, - 7, - VDEC_HEVC); -} - -static int v4l_get_free_buffer_spec(struct vdec_h264_hw_s *hw) -{ - int i; - - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].cma_alloc_addr == 0) - return i; - } - - return -1; -} - -static int v4l_find_buffer_spec_idx(struct vdec_h264_hw_s *hw, unsigned int v4l_indx) -{ - int i; - - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_wrap[i] == v4l_indx) - return i; - } - return -1; -} - -static int v4l_get_free_buf_idx(struct vdec_s *vdec) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx * v4l = hw->v4l2_ctx; - struct v4l_buff_pool *pool = &v4l->cap_pool; - struct buffer_spec_s *pic = NULL; - int i, rt, idx = INVALID_IDX; - ulong flags; - u32 state = 0, index; - - spin_lock_irqsave(&hw->bufspec_lock, flags); - for (i = 0; i < pool->in; ++i) { - state = (pool->seq[i] >> 16); - index = (pool->seq[i] & 0xffff); - - switch (state) { - case V4L_CAP_BUFF_IN_DEC: - rt = v4l_find_buffer_spec_idx(hw, index); - if (rt >= 0) { - pic = &hw->buffer_spec[rt]; - if ((pic->vf_ref == 0) && - (pic->used == 0) && - pic->cma_alloc_addr) { - idx = rt; - } - } - break; - case V4L_CAP_BUFF_IN_M2M: - rt = v4l_get_free_buffer_spec(hw); - if (rt >= 0) { - pic = &hw->buffer_spec[rt]; - if (!alloc_one_buf_spec_from_queue(hw, rt)) { - struct vdec_v4l2_buffer *fb; - config_decode_canvas(hw, rt); - fb = (struct vdec_v4l2_buffer *)pic->cma_alloc_addr; - hw->buffer_wrap[rt] = fb->buf_idx; - idx = rt; - } - } - break; - default: - break; - } - - if (idx != INVALID_IDX) { - pic->used = 1; - break; - } - } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - - if (idx < 0) { - dpb_print(DECODE_ID(hw), 0, "%s fail, state %d\n", __func__, state); - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - dpb_print(DECODE_ID(hw), 0, "%s, %d\n", - __func__, hw->buffer_wrap[i]); - } - vmh264_dump_state(vdec); - } else { - struct vdec_v4l2_buffer *fb = - (struct vdec_v4l2_buffer *)pic->cma_alloc_addr; - - fb->status = FB_ST_DECODER; - - v4l->aux_infos.bind_sei_buffer(v4l, &pic->aux_data_buf, - &pic->aux_data_size, &pic->ctx_buf_idx); - } - - return idx; -} - -int get_free_buf_idx(struct vdec_s *vdec) -{ - int i; - unsigned long addr, flags; - int index = -1; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int buf_total = BUFSPEC_POOL_SIZE; - - if (hw->is_used_v4l) - return v4l_get_free_buf_idx(vdec); - - spin_lock_irqsave(&hw->bufspec_lock, flags); - /*hw->start_search_pos = 0;*/ - for (i = hw->start_search_pos; i < buf_total; i++) { - if (hw->mmu_enable) - addr = hw->buffer_spec[i].alloc_header_addr; - else - addr = hw->buffer_spec[i].cma_alloc_addr; - - if (hw->buffer_spec[i].vf_ref == 0 && - hw->buffer_spec[i].used == 0 && addr) { - hw->buffer_spec[i].used = 1; - hw->start_search_pos = i+1; - index = i; - hw->buffer_wrap[i] = index; - break; - } - } - if (index < 0) { - for (i = 0; i < hw->start_search_pos; i++) { - if (hw->mmu_enable) - addr = hw->buffer_spec[i].alloc_header_addr; - else - addr = hw->buffer_spec[i].cma_alloc_addr; - - if (hw->buffer_spec[i].vf_ref == 0 && - hw->buffer_spec[i].used == 0 && addr) { - hw->buffer_spec[i].used = 1; - hw->start_search_pos = i+1; - index = i; - hw->buffer_wrap[i] = index; - break; - } - } - } - - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - if (hw->start_search_pos >= buf_total) - hw->start_search_pos = 0; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s, buf_spec_num %d\n", __func__, index); - - if (index < 0) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "%s fail\n", __func__); - vmh264_dump_state(vdec); - } - - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - return index; -} - -int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num) -{ - /*u32 cur_buf_idx;*/ - unsigned long flags; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL, - "%s buf_spec_num %d used %d\n", - __func__, buf_spec_num, - buf_spec_num > 0 ? hw->buffer_spec[buf_spec_num].used : 0); - if (buf_spec_num >= 0 && - buf_spec_num < BUFSPEC_POOL_SIZE - ) { - spin_lock_irqsave(&hw->bufspec_lock, flags); - hw->buffer_spec[buf_spec_num].used = 0; - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - if (hw->mmu_enable) { - /*WRITE_VREG(CURR_CANVAS_CTRL, buf_spec_num<<24); - cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL); - cur_buf_idx = cur_buf_idx&0xff;*/ - decoder_mmu_box_free_idx(hw->mmu_box, buf_spec_num); - } - release_aux_data(hw, buf_spec_num); - } - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - return 0; -} - -static void config_buf_specs(struct vdec_s *vdec) -{ - int i, j; - unsigned long flags; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int mode = IS_VDEC_DW(hw) ? 2 : 1; - - spin_lock_irqsave(&hw->bufspec_lock, flags); - for (i = 0, j = 0; - j < hw->dpb.mDPB.size - && i < BUFSPEC_POOL_SIZE; - i++) { - int canvas; - if (hw->buffer_spec[i].used != -1) - continue; - if (vdec->parallel_dec == 1) { - if (hw->buffer_spec[i].y_canvas_index == -1) - hw->buffer_spec[i].y_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - if (hw->buffer_spec[i].u_canvas_index == -1) { - hw->buffer_spec[i].u_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->buffer_spec[i].v_canvas_index = hw->buffer_spec[i].u_canvas_index; - } -#ifdef VDEC_DW - if (IS_VDEC_DW(hw)) { - if (hw->buffer_spec[i].vdec_dw_y_canvas_index == -1) - hw->buffer_spec[i].vdec_dw_y_canvas_index = - vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - if (hw->buffer_spec[i].vdec_dw_u_canvas_index == -1) { - hw->buffer_spec[i].vdec_dw_u_canvas_index = - vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->buffer_spec[i].vdec_dw_v_canvas_index = - hw->buffer_spec[i].vdec_dw_u_canvas_index; - } - } -#endif - } else { - canvas = vdec->get_canvas(j * mode, 2); - hw->buffer_spec[i].y_canvas_index = canvas_y(canvas); - hw->buffer_spec[i].u_canvas_index = canvas_u(canvas); - hw->buffer_spec[i].v_canvas_index = canvas_v(canvas); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DPB_DETAIL, - "config canvas (%d) %x for bufspec %d\r\n", - j, canvas, i); -#ifdef VDEC_DW - if (IS_VDEC_DW(hw)) { - canvas = vdec->get_canvas(j * mode + 1, 2); - hw->buffer_spec[i].vdec_dw_y_canvas_index = canvas_y(canvas); - hw->buffer_spec[i].vdec_dw_u_canvas_index = canvas_u(canvas); - hw->buffer_spec[i].vdec_dw_v_canvas_index = canvas_v(canvas); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DPB_DETAIL, - "vdec_dw: config canvas (%d) %x for bufspec %d\r\n", - j, canvas, i); - } -#endif - } - - hw->buffer_spec[i].used = 0; - hw->buffer_spec[i].canvas_pos = j; - - - j++; - } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); -} - -static void config_buf_specs_ex(struct vdec_s *vdec) -{ - int i, j; - unsigned long flags; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int mode = IS_VDEC_DW(hw) ? 2 : 1; - - spin_lock_irqsave(&hw->bufspec_lock, flags); - for (i = 0, j = 0; - j < hw->dpb.mDPB.size - && i < BUFSPEC_POOL_SIZE; - i++) { - int canvas = 0; - if (hw->buffer_spec[i].used != -1) - continue; - if (vdec->parallel_dec == 1) { - if (hw->buffer_spec[i].y_canvas_index == -1) - hw->buffer_spec[i].y_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - if (hw->buffer_spec[i].u_canvas_index == -1) { - hw->buffer_spec[i].u_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->buffer_spec[i].v_canvas_index = hw->buffer_spec[i].u_canvas_index; - } -#ifdef VDEC_DW - if (IS_VDEC_DW(hw)) { - if (hw->buffer_spec[i].vdec_dw_y_canvas_index == -1) - hw->buffer_spec[i].vdec_dw_y_canvas_index = - vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - if (hw->buffer_spec[i].vdec_dw_u_canvas_index == -1) { - hw->buffer_spec[i].vdec_dw_u_canvas_index = - vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); - hw->buffer_spec[i].vdec_dw_v_canvas_index = - hw->buffer_spec[i].vdec_dw_u_canvas_index; - } - } -#endif - } else { - canvas = vdec->get_canvas(j* mode, 2); - hw->buffer_spec[i].y_canvas_index = canvas_y(canvas); - hw->buffer_spec[i].u_canvas_index = canvas_u(canvas); - hw->buffer_spec[i].v_canvas_index = canvas_v(canvas); - - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DPB_DETAIL, - "config canvas (%d) %x for bufspec %d\r\n", - j, canvas, i); -#ifdef VDEC_DW - if (IS_VDEC_DW(hw)) { - canvas = vdec->get_canvas(j*mode + 1, 2); - hw->buffer_spec[i].vdec_dw_y_canvas_index = canvas_y(canvas); - hw->buffer_spec[i].vdec_dw_u_canvas_index = canvas_u(canvas); - hw->buffer_spec[i].vdec_dw_v_canvas_index = canvas_v(canvas); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DPB_DETAIL, - "vdec_dw: config canvas (%d) %x for bufspec %d\r\n", - j, canvas, i); - } -#endif - } - - hw->buffer_spec[i].used = 0; - hw->buffer_spec[i].alloc_header_addr = 0; - hw->buffer_spec[i].canvas_pos = j; - - j++; - } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); -} - - -static void dealloc_buf_specs(struct vdec_h264_hw_s *hw, - unsigned char release_all) -{ - int i; - unsigned long flags; - unsigned char dealloc_flag = 0; - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].used == 4 || - release_all) { - dealloc_flag = 1; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DPB_DETAIL, - "%s buf_spec_num %d\n", - __func__, i - ); - spin_lock_irqsave - (&hw->bufspec_lock, flags); - hw->buffer_spec[i].used = -1; - spin_unlock_irqrestore - (&hw->bufspec_lock, flags); - release_aux_data(hw, i); - - if (!hw->mmu_enable) { - if (hw->buffer_spec[i].cma_alloc_addr) { - if (!hw->is_used_v4l) { - decoder_bmmu_box_free_idx( - hw->bmmu_box, - i); - } - spin_lock_irqsave - (&hw->bufspec_lock, flags); - hw->buffer_spec[i].cma_alloc_addr = 0; - hw->buffer_spec[i].buf_adr = 0; - spin_unlock_irqrestore - (&hw->bufspec_lock, flags); - } - } else { - if (hw->buffer_spec[i].alloc_header_addr) { - decoder_mmu_box_free_idx( - hw->mmu_box, - i); - spin_lock_irqsave - (&hw->bufspec_lock, flags); - hw->buffer_spec[i]. - alloc_header_addr = 0; - hw->buffer_spec[i].buf_adr = 0; - spin_unlock_irqrestore - (&hw->bufspec_lock, flags); - } - } - } - } - if (dealloc_flag && - dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - return; -} - -unsigned char have_free_buf_spec(struct vdec_s *vdec) -{ - int i; - unsigned long addr; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx * ctx = hw->v4l2_ctx; - int canvas_pos_min = BUFSPEC_POOL_SIZE; - int index = -1; - int ret = 0; - int allocated_count = 0; - - if (hw->is_used_v4l) { - struct h264_dpb_stru *dpb = &hw->dpb; - int free_count = 0; - int used_count = 0; - - /* trigger to parse head data. */ - if (!hw->v4l_params_parsed) - return 1; - - if (dpb->mDPB.used_size >= dpb->mDPB.size - 1) - return 0; - - if (ctx->cap_pool.dec < hw->dpb.mDPB.size) { - if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) { - free_count = - v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1; - } - } - - for (i = 0; i < hw->dpb.mDPB.size; i++) { - if (hw->buffer_spec[i].used == 0 && - hw->buffer_spec[i].vf_ref == 0 && - hw->buffer_spec[i].cma_alloc_addr) { - free_count++; - } else if (hw->buffer_spec[i].cma_alloc_addr) - used_count++; - } - - ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count); - ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count); - - return free_count >= run_ready_min_buf_num ? 1 : 0; - } - - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->mmu_enable) - addr = hw->buffer_spec[i].alloc_header_addr; - else - addr = hw->buffer_spec[i].cma_alloc_addr; - if (hw->buffer_spec[i].used == 0 && - hw->buffer_spec[i].vf_ref == 0) { - - if (addr) - return 1; - if (hw->buffer_spec[i].canvas_pos < canvas_pos_min) { - canvas_pos_min = hw->buffer_spec[i].canvas_pos; - index = i; - } - } - if (addr) - allocated_count++; - } - if (index >= 0) { - mutex_lock(&vmh264_mutex); - dealloc_buf_specs(hw, 0); - if (max_alloc_buf_count == 0 || - allocated_count < max_alloc_buf_count) { - if (alloc_one_buf_spec(hw, index) >= 0) - ret = 1; - } - mutex_unlock(&vmh264_mutex); - } - - return ret; -} - -static int get_buf_spec_by_canvas_pos(struct vdec_h264_hw_s *hw, - int canvas_pos) -{ - int i; - int j = 0; - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].canvas_pos >= 0) { - if (j == canvas_pos) - return i; - j++; - } - } - return -1; -} -static void update_vf_memhandle(struct vdec_h264_hw_s *hw, - struct vframe_s *vf, int index) -{ - if (index < 0) { - vf->mem_handle = NULL; - vf->mem_head_handle = NULL; - } else if (vf->type & VIDTYPE_SCATTER) { - vf->mem_handle = - decoder_mmu_box_get_mem_handle( - hw->mmu_box, index); - vf->mem_head_handle = - decoder_bmmu_box_get_mem_handle( - hw->bmmu_box, HEADER_BUFFER_IDX(index)); - } else { - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - hw->bmmu_box, VF_BUFFER_IDX(index)); - /* vf->mem_head_handle = - decoder_bmmu_box_get_mem_handle( - hw->bmmu_box, HEADER_BUFFER_IDX(index));*/ - } - return; -} -static int check_force_interlace(struct vdec_h264_hw_s *hw, - struct FrameStore *frame) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int bForceInterlace = 0; - /* no di in secure mode, disable force di */ - if (vdec_secure(hw_to_vdec(hw))) - return 0; - - if (hw->is_used_v4l) - return 0; - - if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE) - && hw->bitstream_restriction_flag - && (hw->frame_width == 1920) - && (hw->frame_height >= 1080) /* For being compatible with a fake progressive stream which is interlaced actually*/ - && (hw->frame_dur == 3203 || (hw->frame_dur == 3840 && p_H264_Dpb->mSPS.profile_idc == 100 && - p_H264_Dpb->mSPS.level_idc == 40))) { - bForceInterlace = 1; - } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE) - && (hw->frame_width == 720) - && (hw->frame_height == 576) - && (hw->frame_dur == 3840)) { - bForceInterlace = 1; - } - if (hw->is_used_v4l && (bForceInterlace == 0) && frame->frame) { - bForceInterlace = (frame->frame->mb_aff_frame_flag)?1:0; - } - return bForceInterlace; -} - -static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame) -{ - struct vframe_qos_s *vframe_qos = &hw->vframe_qos; - - if (frame->slice_type == I_SLICE) - vframe_qos->type = 1; - else if (frame->slice_type == P_SLICE) - vframe_qos->type = 2; - else if (frame->slice_type == B_SLICE) - vframe_qos->type = 3; - - if (input_frame_based(hw_to_vdec(hw))) - vframe_qos->size = frame->frame_size2; - else - vframe_qos->size = frame->frame_size; - vframe_qos->pts = frame->pts64; - - vframe_qos->max_mv = frame->max_mv; - vframe_qos->avg_mv = frame->avg_mv; - vframe_qos->min_mv = frame->min_mv; -/* - pr_info("mv: max:%d, avg:%d, min:%d\n", - vframe_qos->max_mv, - vframe_qos->avg_mv, - vframe_qos->min_mv); -*/ - - vframe_qos->max_qp = frame->max_qp; - vframe_qos->avg_qp = frame->avg_qp; - vframe_qos->min_qp = frame->min_qp; -/* - pr_info("qp: max:%d, avg:%d, min:%d\n", - vframe_qos->max_qp, - vframe_qos->avg_qp, - vframe_qos->min_qp); -*/ - - vframe_qos->max_skip = frame->max_skip; - vframe_qos->avg_skip = frame->avg_skip; - vframe_qos->min_skip = frame->min_skip; -/* - pr_info("skip: max:%d, avg:%d, min:%d\n", - vframe_qos->max_skip, - vframe_qos->avg_skip, - vframe_qos->min_skip); -*/ - vframe_qos->num++; -} - -static int is_iframe(struct FrameStore *frame) { - - if (frame->frame && frame->frame->slice_type == I_SLICE) { - return 1; - } - return 0; -} - -static int post_prepare_process(struct vdec_s *vdec, struct FrameStore *frame) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int buffer_index = frame->buf_spec_num; - - if (buffer_index < 0 || buffer_index >= BUFSPEC_POOL_SIZE) { - dpb_print(DECODE_ID(hw), 0, - "%s, buffer_index 0x%x is beyond range\n", - __func__, buffer_index); - return -1; - } - - if (force_disp_bufspec_num & 0x100) { - /*recycle directly*/ - if (hw->buffer_spec[frame->buf_spec_num].used != 3 && - hw->buffer_spec[frame->buf_spec_num].used != 5) - set_frame_output_flag(&hw->dpb, frame->index); - - /*make pre_output not set*/ - return -1; - } - if (hw->error_proc_policy & 0x1000) { - int error_skip_i_count = (error_skip_count >> 12) & 0xf; - int error_skip_frame_count = error_skip_count & 0xfff; - if (((hw->no_error_count < error_skip_frame_count) - && (error_skip_i_count == 0 || - hw->no_error_i_count < error_skip_i_count)) - && (!(frame->data_flag & I_FLAG))) - frame->data_flag |= ERROR_FLAG; - } - - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "%s, buffer_index 0x%x frame_error %x poc %d hw error %x hw error_proc_policy %x\n", - __func__, buffer_index, - frame->data_flag & ERROR_FLAG, - frame->poc, hw->data_flag & ERROR_FLAG, - hw->error_proc_policy); - - if (frame->frame == NULL && - ((frame->is_used == 1 && frame->top_field) - || (frame->is_used == 2 && frame->bottom_field))) { - if (hw->i_only) { - if (frame->is_used == 1) - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s No bottom_field !! frame_num %d used %d\n", - __func__, frame->frame_num, frame->is_used); - if (frame->is_used == 2) - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s No top_field !! frame_num %d used %d\n", - __func__, frame->frame_num, frame->is_used); - } - else { - frame->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "%s Error frame_num %d used %d\n", - __func__, frame->frame_num, frame->is_used); - } - } - if (vdec_stream_based(vdec) && !(frame->data_flag & NODISP_FLAG)) { - if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) { - if ((pts_lookup_offset_us64(PTS_TYPE_VIDEO, - frame->offset_delimiter, &frame->pts, &frame->frame_size, - 0, &frame->pts64) == 0)) { - if ((lookup_check_conut && (atomic_read(&hw->vf_pre_count) > lookup_check_conut) && - (hw->wrong_frame_count > hw->right_frame_count)) && - ((frame->decoded_frame_size * 2 < frame->frame_size))) { - /*resolve many frame only one check in pts, cause playback unsmooth issue*/ - frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ; - frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur); - } - hw->right_frame_count++; - } else { - frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ; - frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur); - hw->wrong_frame_count++; - } - } - - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s error= 0x%x poc = %d offset= 0x%x pts= 0x%x last_pts =0x%x pts64 = %lld last_pts64= %lld duration = %d\n", - __func__, (frame->data_flag & ERROR_FLAG), frame->poc, - frame->offset_delimiter, frame->pts,hw->last_pts, - frame->pts64, hw->last_pts64, hw->frame_dur); - hw->last_pts64 = frame->pts64; - hw->last_pts = frame->pts; - } - - /* SWPL-18973 96000/15=6400, less than 15fps check */ - if ((!hw->duration_from_pts_done) && (hw->frame_dur > 6400ULL)) { - if ((check_force_interlace(hw, frame)) && - (frame->slice_type == I_SLICE) && - (hw->pts_outside)) { - if ((!hw->h264_pts_count) || (!hw->h264pts1)) { - hw->h264pts1 = frame->pts; - hw->h264_pts_count = 0; - } else if (frame->pts > hw->h264pts1) { - u32 calc_dur = - PTS2DUR(frame->pts - hw->h264pts1); - calc_dur = ((calc_dur/hw->h264_pts_count) << 1); - if (hw->frame_dur < (calc_dur + 200) && - hw->frame_dur > (calc_dur - 200)) { - hw->frame_dur >>= 1; - vdec_schedule_work(&hw->notify_work); - dpb_print(DECODE_ID(hw), 0, - "correct frame_dur %d, calc_dur %d, count %d\n", - hw->frame_dur, (calc_dur >> 1), hw->h264_pts_count); - hw->duration_from_pts_done = 1; - hw->h264_pts_count = 0; - } - } - } - hw->h264_pts_count++; - } - - if (frame->data_flag & ERROR_FLAG) { - vdec_count_info(&hw->gvs, 1, 0); - if (frame->slice_type == I_SLICE) { - hw->gvs.i_concealed_frames++; - } else if (frame->slice_type == P_SLICE) { - hw->gvs.p_concealed_frames++; - } else if (frame->slice_type == B_SLICE) { - hw->gvs.b_concealed_frames++; - } - if (!hw->send_error_frame_flag) { - hw->gvs.drop_frame_count++; - if (frame->slice_type == I_SLICE) { - hw->gvs.i_lost_frames++; - } else if (frame->slice_type == P_SLICE) { - hw->gvs.p_lost_frames++; - } else if (frame->slice_type == B_SLICE) { - hw->gvs.b_lost_frames++; - } - } - - } - - if ((!hw->enable_fence) && - ((frame->data_flag & NODISP_FLAG) || - (frame->data_flag & NULL_FLAG) || - ((!hw->send_error_frame_flag) && - (frame->data_flag & ERROR_FLAG)) || - ((hw->i_only & 0x1) && - (!(frame->data_flag & I_FLAG))))) { - frame->show_frame = false; - return 0; - } - - if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL)) { - dpb_print(DECODE_ID(hw), 0, - "%s, fs[%d] poc %d, buf_spec_num %d\n", - __func__, frame->index, frame->poc, - frame->buf_spec_num); - print_pic_info(DECODE_ID(hw), "predis_frm", - frame->frame, -1); - print_pic_info(DECODE_ID(hw), "predis_top", - frame->top_field, -1); - print_pic_info(DECODE_ID(hw), "predis_bot", - frame->bottom_field, -1); - } - - frame->show_frame = true; - - return 0; -} - -static int post_video_frame(struct vdec_s *vdec, struct FrameStore *frame) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct vframe_s *vf = NULL; - int buffer_index = frame->buf_spec_num; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - struct vdec_v4l2_buffer *fb = NULL; - ulong nv_order = VIDTYPE_VIU_NV21; - int bForceInterlace = 0; - int vf_count = 1; - int i; - - /* swap uv */ - if (hw->is_used_v4l) { - if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || - (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) - nv_order = VIDTYPE_VIU_NV12; - } - - if (!is_interlace(frame)) - vf_count = 1; - else - vf_count = 2; - - bForceInterlace = check_force_interlace(hw, frame); - if (bForceInterlace) - vf_count = 2; - - if (!hw->enable_fence) - hw->buffer_spec[buffer_index].vf_ref = 0; - fill_frame_info(hw, frame); - - if ((hw->is_used_v4l) && - ((vdec->prog_only) || (!v4l2_ctx->vpp_is_need))) - vf_count = 1; - - for (i = 0; i < vf_count; i++) { - if (kfifo_get(&hw->newframe_q, &vf) == 0 || - vf == NULL) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "%s fatal error, no available buffer slot.\n", - __func__); - return -1; - } - vf->duration_pulldown = 0; - if (!(is_iframe(frame)) && hw->unstable_pts) { - vf->pts = 0; - vf->pts_us64 = 0; - vf->timestamp = 0; - vf->index = VF_INDEX(frame->index, buffer_index); - } else { - if ((i == 0) && (vf_count == 2)) - vf->timestamp = frame->last_field_timestamp; - else - vf->timestamp = frame->timestamp; - vf->pts = frame->pts; - vf->pts_us64 = frame->pts64; - if ((i > 0) && v4l2_ctx->second_field_pts_mode) { - vf->timestamp = 0; - } - vf->index = VF_INDEX(frame->index, buffer_index); - } - - if (hw->is_used_v4l) { - vf->v4l_mem_handle - = hw->buffer_spec[buffer_index].cma_alloc_addr; - fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle; - } - - if (hw->enable_fence) { - /* fill fence information. */ - if (hw->fence_usage == FENCE_USE_FOR_DRIVER) - vf->fence = frame->fence; - } - - if (hw->mmu_enable) { - if (hw->double_write_mode & 0x10) { - /* double write only */ - vf->compBodyAddr = 0; - vf->compHeadAddr = 0; - } else { - /*head adr*/ - vf->compHeadAddr = - hw->buffer_spec[buffer_index].alloc_header_addr; - /*body adr*/ - vf->compBodyAddr = 0; - vf->canvas0Addr = vf->canvas1Addr = 0; - } - - vf->type = VIDTYPE_SCATTER; - - if (hw->double_write_mode) { - vf->type |= VIDTYPE_PROGRESSIVE - | VIDTYPE_VIU_FIELD; - vf->type |= nv_order; - if (hw->double_write_mode == 3) - vf->type |= VIDTYPE_COMPRESS; - - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->plane_num = 2; - vf->canvas0_config[0] = - hw->buffer_spec[buffer_index]. - canvas_config[0]; - vf->canvas0_config[1] = - hw->buffer_spec[buffer_index]. - canvas_config[1]; - - vf->canvas1_config[0] = - hw->buffer_spec[buffer_index]. - canvas_config[0]; - vf->canvas1_config[1] = - hw->buffer_spec[buffer_index]. - canvas_config[1]; - - } else { - vf->type |= - VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; - vf->canvas0Addr = vf->canvas1Addr = 0; - } - - vf->bitdepth = - BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; - - vf->compWidth = hw->frame_width; - vf->compHeight = hw->frame_height; - } else { - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - nv_order; - - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&hw->buffer_spec[buffer_index]); -#ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw)) - vf->canvas0Addr = vf->canvas1Addr = - vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]); - } else { - if (IS_VDEC_DW(hw)) - vf->canvas0Addr = vf->canvas1Addr = -1; - } -#endif - - } - if (frame->data_flag & ERROR_FLAG) { - vf->frame_type |= V4L2_BUF_FLAG_ERROR; - } - - set_frame_info(hw, vf, buffer_index); - if (hw->discard_dv_data) { - vf->discard_dv_data = true; - } - - if (hw->mmu_enable && hw->double_write_mode) { - vf->width = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); - vf->height = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); - } - - if (frame->slice_type == I_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME; - } else if (frame->slice_type == P_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_PFRAME; - } else if (frame->slice_type == B_SLICE) { - vf->frame_type |= V4L2_BUF_FLAG_BFRAME; - } - - vf->flag = 0; - if (frame->data_flag & I_FLAG) - vf->flag |= VFRAME_FLAG_SYNCFRAME; - if (frame->data_flag & ERROR_FLAG) - vf->flag |= VFRAME_FLAG_ERROR_RECOVERY; - update_vf_memhandle(hw, vf, buffer_index); - - if (!hw->enable_fence) { - hw->buffer_spec[buffer_index].used = 2; - hw->buffer_spec[buffer_index].vf_ref++; - } - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s %d frame = %p top_field = %p bottom_field = %p\n", __func__, __LINE__, frame->frame, - frame->top_field, frame->bottom_field); - - if (frame->frame != NULL) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s %d coded_frame = %d frame_mbs_only_flag = %d structure = %d\n", __func__, __LINE__, - frame->frame->coded_frame, frame->frame->frame_mbs_only_flag, frame->frame->structure); - } - - if (bForceInterlace || is_interlace(frame)) { - vf->type = - VIDTYPE_INTERLACE_FIRST | - nv_order; - - if (frame->frame != NULL && - (frame->frame->pic_struct == PIC_TOP_BOT || - frame->frame->pic_struct == PIC_BOT_TOP) && - frame->frame->coded_frame) { - if (frame->frame != NULL && frame->frame->pic_struct == PIC_TOP_BOT) { - vf->type |= (i == 0 ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM); - } else if (frame->frame != NULL && frame->frame->pic_struct == PIC_BOT_TOP) { - vf->type |= (i == 0 ? - VIDTYPE_INTERLACE_BOTTOM : - VIDTYPE_INTERLACE_TOP); - } - } else if (frame->top_field != NULL && frame->bottom_field != NULL) {/*top first*/ - if (frame->top_field->poc <= frame->bottom_field->poc) - vf->type |= (i == 0 ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM); - else - vf->type |= (i == 0 ? - VIDTYPE_INTERLACE_BOTTOM : - VIDTYPE_INTERLACE_TOP); - } else { - vf->type |= (i == 0 ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM); - } - vf->duration = vf->duration/2; - if (i == 1) { - vf->pts = 0; - vf->pts_us64 = 0; - } - - if (frame->frame) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s %d type = 0x%x pic_struct = %d pts = 0x%x pts_us64 = 0x%llx bForceInterlace = %d\n", - __func__, __LINE__, vf->type, frame->frame->pic_struct, - vf->pts, vf->pts_us64, bForceInterlace); - } - } - - if (hw->i_only) { - if (vf_count == 1 && frame->is_used == 1 && frame->top_field - && frame->bottom_field == NULL && frame->frame == NULL) { - vf->type = - VIDTYPE_INTERLACE_FIRST | - nv_order; - vf->type |= VIDTYPE_INTERLACE_TOP; - vf->duration = vf->duration/2; - } - - if (vf_count == 1 && frame->is_used == 2 && frame->bottom_field - && frame->top_field == NULL && frame->frame == NULL) { - vf->type = - VIDTYPE_INTERLACE_FIRST | - nv_order; - vf->type |= VIDTYPE_INTERLACE_BOTTOM; - vf->duration = vf->duration/2; - } - } - - /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/ - vf->sar_width = hw->width_aspect_ratio; - vf->sar_height = hw->height_aspect_ratio; - if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) { - /* offset for tsplayer pts lookup */ - if (i == 0) { - vf->pts_us64 = - (((u64)vf->duration << 32) & - 0xffffffff00000000) | frame->offset_delimiter; - vf->pts = 0; - } else { - vf->pts_us64 = (u64)-1; - vf->pts = 0; - } - } - atomic_add(1, &hw->vf_pre_count); - vdec_vframe_ready(hw_to_vdec(hw), vf); - if (!frame->show_frame) { - vh264_vf_put(vf, vdec); - atomic_add(1, &hw->vf_get_count); - continue; - } - - if (i == 0) { - struct vdec_s *pvdec; - struct vdec_info vs; - - pvdec = hw_to_vdec(hw); - memset(&vs, 0, sizeof(struct vdec_info)); - pvdec->dec_status(pvdec, &vs); - decoder_do_frame_check(pvdec, vf); - vdec_fill_vdec_frame(pvdec, &hw->vframe_qos, &vs, vf, frame->hw_decode_time); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "[%s:%d] i_decoded_frame = %d p_decoded_frame = %d b_decoded_frame = %d\n", - __func__, __LINE__,vs.i_decoded_frames,vs.p_decoded_frames,vs.b_decoded_frames); - } - - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.pts_name, vf->timestamp); - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); - vdec->vdec_fps_detec(vdec->id); -#ifdef AUX_DATA_CRC - decoder_do_aux_data_check(vdec, hw->buffer_spec[buffer_index].aux_data_buf, - hw->buffer_spec[buffer_index].aux_data_size); -#endif - - dpb_print(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL, "aux_data_size: %d, signal_type: 0x%x\n", - hw->buffer_spec[buffer_index].aux_data_size, hw->video_signal_type); - - if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL)) { - int i = 0; - PR_INIT(128); - - for (i = 0; i < hw->buffer_spec[buffer_index].aux_data_size; i++) { - PR_FILL("%02x ", hw->buffer_spec[buffer_index].aux_data_buf[i]); - if (((i + 1) & 0xf) == 0) - PR_INFO(hw->id); - } - PR_INFO(hw->id); - } - - if (hw->is_used_v4l) { - if ((hw->buffer_spec[buffer_index].aux_data_size == 0) && - (frame->slice_type == I_SLICE) && - (atomic_read(&hw->vf_pre_count) == 1)) { - hw->need_free_aux_data = true; - } - - if (hw->need_free_aux_data) { - v4l2_ctx->aux_infos.free_one_sei_buffer(v4l2_ctx, - &hw->buffer_spec[buffer_index].aux_data_buf, - &hw->buffer_spec[buffer_index].aux_data_size, - hw->buffer_spec[buffer_index].ctx_buf_idx); - } else { - if (!hw->discard_dv_data) - v4l2_ctx->aux_infos.bind_dv_buffer(v4l2_ctx, - &vf->src_fmt.comp_buf, - &vf->src_fmt.md_buf); - update_vframe_src_fmt(vf, - hw->buffer_spec[buffer_index].aux_data_buf, - hw->buffer_spec[buffer_index].aux_data_size, - false, vdec->vf_provider_name, NULL); - } - } - - if (without_display_mode == 0) { - if (hw->is_used_v4l) { - if (v4l2_ctx->is_stream_off) { - vh264_vf_put(vh264_vf_get(vdec), vdec); - } else { - set_meta_data_to_vf(vf, UVM_META_DATA_VF_BASE_INFOS, hw->v4l2_ctx); - ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx); - fb->task->submit(fb->task, TASK_TYPE_DEC); - } - } else - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } else - vh264_vf_put(vh264_vf_get(vdec), vdec); - } - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - - return 0; -} - -int post_picture_early(struct vdec_s *vdec, int index) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct h264_dpb_stru *dpb_stru = &hw->dpb; - struct FrameStore fs; - u32 offset_lo, offset_hi; - - if (!hw->enable_fence) - return 0; - - /* create fence for each buffers. */ - if (vdec_timeline_create_fence(vdec->sync)) - return -1; - - memset(&fs, 0, sizeof(fs)); - - fs.buf_spec_num = index; - fs.fence = vdec->sync->fence; - fs.slice_type = dpb_stru->mSlice.slice_type; - fs.dpb_frame_count = dpb_stru->dpb_frame_count; - - offset_lo = dpb_stru->dpb_param.l.data[OFFSET_DELIMITER_LO]; - offset_hi = dpb_stru->dpb_param.l.data[OFFSET_DELIMITER_HI]; - fs.offset_delimiter = (offset_lo | offset_hi << 16); - - if (hw->chunk) { - fs.pts = hw->chunk->pts; - fs.pts64 = hw->chunk->pts64; - fs.timestamp = hw->chunk->timestamp; - } - fs.show_frame = true; - post_video_frame(vdec, &fs); - - display_frame_count[DECODE_ID(hw)]++; - return 0; -} - -int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame) -{ - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *)vdec->private; - - if (hw->enable_fence) { - int i, j, used_size, ret; - int signed_count = 0; - struct vframe_s *signed_fence[VF_POOL_SIZE]; - - post_prepare_process(vdec, frame); - - if (!frame->show_frame) - pr_info("do not display.\n"); - - hw->buffer_spec[frame->buf_spec_num].used = 2; - hw->buffer_spec[frame->buf_spec_num].vf_ref = 1; - hw->buffer_spec[frame->buf_spec_num].fs_idx = frame->index; - - /* notify signal to wake up wq of fence. */ - vdec_timeline_increase(vdec->sync, 1); - - mutex_lock(&hw->fence_mutex); - used_size = hw->fence_vf_s.used_size; - if (used_size) { - for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) { - if (hw->fence_vf_s.fence_vf[i] != NULL) { - ret = dma_fence_get_status(hw->fence_vf_s.fence_vf[i]->fence); - if (ret == 1) { - signed_fence[signed_count] = hw->fence_vf_s.fence_vf[i]; - hw->fence_vf_s.fence_vf[i] = NULL; - hw->fence_vf_s.used_size--; - signed_count++; - } - j++; - } - } - } - mutex_unlock(&hw->fence_mutex); - if (signed_count != 0) { - for (i = 0; i < signed_count; i++) - vh264_vf_put(signed_fence[i], vdec); - } - - return 0; - } - - if (post_prepare_process(vdec, frame)) - return -1; - - if (post_video_frame(vdec, frame)) - return -1; - - display_frame_count[DECODE_ID(hw)]++; - return 0; -} - -int notify_v4l_eos(struct vdec_s *vdec) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - struct vframe_s *vf = &hw->vframe_dummy; - struct vdec_v4l2_buffer *fb = NULL; - int index = INVALID_IDX; - ulong expires; - - if (hw->eos) { - expires = jiffies + msecs_to_jiffies(2000); - while (!have_free_buf_spec(vdec)) { - if (time_after(jiffies, expires)) { - pr_err("[%d] H264 isn't enough buff for notify eos.\n", ctx->id); - return 0; - } - } - - index = v4l_get_free_buf_idx(vdec); - if (INVALID_IDX == index) { - pr_err("[%d] H264 EOS get free buff fail.\n", ctx->id); - return 0; - } - - fb = (struct vdec_v4l2_buffer *) - hw->buffer_spec[index].cma_alloc_addr; - - vf->type |= VIDTYPE_V4L_EOS; - vf->timestamp = ULONG_MAX; - vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L; - vf->v4l_mem_handle = (ulong)fb; - - vdec_vframe_ready(vdec, vf); - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - ATRACE_COUNTER(hw->trace.pts_name, vf->timestamp); - - ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx); - fb->task->submit(fb->task, TASK_TYPE_DEC); - - pr_info("[%d] H264 EOS notify.\n", ctx->id); - } - - return 0; -} - -/****************** - * Hardware config - */ -char *slice_type_name[] = { - "P_SLICE ", - "B_SLICE ", - "I_SLICE ", - "SP_SLICE", - "SI_SLICE", -}; - -char *picture_structure_name[] = { - "FRAME", - "TOP_FIELD", - "BOTTOM_FIELD" -}; - -void print_pic_info(int decindex, const char *info, - struct StorablePicture *pic, - int slice_type) -{ - if (pic) - dpb_print(decindex, PRINT_FLAG_DEC_DETAIL, - "%s: %s (original %s), %s, mb_aff_frame_flag %d poc %d, pic_num %d, buf_spec_num %d data_flag 0x%x\n", - info, - picture_structure_name[pic->structure], - pic->coded_frame ? "Frame" : "Field", - (slice_type < 0 || - slice_type >= (sizeof(slice_type_name) / sizeof(slice_type_name[0]))) ? "" : slice_type_name[slice_type], - pic->mb_aff_frame_flag, - pic->poc, - pic->pic_num, - pic->buf_spec_num, - pic->data_flag); -} - -static void reset_process_time(struct vdec_h264_hw_s *hw) -{ - if (hw->start_process_time) { - unsigned process_time = - 1000 * (jiffies - hw->start_process_time) / HZ; - hw->start_process_time = 0; - if (process_time > max_process_time[DECODE_ID(hw)]) - max_process_time[DECODE_ID(hw)] = process_time; - } -} - -static void start_process_time(struct vdec_h264_hw_s *hw) -{ - hw->decode_timeout_count = 10; - hw->start_process_time = jiffies; -} - -static void config_aux_buf(struct vdec_h264_hw_s *hw) -{ - WRITE_VREG(H264_AUX_ADR, hw->aux_phy_addr); - WRITE_VREG(H264_AUX_DATA_SIZE, - ((hw->prefix_aux_size >> 4) << 16) | - (hw->suffix_aux_size >> 4) - ); -} - -/* -* dv_meta_flag: 1, dolby meta only; 2, not include dolby meta -*/ -static void set_aux_data(struct vdec_h264_hw_s *hw, - struct StorablePicture *pic, unsigned char suffix_flag, - unsigned char dv_meta_flag, struct vdec_h264_hw_s *hw_b) -{ - int i; - unsigned short *aux_adr; - unsigned size_reg_val = - READ_VREG(H264_AUX_DATA_SIZE); - unsigned aux_count = 0; - int aux_size = 0; - struct vdec_h264_hw_s *hw_buf = hw_b ? hw_b : hw; - if (pic == NULL || pic->buf_spec_num < 0 || pic->buf_spec_num >= BUFSPEC_POOL_SIZE - || (!is_buf_spec_in_use(hw, pic->buf_spec_num))) - return; - - if (suffix_flag) { - aux_adr = (unsigned short *) - (hw_buf->aux_addr + - hw_buf->prefix_aux_size); - aux_count = - ((size_reg_val & 0xffff) << 4) - >> 1; - aux_size = - hw_buf->suffix_aux_size; - } else { - aux_adr = - (unsigned short *)hw_buf->aux_addr; - aux_count = - ((size_reg_val >> 16) << 4) - >> 1; - aux_size = - hw_buf->prefix_aux_size; - } - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) { - dpb_print(DECODE_ID(hw), 0, - "%s:poc %d old size %d count %d,suf %d dv_flag %d\r\n", - __func__, pic->poc, AUX_DATA_SIZE(pic), - aux_count, suffix_flag, dv_meta_flag); - } - if (aux_size > 0 && aux_count > 0) { - int heads_size = 0; - - for (i = 0; i < aux_count; i++) { - unsigned char tag = aux_adr[i] >> 8; - if (tag != 0 && tag != 0xff) { - if (dv_meta_flag == 0) - heads_size += 8; - else if (dv_meta_flag == 1 && tag == 0x1) - heads_size += 8; - else if (dv_meta_flag == 2 && tag != 0x1) - heads_size += 8; - } - } - - if (AUX_DATA_BUF(pic)) { - unsigned char valid_tag = 0; - unsigned char *h = - AUX_DATA_BUF(pic) + - AUX_DATA_SIZE(pic); - unsigned char *p = h + 8; - int len = 0; - int padding_len = 0; - for (i = 0; i < aux_count; i += 4) { - int ii; - unsigned char tag = aux_adr[i + 3] >> 8; - if (tag != 0 && tag != 0xff) { - if (dv_meta_flag == 0) - valid_tag = 1; - else if (dv_meta_flag == 1 - && tag == 0x1) - valid_tag = 1; - else if (dv_meta_flag == 2 - && tag != 0x1) - valid_tag = 1; - else - valid_tag = 0; - if (valid_tag && len > 0) { - AUX_DATA_SIZE(pic) += - (len + 8); - h[0] = - (len >> 24) & 0xff; - h[1] = - (len >> 16) & 0xff; - h[2] = - (len >> 8) & 0xff; - h[3] = - (len >> 0) & 0xff; - h[6] = - (padding_len >> 8) - & 0xff; - h[7] = - (padding_len) & 0xff; - h += (len + 8); - p += 8; - len = 0; - padding_len = 0; - } - if (valid_tag) { - h[4] = tag; - h[5] = 0; - h[6] = 0; - h[7] = 0; - } - } - if (valid_tag) { - for (ii = 0; ii < 4; ii++) { - unsigned short aa = - aux_adr[i + 3 - - ii]; - *p = aa & 0xff; - p++; - len++; - /*if ((aa >> 8) == 0xff) - padding_len++;*/ - } - } - } - if (len > 0) { - AUX_DATA_SIZE(pic) += (len + 8); - h[0] = (len >> 24) & 0xff; - h[1] = (len >> 16) & 0xff; - h[2] = (len >> 8) & 0xff; - h[3] = (len >> 0) & 0xff; - h[6] = (padding_len >> 8) & 0xff; - h[7] = (padding_len) & 0xff; - } - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) { - dpb_print(DECODE_ID(hw), 0, - "aux: (size %d) suffix_flag %d\n", - AUX_DATA_SIZE(pic), suffix_flag); - for (i = 0; i < AUX_DATA_SIZE(pic); i++) { - dpb_print_cont(DECODE_ID(hw), 0, - "%02x ", AUX_DATA_BUF(pic)[i]); - if (((i + 1) & 0xf) == 0) - dpb_print_cont( - DECODE_ID(hw), - 0, "\n"); - } - dpb_print_cont(DECODE_ID(hw), - 0, "\n"); - } - } - } - -} - -static void release_aux_data(struct vdec_h264_hw_s *hw, - int buf_spec_num) -{ -#if 0 - kfree(hw->buffer_spec[buf_spec_num].aux_data_buf); - hw->buffer_spec[buf_spec_num].aux_data_buf = NULL; - hw->buffer_spec[buf_spec_num].aux_data_size = 0; -#endif -} - -static void dump_aux_buf(struct vdec_h264_hw_s *hw) -{ - int i; - unsigned short *aux_adr = - (unsigned short *) - hw->aux_addr; - unsigned aux_size = - (READ_VREG(H264_AUX_DATA_SIZE) - >> 16) << 4; - - if (hw->prefix_aux_size > 0) { - dpb_print(DECODE_ID(hw), - 0, - "prefix aux: (size %d)\n", - aux_size); - for (i = 0; i < - (aux_size >> 1); i++) { - dpb_print_cont(DECODE_ID(hw), - 0, - "%04x ", - *(aux_adr + i)); - if (((i + 1) & 0xf) - == 0) - dpb_print_cont( - DECODE_ID(hw), - 0, "\n"); - } - } - if (hw->suffix_aux_size > 0) { - aux_adr = (unsigned short *) - (hw->aux_addr + - hw->prefix_aux_size); - aux_size = - (READ_VREG(H264_AUX_DATA_SIZE) & 0xffff) - << 4; - dpb_print(DECODE_ID(hw), - 0, - "suffix aux: (size %d)\n", - aux_size); - for (i = 0; i < - (aux_size >> 1); i++) { - dpb_print_cont(DECODE_ID(hw), - 0, - "%04x ", *(aux_adr + i)); - if (((i + 1) & 0xf) == 0) - dpb_print_cont(DECODE_ID(hw), - 0, "\n"); - } - } -} - -#ifdef VDEC_DW - -struct vdec_dw_param_set{ - char dw_x_shrink_1st; - char dw_x_shrink_2nd; - char dw_x_shrink_3rd; - char dw_y_shrink_1st; - char dw_y_shrink_2nd; - char dw_y_shrink_3rd; - char dw_merge_8to16; - char dw_merge_16to32; - char dw_dma_blk_mode; - char dw_bwsave_mode; -}; -//#define FOR_LPDDR4_EFFICIENCY - -static void h264_vdec_dw_cfg(struct vdec_h264_hw_s *hw, int canvas_pos) -{ - u32 data32 = 0, stride = 0; - struct vdec_dw_param_set *p = NULL; - struct vdec_dw_param_set dw_param_set_pool[] = { - /*x1, x2, x3, y1, y2, y3, m8t6, m16to32 */ - //{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/1, 1/1 */ - {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/1 */ - {1, 0, 0, 1, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/2 */ - //{1, 0, 0, 1, 1, 0, 0, 0, 0, 1}, /* 1/4, 1/2 */ - {2, 0, 1, 1, 3, 0, 0, 1, 0, 1}, /* 1/4, 1/4 */ - //{1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/4 */ - {1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/8 */ - }; - - if (IS_VDEC_DW(hw)) - p = &dw_param_set_pool[__ffs(IS_VDEC_DW(hw))]; - else - return; - - WRITE_VREG(MDEC_DOUBLEW_CFG3, - hw->buffer_spec[canvas_pos].vdec_dw_y_addr); // luma start address - WRITE_VREG(MDEC_DOUBLEW_CFG4, - hw->buffer_spec[canvas_pos].vdec_dw_u_addr); // chroma start address - - stride = ALIGN_WIDTH((hw->mb_width << 4) / (IS_VDEC_DW(hw))); - if ((IS_VDEC_DW(hw)) == 1) //width 1/2 - stride >>= 1; - data32 = (stride << 16) | stride; - WRITE_VREG(MDEC_DOUBLEW_CFG5, data32); // chroma stride | luma stride - - data32 = 0; - p->dw_dma_blk_mode = hw->canvas_mode; - data32 |= ((p->dw_x_shrink_1st << 0 ) | // 1st down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_1st << 2 ) | // 1st down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_x_shrink_2nd << 4 ) | // 2nd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_2nd << 6 ) | // 2nd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_x_shrink_3rd << 8 ) | // 3rd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right - (p->dw_y_shrink_3rd << 10) | // 3rd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down - (p->dw_merge_8to16 << 12 ) | // 8->16 horizontal block merge for better ddr efficiency - (p->dw_merge_16to32 << 13) | // 16->32 horizontal block merge for better ddr efficiency - (p->dw_dma_blk_mode << 14) | // DMA block mode, 0:linear 1:32x32 2:64x32 -#ifdef FOR_LPDDR4_EFFICIENCY - (1 << 19) | -#endif - (p->dw_bwsave_mode << 22)); // Save line buffers to save band width - WRITE_VREG(MDEC_DOUBLEW_CFG1, data32); // add some special tests here - - data32 = 0; - data32 |= (1 << 0) | (0 << 27); - WRITE_VREG(MDEC_DOUBLEW_CFG0, data32); // Double Write Enable | source from dblk - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "vdec_double_write mode %d\n", - IS_VDEC_DW(hw)); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "param {%d, %d, %d, %d, %d, %d, %d, %d, %d}\n", - p->dw_x_shrink_1st, - p->dw_y_shrink_1st, - p->dw_x_shrink_2nd, - p->dw_y_shrink_2nd, - p->dw_x_shrink_3rd, - p->dw_y_shrink_3rd, - p->dw_merge_8to16, - p->dw_merge_16to32, - p->dw_dma_blk_mode); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "cfg0,1,3,4,5 = {%x, %x, %x, %x, %x}\n", - READ_VREG(MDEC_DOUBLEW_CFG0), - READ_VREG(MDEC_DOUBLEW_CFG1), - READ_VREG(MDEC_DOUBLEW_CFG3), - READ_VREG(MDEC_DOUBLEW_CFG4), - READ_VREG(MDEC_DOUBLEW_CFG5)); -} -#endif - -static void config_decode_mode(struct vdec_h264_hw_s *hw) -{ -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - struct vdec_s *vdec = hw_to_vdec(hw); -#endif - if (input_frame_based(hw_to_vdec(hw))) - WRITE_VREG(H264_DECODE_MODE, - DECODE_MODE_MULTI_FRAMEBASE); -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - else if (vdec->slave) - WRITE_VREG(H264_DECODE_MODE, - (hw->got_valid_nal << 8) | - DECODE_MODE_MULTI_DVBAL); - else if (vdec->master) - WRITE_VREG(H264_DECODE_MODE, - (hw->got_valid_nal << 8) | - DECODE_MODE_MULTI_DVENL); -#endif - else - WRITE_VREG(H264_DECODE_MODE, - DECODE_MODE_MULTI_STREAMBASE); - WRITE_VREG(H264_DECODE_SEQINFO, - hw->seq_info2); - WRITE_VREG(HEAD_PADING_REG, 0); - - if (hw->init_flag == 0) - WRITE_VREG(INIT_FLAG_REG, 0); - else - WRITE_VREG(INIT_FLAG_REG, 1); -} - -int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) -{ - /* static int count = 0; */ - int ret = 0; - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - struct Slice *pSlice = &(p_H264_Dpb->mSlice); - unsigned int colocate_adr_offset; - unsigned int val; - struct StorablePicture *last_pic = hw->last_dec_picture; - -#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF - int colocate_buf_index; -#endif -#define H264_BUFFER_INFO_INDEX PMV3_X /* 0xc24 */ -#define H264_BUFFER_INFO_DATA PMV2_X /* 0xc22 */ -#define H264_CURRENT_POC_IDX_RESET LAST_SLICE_MV_ADDR /* 0xc30 */ -#define H264_CURRENT_POC LAST_MVY /* 0xc32 shared with conceal MV */ - -#define H264_CO_MB_WR_ADDR VLD_C38 /* 0xc38 */ -/* bit 31:30 -- L1[0] picture coding structure, - * 00 - top field, 01 - bottom field, - * 10 - frame, 11 - mbaff frame - * bit 29 - L1[0] top/bot for B field pciture , 0 - top, 1 - bot - * bit 28:0 h264_co_mb_mem_rd_addr[31:3] - * -- only used for B Picture Direct mode [2:0] will set to 3'b000 - */ -#define H264_CO_MB_RD_ADDR VLD_C39 /* 0xc39 */ - -/* bit 15 -- flush co_mb_data to DDR -- W-Only - * bit 14 -- h264_co_mb_mem_wr_addr write Enable -- W-Only - * bit 13 -- h264_co_mb_info_wr_ptr write Enable -- W-Only - * bit 9 -- soft_reset -- W-Only - * bit 8 -- upgent - * bit 7:2 -- h264_co_mb_mem_wr_addr - * bit 1:0 -- h264_co_mb_info_wr_ptr - */ -#define H264_CO_MB_RW_CTL VLD_C3D /* 0xc3d */ -#define DCAC_DDR_BYTE64_CTL 0x0e1d - unsigned long canvas_adr; - unsigned int ref_reg_val; - unsigned int one_ref_cfg = 0; - int h264_buffer_info_data_write_count; - int i, j; - unsigned int colocate_wr_adr; - unsigned int colocate_rd_adr; - unsigned char use_direct_8x8; - int canvas_pos; - canvas_pos = hw->buffer_spec[pic->buf_spec_num].canvas_pos; - WRITE_VREG(H264_CURRENT_POC_IDX_RESET, 0); - WRITE_VREG(H264_CURRENT_POC, pic->frame_poc); - WRITE_VREG(H264_CURRENT_POC, pic->top_poc); - WRITE_VREG(H264_CURRENT_POC, pic->bottom_poc); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "%s: pic_num is %d, poc is %d (%d, %d, %d), buf_spec_num %d canvas_pos %d\n", - __func__, pic->pic_num, pic->poc, pic->frame_poc, - pic->top_poc, pic->bottom_poc, pic->buf_spec_num, - canvas_pos); - print_pic_info(DECODE_ID(hw), "cur", pic, pSlice->slice_type); - -#ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag) - WRITE_VREG(MDEC_DOUBLEW_CFG0, - (READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30)))); - } -#endif - WRITE_VREG(CURR_CANVAS_CTRL, canvas_pos << 24); - canvas_adr = READ_VREG(CURR_CANVAS_CTRL) & 0xffffff; - - if (!hw->mmu_enable) { - WRITE_VREG(REC_CANVAS_ADDR, canvas_adr); - WRITE_VREG(DBKR_CANVAS_ADDR, canvas_adr); - WRITE_VREG(DBKW_CANVAS_ADDR, canvas_adr); -#ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - WRITE_VREG(MDEC_DOUBLEW_CFG1, - (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index | - (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8))); - } else { - h264_vdec_dw_cfg(hw, canvas_pos); - } -#endif - } else - hevc_sao_set_pic_buffer(hw, pic); - - if (pic->mb_aff_frame_flag) - hw->buffer_spec[pic->buf_spec_num].info0 = 0xf4c0; - else if (pic->structure == TOP_FIELD) - hw->buffer_spec[pic->buf_spec_num].info0 = 0xf400; - else if (pic->structure == BOTTOM_FIELD) - hw->buffer_spec[pic->buf_spec_num].info0 = 0xf440; - else - hw->buffer_spec[pic->buf_spec_num].info0 = 0xf480; - - if (pic->bottom_poc < pic->top_poc) - hw->buffer_spec[pic->buf_spec_num].info0 |= 0x100; - - hw->buffer_spec[pic->buf_spec_num].info1 = pic->top_poc; - hw->buffer_spec[pic->buf_spec_num].info2 = pic->bottom_poc; - WRITE_VREG(H264_BUFFER_INFO_INDEX, 16); - - for (j = 0; j < hw->dpb.mDPB.size; j++) { - int long_term_flag; - i = get_buf_spec_by_canvas_pos(hw, j); - if (i < 0) - break; - long_term_flag = - get_long_term_flag_by_buf_spec_num(p_H264_Dpb, i); - if (long_term_flag > 0) { - if (long_term_flag & 0x1) - hw->buffer_spec[i].info0 |= (1 << 4); - else - hw->buffer_spec[i].info0 &= ~(1 << 4); - - if (long_term_flag & 0x2) - hw->buffer_spec[i].info0 |= (1 << 5); - else - hw->buffer_spec[i].info0 &= ~(1 << 5); - } - - if (i == pic->buf_spec_num) - WRITE_VREG(H264_BUFFER_INFO_DATA, - hw->buffer_spec[i].info0 | 0xf); - else - WRITE_VREG(H264_BUFFER_INFO_DATA, - hw->buffer_spec[i].info0); - WRITE_VREG(H264_BUFFER_INFO_DATA, hw->buffer_spec[i].info1); - WRITE_VREG(H264_BUFFER_INFO_DATA, hw->buffer_spec[i].info2); - } - - /* config reference buffer */ - if (hw->mmu_enable) { - hevc_mcr_config_mc_ref(hw); - hevc_mcr_config_mcrcc(hw); - } - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "list0 size %d\n", pSlice->listXsize[0]); - WRITE_VREG(H264_BUFFER_INFO_INDEX, 0); - ref_reg_val = 0; - j = 0; - h264_buffer_info_data_write_count = 0; - - //disable this read cache when frame width <= 64 (4MBs) - //IQIDCT_CONTROL, bit[16] dcac_dma_read_cache_disable - if (hw->frame_width <= 64) { - SET_VREG_MASK(IQIDCT_CONTROL,(1 << 16)); - if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)) - // Disable DDR_BYTE64_CACHE - WRITE_VREG(DCAC_DDR_BYTE64_CTL, - (READ_VREG(DCAC_DDR_BYTE64_CTL) & (~0xf)) | 0xa); - } - else - CLEAR_VREG_MASK(IQIDCT_CONTROL,(1 << 16)); - - if (last_pic) - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "last_pic->data_flag %x slice_type %x last_pic->slice_type %x\n", - last_pic->data_flag, pSlice->slice_type, last_pic->slice_type); - if (!hw->i_only && !(hw->error_proc_policy & 0x2000) && - last_pic && (last_pic->data_flag & ERROR_FLAG) - && (!(last_pic->slice_type == B_SLICE)) - && (!(pSlice->slice_type == I_SLICE))) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "no i/idr error mark\n"); - hw->data_flag |= ERROR_FLAG; - pic->data_flag |= ERROR_FLAG; - } - - for (i = 0; i < (unsigned int)(pSlice->listXsize[0]); i++) { - /*ref list 0 */ - struct StorablePicture *ref = pSlice->listX[0][i]; - unsigned int cfg; - /* bit[6:5] - frame/field info, - * 01 - top, 10 - bottom, 11 - frame - */ - #ifdef ERROR_CHECK - if (ref == NULL) { - hw->data_flag |= ERROR_FLAG; - pic->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref list0 NULL\n"); - return -1; - } - if ((ref->data_flag & ERROR_FLAG) && ref_frame_mark_flag[DECODE_ID(hw)]) { - hw->data_flag |= ERROR_FLAG; - pic->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark1 \n"); - } - - if (hw->error_proc_policy & 0x80000) { - if (ref_b_frame_error_max_count && - ref->slice_type == B_SLICE) { - if (ref->data_flag & ERROR_FLAG) - hw->b_frame_error_count++; - else - hw->b_frame_error_count = 0; - if (hw->b_frame_error_count > ref_b_frame_error_max_count) { - hw->b_frame_error_count = 0; - dpb_print(DECODE_ID(hw), 0, - "error %d B frame, reset dpb buffer\n", - ref_b_frame_error_max_count); - return -1; - } - } - } - - if (ref->data_flag & NULL_FLAG) - hw->data_flag |= NULL_FLAG; -#endif - canvas_pos = hw->buffer_spec[ref->buf_spec_num].canvas_pos; - - if (ref->structure == TOP_FIELD) - cfg = 0x1; - else if (ref->structure == BOTTOM_FIELD) - cfg = 0x2; - else /* FRAME */ - cfg = 0x3; - - one_ref_cfg = (canvas_pos & 0x1f) | (cfg << 5); - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - - if (j == 4) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "H264_BUFFER_INFO_DATA: %x\n", ref_reg_val); - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - h264_buffer_info_data_write_count++; - j = 0; - } - print_pic_info(DECODE_ID(hw), "list0", - pSlice->listX[0][i], -1); - } - if (j != 0) { - while (j != 4) { - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - } - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "H264_BUFFER_INFO_DATA: %x\n", - ref_reg_val); - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - h264_buffer_info_data_write_count++; - } - ref_reg_val = (one_ref_cfg << 24) | (one_ref_cfg<<16) | - (one_ref_cfg << 8) | one_ref_cfg; - for (i = h264_buffer_info_data_write_count; i < 8; i++) - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "list1 size %d\n", pSlice->listXsize[1]); - WRITE_VREG(H264_BUFFER_INFO_INDEX, 8); - ref_reg_val = 0; - j = 0; - - for (i = 0; i < (unsigned int)(pSlice->listXsize[1]); i++) { - /* ref list 0 */ - struct StorablePicture *ref = pSlice->listX[1][i]; - unsigned int cfg; - /* bit[6:5] - frame/field info, - * 01 - top, 10 - bottom, 11 - frame - */ - - #ifdef ERROR_CHECK - if (ref == NULL) { - hw->data_flag |= ERROR_FLAG; - pic->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error list1 NULL\n"); - return -2; - } - if ((ref->data_flag & ERROR_FLAG) && (ref_frame_mark_flag[DECODE_ID(hw)])) { - pic->data_flag |= ERROR_FLAG; - hw->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark2\n"); - } - if (ref->data_flag & NULL_FLAG) - hw->data_flag |= NULL_FLAG; -#endif - canvas_pos = hw->buffer_spec[ref->buf_spec_num].canvas_pos; - if (ref->structure == TOP_FIELD) - cfg = 0x1; - else if (ref->structure == BOTTOM_FIELD) - cfg = 0x2; - else /* FRAME */ - cfg = 0x3; - one_ref_cfg = (canvas_pos & 0x1f) | (cfg << 5); - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - - if (j == 4) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "H264_BUFFER_INFO_DATA: %x\n", - ref_reg_val); - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - j = 0; - } - print_pic_info(DECODE_ID(hw), "list1", - pSlice->listX[1][i], -1); - } - if (j != 0) { - while (j != 4) { - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - } - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "H264_BUFFER_INFO_DATA: %x\n", ref_reg_val); - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - } - - /* configure co-locate buffer */ - while ((READ_VREG(H264_CO_MB_RW_CTL) >> 11) & 0x1) - ; - if ((pSlice->mode_8x8_flags & 0x4) && - (pSlice->mode_8x8_flags & 0x2)) - use_direct_8x8 = 1; - else - use_direct_8x8 = 0; - -#ifndef ONE_COLOCATE_BUF_PER_DECODE_BUF - colocate_adr_offset = - ((pic->structure == FRAME && pic->mb_aff_frame_flag == 0) - ? 1 : 2) * 96; - if (use_direct_8x8) - colocate_adr_offset >>= 2; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "colocate buf size of each mb 0x%x first_mb_in_slice 0x%x colocate_adr_offset 0x%x\r\n", - colocate_adr_offset, pSlice->first_mb_in_slice, - colocate_adr_offset * pSlice->first_mb_in_slice); - - colocate_adr_offset *= pSlice->first_mb_in_slice; - - if ((pic->colocated_buf_index >= 0) && - (pic->colocated_buf_index < p_H264_Dpb->colocated_buf_count)) { - colocate_wr_adr = p_H264_Dpb->colocated_mv_addr_start + - ((p_H264_Dpb->colocated_buf_size * - pic->colocated_buf_index) - >> (use_direct_8x8 ? 2 : 0)); - if ((colocate_wr_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, index is %d\n", - pic->colocated_buf_index); - ret = -3; - } - val = colocate_wr_adr + colocate_adr_offset; - WRITE_VREG(H264_CO_MB_WR_ADDR, val); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "WRITE_VREG(H264_CO_MB_WR_ADDR) = %x, first_mb_in_slice %x pic_structure %x colocate_adr_offset %x mode_8x8_flags %x colocated_buf_size %x\n", - val, pSlice->first_mb_in_slice, pic->structure, - colocate_adr_offset, pSlice->mode_8x8_flags, - p_H264_Dpb->colocated_buf_size); - } else { - WRITE_VREG(H264_CO_MB_WR_ADDR, 0xffffffff); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "WRITE_VREG(H264_CO_MB_WR_ADDR) = 0xffffffff\n"); - } -#else - colocate_buf_index = hw->buffer_spec[pic->buf_spec_num].canvas_pos; - colocate_adr_offset = - ((pic->structure == FRAME && pic->mb_aff_frame_flag == 0) ? 1 : 2) * 96; - if (use_direct_8x8) - colocate_adr_offset >>= 2; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "colocate buf size of each mb 0x%x first_mb_in_slice 0x%x colocate_adr_offset 0x%x\r\n", - colocate_adr_offset, pSlice->first_mb_in_slice, - colocate_adr_offset * pSlice->first_mb_in_slice); - - colocate_adr_offset *= pSlice->first_mb_in_slice; - - colocate_wr_adr = p_H264_Dpb->colocated_mv_addr_start + - ((p_H264_Dpb->colocated_buf_size * colocate_buf_index) >> - (use_direct_8x8 ? 2 : 0)); - - if ((colocate_wr_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, col buf index is %d\n", - colocate_buf_index); - ret = -4; - } - val = colocate_wr_adr + colocate_adr_offset; - WRITE_VREG(H264_CO_MB_WR_ADDR, val); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "WRITE_VREG(H264_CO_MB_WR_ADDR) = %x, first_mb_in_slice %x pic_structure %x colocate_adr_offset %x mode_8x8_flags %x colocated_buf_size %x\n", - val, pSlice->first_mb_in_slice, pic->structure, - colocate_adr_offset, pSlice->mode_8x8_flags, - p_H264_Dpb->colocated_buf_size); -#endif - if (pSlice->listXsize[1] > 0) { - struct StorablePicture *colocate_pic = pSlice->listX[1][0]; - /* H264_CO_MB_RD_ADDR[bit 31:30], - * original picture structure of L1[0], - * 00 - top field, 01 - bottom field, - * 10 - frame, 11 - mbaff frame - */ - int l10_structure, cur_structure; - int cur_colocate_ref_type; - /* H264_CO_MB_RD_ADDR[bit 29], top/bot for B field pciture, - * 0 - top, 1 - bot - */ - unsigned int val; - unsigned int colocate_rd_adr_offset; - unsigned int mby_mbx; - unsigned int mby, mbx; -#ifdef ERROR_CHECK - if (colocate_pic == NULL) { - hw->data_flag |= ERROR_FLAG; - pic->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocate error pic NULL\n"); - return -5; - } - if (colocate_pic->data_flag & ERROR_FLAG) { - pic->data_flag |= ERROR_FLAG; - hw->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocare ref error mark\n"); - } - if (colocate_pic->data_flag & NULL_FLAG) - hw->data_flag |= NULL_FLAG; -#endif - - if (colocate_pic->mb_aff_frame_flag) - l10_structure = 3; - else { - if (colocate_pic->coded_frame) - l10_structure = 2; - else - l10_structure = (colocate_pic->structure == - BOTTOM_FIELD) ? 1 : 0; - } - - //ALLEGRO_FIX, ported from single mode ucode - mby_mbx = READ_VREG(MBY_MBX); - mby = pSlice->first_mb_in_slice / hw->mb_width; - mbx = pSlice->first_mb_in_slice % hw->mb_width; - if (pic->mb_aff_frame_flag) - cur_structure = 3; - else { - if (pic->coded_frame) - cur_structure = 2; - else - cur_structure = (pic->structure == - BOTTOM_FIELD) ? 1 : 0; - } - if (cur_structure < 2) { - //current_field_structure - if (l10_structure != 2) { - colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2; - } else { - // field_ref_from_frame co_mv_rd_addr : - // mby*2*mb_width + mbx - colocate_rd_adr_offset = mby * 2 * hw->mb_width + mbx; - } - - } else { - //current_frame_structure - if (l10_structure < 2) { - //calculate_co_mv_offset_frame_ref_field: - // frame_ref_from_field co_mv_rd_addr : - // (mby/2*mb_width+mbx)*2 - colocate_rd_adr_offset = ((mby / 2) * hw->mb_width + mbx) * 2; - } else if (cur_structure == 2) { - colocate_rd_adr_offset = pSlice->first_mb_in_slice; - } else { - //mbaff frame case1196 - colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2; - } - - } - - colocate_rd_adr_offset *= 96; - if (use_direct_8x8) - colocate_rd_adr_offset >>= 2; - - if (colocate_old_cal) - colocate_rd_adr_offset = colocate_adr_offset; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "first_mb_in_slice 0x%x 0x%x 0x%x (MBY_MBX reg 0x%x) use_direct_8x8 %d cur %d (mb_aff_frame_flag %d, coded_frame %d structure %d) col %d (mb_aff_frame_flag %d, coded_frame %d structure %d) offset 0x%x rdoffset 0x%x\n", - pSlice->first_mb_in_slice, mby, mbx, mby_mbx, use_direct_8x8, - cur_structure, pic->mb_aff_frame_flag, pic->coded_frame, pic->structure, - l10_structure, colocate_pic->mb_aff_frame_flag, colocate_pic->coded_frame, colocate_pic->structure, - colocate_adr_offset, - colocate_rd_adr_offset); - -#if 0 - /*case0016, p16, - *cur_colocate_ref_type should be configured base on current pic - */ - if (pic->structure == FRAME && - pic->mb_aff_frame_flag) - cur_colocate_ref_type = 0; - else if (pic->structure == BOTTOM_FIELD) - cur_colocate_ref_type = 1; - else - cur_colocate_ref_type = 0; -#else - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - " CUR TMP DEBUG : mb_aff_frame_flag : %d, structure : %d coded_frame %d\n", - pic->mb_aff_frame_flag, - pic->structure, - pic->coded_frame); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - " COL TMP DEBUG : mb_aff_frame_flag : %d, structure : %d coded_frame %d\n", - colocate_pic->mb_aff_frame_flag, - colocate_pic->structure, - colocate_pic->coded_frame); - if (pic->structure == FRAME || pic->mb_aff_frame_flag) { - cur_colocate_ref_type = - (abs(pic->poc - colocate_pic->top_poc) - < abs(pic->poc - - colocate_pic->bottom_poc)) ? 0 : 1; - } else - cur_colocate_ref_type = - (colocate_pic->structure - == BOTTOM_FIELD) ? 1 : 0; -#endif - -#ifndef ONE_COLOCATE_BUF_PER_DECODE_BUF - if ((colocate_pic->colocated_buf_index >= 0) && - (colocate_pic->colocated_buf_index < - p_H264_Dpb->colocated_buf_count)) { - colocate_rd_adr = p_H264_Dpb->colocated_mv_addr_start + - ((p_H264_Dpb->colocated_buf_size * - colocate_pic->colocated_buf_index) - >> (use_direct_8x8 ? 2 : 0)); - if ((colocate_rd_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, index is %d\n", - colocate_pic->colocated_buf_index); - ret = -6; - } - /* bit 31:30 -- L1[0] picture coding structure, - * 00 - top field, 01 - bottom field, - * 10 - frame, 11 - mbaff frame - * bit 29 - L1[0] top/bot for B field pciture, - * 0 - top, 1 - bot - * bit 28:0 h264_co_mb_mem_rd_addr[31:3] - * -- only used for B Picture Direct mode - * [2:0] will set to 3'b000 - */ - /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */ - val = ((colocate_rd_adr+colocate_rd_adr_offset) >> 3) | - (l10_structure << 30) | - (cur_colocate_ref_type << 29); - WRITE_VREG(H264_CO_MB_RD_ADDR, val); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "co idx %d, WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, addr %x L1(0) pic_structure %d mbaff %d\n", - colocate_pic->colocated_buf_index, - val, colocate_rd_adr + colocate_rd_adr_offset, - colocate_pic->structure, - colocate_pic->mb_aff_frame_flag); - } else { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "Error, reference pic has no colocated buf\n"); - ret = -7; - } -#else - colocate_buf_index = - hw->buffer_spec[colocate_pic->buf_spec_num].canvas_pos; - colocate_rd_adr = p_H264_Dpb->colocated_mv_addr_start + - ((p_H264_Dpb->colocated_buf_size * - colocate_buf_index) - >> (use_direct_8x8 ? 2 : 0)); - if ((colocate_rd_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, col buf index is %d\n", - colocate_buf_index); - ret = -8; - } - /* bit 31:30 -- L1[0] picture coding structure, - * 00 - top field, 01 - bottom field, - * 10 - frame, 11 - mbaff frame - * bit 29 - L1[0] top/bot for B field pciture, - * 0 - top, 1 - bot - * bit 28:0 h264_co_mb_mem_rd_addr[31:3] - * -- only used for B Picture Direct mode - * [2:0] will set to 3'b000 - */ - /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */ - val = ((colocate_rd_adr+colocate_rd_adr_offset)>>3) | - (l10_structure << 30) | (cur_colocate_ref_type << 29); - WRITE_VREG(H264_CO_MB_RD_ADDR, val); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, L1(0) pic_structure %d mbaff %d\n", - val, colocate_pic->structure, - colocate_pic->mb_aff_frame_flag); -#endif - } - return ret; -} - -static int vh264_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - spin_lock_irqsave(&hw->lock, flags); - - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&hw->newframe_q); - states->buf_avail_num = kfifo_len(&hw->display_q); - - spin_unlock_irqrestore(&hw->lock, flags); - - return 0; -} - -static struct vframe_s *vh264_vf_peek(void *op_arg) -{ - struct vframe_s *vf[2] = {0, 0}; - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - if (!hw) - return NULL; - - if (force_disp_bufspec_num & 0x100) { - if (force_disp_bufspec_num & 0x200) - return NULL; - return &hw->vframe_dummy; - } - - if (kfifo_out_peek(&hw->display_q, (void *)&vf, 2)) { - if (vf[1]) { - vf[0]->next_vf_pts_valid = true; - vf[0]->next_vf_pts = vf[1]->pts; - } else - vf[0]->next_vf_pts_valid = false; - return vf[0]; - } - - return NULL; -} - -static struct vframe_s *vh264_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - ulong nv_order = VIDTYPE_VIU_NV21; - - if (!hw) - return NULL; - - /* swap uv */ - if (hw->is_used_v4l) { - if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) || - (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M)) - nv_order = VIDTYPE_VIU_NV12; - } - - if (force_disp_bufspec_num & 0x100) { - int buffer_index = force_disp_bufspec_num & 0xff; - if (force_disp_bufspec_num & 0x200) - return NULL; - - vf = &hw->vframe_dummy; - vf->duration_pulldown = 0; - vf->pts = 0; - vf->pts_us64 = 0; - set_frame_info(hw, vf, buffer_index); - vf->flag = 0; - if (hw->mmu_enable) { - if (hw->double_write_mode & 0x10) { - /* double write only */ - vf->compBodyAddr = 0; - vf->compHeadAddr = 0; - } else { - /*head adr*/ - vf->compHeadAddr = - hw->buffer_spec[buffer_index].alloc_header_addr; - /*body adr*/ - vf->compBodyAddr = 0; - vf->canvas0Addr = vf->canvas1Addr = 0; - } - - vf->type = VIDTYPE_SCATTER; - - if (hw->double_write_mode) { - vf->type |= VIDTYPE_PROGRESSIVE - | VIDTYPE_VIU_FIELD; - vf->type |= nv_order; - if (hw->double_write_mode == 3) - vf->type |= VIDTYPE_COMPRESS; - - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->plane_num = 2; - vf->canvas0_config[0] = - hw->buffer_spec[buffer_index]. - canvas_config[0]; - vf->canvas0_config[1] = - hw->buffer_spec[buffer_index]. - canvas_config[1]; - - vf->canvas1_config[0] = - hw->buffer_spec[buffer_index]. - canvas_config[0]; - vf->canvas1_config[1] = - hw->buffer_spec[buffer_index]. - canvas_config[1]; - } else { - vf->type |= - VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; - vf->canvas0Addr = vf->canvas1Addr = 0; - } - vf->bitdepth = - BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; - - vf->compWidth = hw->frame_width; - vf->compHeight = hw->frame_height; - - if (hw->double_write_mode) { - vf->width = hw->frame_width / - get_double_write_ratio(hw->double_write_mode); - vf->height = hw->frame_height / - get_double_write_ratio(hw->double_write_mode); - } - } else { - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - nv_order; - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&hw->buffer_spec[buffer_index]); - } - - /*vf->mem_handle = decoder_bmmu_box_get_mem_handle( - hw->bmmu_box, buffer_index);*/ - update_vf_memhandle(hw, vf, buffer_index); - force_disp_bufspec_num |= 0x200; - return vf; - } - - if (kfifo_get(&hw->display_q, &vf)) { - int time = jiffies; - unsigned int frame_interval = - 1000*(time - hw->last_frame_time)/HZ; - struct vframe_s *next_vf = NULL; - ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q)); - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_VDEC_DETAIL)) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int frame_index = FRAME_INDEX(vf->index); - if (frame_index < 0 || - frame_index >= DPB_SIZE_MAX) { - dpb_print(DECODE_ID(hw), 0, - "%s vf index 0x%x error\r\n", - __func__, vf->index); - } else { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms, ts: %lld\n", - __func__, BUFSPEC_INDEX(vf->index), vf, - p_H264_Dpb->mFrameStore[frame_index].poc, - vf->duration, vf->pts, frame_interval, vf->timestamp); - } - } - if (hw->last_frame_time > 0) { - if (frame_interval > - max_get_frame_interval[DECODE_ID(hw)]) - max_get_frame_interval[DECODE_ID(hw)] - = frame_interval; - } - hw->last_frame_time = time; - vf->index_disp = atomic_read(&hw->vf_get_count); - atomic_add(1, &hw->vf_get_count); - if (kfifo_peek(&hw->display_q, &next_vf) && next_vf) { - vf->next_vf_pts_valid = true; - vf->next_vf_pts = next_vf->pts; - } else - vf->next_vf_pts_valid = false; - - return vf; - } - - return NULL; -} - -static bool vf_valid_check(struct vframe_s *vf, struct vdec_h264_hw_s *hw) { - int i,j; - if (hw->is_used_v4l) - return true; - for (i = 0; i < VF_POOL_SIZE; i++) { - for (j = 0; j < VF_POOL_NUM; j ++) { - if (vf == &(hw->vfpool[j][i]) || vf == &hw->vframe_dummy) - return true; - } - } - dpb_print(DECODE_ID(hw), 0, " invalid vf been put, vf = %p\n", vf); - for (i = 0; i < VF_POOL_SIZE; i++) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "dump vf [%d]= %p\n", i, &(hw->vfpool[hw->cur_pool][i])); - } - return false; -} - -static void vh264_vf_put(struct vframe_s *vf, void *op_arg) -{ - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - unsigned long flags; - int buf_spec_num; - int frame_index; - - if (vf == (&hw->vframe_dummy)) - return; - - if (!vf) - return; - - if (vf->index == -1) { - dpb_print(DECODE_ID(hw), 0, - "Warning: %s vf %p invalid index\r\n", - __func__, vf); - return; - } - - if (hw->enable_fence && vf->fence) { - int ret, i; - - mutex_lock(&hw->fence_mutex); - ret = dma_fence_get_status(vf->fence); - if (ret == 0) { - for (i = 0; i < VF_POOL_SIZE; i++) { - if (hw->fence_vf_s.fence_vf[i] == NULL) { - hw->fence_vf_s.fence_vf[i] = vf; - hw->fence_vf_s.used_size++; - mutex_unlock(&hw->fence_mutex); - return; - } - } - } - mutex_unlock(&hw->fence_mutex); - } - - buf_spec_num = BUFSPEC_INDEX(vf->index); - if (hw->enable_fence) - frame_index = hw->buffer_spec[buf_spec_num].fs_idx; - else - frame_index = FRAME_INDEX(vf->index); - - if (frame_index < 0 || - frame_index >= DPB_SIZE_MAX || - buf_spec_num < 0 || - buf_spec_num >= BUFSPEC_POOL_SIZE) { - dpb_print(DECODE_ID(hw), 0, - "%s vf index 0x%x error\r\n", - __func__, vf->index); - return; - } - /*get_buf_spec_idx_by_canvas_config(hw, - &vf->canvas0_config[0]);*/ - - if (hw->enable_fence && vf->fence) { - vdec_fence_put(vf->fence); - vf->fence = NULL; - } - - if (vf->meta_data_buf) { - vf->meta_data_buf = NULL; - vf->meta_data_size = 0; - } - - spin_lock_irqsave(&hw->bufspec_lock, flags); - if (hw->buffer_spec[buf_spec_num].used == 2) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s %p to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n", - __func__, vf, frame_index, - p_H264_Dpb->mFrameStore[frame_index].poc, - buf_spec_num, - hw->buffer_spec[buf_spec_num].used, - hw->buffer_spec[buf_spec_num].vf_ref); - hw->buffer_spec[buf_spec_num].vf_ref--; - if (hw->buffer_spec[buf_spec_num].vf_ref <= 0) - set_frame_output_flag(&hw->dpb, frame_index); - } else { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s %p isolated vf, buf_spec_num %d used %d vf_ref %d\n", - __func__, vf, buf_spec_num, - hw->buffer_spec[buf_spec_num].used, - hw->buffer_spec[buf_spec_num].vf_ref); - hw->buffer_spec[buf_spec_num].vf_ref--; - if (hw->buffer_spec[buf_spec_num].vf_ref <= 0) { - if (hw->buffer_spec[buf_spec_num].used == 3) - hw->buffer_spec[buf_spec_num].used = 4; - else if (hw->buffer_spec[buf_spec_num].used == 5) - hw->buffer_spec[buf_spec_num].used = 0; - } - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - - } - - if (hw->is_used_v4l) { - struct buffer_spec_s *pic = &hw->buffer_spec[buf_spec_num]; - - if (vf->v4l_mem_handle != pic->cma_alloc_addr) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL, - "H264 update fb handle, old:%llx, new:%llx\n", - pic->cma_alloc_addr, vf->v4l_mem_handle); - - pic->cma_alloc_addr = vf->v4l_mem_handle; - } - } - - if (vf && (vf_valid_check(vf, hw) == true)) { - atomic_add(1, &hw->vf_put_count); - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q)); - } -#define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG - if (hw->buffer_empty_flag) - WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1); - spin_unlock_irqrestore(&hw->bufspec_lock, flags); -} - - -void * vh264_get_bufspec_lock(struct vdec_s *vdec) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - if (hw) - return (&hw->bufspec_lock); - else - return NULL; -} -static int vh264_event_cb(int type, void *data, void *op_arg) -{ - unsigned long flags; - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) { - struct provider_aux_req_s *req = - (struct provider_aux_req_s *)data; - int buf_spec_num; - - if (!req->vf) { - req->aux_size = atomic_read(&hw->vf_put_count); - return 0; - } - buf_spec_num = BUFSPEC_INDEX(req->vf->index); - spin_lock_irqsave(&hw->lock, flags); - req->aux_buf = NULL; - req->aux_size = 0; - if (buf_spec_num >= 0 && - buf_spec_num < BUFSPEC_POOL_SIZE && - is_buf_spec_in_disp_q(hw, buf_spec_num) - ) { - req->aux_buf = - hw->buffer_spec[buf_spec_num].aux_data_buf; - req->aux_size = - hw->buffer_spec[buf_spec_num].aux_data_size; -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - req->dv_enhance_exist = - hw->buffer_spec[buf_spec_num].dv_enhance_exist; -#else - req->dv_enhance_exist = 0; -#endif - } - spin_unlock_irqrestore(&hw->lock, flags); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s(type 0x%x vf buf_spec_num 0x%x)=>size 0x%x\n", - __func__, type, buf_spec_num, req->aux_size); - } else 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(vdec); - else - req->req_result[0] = 0xffffffff; - } - - return 0; -} - -static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf, - u32 index) -{ - int endian_tmp; - struct canvas_config_s *p_canvas_config; - int force_rate = input_frame_based(hw_to_vdec(hw)) ? - force_rate_framebase : force_rate_streambase; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s (%d,%d) dur %d, vf %p, index %d\n", __func__, - hw->frame_width, hw->frame_height, hw->frame_dur, vf, index); - - /* signal_type */ - if (hw->video_signal_from_vui & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) { - vf->signal_type = hw->video_signal_from_vui; - if (hw->is_used_v4l) { - struct aml_vdec_hdr_infos hdr; - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - - memset(&hdr, 0, sizeof(hdr)); - hdr.signal_type = hw->video_signal_from_vui; - vdec_v4l_set_hdr_infos(ctx, &hdr); - } - } else - vf->signal_type = 0; - hw->video_signal_type = vf->signal_type; - - vf->width = hw->frame_width; - vf->height = hw->frame_height; - if (force_rate) { - if (force_rate == -1) - vf->duration = 0; - else - vf->duration = 96000/force_rate; - } else - vf->duration = hw->frame_dur; - vf->ratio_control = - (min(hw->h264_ar, (u32) DISP_RATIO_ASPECT_RATIO_MAX)) << - DISP_RATIO_ASPECT_RATIO_BIT; - vf->orientation = hw->vh264_rotation; - - vf->sidebind_type = hw->sidebind_type; - vf->sidebind_channel_id = hw->sidebind_channel_id; - - if (hw->mmu_enable) - return; - - vf->canvas0Addr = vf->canvas1Addr = -1; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->plane_num = 3; -#endif - - if (IS_VDEC_DW(hw)) { - if (IS_VDEC_DW(hw) == 1) - vf->width = hw->frame_width / 2; - else - vf->width = (hw->frame_width / IS_VDEC_DW(hw)); - vf->height = (hw->frame_height / IS_VDEC_DW(hw)); - p_canvas_config = &hw->buffer_spec[index].vdec_dw_canvas_config[0]; - } else - p_canvas_config = &hw->buffer_spec[index].canvas_config[0]; - - vf->canvas0_config[0] = p_canvas_config[0]; - vf->canvas0_config[1] = p_canvas_config[1]; - vf->canvas1_config[0] = p_canvas_config[0]; - vf->canvas1_config[1] = p_canvas_config[1]; -#ifndef NV21 - vf->canvas0_config[2] = p_canvas_config[2]; - vf->canvas1_config[2] = p_canvas_config[2]; -#endif - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) { - endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0; - } else { - endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 0 : 7; - } - vf->canvas0_config[0].endian = endian_tmp; - vf->canvas0_config[1].endian = endian_tmp; - vf->canvas1_config[0].endian = endian_tmp; - vf->canvas1_config[1].endian = endian_tmp; -#ifndef NV21 - vf->canvas0_config[2].endian = endian_tmp; - vf->canvas1_config[2].endian = endian_tmp; -#endif -} - -static void get_picture_qos_info(struct StorablePicture *picture) -{ - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) { - unsigned char a[3]; - unsigned char i, j, t; - unsigned long data; - - get_random_bytes(&data, sizeof(unsigned long)); - if (picture->slice_type == I_SLICE) - 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->max_mv = a[2]; - picture->avg_mv = a[1]; - picture->min_mv = a[0]; - /* - pr_info("mv data %x a[0]= %x a[1]= %x a[2]= %x\n", - data, a[0], a[1], a[2]); - */ - - get_random_bytes(&data, sizeof(unsigned long)); - 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->max_qp = a[2]; - picture->avg_qp = a[1]; - picture->min_qp = a[0]; - /* - pr_info("qp data %x a[0]= %x a[1]= %x a[2]= %x\n", - data, a[0], a[1], a[2]); - */ - - get_random_bytes(&data, sizeof(unsigned long)); - 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->max_skip = a[2]; - picture->avg_skip = a[1]; - picture->min_skip = a[0]; - - - /* - pr_info("skip data %x a[0]= %x a[1]= %x a[2]= %x\n", - data,a[0], a[1], a[2]); - */ - } else { - 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; -/* -#define DEBUG_QOS -*/ -#ifdef DEBUG_QOS - int pic_number = picture->poc; -#endif - - picture->max_mv = 0; - picture->avg_mv = 0; - picture->min_mv = 0; - - picture->max_skip = 0; - picture->avg_skip = 0; - picture->min_skip = 0; - - picture->max_qp = 0; - picture->avg_qp = 0; - picture->min_qp = 0; - - - - - - /* set rd_idx to 0 */ - WRITE_VREG(VDEC_PIC_QUALITY_CTRL, 0); - blk88_y_count = READ_VREG(VDEC_PIC_QUALITY_DATA); - if (blk88_y_count == 0) { -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] NO Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8)); - return; - } - /* qp_y_sum */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y QP AVG : %d (%d/%d)\n", - pic_number, rdata32/blk88_y_count, - rdata32, blk88_y_count); -#endif - picture->avg_qp = rdata32/blk88_y_count; - /* intra_y_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y intra rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_y_count, - '%', rdata32); -#endif - /* skipped_y_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y skipped rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_y_count, - '%', rdata32); -#endif - picture->avg_skip = rdata32*100/blk88_y_count; - /* coeff_non_zero_y_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n", - pic_number, (100 - rdata32*100/(blk88_y_count*1)), - '%', rdata32); -#endif - /* blk66_c_count */ - blk88_c_count = READ_VREG(VDEC_PIC_QUALITY_DATA); - if (blk88_c_count == 0) { -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] NO Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8)); - return; - } - /* qp_c_sum */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] C QP AVG : %d (%d/%d)\n", - pic_number, rdata32/blk88_c_count, - rdata32, blk88_c_count); -#endif - /* intra_c_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] C intra rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_c_count, - '%', rdata32); -#endif - /* skipped_cu_c_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] C skipped rate : %d%c (%d)\n", - pic_number, rdata32*100/blk88_c_count, - '%', rdata32); -#endif - /* coeff_non_zero_c_count */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n", - pic_number, (100 - rdata32*100/(blk88_c_count*1)), - '%', rdata32); -#endif - - /* 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(VDEC_PIC_QUALITY_DATA); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y QP min : %d\n", - pic_number, (rdata32>>0)&0xff); -#endif - picture->min_qp = (rdata32>>0)&0xff; - -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] Y QP max : %d\n", - pic_number, (rdata32>>8)&0xff); -#endif - picture->max_qp = (rdata32>>8)&0xff; - -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] C QP min : %d\n", - pic_number, (rdata32>>16)&0xff); - pr_info(" [Picture %d Quality] C QP max : %d\n", - pic_number, (rdata32>>24)&0xff); -#endif - - /* blk22_mv_count */ - blk22_mv_count = READ_VREG(VDEC_PIC_QUALITY_DATA); - if (blk22_mv_count == 0) { -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] NO MV Data yet.\n", - pic_number); -#endif - /* reset all counts */ - WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (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(VDEC_PIC_QUALITY_DATA); - /* should all be 0x00 or 0xff */ -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MV AVG High Bits: 0x%X\n", - pic_number, rdata32); -#endif - 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(VDEC_PIC_QUALITY_DATA); - 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, blk22_mv_count); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n", - pic_number, (int)(value), - value, blk22_mv_count); -#endif - picture->avg_mv = value; - - /* mvy_L0_count[31:0] */ - rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* mvx_L1_count[31:0] */ - rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* mvy_L1_count[31:0] */ - rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA); - 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; -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n", - pic_number, rdata32_l/blk22_mv_count, - value, blk22_mv_count); -#endif - - /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVX_L0 MAX : %d\n", - pic_number, mv_hi); -#endif - picture->max_mv = mv_hi; - - mv_lo = (rdata32>>0)&0xffff; - if (mv_lo & 0x8000) - mv_lo = 0x8000 - mv_lo; -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] MVX_L0 MIN : %d\n", - pic_number, mv_lo); -#endif - picture->min_mv = mv_lo; - -#ifdef DEBUG_QOS - /* {mvy_L0_max, mvy_L0_min} */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - pr_info(" [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; - - pr_info(" [Picture %d Quality] MVY_L0 MIN : %d\n", - pic_number, mv_lo); - - - /* {mvx_L1_max, mvx_L1_min} */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - - pr_info(" [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; - - pr_info(" [Picture %d Quality] MVX_L1 MIN : %d\n", - pic_number, mv_lo); - - - /* {mvy_L1_max, mvy_L1_min} */ - rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA); - mv_hi = (rdata32>>16)&0xffff; - if (mv_hi & 0x8000) - mv_hi = 0x8000 - mv_hi; - - pr_info(" [Picture %d Quality] MVY_L1 MAX : %d\n", - pic_number, mv_hi); - - mv_lo = (rdata32>>0)&0xffff; - if (mv_lo & 0x8000) - mv_lo = 0x8000 - mv_lo; - - pr_info(" [Picture %d Quality] MVY_L1 MIN : %d\n", - pic_number, mv_lo); -#endif - - rdata32 = READ_VREG(VDEC_PIC_QUALITY_CTRL); -#ifdef DEBUG_QOS - pr_info(" [Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n", - pic_number, rdata32); -#endif - /* reset all counts */ - WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8)); - } -} - -static int get_dec_dpb_size(struct vdec_h264_hw_s *hw, int mb_width, - int mb_height, int level_idc) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int pic_size = mb_width * mb_height * 384; - int size = 0, size_vui; - - switch (level_idc) { - case 9: - size = 152064; - break; - case 10: - size = 152064; - break; - case 11: - size = 345600; - break; - case 12: - size = 912384; - break; - case 13: - size = 912384; - break; - case 20: - size = 912384; - break; - case 21: - size = 1824768; - break; - case 22: - size = 3110400; - break; - case 30: - size = 3110400; - break; - case 31: - size = 6912000; - break; - case 32: - size = 7864320; - break; - case 40: - size = 12582912; - break; - case 41: - size = 12582912; - break; - case 42: - size = 13369344; - break; - case 50: - size = 42393600; - break; - case 51: - case 52: - default: - size = 70778880; - break; - } - - size /= pic_size; - size = imin(size, 16); - dpb_print(DECODE_ID(hw), 0, - "level_idc = %d pic_size = %d size = %d\n", - level_idc, pic_size, size); - if (p_H264_Dpb->bitstream_restriction_flag) { - if ((int)p_H264_Dpb->max_dec_frame_buffering > size) { - dpb_print(DECODE_ID(hw), 0, - "max_dec_frame_buffering larger than MaxDpbSize.\n"); - } - size_vui = imax (1, p_H264_Dpb->max_dec_frame_buffering); - if (size_vui < size) { - dpb_print(DECODE_ID(hw), 0, - "Warning: max_dec_frame_buffering(%d) is less than DPB size(%d) calculated from Profile/Level.\n", - size_vui, size); - } - size = size_vui; - } - - size += 2; /* need two more buffer */ - - if (!hw->discard_dv_data) { - size += 1; - dpb_print(DECODE_ID(hw), 0, "dv stream need one more buffer.\n"); - } - - return size; -} - -static int get_dec_dpb_size_active(struct vdec_h264_hw_s *hw, u32 param1, u32 param4) -{ - int mb_width, mb_total; - int mb_height = 0; - int dec_dpb_size; - int level_idc = param4 & 0xff; - - mb_width = param1 & 0xff; - mb_total = (param1 >> 8) & 0xffff; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - if (mb_width) - mb_height = mb_total/mb_width; - if (mb_width <= 0 || mb_height <= 0 || - is_oversize(mb_width << 4, mb_height << 4)) { - dpb_print(DECODE_ID(hw), 0, - "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", - param1, - mb_width, - mb_height); - hw->error_frame_width = mb_width << 4; - hw->error_frame_height = mb_height << 4; - return -1; - } - hw->error_frame_width = 0; - hw->error_frame_height = 0; - - dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height, level_idc); - - if (hw->no_poc_reorder_flag) - dec_dpb_size = 1; - - return dec_dpb_size; -} - -static void vh264_config_canvs_for_mmu(struct vdec_h264_hw_s *hw) -{ - int i, j; - - if (hw->double_write_mode) { - mutex_lock(&vmh264_mutex); - if (hw->decode_pic_count == 0) { - for (j = 0; j < hw->dpb.mDPB.size; j++) { - i = get_buf_spec_by_canvas_pos(hw, j); - if (i >= 0) - config_decode_canvas_ex(hw, i); - } - } - mutex_unlock(&vmh264_mutex); - } -} - -static int vh264_set_params(struct vdec_h264_hw_s *hw, - u32 param1, u32 param2, u32 param3, u32 param4, bool buffer_reset_flag) -{ - int i, j; - int mb_width, mb_total; - int max_reference_size, level_idc; - int mb_height = 0; - unsigned long flags; - /*int mb_mv_byte;*/ - struct vdec_s *vdec = hw_to_vdec(hw); - u32 seq_info2; - int ret = 0; - int active_buffer_spec_num; - unsigned int buf_size; - unsigned int frame_mbs_only_flag; - unsigned int chroma_format_idc; - unsigned int crop_bottom, crop_right; - unsigned int used_reorder_dpb_size_margin - = hw->reorder_dpb_size_margin; - u8 *colocate_vaddr = NULL; - int dec_dpb_size_change = 0; - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (vdec->master || vdec->slave) - used_reorder_dpb_size_margin = - reorder_dpb_size_margin_dv; -#endif - seq_info2 = param1; - hw->seq_info = param2; - - mb_width = seq_info2 & 0xff; - mb_total = (seq_info2 >> 8) & 0xffff; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - if (mb_width) - mb_height = mb_total/mb_width; - if (mb_width <= 0 || mb_height <= 0 || - is_oversize(mb_width << 4, mb_height << 4)) { - dpb_print(DECODE_ID(hw), 0, - "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", - seq_info2, - mb_width, - mb_height); - hw->error_frame_width = mb_width << 4; - hw->error_frame_height = mb_height << 4; - return -1; - } - hw->error_frame_width = 0; - hw->error_frame_height = 0; - - dec_dpb_size_change = hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1, param4); - - if (((seq_info2 != 0 && - hw->seq_info2 != seq_info2) || hw->csd_change_flag) && - hw->seq_info2 != 0 - ) { - if (((hw->seq_info2 & 0x80ffffff) != (param1 & 0x80ffffff)) || dec_dpb_size_change) { /*picture size changed*/ - h264_reconfig(hw); - } else { - /*someting changes and not including dpb_size, width, height, ...*/ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - u32 reg_val = param4; - max_reference_size = (reg_val >> 8) & 0xff; - hw->dpb.reorder_output = max_reference_size; - - hw->cfg_param1 = param1; - hw->cfg_bitstream_restriction_flag = hw->bitstream_restriction_flag; - - hw->seq_info2 = seq_info2; - - if (p_H264_Dpb->bitstream_restriction_flag && - p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering && - p_H264_Dpb->num_reorder_frames >= 0) { - hw->dpb.reorder_output = hw->num_reorder_frames + 1; - } - - hw->max_reference_size = - max_reference_size + reference_buf_margin; - - if (hw->max_reference_size > MAX_VF_BUF_NUM) - hw->max_reference_size = MAX_VF_BUF_NUM; - hw->dpb.max_reference_size = hw->max_reference_size; - } - } - - if (hw->config_bufmgr_done == 0) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - u32 reg_val; - int sub_width_c = 0, sub_height_c = 0; - - hw->cfg_param1 = param1; - hw->cfg_param2 = param2; - hw->cfg_param3 = param3; - hw->cfg_param4 = param4; - hw->cfg_bitstream_restriction_flag = hw->bitstream_restriction_flag; - - hw->seq_info2 = seq_info2; - dpb_print(DECODE_ID(hw), 0, - "AV_SCRATCH_1 = %x, AV_SCRATCH_2 %x\r\n", - seq_info2, hw->seq_info); - - dpb_init_global(&hw->dpb, - DECODE_ID(hw), 0, 0); - - p_H264_Dpb->fast_output_enable = fast_output_enable; - /*mb_mv_byte = (seq_info2 & 0x80000000) ? 24 : 96;*/ - - if (hw->enable_fence) - p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST; - -#if 1 - /*crop*/ - /* AV_SCRATCH_2 - bit 15: frame_mbs_only_flag - bit 13-14: chroma_format_idc */ - frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01; - if (p_H264_Dpb->mSPS.profile_idc != 100 && - p_H264_Dpb->mSPS.profile_idc != 110 && - p_H264_Dpb->mSPS.profile_idc != 122 && - p_H264_Dpb->mSPS.profile_idc != 144) { - p_H264_Dpb->chroma_format_idc = 1; - } - chroma_format_idc = p_H264_Dpb->chroma_format_idc; - - /* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1 - @AV_SCRATCH_6.15-0 = (top << 8 | bottom ) << - (2 - frame_mbs_only_flag) */ - - switch (chroma_format_idc) { - case 1: - sub_width_c = 2; - sub_height_c = 2; - break; - - case 2: - sub_width_c = 2; - sub_height_c = 1; - break; - - case 3: - sub_width_c = 1; - sub_height_c = 1; - break; - - default: - break; - } - - if (chroma_format_idc == 0) { - crop_right = p_H264_Dpb->frame_crop_right_offset; - crop_bottom = p_H264_Dpb->frame_crop_bottom_offset * - (2 - frame_mbs_only_flag); - } else { - crop_right = sub_width_c * p_H264_Dpb->frame_crop_right_offset; - crop_bottom = sub_height_c * p_H264_Dpb->frame_crop_bottom_offset * - (2 - frame_mbs_only_flag); - } - - p_H264_Dpb->mSPS.frame_mbs_only_flag = frame_mbs_only_flag; - hw->frame_width = mb_width << 4; - hw->frame_height = mb_height << 4; - - hw->frame_width = hw->frame_width - crop_right; - hw->frame_height = hw->frame_height - crop_bottom; - - dpb_print(DECODE_ID(hw), 0, - "chroma_format_idc = %d frame_mbs_only_flag %d, crop_bottom %d, frame_height %d,\n", - chroma_format_idc, frame_mbs_only_flag, crop_bottom, hw->frame_height); - dpb_print(DECODE_ID(hw), 0, - "mb_height %d,crop_right %d, frame_width %d, mb_width %d\n", - mb_height, crop_right, - hw->frame_width, mb_width); - - if (hw->frame_height == 1088 && (crop_right != 0 || crop_bottom != 0)) - hw->frame_height = 1080; -#endif - reg_val = param4; - level_idc = reg_val & 0xff; - p_H264_Dpb->mSPS.level_idc = level_idc; - max_reference_size = (reg_val >> 8) & 0xff; - hw->dpb.reorder_output = max_reference_size; - hw->dpb.dec_dpb_size = - get_dec_dpb_size(hw , mb_width, mb_height, level_idc); - if (!hw->mmu_enable) { - mb_width = (mb_width+3) & 0xfffffffc; - mb_height = (mb_height+3) & 0xfffffffc; - } - mb_total = mb_width * mb_height; - hw->mb_width = mb_width; - hw->mb_height = mb_height; - hw->mb_total = mb_total; - if (hw->mmu_enable) - hevc_mcr_sao_global_hw_init(hw, - (hw->mb_width << 4), (hw->mb_height << 4)); - - dpb_print(DECODE_ID(hw), 0, - "mb height/widht/total: %x/%x/%x level_idc %x max_ref_num %x\n", - mb_height, mb_width, mb_total, - level_idc, max_reference_size); - - p_H264_Dpb->colocated_buf_size = mb_total * 96; - - dpb_print(DECODE_ID(hw), 0, - "restriction_flag=%d, max_dec_frame_buffering=%d, dec_dpb_size=%d num_reorder_frames %d used_reorder_dpb_size_margin %d\n", - hw->bitstream_restriction_flag, - hw->max_dec_frame_buffering, - hw->dpb.dec_dpb_size, - hw->num_reorder_frames, - used_reorder_dpb_size_margin); - - if (p_H264_Dpb->bitstream_restriction_flag && - p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering && - p_H264_Dpb->num_reorder_frames >= 0) { - hw->dpb.reorder_output = hw->num_reorder_frames + 1; - } - - active_buffer_spec_num = - hw->dpb.dec_dpb_size - + used_reorder_dpb_size_margin; - hw->max_reference_size = - max_reference_size + reference_buf_margin; - - if (active_buffer_spec_num > MAX_VF_BUF_NUM) { - active_buffer_spec_num = MAX_VF_BUF_NUM; - hw->dpb.dec_dpb_size = active_buffer_spec_num - - used_reorder_dpb_size_margin; - dpb_print(DECODE_ID(hw), 0, - "active_buffer_spec_num is larger than MAX %d, set dec_dpb_size to %d\n", - MAX_VF_BUF_NUM, hw->dpb.dec_dpb_size); - } - - if (hw->is_used_v4l) { - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - struct vdec_pic_info pic; - - vdec_v4l_get_pic_info(ctx, &pic); - - active_buffer_spec_num = pic.dpb_frames + - pic.dpb_margin; - } - - hw->dpb.mDPB.size = active_buffer_spec_num; - if (hw->max_reference_size > MAX_VF_BUF_NUM) - hw->max_reference_size = MAX_VF_BUF_NUM; - hw->dpb.max_reference_size = hw->max_reference_size; - - if (hw->no_poc_reorder_flag) - hw->dpb.dec_dpb_size = 1; - dpb_print(DECODE_ID(hw), 0, - "%s active_buf_spec_num %d dec_dpb_size %d collocate_buf_num %d\r\n", - __func__, active_buffer_spec_num, - hw->dpb.dec_dpb_size, - hw->max_reference_size); - - if (hw->kpi_first_i_comming == 0) { - hw->kpi_first_i_comming = 1; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "[vdec_kpi][%s] First I frame comming.\n", __func__); - } - - buf_size = (hw->mb_total << 8) + (hw->mb_total << 7); - - mutex_lock(&vmh264_mutex); - if (!hw->mmu_enable) { - if (!buffer_reset_flag) - config_buf_specs(vdec); - i = get_buf_spec_by_canvas_pos(hw, 0); - - if (hw->is_used_v4l) { - if (i != -1) { - pr_info("v4l: delay alloc the buffer.\n"); - } - } else { - if ((i != -1) && alloc_one_buf_spec(hw, i) >= 0) - config_decode_canvas(hw, i); - else - ret = -1; - } - } else { - if (hw->double_write_mode) { - config_buf_specs_ex(vdec); - } else { - spin_lock_irqsave(&hw->bufspec_lock, flags); - for (i = 0, j = 0; - j < active_buffer_spec_num - && i < BUFSPEC_POOL_SIZE; - i++) { - if (hw->buffer_spec[i].used != -1) - continue; - hw->buffer_spec[i].used = 0; - hw->buffer_spec[i]. - alloc_header_addr = 0; - hw->buffer_spec[i].canvas_pos = j; - j++; - } - spin_unlock_irqrestore(&hw->bufspec_lock, - flags); - } - hevc_mcr_config_canv2axitbl(hw, 0); - } - mutex_unlock(&vmh264_mutex); - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_DUMP_BUFSPEC)) - dump_bufspec(hw, __func__); - -#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF - buf_size = PAGE_ALIGN( - p_H264_Dpb->colocated_buf_size * - active_buffer_spec_num); -#else - buf_size = PAGE_ALIGN( - p_H264_Dpb->colocated_buf_size * - hw->max_reference_size); -#endif - - if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_REF_IDX, - buf_size, DRIVER_NAME, - &hw->collocate_cma_alloc_addr) < 0) - return -1; - if (!vdec_secure(vdec)) { - /* clear for some mosaic problem after reset bufmgr */ - colocate_vaddr = codec_mm_vmap(hw->collocate_cma_alloc_addr, buf_size); - if (colocate_vaddr != NULL) { - memset(colocate_vaddr, 0, buf_size); - codec_mm_dma_flush(colocate_vaddr, buf_size, DMA_TO_DEVICE); - codec_mm_unmap_phyaddr(colocate_vaddr); - } - } - - hw->dpb.colocated_mv_addr_start = - hw->collocate_cma_alloc_addr; -#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF - hw->dpb.colocated_mv_addr_end = - hw->dpb.colocated_mv_addr_start + - (p_H264_Dpb->colocated_buf_size * - active_buffer_spec_num); -#else - hw->dpb.colocated_mv_addr_end = - hw->dpb.colocated_mv_addr_start + - (p_H264_Dpb->colocated_buf_size * - hw->max_reference_size); -#endif - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "callocate cma, %lx, %x\n", - hw->collocate_cma_alloc_addr, - hw->dpb.colocated_mv_addr_start); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "colocated_mv_addr_start %x colocated_mv_addr_end %x\n", - hw->dpb.colocated_mv_addr_start, - hw->dpb.colocated_mv_addr_end); - if (!hw->mmu_enable) { - mutex_lock(&vmh264_mutex); - if (ret >= 0 && hw->decode_pic_count == 0) { - int buf_cnt; - /* h264_reconfig: alloc later*/ - buf_cnt = hw->dpb.mDPB.size; - - for (j = 1; j < buf_cnt; j++) { - i = get_buf_spec_by_canvas_pos(hw, j); - - if (hw->is_used_v4l) { - pr_info("v4l: delay alloc the buffer.\n"); - break; - } else if (alloc_one_buf_spec(hw, i) < 0) - break; - - config_decode_canvas(hw, i); - } - } - mutex_unlock(&vmh264_mutex); - } else { - vh264_config_canvs_for_mmu(hw); - } - - hw->config_bufmgr_done = 1; - - /*end of config_bufmgr_done */ - } - - return ret; -} - -static void vui_config(struct vdec_h264_hw_s *hw) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int aspect_ratio_info_present_flag, aspect_ratio_idc; - /*time*/ - hw->num_units_in_tick = p_H264_Dpb->num_units_in_tick; - hw->time_scale = p_H264_Dpb->time_scale; - hw->timing_info_present_flag = p_H264_Dpb->vui_status & 0x2; - - hw->bitstream_restriction_flag = - p_H264_Dpb->bitstream_restriction_flag; - hw->num_reorder_frames = - p_H264_Dpb->num_reorder_frames; - hw->max_dec_frame_buffering = - p_H264_Dpb->max_dec_frame_buffering; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "vui_config: pdb %d, %d, %d\n", - p_H264_Dpb->bitstream_restriction_flag, - p_H264_Dpb->num_reorder_frames, - p_H264_Dpb->max_dec_frame_buffering); - - hw->fixed_frame_rate_flag = 0; - if (hw->timing_info_present_flag) { - hw->fixed_frame_rate_flag = - p_H264_Dpb->fixed_frame_rate_flag; - - if (hw->is_used_v4l && (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] == I_Slice) && - (hw->num_units_in_tick != 0)) { - if (hw->num_units_in_tick % 1001 == 0) { - int multiple = hw->num_units_in_tick / 1001; - - if (hw->time_scale / multiple == 120000) { - hw->frame_dur = RATE_11990_FPS; - if (hw->fixed_frame_rate_flag == 1) - hw->frame_dur = RATE_5994_FPS; - } else if (hw->time_scale / multiple == 60000) { - hw->frame_dur = RATE_5994_FPS; - if (hw->fixed_frame_rate_flag == 1) - hw->frame_dur = RATE_2997_FPS; - } else if ((hw->time_scale / multiple == 48000) && - (hw->fixed_frame_rate_flag == 1)) { - hw->frame_dur = RATE_2397_FPS; - } else if (hw->time_scale / multiple == 30000) { - hw->frame_dur = RATE_2997_FPS; - } else if (hw->time_scale / multiple == 24000) { - hw->frame_dur = RATE_2397_FPS; - } - } else { - u32 frame_rate = hw->time_scale / hw->num_units_in_tick; - - if (hw->fixed_frame_rate_flag == 1) { - frame_rate = frame_rate / 2; - } - hw->frame_dur = 96000 / frame_rate; - } - } - - if (((hw->num_units_in_tick * 120) >= hw->time_scale && - ((!hw->sync_outside) || - (!hw->frame_dur))) - && hw->num_units_in_tick && hw->time_scale) { - if (hw->use_idr_framerate || - hw->fixed_frame_rate_flag || - !hw->frame_dur || - !hw->duration_from_pts_done - /*|| vh264_running*/) { - u32 frame_dur_es = - div_u64(96000ULL * 2 * hw->num_units_in_tick, - hw->time_scale); - if (hw->frame_dur != frame_dur_es) { - hw->h264_first_valid_pts_ready = false; - hw->h264pts1 = 0; - hw->h264pts2 = 0; - hw->h264_pts_count = 0; - hw->duration_from_pts_done = 0; - fixed_frame_rate_mode = - FIX_FRAME_RATE_OFF; - hw->pts_duration = 0; - hw->frame_dur = frame_dur_es; - if (!hw->fixed_frame_rate_flag && (p_H264_Dpb->mSPS.profile_idc != BASELINE)) { - if (frame_dur_es == 7680) - hw->frame_dur = frame_dur_es /2; - } - vdec_schedule_work(&hw->notify_work); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DEC_DETAIL, - "frame_dur %d from timing_info\n", - hw->frame_dur); - } - - /*hack to avoid use ES frame duration when - *it's half of the rate from system info - * sometimes the encoder is given a wrong - * frame rate but the system side information - * is more reliable - *if ((frame_dur * 2) != frame_dur_es) { - * frame_dur = frame_dur_es; - *} - */ - } - } - } else { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "H.264: timing_info not present\n"); - } - - /*aspect ratio*/ - aspect_ratio_info_present_flag = - p_H264_Dpb->vui_status & 0x1; - aspect_ratio_idc = p_H264_Dpb->aspect_ratio_idc; - - if (aspect_ratio_info_present_flag) { - if (aspect_ratio_idc == EXTEND_SAR) { - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = - p_H264_Dpb->aspect_ratio_sar_height; - hw->width_aspect_ratio = - p_H264_Dpb->aspect_ratio_sar_width; - } else { - /* pr_info("v264dec: aspect_ratio_idc = %d\n", - aspect_ratio_idc); */ - - switch (aspect_ratio_idc) { - case 1: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 1; - break; - case 2: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 12; - break; - case 3: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 10; - break; - case 4: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 16; - break; - case 5: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 33; - hw->width_aspect_ratio = 40; - break; - case 6: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 24; - break; - case 7: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 20; - break; - case 8: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 32; - break; - case 9: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 33; - hw->width_aspect_ratio = 80; - break; - case 10: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 18; - break; - case 11: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 11; - hw->width_aspect_ratio = 15; - break; - case 12: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 33; - hw->width_aspect_ratio = 64; - break; - case 13: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 99; - hw->width_aspect_ratio = 160; - break; - case 14: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 3; - hw->width_aspect_ratio = 4; - break; - case 15: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 2; - hw->width_aspect_ratio = 3; - break; - case 16: - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 2; - break; - default: - if (hw->vh264_ratio >> 16) { - hw->h264_ar = (hw->frame_height * - (hw->vh264_ratio & 0xffff) * - 0x100 + - ((hw->vh264_ratio >> 16) * - hw->frame_width / 2)) / - ((hw->vh264_ratio >> 16) * - hw->frame_width); - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 1; - } else { - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 1; - } - break; - } - } - } else { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "v264dec: aspect_ratio not available from source\n"); - if (hw->vh264_ratio >> 16) { - /* high 16 bit is width, low 16 bit is height */ - hw->h264_ar = - ((hw->vh264_ratio & 0xffff) * - hw->frame_height * 0x100 + - (hw->vh264_ratio >> 16) * - hw->frame_width / 2) / - ((hw->vh264_ratio >> 16) * - hw->frame_width); - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 1; - } else { - hw->h264_ar = 0x3ff; - hw->height_aspect_ratio = 1; - hw->width_aspect_ratio = 1; - } - } - - if (hw->pts_unstable && (hw->fixed_frame_rate_flag == 0)) { - if (((hw->frame_dur == RATE_2397_FPS) - && (dec_control - & DEC_CONTROL_FLAG_FORCE_RATE_2397_FPS_FIX_FRAME_RATE)) - || ((RATE_2997_FPS == - hw->frame_dur) && - (dec_control & - DEC_CONTROL_FLAG_FORCE_RATE_2997_FPS_FIX_FRAME_RATE))) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "force fix frame rate\n"); - hw->fixed_frame_rate_flag = 0x40; - } - } - - /*video_signal_from_vui: to do .. */ -} - -static void bufmgr_recover(struct vdec_h264_hw_s *hw) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 2); - if (hw->error_proc_policy & 0x20) { - if (!hw->is_used_v4l) - hw->reset_bufmgr_flag = 1; - } -} - -void bufmgr_force_recover(struct h264_dpb_stru *p_H264_Dpb) -{ - struct vdec_h264_hw_s *hw = - container_of(p_H264_Dpb, struct vdec_h264_hw_s, dpb); - - dpb_print(DECODE_ID(hw), 0, "call %s\n", __func__); - - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 2); - hw->reset_bufmgr_flag = 1; -} - -#ifdef CONSTRAIN_MAX_BUF_NUM -static int get_vf_ref_only_buf_count(struct vdec_h264_hw_s *hw) -{ - int i; - int count = 0; - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (is_buf_spec_in_disp_q(hw, i) && - hw->buffer_spec[i].vf_ref > 0) - count++; - } - return count; -} - -static int get_used_buf_count(struct vdec_h264_hw_s *hw) -{ - int i; - int count = 0; - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (is_buf_spec_in_use(hw, i)) - count++; - } - return count; -} -#endif - - -static bool is_buffer_available(struct vdec_s *vdec) -{ - bool buffer_available = 1; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - int i, frame_outside_count = 0, inner_size = 0; - if ((kfifo_len(&hw->newframe_q) <= 0) || - ((hw->config_bufmgr_done) && (!have_free_buf_spec(vdec))) || - ((p_H264_Dpb->mDPB.init_done) && - (p_H264_Dpb->mDPB.used_size >= (p_H264_Dpb->mDPB.size - 1)) && - (is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB) == 0))) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s, empty, newq(%d), free_spec(%d), initdon(%d), used_size(%d/%d), unused_fr_dpb(%d)\n", - __func__, - kfifo_len(&hw->newframe_q), - have_free_buf_spec(vdec), - p_H264_Dpb->mDPB.init_done, - p_H264_Dpb->mDPB.used_size, p_H264_Dpb->mDPB.size, - is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB) - ); - buffer_available = 0; - if (dpb_is_debug(DECODE_ID(hw), - DEBUG_DISABLE_RUNREADY_RMBUF)) - return buffer_available; - - if ((hw->error_proc_policy & 0x4) && - (hw->error_proc_policy & 0x8)) { - if ((kfifo_len(&hw->display_q) <= 0) && - (p_H264_Dpb->mDPB.used_size >= - (p_H264_Dpb->mDPB.size - 1)) && - (p_Dpb->ref_frames_in_buffer > - (imax( - 1, p_Dpb->num_ref_frames) - - p_Dpb->ltref_frames_in_buffer + - force_sliding_margin))){ - bufmgr_recover(hw); - } else { - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 1); - } - } else if ((hw->error_proc_policy & 0x4) && - (kfifo_len(&hw->display_q) <= 0) && - ((p_H264_Dpb->mDPB.used_size >= - (p_H264_Dpb->mDPB.size - 1)) || - (!have_free_buf_spec(vdec))) && - (hw->discard_dv_data)) { - unsigned long flags; - spin_lock_irqsave(&hw->bufspec_lock, flags); - - for (i = 0; i < p_Dpb->used_size; i++) { - if (p_Dpb->fs[i]->pre_output) - frame_outside_count++; - else if (p_Dpb->fs[i]->is_output && !is_used_for_reference(p_Dpb->fs[i])) { - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); - return 0; - } - } - spin_unlock_irqrestore(&hw->bufspec_lock, flags); - inner_size = p_Dpb->size - frame_outside_count; - - if (inner_size >= p_H264_Dpb->dec_dpb_size) { - if (p_H264_Dpb->mDPB.used_size >= - p_H264_Dpb->mDPB.size) { - bufmgr_recover(hw); - } else if (p_H264_Dpb->mDPB.used_size >= - (p_H264_Dpb->mDPB.size - 1)) { - if (inner_size > p_H264_Dpb->dec_dpb_size) { - bufmgr_recover(hw); - } - } - } - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); - } else if ((hw->error_proc_policy & 0x8) && - (p_Dpb->ref_frames_in_buffer > - (imax( - 1, p_Dpb->num_ref_frames) - - p_Dpb->ltref_frames_in_buffer + - force_sliding_margin))) - bufmgr_recover(hw); - else - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 1); - - if (hw->reset_bufmgr_flag == 1) - buffer_available = 1; - } - - if (hw->is_used_v4l) - buffer_available = have_free_buf_spec(vdec); - - return buffer_available; -} - -#define AUX_TAG_SEI 0x2 - -#define SEI_BUFFERING_PERIOD 0 -#define SEI_PicTiming 1 -#define SEI_USER_DATA 4 -#define SEI_RECOVERY_POINT 6 - -/* - ************************************************************************* - * Function:Reads bits from the bitstream buffer - * Input: - byte buffer[] - containing sei message data bits - int totbitoffset - bit offset from start of partition - int bytecount - total bytes in bitstream - int numbits - number of bits to read - * Output: - int *info - * Return: - -1: failed - > 0: the count of bit read - * Attention: - ************************************************************************* - */ - -static 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; -} - -static int parse_one_sei_record(struct vdec_h264_hw_s *hw, - u8 *sei_data_buf, - u8 *sei_data_buf_end) -{ - int payload_type; - int payload_size; - u8 *p_sei; - int temp = 0; - int bit_offset; - int read_size; - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - p_sei = sei_data_buf; - read_size = 0; - payload_type = 0; - do { - if (p_sei >= sei_data_buf_end) - return read_size; - - payload_type += *p_sei; - read_size++; - } while (*p_sei++ == 255); - - - payload_size = 0; - do { - if (p_sei >= sei_data_buf_end) - return read_size; - - payload_size += *p_sei; - read_size++; - } while (*p_sei++ == 255); - - - if (p_sei + payload_size > sei_data_buf_end) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s: payload_type = %d, payload_size = %d is over\n", - __func__, payload_type, payload_size); - return read_size; - } - bit_offset = 0; - - if (payload_size <= 0) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "%s warning: this is a null sei message for payload_type = %d\n", - __func__, payload_type); - return read_size; - } - p_H264_Dpb->vui_status = p_H264_Dpb->dpb_param.l.data[VUI_STATUS]; - switch (payload_type) { - case SEI_BUFFERING_PERIOD: - break; - case SEI_PicTiming: - if (p_H264_Dpb->vui_status & 0xc) { - int cpb_removal_delay; - int dpb_output_delay; - u32 delay_len; - - delay_len = p_H264_Dpb->dpb_param.l.data[DELAY_LENGTH]; - cpb_removal_delay - = (delay_len & 0x1F) + 1; - dpb_output_delay - = ((delay_len >> 5) & 0x1F) + 1; - - get_bits(p_sei, bit_offset, - &temp, payload_size, - dpb_output_delay+cpb_removal_delay); - bit_offset += dpb_output_delay+cpb_removal_delay; - } - if (p_H264_Dpb->vui_status & 0x10) { - get_bits(p_sei, bit_offset, &temp, payload_size, 4); - bit_offset += 4; - p_H264_Dpb->dpb_param.l.data[PICTURE_STRUCT] = temp; - } - break; - case SEI_USER_DATA: - if (enable_itu_t35) { - int i; - int j; - int data_len; - u8 *user_data_buf; - - user_data_buf - = hw->sei_itu_data_buf + hw->sei_itu_data_len; - /* user data length should be align with 8 bytes, - if not, then padding with zero*/ - for (i = 0; i < payload_size; i += 8) { - if (hw->sei_itu_data_len + i >= SEI_ITU_DATA_SIZE) - break; // Avoid out-of-bound writing - for (j = 0; j < 8; j++) { - int index; - - index = i+7-j; - if (index >= payload_size) - user_data_buf[i+j] = 0; - else - user_data_buf[i+j] - = p_sei[i+7-j]; - } - } - - data_len = payload_size; - if (payload_size % 8) - data_len = ((payload_size + 8) >> 3) << 3; - - hw->sei_itu_data_len += data_len; - if (hw->sei_itu_data_len >= SEI_ITU_DATA_SIZE) - hw->sei_itu_data_len = SEI_ITU_DATA_SIZE; - /* - dpb_print(DECODE_ID(hw), 0, - "%s: user data, and len = %d:\n", - __func__, hw->sei_itu_data_len); - */ - } - break; - case SEI_RECOVERY_POINT: - p_H264_Dpb->dpb_param.l.data[RECOVERY_POINT] = 1; - break; - } - - return read_size + payload_size; -} - -static void parse_sei_data(struct vdec_h264_hw_s *hw, - u8 *sei_data_buf, - int len) -{ - char *p_sei; - char *p_sei_end; - int parsed_size; - int read_size; - - - p_sei = sei_data_buf; - p_sei_end = p_sei + len; - parsed_size = 0; - while (parsed_size < len) { - read_size = parse_one_sei_record(hw, p_sei, p_sei_end); - p_sei += read_size; - parsed_size += read_size; - if (*p_sei == 0x80) { - p_sei++; - parsed_size++; - } - } -} - -static void check_decoded_pic_error(struct vdec_h264_hw_s *hw) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - struct StorablePicture *p = p_H264_Dpb->mVideo.dec_picture; - unsigned mby_mbx = READ_VREG(MBY_MBX); - unsigned mb_total = (hw->seq_info2 >> 8) & 0xffff; - unsigned mb_width = hw->seq_info2 & 0xff; - unsigned decode_mb_count; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - decode_mb_count = ((mby_mbx & 0xff) * mb_width + - (((mby_mbx >> 8) & 0xff) + 1)); - if ((mby_mbx == 0) && (p_H264_Dpb->dec_dpb_status != H264_SLICE_HEAD_DONE)) { - dpb_print(DECODE_ID(hw), 0, - "mby_mbx is zero\n"); - return; - } - if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME) - mb_total /= 2; - - if ((hw->error_proc_policy & 0x200) && - READ_VREG(ERROR_STATUS_REG) != 0) { - p->data_flag |= ERROR_FLAG; - } - - if (error_proc_policy & 0x100 && !(p->data_flag & ERROR_FLAG)) { - if (decode_mb_count < mb_total) { - p->data_flag |= ERROR_FLAG; - if (((error_proc_policy & 0x20000) && - decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100)) { - p->data_flag &= ~ERROR_FLAG; - } - } - } - - if ((hw->error_proc_policy & 0x100000) && - hw->last_dec_picture && - (hw->last_dec_picture->slice_type == I_SLICE) && - (hw->dpb.mSlice.slice_type == P_SLICE)) { - if ((p->data_flag & ERROR_FLAG) && - (decode_mb_count >= mb_total)) { - hw->ip_field_error_count++; - if (hw->ip_field_error_count == 4) { - unsigned int i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->top_field) - p_Dpb->fs_ref[i]->top_field->data_flag &= ~ERROR_FLAG; - if (p_Dpb->fs_ref[i]->bottom_field) - p_Dpb->fs_ref[i]->bottom_field->data_flag &= ~ERROR_FLAG; - if (p_Dpb->fs_ref[i]->frame) - p_Dpb->fs_ref[i]->frame->data_flag &= ~ERROR_FLAG; - } - hw->ip_field_error_count = 0; - p->data_flag &= ~ERROR_FLAG; - hw->data_flag &= ~ERROR_FLAG; - dpb_print(DECODE_ID(hw), 0, - "clear all ref frame error flag\n"); - } - } else { - if (hw->ip_field_error_count > 0) - dpb_print(DECODE_ID(hw), 0, - "clear error count %d\n", hw->ip_field_error_count); - hw->ip_field_error_count = 0; - } - } - - if (p->data_flag & ERROR_FLAG) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, - "%s: decode error, seq_info2 0x%x, mby_mbx 0x%x, mb_total %d decoded mb_count %d ERROR_STATUS_REG 0x%x\n", - __func__, - hw->seq_info2, - mby_mbx, - mb_total, - decode_mb_count, - READ_VREG(ERROR_STATUS_REG) - ); - - } -} - -static int vh264_pic_done_proc(struct vdec_s *vdec) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int ret; - int i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - if (vdec->mvfrm) - vdec->mvfrm->hw_decode_time = - local_clock() - vdec->mvfrm->hw_decode_start; - - if (input_frame_based(vdec) && - (!(hw->i_only & 0x2)) && - frmbase_cont_bitlevel != 0 && - READ_VREG(VIFF_BIT_CNT) > - frmbase_cont_bitlevel) { - /*handle the case: multi pictures in one packet*/ - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n", - __func__, - hw->decode_pic_count, - READ_VREG(VIFF_BIT_CNT)); - hw->frmbase_cont_flag = 1; - } else - hw->frmbase_cont_flag = 0; - - if (p_H264_Dpb->mVideo.dec_picture) { - get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture); -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - DEL_EXIST(hw, - p_H264_Dpb->mVideo.dec_picture) = 0; - if (vdec->master) { - struct vdec_h264_hw_s *hw_ba = - (struct vdec_h264_hw_s *) - vdec->master->private; - if (hw_ba->last_dec_picture) - DEL_EXIST(hw_ba, - hw_ba->last_dec_picture) - = 1; - } -#endif - mutex_lock(&hw->chunks_mutex); - if (hw->chunk) { - p_H264_Dpb->mVideo.dec_picture->pts = - hw->chunk->pts; - p_H264_Dpb->mVideo.dec_picture->pts64 = - hw->chunk->pts64; - p_H264_Dpb->mVideo.dec_picture->timestamp = - hw->chunk->timestamp; -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - hw->chunk->pts, 1); -#endif - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - } else if (vdec->master) { - /*dv enhance layer, - do not checkout pts*/ - struct StorablePicture *pic = - p_H264_Dpb->mVideo.dec_picture; - pic->pts = 0; - pic->pts64 = 0; -#endif - } else { - struct StorablePicture *pic = - p_H264_Dpb->mVideo.dec_picture; - u32 offset = pic->offset_delimiter; - pic->pic_size = (hw->start_bit_cnt - READ_VREG(VIFF_BIT_CNT)) >> 3; - if (pts_pickout_offset_us64(PTS_TYPE_VIDEO, - offset, &pic->pts, 0, &pic->pts64)) { - pic->pts = 0; - pic->pts64 = 0; -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - pic->pts, 0); -#endif - } else { -#ifdef MH264_USERDATA_ENABLE - vmh264_udc_fill_vpts(hw, - p_H264_Dpb->mSlice.slice_type, - pic->pts, 1); -#endif - } - - } - mutex_unlock(&hw->chunks_mutex); - - check_decoded_pic_error(hw); -#ifdef ERROR_HANDLE_TEST - if ((hw->data_flag & ERROR_FLAG) - && (hw->error_proc_policy & 0x80)) { - release_cur_decoding_buf(hw); - h264_clear_dpb(hw); - hw->dec_flag = 0; - hw->data_flag = 0; - hw->skip_frame_count = 0; - hw->has_i_frame = 0; - hw->no_error_count = 0xfff; - hw->no_error_i_count = 0xf; - } else -#endif - if (hw->error_proc_policy & 0x200000) { - if (!hw->loop_flag) { - for (i = 0; i < p_Dpb->used_size; i++) { - if ((p_H264_Dpb->mVideo.dec_picture->poc + loop_playback_poc_threshold < p_Dpb->fs[i]->poc) && - !p_Dpb->fs[i]->is_output && - !p_Dpb->fs[i]->pre_output) { - hw->loop_flag = 1; - hw->loop_last_poc = p_H264_Dpb->mVideo.dec_picture->poc; - break; - } - } - } else { - if ((p_H264_Dpb->mVideo.dec_picture->poc >= hw->loop_last_poc - poc_threshold) && - (p_H264_Dpb->mVideo.dec_picture->poc <= hw->loop_last_poc + poc_threshold)) { - if (hw->loop_flag >= 5) { - for (i = 0; i < p_Dpb->used_size; i++) { - if ((hw->loop_last_poc + loop_playback_poc_threshold < p_Dpb->fs[i]->poc) && - !p_Dpb->fs[i]->is_output && - !p_Dpb->fs[i]->pre_output) { - p_Dpb->fs[i]->is_output = 1; - } - } - hw->loop_flag = 0; - } else - hw->loop_flag++; - } else - hw->loop_flag = 0; - } - } - p_H264_Dpb->wait_aux_data_flag = ((!hw->discard_dv_data) && (hw->frmbase_cont_flag)); - ret = store_picture_in_dpb(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture, - hw->data_flag | hw->dec_flag | - p_H264_Dpb->mVideo.dec_picture->data_flag); - - - - if (ret == -1) { - release_cur_decoding_buf(hw); - bufmgr_force_recover(p_H264_Dpb); - } else if (ret == -2) { - release_cur_decoding_buf(hw); - } else { - if (hw->data_flag & ERROR_FLAG) { - hw->no_error_count = 0; - hw->no_error_i_count = 0; - } else { - hw->no_error_count++; - if (hw->data_flag & I_FLAG) - hw->no_error_i_count++; - } - if (hw->mmu_enable) - hevc_set_unused_4k_buff_idx(hw, - p_H264_Dpb->mVideo. - dec_picture->buf_spec_num); - bufmgr_post(p_H264_Dpb); - hw->last_dec_picture = - p_H264_Dpb->mVideo.dec_picture; - p_H264_Dpb->mVideo.dec_picture = NULL; - /* dump_dpb(&p_H264_Dpb->mDPB); */ - hw->has_i_frame = 1; - if (hw->mmu_enable) - hevc_set_frame_done(hw); - hw->decode_pic_count++; - p_H264_Dpb->decode_pic_count = hw->decode_pic_count; - if (hw->skip_frame_count > 0) { - /*skip n frame after first I */ - hw->skip_frame_count--; - if (hw->skip_frame_count == 0) - hw->dec_flag &= (~NODISP_FLAG); - } else if (hw->skip_frame_count < -1) { - /*skip n frame after first I until second I */ - hw->skip_frame_count++; - if (hw->skip_frame_count == -1) - hw->dec_flag &= (~NODISP_FLAG); - } - } - } - return 0; -} - -static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq) -{ - int i; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status; - u32 debug_tag; - - if (dec_dpb_status == H264_SLICE_HEAD_DONE || - p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START); - } - else if (dec_dpb_status == H264_PIC_DATA_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START); - } - else if (dec_dpb_status == H264_SEI_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_SEI_START); - else if (dec_dpb_status == H264_AUX_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_AUX_START); - - if (dec_dpb_status == H264_CONFIG_REQUEST) { -#if 1 - unsigned short *p = (unsigned short *)hw->lmem_addr; - for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { - int ii; - for (ii = 0; ii < 4; ii++) { - p_H264_Dpb->dpb_param.l.data[i+ii] = - p[i+3-ii]; - if (dpb_is_debug(DECODE_ID(hw), - RRINT_FLAG_RPM)) { - if (((i + ii) & 0xf) == 0) - dpb_print(DECODE_ID(hw), - 0, "%04x:", - i); - dpb_print_cont(DECODE_ID(hw), - 0, "%04x ", - p[i+3-ii]); - if (((i + ii + 1) & 0xf) == 0) - dpb_print_cont( - DECODE_ID(hw), - 0, "\r\n"); - } - } - } - - if (p_H264_Dpb->bitstream_restriction_flag != - ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)) { - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "p_H264_Dpb->bitstream_restriction_flag 0x%x, new 0x%x\n", - p_H264_Dpb->bitstream_restriction_flag, ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)); - hw->csd_change_flag = 1; - } - p_H264_Dpb->bitstream_restriction_flag = - (p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1; - p_H264_Dpb->num_reorder_frames = - p_H264_Dpb->dpb_param.l.data[NUM_REORDER_FRAMES]; - p_H264_Dpb->max_dec_frame_buffering = - p_H264_Dpb->dpb_param.l.data[MAX_BUFFER_FRAME]; - - dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL, - "H264_CONFIG_REQUEST: pdb %d, %d, %d\n", - p_H264_Dpb->bitstream_restriction_flag, - p_H264_Dpb->num_reorder_frames, - p_H264_Dpb->max_dec_frame_buffering); - hw->bitstream_restriction_flag = - p_H264_Dpb->bitstream_restriction_flag; - hw->num_reorder_frames = - p_H264_Dpb->num_reorder_frames; - hw->max_dec_frame_buffering = - p_H264_Dpb->max_dec_frame_buffering; - - /*crop*/ - p_H264_Dpb->chroma_format_idc = p_H264_Dpb->dpb_param.dpb.chroma_format_idc; - p_H264_Dpb->frame_crop_left_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_left_offset; - p_H264_Dpb->frame_crop_right_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_right_offset; - p_H264_Dpb->frame_crop_top_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_top_offset; - p_H264_Dpb->frame_crop_bottom_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_bottom_offset; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s chroma_format_idc %d crop offset: left %d right %d top %d bottom %d\n", - __func__, p_H264_Dpb->chroma_format_idc, - p_H264_Dpb->frame_crop_left_offset, - p_H264_Dpb->frame_crop_right_offset, - p_H264_Dpb->frame_crop_top_offset, - p_H264_Dpb->frame_crop_bottom_offset); -#endif - - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE); - reset_process_time(hw); - hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->reg_iqidct_control_init_flag = 1; - hw->dec_result = DEC_RESULT_CONFIG_PARAM; -#ifdef DETECT_WRONG_MULTI_SLICE - /*restart check count and set 'unknown'*/ - dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_CONFIG_REQUEST => restart check\n", - __func__, - hw->multi_slice_pic_check_count, - hw->picture_slice_count, - hw->cur_picture_slice_count, - hw->multi_slice_pic_flag); - - hw->multi_slice_pic_check_count = 0; - hw->multi_slice_pic_flag = 0; - hw->picture_slice_count = 0; -#endif - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); - vdec_schedule_work(&hw->work); - } else if (dec_dpb_status == H264_SLICE_HEAD_DONE) { - u16 data_hight; - u16 data_low; - u32 video_signal; - - int slice_header_process_status = 0; - int I_flag; - int frame_num_gap = 0; - union param dpb_param_bak; - /*unsigned char is_idr;*/ - unsigned short *p = (unsigned short *)hw->lmem_addr; - unsigned mb_width = hw->seq_info2 & 0xff; - unsigned short first_mb_in_slice; - unsigned int decode_mb_count, mby_mbx; - struct StorablePicture *pic = p_H264_Dpb->mVideo.dec_picture; - reset_process_time(hw); - hw->frmbase_cont_flag = 0; - - if ((pic != NULL) && (pic->mb_aff_frame_flag == 1)) - first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3] * 2; - else - first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3]; - -#ifdef DETECT_WRONG_MULTI_SLICE - hw->cur_picture_slice_count++; - - if ((hw->error_proc_policy & 0x10000) && - (hw->cur_picture_slice_count > 1) && - (first_mb_in_slice == 0) && - (hw->multi_slice_pic_flag == 0)) - hw->multi_slice_pic_check_count = 0; - - if ((hw->error_proc_policy & 0x10000) && - (hw->cur_picture_slice_count > 1) && - (hw->multi_slice_pic_flag == 1)) { - dpb_print(DECODE_ID(hw), 0, - "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n", - __func__, - hw->multi_slice_pic_check_count, - hw->picture_slice_count, - hw->cur_picture_slice_count, - hw->multi_slice_pic_flag); - - mby_mbx = READ_VREG(MBY_MBX); - decode_mb_count = ((mby_mbx & 0xff) * mb_width + - (((mby_mbx >> 8) & 0xff) + 1)); - - if (first_mb_in_slice == decode_mb_count && - first_mb_in_slice != 0) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s first_mb_in_slice = %d \n", - __func__, first_mb_in_slice); - - hw->multi_slice_pic_flag = 0; - hw->multi_slice_pic_check_count = 0; - } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count) { - vh264_pic_done_proc(vdec); - //if (p_H264_Dpb->mDPB.used_size == p_H264_Dpb->mDPB.size) { - if (!have_free_buf_spec(vdec)) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "dpb full, wait buffer\n"); - p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num; - hw->last_picture_slice_count = hw->cur_picture_slice_count; - hw->no_decoder_buffer_flag = 1; - hw->dec_result = DEC_RESULT_AGAIN; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } - else { - if (p_H264_Dpb->mVideo.dec_picture) { - if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) { - release_colocate_buf(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture->colocated_buf_index); - p_H264_Dpb->mVideo.dec_picture->colocated_buf_index = -1; - } - } - release_cur_decoding_buf(hw); - } - } -#endif - - hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->reg_iqidct_control_init_flag = 1; - hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); - hw->reg_rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); - hw->vld_dec_control = READ_VREG(VLD_DECODE_CONTROL); - if (input_frame_based(vdec) && - frmbase_cont_bitlevel2 != 0 && - READ_VREG(VIFF_BIT_CNT) < - frmbase_cont_bitlevel2 && - hw->get_data_count >= 0x70000000) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s H264_SLICE_HEAD_DONE with small bitcnt %d, goto empty_proc\n", - __func__, - READ_VREG(VIFF_BIT_CNT)); - - goto empty_proc; - } - -#if 0 - if (p_H264_Dpb->mVideo.dec_picture == NULL) { - if (!is_buffer_available(vdec)) { - hw->buffer_empty_flag = 1; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_UCODE_EVT, - "%s, buffer_empty, newframe_q(%d), have_free_buf_spec(%d), init_done(%d), used_size(%d/%d), is_there_unused_frame_from_dpb(%d)\n", - __func__, - kfifo_len(&hw->newframe_q), - have_free_buf_spec(vdec), - p_H264_Dpb->mDPB.init_done, - p_H264_Dpb->mDPB.used_size, - p_H264_Dpb->mDPB.size, - is_there_unused_frame_from_dpb( - &p_H264_Dpb->mDPB)); - return IRQ_HANDLED; - } - } - - hw->buffer_empty_flag = 0; -#endif -#ifdef SEND_PARAM_WITH_REG - for (i = 0; i < (RPM_END-RPM_BEGIN); i++) { - unsigned int data32; - - do { - data32 = READ_VREG(RPM_CMD_REG); - /* printk("%x\n", data32); */ - } while ((data32&0x10000) == 0); - p_H264_Dpb->dpb_param.l.data[i] = data32 & 0xffff; - WRITE_VREG(RPM_CMD_REG, 0); - /* printk("%x:%x\n", i,data32); */ - } -#else - dpb_param_bak = p_H264_Dpb->dpb_param; - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_START); - for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) { - int ii; - - for (ii = 0; ii < 4; ii++) { - p_H264_Dpb->dpb_param.l.data[i+ii] = - p[i+3-ii]; - if (dpb_is_debug(DECODE_ID(hw), - RRINT_FLAG_RPM)) { - if (((i + ii) & 0xf) == 0) - dpb_print(DECODE_ID(hw), - 0, "%04x:", - i); - dpb_print_cont(DECODE_ID(hw), - 0, "%04x ", - p[i+3-ii]); - if (((i + ii + 1) & 0xf) == 0) - dpb_print_cont( - DECODE_ID(hw), - 0, "\r\n"); - } - } - } - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_END); -#endif -#ifdef DETECT_WRONG_MULTI_SLICE - - if (p_H264_Dpb->mVideo.dec_picture && - hw->multi_slice_pic_flag == 2 && - (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] != dpb_param_bak.l.data[SLICE_TYPE] || - dpb_param_bak.l.data[FIRST_MB_IN_SLICE] > p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE])) { - dpb_print(DECODE_ID(hw), 0, - "decode next pic, save before, SLICE_TYPE BAK %d, SLICE_TYPE %d, FIRST_MB_IN_SLICE BAK %d, FIRST_MB_IN_SLICE %d\n", - dpb_param_bak.l.data[SLICE_TYPE], p_H264_Dpb->dpb_param.l.data[SLICE_TYPE], - dpb_param_bak.l.data[FIRST_MB_IN_SLICE], p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]); - vh264_pic_done_proc(vdec); - } -#endif - data_low = p_H264_Dpb->dpb_param.l.data[VIDEO_SIGNAL_LOW]; - data_hight = p_H264_Dpb->dpb_param.l.data[VIDEO_SIGNAL_HIGHT]; - - video_signal = (data_hight << 16) | data_low; - hw->video_signal_from_vui = - ((video_signal & 0xffff) << 8) | - ((video_signal & 0xff0000) >> 16) | - ((video_signal & 0x3f000000)); - - - /*dpb_print(DECODE_ID(hw), - 0, - "video_signal_from_vui:0x%x, " - "data_low:0x%x, data_hight:0x%x\n", - hw->video_signal_from_vui, - data_low, - data_hight);*/ - - parse_sei_data(hw, hw->sei_data_buf, hw->sei_data_len); - - if (hw->config_bufmgr_done == 0) { - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_UCODE_EVT, - "config_bufmgr not done, discard frame\n"); - return IRQ_HANDLED; - } else if ((hw->first_i_policy & 0x3) != 0) { - unsigned char is_i_slice = - (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] - == I_Slice) - ? 1 : 0; - unsigned char is_idr = - ((p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f) - == 5); - if ((hw->first_i_policy & 0x3) == 0x3) - is_i_slice = is_idr; - if (!is_i_slice) { - if (hw->has_i_frame == 0) { - amvdec_stop(); - vdec->mc_loaded = 0; - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - dpb_print(DECODE_ID(hw), - PRINT_FLAG_UCODE_EVT, - "has_i_frame is 0, discard none I(DR) frame silce_type %d is_idr %d\n", p_H264_Dpb->dpb_param.l.data[SLICE_TYPE], is_idr); - return IRQ_HANDLED; - } - } else { - if (hw->skip_frame_count < 0 || is_idr) { - /* second I */ - hw->dec_flag &= (~NODISP_FLAG); - hw->skip_frame_count = 0; - } - if (hw->has_i_frame == 0 && - (!is_idr)) { - int skip_count = - (hw->first_i_policy >> 8) & 0xff; - /* first I (not IDR) */ - if ((hw->first_i_policy & 0x3) == 2) - hw->skip_frame_count = - -1 - skip_count; - else - hw->skip_frame_count = - skip_count; - if (hw->skip_frame_count != 0) - hw->dec_flag |= NODISP_FLAG; - } - } - } - dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "current dpb index %d, poc %d, top/bot poc (%d,%d)\n", - p_H264_Dpb->dpb_param.dpb.current_dpb_index, - val(p_H264_Dpb->dpb_param.dpb.frame_pic_order_cnt), - val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt), - val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt)); - I_flag = (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] == I_Slice) - ? I_FLAG : 0; - - if ((hw->i_only & 0x2) && (I_flag & I_FLAG)) - flush_dpb(p_H264_Dpb); - - if ((hw->i_only & 0x2) && (!(I_flag & I_FLAG)) && - (p_H264_Dpb->mSlice.structure == FRAME)) { - hw->data_flag = NULL_FLAG; - goto pic_done_proc; - } - - slice_header_process_status = - h264_slice_header_process(p_H264_Dpb, &frame_num_gap); - if (hw->mmu_enable) - hevc_sao_set_slice_type(hw, - slice_header_process_status, - hw->dpb.mSlice.idr_flag); - vui_config(hw); - - if (slice_header_process_status == -1) { - amvdec_stop(); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - - if (p_H264_Dpb->mVideo.dec_picture) { - int cfg_ret = 0; - bool field_pic_flag = false; - unsigned mby_mbx = READ_VREG(MBY_MBX); - struct StorablePicture *p = - p_H264_Dpb->mVideo.dec_picture; - - if (slice_header_process_status == 1) { - if (!p_H264_Dpb->mSPS.frame_mbs_only_flag) { - field_pic_flag = - (p_H264_Dpb->mSlice.structure == TOP_FIELD || - p_H264_Dpb->mSlice.structure == BOTTOM_FIELD) ? - true : false; - } - - vdec_set_profile_level(vdec, p_H264_Dpb->mSPS.profile_idc, - p_H264_Dpb->mSPS.level_idc); - - if (!field_pic_flag && (((p_H264_Dpb->mSPS.profile_idc == BASELINE) && - (p_H264_Dpb->dec_dpb_size < 2)) || - (((unsigned long)(hw->vh264_amstream_dec_info - .param)) & 0x8) || hw->low_latency_mode & 0x8)) { - p_H264_Dpb->fast_output_enable = - H264_OUTPUT_MODE_FAST; - } - else - p_H264_Dpb->fast_output_enable - = fast_output_enable; - if (hw->enable_fence) - p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST; - - hw->data_flag = I_flag; - if ((p_H264_Dpb-> - dpb_param.dpb.NAL_info_mmco & 0x1f) - == 5) - hw->data_flag |= IDR_FLAG; - if ((p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]) && !mby_mbx) { - p->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_VDEC_STATUS, - "one slice error in muulti-slice first_mb 0x%x mby_mbx 0x%x slice_type %d\n", - p_H264_Dpb->dpb_param.l. - data[FIRST_MB_IN_SLICE], - READ_VREG(MBY_MBX), - p->slice_type); - } - dpb_print(DECODE_ID(hw), - PRINT_FLAG_VDEC_STATUS, - "==================> frame count %d to skip %d\n", - hw->decode_pic_count+1, - hw->skip_frame_count); - } else if (hw->error_proc_policy & 0x100){ - unsigned decode_mb_count = - ((mby_mbx & 0xff) * hw->mb_width + - (((mby_mbx >> 8) & 0xff) + 1)); - if (decode_mb_count < - ((p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]) * - (1 + p->mb_aff_frame_flag)) && decode_mb_count) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_VDEC_STATUS, - "Error detect! first_mb 0x%x mby_mbx 0x%x decode_mb 0x%x\n", - p_H264_Dpb->dpb_param.l. - data[FIRST_MB_IN_SLICE], - READ_VREG(MBY_MBX), - decode_mb_count); - p->data_flag |= ERROR_FLAG; - }/* else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) { - p->data_flag |= ERROR_FLAG; - goto pic_done_proc; - }*/ - } - - if (!I_flag && frame_num_gap && !p_H264_Dpb->long_term_reference_flag) { - if (!(hw->error_proc_policy & 0x800000)) { - hw->data_flag |= ERROR_FLAG; - p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), 0, "frame number gap error\n"); - } - } - - if (hw->error_proc_policy & 0x400) { - int ret = dpb_check_ref_list_error(p_H264_Dpb); - if (ret != 0) { - hw->reflist_error_count ++; - dpb_print(DECODE_ID(hw), 0, - "reference list error %d frame count %d to skip %d reflist_error_count %d\n", - ret, - hw->decode_pic_count+1, - hw->skip_frame_count, - hw->reflist_error_count); - - p_H264_Dpb->mVideo.dec_picture->data_flag = NODISP_FLAG; - if (((hw->error_proc_policy & 0x80) - && ((hw->dec_flag & - NODISP_FLAG) == 0)) ||(hw->reflist_error_count > 50)) { - hw->reset_bufmgr_flag = 1; - hw->reflist_error_count =0; - amvdec_stop(); - vdec->mc_loaded = 0; - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } else - hw->reflist_error_count = 0; - } - if ((hw->error_proc_policy & 0x800) && (!(hw->i_only & 0x2)) - && p_H264_Dpb->dpb_error_flag != 0) { - dpb_print(DECODE_ID(hw), 0, - "dpb error %d\n", - p_H264_Dpb->dpb_error_flag); - hw->data_flag |= ERROR_FLAG; - p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; - if ((hw->error_proc_policy & 0x80) && - ((hw->dec_flag & NODISP_FLAG) == 0)) { - hw->reset_bufmgr_flag = 1; - amvdec_stop(); - vdec->mc_loaded = 0; - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - } - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_START); - cfg_ret = config_decode_buf(hw, - p_H264_Dpb->mVideo.dec_picture); - ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_END); - if (cfg_ret < 0) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "config_decode_buf fail (%d)\n", - cfg_ret); - if (hw->error_proc_policy & 0x2) { - release_cur_decoding_buf(hw); - /*hw->data_flag |= ERROR_FLAG;*/ - hw->reset_bufmgr_flag = 1; - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } else - hw->data_flag |= ERROR_FLAG; - p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG; - } - } - - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END); - - if (slice_header_process_status == 1) - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_NEWPIC); - else - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_SLICE); - hw->last_mby_mbx = 0; - hw->last_vld_level = 0; - start_process_time(hw); - } else if (dec_dpb_status == H264_PIC_DATA_DONE - ||((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) { -#ifdef DETECT_WRONG_MULTI_SLICE - dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_PIC_DATA_DONE\n", - __func__, - hw->multi_slice_pic_check_count, - hw->picture_slice_count, - hw->cur_picture_slice_count, - hw->multi_slice_pic_flag); - - if (hw->multi_slice_pic_check_count < check_slice_num) { - hw->multi_slice_pic_check_count++; - if (hw->cur_picture_slice_count != - hw->picture_slice_count) { - /*restart check count and set 'unknown'*/ - hw->multi_slice_pic_check_count = 0; - hw->multi_slice_pic_flag = 0; - } - hw->picture_slice_count = - hw->cur_picture_slice_count; - } else if (hw->multi_slice_pic_check_count >= check_slice_num) { - if (hw->picture_slice_count > 1) - hw->multi_slice_pic_flag = 2; - else - hw->multi_slice_pic_flag = 1; - } -#endif - -pic_done_proc: - reset_process_time(hw); - if ((dec_dpb_status == H264_SEARCH_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_TIMEOUT) || - ((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) { - hw->data_flag |= ERROR_FLAG; - if (hw->dpb.mVideo.dec_picture) - hw->dpb.mVideo.dec_picture->data_flag |= ERROR_FLAG; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s, mark err_frame\n", __func__); - } - vh264_pic_done_proc(vdec); - - if (hw->frmbase_cont_flag) { - bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0); - if (!have_free_buf_spec(vdec)) { - hw->dec_result = DEC_RESULT_NEED_MORE_BUFFER; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } - /*do not DEC_RESULT_GET_DATA*/ - hw->get_data_count = 0x7fffffff; - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); - decode_frame_count[DECODE_ID(hw)]++; - if (p_H264_Dpb->mSlice.slice_type == I_SLICE) { - hw->gvs.i_decoded_frames++; - } else if (p_H264_Dpb->mSlice.slice_type == P_SLICE) { - hw->gvs.p_decoded_frames++; - } else if (p_H264_Dpb->mSlice.slice_type == B_SLICE) { - hw->gvs.b_decoded_frames++; - } - start_process_time(hw); - return IRQ_HANDLED; - } - amvdec_stop(); - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s %s decode slice count %d\n", - __func__, - (dec_dpb_status == H264_PIC_DATA_DONE) ? - "H264_PIC_DATA_DONE" : - (dec_dpb_status == H264_FIND_NEXT_PIC_NAL) ? - "H264_FIND_NEXT_PIC_NAL" : "H264_FIND_NEXT_DVEL_NAL", - hw->decode_pic_count); - if (hw->kpi_first_i_decoded == 0) { - hw->kpi_first_i_decoded = 1; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "[vdec_kpi][%s] First I frame decoded.\n", __func__); - } - /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); */ - hw->dec_result = DEC_RESULT_DONE; -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (vdec->slave && - dec_dpb_status == H264_FIND_NEXT_DVEL_NAL) { - struct vdec_h264_hw_s *hw_el = - (struct vdec_h264_hw_s *)(vdec->slave->private); - hw_el->got_valid_nal = 0; - hw->switch_dvlayer_flag = 1; - } else if (vdec->master && - dec_dpb_status == H264_FIND_NEXT_PIC_NAL) { - struct vdec_h264_hw_s *hw_bl = - (struct vdec_h264_hw_s *)(vdec->master->private); - hw_bl->got_valid_nal = 0; - hw->switch_dvlayer_flag = 1; - } else { - hw->switch_dvlayer_flag = 0; - hw->got_valid_nal = 1; - } -#endif - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); - - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - } else if ( - (dec_dpb_status == H264_FIND_NEXT_PIC_NAL) || - (dec_dpb_status == H264_FIND_NEXT_DVEL_NAL)) { - goto pic_done_proc; -#endif - } else if (dec_dpb_status == H264_AUX_DATA_READY) { - reset_process_time(hw); - if (READ_VREG(H264_AUX_DATA_SIZE) != 0) { - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FLAG_SEI_DETAIL)) - dump_aux_buf(hw); -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (vdec_frame_based(vdec)) { - if (hw->last_dec_picture) - set_aux_data(hw, - hw->last_dec_picture, 0, 0, NULL); - } else if (vdec->dolby_meta_with_el || vdec->slave) { - if (hw->last_dec_picture) - set_aux_data(hw, hw->last_dec_picture, - 0, 0, NULL); - } else { - if (vdec->master) { - struct vdec_h264_hw_s *hw_bl = - (struct vdec_h264_hw_s *) - (vdec->master->private); - if (hw_bl->last_dec_picture != NULL) { - set_aux_data(hw_bl, - hw_bl->last_dec_picture, - 0, 1, hw); - } - set_aux_data(hw, - hw->last_dec_picture, - 0, 2, NULL); - } - } -#else - if (hw->last_dec_picture) - set_aux_data(hw, - hw->last_dec_picture, 0, 0, NULL); -#endif - } -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - hw->switch_dvlayer_flag = 0; - hw->got_valid_nal = 1; -#endif - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s H264_AUX_DATA_READY\n", __func__); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - } else if (/*(dec_dpb_status == H264_DATA_REQUEST) ||*/ - (dec_dpb_status == H264_SEARCH_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_BUFEMPTY) || - (dec_dpb_status == H264_DECODE_TIMEOUT)) { -empty_proc: - reset_process_time(hw); - if ((hw->error_proc_policy & 0x40000) && - ((dec_dpb_status == H264_DECODE_TIMEOUT) || - (!hw->frmbase_cont_flag && (dec_dpb_status == H264_SEARCH_BUFEMPTY || dec_dpb_status == H264_DECODE_BUFEMPTY) && input_frame_based(vdec)))) - goto pic_done_proc; - if (!hw->frmbase_cont_flag) - release_cur_decoding_buf(hw); - - if (input_frame_based(vdec) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) { - if (h264_debug_flag & - DISABLE_ERROR_HANDLE) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, - "%s decoding error, level 0x%x\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - goto send_again; - } - amvdec_stop(); - vdec->mc_loaded = 0; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s %s\n", __func__, - (dec_dpb_status == H264_SEARCH_BUFEMPTY) ? - "H264_SEARCH_BUFEMPTY" : - (dec_dpb_status == H264_DECODE_BUFEMPTY) ? - "H264_DECODE_BUFEMPTY" : - (dec_dpb_status == H264_DECODE_TIMEOUT) ? - "H264_DECODE_TIMEOUT" : - "OTHER"); - hw->dec_result = DEC_RESULT_DONE; - - if (dec_dpb_status == H264_SEARCH_BUFEMPTY) - hw->search_dataempty_num++; - else if (dec_dpb_status == H264_DECODE_TIMEOUT) { - hw->decode_timeout_num++; - if (hw->error_proc_policy & 0x4000) { - hw->data_flag |= ERROR_FLAG; - if ((p_H264_Dpb->last_dpb_status == H264_DECODE_TIMEOUT) || - (p_H264_Dpb->last_dpb_status == H264_PIC_DATA_DONE) || - ((p_H264_Dpb->last_dpb_status == H264_SLICE_HEAD_DONE) && - (p_H264_Dpb->mSlice.slice_type != B_SLICE))) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, "%s last dpb status 0x%x need bugmgr reset \n", - p_H264_Dpb->last_dpb_status, __func__); - hw->reset_bufmgr_flag = 1; - } - } - } else if (dec_dpb_status == H264_DECODE_BUFEMPTY) - hw->decode_dataempty_num++; - if (!hw->frmbase_cont_flag) - hw->data_flag |= ERROR_FLAG; - - vdec_schedule_work(&hw->work); - } else { - /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */ -#ifdef DETECT_WRONG_MULTI_SLICE - if (hw->error_proc_policy & 0x10000) { - p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num; - } - hw->last_picture_slice_count = hw->cur_picture_slice_count; -#endif - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_AGAIN\n", __func__); -send_again: - hw->dec_result = DEC_RESULT_AGAIN; - vdec_schedule_work(&hw->work); - } - } else if (dec_dpb_status == H264_DATA_REQUEST) { - reset_process_time(hw); - if (input_frame_based(vdec)) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_VDEC_STATUS, - "%s H264_DATA_REQUEST (%d)\n", - __func__, hw->get_data_count); - hw->dec_result = DEC_RESULT_GET_DATA; - hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->reg_iqidct_control_init_flag = 1; - hw->get_data_start_time = jiffies; - hw->get_data_count++; - if (hw->get_data_count >= frame_max_data_packet) - goto empty_proc; - vdec_schedule_work(&hw->work); - } else - goto empty_proc; - } else if (dec_dpb_status == H264_DECODE_OVER_SIZE) { - dpb_print(DECODE_ID(hw), 0, - "vmh264 decode oversize !!\n"); - release_cur_decoding_buf(hw); - hw->data_flag |= ERROR_FLAG; - hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; - reset_process_time(hw); - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - return IRQ_HANDLED; - } else if (dec_dpb_status == H264_SEI_DATA_READY) { - int aux_data_len; - aux_data_len = - (READ_VREG(H264_AUX_DATA_SIZE) >> 16) << 4; - - if (aux_data_len > SEI_DATA_SIZE) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR, - "sei data size more than 4K: %d, discarded it\n", - hw->sei_itu_data_len); - hw->sei_itu_data_len = 0; - } - - if (aux_data_len != 0) { - u8 *trans_data_buf; - u8 *sei_data_buf; - u8 swap_byte; - -#if 0 - dump_aux_buf(hw); -#endif - trans_data_buf = (u8 *)hw->aux_addr; - - if (trans_data_buf[7] == AUX_TAG_SEI) { - int left_len; - - sei_data_buf = (u8 *)hw->sei_data_buf - + hw->sei_data_len; - left_len = SEI_DATA_SIZE - hw->sei_data_len; - if (aux_data_len/2 <= left_len) { - for (i = 0; i < aux_data_len/2; i++) - sei_data_buf[i] - = trans_data_buf[i*2]; - - aux_data_len = aux_data_len / 2; - for (i = 0; i < aux_data_len; i = i+4) { - swap_byte = sei_data_buf[i]; - sei_data_buf[i] - = sei_data_buf[i+3]; - sei_data_buf[i+3] = swap_byte; - - swap_byte = sei_data_buf[i+1]; - sei_data_buf[i+1] - = sei_data_buf[i+2]; - sei_data_buf[i+2] = swap_byte; - } - - for (i = aux_data_len-1; i >= 0; i--) - if (sei_data_buf[i] != 0) - break; - - hw->sei_data_len += i+1; - } else - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, - "sei data size %d and more than left space: %d, discarded it\n", - hw->sei_itu_data_len, - left_len); - } - } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN); - WRITE_VREG(DPB_STATUS_REG, H264_SEI_DATA_DONE); - - return IRQ_HANDLED; - } - - - /* ucode debug */ - debug_tag = READ_VREG(DEBUG_REG1); - if (debug_tag & 0x10000) { - unsigned short *p = (unsigned short *)hw->lmem_addr; - - dpb_print(DECODE_ID(hw), 0, - "LMEM<tag %x>:\n", debug_tag); - for (i = 0; i < 0x400; i += 4) { - int ii; - if ((i & 0xf) == 0) - dpb_print_cont(DECODE_ID(hw), 0, - "%03x: ", i); - for (ii = 0; ii < 4; ii++) - dpb_print_cont(DECODE_ID(hw), 0, - "%04x ", p[i+3-ii]); - if (((i+ii) & 0xf) == 0) - dpb_print_cont(DECODE_ID(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) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "dbg%x: %x\n", debug_tag, - READ_VREG(DEBUG_REG2)); - 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; - } - if (hw->ucode_pause_pos) - reset_process_time(hw); - else - WRITE_VREG(DEBUG_REG1, 0); - } - /**/ - return IRQ_HANDLED; -} - -static irqreturn_t vh264_isr(struct vdec_s *vdec, int irq) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - if (!hw) - return IRQ_HANDLED; - - if (hw->eos) - return IRQ_HANDLED; - - p_H264_Dpb->vdec = vdec; - p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG); - - if (p_H264_Dpb->dec_dpb_status == H264_SLICE_HEAD_DONE || - p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE); - } - else if (p_H264_Dpb->dec_dpb_status == H264_PIC_DATA_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE); - } - else if (p_H264_Dpb->dec_dpb_status == H264_SEI_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_SEI_DONE); - else if (p_H264_Dpb->dec_dpb_status == H264_AUX_DATA_READY) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_AUX_DONE); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT, - "%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n", - __func__, - p_H264_Dpb->dec_dpb_status, - run_count[DECODE_ID(hw)], - hw->dec_result, - READ_VREG(ERROR_STATUS_REG), - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VIFF_BIT_CNT), - READ_VREG(MBY_MBX)); - - ATRACE_COUNTER("V_ST_DEC-decode_state", p_H264_Dpb->dec_dpb_status); - - if (p_H264_Dpb->dec_dpb_status == H264_WRRSP_REQUEST) { - if (hw->mmu_enable) - hevc_sao_wait_done(hw); - WRITE_VREG(DPB_STATUS_REG, H264_WRRSP_DONE); - return IRQ_HANDLED; - } - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END); - return IRQ_WAKE_THREAD; - -} - -static void timeout_process(struct vdec_h264_hw_s *hw) -{ - struct vdec_s *vdec = hw_to_vdec(hw); - - /* - * In this very timeout point,the vh264_work arrives, - * or in some cases the system become slow, then come - * this second timeout. In both cases we return. - */ - if (work_pending(&hw->work) || - work_busy(&hw->work) || - work_busy(&hw->timeout_work) || - work_pending(&hw->timeout_work)) { - pr_err("%s h264[%d] work pending, do nothing.\n",__func__, vdec->id); - return; - } - - hw->timeout_num++; - amvdec_stop(); - vdec->mc_loaded = 0; - if (hw->mmu_enable) { - hevc_set_frame_done(hw); - hevc_sao_wait_done(hw); - } - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, "%s decoder timeout, DPB_STATUS_REG 0x%x\n", __func__, READ_VREG(DPB_STATUS_REG)); - release_cur_decoding_buf(hw); - hw->dec_result = DEC_RESULT_TIMEOUT; - hw->data_flag |= ERROR_FLAG; - - if (work_pending(&hw->work)) - return; - vdec_schedule_work(&hw->timeout_work); -} - -static void dump_bufspec(struct vdec_h264_hw_s *hw, - const char *caller) -{ - int i; - dpb_print(DECODE_ID(hw), 0, - "%s in %s:\n", __func__, caller); - for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { - if (hw->buffer_spec[i].used == -1) - continue; - dpb_print(DECODE_ID(hw), 0, - "bufspec (%d): used %d adr 0x%x(%lx) canvas(%d) vf_ref(%d) ", - i, hw->buffer_spec[i].used, - hw->buffer_spec[i].buf_adr, - hw->buffer_spec[i].cma_alloc_addr, - hw->buffer_spec[i].canvas_pos, - hw->buffer_spec[i].vf_ref - ); -#ifdef CONFIG_AM_VDEC_DV - dpb_print_cont(DECODE_ID(hw), 0, - "dv_el_exist %d", - hw->buffer_spec[i].dv_enhance_exist - ); -#endif - dpb_print_cont(DECODE_ID(hw), 0, "\n"); - } - -} - -static void vmh264_dump_state(struct vdec_s *vdec) -{ - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - dpb_print(DECODE_ID(hw), 0, - "====== %s\n", __func__); - dpb_print(DECODE_ID(hw), 0, - "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d signal_type 0x%x send_err %d\n", - hw->frame_width, - hw->frame_height, - hw->num_reorder_frames, - hw->dpb.dec_dpb_size, - hw->dpb.mDPB.size, - hw->max_reference_size, - hw->i_only, - hw->video_signal_type, - hw->send_error_frame_flag - ); - - dpb_print(DECODE_ID(hw), 0, - "is_framebase(%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 bufmgr_reset_cnt %d error_frame_count = %d, drop_frame_count = %d\n", - input_frame_based(vdec), - hw->eos, - hw->stat, - hw->dec_result, - decode_frame_count[DECODE_ID(hw)], - display_frame_count[DECODE_ID(hw)], - run_count[DECODE_ID(hw)], - not_run_ready[DECODE_ID(hw)], - input_empty[DECODE_ID(hw)], - hw->reset_bufmgr_count, - hw->gvs.error_frame_count, - hw->gvs.drop_frame_count - ); - -#ifdef DETECT_WRONG_MULTI_SLICE - dpb_print(DECODE_ID(hw), 0, - "MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d)\n", - hw->multi_slice_pic_check_count, - hw->picture_slice_count, - hw->cur_picture_slice_count, - hw->multi_slice_pic_flag); -#endif - if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) { - enum receviver_start_e state = - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_QUREY_STATE, - NULL); - dpb_print(DECODE_ID(hw), 0, - "\nreceiver(%s) state %d\n", - vdec->vf_provider_name, - state); - } - - dpb_print(DECODE_ID(hw), 0, - "%s, newq(%d/%d), dispq(%d/%d) vf prepare/get/put (%d/%d/%d), free_spec(%d), initdon(%d), used_size(%d/%d), unused_fr_dpb(%d) fast_output_enable %x \n", - __func__, - kfifo_len(&hw->newframe_q), - VF_POOL_SIZE, - kfifo_len(&hw->display_q), - VF_POOL_SIZE, - hw->vf_pre_count, - hw->vf_get_count, - hw->vf_put_count, - have_free_buf_spec(vdec), - p_H264_Dpb->mDPB.init_done, - p_H264_Dpb->mDPB.used_size, p_H264_Dpb->mDPB.size, - is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB), - p_H264_Dpb->fast_output_enable - ); - - dump_dpb(&p_H264_Dpb->mDPB, 1); - dump_pic(p_H264_Dpb); - dump_bufspec(hw, __func__); - - dpb_print(DECODE_ID(hw), 0, - "DPB_STATUS_REG=0x%x\n", - READ_VREG(DPB_STATUS_REG)); - dpb_print(DECODE_ID(hw), 0, - "MPC_E=0x%x\n", - READ_VREG(MPC_E)); - dpb_print(DECODE_ID(hw), 0, - "H264_DECODE_MODE=0x%x\n", - READ_VREG(H264_DECODE_MODE)); - dpb_print(DECODE_ID(hw), 0, - "MBY_MBX=0x%x\n", - READ_VREG(MBY_MBX)); - dpb_print(DECODE_ID(hw), 0, - "H264_DECODE_SIZE=0x%x\n", - READ_VREG(H264_DECODE_SIZE)); - dpb_print(DECODE_ID(hw), 0, - "VIFF_BIT_CNT=0x%x\n", - READ_VREG(VIFF_BIT_CNT)); - dpb_print(DECODE_ID(hw), 0, - "VLD_MEM_VIFIFO_LEVEL=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - dpb_print(DECODE_ID(hw), 0, - "VLD_MEM_VIFIFO_WP=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_WP)); - dpb_print(DECODE_ID(hw), 0, - "VLD_MEM_VIFIFO_RP=0x%x\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - dpb_print(DECODE_ID(hw), 0, - "PARSER_VIDEO_RP=0x%x\n", - STBUF_READ(&vdec->vbuf, get_rp)); - dpb_print(DECODE_ID(hw), 0, - "PARSER_VIDEO_WP=0x%x\n", - STBUF_READ(&vdec->vbuf, get_wp)); - - if (input_frame_based(vdec) && - dpb_is_debug(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA) - ) { - int jj; - if (hw->chunk && hw->chunk->block && - hw->chunk->size > 0) { - u8 *data = NULL; - - if (!hw->chunk->block->is_mapped) - data = codec_mm_vmap(hw->chunk->block->start + - hw->chunk->offset, hw->chunk->size); - else - data = ((u8 *)hw->chunk->block->start_virt) - + hw->chunk->offset; - - dpb_print(DECODE_ID(hw), 0, - "frame data size 0x%x\n", - hw->chunk->size); - for (jj = 0; jj < hw->chunk->size; jj++) { - if ((jj & 0xf) == 0) - dpb_print(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "%06x:", jj); - dpb_print_cont(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - dpb_print_cont(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "\n"); - } - - if (!hw->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); - } - } -} - - -static void check_timer_func(struct timer_list *timer) -{ - struct vdec_h264_hw_s *hw = container_of(timer, - struct vdec_h264_hw_s, check_timer); - struct vdec_s *vdec = hw_to_vdec(hw); - int error_skip_frame_count = error_skip_count & 0xfff; - unsigned int timeout_val = decode_timeout_val; - if (timeout_val != 0 && - hw->no_error_count < error_skip_frame_count) - timeout_val = errordata_timeout_val; - if ((h264_debug_cmd & 0x100) != 0 && - DECODE_ID(hw) == (h264_debug_cmd & 0xff)) { - hw->dec_result = DEC_RESULT_DONE; - vdec_schedule_work(&hw->work); - pr_info("vdec %d is forced to be disconnected\n", - h264_debug_cmd & 0xff); - h264_debug_cmd = 0; - return; - } - if ((h264_debug_cmd & 0x200) != 0 && - DECODE_ID(hw) == (h264_debug_cmd & 0xff)) { - pr_debug("vdec %d is forced to reset bufmgr\n", - h264_debug_cmd & 0xff); - hw->reset_bufmgr_flag = 1; - h264_debug_cmd = 0; - return; - } - - if (vdec->next_status == VDEC_STATUS_DISCONNECTED && - !hw->is_used_v4l) { - hw->dec_result = DEC_RESULT_FORCE_EXIT; - vdec_schedule_work(&hw->work); - pr_debug("vdec requested to be disconnected\n"); - return; - } - - 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 (((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) && - (timeout_val > 0) && - (hw->start_process_time > 0) && - ((1000 * (jiffies - hw->start_process_time) / HZ) - > timeout_val) - ) { - u32 dpb_status = READ_VREG(DPB_STATUS_REG); - u32 mby_mbx = READ_VREG(MBY_MBX); - if ((dpb_status == H264_ACTION_DECODE_NEWPIC) || - (dpb_status == H264_ACTION_DECODE_SLICE) || - (dpb_status == H264_SEI_DATA_DONE) || - (dpb_status == H264_STATE_SEARCH_HEAD) || - (dpb_status == H264_SLICE_HEAD_DONE) || - (dpb_status == H264_SEI_DATA_READY)) { - if (h264_debug_flag & DEBUG_TIMEOUT_DEC_STAT) - pr_debug("%s dpb_status = 0x%x last_mby_mbx = %u mby_mbx = %u\n", - __func__, dpb_status, hw->last_mby_mbx, mby_mbx); - - if (hw->last_mby_mbx == mby_mbx) { - if (hw->decode_timeout_count > 0) - hw->decode_timeout_count--; - if (hw->decode_timeout_count == 0) - { - reset_process_time(hw); - timeout_process(hw); - } - } else - start_process_time(hw); - } else if (is_in_parsing_state(dpb_status)) { - if (hw->last_vld_level == - READ_VREG(VLD_MEM_VIFIFO_LEVEL)) { - if (hw->decode_timeout_count > 0) - hw->decode_timeout_count--; - if (hw->decode_timeout_count == 0) - { - reset_process_time(hw); - timeout_process(hw); - } - } - } - hw->last_vld_level = - READ_VREG(VLD_MEM_VIFIFO_LEVEL); - hw->last_mby_mbx = mby_mbx; - } - - if ((hw->ucode_pause_pos != 0) && - (hw->ucode_pause_pos != 0xffffffff) && - udebug_pause_pos != hw->ucode_pause_pos) { - hw->ucode_pause_pos = 0; - WRITE_VREG(DEBUG_REG1, 0); - } - - mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); -} - -static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) -{ - u32 ar, ar_tmp; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - if (!hw) - return -1; - - vstatus->frame_width = hw->frame_width; - vstatus->frame_height = hw->frame_height; - if (hw->error_frame_width && - hw->error_frame_height) { - vstatus->frame_width = hw->error_frame_width; - vstatus->frame_height = hw->error_frame_height; - } - if (hw->frame_dur != 0) { - vstatus->frame_dur = hw->frame_dur; - vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ? - 96000 / hw->frame_dur : (96000 / hw->frame_dur +1); - } - else - vstatus->frame_rate = -1; - vstatus->error_count = hw->gvs.error_frame_count; - vstatus->status = hw->stat; - if (hw->h264_ar == 0x3ff) - ar_tmp = (0x100 * - hw->frame_height * hw->height_aspect_ratio) / - (hw->frame_width * hw->width_aspect_ratio); - else - ar_tmp = hw->h264_ar; - ar = min_t(u32, - ar_tmp, - DISP_RATIO_ASPECT_RATIO_MAX); - vstatus->ratio_control = - ar << DISP_RATIO_ASPECT_RATIO_BIT; - - vstatus->error_frame_count = hw->gvs.error_frame_count; - vstatus->drop_frame_count = hw->gvs.drop_frame_count; - vstatus->frame_count = decode_frame_count[DECODE_ID(hw)]; - vstatus->i_decoded_frames = hw->gvs.i_decoded_frames; - vstatus->i_lost_frames = hw->gvs.i_lost_frames; - vstatus->i_concealed_frames = hw->gvs.i_concealed_frames; - vstatus->p_decoded_frames = hw->gvs.p_decoded_frames; - vstatus->p_lost_frames = hw->gvs.p_lost_frames; - vstatus->p_concealed_frames = hw->gvs.p_concealed_frames; - vstatus->b_decoded_frames = hw->gvs.b_decoded_frames; - vstatus->b_lost_frames = hw->gvs.b_lost_frames; - vstatus->b_concealed_frames = hw->gvs.b_concealed_frames; - snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), - "%s-%02d", DRIVER_NAME, hw->id); - - return 0; -} - -static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw) -{ - int i, j; - struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; - hw->frmbase_cont_flag = 0; - - /* if (hw->init_flag == 0) { */ - if (h264_debug_flag & 0x40000000) { - /* if (1) */ - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s, reset register\n", __func__); - - while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) - ; - while (READ_VREG(LMEM_DMA_CTRL) & 0x8000) - ; /* reg address is 0x350 */ - -#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); - READ_VREG(DOS_SW_RESET0); - 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); - - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - -#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 - WRITE_VREG(POWER_CTL_VLD, - READ_VREG(POWER_CTL_VLD) | (0 << 10) | - (1 << 9) | (1 << 6)); - } else { - /* WRITE_VREG(POWER_CTL_VLD, - * READ_VREG(POWER_CTL_VLD) | (0 << 10) | (1 << 9) ); - */ - WRITE_VREG(POWER_CTL_VLD, - READ_VREG(POWER_CTL_VLD) | - (0 << 10) | (1 << 9) | (1 << 6)); - } - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17); -#endif - - /* cbcr_merge_swap_en */ - if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - else - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - } else { - if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) || - (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M)) - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - else - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16); - } - - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24); - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24); - - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); - if (hw->mmu_enable) { - SET_VREG_MASK(MDEC_PIC_DC_MUX_CTRL, 1<<31); - /* sw reset to extif hardware */ - SET_VREG_MASK(MDEC_EXTIF_CFG1, 1<<30); - CLEAR_VREG_MASK(MDEC_EXTIF_CFG1, 1<<30); - } else { - CLEAR_VREG_MASK(MDEC_PIC_DC_MUX_CTRL, 1 << 31); - WRITE_VREG(MDEC_EXTIF_CFG1, 0); - } - - -#if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - /* pr_info("vh264 meson8 prot init\n"); */ - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); -#endif - -#ifdef VDEC_DW - if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) { - if (IS_VDEC_DW(hw)) { - u32 data = ((1 << 30) |(1 << 0) |(1 << 8)); - - if (IS_VDEC_DW(hw) == 2) - data |= (1 << 9); - WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/ - } - } -#endif - if (hw->dpb.mDPB.size > 0) { - WRITE_VREG(AV_SCRATCH_7, (hw->max_reference_size << 24) | - (hw->dpb.mDPB.size << 16) | - (hw->dpb.mDPB.size << 8)); - - for (j = 0; j < hw->dpb.mDPB.size; j++) { - i = get_buf_spec_by_canvas_pos(hw, j); - if (i < 0) - break; - - if (!hw->mmu_enable && - hw->buffer_spec[i].cma_alloc_addr) - config_decode_canvas(hw, i); - if (hw->mmu_enable && hw->double_write_mode) - config_decode_canvas_ex(hw, i); - } - } else { - WRITE_VREG(AV_SCRATCH_0, 0); - WRITE_VREG(AV_SCRATCH_9, 0); - } - - if (hw->init_flag == 0) - WRITE_VREG(DPB_STATUS_REG, 0); - else - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_START); - - WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count); - WRITE_VREG(AV_SCRATCH_8, hw->buf_offset); - if (!tee_enabled()) - WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle); - - /* hw->error_recovery_mode = (error_recovery_mode != 0) ? - * error_recovery_mode : error_recovery_mode_in; - */ - /* WRITE_VREG(AV_SCRATCH_F, - * (READ_VREG(AV_SCRATCH_F) & 0xffffffc3) ); - */ - WRITE_VREG(AV_SCRATCH_F, (hw->save_reg_f & 0xffffffc3) | - ((error_recovery_mode_in & 0x1) << 4)); - /*if (hw->ucode_type == UCODE_IP_ONLY_PARAM) - SET_VREG_MASK(AV_SCRATCH_F, 1 << 6); - else*/ - CLEAR_VREG_MASK(AV_SCRATCH_F, 1 << 6); - - WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr); -#if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); -#endif - - WRITE_VREG(DEBUG_REG1, 0); - WRITE_VREG(DEBUG_REG2, 0); - - /*Because CSD data is not found at playback start, - the IQIDCT_CONTROL register is not saved, - the initialized value 0x200 of IQIDCT_CONTROL is set*/ - if (hw->init_flag && (hw->reg_iqidct_control_init_flag == 0)) - WRITE_VREG(IQIDCT_CONTROL, 0x200); - - if (hw->reg_iqidct_control) - WRITE_VREG(IQIDCT_CONTROL, hw->reg_iqidct_control); - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "IQIDCT_CONTROL = 0x%x\n", READ_VREG(IQIDCT_CONTROL)); - - if (hw->reg_vcop_ctrl_reg) - WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg); - if (hw->vld_dec_control) - WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_dec_control); - return 0; -} - -static int vmh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) -{ - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *)vdec->private; - if (i_only_flag & 0x100) - return 0; - if (trickmode == TRICKMODE_I) - hw->i_only = 0x3; - else if (trickmode == TRICKMODE_NONE) - hw->i_only = 0x0; - return 0; -} - -static unsigned char amvdec_enable_flag; -static void vh264_local_init(struct vdec_h264_hw_s *hw, bool is_reset) -{ - int i; - hw->init_flag = 0; - hw->first_sc_checked= 0; - hw->eos = 0; - hw->valve_count = 0; - hw->config_bufmgr_done = 0; - hw->start_process_time = 0; - hw->has_i_frame = 0; - hw->no_error_count = 0xfff; - hw->no_error_i_count = 0xf; - - hw->dec_flag = 0; - hw->data_flag = 0; - hw->skip_frame_count = 0; - hw->reg_iqidct_control = 0; - hw->reg_iqidct_control_init_flag = 0; - hw->reg_vcop_ctrl_reg = 0; - hw->reg_rv_ai_mb_count = 0; - hw->vld_dec_control = 0; - hw->decode_timeout_count = 0; - hw->no_mem_count = 0; - hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio; - /* vh264_ratio = 0x100; */ - - hw->vh264_rotation = (((unsigned long) - hw->vh264_amstream_dec_info.param) >> 16) & 0xffff; - - hw->frame_prog = 0; - hw->frame_width = hw->vh264_amstream_dec_info.width; - hw->frame_height = hw->vh264_amstream_dec_info.height; - hw->frame_dur = hw->vh264_amstream_dec_info.rate; - hw->pts_outside = ((unsigned long) - hw->vh264_amstream_dec_info.param) & 0x01; - hw->sync_outside = ((unsigned long) - hw->vh264_amstream_dec_info.param & 0x02) >> 1; - hw->use_idr_framerate = ((unsigned long) - hw->vh264_amstream_dec_info.param & 0x04) >> 2; - hw->max_refer_buf = !(((unsigned long) - hw->vh264_amstream_dec_info.param & 0x10) >> 4); - if (hw->frame_dur < 96000/960) { - /*more than 960fps,it should not be a correct value, - *give default 30fps - */ - hw->frame_dur = 96000/30; - } - - hw->unstable_pts = (((unsigned long) hw->vh264_amstream_dec_info.param & 0x40) >> 6); - - hw->first_i_policy = first_i_policy; - - pr_info("H264 sysinfo: %dx%d duration=%d, pts_outside=%d\n", - hw->frame_width, hw->frame_height, hw->frame_dur, hw->pts_outside); - pr_debug("sync_outside=%d, use_idr_framerate=%d, is_used_v4l: %d\n", - hw->sync_outside, hw->use_idr_framerate, hw->is_used_v4l); - - if (i_only_flag & 0x100) - hw->i_only = i_only_flag & 0xff; - if (hw->i_only) - hw->dpb.first_insert_frame = FirstInsertFrm_SKIPDONE; - - if ((unsigned long) hw->vh264_amstream_dec_info.param - & 0x08) - hw->no_poc_reorder_flag = 1; - - error_recovery_mode_in = 1; /*ucode control?*/ - if (hw->error_proc_policy & 0x80000000) - hw->send_error_frame_flag = hw->error_proc_policy & 0x1; - else if ((unsigned long) hw->vh264_amstream_dec_info.param & 0x20) - hw->send_error_frame_flag = 0; /*Don't display mark err frames*/ - - if (!is_reset) { - INIT_KFIFO(hw->display_q); - INIT_KFIFO(hw->newframe_q); - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]); - hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */ - hw->vfpool[hw->cur_pool][i].bufWidth = 1920; - kfifo_put(&hw->newframe_q, vf); - } - } - - hw->duration_from_pts_done = 0; - - hw->p_last_vf = NULL; - hw->vh264_stream_switching_state = SWITCHING_STATE_OFF; - hw->hevc_cur_buf_idx = 0xffff; - - init_waitqueue_head(&hw->wait_q); - - return; -} - -static s32 vh264_init(struct vdec_h264_hw_s *hw) -{ - int size = -1; - int fw_size = 0x1000 * 16; - int fw_mmu_size = 0x1000 * 16; - struct firmware_s *fw = NULL, *fw_mmu = NULL; - - /* int trickmode_fffb = 0; */ - - /* pr_info("\nvh264_init\n"); */ - /* init_timer(&hw->recycle_timer); */ - - /* timer init */ - timer_setup(&hw->check_timer, check_timer_func, 0); - hw->check_timer.expires = jiffies + CHECK_INTERVAL; - - /* add_timer(&hw->check_timer); */ - hw->stat |= STAT_TIMER_ARM; - hw->stat |= STAT_ISR_REG; - - mutex_init(&hw->chunks_mutex); - vh264_local_init(hw, false); - INIT_WORK(&hw->work, vh264_work); - INIT_WORK(&hw->notify_work, vh264_notify_work); - INIT_WORK(&hw->timeout_work, vh264_timeout_work); -#ifdef MH264_USERDATA_ENABLE - INIT_WORK(&hw->user_data_ready_work, user_data_ready_notify_work); -#endif - - /*if (!amvdec_enable_flag) { - amvdec_enable_flag = true; - amvdec_enable(); - if (hw->mmu_enable) - amhevc_enable(); - }*/ - if (hw->mmu_enable) { - - hw->frame_mmu_map_addr = - dma_alloc_coherent(amports_get_dma_device(), - FRAME_MMU_MAP_SIZE, - &hw->frame_mmu_map_phy_addr, GFP_KERNEL); - if (hw->frame_mmu_map_addr == NULL) { - pr_err("%s: failed to alloc count_buffer\n", __func__); - return -ENOMEM; - } - } - - fw = vmalloc(sizeof(struct firmware_s) + fw_size); - if (IS_ERR_OR_NULL(fw)) - return -ENOMEM; - - size = get_firmware_data(VIDEO_DEC_H264_MULTI, fw->data); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(fw); - return -1; - } - - fw->len = size; - hw->fw = fw; - - if (hw->mmu_enable) { - fw_mmu = vmalloc(sizeof(struct firmware_s) + fw_mmu_size); - if (IS_ERR_OR_NULL(fw_mmu)) - return -ENOMEM; - - size = get_firmware_data(VIDEO_DEC_H264_MULTI_MMU, fw_mmu->data); - if (size < 0) { - pr_err("get mmu fw fail.\n"); - vfree(fw_mmu); - return -1; - } - - fw_mmu->len = size; - hw->fw_mmu = fw_mmu; - } - - if (!tee_enabled()) { - /* -- ucode loading (amrisc and swap code) */ - hw->mc_cpu_addr = - dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE, - &hw->mc_dma_handle, GFP_KERNEL); - if (!hw->mc_cpu_addr) { - amvdec_enable_flag = false; - amvdec_disable(); - hw->vdec_pg_enable_flag = 0; - if (hw->mmu_enable) - amhevc_disable(); - pr_info("vh264_init: Can not allocate mc memory.\n"); - return -ENOMEM; - } - - /*pr_info("264 ucode swap area: phyaddr %p, cpu vaddr %p\n", - (void *)hw->mc_dma_handle, hw->mc_cpu_addr); - */ - - /*ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf);*/ - - /*header*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_HEADER, - fw->data + 0x4000, MC_SWAP_SIZE); - /*data*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_DATA, - fw->data + 0x2000, MC_SWAP_SIZE); - /*mmco*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MMCO, - fw->data + 0x6000, MC_SWAP_SIZE); - /*list*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_LIST, - fw->data + 0x3000, MC_SWAP_SIZE); - /*slice*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_SLICE, - fw->data + 0x5000, MC_SWAP_SIZE); - /*main*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN, - fw->data, 0x2000); - /*data*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x2000, - fw->data + 0x2000, 0x1000); - /*slice*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x3000, - fw->data + 0x5000, 0x1000); - } - -#if 1 /* #ifdef BUFFER_MGR_IN_C */ - hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(), - PAGE_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL); - - if (hw->lmem_addr == 0) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - return -1; - } - pr_debug("%s, phy_addr=%lx vaddr=%p\n", - __func__, hw->lmem_phy_addr, (void *)hw->lmem_addr); - - if (prefix_aux_buf_size > 0 || - suffix_aux_buf_size > 0) { - u32 aux_buf_size; - hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size); - hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size); - aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size; - hw->aux_addr = dma_alloc_coherent(amports_get_dma_device(), - aux_buf_size, &hw->aux_phy_addr, - GFP_KERNEL); - if (hw->aux_addr == NULL) { - pr_err("%s: failed to alloc rpm buffer\n", __func__); - return -1; - } - - hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL); - if (hw->sei_data_buf == NULL) { - pr_err("%s: failed to alloc sei itu data buffer\n", - __func__); - return -1; - } - hw->sei_itu_data_buf = kmalloc(SEI_ITU_DATA_SIZE, GFP_KERNEL); - if (hw->sei_itu_data_buf == NULL) { - pr_err("%s: failed to alloc sei itu data buffer\n", - __func__); - dma_free_coherent(amports_get_dma_device(), - hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, - hw->aux_phy_addr); - hw->aux_addr = NULL; - kfree(hw->sei_data_buf); - hw->sei_data_buf = NULL; - - return -1; - } - - if (NULL == hw->sei_user_data_buffer) { - hw->sei_user_data_buffer = kmalloc(USER_DATA_SIZE, - GFP_KERNEL); - if (!hw->sei_user_data_buffer) { - pr_info("%s: Can not allocate sei_data_buffer\n", - __func__); - dma_free_coherent(amports_get_dma_device(), - hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, - hw->aux_phy_addr); - hw->aux_addr = NULL; - kfree(hw->sei_data_buf); - hw->sei_data_buf = NULL; - kfree(hw->sei_itu_data_buf); - hw->sei_itu_data_buf = NULL; - - return -1; - } - hw->sei_user_data_wp = 0; - } - } -/* BUFFER_MGR_IN_C */ -#endif - hw->stat |= STAT_MC_LOAD; - - /* add memory barrier */ - wmb(); - - return 0; -} - -static int vh264_stop(struct vdec_h264_hw_s *hw) -{ - if (hw->stat & STAT_VDEC_RUN) { - amvdec_stop(); - hw->stat &= ~STAT_VDEC_RUN; - } -#ifdef VDEC_DW - WRITE_VREG(MDEC_DOUBLEW_CFG0, 0); - WRITE_VREG(MDEC_DOUBLEW_CFG1, 0); -#endif -#ifdef MH264_USERDATA_ENABLE - cancel_work_sync(&hw->user_data_ready_work); -#endif - cancel_work_sync(&hw->notify_work); - cancel_work_sync(&hw->timeout_work); - cancel_work_sync(&hw->work); - - if (hw->stat & STAT_MC_LOAD) { - if (hw->mc_cpu_addr != NULL) { - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, hw->mc_cpu_addr, - hw->mc_dma_handle); - hw->mc_cpu_addr = NULL; - } - if (hw->frame_mmu_map_addr != NULL) { - dma_free_coherent(amports_get_dma_device(), - FRAME_MMU_MAP_SIZE, hw->frame_mmu_map_addr, - hw->frame_mmu_map_phy_addr); - hw->frame_mmu_map_addr = NULL; - } - - } - if (hw->stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)hw); - hw->stat &= ~STAT_ISR_REG; - } - if (hw->lmem_addr) { - dma_free_coherent(amports_get_dma_device(), - PAGE_SIZE, (void *)hw->lmem_addr, - hw->lmem_phy_addr); - hw->lmem_addr = 0; - } - - if (hw->aux_addr) { - dma_free_coherent(amports_get_dma_device(), - hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr, - hw->aux_phy_addr); - hw->aux_addr = NULL; - } - if (hw->sei_data_buf != NULL) { - kfree(hw->sei_data_buf); - hw->sei_data_buf = NULL; - } - if (hw->sei_itu_data_buf != NULL) { - kfree(hw->sei_itu_data_buf); - hw->sei_itu_data_buf = NULL; - } - if (hw->sei_user_data_buffer != NULL) { - kfree(hw->sei_user_data_buffer); - hw->sei_user_data_buffer = NULL; - } - /* amvdec_disable(); */ - - vfree(hw->fw); - hw->fw = NULL; - - if (hw->mmu_enable) { - vfree(hw->fw_mmu); - hw->fw_mmu = NULL; - } - - dpb_print(DECODE_ID(hw), 0, - "%s\n", - __func__); - return 0; -} - -static void wait_vmh264_search_done(struct vdec_h264_hw_s *hw) -{ - u32 vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP); - int count = 0; - do { - usleep_range(100, 500); - if (vld_rp == READ_VREG(VLD_MEM_VIFIFO_RP)) - break; - if (count > 2000) { - dpb_print(DECODE_ID(hw), - PRINT_FLAG_ERROR, "%s timeout count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n", - __func__, count, vld_rp, READ_VREG(VLD_MEM_VIFIFO_RP)); - break; - } else - vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP); - count++; - } while (1); -} - -static void vh264_notify_work(struct work_struct *work) -{ - struct vdec_h264_hw_s *hw = container_of(work, - struct vdec_h264_hw_s, notify_work); - struct vdec_s *vdec = hw_to_vdec(hw); - - if (hw->is_used_v4l) - return; - - if (vdec->fr_hint_state == VDEC_NEED_HINT) { - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)hw->frame_dur)); - vdec->fr_hint_state = VDEC_HINTED; - } - - return; -} - -#ifdef MH264_USERDATA_ENABLE -static void vmh264_reset_udr_mgr(struct vdec_h264_hw_s *hw) -{ - hw->wait_for_udr_send = 0; - hw->sei_itu_data_len = 0; - memset(&hw->ud_record, 0, sizeof(hw->ud_record)); -} - -static void vmh264_crate_userdata_manager( - struct vdec_h264_hw_s *hw, - u8 *userdata_buf, - int buf_len) -{ - if (hw) { - - - mutex_init(&hw->userdata_mutex); - - memset(&hw->userdata_info, 0, - sizeof(struct mh264_userdata_info_t)); - hw->userdata_info.data_buf = userdata_buf; - hw->userdata_info.buf_len = buf_len; - hw->userdata_info.data_buf_end = userdata_buf + buf_len; - - vmh264_reset_udr_mgr(hw); - - } -} - -static void vmh264_destroy_userdata_manager(struct vdec_h264_hw_s *hw) -{ - if (hw) - memset(&hw->userdata_info, - 0, - sizeof(struct mh264_userdata_info_t)); -} - -/* -#define DUMP_USERDATA_RECORD -*/ -#ifdef DUMP_USERDATA_RECORD - -#define MAX_USER_DATA_SIZE 3145728 -static void *user_data_buf; -static unsigned char *pbuf_start; -static int total_len; -static int bskip; -static int n_userdata_id; - -static void print_data(unsigned char *pdata, - int len, - unsigned int poc_number, - unsigned int flag, - unsigned int duration, - unsigned int vpts, - unsigned int vpts_valid, - int rec_id) -{ - int nLeft; - - nLeft = len; -#if 0 - pr_info("%d len:%d, flag:%d, dur:%d, vpts:0x%x, valid:%d, poc:%d\n", - rec_id, len, flag, - duration, vpts, vpts_valid, poc_number); -#endif - pr_info("%d len = %d, flag = %d, vpts = 0x%x\n", - rec_id, len, flag, vpts); - - if (len == 96) { - int i; - nLeft = 72; - while (nLeft >= 16) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x %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], - pdata[8], pdata[9], pdata[10], pdata[11], - pdata[12], pdata[13], pdata[14], pdata[15]); - nLeft -= 16; - pdata += 16; - } - - - while (nLeft > 0) { - 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; - } - - i = 0; - nLeft = 96-72; - while (i < nLeft) { - if (pdata[0] != 0) { - pr_info("some data error\n"); - break; - } - pdata++; - i++; - } - } else { - while (nLeft >= 16) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x %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], - pdata[8], pdata[9], pdata[10], pdata[11], - pdata[12], pdata[13], pdata[14], pdata[15]); - nLeft -= 16; - pdata += 16; - } - - - while (nLeft > 0) { - 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; - } - - } -} - -static void push_to_buf(struct vdec_h264_hw_s *hw, - u8 *pdata, - int len, - struct userdata_meta_info_t *pmeta); - -static void dump_userdata_record(struct vdec_h264_hw_s *hw, - struct mh264_userdata_record_t *record) -{ - if (record && hw) { - u8 *pdata; - - pdata = hw->userdata_info.data_buf + record->rec_start; -/* - print_data(pdata, - record->rec_len, - record->meta_info.flags, - record->meta_info.duration, - record->meta_info.vpts, - record->meta_info.vpts_valid, - n_record_id); -*/ - push_to_buf(hw, pdata, record->rec_len, &record->meta_info); - n_userdata_id++; - } -} - - -static void push_to_buf(struct vdec_h264_hw_s *hw, - u8 *pdata, int len, - struct userdata_meta_info_t *pmeta) -{ - u32 *pLen; - int info_cnt; - u8 *pbuf_end; - - if (!user_data_buf) - return; - - if (bskip) { - pr_info("over size, skip\n"); - return; - } - info_cnt = 0; - pLen = (u32 *)pbuf_start; - - *pLen = len; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - *pLen = pmeta->poc_number; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - *pLen = pmeta->duration; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - *pLen = pmeta->flags; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - *pLen = pmeta->vpts; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - *pLen = pmeta->vpts_valid; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - - *pLen = n_userdata_id; - pbuf_start += sizeof(u32); - info_cnt++; - pLen++; - - - - pbuf_end = (u8 *)hw->sei_user_data_buffer + USER_DATA_SIZE; - if (pdata + len > pbuf_end) { - int first_section_len; - - first_section_len = pbuf_end - pdata; - memcpy(pbuf_start, pdata, first_section_len); - pdata = (u8 *)hw->sei_user_data_buffer; - pbuf_start += first_section_len; - memcpy(pbuf_start, pdata, len - first_section_len); - pbuf_start += len - first_section_len; - } else { - memcpy(pbuf_start, pdata, len); - pbuf_start += len; - } - - total_len += len + info_cnt * sizeof(u32); - if (total_len >= MAX_USER_DATA_SIZE-4096) - bskip = 1; -} - -static void show_user_data_buf(void) -{ - u8 *pbuf; - int len; - unsigned int flag; - unsigned int duration; - unsigned int vpts; - unsigned int vpts_valid; - unsigned int poc_number; - int rec_id; - - pr_info("show user data buf\n"); - pbuf = user_data_buf; - - while (pbuf < pbuf_start) { - u32 *pLen; - - pLen = (u32 *)pbuf; - - len = *pLen; - pLen++; - pbuf += sizeof(u32); - - poc_number = *pLen; - pLen++; - pbuf += sizeof(u32); - - duration = *pLen; - pLen++; - pbuf += sizeof(u32); - - flag = *pLen; - pLen++; - pbuf += sizeof(u32); - - vpts = *pLen; - pLen++; - pbuf += sizeof(u32); - - vpts_valid = *pLen; - pLen++; - pbuf += sizeof(u32); - - rec_id = *pLen; - pLen++; - pbuf += sizeof(u32); - - print_data(pbuf, len, poc_number, flag, - duration, vpts, - vpts_valid, rec_id); - pbuf += len; - msleep(30); - } -} - -static int vmh264_init_userdata_dump(void) -{ - user_data_buf = kmalloc(MAX_USER_DATA_SIZE, GFP_KERNEL); - if (user_data_buf) - return 1; - else - return 0; -} - -static void vmh264_dump_userdata(void) -{ - if (user_data_buf) { - show_user_data_buf(); - kfree(user_data_buf); - user_data_buf = NULL; - } -} - -static void vmh264_reset_user_data_buf(void) -{ - total_len = 0; - pbuf_start = user_data_buf; - bskip = 0; - n_userdata_id = 0; -} -#endif - - -static void vmh264_udc_fill_vpts(struct vdec_h264_hw_s *hw, - int frame_type, - u32 vpts, - u32 vpts_valid) -{ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - unsigned char *pdata; - u8 *pmax_sei_data_buffer; - u8 *sei_data_buf; - int i; - int wp; - int data_length; - struct mh264_userdata_record_t *p_userdata_rec; - - -#ifdef MH264_USERDATA_ENABLE - struct userdata_meta_info_t meta_info; - memset(&meta_info, 0, sizeof(meta_info)); -#endif - - if (hw->sei_itu_data_len <= 0) - return; - - pdata = (u8 *)hw->sei_user_data_buffer + hw->sei_user_data_wp; - pmax_sei_data_buffer = (u8 *)hw->sei_user_data_buffer + USER_DATA_SIZE; - sei_data_buf = (u8 *)hw->sei_itu_data_buf; - for (i = 0; i < hw->sei_itu_data_len; i++) { - *pdata++ = sei_data_buf[i]; - if (pdata >= pmax_sei_data_buffer) - pdata = (u8 *)hw->sei_user_data_buffer; - } - - hw->sei_user_data_wp = (hw->sei_user_data_wp - + hw->sei_itu_data_len) % USER_DATA_SIZE; - hw->sei_itu_data_len = 0; - -#ifdef MH264_USERDATA_ENABLE - meta_info.duration = hw->frame_dur; - meta_info.flags |= (VFORMAT_H264 << 3); - - meta_info.vpts = vpts; - meta_info.vpts_valid = vpts_valid; - meta_info.poc_number = - p_H264_Dpb->mVideo.dec_picture->poc; - - - wp = hw->sei_user_data_wp; - - if (hw->sei_user_data_wp > hw->userdata_info.last_wp) - data_length = wp - hw->userdata_info.last_wp; - else - data_length = wp + hw->userdata_info.buf_len - - hw->userdata_info.last_wp; - - if (data_length & 0x7) - data_length = (((data_length + 8) >> 3) << 3); - - p_userdata_rec = &hw->ud_record; - p_userdata_rec->meta_info = meta_info; - p_userdata_rec->rec_start = hw->userdata_info.last_wp; - p_userdata_rec->rec_len = data_length; - hw->userdata_info.last_wp = wp; - - p_userdata_rec->meta_info.flags |= - p_H264_Dpb->mVideo.dec_picture->pic_struct << 12; - - hw->wait_for_udr_send = 1; - vdec_schedule_work(&hw->user_data_ready_work); -#endif -} - - -static void user_data_ready_notify_work(struct work_struct *work) -{ - struct vdec_h264_hw_s *hw = container_of(work, - struct vdec_h264_hw_s, user_data_ready_work); - - - mutex_lock(&hw->userdata_mutex); - - hw->userdata_info.records[hw->userdata_info.write_index] - = hw->ud_record; - hw->userdata_info.write_index++; - if (hw->userdata_info.write_index >= USERDATA_FIFO_NUM) - hw->userdata_info.write_index = 0; - - mutex_unlock(&hw->userdata_mutex); - -#ifdef DUMP_USERDATA_RECORD - dump_userdata_record(hw, &hw->ud_record); -#endif - vdec_wakeup_userdata_poll(hw_to_vdec(hw)); - - hw->wait_for_udr_send = 0; -} - -static int vmh264_user_data_read(struct vdec_s *vdec, - struct userdata_param_t *puserdata_para) -{ - struct vdec_h264_hw_s *hw = NULL; - int rec_ri, rec_wi; - int rec_len; - u8 *rec_data_start; - u8 *pdest_buf; - struct mh264_userdata_record_t *p_userdata_rec; - u32 data_size; - u32 res; - int copy_ok = 1; - - hw = (struct vdec_h264_hw_s *)vdec->private; - - pdest_buf = puserdata_para->pbuf_addr; - - mutex_lock(&hw->userdata_mutex); - -/* - pr_info("ri = %d, wi = %d\n", - lg_p_mpeg12_userdata_info->read_index, - lg_p_mpeg12_userdata_info->write_index); -*/ - rec_ri = hw->userdata_info.read_index; - rec_wi = hw->userdata_info.write_index; - - if (rec_ri == rec_wi) { - mutex_unlock(&hw->userdata_mutex); - return 0; - } - - p_userdata_rec = hw->userdata_info.records + rec_ri; - - rec_len = p_userdata_rec->rec_len; - rec_data_start = p_userdata_rec->rec_start + hw->userdata_info.data_buf; -/* - pr_info("rec_len:%d, rec_start:%d, buf_len:%d\n", - p_userdata_rec->rec_len, - p_userdata_rec->rec_start, - puserdata_para->buf_len); -*/ - if (rec_len <= puserdata_para->buf_len) { - /* dvb user data buffer is enought to - copy the whole recored. */ - data_size = rec_len; - if (rec_data_start + data_size - > hw->userdata_info.data_buf_end) { - int first_section_len; - - first_section_len = hw->userdata_info.buf_len - - p_userdata_rec->rec_start; - res = (u32)copy_to_user((void *)pdest_buf, - (void *)rec_data_start, - first_section_len); - if (res) { - pr_info("p1 read not end res=%d, request=%d\n", - res, first_section_len); - copy_ok = 0; - - p_userdata_rec->rec_len -= - first_section_len - res; - p_userdata_rec->rec_start += - first_section_len - res; - puserdata_para->data_size = - first_section_len - res; - } else { - res = (u32)copy_to_user( - (void *)(pdest_buf+first_section_len), - (void *)hw->userdata_info.data_buf, - data_size - first_section_len); - if (res) { - pr_info("p2 read not end res=%d, request=%d\n", - res, data_size); - copy_ok = 0; - } - p_userdata_rec->rec_len -= - data_size - res; - p_userdata_rec->rec_start = - data_size - first_section_len - res; - puserdata_para->data_size = - data_size - res; - } - } else { - res = (u32)copy_to_user((void *)pdest_buf, - (void *)rec_data_start, - data_size); - if (res) { - pr_info("p3 read not end res=%d, request=%d\n", - res, data_size); - copy_ok = 0; - } - p_userdata_rec->rec_len -= data_size - res; - p_userdata_rec->rec_start += data_size - res; - puserdata_para->data_size = data_size - res; - } - - if (copy_ok) { - hw->userdata_info.read_index++; - if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM) - hw->userdata_info.read_index = 0; - } - } else { - /* dvb user data buffer is not enought - to copy the whole recored. */ - data_size = puserdata_para->buf_len; - if (rec_data_start + data_size - > hw->userdata_info.data_buf_end) { - int first_section_len; - - first_section_len = hw->userdata_info.buf_len - - p_userdata_rec->rec_start; - res = (u32)copy_to_user((void *)pdest_buf, - (void *)rec_data_start, - first_section_len); - if (res) { - pr_info("p4 read not end res=%d, request=%d\n", - res, first_section_len); - copy_ok = 0; - p_userdata_rec->rec_len -= - first_section_len - res; - p_userdata_rec->rec_start += - first_section_len - res; - puserdata_para->data_size = - first_section_len - res; - } else { - /* first secton copy is ok*/ - res = (u32)copy_to_user( - (void *)(pdest_buf+first_section_len), - (void *)hw->userdata_info.data_buf, - data_size - first_section_len); - if (res) { - pr_info("p5 read not end res=%d, request=%d\n", - res, - data_size - first_section_len); - copy_ok = 0; - } - - p_userdata_rec->rec_len -= - data_size - res; - p_userdata_rec->rec_start = - data_size - first_section_len - res; - puserdata_para->data_size = - data_size - res; - } - } else { - res = (u32)copy_to_user((void *)pdest_buf, - (void *)rec_data_start, - data_size); - if (res) { - pr_info("p6 read not end res=%d, request=%d\n", - res, data_size); - copy_ok = 0; - } - - p_userdata_rec->rec_len -= data_size - res; - p_userdata_rec->rec_start += data_size - res; - puserdata_para->data_size = data_size - res; - } - - if (copy_ok) { - hw->userdata_info.read_index++; - if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM) - hw->userdata_info.read_index = 0; - } - - } - puserdata_para->meta_info = p_userdata_rec->meta_info; - - if (hw->userdata_info.read_index <= hw->userdata_info.write_index) - puserdata_para->meta_info.records_in_que = - hw->userdata_info.write_index - - hw->userdata_info.read_index; - else - puserdata_para->meta_info.records_in_que = - hw->userdata_info.write_index + - USERDATA_FIFO_NUM - - hw->userdata_info.read_index; - - puserdata_para->version = (0<<24|0<<16|0<<8|1); - - mutex_unlock(&hw->userdata_mutex); - - return 1; -} - -static void vmh264_reset_userdata_fifo(struct vdec_s *vdec, int bInit) -{ - struct vdec_h264_hw_s *hw = NULL; - - hw = (struct vdec_h264_hw_s *)vdec->private; - - if (hw) { - mutex_lock(&hw->userdata_mutex); - pr_info("vmh264_reset_userdata_fifo: bInit: %d, ri: %d, wi: %d\n", - bInit, - hw->userdata_info.read_index, - hw->userdata_info.write_index); - hw->userdata_info.read_index = 0; - hw->userdata_info.write_index = 0; - - if (bInit) - hw->userdata_info.last_wp = 0; - mutex_unlock(&hw->userdata_mutex); - } -} - -static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec) -{ - amstream_wakeup_userdata_poll(vdec); -} - -#endif - -static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw, - u32 param1, u32 param2, u32 param3, u32 param4, - struct aml_vdec_ps_infos *ps) -{ -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - struct vdec_s *vdec = hw_to_vdec(hw); -#endif - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - struct vdec_pic_info pic; - int mb_width, mb_total; - int mb_height = 0; - int active_buffer_spec_num, dec_dpb_size; - int max_reference_size ,level_idc; - u32 frame_mbs_only_flag; - u32 chroma_format_idc; - u32 crop_bottom, crop_right; - int sub_width_c = 0, sub_height_c = 0; - u32 frame_width, frame_height; - u32 used_reorder_dpb_size_margin - = hw->reorder_dpb_size_margin; - - level_idc = param4 & 0xff; - max_reference_size = (param4 >> 8) & 0xff; - hw->dpb.mSPS.level_idc = level_idc; - -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (vdec->master || vdec->slave) - used_reorder_dpb_size_margin = - reorder_dpb_size_margin_dv; -#endif - mb_width = param1 & 0xff; - mb_total = (param1 >> 8) & 0xffff; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - if (mb_width) - mb_height = mb_total/mb_width; - if (mb_width <= 0 || mb_height <= 0 || - is_oversize(mb_width << 4, mb_height << 4)) { - dpb_print(DECODE_ID(hw), 0, - "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n", - param1, - mb_width, - mb_height); - hw->error_frame_width = mb_width << 4; - hw->error_frame_height = mb_height << 4; - return -1; - } - hw->error_frame_width = 0; - hw->error_frame_height = 0; - - dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height, level_idc); - - dpb_print(DECODE_ID(hw), 0, - "v4l restriction:%d, max buffering:%d, DPB size:%d, reorder frames:%d, margin:%d\n", - hw->bitstream_restriction_flag, - hw->max_dec_frame_buffering, - dec_dpb_size, - hw->num_reorder_frames, - used_reorder_dpb_size_margin); - - active_buffer_spec_num = - dec_dpb_size - + used_reorder_dpb_size_margin; - - if (active_buffer_spec_num > MAX_VF_BUF_NUM) { - active_buffer_spec_num = MAX_VF_BUF_NUM; - dec_dpb_size = active_buffer_spec_num - - used_reorder_dpb_size_margin; - } - - hw->dpb.mDPB.size = active_buffer_spec_num; - - if (hw->no_poc_reorder_flag) - dec_dpb_size = 1; - - /* - * crop - * AV_SCRATCH_2 - * bit 15: frame_mbs_only_flag - * bit 13-14: chroma_format_idc - */ - hw->seq_info = param2; - frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01; - if (hw->dpb.mSPS.profile_idc != 100 && - hw->dpb.mSPS.profile_idc != 110 && - hw->dpb.mSPS.profile_idc != 122 && - hw->dpb.mSPS.profile_idc != 144) { - hw->dpb.chroma_format_idc = 1; - } - chroma_format_idc = hw->dpb.chroma_format_idc; - - /* - * AV_SCRATCH_6 bit 31-16 = (left << 8 | right ) << 1 - * AV_SCRATCH_6 bit 15-0 = (top << 8 | bottom ) << - * (2 - frame_mbs_only_flag) - */ - switch (chroma_format_idc) { - case 1: - sub_width_c = 2; - sub_height_c = 2; - break; - - case 2: - sub_width_c = 2; - sub_height_c = 1; - break; - - case 3: - sub_width_c = 1; - sub_height_c = 1; - break; - - default: - break; - } - - if (chroma_format_idc == 0) { - crop_right = hw->dpb.frame_crop_right_offset; - crop_bottom = hw->dpb.frame_crop_bottom_offset * - (2 - frame_mbs_only_flag); - } else { - crop_right = sub_width_c * hw->dpb.frame_crop_right_offset; - crop_bottom = sub_height_c * hw->dpb.frame_crop_bottom_offset * - (2 - frame_mbs_only_flag); - } - - frame_width = mb_width << 4; - frame_height = mb_height << 4; - - frame_width = frame_width - crop_right; - frame_height = frame_height - crop_bottom; - - ps->profile = level_idc; - ps->ref_frames = max_reference_size; - ps->mb_width = mb_width; - ps->mb_height = mb_height; - ps->visible_width = frame_width; - ps->visible_height = frame_height; - ps->coded_width = ALIGN(mb_width << 4, 64); - ps->coded_height = ALIGN(mb_height << 4, 64); - ps->dpb_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */ - ps->dpb_margin = used_reorder_dpb_size_margin; - ps->dpb_size = active_buffer_spec_num; - ps->field = frame_mbs_only_flag ? - V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED; - - /* update reoder and margin num. */ - if (hw->res_ch_flag) { - vdec_v4l_get_pic_info(ctx, &pic); - ps->dpb_frames = pic.dpb_frames; - ps->dpb_margin = pic.dpb_margin; - } - - if ((ps->dpb_frames >= 16) && (ps->coded_width > 1280) && - (ps->coded_height > 768)) { - if (ps->field == V4L2_FIELD_NONE) { - ps->dpb_frames = adjust_dpb_size; - } else { - ps->dpb_frames = adjust_dpb_size - 2; - } - } - - dpb_print(DECODE_ID(hw), 0, - "Res:%dx%d, DPB size:%d, margin:%d, scan:%s\n", - ps->visible_width, ps->visible_height, - ps->dpb_frames, ps->dpb_margin, - (ps->field == V4L2_FIELD_NONE) ? "P" : "I"); - - return 0; -} - -static int v4l_res_change(struct vdec_h264_hw_s *hw, - u32 param1, u32 param2, - u32 param3, u32 param4) -{ - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int ret = 0; - int dec_dpb_size_change = hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1, param4); - - if (ctx->param_sets_from_ucode && - hw->res_ch_flag == 0) { - if (((param1 != 0 && - hw->seq_info2 != param1) || hw->csd_change_flag) && - hw->seq_info2 != 0) { - if (((hw->seq_info2 & 0x80ffffff) != (param1 & 0x80ffffff)) || dec_dpb_size_change) { /*picture size changed*/ - struct aml_vdec_ps_infos ps; - dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL, - "h264 res_change\n"); - if (vmh264_get_ps_info(hw, param1, - param2, param3, param4, &ps) < 0) { - dpb_print(DECODE_ID(hw), 0, - "set parameters error\n"); - } - hw->v4l_params_parsed = false; - vdec_v4l_set_ps_infos(ctx, &ps); - vdec_v4l_res_ch_event(ctx); - hw->res_ch_flag = 1; - ctx->v4l_resolution_change = 1; - hw->bitstream_restriction_flag = hw->cfg_bitstream_restriction_flag; // restore the old value when v4l res change - amvdec_stop(); - if (hw->mmu_enable) - amhevc_stop(); - hw->eos = 1; - flush_dpb(p_H264_Dpb); - //del_timer_sync(&hw->check_timer); - ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__); - notify_v4l_eos(hw_to_vdec(hw)); - ATRACE_COUNTER("V_ST_DEC-submit_eos", 0); - ret = 1; - } - } - } - - return ret; - -} - -static void vh264_work_implement(struct vdec_h264_hw_s *hw, - struct vdec_s *vdec, int from) -{ - /* finished decoding one frame or error, - * notify vdec core to switch context - */ - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - - if (hw->dec_result == DEC_RESULT_DONE) { - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START); - } else if (hw->dec_result == DEC_RESULT_AGAIN) - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN); - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL, - "%s dec_result %d %x %x %x\n", - __func__, - hw->dec_result, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP)); - - ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result); - - if (!hw->mmu_enable) { - mutex_lock(&vmh264_mutex); - dealloc_buf_specs(hw, 0); - mutex_unlock(&vmh264_mutex); - } - hw->save_reg_f = READ_VREG(AV_SCRATCH_F); - hw->dpb.last_dpb_status = hw->dpb.dec_dpb_status; - if (hw->dec_result == DEC_RESULT_CONFIG_PARAM) { - u32 param1 = READ_VREG(AV_SCRATCH_1); - u32 param2 = READ_VREG(AV_SCRATCH_2); - u32 param3 = READ_VREG(AV_SCRATCH_6); - u32 param4 = READ_VREG(AV_SCRATCH_B); - struct aml_vcodec_ctx *ctx = - (struct aml_vcodec_ctx *)(hw->v4l2_ctx); - - if (hw->is_used_v4l && - ctx->param_sets_from_ucode) { - if (!v4l_res_change(hw, param1, param2, param3, param4)) { - if (!hw->v4l_params_parsed) { - struct aml_vdec_ps_infos ps; - dpb_print(DECODE_ID(hw), - PRINT_FLAG_DEC_DETAIL, - "h264 parsered csd data\n"); - if (vmh264_get_ps_info(hw, - param1, param2, - param3, param4, &ps) < 0) { - dpb_print(DECODE_ID(hw), 0, - "set parameters error\n"); - } - hw->v4l_params_parsed = true; - vdec_v4l_set_ps_infos(ctx, &ps); - - amvdec_stop(); - if (hw->mmu_enable) - amhevc_stop(); - ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START); - } else { - if (vh264_set_params(hw, param1, - param2, param3, param4, false) < 0) { - hw->init_flag = 0; - dpb_print(DECODE_ID(hw), 0, "set parameters error, init_flag: %u\n", - hw->init_flag); - } - - WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | - (hw->dpb.mDPB.size<<16) | - (hw->dpb.mDPB.size<<8)); - hw->res_ch_flag = 0; - start_process_time(hw); - return; - } - } - } else { - if (vh264_set_params(hw, param1, - param2, param3, param4, false) < 0) { - hw->init_flag = 0; - dpb_print(DECODE_ID(hw), 0, "set parameters error, init_flag: %u\n", - hw->init_flag); - } - - WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | - (hw->dpb.mDPB.size<<16) | - (hw->dpb.mDPB.size<<8)); - start_process_time(hw); - return; - } - } else - if (((hw->dec_result == DEC_RESULT_GET_DATA) || - (hw->dec_result == DEC_RESULT_GET_DATA_RETRY)) - && (hw_to_vdec(hw)->next_status != - VDEC_STATUS_DISCONNECTED)) { - if (!vdec_has_more_input(vdec)) { - hw->dec_result = DEC_RESULT_EOS; - vdec_schedule_work(&hw->work); - return; - } - - if (hw->dec_result == DEC_RESULT_GET_DATA) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_GET_DATA %x %x %x\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP)); - mutex_lock(&hw->chunks_mutex); - vdec_vframe_dirty(vdec, hw->chunk); - hw->chunk = NULL; - mutex_unlock(&hw->chunks_mutex); - vdec_clean_input(vdec); - } - if ((hw->dec_result == DEC_RESULT_GET_DATA_RETRY) && - ((1000 * (jiffies - hw->get_data_start_time) / HZ) - > get_data_timeout_val)) { - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_GET_DATA_RETRY timeout\n", - __func__); - goto result_done; - } - if (is_buffer_available(vdec)) { - int r; - int decode_size; - r = vdec_prepare_input(vdec, &hw->chunk); - if (r < 0 && (hw_to_vdec(hw)->next_status != - VDEC_STATUS_DISCONNECTED)) { - hw->dec_result = DEC_RESULT_GET_DATA_RETRY; - - dpb_print(DECODE_ID(hw), - PRINT_FLAG_VDEC_DETAIL, - "vdec_prepare_input: Insufficient data\n"); - vdec_schedule_work(&hw->work); - return; - } - hw->dec_result = DEC_RESULT_NONE; - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s: chunk size 0x%x\n", - __func__, hw->chunk->size); - - if (dpb_is_debug(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA)) { - int jj; - u8 *data = NULL; - - if (!hw->chunk->block->is_mapped) - data = codec_mm_vmap( - hw->chunk->block->start + - hw->chunk->offset, r); - else - data = ((u8 *) - hw->chunk->block->start_virt) - + hw->chunk->offset; - - for (jj = 0; jj < r; jj++) { - if ((jj & 0xf) == 0) - dpb_print(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "%06x:", jj); - dpb_print_cont(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - dpb_print_cont(DECODE_ID(hw), - PRINT_FRAMEBASE_DATA, - "\n"); - } - - if (!hw->chunk->block->is_mapped) - codec_mm_unmap_phyaddr(data); - } - WRITE_VREG(POWER_CTL_VLD, - READ_VREG(POWER_CTL_VLD) | - (0 << 10) | (1 << 9) | (1 << 6)); - WRITE_VREG(H264_DECODE_INFO, (1<<13)); - decode_size = hw->chunk->size + - (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1)); - WRITE_VREG(H264_DECODE_SIZE, decode_size); - WRITE_VREG(VIFF_BIT_CNT, decode_size * 8); - vdec_enable_input(vdec); - - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); - start_process_time(hw); - } else{ - if (hw_to_vdec(hw)->next_status - != VDEC_STATUS_DISCONNECTED) { - hw->dec_result = DEC_RESULT_GET_DATA_RETRY; - vdec_schedule_work(&hw->work); - } - } - return; - } else if (hw->dec_result == DEC_RESULT_DONE || - hw->dec_result == DEC_RESULT_TIMEOUT) { - /* if (!hw->ctx_valid) - hw->ctx_valid = 1; */ - if ((hw->dec_result == DEC_RESULT_TIMEOUT) && - !hw->i_only && (hw->error_proc_policy & 0x2)) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - dpb_print(DECODE_ID(hw), 0, - "%s, decode timeout flush dpb\n", - __func__); - flush_dpb(p_H264_Dpb); - } -result_done: - { - if (hw->error_proc_policy & 0x8000) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int i; - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - - for (i = 0; i < p_Dpb->used_size; i++) { - int i_flag = p_Dpb->fs[i]->bottom_field || p_Dpb->fs[i]->top_field; - int threshold = (i_flag || (hw->max_reference_size >= 12)) ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size; - if ((p_Dpb->fs[i]->dpb_frame_count + threshold - < p_H264_Dpb->dpb_frame_count) && - p_Dpb->fs[i]->is_reference && - !p_Dpb->fs[i]->is_long_term && - p_Dpb->fs[i]->is_output) { - dpb_print(DECODE_ID(hw), - 0, - "unmark reference dpb_frame_count diffrence large in dpb\n"); - unmark_for_reference(p_Dpb, p_Dpb->fs[i]); - update_ref_list(p_Dpb); - } - } - } - } - if (hw->mmu_enable - && hw->frame_busy && hw->frame_done) { - long used_4k_num; - hevc_sao_wait_done(hw); - if (hw->hevc_cur_buf_idx != 0xffff) { - used_4k_num = - (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); - if (used_4k_num >= 0) - dpb_print(DECODE_ID(hw), - PRINT_FLAG_MMU_DETAIL, - "release unused buf , used_4k_num %ld index %d\n", - used_4k_num, hw->hevc_cur_buf_idx); - hevc_mmu_dma_check(hw_to_vdec(hw)); - decoder_mmu_box_free_idx_tail( - hw->mmu_box, - hw->hevc_cur_buf_idx, - used_4k_num); - hw->hevc_cur_buf_idx = 0xffff; - } - } - decode_frame_count[DECODE_ID(hw)]++; - if (hw->dpb.mSlice.slice_type == I_SLICE) { - hw->gvs.i_decoded_frames++; - } else if (hw->dpb.mSlice.slice_type == P_SLICE) { - hw->gvs.p_decoded_frames++; - } else if (hw->dpb.mSlice.slice_type == B_SLICE) { - hw->gvs.b_decoded_frames++; - } - amvdec_stop(); - - dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, - "%s dec_result %d %x %x %x\n", - __func__, - hw->dec_result, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP)); - mutex_lock(&hw->chunks_mutex); - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - hw->chunk = NULL; - mutex_unlock(&hw->chunk