author | Nanxin Qin <nanxin.qin@amlogic.com> | 2017-06-12 08:02:57 (GMT) |
---|---|---|
committer | Nanxin Qin <nanxin.qin@amlogic.com> | 2017-06-12 08:27:15 (GMT) |
commit | 28a80bbcef417e2d56240c0ecef263cb2711fc50 (patch) | |
tree | 02f52a1ac459fd4502e2d98bf829c3cf29a3a195 | |
parent | 833efe3d43f4f85ed91ea509fbc7f0ad14a621cf (diff) | |
download | media-28a80bbcef417e2d56240c0ecef263cb2711fc50.zip media-28a80bbcef417e2d56240c0ecef263cb2711fc50.tar.gz media-28a80bbcef417e2d56240c0ecef263cb2711fc50.tar.bz2 |
add media codec to android O
Change-Id: I7fde19f49c50196e1226389d872c4966e26966f6
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
180 files changed, 16354 insertions, 79358 deletions
@@ -24,7 +24,7 @@ *.order modules.builtin *.elf -#*.bin +*.bin *.gz *.bz2 *.lzma diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..5053e7d --- a/dev/null +++ b/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/Media.mk b/Media.mk deleted file mode 100644 index 69cbf22..0000000 --- a/Media.mk +++ b/dev/null @@ -1,93 +0,0 @@ - -KERNEL_ARCH := arm64 -TOOLS := /opt/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=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_H264_4K2K=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_VENC_H264=m \ - CONFIG_AMLOGIC_MEDIA_VECN_H265=m - -define copy-media-modules -$(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\ - $(shell cp $(m) $(strip $(2)) -rfa)) -endef - -ifneq (,$(ANDROID_BUILD_TOP)) -KDIR := $(OUT)/obj/KERNEL_OBJ/ - -MEDIA_DRIVERS := $(ANDROID_BUILD_TOP)/hardware/amlogic/media/drivers -ifeq (,$(wildcard $(MEDIA_DRIVERS))) -$(error No find the dir of drivers.) -endif - -INCLUDE := $(MEDIA_DRIVERS)/include -ifeq (,$(wildcard $(INCLUDE))) -$(error No find the dir of include.) -endif - -MEDIA_MODULES := $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/obj/media -ifeq (,$(wildcard $(MEDIA_MODULES))) -$(shell mkdir $(MEDIA_MODULES) -p) -endif - -MODS_OUT := $(ANDROID_BUILD_TOP)/$(TARGET_OUT)/lib - -$(shell cp $(MEDIA_DRIVERS)/* $(MEDIA_MODULES) -rfa) - -define media-modules - @$(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) ARCH=$(KERNEL_ARCH) \ - CROSS_COMPILE=$(TOOLS) $(CONFIGS) \ - EXTRA_CFLAGS+=-I$(INCLUDE) modules; \ - find $(MEDIA_MODULES) -name "*.ko" | xargs -i cp {} $(MODS_OUT) -endef - -else -KDIR := $(PWD)/kernel -ifeq (,$(wildcard $(KDIR))) -$(error No find the dir of kernel.) -endif - -MEDIA_DRIVERS := $(PWD)/media/drivers -ifeq (,$(wildcard $(MEDIA_DRIVERS))) -$(error No find the dir of drivers.) -endif - -INCLUDE := $(MEDIA_DRIVERS)/include -ifeq (,$(wildcard $(INCLUDE))) -$(error No find the dir of include.) -endif - -MODS_OUT ?= $(MEDIA_DRIVERS)/../modules -ifeq (,$(wildcard $(MODS_OUT))) -$(shell mkdir $(MODS_OUT) -p) -endif - -TOOLS := /opt/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- - -modules: - @$(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." - $(call copy-media-modules, $(MEDIA_DRIVERS), $(MODS_OUT)) - -all: modules copy-modules - -clean: - $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) clean - -endif diff --git a/amavutils/Amsyswrite.cpp b/amavutils/Amsyswrite.cpp new file mode 100644 index 0000000..eb711b5 --- a/dev/null +++ b/amavutils/Amsyswrite.cpp @@ -0,0 +1,217 @@ +#ifndef NO_USE_SYSWRITE +#define LOG_TAG "amSystemWrite" + + +#include <binder/Binder.h> +#include <binder/IServiceManager.h> +#include <utils/Atomic.h> +#include <utils/Log.h> +#include <utils/RefBase.h> +#include <utils/String8.h> +#include <utils/String16.h> +#include <utils/threads.h> +#include <Amsyswrite.h> +#include <unistd.h> +#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 +#include <systemcontrol/ISystemControlService.h> +#else +#include <systemwrite/ISystemWriteService.h> +#endif + +using namespace android; + +class DeathNotifier: public IBinder::DeathRecipient +{ + public: + DeathNotifier() { + } + + void binderDied(const wp<IBinder>& who) { + ALOGW("system_write died!"); + } +}; + + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 +//used ISystemControlService +#define SYST_SERVICES_NAME "system_control" +#else +//used amSystemWriteService +#define ISystemControlService ISystemWriteService +#define SYST_SERVICES_NAME "system_write" +#endif + +static sp<ISystemControlService> amSystemWriteService; +static sp<DeathNotifier> amDeathNotifier; +static Mutex amLock; +static Mutex amgLock; + +const sp<ISystemControlService>& getSystemWriteService() +{ + Mutex::Autolock _l(amgLock); + if (amSystemWriteService.get() == 0) { + sp<IServiceManager> sm = defaultServiceManager(); +#if 0 + sp<IBinder> binder; + do { + binder = sm->getService(String16("system_write")); + if (binder != 0) + break; + ALOGW("SystemWriteService not published, waiting..."); + usleep(500000); // 0.5 s + } while(true); + if (amDeathNotifier == NULL) { + amDeathNotifier = new DeathNotifier(); + } + binder->linkToDeath(amDeathNotifier); + amSystemWriteService = interface_cast<ISystemWriteService>(binder); +#endif + + + amSystemWriteService = interface_cast<ISystemControlService>(sm->getService(String16(SYST_SERVICES_NAME))); + + } + ALOGE_IF(amSystemWriteService==0, "no SystemWrite Service!?"); + + return amSystemWriteService; +} + +int amSystemWriteGetProperty(const char* key, char* value) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + String16 v; + if (sws->getProperty(String16(key), v)) { + strcpy(value, String8(v).string()); + return 0; + } + } + return -1; + +} + +int amSystemWriteGetPropertyStr(const char* key, char* def, char* value) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + String16 v; + String16 d(def); + sws->getPropertyString(String16(key), v, d); + strcpy(value, String8(v).string()); + } + strcpy(value, def); + return -1; +} + +int amSystemWriteGetPropertyInt(const char* key, int def) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + return sws->getPropertyInt(String16(key), def); + } + return def; +} + + +long amSystemWriteGetPropertyLong(const char* key, long def) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + return sws->getPropertyLong(String16(key), def); + } + return def; +} + + +int amSystemWriteGetPropertyBool(const char* key, int def) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + if (sws->getPropertyBoolean(String16(key), def)) { + return 1; + } else { + return 0; + } + } + return def; + +} + +void amSystemWriteSetProperty(const char* key, const char* value) +{ + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + sws->setProperty(String16(key), String16(value)); + } +} + +int amSystemWriteReadSysfs(const char* path, char* value) +{ + //ALOGD("amSystemWriteReadNumSysfs:%s",path); + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + String16 v; + if (sws->readSysfs(String16(path), v)) { + strcpy(value, String8(v).string()); + return 0; + } + } + return -1; +} + +int amSystemWriteReadNumSysfs(const char* path, char* value, int size) +{ + //ALOGD("amSystemWriteReadNumSysfs:%s",path); + + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0 && value != NULL && access(path, 0) != -1) { + String16 v; + if (sws->readSysfs(String16(path), v)) { + if (v.size() != 0) { + //ALOGD("readSysfs ok:%s,%s,%d", path, String8(v).string(), String8(v).size()); + memset(value, 0, size); + if (size <= String8(v).size() + 1) { + memcpy(value, String8(v).string(), size - 1); + value[strlen(value)] = '\0'; + + } else { + strcpy(value, String8(v).string()); + + } + return 0; + } + } + + } + //ALOGD("[false]amSystemWriteReadNumSysfs%s,",path); + return -1; +} + +int amSystemWriteWriteSysfs(const char* path, char* value) +{ + //ALOGD("amSystemWriteWriteSysfs:%s",path); + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + String16 v(value); + if (sws->writeSysfs(String16(path), v)) { + //ALOGD("writeSysfs ok"); + return 0; + } + } + //ALOGD("[false]amSystemWriteWriteSysfs%s,",path); + return -1; +} + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 +extern "C" int amSystemControlSetNativeWindowRect(int x, int y, int w, int h) { + const sp<ISystemControlService>& sws = getSystemWriteService(); + if (sws != 0) { + sws->setNativeWindowRect(x, y, w, h); + return 0; + } + + return -1; +} +#endif + +#endif diff --git a/amavutils/Amvideocaptools.c b/amavutils/Amvideocaptools.c new file mode 100644 index 0000000..60f132d --- a/dev/null +++ b/amavutils/Amvideocaptools.c @@ -0,0 +1,87 @@ +#define LOG_TAG "AmAvutls" + +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <cutils/log.h> +#include <sys/ioctl.h> + +#include "Amvideocaptools.h" + + +#define VIDEOCAPDEV "/dev/amvideocap0" +int amvideocap_capframe(char *buf, int size, int *w, int *h, int fmt_ignored, int at_end, int* ret_size, int fmt) +{ + int fd = open(VIDEOCAPDEV, O_RDWR); + int ret = 0; + if (fd < 0) { + ALOGI("amvideocap_capframe open %s failed\n", VIDEOCAPDEV); + return -1; + } + if (w != NULL && *w > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, *w); + } + if (h != NULL && *h > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, *h); + } + if (fmt) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT, fmt); + } + if (at_end) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS, CAP_FLAG_AT_END); + } + *ret_size = read(fd, buf, size); + if (w != NULL) { + ret = ioctl(fd, AMVIDEOCAP_IOR_GET_FRAME_WIDTH, w); + } + if (h != NULL) { + ret = ioctl(fd, AMVIDEOCAP_IOR_GET_FRAME_HEIGHT, h); + } + close(fd); + return ret; +} + +int amvideocap_capframe_with_rect(char *buf, int size, int src_rect_x, int src_rect_y, int *w, int *h, int fmt_ignored, int at_end, int* ret_size) +{ + int fd = open(VIDEOCAPDEV, O_RDWR); + int ret = 0; + if (fd < 0) { + ALOGI("amvideocap_capframe_with_rect open %s failed\n", VIDEOCAPDEV); + return -1; + } + ALOGI("amvideocap_capframe_with_rect open %d, %d\n", *w, *h); + if (src_rect_x > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_SET_SRC_X, src_rect_x); + } + if (src_rect_y > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_SET_SRC_Y, src_rect_y); + } + if (*w > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_SET_SRC_WIDTH, *w); + } + if (*h > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_SET_SRC_HEIGHT, *h); + } + if (*w > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, *w); + } + if (*h > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, *h); + } + if (at_end) { + ret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS, CAP_FLAG_AT_END); + } + *ret_size = read(fd, buf, size); + + if (*w > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_GET_FRAME_WIDTH, w); + } + + if (*h > 0) { + ret = ioctl(fd, AMVIDEOCAP_IOR_GET_FRAME_HEIGHT, h); + } + close(fd); + return ret; +} + diff --git a/amavutils/Amvideoutils.c b/amavutils/Amvideoutils.c new file mode 100644 index 0000000..67393e1 --- a/dev/null +++ b/amavutils/Amvideoutils.c @@ -0,0 +1,960 @@ + +#define LOG_TAG "amavutils" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <strings.h> +#include <cutils/log.h> +#include <cutils/properties.h> +#include <sys/ioctl.h> +#include "include/Amvideoutils.h" +#include "include/Amsysfsutils.h" +#include "include/Amdisplayutils.h" +#include "include/Amsyswrite.h" + +#include "amports/amstream.h" +#include "ppmgr/ppmgr.h" + +#define SYSCMD_BUFSIZE 40 +#define DISP_DEVICE_PATH "/sys/class/video/device_resolution" +#define FB_DEVICE_PATH "/sys/class/graphics/fb0/virtual_size" +#define ANGLE_PATH "/dev/ppmgr" +#define VIDEO_PATH "/dev/amvideo" +#define VIDEO_AXIS_PATH "sys/class/video/axis" +#define PPMGR_ANGLE_PATH "sys/class/ppmgr/angle" +#define VIDEO_GLOBAL_OFFSET_PATH "/sys/class/video/global_offset" +#define FREE_SCALE_PATH "/sys/class/graphics/fb0/free_scale" +#define FREE_SCALE_PATH_FB2 "/sys/class/graphics/fb2/free_scale" +#define FREE_SCALE_PATH_FB1 "/sys/class/graphics/fb1/free_scale" +#define PPSCALER_PATH "/sys/class/ppmgr/ppscaler" +#define HDMI_AUTHENTICATE_PATH "/sys/module/hdmitx/parameters/hdmi_authenticated" +#define FREE_SCALE_MODE_PATH "/sys/class/graphics/fb0/freescale_mode" +#define WINDOW_AXIS_PATH "/sys/class/graphics/fb0/window_axis" +#define DISPLAY_AXIS_PATH "/sys/class/display/axis" +#define FREE_SCALE_AXIS_PATH "/sys/class/graphics/fb0/free_scale_axis" +#define PPSCALER_RECT "/sys/class/ppmgr/ppscaler_rect" +#define WINDOW_AXIS_PATH_FB1 "/sys/class/graphics/fb1/window_axis" +#define FREE_SCALE_AXIS_PATH_FB1 "/sys/class/graphics/fb1/free_scale_axis" +#define PROC_SETMODE_COMPLETE "sys.setmode.complete" //set this prop to true, when set outputmode complete + +static int rotation = 0; +static int disp_width = 1920; +static int disp_height = 1080; + +#ifndef LOGD +#define LOGV ALOGV +#define LOGD ALOGD +#define LOGI ALOGI +#define LOGW ALOGW +#define LOGE ALOGE +#endif + +//#define LOG_FUNCTION_NAME LOGI("%s-%d\n",__FUNCTION__,__LINE__); +#define LOG_FUNCTION_NAME + +int amvideo_utils_get_freescale_enable(void) +{ + int ret = 0; + char buf[32]; + + ret = amsysfs_get_sysfs_str("/sys/class/graphics/fb0/free_scale", buf, 32); + if ((ret >= 0) && strncmp(buf, "free_scale_enalbe:[0x1]", + strlen("free_scale_enalbe:[0x1]")) == 0) { + + return 1; + + } + return 0; +} + +int amvideo_utils_get_global_offset(void) +{ + LOG_FUNCTION_NAME + int offset = 0; + char buf[SYSCMD_BUFSIZE]; + int ret; + ret = amsysfs_get_sysfs_str(VIDEO_GLOBAL_OFFSET_PATH, buf, SYSCMD_BUFSIZE); + if (ret < 0) { + return offset; + } + if (sscanf(buf, "%d", &offset) == 1) { + LOGI("video global_offset %d\n", offset); + } + return offset; +} + +int is_video_on_vpp2(void) +{ + int ret = 0; + + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (property_get("ro.vout.dualdisplay4", val, "false") + && strcmp(val, "true") == 0) { + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str("/sys/module/amvideo/parameters/cur_dev_idx", val, sizeof(val)) == 0) { + if ((strncmp(val, "1", 1) == 0)) { + ret = 1; + } + } + } + + return ret; +} + +int is_vertical_panel(void) +{ + int ret = 0; + + // ro.vout.dualdisplay4.ver-panel + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (property_get("ro.vout.dualdisplay4.ver-panel", val, "false") + && strcmp(val, "true") == 0) { + ret = 1; + } + + return ret; +} + +int is_screen_portrait(void) +{ + int ret = 0; + + // ro.vout.dualdisplay4.ver-panel + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (property_get("ro.screen.portrait", val, "false") + && strcmp(val, "true") == 0) { + ret = 1; + } + + return ret; +} + +int is_osd_on_vpp2_new(void) +{ + int ret = 0; + + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str("/sys/class/graphics/fb2/clone", val, sizeof(val)) == 0) { + ret = (val[19] == '1') ? 1 : 0; + } + return ret; +} + +int is_hdmi_on_vpp1_new(void) +{ + int ret1 = 0; + int ret2 = 0; + int ret = 0; + + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str("/sys/class/graphics/fb1/ver_clone", val, sizeof(val)) == 0) { + ret1 = (val[11] == 'O') ? 1 : 0; + ret2 = (val[12] == 'N') ? 1 : 0; + if ((ret1 == 1) && (ret2 == 1)) { + ret = 1; + } + } + return ret; +} + +int is_vertical_panel_reverse(void) +{ + int ret = 0; + + // ro.vout.dualdisplay4.ver-panel + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (property_get("ro.ver-panel.reverse", val, "false") + && strcmp(val, "true") == 0) { + ret = 1; + } + + return ret; +} + +int is_panel_mode(void) +{ + int ret = 0; + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str("/sys/class/display/mode", val, sizeof(val)) == 0) { + ret = (val[0] == 'p') ? 1 : 0; + } + return ret; +} + + +typedef enum _OSD_DISP_MODE { + OSD_DISP_480I, + OSD_DISP_480P, + OSD_DISP_576I, + OSD_DISP_576P, + OSD_DISP_720P, + OSD_DISP_1080I, + OSD_DISP_1080P, + OSD_DISP_LVDS1080P, +} OSD_DISP_MODE; + +OSD_DISP_MODE get_osd_display_mode() +{ + OSD_DISP_MODE ret = OSD_DISP_1080P; + char buf[PROPERTY_VALUE_MAX]; + memset(buf, 0, sizeof(buf)); + property_get("ubootenv.var.outputmode", buf, "1080p"); + if (!strncmp(buf, "720p", 4)) { + ret = OSD_DISP_720P; + } else if (!strncmp(buf, "480p", 4)) { + ret = OSD_DISP_480P; + } else if (!strncmp(buf, "480", 3)) { //for 480i&480cvbs + ret = OSD_DISP_480I; + } else if (!strncmp(buf, "576p", 4)) { + ret = OSD_DISP_576P; + } else if (!strncmp(buf, "576", 3)) { //for 576i&576cvbs + ret = OSD_DISP_576I; + } else if (!strncmp(buf, "1080i", 5)) { + ret = OSD_DISP_1080I; + } else if (!strncmp(buf, "1080p", 5)) { + ret = OSD_DISP_1080P; + } else if (!strncmp(buf, "lvds1080p", 9)) { + ret = OSD_DISP_LVDS1080P; + } + return ret; +} + +int get_device_win(OSD_DISP_MODE dismod, int *x, int *y, int *w, int *h) +{ + const char *prop1080i_h = "ubootenv.var.1080i_h"; + const char *prop1080i_w = "ubootenv.var.1080i_w"; + const char *prop1080i_x = "ubootenv.var.1080i_x"; + const char *prop1080i_y = "ubootenv.var.1080i_y"; + + const char *prop1080p_h = "ubootenv.var.1080p_h"; + const char *prop1080p_w = "ubootenv.var.1080p_w"; + const char *prop1080p_x = "ubootenv.var.1080p_x"; + const char *prop1080p_y = "ubootenv.var.1080p_y"; + + const char *prop720p_h = "ubootenv.var.720p_h"; + const char *prop720p_w = "ubootenv.var.720p_w"; + const char *prop720p_x = "ubootenv.var.720p_x"; + const char *prop720p_y = "ubootenv.var.720p_y"; + + const char *prop480i_h = "ubootenv.var.480i_h"; + const char *prop480i_w = "ubootenv.var.480i_w"; + const char *prop480i_x = "ubootenv.var.480i_x"; + const char *prop480i_y = "ubootenv.var.480i_y"; + + const char *prop480p_h = "ubootenv.var.480p_h"; + const char *prop480p_w = "ubootenv.var.480p_w"; + const char *prop480p_x = "ubootenv.var.480p_x"; + const char *prop480p_y = "ubootenv.var.480p_y"; + + const char *prop576i_h = "ubootenv.var.576i_h"; + const char *prop576i_w = "ubootenv.var.576i_w"; + const char *prop576i_x = "ubootenv.var.576i_x"; + const char *prop576i_y = "ubootenv.var.576i_y"; + + const char *prop576p_h = "ubootenv.var.576p_h"; + const char *prop576p_w = "ubootenv.var.576p_w"; + const char *prop576p_x = "ubootenv.var.576p_x"; + const char *prop576p_y = "ubootenv.var.576p_y"; + + char prop_value_h[PROPERTY_VALUE_MAX]; + memset(prop_value_h, 0, PROPERTY_VALUE_MAX); + char prop_value_w[PROPERTY_VALUE_MAX]; + memset(prop_value_w, 0, PROPERTY_VALUE_MAX); + char prop_value_x[PROPERTY_VALUE_MAX]; + memset(prop_value_x, 0, PROPERTY_VALUE_MAX); + char prop_value_y[PROPERTY_VALUE_MAX]; + memset(prop_value_y, 0, PROPERTY_VALUE_MAX); + + switch (dismod) { + case OSD_DISP_1080P: + property_get(prop1080p_h, prop_value_h, "1080"); + property_get(prop1080p_w, prop_value_w, "1920"); + property_get(prop1080p_x, prop_value_x, "0"); + property_get(prop1080p_y, prop_value_y, "0"); + break; + case OSD_DISP_1080I: + property_get(prop1080i_h, prop_value_h, "1080"); + property_get(prop1080i_w, prop_value_w, "1920"); + property_get(prop1080i_x, prop_value_x, "0"); + property_get(prop1080i_y, prop_value_y, "0"); + break; + case OSD_DISP_LVDS1080P: + property_get(prop1080p_h, prop_value_h, "1080"); + property_get(prop1080p_w, prop_value_w, "1920"); + property_get(prop1080p_x, prop_value_x, "0"); + property_get(prop1080p_y, prop_value_y, "0"); + break; + case OSD_DISP_720P: + property_get(prop720p_h, prop_value_h, "720"); + property_get(prop720p_w, prop_value_w, "1280"); + property_get(prop720p_x, prop_value_x, "0"); + property_get(prop720p_y, prop_value_y, "0"); + break; + case OSD_DISP_576P: + property_get(prop576p_h, prop_value_h, "576"); + property_get(prop576p_w, prop_value_w, "720"); + property_get(prop576p_x, prop_value_x, "0"); + property_get(prop576p_y, prop_value_y, "0"); + break; + case OSD_DISP_576I: + property_get(prop576i_h, prop_value_h, "576"); + property_get(prop576i_w, prop_value_w, "720"); + property_get(prop576i_x, prop_value_x, "0"); + property_get(prop576i_y, prop_value_y, "0"); + break; + case OSD_DISP_480P: + property_get(prop480p_h, prop_value_h, "480"); + property_get(prop480p_w, prop_value_w, "720"); + property_get(prop480p_x, prop_value_x, "0"); + property_get(prop480p_y, prop_value_y, "0"); + break; + case OSD_DISP_480I: + property_get(prop480i_h, prop_value_h, "480"); + property_get(prop480i_w, prop_value_w, "720"); + property_get(prop480i_x, prop_value_x, "0"); + property_get(prop480i_y, prop_value_y, "0"); + break; + default : + break; + } + + LOGD("get_device_win h:%s , w:%s, x:%s, y:%s \n", prop_value_h, prop_value_w, prop_value_x, prop_value_y); + if (h) { + *h = atoi(prop_value_h); + } + if (w) { + *w = atoi(prop_value_w); + } + if (x) { + *x = atoi(prop_value_x); + } + if (y) { + *y = atoi(prop_value_y); + } + return 0; +} + +void get_axis(const char *path, int *x, int *y, int *w, int *h) +{ + int fd = -1; + char buf[SYSCMD_BUFSIZE]; + if (amsysfs_get_sysfs_str(path, buf, sizeof(buf)) == 0) { + if (sscanf(buf, "%d %d %d %d", x, y, w, h) == 4) { + LOGI("%s axis: %d %d %d %d\n", path, *x, *y, *w, *h); + } + } +} + +int amvideo_convert_axis(int32_t* x, int32_t* y, int32_t* w, int32_t* h, int *rotation, int osd_rotation) +{ + int fb0_w, fb0_h; + amdisplay_utils_get_size(&fb0_w, &fb0_h); + ALOGD("amvideo_convert_axis convert before %d,%d,%d,%d -- %d,%d", *x, *y, *w, *h, *rotation, osd_rotation); + /*if the video's width >= fb0_w and x == 0 , we think this a full screen video,then transfer the whole display size to decode + either is to y == 0 and hight >= fb0_h. + this is added for platforms which is 4:3 and hdmi mode are 16:9*/ + if (osd_rotation == 90) { + *rotation = (*rotation + osd_rotation) % 360; + int tmp = *w; + *w = *h; + *h = tmp; + + tmp = *y; + *y = *x; + *x = fb0_h - tmp - *w + 1; + } else if (osd_rotation == 270) { // 270 + *rotation = (*rotation + osd_rotation) % 360; + int tmp = *w; + *w = *h; + *h = tmp; + + tmp = *x; + *x = *y; + *y = fb0_w - tmp - *h + 1; + } else { + ALOGE("should no this rotation!"); + } + ALOGD("amvideo_convert_axis convert end %d,%d,%d,%d -- %d", *x, *y, *w, *h, *rotation); + return 0; +} + +void amvideo_setscreenmode() +{ + + float wh_ratio = 0; + float ratio4_3 = 1.3333; + float ratio16_9 = 1.7778; + float offset = 0.2; + char val[PROPERTY_VALUE_MAX]; + memset(val, 0, sizeof(val)); + int enable_fullscreen = 1; + int default_screen_mode = -1; + + /*if(x<0 || y<0) + return;*/ + + if (property_get("tv.default.screen.mode", val, "-1") && (!(strcmp(val, "-1") == 0))) { + default_screen_mode = atoi(val); + if (default_screen_mode >= 0 && default_screen_mode <=3) { + amvideo_utils_set_screen_mode(default_screen_mode); + return ; + } + } + + int fs_x = 0, fs_y = 0, fs_w = 0, fs_h = 0; + get_axis(FREE_SCALE_AXIS_PATH, &fs_x, &fs_y, &fs_w, &fs_h); + + if (fs_h > fs_w) { + int i = fs_w; + fs_w = fs_h; + fs_h = i; + } + + if (fs_h > 0) { + wh_ratio = fs_w * (float)1.0 / fs_h; + } + + ALOGD("amvideo_setscreenmode as %f", wh_ratio); + if ((wh_ratio < (ratio4_3 + offset)) + && (wh_ratio > 0) + && (is_panel_mode() == 0)) { + amvideo_utils_set_screen_mode(1); + ALOGD("set screen mode as 1"); + }/*else{ + amvideo_utils_set_screen_mode(0); + ALOGD("set screen mode as 0"); + }*/ +} + +void set_scale(int x, int y, int w, int h, int *dst_x, int *dst_y, int *dst_w, int *dst_h, int disp_w, int disp_h) +{ + float tmp_x,tmp_y,tmp_w,tmp_h; + tmp_x = (float)((float)((*dst_x) * w) / (float)disp_w); + tmp_y = (float)((float)((*dst_y) * h) / (float)disp_h); + tmp_w = (float)((float)((*dst_w) * w) / (float)disp_w); + tmp_h = (float)((float)((*dst_h) * h) / (float)disp_h); + *dst_x = (int)(tmp_x+0.5) + x; + *dst_y = (int)(tmp_y+0.5) + y; + *dst_w = (int)(tmp_w+0.5); + *dst_h = (int)(tmp_h+0.5); +} + +int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) +{ + LOG_FUNCTION_NAME + + //this code block ensure to exec this func, when system_control setSourceOutputMode complete or Timeout. + for (int i = 0; i < 20; i++) { + char value[PROPERTY_VALUE_MAX] = {0}; + property_get(PROC_SETMODE_COMPLETE, value, "null"); + if (!strcmp(value, "true") || !strcmp(value, "null")) { + break; + } else { + LOGI("wait set outputmode complete, SLEEP 50ms!"); + usleep(50000); + } + } + + //for osd rotation, need convert the axis first + int osd_rotation = amdisplay_utils_get_osd_rotation(); + if (osd_rotation > 0) { + amvideo_convert_axis(&x, &y, &w, &h, &rotation, osd_rotation); + } +#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 + // amSystemControlSetNativeWindowRect(x, y, w, h); +#endif + + int dev_w, dev_h, disp_w, disp_h, video_global_offset; + int dst_x, dst_y, dst_w, dst_h; + char buf[SYSCMD_BUFSIZE]; + int angle_fd = -1; + int ret = -1; + int axis[4]; + char enable_p2p_play[8] = {0}; + int video_on_vpp2_new = is_osd_on_vpp2_new(); + int screen_portrait = is_screen_portrait(); + int video_on_vpp2 = is_video_on_vpp2(); + int vertical_panel = is_vertical_panel(); + int vertical_panel_reverse = is_vertical_panel_reverse(); +#ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 + int hdmi_swith_on_vpp1 = is_hdmi_on_vpp1_new(); +#else + int hdmi_swith_on_vpp1 = !is_hdmi_on_vpp1_new(); +#endif + + if (video_on_vpp2) { + int fb0_w, fb0_h, fb2_w, fb2_h; + + amdisplay_utils_get_size(&fb0_w, &fb0_h); + amdisplay_utils_get_size_fb2(&fb2_w, &fb2_h); + + if (fb0_w > 0 && fb0_h > 0 && fb2_w > 0 && fb2_h > 0) { + if (vertical_panel) { + int x1, y1, w1, h1; + if (vertical_panel_reverse) { + x1 = (1.0 * fb2_w / fb0_h) * y; + y1 = (1.0 * fb2_h / fb0_w) * x; + w1 = (1.0 * fb2_w / fb0_h) * h; + h1 = (1.0 * fb2_h / fb0_w) * w; + } else { + x1 = (1.0 * fb2_w / fb0_h) * y; + y1 = (1.0 * fb2_h / fb0_w) * (fb0_w - x - w); + w1 = (1.0 * fb2_w / fb0_h) * h; + h1 = (1.0 * fb2_h / fb0_w) * w; + } + x = x1; + y = y1; + w = w1; + h = h1; + } else { + int x1, y1, w1, h1; + x1 = (1.0 * fb2_w / fb0_w) * x; + y1 = (1.0 * fb2_h / fb0_h) * y; + w1 = (1.0 * fb2_w / fb0_w) * w; + h1 = (1.0 * fb2_h / fb0_h) * h; + x = x1; + y = y1; + w = w1; + h = h1; + } + } + } +#ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 + if (screen_portrait && hdmi_swith_on_vpp1) { + int val = 0 ; + val = x ; + x = y; + y = val; + val = w; + w = h; + h = val; + } +#endif + LOGI("amvideo_utils_set_virtual_position :: x=%d y=%d w=%d h=%d\n", x, y, w, h); + + bzero(buf, SYSCMD_BUFSIZE); + + dst_x = x; + dst_y = y; + dst_w = w; + dst_h = h; + + if (amsysfs_get_sysfs_str(DISP_DEVICE_PATH, buf, sizeof(buf)) == 0) { + if (sscanf(buf, "%dx%d", &dev_w, &dev_h) == 2) { + LOGI("device resolution %dx%d\n", dev_w, dev_h); + } else { + ret = -2; + goto OUT; + } + } else { + goto OUT; + } + + + if (video_on_vpp2) { + amdisplay_utils_get_size_fb2(&disp_w, &disp_h); + } else { + amdisplay_utils_get_size(&disp_w, &disp_h); + } + + LOGI("amvideo_utils_set_virtual_position:: disp_w=%d, disp_h=%d\n", disp_w, disp_h); + + video_global_offset = amvideo_utils_get_global_offset(); + + int free_scale_enable = 0; + int ppscaler_enable = 0; + int freescale_mode_enable = 0; + + if (((disp_w != dev_w) || (disp_h / 2 != dev_h)) && + (video_global_offset == 0)) { + char val[256]; + char freescale_mode[50] = {0}; + char *p; + memset(val, 0, sizeof(val)); + if (video_on_vpp2) { + if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB2, val, sizeof(val)) == 0) { + /* the returned string should be "free_scale_enable:[0x%x]" */ + free_scale_enable = (val[21] == '0') ? 0 : 1; + } + } else if (hdmi_swith_on_vpp1) { + if (amsysfs_get_sysfs_str(FREE_SCALE_PATH_FB1, val, sizeof(val)) == 0) { + /* the returned string should be "free_scale_enable:[0x%x]" */ + free_scale_enable = (val[21] == '0') ? 0 : 1; + } + } else { + if (amsysfs_get_sysfs_str(FREE_SCALE_PATH, val, sizeof(val)) == 0) { + /* the returned string should be "free_scale_enable:[0x%x]" */ + free_scale_enable = (val[21] == '0') ? 0 : 1; + } + } + + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str(PPSCALER_PATH, val, sizeof(val)) == 0) { + /* the returned string should be "current ppscaler mode is disabled/enable" */ + ppscaler_enable = (val[25] == 'd') ? 0 : 1; + } + + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str(FREE_SCALE_MODE_PATH, val, sizeof(val)) == 0) { + /* the returned string should be "free_scale_mode:new/default" */ + p = strstr(val, "current"); + if (p) { + strcpy(freescale_mode, p); + } else { + freescale_mode[0] = '\0'; + } + freescale_mode_enable = (strstr(freescale_mode, "0") == NULL) ? 1 : 0; + } + } + +#ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 + if ((video_on_vpp2 && vertical_panel) || (screen_portrait && video_on_vpp2_new) + || (screen_portrait && hdmi_swith_on_vpp1)) +#else + if ((video_on_vpp2 && vertical_panel) || (screen_portrait && video_on_vpp2_new) + /*||(screen_portrait && hdmi_swith_on_vpp1)*/) +#endif + amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, 0); + else { + amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, (rotation / 90) & 3); + } + + LOGI("set ppmgr angle :%d\n", (rotation / 90) & 3); + /* this is unlikely and only be used when ppmgr does not exist + * to support video rotation. If that happens, we convert the window + * position to non-rotated window position. + * On ICS, this might not work at all because the transparent UI + * window is still drawn is it's direction, just comment out this for now. + */ +#if 0 + if (((rotation == 90) || (rotation == 270)) && (angle_fd < 0)) { + if (dst_h == disp_h) { + int center = x + w / 2; + + if (abs(center - disp_w / 2) < 2) { + /* a centered overlay with rotation, change to full screen */ + dst_x = 0; + dst_y = 0; + dst_w = dev_w; + dst_h = dev_h; + + LOGI("centered overlay expansion"); + } + } + } +#endif + /*if (free_scale_enable == 0 && ppscaler_enable == 0) { + + OSD_DISP_MODE display_mode = OSD_DISP_1080P; + int x_d=0,y_d=0,w_d=0,h_d=0; + LOGI("set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); + + display_mode = get_osd_display_mode(); + get_device_win(display_mode, &x_d, &y_d, &w_d, &h_d); + if (display_mode == OSD_DISP_720P) { + if ((dst_w >= 1279) || (dst_w == 0)) { + dst_x = x_d; + dst_y = y_d; + dst_w = w_d; + dst_h = h_d; + } + else { + dst_x = dst_x*w_d/1280+x_d; + dst_y = dst_y*h_d/720+y_d; + dst_w = dst_w*w_d/1280; + dst_h = dst_h*h_d/720; + } + } + else if ((display_mode==OSD_DISP_1080I)||(display_mode==OSD_DISP_1080P)||(display_mode==OSD_DISP_LVDS1080P)) { + if ((dst_w >= 1919) || (dst_w == 0)) { + dst_x = x_d; + dst_y = y_d; + dst_w = w_d; + dst_h = h_d; + } + else {//scaled to 1080p + dst_x = dst_x*w_d/1920+x_d; + dst_y = dst_y*h_d/1080+y_d; + dst_w = dst_w*w_d/1920; + dst_h = dst_h*h_d/1080; + + LOGI("after scaled to 1080 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); + } + } + else if ((display_mode==OSD_DISP_480I)||(display_mode==OSD_DISP_480P)) { + if ((dst_w >= 719) || (dst_w == 0)) { + dst_x = x_d; + dst_y = y_d; + dst_w = w_d; + dst_h = h_d; + } + else {//scaled to 480p/480i + dst_x = dst_x*w_d/720+x_d; + dst_y = dst_y*h_d/480+y_d; + dst_w = dst_w*w_d/720; + dst_h = dst_h*h_d/480; + + LOGI("after scaled to 480,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); + } + } + else if ((display_mode==OSD_DISP_576I)||(display_mode==OSD_DISP_576P)) { + if ((dst_w >= 719) || (dst_w == 0)) { + dst_x = x_d; + dst_y = y_d; + dst_w = w_d; + dst_h = h_d; + } + else {//scaled to 576p/576i + dst_x = dst_x*w_d/720+x_d; + dst_y = dst_y*h_d/576+y_d; + dst_w = dst_w*w_d/720; + dst_h = dst_h*h_d/576; + + LOGI("after scaled to 576 ,set screen position:x[%d],y[%d],w[%d],h[%d]", dst_x, dst_y, dst_w, dst_h); + } + } + }*/ + + if (free_scale_enable == 0 && ppscaler_enable == 0) { + char val[256]; + char axis_string[100]; + char num[11]="0123456789\0"; + char *first_num, *last_num; + + if (freescale_mode_enable == 1) { + int left = 0, top = 0, right = 0, bottom = 0; + int x = 0, y = 0, w = 0, h = 0; + + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)) == 0 + && (is_panel_mode() == 0)) { + /* the returned string should be "window axis is [a b c d]" */ + first_num = strpbrk(val,num); + if (first_num != NULL) { + memset(axis_string, 0, sizeof(axis_string)); + strcpy(axis_string, first_num); + last_num = strchr(axis_string, ']'); + if (last_num) { + *last_num = '\0'; + } + } + if (sscanf(axis_string, "%d %d %d %d", &left, &top, &right, &bottom) == 4) { + if ((right > 0) && (bottom > 0)) { + x = left; + y = top; + w = right - left + 1; + h = bottom - top + 1; + + dst_x = dst_x * w / dev_w + x; + dst_y = dst_y * h / dev_h + y; + LOGI("after scaled, screen position1: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); + } + } + } + } else { + int x = 0, y = 0, w = 0, h = 0; + int fb_w = 0, fb_h = 0; + int req_2xscale = 0; + + memset(val, 0, sizeof(val)); + if (amsysfs_get_sysfs_str(PPSCALER_RECT, val, sizeof(val)) == 0) { + /* the returned string should be "a b c" */ + if (sscanf(val, "ppscaler rect:\nx:%d,y:%d,w:%d,h:%d", &x, &y, &w, &h) == 4) { + if ((w > 1) && (h > 1)) { + if (fb_w == 0 || fb_h == 0) { + fb_w = 1280; + fb_h = 720; + } + set_scale(x, y, w - 1, h - 1, &dst_x, &dst_y, &dst_w, &dst_h, fb_w, fb_h); + LOGI("after scaled, screen position2: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); + } + } + } + } + } else if (free_scale_enable == 1 && ppscaler_enable == 0) { + char val[256]; + char axis_string[100]; + char num[11]="0123456789\0"; + char *first_num, *last_num; + int left = 0, top = 0, right = 0, bottom = 0; + int x = 0, y = 0, w = 0, h = 0; + int freescale_x = 0, freescale_y = 0, freescale_w = 0, freescale_h = 0; + + int mGetWinAxis = 0; + if (hdmi_swith_on_vpp1) { + mGetWinAxis = amsysfs_get_sysfs_str(WINDOW_AXIS_PATH_FB1, val, sizeof(val)); + } else { + mGetWinAxis = amsysfs_get_sysfs_str(WINDOW_AXIS_PATH, val, sizeof(val)); + } + + if (mGetWinAxis == 0) { + /* the returned string should be "window axis is [a b c d]" */ + first_num = strpbrk(val,num); + if (first_num != NULL) { + memset(axis_string, 0, sizeof(axis_string)); + strcpy(axis_string, first_num); + last_num = strchr(axis_string, ']'); + if (last_num) { + *last_num = '\0'; + } + } + if (sscanf(axis_string, "%d %d %d %d", &left, &top, &right, &bottom) == 4) { + x = left; + y = top; + w = right - left + 1; + h = bottom - top + 1; + + if (hdmi_swith_on_vpp1) { + freescale_x = 0; + freescale_y = 0; + if (screen_portrait) { + freescale_w = disp_h; + freescale_h = disp_w; + } else { + freescale_w = disp_w; + freescale_h = disp_h; + } + } else { + get_axis(FREE_SCALE_AXIS_PATH, &freescale_x, &freescale_y, &freescale_w, &freescale_h); + } + freescale_w = (freescale_w + 1) & (~1); + freescale_h = (freescale_h + 1) & (~1); + + set_scale(x, y, w, h, &dst_x, &dst_y, &dst_w, &dst_h, freescale_w, freescale_h); + LOGI("after scaled, screen position3: %d %d %d %d", dst_x, dst_y, dst_w, dst_h); + } + } + } + + axis[0] = dst_x; + axis[1] = dst_y; + axis[2] = dst_x + dst_w - 1; + axis[3] = dst_y + dst_h - 1; + sprintf(buf, "%d %d %d %d", axis[0], axis[1], axis[2], axis[3]); + amsysfs_set_sysfs_str(VIDEO_AXIS_PATH, buf); + + ret = 0; +OUT: + + LOGI("amvideo_utils_set_virtual_position (corrected):: x=%d y=%d w=%d h=%d\n", dst_x, dst_y, dst_w, dst_h); + amvideo_setscreenmode(); + + return ret; +} + +int amvideo_utils_set_absolute_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation) +{ + LOG_FUNCTION_NAME + char buf[SYSCMD_BUFSIZE]; + int axis[4]; + int video_on_vpp2 = is_video_on_vpp2(); + int vertical_panel = is_vertical_panel(); + + LOGI("amvideo_utils_set_absolute_position:: x=%d y=%d w=%d h=%d\n", x, y, w, h); + + if ((video_on_vpp2 && vertical_panel)) { + amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, 0); + } else { + amsysfs_set_sysfs_int(PPMGR_ANGLE_PATH, (rotation / 90) & 3); + } + + axis[0] = x; + axis[1] = y; + axis[2] = x + w - 1; + axis[3] = y + h - 1; + + sprintf(buf, "%d %d %d %d", axis[0], axis[1], axis[2], axis[3]); + amsysfs_set_sysfs_str(VIDEO_AXIS_PATH, buf); + + return 0; +} + +int amvideo_utils_get_position(int32_t *x, int32_t *y, int32_t *w, int32_t *h) +{ + LOG_FUNCTION_NAME + int axis[4]; + get_axis(VIDEO_AXIS_PATH, &axis[0], &axis[1], &axis[2], &axis[3]); + *x = axis[0]; + *y = axis[1]; + *w = axis[2] - axis[0] + 1; + *h = axis[3] - axis[1] + 1; + + return 0; +} + +int amvideo_utils_get_screen_mode(int *mode) +{ + LOG_FUNCTION_NAME + int video_fd; + int screen_mode = 0; + + video_fd = open(VIDEO_PATH, O_RDWR); + if (video_fd < 0) { + return -1; + } + + ioctl(video_fd, AMSTREAM_IOC_GET_SCREEN_MODE, &screen_mode); + + close(video_fd); + + *mode = screen_mode; + + return 0; +} + +int amvideo_utils_set_screen_mode(int mode) +{ + LOG_FUNCTION_NAME + int screen_mode = mode; + int video_fd; + + video_fd = open(VIDEO_PATH, O_RDWR); + if (video_fd < 0) { + return -1; + } + + ioctl(video_fd, AMSTREAM_IOC_SET_SCREEN_MODE, &screen_mode); + + close(video_fd); + + return 0; +} + +int amvideo_utils_get_video_angle(int *angle) +{ + LOG_FUNCTION_NAME + char buf[SYSCMD_BUFSIZE]; + int angle_val; + if (amsysfs_get_sysfs_str(PPMGR_ANGLE_PATH, buf, sizeof(buf)) == 0) { + if (sscanf(buf, "current angel is %d", &angle_val) == 1) { + *angle = angle_val; + } + } + return 0; +} + +int amvideo_utils_get_hdmi_authenticate(void) +{ + LOG_FUNCTION_NAME + int fd = -1; + int val = -1; + char bcmd[16]; + fd = open(HDMI_AUTHENTICATE_PATH, O_RDONLY); + if (fd >= 0) { + read(fd, bcmd, sizeof(bcmd)); + val = strtol(bcmd, NULL, 10); + close(fd); + } + return val; +} diff --git a/amavutils/Android.mk b/amavutils/Android.mk new file mode 100644 index 0000000..bf1152f --- a/dev/null +++ b/amavutils/Android.mk @@ -0,0 +1,214 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_CFLAGS+=-DNO_USE_SYSWRITE + +ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) + LOCAL_CFLAGS += -DFB_BUFFER_NUM=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) +endif + +ifeq ($(TARGET_EXTERNAL_DISPLAY),true) +ifeq ($(TARGET_SINGLE_EXTERNAL_DISPLAY_USE_FB1),true) +LOCAL_CFLAGS += -DSINGLE_EXTERNAL_DISPLAY_USE_FB1 +endif +endif + +ifeq ($(TARGET_EXTERNAL_DISPLAY),true) +ifeq ($(TARGET_SINGLE_EXTERNAL_DISPLAY_USE_FB1),true) +LOCAL_CFLAGS += -DSINGLE_EXTERNAL_DISPLAY_USE_FB1 +endif +endif + +LOCAL_SRC_LISTS := \ + $(wildcard $(LOCAL_PATH)/*.c) \ + $(wildcard $(LOCAL_PATH)/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediaconfig/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediactl/*.cpp) + +LOCAL_SRC_FILES := $(LOCAL_SRC_LISTS:$(LOCAL_PATH)/%=%) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/../amcodec/include \ + $(JNI_H_INCLUDE) \ + $(TOP)/frameworks/native/services \ + $(TOP)/frameworks/native/include \ + $(TOP)/vendor/amlogic/frameworks/services \ + $(LOCAL_PATH)/../mediaconfig \ + $(TOP)/frameworks/native/libs/nativewindow/include + +LOCAL_CFLAGS += -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libc \ + libdl \ + libbinder \ + liblog \ + libui \ + libgui + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamavutils +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_SHARED_LIBRARY) + + +include $(CLEAR_VARS) +LOCAL_CFLAGS+=-DNO_USE_SYSWRITE + +ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) + LOCAL_CFLAGS += -DFB_BUFFER_NUM=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) +endif + +ifeq ($(TARGET_EXTERNAL_DISPLAY),true) +ifeq ($(TARGET_SINGLE_EXTERNAL_DISPLAY_USE_FB1),true) +LOCAL_CFLAGS += -DSINGLE_EXTERNAL_DISPLAY_USE_FB1 +endif +endif + +LOCAL_CFLAGS += -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +LOCAL_SRC_LISTS := \ + $(wildcard $(LOCAL_PATH)/*.c) \ + $(wildcard $(LOCAL_PATH)/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediaconfig/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediactl/*.cpp) + +LOCAL_SRC_FILES := $(LOCAL_SRC_LISTS:$(LOCAL_PATH)/%=%) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/../amcodec/include \ + $(LOCAL_PATH)/../mediaconfig \ + $(JNI_H_INCLUDE) \ + $(TOP)/frameworks/native/services \ + $(TOP)/frameworks/native/include \ + $(TOP)/vendor/amlogic/frameworks/services \ + $(TOP)/frameworks/native/libs/nativewindow/include + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libc \ + libui \ + libgui \ + libbinder \ + liblog + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamavutils +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_STATIC_LIBRARY) + + +include $(CLEAR_VARS) +LOCAL_CFLAGS+=-DNO_USE_SYSWRITE + +ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) + LOCAL_CFLAGS += -DFB_BUFFER_NUM=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) +endif + +ifeq ($(TARGET_EXTERNAL_DISPLAY),true) +ifeq ($(TARGET_SINGLE_EXTERNAL_DISPLAY_USE_FB1),true) +LOCAL_CFLAGS += -DSINGLE_EXTERNAL_DISPLAY_USE_FB1 +endif +endif + +LOCAL_CFLAGS += -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +LOCAL_SRC_LISTS := \ + $(wildcard $(LOCAL_PATH)/*.c) \ + $(wildcard $(LOCAL_PATH)/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediaconfig/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediactl/*.cpp) + +LOCAL_SRC_FILES := $(LOCAL_SRC_LISTS:$(LOCAL_PATH)/%=%) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/../amcodec/include \ + $(JNI_H_INCLUDE) \ + $(TOP)/frameworks/native/services \ + $(TOP)/frameworks/native/include \ + $(TOP)/vendor/amlogic/frameworks/services \ + $(LOCAL_PATH)/../mediaconfig \ + $(TOP)/frameworks/native/libs/nativewindow/include + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libc \ + libdl \ + libbinder \ + liblog \ + libui \ + libgui \ + libamavutils + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamavutils_alsa +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_SHARED_LIBRARY) + + +include $(CLEAR_VARS) +LOCAL_CFLAGS+=-DNO_USE_SYSWRITE + +ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),) + LOCAL_CFLAGS += -DFB_BUFFER_NUM=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS) +endif + +ifeq ($(TARGET_EXTERNAL_DISPLAY),true) +ifeq ($(TARGET_SINGLE_EXTERNAL_DISPLAY_USE_FB1),true) +LOCAL_CFLAGS += -DSINGLE_EXTERNAL_DISPLAY_USE_FB1 +endif +endif + +LOCAL_CFLAGS += -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) + +LOCAL_SRC_LISTS := \ + $(wildcard $(LOCAL_PATH)/*.c) \ + $(wildcard $(LOCAL_PATH)/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediaconfig/*.cpp) \ + $(wildcard $(LOCAL_PATH)/mediactl/*.cpp) + +LOCAL_SRC_FILES := $(LOCAL_SRC_LISTS:$(LOCAL_PATH)/%=%) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(call include-path-for, graphics corecg) \ + $(LOCAL_PATH)/../amcodec/include \ + $(JNI_H_INCLUDE) \ + $(TOP)/frameworks/native/services \ + $(TOP)/frameworks/native/include \ + $(TOP)/vendor/amlogic/frameworks/services \ + $(LOCAL_PATH)/../mediaconfig \ + $(TOP)/frameworks/native/libs/nativewindow/include + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libc \ + libbinder \ + liblog \ + libui \ + libgui + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamavutils_alsa +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_STATIC_LIBRARY) diff --git a/amavutils/amaudioutils.c b/amavutils/amaudioutils.c new file mode 100644 index 0000000..5db821d --- a/dev/null +++ b/amavutils/amaudioutils.c @@ -0,0 +1,81 @@ +#define LOG_TAG "AmAvutls" + +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <cutils/log.h> +#include <sys/ioctl.h> + +#include <Amsysfsutils.h> +#include "include/amaudioutils.h" + +typedef enum { + AUDIO_DSP_FREQ_NONE = 0, + AUDIO_DSP_FREQ_NORMAL, + AUDIO_DSP_FREQ_HIGH, + AUDIO_DSP_FREQ_MAX +} audiodsp_freqlevel_t; + +#define AUDIODSP_CODEC_MIPS_IN "/sys/class/audiodsp/codec_mips" +#define AUDIODSP_CODEC_MIPS_OUT "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq" +#define AUDIODSP_CLK81_FRQ_LEVEL "/sys/class/aml_clk81/clk81_freq_level" + +#ifndef LOGD +#define LOGV ALOGV +#define LOGD ALOGD +#define LOGI ALOGI +#define LOGW ALOGW +#define LOGE ALOGE +#endif + +#define LOG_FUNCTION_NAME LOGI("%s-%d\n",__FUNCTION__,__LINE__); +///#define LOG_FUNCTION_NAME + +static int set_audiodsp_frelevel(int m1_flag, int coeff) +{ + int val; + if (m1_flag) { + val = amsysfs_get_sysfs_int16(AUDIODSP_CODEC_MIPS_IN); + if (val > 0 && coeff > 0) { + val = coeff * val; + amsysfs_set_sysfs_int(AUDIODSP_CODEC_MIPS_OUT, val); + LOGI("m1:set_cpu_freq_scaling_based_auido %d\n", val); + } else { + LOGI("m1:set_cpu_freq_scaling_based_auido failed\n"); + return -1; + } + } else { + amsysfs_set_sysfs_int(AUDIODSP_CLK81_FRQ_LEVEL, coeff); + } + return 0; +} + +int amaudio_utils_set_dsp_freqlevel(audiodsp_freqlevel_t level, int val) +{ + int m1_cpu_flag = 0; + + LOG_FUNCTION_NAME + + switch (level) { + case AUDIO_DSP_FREQ_NONE: + break; + + case AUDIO_DSP_FREQ_NORMAL: + if (open(AUDIODSP_CODEC_MIPS_IN, O_RDWR) >= 0) { + m1_cpu_flag = 1; + } + set_audiodsp_frelevel(m1_cpu_flag, val); + break; + + case AUDIO_DSP_FREQ_HIGH: + case AUDIO_DSP_FREQ_MAX: + break; + + default: + LOGI("level not in range! level=%d\n", level); + } + + return 0; + +} diff --git a/amavutils/amconfigutils.c b/amavutils/amconfigutils.c new file mode 100644 index 0000000..a1d6978 --- a/dev/null +++ b/amavutils/amconfigutils.c @@ -0,0 +1,263 @@ +/* +libplayer's configs. +changed to HASH and list for fast get,set... + +*/ +#include "include/amconfigutils.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <pthread.h> +static char *amconfigs[MAX_CONFIG] = {0}; +static int amconfig_inited = 0; +#define lock_t pthread_mutex_t +#define lp_lock_init(x,v) pthread_mutex_init(x,v) +#define lp_lock(x) pthread_mutex_lock(x) +#define lp_unlock(x) pthread_mutex_unlock(x) +#define lp_trylock(x) pthread_mutex_trylock(x) +#ifdef ANDROID +#include <cutils/properties.h> + +#include <sys/system_properties.h> +#endif +//#define CONFIG_DEBUG +#ifdef CONFIG_DEBUG +#define DBGPRINT printf +#else +#define DBGPRINT(...) +#endif +static lock_t config_lock; +static char *malloc_config_item() +{ + return malloc(CONFIG_PATH_MAX + CONFIG_VALUE_MAX + 8); +} +static void free_config_item(char *item) +{ + free(item); +} + +static int get_matched_index(const char * path) +{ + int len = strlen(path); + char *ppath; + int i; + + if (len >= CONFIG_PATH_MAX) { + return -40; + } + for (i = 0; i < MAX_CONFIG; i++) { + ppath = amconfigs[i]; + if (ppath) { + ; //DBGPRINT("check match [%d]=%s ?= %s \n",i,path,amconfigs[i]); + } + if (ppath != NULL && strncmp(path, ppath, len) == 0) { + return i; + } + } + return -10; +} +static int get_unused_index(const char * path) +{ + int i; + for (i = 0; i < MAX_CONFIG; i++) { + if (amconfigs[i] == NULL) { + return i; + } + } + return -20; +} +int am_config_init(void) +{ + lp_lock_init(&config_lock, NULL); + lp_lock(&config_lock); + //can do more init here. + memset(amconfigs, 0, sizeof(amconfigs)); + amconfig_inited = 1; + lp_unlock(&config_lock); + return 0; +} +int am_getconfig(const char * path, char *val, const char * def) +{ + int i, ret; + if (!amconfig_inited) { + am_config_init(); + } + val[0] = 0x0;//"\0"; + lp_lock(&config_lock); + i = get_matched_index(path); + if (i >= 0) { + strcpy(val, amconfigs[i] + CONFIG_VALUE_OFF); + } else if (def != NULL) { + strcpy(val, def); + } + lp_unlock(&config_lock); +#ifdef ANDROID + if (i < 0) { + /*get failed,get from android prop settings*/ + ret = property_get(path, val, def); + if (ret > 0) { + i = 1; + } + } +#endif + return strlen(val) ; +} + + +int am_setconfig(const char * path, const char *val) +{ + int i; + char **pppath, *pconfig; + char value[CONFIG_VALUE_MAX]; + char *setval = NULL; + int ret = -1; + if (!amconfig_inited) { + am_config_init(); + } + if (strlen(path) > CONFIG_PATH_MAX) { + return -1; /*too long*/ + } + if (val != NULL) { + setval = strdup(val); + if (strlen(setval) >= CONFIG_VALUE_MAX) { + setval[CONFIG_VALUE_MAX] = '\0'; /*maybe val is too long,cut it*/ + } + } + lp_lock(&config_lock); + i = get_matched_index(path); + if (i >= 0) { + pppath = &amconfigs[i]; + if (!setval || strlen(setval) == 0) { //del value + free_config_item(*pppath); + amconfigs[i] = NULL; + ret = 1; /*just not setting*/ + goto end_out; + } + } else { + i = get_unused_index(path); + if (i < 0) { + ret = i; + goto end_out; + } + if (!setval || strlen(setval) == 0) { //value is nothing.exit now; + ret = 1; /*just not setting*/ + goto end_out; + } + DBGPRINT("used config index=%d,path=%s,val=%s\n", i, path, setval); + pppath = &amconfigs[i]; + *pppath = malloc_config_item(); + if (!*pppath) { + ret = -4; /*no MEM ?*/ + goto end_out; + } + } + pconfig = *pppath; + strcpy(pconfig, path); + strcpy(pconfig + CONFIG_VALUE_OFF, setval); + ret = 0; +end_out: + if (setval != NULL) { + free(setval); + } + lp_unlock(&config_lock); + return ret; +} + +int am_dumpallconfigs(void) +{ + int i; + char *config; + lp_lock(&config_lock); + for (i = 0; i < MAX_CONFIG; i++) { + config = amconfigs[i]; + if (config != NULL) { + fprintf(stderr, "[%d] %s=%s\n", i, config, config + CONFIG_VALUE_OFF); + } + } + lp_unlock(&config_lock); + return 0; +} +int am_setconfig_float(const char * path, float value) +{ + char buf[CONFIG_VALUE_MAX]; + int len; + len = snprintf(buf, CONFIG_VALUE_MAX - 1, "%f", value); + buf[len] = '\0'; + return am_setconfig(path, buf); +} +int am_getconfig_float(const char * path, float *value) +{ + char buf[CONFIG_VALUE_MAX]; + int ret = -1; + + *value = -1.0; + ret = am_getconfig(path, buf, NULL); + if (ret > 0) { + ret = sscanf(buf, "%f", value); + } + return ret > 0 ? 0 : -2; +} + +int am_getconfig_int_def(const char * path, int def) +{ + char buf[CONFIG_VALUE_MAX]; + int ret = -1; + int value = 0; + + ret = am_getconfig(path, buf, NULL); + if (ret > 0) { + ret = sscanf(buf, "%d", &value); + } + + if (ret <= 0) { + value = def; + } + return value; +} + +float am_getconfig_float_def(const char * path, float defvalue) +{ + char buf[CONFIG_VALUE_MAX]; + int ret = -1; + float value = defvalue; + ret = am_getconfig(path, buf, NULL); + if (ret > 0) { + ret = sscanf(buf, "%f", &value); + } + if (ret <= 0) { + value = defvalue; + } + return value; +} + +int am_getconfig_bool(const char * path) +{ + char buf[CONFIG_VALUE_MAX]; + int ret = -1; + + ret = am_getconfig(path, buf, NULL); + if (ret > 0) { + if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) { + return 1; + } + } + return 0; +} + +int am_getconfig_bool_def(const char * path, int def) +{ + char buf[CONFIG_VALUE_MAX]; + int ret = -1; + + ret = am_getconfig(path, buf, NULL); + if (ret > 0) { + if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) { + return 1; + } else { + return 0; + } + } + return def; +} + diff --git a/amavutils/amdisplayutils.c b/amavutils/amdisplayutils.c new file mode 100644 index 0000000..3a3a43d --- a/dev/null +++ b/amavutils/amdisplayutils.c @@ -0,0 +1,174 @@ + +#define LOG_TAG "amavutils" + +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <cutils/log.h> +#include <sys/ioctl.h> +#include "include/Amdisplayutils.h" +#include "include/Amsysfsutils.h" + + +#define FB_DEVICE_PATH "/sys/class/graphics/fb0/virtual_size" +#define SCALE_AXIS_PATH "/sys/class/graphics/fb0/scale_axis" +#define SCALE_PATH "/sys/class/graphics/fb0/scale" +#define SCALE_REQUEST "/sys/class/graphics/fb0/request2XScale" +#define OSD_ROTATION_PATH "/sys/class/graphics/fb0/prot_angle" +#define OSD_ROTATION_ON "/sys/class/graphics/fb0/prot_on" +#define SYSCMD_BUFSIZE 40 + + +//Temp solution, finally we will move out all the functions about display, +//it should be not part of player. +#ifndef FB_BUFFER_NUM +#define FB_BUFFER_NUM (2) +#endif + +#ifndef LOGD +#define LOGV ALOGV +#define LOGD ALOGD +#define LOGI ALOGI +#define LOGW ALOGW +#define LOGE ALOGE +#endif + +//#define LOG_FUNCTION_NAME LOGI("%s-%d\n",__FUNCTION__,__LINE__); +#define LOG_FUNCTION_NAME + +static void get_display_mode(char *mode) +{ + int fd; + char *path = "/sys/class/display/mode"; + if (!mode) { + LOGE("[get_display_mode]Invalide parameter!"); + return; + } + fd = open(path, O_RDONLY); + if (fd >= 0) { + memset(mode, 0, 16); // clean buffer and read 15 byte to avoid strlen > 15 + read(fd, mode, 15); + LOGI("[get_display_mode]mode=%s strlen=%d\n", mode, strlen(mode)); + mode[strlen(mode)] = '\0'; + close(fd); + } else { + sprintf(mode, "%s", "fail"); + }; + LOGI("[get_display_mode]display_mode=%s\n", mode); + return ; +} +int amdisplay_utils_get_size(int *width, int *height) +{ + LOG_FUNCTION_NAME + char buf[SYSCMD_BUFSIZE]; + int disp_w = 0; + int disp_h = 0; + int ret; + ret = amsysfs_get_sysfs_str(FB_DEVICE_PATH, buf, SYSCMD_BUFSIZE); + if (ret < 0) { + return ret; + } + if (sscanf(buf, "%d,%d", &disp_w, &disp_h) == 2) { + LOGI("disp resolution %dx%d\n", disp_w, disp_h); + disp_h = disp_h / FB_BUFFER_NUM; + } else { + return -2;/*format unknow*/ + } + *width = disp_w; + *height = disp_h; + return 0; +} + +#define FB_DEVICE_PATH_FB2 "/sys/class/graphics/fb2/virtual_size" +int amdisplay_utils_get_size_fb2(int *width, int *height) +{ + LOG_FUNCTION_NAME + char buf[SYSCMD_BUFSIZE]; + int disp_w = 0; + int disp_h = 0; + int ret; + ret = amsysfs_get_sysfs_str(FB_DEVICE_PATH_FB2, buf, SYSCMD_BUFSIZE); + if (ret < 0) { + return ret; + } + if (sscanf(buf, "%d,%d", &disp_w, &disp_h) == 2) { + LOGI("disp resolution %dx%d\n", disp_w, disp_h); + disp_h = disp_h / FB_BUFFER_NUM; + } else { + return -2;/*format unknow*/ + } + *width = disp_w; + *height = disp_h; + return 0; +} + +int amdisplay_utils_set_scale_mode(int scale_wx, int scale_hx) +{ + int width, height; + int ret; + int neww, newh; + char buf[40]; + + /*scale mode only support x2,x1*/ + if ((scale_wx != 1 && scale_wx != 2) || (scale_hx != 1 && scale_hx != 2)) { + LOGI("unsupport scaling mode,x1,x2 only\n", scale_wx, scale_hx); + return -1; + } + + if (scale_wx == 2) { + ret = amsysfs_set_sysfs_str(SCALE_REQUEST, "1"); + } else if (scale_wx == 1) { + ret = amsysfs_set_sysfs_str(SCALE_REQUEST, "2"); + } + + if (ret < 0) { + LOGI("set [%s]=[%s] failed\n", SCALE_AXIS_PATH, buf); + return -2; + } + + return ret; +} + + +int amdisplay_utils_get_osd_rotation() +{ + char buf[40]; + int ret; + + ret = amsysfs_get_sysfs_str(OSD_ROTATION_ON, buf, SYSCMD_BUFSIZE); + if ((ret < 0) || strstr(buf, "OFF")) { + return 0;//no rotation+ + } + memset(buf, 0 , 40); + + + ret = amsysfs_get_sysfs_str(OSD_ROTATION_PATH, buf, SYSCMD_BUFSIZE); + if (ret < 0) { + return 0; //no rotation + } + + int rotation = 0; + if (sscanf(buf, "osd_rotate:%d", &rotation) == 1) { + LOGI("get osd rotation %d\n", rotation); + } + + switch (rotation) { + case 0: + rotation = 0; + break; + case 1: + rotation = 90; + break; + case 2: + rotation = 270; + break; + default: + break; + } + + LOGD("amdisplay_utils_get_osd_rotation return %d", rotation); + return rotation; +} + + diff --git a/amavutils/amdrmutils.c b/amavutils/amdrmutils.c new file mode 100644 index 0000000..aae8354 --- a/dev/null +++ b/amavutils/amdrmutils.c @@ -0,0 +1,185 @@ + +#define LOG_TAG "amdrmutils" + +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <cutils/log.h> +#include <cutils/properties.h> +#include <sys/ioctl.h> +#include "include/Amsyswrite.h" +#include "include/amdrmutils.h" + +#define TVP_ENABLE_PATH "/sys/class/codec_mm/tvp_enable" +#define TVP_REGION_PATH "/sys/class/codec_mm/tvp_region" +#define FREE_KEEP_BUFFER_PATH "/sys/class/video/free_keep_buffer" +#define FREE_CMA_BUFFER_PATH "/sys/class/video/free_cma_buffer" +#define VFM_DEF_MAP_PATH "/sys/class/vfm/map" +#define DI_TVP_REGION_PATH "/sys/class/deinterlace/di0/tvp_region" +#define DISABLE_VIDEO_PATH "/sys/class/video/disable_video" + +#ifndef LOGD +#define LOGV ALOGV +#define LOGD ALOGD +#define LOGI ALOGI +#define LOGW ALOGW +#define LOGE ALOGE +#endif + +//#define LOG_FUNCTION_NAME LOGI("%s-%d\n",__FUNCTION__,__LINE__); +#define LOG_FUNCTION_NAME +#define BUF_LEN 512 +#define MAX_REGION 6 + +int set_tvp_enable(int enable) +{ + int fd; + char bcmd[16]; + fd = open(TVP_ENABLE_PATH, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", enable); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int free_keep_buffer(void) +{ + int fd; + char bcmd[16]; + fd = open(FREE_KEEP_BUFFER_PATH, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", 1); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int free_cma_buffer(void) +{ + int fd; + char bcmd[16]; + fd = open(FREE_CMA_BUFFER_PATH, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", 1); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int set_vfmmap_ppmgr_di(int enable) +{ + int fd; + char bcmd[128]; + fd = open(VFM_DEF_MAP_PATH, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "rm default"); + write(fd, bcmd, strlen(bcmd)); + if (enable) + sprintf(bcmd, "add default decoder ppmgr deinterlace amvideo"); + else + sprintf(bcmd, "add default decoder amvideo"); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + return -1; +} + +int set_disable_video(int mode) +{ + int fd; + char bcmd[16]; + fd = open(DISABLE_VIDEO_PATH, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", mode); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int tvp_mm_enable(int flags) +{ + //flags: bit 1---4k ; + int is_4k= flags &TVP_MM_ENABLE_FLAGS_FOR_4K; + free_keep_buffer(); + //set_vfmmap_ppmgr_di(0); + if (is_4k) + set_tvp_enable(2); + else + set_tvp_enable(1); + return 0; + +} + +int tvp_mm_disable(int flags) +{ + set_disable_video(0); + free_keep_buffer(); + //set_vfmmap_ppmgr_di(1); + set_tvp_enable(0); + /*unused flags*/ + return 0; +} + +int tvp_mm_get_mem_region(struct tvp_region* region, int region_size) +{ + int fd, len; + char buf[BUF_LEN]; + uint32_t n=0, i=0, rnum = 0, siz; + uint64_t start=0, end=0; + + //rnum = min(region_size/sizeof(struct tvp_region), MAX_REGION); + rnum = region_size/sizeof(struct tvp_region); + +#if 0 + fd = open(DI_TVP_REGION_PATH, O_RDONLY, 0644); + if (fd >=0 && rnum >= 1) { + len = read(fd, buf, BUF_LEN); + close(fd); + if (3 == sscanf(buf, "segment DI:%llx - %llx (size:0x%x)", + &start, &end, &siz)) { + region->start = start; + region->end = end; + region->mem_flags = 0; + region++; + ALOGE("segment DI: [%llx-%llx]\n", i, start, end); + } + } +#endif + + fd = open(TVP_REGION_PATH, O_RDONLY, 0644); + if (fd >= 0) { + len = read(fd, buf, BUF_LEN); + close(fd); + for (i=0,n=0; (n < len) && (i < rnum); i++, region++) { + if (4 == sscanf(buf+n, "segment%d:%llx - %llx (size:%x)", + &i, &start, &end, &siz)) + { + ALOGE("segment %d: [%llx-%llx]\n", i, start, end); + region->start = start; + region->end = end; + region->mem_flags = 0; + n += strcspn(buf+n, "\n") + 1; + } + } + return i; + } + return -1; +} + + diff --git a/amavutils/ammodule.c b/amavutils/ammodule.c new file mode 100644 index 0000000..d4348e1 --- a/dev/null +++ b/amavutils/ammodule.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ammodule.h> +#include <dlfcn.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <limits.h> +#include <unistd.h> +#define LOG_TAG "ammodule" +#ifdef ANDROID +#include <utils/Log.h> +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) +#define LOGV(...) +#else +#define LOGI printf +#define LOGE printf +#define LOGV printf +#endif +#include <amconfigutils.h> +/** Base path of the hal modules */ +#define AM_LIBRARY_PATH1 "/system/lib/amplayer" +#define AM_LIBRARY_PATH2 "/vendor/lib/amplayer" +#define AM_LIBRARY_SETTING "media.libplayer.modulepath" + +static const char *defaut_path[] = { + AM_LIBRARY_PATH1, + AM_LIBRARY_PATH2, + ""/*real path.*/ + +}; + +static const int PATH_COUNT = + (sizeof(defaut_path) / sizeof(defaut_path[0])); + +/** + * Load the file defined by the variant and if successful + * return the dlopen handle and the hmi. + * @return 0 = success, !0 = failure. + */ +static int amload(const char *path, + const struct ammodule_t **pHmi) +{ + int status; + void *handle; + struct ammodule_t *hmi; + + /* + * load the symbols resolving undefined symbols before + * dlopen returns. Since RTLD_GLOBAL is not or'd in with + * RTLD_NOW the external symbols will not be global + */ + handle = dlopen(path, RTLD_NOW); + if (handle == NULL) { + char const *err_str = dlerror(); + LOGE("amload: module=%s\n%s", path, err_str ? err_str : "unknown"); + status = -EINVAL; + goto done; + } + + /* Get the address of the struct hal_module_info. */ + const char *sym = AMPLAYER_MODULE_INFO_SYM_AS_STR; + hmi = (struct ammodule_t *)dlsym(handle, sym); + if (hmi == NULL) { + LOGE("amload: couldn't find symbol %s", sym); + status = -EINVAL; + goto done; + } + + hmi->dso = handle; + + /* success */ + status = 0; + if (hmi->tag != AMPLAYER_MODULE_TAG || + hmi->version_major != AMPLAYER_API_MAIOR) { + status = -1; + LOGE("module tag,api unsupport tag=%d,expect=%d api=%d.%d,expect=%d.%d\n", + hmi->tag, AMPLAYER_MODULE_TAG, + hmi->version_major, hmi->version_minor, + AMPLAYER_API_MAIOR, AMPLAYER_API_MINOR); + } +done: + if (status != 0) { + hmi = NULL; + if (handle != NULL) { + dlclose(handle); + handle = NULL; + } + } else { + LOGV("loaded module path=%s hmi=%p handle=%p", + path, *pHmi, handle); + } + + *pHmi = hmi; + + return status; +} + +int ammodule_load_module(const char *modulename, const struct ammodule_t **module) +{ + int status = -ENOENT;; + int i; + const struct ammodule_t *hmi = NULL; + char prop[PATH_MAX]; + char path[PATH_MAX]; + char name[PATH_MAX]; + const char *prepath = NULL; + + snprintf(name, PATH_MAX, "%s", modulename); + + for (i = -1 ; i < PATH_COUNT; i++) { + if (i >= 0) { + prepath = defaut_path[i]; + } else { + if (am_getconfig(AM_LIBRARY_SETTING, prop, NULL) <= 0) { + continue; + } + prepath = prop; + } + snprintf(path, sizeof(path), "%s/lib%s.so", + prepath, name); + if (access(path, R_OK) == 0) { + break; + } + snprintf(path, sizeof(path), "%s/%s.so", + prepath, name); + if (access(path, R_OK) == 0) { + break; + } + + snprintf(path, sizeof(path), "%s/%s", + prepath, name); + if (access(path, R_OK) == 0) { + break; + } + snprintf(path, sizeof(path), "%s", + name); + if (access(path, R_OK) == 0) { + break; + } + } + + status = -ENOENT; + if (i < PATH_COUNT) { + /* load the module, if this fails, we're doomed, and we should not try + * to load a different variant. */ + status = amload(path, module); + } + LOGI("load mode %s,on %s %d\n", modulename, path, status); + return status; +} + +int ammodule_open_module(struct ammodule_t *module) +{ + int ret = -1000; + + if (module->methods) { + ret = module->methods->init(module, 0); + } + if (ret != 0) { + LOGE("open module (%s) failed ret(%d)\n", module->name, ret); + } else { + LOGI("open module success,\n\tname:%s\n\t%s\n", module->name, module->descript); + } + return 0; +} +int ammodule_match_check(const char* filefmtstr, const char* fmtsetting) +{ + const char * psets = fmtsetting; + const char *psetend; + int psetlen = 0; + char codecstr[64] = ""; + if (filefmtstr == NULL || fmtsetting == NULL) { + return 0; + } + + while (psets && psets[0] != '\0') { + psetlen = 0; + psetend = strchr(psets, ','); + if (psetend != NULL && psetend > psets && psetend - psets < 64) { + psetlen = psetend - psets; + memcpy(codecstr, psets, psetlen); + codecstr[psetlen] = '\0'; + psets = &psetend[1]; //skip ";" + } else { + strcpy(codecstr, psets); + psets = NULL; + } + if (strlen(codecstr) > 0) { + if (strstr(filefmtstr, codecstr) != NULL) { + return 1; + } + } + } + return 0; +} + +int ammodule_simple_load_module(char* name) +{ + int ret; + struct ammodule_t *module; + ret = ammodule_load_module(name, &module); + if (ret == 0) { + ret = ammodule_open_module(module); + } + return ret; + +}
\ No newline at end of file diff --git a/amavutils/amsufaceutils.cpp b/amavutils/amsufaceutils.cpp new file mode 100644 index 0000000..9e2b310 --- a/dev/null +++ b/amavutils/amsufaceutils.cpp @@ -0,0 +1,21 @@ +#include "utils/Log.h" +#include <android/native_window.h> +#include "Amsufaceutils.h" + +namespace android +{ + + +int InitVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer) +{ + sp<ANativeWindow> mNativeWindow = NULL; + if (bufferProducer == NULL) + return -1; + mNativeWindow = new Surface(bufferProducer); + ///native_window_set_usage(mNativeWindow.get(), GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP | GRALLOC_USAGE_AML_VIDEO_OVERLAY); + native_window_set_buffers_format(mNativeWindow.get(), WINDOW_FORMAT_RGBA_8888); + native_window_set_scaling_mode(mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_FREEZE); + return 0; +} + +} diff --git a/amavutils/amsysfsutils.c b/amavutils/amsysfsutils.c new file mode 100644 index 0000000..230e233 --- a/dev/null +++ b/amavutils/amsysfsutils.c @@ -0,0 +1,278 @@ + +#define LOG_TAG "amavutils" + +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <cutils/log.h> +#include <sys/ioctl.h> +#include "include/Amsysfsutils.h" +#include <Amsyswrite.h> +#include <cutils/properties.h> +#include <media_ctl.h> + +#ifndef LOGD +#define LOGV ALOGV +#define LOGD ALOGD +#define LOGI ALOGI +#define LOGW ALOGW +#define LOGE ALOGE +#endif + +#ifndef NO_USE_SYSWRITE //added by lifengcao for startup video +#define USE_SYSWRITE +#endif + + +#ifndef USE_SYSWRITE +int amsysfs_set_sysfs_str(const char *path, const char *val) +{ + int fd,ret; + int bytes; + ret = mediactl_set_str_func(path,val); + if (ret == UnSupport) + { + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + bytes = write(fd, val, strlen(val)); + close(fd); + return 0; + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + return -1; +} + else return ret; +} +int amsysfs_get_sysfs_str(const char *path, char *valstr, int size) +{ + int fd,ret; + ret = mediactl_get_str_func(path, valstr, size); + if (ret == UnSupport) + { + fd = open(path, O_RDONLY); + if (fd >= 0) { + memset(valstr, 0, size); + read(fd, valstr, size - 1); + valstr[strlen(valstr)] = '\0'; + close(fd); + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + sprintf(valstr, "%s", "fail"); + return -1; + }; + //LOGI("get_sysfs_str=%s\n", valstr); + return 0; +} + else return ret; +} +int amsysfs_set_sysfs_int(const char *path, int val) +{ + int fd,ret; + int bytes; + char bcmd[16]; + ret = mediactl_set_int_func(path,val); + if (ret == UnSupport) + { + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", val); + bytes = write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + return -1; +} + else return ret; +} +int amsysfs_get_sysfs_int(const char *path) +{ + int fd,ret; + int val = 0; + char bcmd[16]; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + fd = open(path, O_RDONLY); + if (fd >= 0) { + read(fd, bcmd, sizeof(bcmd)); + val = strtol(bcmd, NULL, 10); + close(fd); + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + return val; +} + else return ret; +} +int amsysfs_set_sysfs_int16(const char *path, int val) +{ + int fd,ret; + int bytes; + ret = mediactl_set_int_func(path,val); + if (ret == UnSupport) { + char bcmd[16]; + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "0x%x", val); + bytes = write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + + return -1; +} + else return ret; +} +int amsysfs_get_sysfs_int16(const char *path) +{ + int fd,ret; + int val = 0; + char bcmd[16]; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + fd = open(path, O_RDONLY); + if (fd >= 0) { + read(fd, bcmd, sizeof(bcmd)); + val = strtol(bcmd, NULL, 16); + close(fd); + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + return val; +} + else return ret; +} +unsigned long amsysfs_get_sysfs_ulong(const char *path) +{ + int fd,ret; + char bcmd[24] = ""; + unsigned long num = 0; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + if ((fd = open(path, O_RDONLY)) >= 0) { + read(fd, bcmd, sizeof(bcmd)); + num = strtoul(bcmd, NULL, 0); + close(fd); + } else { + LOGE("unable to open file %s,err: %s", path, strerror(errno)); + } + return num; + } + else return ret; +} +void amsysfs_write_prop(const char* key, const char* value) +{ + int ret = 0; + ret = property_set(key,value); +} +#else +int amsysfs_set_sysfs_str(const char *path, const char *val) +{ + int ret = 0; + ret = mediactl_set_str_func(path,val); + if (ret == UnSupport) { + LOGD("%s path =%s,val=%s\n",__FUNCTION__,path,val); + return amSystemWriteWriteSysfs(path, val); + } + else return ret; + +} +int amsysfs_get_sysfs_str(const char *path, char *valstr, int size) +{ + int ret = 0; + ret = mediactl_get_str_func(path, valstr, size); + if (ret == UnSupport) { + LOGD("%s path =%s,val=%s,size=%d\n",__FUNCTION__,path,valstr,size); + if (amSystemWriteReadNumSysfs(path, valstr, size) != -1) { + return 0; + } + sprintf(valstr, "%s", "fail"); + return -1; + } + else return ret; +} + +int amsysfs_set_sysfs_int(const char *path, int val) +{ + int ret = 0; + ret = mediactl_set_int_func(path,val); + if (ret == UnSupport) { + LOGD("%s path =%s,val=%d\n",__FUNCTION__,path,val); + char bcmd[16] = ""; + sprintf(bcmd, "%d", val); + return amSystemWriteWriteSysfs(path, bcmd); + } + else return ret; +} + +int amsysfs_get_sysfs_int(const char *path) +{ + int ret = 0; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + LOGD("%s path =%s\n",__FUNCTION__,path); + char bcmd[16] = ""; + int val = 0; + if (amSystemWriteReadSysfs(path, bcmd) == 0) { + val = strtol(bcmd, NULL, 10); + } + return val; + } + else return ret; +} + +int amsysfs_set_sysfs_int16(const char *path, int val) +{ + int ret = 0; + ret = mediactl_set_int_func(path,val); + if (ret == UnSupport) { + LOGD("%s path =%s,val=%d\n",__FUNCTION__,path,val); + char bcmd[16] = ""; + sprintf(bcmd, "0x%x", val); + return amSystemWriteWriteSysfs(path, bcmd); + } + else return ret; +} + +int amsysfs_get_sysfs_int16(const char *path) +{ + int ret = 0; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + LOGD("%s path =%s\n",__FUNCTION__,path); + char bcmd[16] = ""; + int val = 0; + if (amSystemWriteReadSysfs(path, bcmd) == 0) { + val = strtol(bcmd, NULL, 16); + } + return val; + } + else return ret; +} + +unsigned long amsysfs_get_sysfs_ulong(const char *path) +{ + int ret = 0; + ret = mediactl_get_int_func(path); + if (ret == UnSupport) { + LOGD("%s path =%s\n",__FUNCTION__,path); + char bcmd[24] = ""; + int val = 0; + if (amSystemWriteReadSysfs(path, bcmd) == 0) { + val = strtoul(bcmd, NULL, 0); + } + return val; + } + else return ret; +} +void amsysfs_write_prop(const char* key, const char* value) +{ + amSystemWriteSetProperty(key,value); +} +#endif + diff --git a/amavutils/amthreadpool.c b/amavutils/amthreadpool.c new file mode 100644 index 0000000..073c854 --- a/dev/null +++ b/amavutils/amthreadpool.c @@ -0,0 +1,467 @@ +#include <amthreadpool.h> +#include <itemlist.h> + +#define LOG_TAG "amthreadpool" +#include <utils/Log.h> + +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> + + +static struct itemlist threadpool_list; +static struct itemlist threadpool_threadlist; +#define MAX_THREAD_DEPTH 8 + +#define T_ASSERT_TRUE(x)\ + do {\ + if (!(x))\ + ALOGE("amthreadpool error at %d\n",__LINE__);\ + } while(0) + +#define T_ASSERT_NO_NULL(p) T_ASSERT_TRUE((p)!=NULL) + +typedef struct threadpool { + pthread_t pid; + struct itemlist threadlist; +} threadpool_t; + +typedef struct threadpool_thread_data { + pthread_t pid; + void * (*start_routine)(void *); + void * arg; + pthread_t ppid[MAX_THREAD_DEPTH]; + threadpool_t *pool; + pthread_mutex_t pthread_mutex; + pthread_cond_t pthread_cond; + int on_requred_exit; + int thread_inited; +} threadpool_thread_data_t; +#define POOL_OF_ITEM(item) ((threadpool_t *)(item)->extdata[0]) +#define THREAD_OF_ITEM(item) ((threadpool_thread_data_t *)(item)->extdata[0]) + +static int amthreadpool_release(pthread_t pid); +static threadpool_t * amthreadpool_create_pool(pthread_t pid); + +static threadpool_t * amthreadpool_findthead_pool(pthread_t pid) +{ + struct item *item; + item = itemlist_find_match_item(&threadpool_list, pid); + if (item) { + return (threadpool_t *)item->extdata[0]; + } + return NULL; +} + +static threadpool_thread_data_t * amthreadpool_findthead_thread_data(pthread_t pid) +{ + struct item *item; + item = itemlist_find_match_item(&threadpool_threadlist, pid); + if (item) { + return (threadpool_thread_data_t *)item->extdata[0]; + } + return NULL; +} + +/*creat thread pool for main thread*/ +static threadpool_t * amthreadpool_create_pool(pthread_t pid) +{ + struct item *poolitem; + threadpool_t *pool; + int ret = -1; + unsigned long exdata[2]; + pool = malloc(sizeof(threadpool_t)); + if (!pool) { + ALOGE("malloc pool data failed\n"); + return NULL; + } + memset(pool, 0, sizeof(threadpool_t)); + pool->pid = pid; + if (pid == 0) { + pool->pid = pthread_self(); + } + pool->threadlist.max_items = 0; + pool->threadlist.item_ext_buf_size = 0; + pool->threadlist.muti_threads_access = 1; + pool->threadlist.reject_same_item_data = 1; + itemlist_init(&pool->threadlist); + exdata[0] = (unsigned long)pool; + itemlist_add_tail_data_ext(&threadpool_list, pool->pid, 1, exdata); + + return pool; +} + +static int amthreadpool_pool_add_thread(threadpool_t *pool, unsigned long pid, threadpool_thread_data_t* thread) +{ + int ret; + unsigned long exdata[2]; + exdata[0] = (unsigned long)thread; + if (pool) { + ret = itemlist_add_tail_data_ext(&pool->threadlist, thread->pid, 1, exdata); + } else { + pool = amthreadpool_create_pool(pid); + thread->pool = pool; + } + ret |= itemlist_add_tail_data_ext(&threadpool_threadlist, thread->pid, 1, exdata); + return ret; +} +static int amthreadpool_pool_del_thread(pthread_t pid) +{ + threadpool_t *pool; + threadpool_thread_data_t* t1, *t2; + int ret = 0; + struct item *item; + item = itemlist_get_match_item(&threadpool_threadlist, pid); + if (!item) { + return -2; /*freed before*/ + } + t1 = THREAD_OF_ITEM(item); + item_free(item); + T_ASSERT_NO_NULL(t1); + pool = t1->pool; + T_ASSERT_NO_NULL(pool); + item = itemlist_get_match_item(&pool->threadlist, pid); + if (item) { + T_ASSERT_NO_NULL(item); + t2 = THREAD_OF_ITEM(item); + T_ASSERT_NO_NULL(t2); + if (t1 != t2) { + ALOGE("%d thread data not mached, %p!=%p\n", (int)pid, t1, t2); + } + item_free(item); + } + pthread_cond_destroy(&t1->pthread_cond); + pthread_mutex_destroy(&t1->pthread_mutex); + free(t1); + if (pool->pid == pid) { + amthreadpool_release(pid); + } + return ret; +} + + +static int amthreadpool_thread_wake_t(threadpool_thread_data_t*t, int trycancel) +{ + int ret; + pthread_mutex_lock(&t->pthread_mutex); + t->on_requred_exit = trycancel; + ret = pthread_cond_signal(&t->pthread_cond); + pthread_mutex_unlock(&t->pthread_mutex); + return ret; +} +static int64_t amthreadpool_gettime(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +} + +int amthreadpool_thread_usleep_in_monotonic(int us) +{ + pthread_t pid = pthread_self(); + struct timespec pthread_ts, tnow; + int64_t us64 = us; + threadpool_thread_data_t *t = amthreadpool_findthead_thread_data(pid); + int ret = 0; +/* 64bit compiler do not have pthread_cond_timedwait_monotonic_np */ +#ifndef __aarch64__ + if (!t) { + ///ALOGE("%lu thread sleep data not found!!!\n", pid); + usleep(us);//for not deadlock. + return 0; + } + if (t->on_requred_exit > 1) { + if (us64 < 100 * 1000) { + us64 = 100 * 1000; + } + t->on_requred_exit--; /*if on_requred_exit,do less sleep till 1.*/ + } + clock_gettime(CLOCK_MONOTONIC, &tnow); + pthread_ts.tv_sec = tnow.tv_sec + (us64 + tnow.tv_nsec / 1000) / 1000000; + pthread_ts.tv_nsec = (us64 * 1000 + tnow.tv_nsec) % 1000000000; + pthread_mutex_lock(&t->pthread_mutex); + ret = pthread_cond_timedwait_monotonic_np(&t->pthread_cond, &t->pthread_mutex, &pthread_ts); + + pthread_mutex_unlock(&t->pthread_mutex); + return ret; +#else + usleep(us);//for not deadlock. + return 0; +#endif + +} + + +int amthreadpool_thread_usleep_in(int us) +{ + pthread_t pid = pthread_self(); + struct timespec pthread_ts; + struct timeval now; + int64_t us64 = us; + threadpool_thread_data_t *t = amthreadpool_findthead_thread_data(pid); + int ret = 0; + + if (!t) { + ///ALOGE("%lu thread sleep data not found!!!\n", pid); + usleep(us);//for not deadlock. + return 0; + } + if (t->on_requred_exit > 1) { + if (us64 < 100 * 1000) { + us64 = 100 * 1000; + } + t->on_requred_exit--; /*if on_requred_exit,do less sleep till 1.*/ + } + ret = gettimeofday(&now, NULL); + pthread_ts.tv_sec = now.tv_sec + (us64 + now.tv_usec) / 1000000; + pthread_ts.tv_nsec = ((us64 + now.tv_usec) * 1000) % 1000000000; + pthread_mutex_lock(&t->pthread_mutex); + ret = pthread_cond_timedwait(&t->pthread_cond, &t->pthread_mutex, &pthread_ts); + pthread_mutex_unlock(&t->pthread_mutex); + return ret; +} +int amthreadpool_thread_usleep_debug(int us, const char *func, int line) +{ + + int64_t starttime = amthreadpool_gettime(); + int64_t endtime; + int ret; + +#ifdef AMTHREADPOOL_SLEEP_US_MONOTONIC + ret = amthreadpool_thread_usleep_in_monotonic(us); +#else + ret = amthreadpool_thread_usleep_in(us); +#endif + endtime = amthreadpool_gettime(); + if ((endtime - starttime - us) > 100 * 1000) { + ALOGE("***amthreadpool_thread_usleep wast more time wait %d us, real %lld us\n", us, (int64_t)(endtime - starttime)); + } + return ret; +} + +int amthreadpool_thread_wake(pthread_t pid) +{ + threadpool_thread_data_t *t = amthreadpool_findthead_thread_data(pid); + if (!t) { + ALOGE("%lu wake thread data not found!!!\n", pid); + return -1; + } + return amthreadpool_thread_wake_t(t, t->on_requred_exit); +} +int amthreadpool_on_requare_exit(pthread_t pid) +{ + unsigned long rpid = pid != 0 ? pid : pthread_self(); + threadpool_thread_data_t *t = amthreadpool_findthead_thread_data(rpid); + if (!t) { + return 0; + } + if (t->on_requred_exit) { + ///ALOGI("%lu name on try exit.\n", pid); + } + return !!t->on_requred_exit; +} + +static int amthreadpool_pool_thread_cancel_l1(pthread_t pid, int cancel, int allthreads) +{ + struct itemlist *itemlist; + threadpool_thread_data_t *t, *t1; + struct item *item = NULL; + threadpool_t *pool; + t = amthreadpool_findthead_thread_data(pid); + if (!t) { + ALOGE("%lu pool data not found!!!\n", pid); + return 0; + } + pool = t->pool; + if (allthreads && pool && pool->pid == pid) { + itemlist = &pool->threadlist; + FOR_EACH_ITEM_IN_ITEMLIST(itemlist, item) + t1 = THREAD_OF_ITEM(item); + amthreadpool_thread_wake_t(t1, cancel); + FOR_ITEM_END(itemlist); + } + amthreadpool_thread_wake_t(t, cancel); + ///amthreadpool_system_dump_info(); + return 0; +} + +int amthreadpool_pool_thread_cancel(pthread_t pid) +{ + return amthreadpool_pool_thread_cancel_l1(pid, 3, 1); +} + +int amthreadpool_pool_thread_uncancel(pthread_t pid) +{ + return amthreadpool_pool_thread_cancel_l1(pid, 0, 1); +} +int amthreadpool_thread_cancel(pthread_t pid) +{ + return amthreadpool_pool_thread_cancel_l1(pid, 3, 0); +} +int amthreadpool_thread_uncancel(pthread_t pid) +{ + return amthreadpool_pool_thread_cancel_l1(pid, 0, 0); +} + +static int amthreadpool_release(pthread_t pid) +{ + struct item *poolitem; + threadpool_t *pool; + poolitem = itemlist_get_match_item(&threadpool_list, pid); + if (poolitem) { + pool = POOL_OF_ITEM(poolitem); + itemlist_deinit(&pool->threadlist); + free((void *)pool); + item_free(poolitem); + } + return 0; +} + + +void * amthreadpool_start_thread(void *arg) +{ + void *ret; + threadpool_thread_data_t *t = (threadpool_thread_data_t *)arg; + { + threadpool_thread_data_t *thread_p; + threadpool_t *pool = NULL; + int i; + t->pid = pthread_self(); + thread_p = amthreadpool_findthead_thread_data(t->ppid[0]); + if (thread_p) { + pool = thread_p->pool; + for (i = 0; i < MAX_THREAD_DEPTH - 1; i++) { + if (!thread_p->ppid[i]) { + break; + } + t->ppid[i + 1] = thread_p->ppid[i]; + } + t->pool = pool; + + } + amthreadpool_pool_add_thread(pool, t->pid, t); + } + pthread_mutex_lock(&t->pthread_mutex); + t->thread_inited = 1; + pthread_cond_signal(&t->pthread_cond); + pthread_mutex_unlock(&t->pthread_mutex); + ret = t->start_routine(t->arg); + return ret; +} + +int amthreadpool_pthread_create_name(pthread_t * newthread, + __const pthread_attr_t * attr, + void * (*start_routine)(void *), + void * arg, const char *name) +{ + pthread_t pid = pthread_self(); + pthread_t subpid; + int ret; + + threadpool_thread_data_t *t = malloc(sizeof(threadpool_thread_data_t)); + if (!t) { + ALOGE("malloc threadpool_thread_data_t data failed\n"); + return -100; + } + memset(t, 0, sizeof(threadpool_thread_data_t)); + t->start_routine = start_routine; + t->arg = arg; + t->ppid[0] = pid; + t->thread_inited = 0; + pthread_mutex_init(&t->pthread_mutex, NULL); + pthread_cond_init(&t->pthread_cond, NULL); + ret = pthread_create(&subpid, attr, amthreadpool_start_thread, (void *)t); + if (ret == 0) { + *newthread = subpid; + if (name) { + pthread_setname_np(pid, name); + } + pthread_mutex_lock(&t->pthread_mutex); + while (t->thread_inited == 0) + pthread_cond_wait(&t->pthread_cond, &t->pthread_mutex); + pthread_mutex_unlock(&t->pthread_mutex); + } + return ret; +} + + + +int amthreadpool_pthread_create(pthread_t * newthread, + __const pthread_attr_t * attr, + void * (*start_routine)(void *), + void * arg) +{ + return amthreadpool_pthread_create_name(newthread, attr, start_routine, arg, NULL); +} + +int amthreadpool_pthread_join(pthread_t thid, void ** ret_val) +{ + int ret; + ret = pthread_join(thid, ret_val); + amthreadpool_pool_del_thread(thid); + return ret; +} + + + + + +/*creat thread pool system init*/ +int amthreadpool_system_init(void) +{ + static int inited = 0; + if (inited) { + return 0; + } + inited ++; + threadpool_list.max_items = 0; + threadpool_list.item_ext_buf_size = 0; + threadpool_list.muti_threads_access = 1; + threadpool_list.reject_same_item_data = 1; + itemlist_init(&threadpool_list); + + threadpool_threadlist.max_items = 0; + threadpool_threadlist.item_ext_buf_size = 0; + threadpool_threadlist.muti_threads_access = 1; + threadpool_threadlist.reject_same_item_data = 1; + itemlist_init(&threadpool_threadlist); + return 0; +} + + +int amthreadpool_system_dump_info(void) +{ + threadpool_thread_data_t *t; + threadpool_t *pool; + struct item *item = NULL; + struct item *item1 = NULL; + ALOGI("------------amthreadpool_system_dump_info----------START\n"); + ALOGI("pool & threads:\n"); + FOR_EACH_ITEM_IN_ITEMLIST(&threadpool_list, item) { + pool = POOL_OF_ITEM(item); + ALOGI("pool:%p\n", pool); + ALOGI("--tpid:%lu\n", pool->pid); + FOR_EACH_ITEM_IN_ITEMLIST(&pool->threadlist, item1) { + t = THREAD_OF_ITEM(item1); + ALOGI("--tpid:%lu\n", t->pid); + //ALOGI("----name=%p\n",amthreadpool_thread_name(t->pid)); + ALOGI("----ppid=%lu,%lu,%lu,%lu,%lu", t->ppid[0], t->ppid[1], t->ppid[2], t->ppid[3], t->ppid[4]); + ALOGI("----pool:%p\n", t->pool); + ALOGI("----on_requred_exit:%d\n", t->on_requred_exit); + } + FOR_ITEM_END(&pool->threadlist); + } + FOR_ITEM_END(&threadpool_list); + ALOGI("all threads:\n"); + FOR_EACH_ITEM_IN_ITEMLIST(&threadpool_threadlist, item) { + t = THREAD_OF_ITEM(item); + ALOGI("--tpid:%lu\n", t->pid); + //ALOGI("----name=%p\n",amthreadpool_thread_name(t->pid)); + ALOGI("----ppid=%lu,%lu,%lu,%lu,%lu", t->ppid[0], t->ppid[1], t->ppid[2], t->ppid[3], t->ppid[4]); + ALOGI("----pool:%p\n", t->pool); + ALOGI("----on_requred_exit:%d\n", t->on_requred_exit); + } + FOR_ITEM_END(&threadpool_threadlist); + ALOGI("------------amthreadpool_system_dump_info----------END\n"); + return 0; +} diff --git a/amavutils/include/Amavutils.h b/amavutils/include/Amavutils.h new file mode 100644 index 0000000..7fc46f2 --- a/dev/null +++ b/amavutils/include/Amavutils.h @@ -0,0 +1,15 @@ + +#ifndef AMAV_UTILS_H +#define AMAV_UTILS_H + +#include "Amsysfsutils.h" +#include "Amdisplayutils.h" +#include "Amvideoutils.h" +#include "video_ctl.h" +#include "tsync_ctl.h" +#include "sub_ctl.h" +#include "media_ctl.h" +#include "audio_ctl.h" +#include "vfm_ctl.h" +#endif + diff --git a/amavutils/include/Amdisplayutils.h b/amavutils/include/Amdisplayutils.h new file mode 100644 index 0000000..a27c9cb --- a/dev/null +++ b/amavutils/include/Amdisplayutils.h @@ -0,0 +1,20 @@ + +#ifndef AMDISPLAY_UTILS_H +#define AMDISPLAY_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + int amdisplay_utils_get_size(int *width, int *height); + int amdisplay_utils_get_size_fb2(int *width, int *height); + + /*scale osd mode ,only support x1 x2*/ + int amdisplay_utils_set_scale_mode(int scale_wx, int scale_hx); + int amdisplay_utils_get_osd_rotation(); +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/amavutils/include/Amsufaceutils.h b/amavutils/include/Amsufaceutils.h new file mode 100644 index 0000000..fb21de1 --- a/dev/null +++ b/amavutils/include/Amsufaceutils.h @@ -0,0 +1,12 @@ +#ifndef AMSURFACE_UTILS_HEADER_SS +#define AMSURFACE_UTILS_HEADER_SS + +#include <gui/Surface.h> + + +namespace android +{ + +int InitVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer); +} +#endif diff --git a/amavutils/include/Amsysfsutils.h b/amavutils/include/Amsysfsutils.h new file mode 100644 index 0000000..3584ac4 --- a/dev/null +++ b/amavutils/include/Amsysfsutils.h @@ -0,0 +1,22 @@ + +#ifndef AMSYSFS_UTILS_H +#define AMSYSFS_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + int amsysfs_set_sysfs_str(const char *path, const char *val); + int amsysfs_get_sysfs_str(const char *path, char *valstr, int size); + int amsysfs_set_sysfs_int(const char *path, int val); + int amsysfs_get_sysfs_int(const char *path); + int amsysfs_set_sysfs_int16(const char *path, int val); + int amsysfs_get_sysfs_int16(const char *path); + unsigned long amsysfs_get_sysfs_ulong(const char *path); + void amsysfs_write_prop(const char* key, const char* value); +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/amavutils/include/Amsyswrite.h b/amavutils/include/Amsyswrite.h new file mode 100644 index 0000000..b456002 --- a/dev/null +++ b/amavutils/include/Amsyswrite.h @@ -0,0 +1,27 @@ +#ifndef AMSYSWRITE_UTILS_H +#define AMSYSWRITE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + int amSystemWriteGetProperty(const char* key, char* value); + int amSystemWriteGetPropertyStr(const char* key, char* def, char* value); + int amSystemWriteGetPropertyInt(const char* key, int def); + long amSystemWriteGetPropertyLong(const char* key, long def); + int amSystemWriteGetPropertyBool(const char* key, int def); + void amSystemWriteSetProperty(const char* key, const char* value); + int amSystemWriteReadSysfs(const char* path, char* value); + int amSystemWriteReadNumSysfs(const char* path, char* value, int size); + int amSystemWriteWriteSysfs(const char* path, char* value); + +#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0 + int amSystemControlSetNativeWindowRect(int x, int y, int w, int h); +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/amavutils/include/Amvideocap.h b/amavutils/include/Amvideocap.h new file mode 100644 index 0000000..92ad575 --- a/dev/null +++ b/amavutils/include/Amvideocap.h @@ -0,0 +1,82 @@ +#ifndef __AMVIDEOCAP_HEADHER_ +#define __AMVIDEOCAP_HEADHER_ +#define AMVIDEOCAP_IOC_MAGIC 'V' +#include <linux/videodev2.h> + +#define CAP_FLAG_AT_CURRENT 0 +#define CAP_FLAG_AT_TIME_WINDOW 1 +#define CAP_FLAG_AT_END 2 + + + +/* +format see linux/ge2d/ge2d.h +like: +GE2D_FORMAT_S24_RGB +*/ +#define ENDIAN_SHIFT 24 +#define LITTLE_ENDIAN (1 << ENDIAN_SHIFT) +#define FMT_S24_RGB (LITTLE_ENDIAN|0x00200) /* 10_00_0_00_0_00 */ +#define FMT_S16_RGB (LITTLE_ENDIAN|0x00100) /* 01_00_0_00_0_00 */ +#define FMT_S32_RGBA (LITTLE_ENDIAN|0x00300) /* 11_00_0_00_0_00 */ + +#define COLOR_MAP_SHIFT 20 +#define COLOR_MAP_MASK (0xf << COLOR_MAP_SHIFT) +/* 16 bit */ +#define COLOR_MAP_RGB565 (5 << COLOR_MAP_SHIFT) +/* 24 bit */ +#define COLOR_MAP_RGB888 (0 << COLOR_MAP_SHIFT) +#define COLOR_MAP_BGR888 (5 << COLOR_MAP_SHIFT) +/* 32 bit */ +#define COLOR_MAP_RGBA8888 (0 << COLOR_MAP_SHIFT) +#define COLOR_MAP_ARGB8888 (1 << COLOR_MAP_SHIFT) +#define COLOR_MAP_ABGR8888 (2 << COLOR_MAP_SHIFT) +#define COLOR_MAP_BGRA8888 (3 << COLOR_MAP_SHIFT) + +/*16 bit*/ +#define FORMAT_S16_RGB_565 (FMT_S16_RGB | COLOR_MAP_RGB565) +/*24 bit*/ +#define FORMAT_S24_BGR (FMT_S24_RGB | COLOR_MAP_BGR888) +#define FORMAT_S24_RGB (FMT_S24_RGB | COLOR_MAP_RGB888) +/*32 bit*/ +#define FORMAT_S32_ARGB (FMT_S32_RGBA | COLOR_MAP_ARGB8888) +#define FORMAT_S32_ABGR (FMT_S32_RGBA | COLOR_MAP_ABGR8888) +#define FORMAT_S32_BGRA (FMT_S32_RGBA | COLOR_MAP_BGRA8888) +#define FORMAT_S32_RGBA (FMT_S32_RGBA | COLOR_MAP_RGBA8888) + +#define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x01, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_TIMESTAMP_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x04, u64) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_WAIT_MAX_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x05, u64) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x06, int) + + +#define AMVIDEOCAP_IOR_GET_FRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x10, int) +#define AMVIDEOCAP_IOR_GET_FRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x11, int) +#define AMVIDEOCAP_IOR_GET_FRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x12, int) +#define AMVIDEOCAP_IOR_GET_FRAME_TIMESTAMP_MS _IOR(AMVIDEOCAP_IOC_MAGIC, 0x13, int) + + +#define AMVIDEOCAP_IOR_GET_SRCFRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x20, int) +#define AMVIDEOCAP_IOR_GET_SRCFRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x21, int) +#define AMVIDEOCAP_IOR_GET_SRCFRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x22, int) + + +#define AMVIDEOCAP_IOR_GET_STATE _IOR(AMVIDEOCAP_IOC_MAGIC, 0x31, int) +#define AMVIDEOCAP_IOW_SET_START_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x32, int) +#define AMVIDEOCAP_IOW_SET_CANCEL_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x33, int) + +#define AMVIDEOCAP_IOR_SET_SRC_X _IOR(AMVIDEOCAP_IOC_MAGIC, 0x40, int) +#define AMVIDEOCAP_IOR_SET_SRC_Y _IOR(AMVIDEOCAP_IOC_MAGIC, 0x41, int) +#define AMVIDEOCAP_IOR_SET_SRC_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x42, int) +#define AMVIDEOCAP_IOR_SET_SRC_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x43, int) + +enum amvideocap_state { + AMVIDEOCAP_STATE_INIT = 0, + AMVIDEOCAP_STATE_ON_CAPTURE = 200, + AMVIDEOCAP_STATE_FINISHED_CAPTURE = 300, + AMVIDEOCAP_STATE_ERROR = 0xffff, +}; +#endif//__AMVIDEOCAP_HEADHER_ + diff --git a/amavutils/include/Amvideocaptools.h b/amavutils/include/Amvideocaptools.h new file mode 100644 index 0000000..597c82f --- a/dev/null +++ b/amavutils/include/Amvideocaptools.h @@ -0,0 +1,8 @@ +#ifndef AMVIDEOCAP_TOOLS_HEAD +#define AMVIDEOCAP_TOOLS_HEAD +#include "Amvideocap.h" +//fmt ignored,always RGB888 now +int amvideocap_capframe(char *buf, int size, int *w, int *h, int fmt_ignored, int at_end, int* ret_size, int fmt); +int amvideocap_capframe_with_rect(char *buf, int size, int src_rect_x, int src_rect_y, int *w, int *h, int fmt_ignored, int at_end, int* ret_size); +#endif + diff --git a/amavutils/include/Amvideoutils.h b/amavutils/include/Amvideoutils.h new file mode 100644 index 0000000..7913374 --- a/dev/null +++ b/amavutils/include/Amvideoutils.h @@ -0,0 +1,29 @@ +#ifndef AMVIDEO_UTILS_H +#define AMVIDEO_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define HDMI_HDCP_PASS (1) +#define HDMI_HDCP_FAILED (0) +#define HDMI_NOCONNECT (-1) + + int amvideo_utils_get_freescale_enable(void); + int amvideo_utils_get_global_offset(); + int amvideo_utils_set_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation); + int amvideo_utils_set_virtual_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation); + int amvideo_utils_set_absolute_position(int32_t x, int32_t y, int32_t w, int32_t h, int rotation); + int amvideo_utils_get_position(int32_t *x, int32_t *y, int32_t *w, int32_t *h); + int amvideo_utils_get_screen_mode(int *mode); + int amvideo_utils_set_screen_mode(int mode); + int amvideo_utils_get_video_angle(int *angle); + int amvideo_utils_get_hdmi_authenticate(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/amavutils/include/amaudioutils.h b/amavutils/include/amaudioutils.h new file mode 100644 index 0000000..ff2307f --- a/dev/null +++ b/amavutils/include/amaudioutils.h @@ -0,0 +1,14 @@ +#ifndef AMAUDIO_UTILS_H +#define AMAUDIO_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/amavutils/include/amconfigutils.h b/amavutils/include/amconfigutils.h new file mode 100644 index 0000000..cbdd0bc --- a/dev/null +++ b/amavutils/include/amconfigutils.h @@ -0,0 +1,26 @@ +#ifndef FF_CONFIGS_H__ +#define FF_CONFIGS_H__ + +#define MAX_CONFIG 128 +#define CONFIG_PATH_MAX 32 +#define CONFIG_VALUE_MAX 92 +#define CONFIG_VALUE_OFF (CONFIG_PATH_MAX+4) +#ifdef __cplusplus +extern "C" { +#endif + + int am_config_init(void); + int am_getconfig(const char * path, char *val, const char * def); + int am_setconfig(const char * path, const char *val); + int am_setconfig_float(const char * path, float value); + int am_getconfig_float(const char * path, float *value); + int am_dumpallconfigs(void); + int am_getconfig_bool(const char * path); + int am_getconfig_bool_def(const char * path, int def); + int am_getconfig_int_def(const char * path, int def); + float am_getconfig_float_def(const char * path, float defvalue); +#ifdef __cplusplus +} +#endif +#endif + diff --git a/amavutils/include/amdrmutils.h b/amavutils/include/amdrmutils.h new file mode 100644 index 0000000..f78eb56 --- a/dev/null +++ b/amavutils/include/amdrmutils.h @@ -0,0 +1,28 @@ +#ifndef AMDRM_UTILS_H +#define AMDRM_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct tvp_region +{ + uint64_t start; + uint64_t end; + int mem_flags; +}; + +#define TVP_MM_ENABLE_FLAGS_FOR_4K 0x02 + +extern int tvp_mm_enable(int flags); +extern int tvp_mm_disable(int flags); +extern int tvp_mm_get_mem_region(struct tvp_region* region, int region_size); +extern int free_cma_buffer(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/amavutils/include/ammodule.h b/amavutils/include/ammodule.h new file mode 100644 index 0000000..ed70539 --- a/dev/null +++ b/amavutils/include/ammodule.h @@ -0,0 +1,63 @@ +#ifndef ANDROID_INCLUDE_AMMODULE_H +#define ANDROID_INCLUDE_AMMODULE_H + +#include <stdint.h> +#include <sys/cdefs.h> + + +#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D)) + +#define AMPLAYER_MODULE_TAG MAKE_TAG_CONSTANT('A', 'M', 'M', 'D') + +#define AMPLAYER_MAKE_API_VERSION(maj,min) \ + ((((maj) & 0xff) << 8) | ((min) & 0xff)) + +#define AMPLAYER_API_MAIOR (1) +#define AMPLAYER_API_MINOR (0) /*diff,can load,but some functions may lost.*/ +#define AMPLAYER_HAL_API_VERSION AMPLAYER_MAKE_API_VERSION(AMPLAYER_API_MAIOR, AMPLAYER_API_MINOR) + +#define AMPLAYER_MODULE_API_VERSION(maj,min) AMPLAYER_MAKE_API_VERSION(maj,min) + + + +struct ammodule_t; +struct ammodule_methods_t; +typedef struct ammodule_t { + uint32_t tag;/*AMPLAYER_MODULE_TAG*/ + uint16_t module_api_version; +#define version_major module_api_version + uint16_t hal_api_version; +#define version_minor hal_api_version + const char *id; + const char *name;/*a simple name.*/ + const char *author; + const char *descript;/*functions..*/ + struct ammodule_methods_t* methods; + void* dso; + uint32_t reserved[32 - 7]; + +} ammodule_t; + +typedef struct ammodule_methods_t { + /** Open a specific device */ + int (*init)(const struct ammodule_t* module, int flags); + int (*release)(const struct ammodule_t* module); +} ammodule_methods_t; + +#define AMPLAYER_MODULE_INFO_SYM AMMD +#define AMPLAYER_MODULE_INFO_SYM_AS_STR "AMMD" + +#ifdef __cplusplus +extern "C" { +#endif + + int ammodule_load_module(const char *modulename, const struct ammodule_t **module); + int ammodule_open_module(struct ammodule_t *module); + int ammodule_simple_load_module(char* name); + int ammodule_match_check(const char* allmodstr, const char* modname); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/amavutils/include/amports/aformat.h b/amavutils/include/amports/aformat.h new file mode 100644 index 0000000..a446cbd --- a/dev/null +++ b/amavutils/include/amports/aformat.h @@ -0,0 +1,114 @@ +/** +* @file aformat.h +* @brief Porting from decoder driver for audio format +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef AFORMAT_H +#define AFORMAT_H + +typedef enum { + AFORMAT_UNKNOWN = -1, + AFORMAT_MPEG = 0, + AFORMAT_PCM_S16LE = 1, + AFORMAT_AAC = 2, + AFORMAT_AC3 = 3, + AFORMAT_ALAW = 4, + AFORMAT_MULAW = 5, + AFORMAT_DTS = 6, + AFORMAT_PCM_S16BE = 7, + AFORMAT_FLAC = 8, + AFORMAT_COOK = 9, + AFORMAT_PCM_U8 = 10, + AFORMAT_ADPCM = 11, + AFORMAT_AMR = 12, + AFORMAT_RAAC = 13, + AFORMAT_WMA = 14, + AFORMAT_WMAPRO = 15, + AFORMAT_PCM_BLURAY = 16, + AFORMAT_ALAC = 17, + AFORMAT_VORBIS = 18, + AFORMAT_AAC_LATM = 19, + AFORMAT_APE = 20, + AFORMAT_EAC3 = 21, + AFORMAT_PCM_WIFIDISPLAY = 22, + AFORMAT_DRA = 23, + AFORMAT_SIPR = 24, + AFORMAT_TRUEHD = 25, + AFORMAT_MPEG1 = 26, //AFORMAT_MPEG-->mp3,AFORMAT_MPEG1-->mp1,AFROMAT_MPEG2-->mp2 + AFORMAT_MPEG2 = 27, + AFORMAT_WMAVOI = 28, + AFORMAT_WMALOSSLESS =29, + AFORMAT_PCM_S24LE = 30, + AFORMAT_UNSUPPORT , + AFORMAT_MAX + +} aformat_t; + +#define AUDIO_EXTRA_DATA_SIZE (4096) +#define IS_AFMT_VALID(afmt) ((afmt > AFORMAT_UNKNOWN) && (afmt < AFORMAT_MAX)) + +#define IS_AUIDO_NEED_EXT_INFO(afmt) ((afmt == AFORMAT_ADPCM) \ + ||(afmt == AFORMAT_WMA) \ + ||(afmt == AFORMAT_WMAPRO) \ + ||(afmt == AFORMAT_PCM_S16BE) \ + ||(afmt == AFORMAT_PCM_S16LE) \ + ||(afmt == AFORMAT_PCM_U8) \ + ||(afmt == AFORMAT_PCM_BLURAY) \ + ||(afmt == AFORMAT_AMR)\ + ||(afmt == AFORMAT_ALAC)\ + ||(afmt == AFORMAT_AC3) \ + ||(afmt == AFORMAT_EAC3) \ + ||(afmt == AFORMAT_APE) \ + ||(afmt == AFORMAT_FLAC)\ + ||(afmt == AFORMAT_PCM_WIFIDISPLAY) \ + ||(afmt == AFORMAT_COOK) \ + ||(afmt == AFORMAT_RAAC)) \ + ||(afmt == AFORMAT_TRUEHD) \ + ||(afmt == AFORMAT_WMAVOI) \ + ||(afmt == AFORMAT_WMALOSSLESS) + +#define IS_AUDIO_NOT_SUPPORT_EXCEED_2CH(afmt) ((afmt == AFORMAT_RAAC) \ + ||(afmt == AFORMAT_COOK) \ + /*||(afmt == AFORMAT_FLAC)*/) + +#define IS_AUDIO_NOT_SUPPORT_EXCEED_6CH(afmt) ((afmt == AFORMAT_WMAPRO)) +#define IS_AUDIO_NOT_SUPPORT_EXCEED_FS48k(afmt) ((afmt == AFORMAT_WMAPRO)) + + +#define IS_AUIDO_NEED_PREFEED_HEADER(afmt) ((afmt == AFORMAT_VORBIS) ) +#define IS_AUDIO_NOT_SUPPORTED_BY_AUDIODSP(afmt,codec) \ + ((afmt == AFORMAT_AAC_LATM || afmt == AFORMAT_AAC) \ + &&codec->profile == 0/* FF_PROFILE_AAC_MAIN*/) + +#define IS_SUB_NEED_PREFEED_HEADER(sfmt) ((sfmt == CODEC_ID_DVD_SUBTITLE) ) + +#endif /* AFORMAT_H */ + diff --git a/amavutils/include/amports/amstream.h b/amavutils/include/amports/amstream.h new file mode 100644 index 0000000..f883c4b --- a/dev/null +++ b/amavutils/include/amports/amstream.h @@ -0,0 +1,417 @@ +/** +* @file amstream.h +* @brief Porting from decoder driver for codec ioctl commands +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef AMSTREAM_H +#define AMSTREAM_H + +#include "amports/vformat.h" +#include "amports/aformat.h" + +#define PORT_FLAG_IN_USE 0x0001 +#define PORT_FLAG_VFORMAT 0x0002 +#define PORT_FLAG_AFORMAT 0x0004 +#define PORT_FLAG_FORMAT (PORT_FLAG_VFORMAT | PORT_FLAG_AFORMAT) +#define PORT_FLAG_VID 0x0008 +#define PORT_FLAG_AID 0x0010 +#define PORT_FLAG_ID (PORT_FLAG_VID | PORT_FLAG_AID) +#define PORT_FLAG_INITED 0x100 + +#define PORT_TYPE_VIDEO 0x01 +#define PORT_TYPE_AUDIO 0x02 +#define PORT_TYPE_MPTS 0x04 +#define PORT_TYPE_MPPS 0x08 +#define PORT_TYPE_ES 0x10 +#define PORT_TYPE_RM 0x20 + +#define AMSTREAM_IOC_MAGIC 'S' +#define AMSTREAM_IOC_VB_START _IOW((AMSTREAM_IOC_MAGIC), 0x00, int) +#define AMSTREAM_IOC_VB_SIZE _IOW((AMSTREAM_IOC_MAGIC), 0x01, int) +#define AMSTREAM_IOC_AB_START _IOW((AMSTREAM_IOC_MAGIC), 0x02, int) +#define AMSTREAM_IOC_AB_SIZE _IOW((AMSTREAM_IOC_MAGIC), 0x03, int) +#define AMSTREAM_IOC_VFORMAT _IOW((AMSTREAM_IOC_MAGIC), 0x04, int) +#define AMSTREAM_IOC_AFORMAT _IOW((AMSTREAM_IOC_MAGIC), 0x05, int) +#define AMSTREAM_IOC_VID _IOW((AMSTREAM_IOC_MAGIC), 0x06, int) +#define AMSTREAM_IOC_AID _IOW((AMSTREAM_IOC_MAGIC), 0x07, int) +#define AMSTREAM_IOC_VB_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x08, int) +#define AMSTREAM_IOC_AB_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x09, int) +#define AMSTREAM_IOC_SYSINFO _IOW((AMSTREAM_IOC_MAGIC), 0x0a, int) +#define AMSTREAM_IOC_ACHANNEL _IOW((AMSTREAM_IOC_MAGIC), 0x0b, int) +#define AMSTREAM_IOC_SAMPLERATE _IOW((AMSTREAM_IOC_MAGIC), 0x0c, int) +#define AMSTREAM_IOC_DATAWIDTH _IOW((AMSTREAM_IOC_MAGIC), 0x0d, int) +#define AMSTREAM_IOC_TSTAMP _IOW((AMSTREAM_IOC_MAGIC), 0x0e, int) +#define AMSTREAM_IOC_VDECSTAT _IOR((AMSTREAM_IOC_MAGIC), 0x0f, int) +#define AMSTREAM_IOC_ADECSTAT _IOR((AMSTREAM_IOC_MAGIC), 0x10, int) + +#define AMSTREAM_IOC_PORT_INIT _IO((AMSTREAM_IOC_MAGIC), 0x11) +#define AMSTREAM_IOC_TRICKMODE _IOW((AMSTREAM_IOC_MAGIC), 0x12, int) + +#define AMSTREAM_IOC_AUDIO_INFO _IOW((AMSTREAM_IOC_MAGIC), 0x13, int) +#define AMSTREAM_IOC_TRICK_STAT _IOR((AMSTREAM_IOC_MAGIC), 0x14, int) +#define AMSTREAM_IOC_AUDIO_RESET _IO((AMSTREAM_IOC_MAGIC), 0x15) +#define AMSTREAM_IOC_SID _IOW((AMSTREAM_IOC_MAGIC), 0x16, int) +#define AMSTREAM_IOC_VPAUSE _IOW((AMSTREAM_IOC_MAGIC), 0x17, int) +#define AMSTREAM_IOC_AVTHRESH _IOW((AMSTREAM_IOC_MAGIC), 0x18, int) +#define AMSTREAM_IOC_SYNCTHRESH _IOW((AMSTREAM_IOC_MAGIC), 0x19, int) +#define AMSTREAM_IOC_SUB_RESET _IOW((AMSTREAM_IOC_MAGIC), 0x1a, int) +#define AMSTREAM_IOC_SUB_LENGTH _IOR((AMSTREAM_IOC_MAGIC), 0x1b, int) +#define AMSTREAM_IOC_SET_DEC_RESET _IOW((AMSTREAM_IOC_MAGIC), 0x1c, int) +#define AMSTREAM_IOC_TS_SKIPBYTE _IOW((AMSTREAM_IOC_MAGIC), 0x1d, int) +#define AMSTREAM_IOC_SUB_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x1e, int) +#define AMSTREAM_IOC_CLEAR_VIDEO _IOW((AMSTREAM_IOC_MAGIC), 0x1f, int) + +#define AMSTREAM_IOC_APTS _IOR((AMSTREAM_IOC_MAGIC), 0x40, int) +#define AMSTREAM_IOC_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0x41, int) +#define AMSTREAM_IOC_PCRSCR _IOR((AMSTREAM_IOC_MAGIC), 0x42, int) +#define AMSTREAM_IOC_SYNCENABLE _IOW((AMSTREAM_IOC_MAGIC), 0x43, int) +#define AMSTREAM_IOC_GET_SYNC_ADISCON _IOR((AMSTREAM_IOC_MAGIC), 0x44, int) +#define AMSTREAM_IOC_SET_SYNC_ADISCON _IOW((AMSTREAM_IOC_MAGIC), 0x45, int) +#define AMSTREAM_IOC_GET_SYNC_VDISCON _IOR((AMSTREAM_IOC_MAGIC), 0x46, int) +#define AMSTREAM_IOC_SET_SYNC_VDISCON _IOW((AMSTREAM_IOC_MAGIC), 0x47, int) +#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR((AMSTREAM_IOC_MAGIC), 0x48, int) +#define AMSTREAM_IOC_SET_VIDEO_DISABLE _IOW((AMSTREAM_IOC_MAGIC), 0x49, int) +#define AMSTREAM_IOC_SET_PCRSCR _IOW((AMSTREAM_IOC_MAGIC), 0x4a, int) +#define AMSTREAM_IOC_GET_VIDEO_AXIS _IOR((AMSTREAM_IOC_MAGIC), 0x4b, int) +#define AMSTREAM_IOC_SET_VIDEO_AXIS _IOW((AMSTREAM_IOC_MAGIC), 0x4c, int) +#define AMSTREAM_IOC_GET_VIDEO_CROP _IOR((AMSTREAM_IOC_MAGIC), 0x4d, int) +#define AMSTREAM_IOC_SET_VIDEO_CROP _IOW((AMSTREAM_IOC_MAGIC), 0x4e, int) +#define AMSTREAM_IOC_PCRID _IOW((AMSTREAM_IOC_MAGIC), 0x4f, int) + +/* VPP.3D IOCTL command list^M */ +#define AMSTREAM_IOC_SET_3D_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x3c, unsigned int) +#define AMSTREAM_IOC_GET_3D_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x3d, unsigned int) + +#define AMSTREAM_IOC_SUB_NUM _IOR((AMSTREAM_IOC_MAGIC), 0x50, int) +#define AMSTREAM_IOC_SUB_INFO _IOR((AMSTREAM_IOC_MAGIC), 0x51, int) +#define AMSTREAM_IOC_GET_BLACKOUT_POLICY _IOR((AMSTREAM_IOC_MAGIC), 0x52, int) +#define AMSTREAM_IOC_SET_BLACKOUT_POLICY _IOW((AMSTREAM_IOC_MAGIC), 0x53, int) +#define AMSTREAM_IOC_UD_LENGTH _IOR((AMSTREAM_IOC_MAGIC), 0x54, int) +#define AMSTREAM_IOC_UD_POC _IOR((AMSTREAM_IOC_MAGIC), 0x55, int) +#define AMSTREAM_IOC_GET_SCREEN_MODE _IOR((AMSTREAM_IOC_MAGIC), 0x58, int) +#define AMSTREAM_IOC_SET_SCREEN_MODE _IOW((AMSTREAM_IOC_MAGIC), 0x59, int) +#define AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT _IOR((AMSTREAM_IOC_MAGIC), 0x5a, int) +#define AMSTREAM_IOC_SET_VIDEO_DISCONTINUE_REPORT _IOW((AMSTREAM_IOC_MAGIC), 0x5b, int) +#define AMSTREAM_IOC_VF_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x60, int) +#define AMSTREAM_IOC_CLEAR_VBUF _IO((AMSTREAM_IOC_MAGIC), 0x80) + +#define AMSTREAM_IOC_APTS_LOOKUP _IOR((AMSTREAM_IOC_MAGIC), 0x81, int) +#define GET_FIRST_APTS_FLAG _IOR((AMSTREAM_IOC_MAGIC), 0x82, int) +#define AMSTREAM_IOC_GET_SYNC_ADISCON_DIFF _IOR((AMSTREAM_IOC_MAGIC), 0x83, int) +#define AMSTREAM_IOC_GET_SYNC_VDISCON_DIFF _IOR((AMSTREAM_IOC_MAGIC), 0x84, int) +#define AMSTREAM_IOC_SET_SYNC_ADISCON_DIFF _IOW((AMSTREAM_IOC_MAGIC), 0x85, int) +#define AMSTREAM_IOC_SET_SYNC_VDISCON_DIFF _IOW((AMSTREAM_IOC_MAGIC), 0x86, int) +#define AMSTREAM_IOC_GET_FREERUN_MODE _IOR((AMSTREAM_IOC_MAGIC), 0x87, int) +#define AMSTREAM_IOC_SET_FREERUN_MODE _IOW((AMSTREAM_IOC_MAGIC), 0x88, int) +#define AMSTREAM_IOC_SET_VSYNC_UPINT _IOW((AMSTREAM_IOC_MAGIC), 0x89, int) +#define AMSTREAM_IOC_GET_VSYNC_SLOW_FACTOR _IOW((AMSTREAM_IOC_MAGIC), 0x8a, int) +#define AMSTREAM_IOC_SET_VSYNC_SLOW_FACTOR _IOW((AMSTREAM_IOC_MAGIC), 0x8b, int) +#define AMSTREAM_IOC_SET_DEMUX _IOW((AMSTREAM_IOC_MAGIC), 0x90, int) +#define AMSTREAM_IOC_SET_DRMMODE _IOW((AMSTREAM_IOC_MAGIC), 0x91, int) +#define AMSTREAM_IOC_TSTAMP_uS64 _IOW((AMSTREAM_IOC_MAGIC), 0x95, int) + +#define AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS _IOW((AMSTREAM_IOC_MAGIC), 0xa0, int) +#define AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa1, int) +#define AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS _IOW((AMSTREAM_IOC_MAGIC), 0xa2, int) +#define AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa3, int) +#define AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa4, int) +#define AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa5, int) +#define AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS _IOR((AMSTREAM_IOC_MAGIC), 0xa6, int) +#define AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS _IOR((AMSTREAM_IOC_MAGIC), 0xa7, int) +#define AMSTREAM_IOC_SET_APTS _IOW((AMSTREAM_IOC_MAGIC), 0xa8, int) +#define AMSTREAM_IOC_GET_LAST_CHECKIN_APTS _IOR((AMSTREAM_IOC_MAGIC), 0xa9, int) +#define AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xaa, int) +#define AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS _IOR((AMSTREAM_IOC_MAGIC), 0xab, int) +#define AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xac, int) +/* subtitle.c get/set subtitle info */ +#define AMSTREAM_IOC_GET_SUBTITLE_INFO _IOR((AMSTREAM_IOC_MAGIC), 0xad, int) +#define AMSTREAM_IOC_SET_SUBTITLE_INFO _IOW((AMSTREAM_IOC_MAGIC), 0xae, int) +#define AMSTREAM_IOC_SET_OMX_VPTS _IOW((AMSTREAM_IOC_MAGIC), 0xaf, int) +#define AMSTREAM_IOC_GET_OMX_VPTS _IOW((AMSTREAM_IOC_MAGIC), 0xb0, int) + +#define AMSTREAM_IOC_GET_TRICK_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xf0, int) +#define AMSTREAM_IOC_DISABLE_SLOW_SYNC _IOW((AMSTREAM_IOC_MAGIC), 0xf1, int) + +#define AMSTREAM_IOC_GET_AUDIO_CHECKIN_BITRATE_BPS _IOR(AMSTREAM_IOC_MAGIC, 0xf2, int) +#define AMSTREAM_IOC_GET_VIDEO_CHECKIN_BITRATE_BPS _IOR(AMSTREAM_IOC_MAGIC, 0xf3, int) + +#define AMSTREAM_IOC_GET_VERSION _IOR((AMSTREAM_IOC_MAGIC), 0xc0, int) +#define AMSTREAM_IOC_GET _IOWR((AMSTREAM_IOC_MAGIC), 0xc1, struct am_ioctl_parm) +#define AMSTREAM_IOC_SET _IOW((AMSTREAM_IOC_MAGIC), 0xc2, struct am_ioctl_parm) +#define AMSTREAM_IOC_GET_EX _IOWR((AMSTREAM_IOC_MAGIC), 0xc3, struct am_ioctl_parm_ex) +#define AMSTREAM_IOC_SET_EX _IOW((AMSTREAM_IOC_MAGIC), 0xc4, struct am_ioctl_parm_ex) +#define AMSTREAM_IOC_GET_PTR _IOWR((AMSTREAM_IOC_MAGIC), 0xc5, struct am_ioctl_parm_ptr) +#define AMSTREAM_IOC_SET_PTR _IOW((AMSTREAM_IOC_MAGIC), 0xc6, struct am_ioctl_parm_ptr) + +#define AMAUDIO_IOC_MAGIC 'A' +#define AMAUDIO_IOC_SET_RESAMPLE_ENA _IOW(AMAUDIO_IOC_MAGIC, 0x19, unsigned long) +#define AMAUDIO_IOC_GET_RESAMPLE_ENA _IOR(AMAUDIO_IOC_MAGIC, 0x1a, unsigned long) +#define AMAUDIO_IOC_SET_RESAMPLE_TYPE _IOW(AMAUDIO_IOC_MAGIC, 0x1b, unsigned long) +#define AMAUDIO_IOC_GET_RESAMPLE_TYPE _IOR(AMAUDIO_IOC_MAGIC, 0x1c, unsigned long) +#define AMAUDIO_IOC_SET_RESAMPLE_DELTA _IOW(AMAUDIO_IOC_MAGIC, 0x1d, unsigned long) + +struct buf_status { + int size; + int data_len; + int free_len; + unsigned int read_pointer; + unsigned int write_pointer; +}; + +/*struct vdec_status.status*/ +#define STAT_TIMER_INIT 0x01 +#define STAT_MC_LOAD 0x02 +#define STAT_ISR_REG 0x04 +#define STAT_VF_HOOK 0x08 +#define STAT_TIMER_ARM 0x10 +#define STAT_VDEC_RUN 0x20 +//-/*struct vdec_status.status on error*/ + +#define PARSER_FATAL_ERROR (0x10<<16) +#define DECODER_ERROR_VLC_DECODE_TBL (0x20<<16) +#define PARSER_ERROR_WRONG_HEAD_VER (0x40<<16) +#define PARSER_ERROR_WRONG_PACKAGE_SIZE (0x80<<16) +#define DECODER_FATAL_ERROR_SIZE_OVERFLOW (0x100<<16) +#define DECODER_FATAL_ERROR_UNKNOW (0x200<<16) +#define DECODER_FATAL_ERROR_NO_MEM (0x400<<16) + + +#define DECODER_ERROR_MASK (0xffff<<16) +struct vdec_status { + unsigned int width; + unsigned int height; + unsigned int fps; + unsigned int error_count; + unsigned int status; +}; + +struct adec_status { + unsigned int channels; + unsigned int sample_rate; + unsigned int resolution; + unsigned int error_count; + unsigned int status; +}; + +struct am_io_param { + union { + int data; + int id;//get bufstatus? //or others + }; + + int len; //buffer size; + + union { + char buf[1]; + struct buf_status status; + struct vdec_status vstatus; + struct adec_status astatus; + }; +}; +struct subtitle_info { + + unsigned char id; + + unsigned char width; + + unsigned char height; + + unsigned char type; +}; + +struct userdata_poc_info_t { + + unsigned int poc_info; + + unsigned int poc_number; +}; + +/******************************************************************* +* 0x100~~0x1FF : set cmd +* 0x200~~0x2FF : set ex cmd +* 0x300~~0x3FF : set ptr cmd +* 0x400~~0x7FF : set reserved cmd +* 0x800~~0x8FF : get cmd +* 0x900~~0x9FF : get ex cmd +* 0xA00~~0xAFF : get ptr cmd +* 0xBFF~~0xFFF : get reserved cmd +* 0xX00~~0xX5F : amstream cmd(X: cmd type) +* 0xX60~~0xXAF : video cmd(X: cmd type) +* 0xXAF~~0xXFF : reserved cmd(X: cmd type) +*******************************************************************/ +/* amstream set cmd */ +#define AMSTREAM_SET_VB_START 0x101 +#define AMSTREAM_SET_VB_SIZE 0x102 +#define AMSTREAM_SET_AB_START 0x103 +#define AMSTREAM_SET_AB_SIZE 0x104 +#define AMSTREAM_SET_VFORMAT 0x105 +#define AMSTREAM_SET_AFORMAT 0x106 +#define AMSTREAM_SET_VID 0x107 +#define AMSTREAM_SET_AID 0x108 +#define AMSTREAM_SET_SID 0x109 +#define AMSTREAM_SET_PCRID 0x10A +#define AMSTREAM_SET_ACHANNEL 0x10B +#define AMSTREAM_SET_SAMPLERATE 0x10C +#define AMSTREAM_SET_DATAWIDTH 0x10D +#define AMSTREAM_SET_TSTAMP 0x10E +#define AMSTREAM_SET_TSTAMP_US64 0x10F +#define AMSTREAM_SET_APTS 0x110 +#define AMSTREAM_PORT_INIT 0x111 +#define AMSTREAM_SET_TRICKMODE 0x112 /* amstream,video */ +#define AMSTREAM_AUDIO_RESET 0x013 +#define AMSTREAM_SUB_RESET 0x114 +#define AMSTREAM_DEC_RESET 0x115 +#define AMSTREAM_SET_TS_SKIPBYTE 0x116 +#define AMSTREAM_SET_SUB_TYPE 0x117 +#define AMSTREAM_SET_PCRSCR 0x118 +#define AMSTREAM_SET_DEMUX 0x119 +#define AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS 0x11A +#define AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS 0x11B +#define AMSTREAM_SET_DRMMODE 0x11C +/* video set cmd */ +#define AMSTREAM_SET_OMX_VPTS 0x160 +#define AMSTREAM_SET_VPAUSE 0x161 +#define AMSTREAM_SET_AVTHRESH 0x162 +#define AMSTREAM_SET_SYNCTHRESH 0x163 +#define AMSTREAM_SET_SYNCENABLE 0x164 +#define AMSTREAM_SET_SYNC_ADISCON 0x165 +#define AMSTREAM_SET_SYNC_VDISCON 0x166 +#define AMSTREAM_SET_SYNC_ADISCON_DIFF 0x167 +#define AMSTREAM_SET_SYNC_VDISCON_DIFF 0x168 +#define AMSTREAM_SET_VIDEO_DISABLE 0x169 +#define AMSTREAM_SET_VIDEO_DISCONTINUE_REPORT 0x16A +#define AMSTREAM_SET_SCREEN_MODE 0x16B +#define AMSTREAM_SET_BLACKOUT_POLICY 0x16C +#define AMSTREAM_CLEAR_VBUF 0x16D +#define AMSTREAM_SET_CLEAR_VIDEO 0x16E +#define AMSTREAM_SET_FREERUN_MODE 0x16F +#define AMSTREAM_SET_DISABLE_SLOW_SYNC 0x170 +#define AMSTREAM_SET_3D_TYPE 0x171 +#define AMSTREAM_SET_VSYNC_UPINT 0x172 +#define AMSTREAM_SET_VSYNC_SLOW_FACTOR 0x173 +#define AMSTREAM_SET_FRAME_BASE_PATH 0x174 +#define AMSTREAM_SET_EOS 0x175 + +/* video set ex cmd */ +#define AMSTREAM_SET_EX_VIDEO_AXIS 0x260 +#define AMSTREAM_SET_EX_VIDEO_CROP 0x261 +/* amstream set ptr cmd */ +#define AMSTREAM_SET_PTR_AUDIO_INFO 0x300 + +/* amstream get cmd */ +#define AMSTREAM_GET_SUB_LENGTH 0x800 +#define AMSTREAM_GET_UD_LENGTH 0x801 +#define AMSTREAM_GET_APTS_LOOKUP 0x802 +#define AMSTREAM_GET_FIRST_APTS_FLAG 0x803 +#define AMSTREAM_GET_APTS 0x804 +#define AMSTREAM_GET_VPTS 0x805 +#define AMSTREAM_GET_PCRSCR 0x806 +#define AMSTREAM_GET_LAST_CHECKIN_APTS 0x807 +#define AMSTREAM_GET_LAST_CHECKIN_VPTS 0x808 +#define AMSTREAM_GET_LAST_CHECKOUT_APTS 0x809 +#define AMSTREAM_GET_LAST_CHECKOUT_VPTS 0x80A +#define AMSTREAM_GET_SUB_NUM 0x80B +#define AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS 0x80C +#define AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS 0x80D +#define AMSTREAM_GET_AUDIO_CUR_DELAY_MS 0x80E +#define AMSTREAM_GET_VIDEO_CUR_DELAY_MS 0x80F +#define AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS 0x810 +#define AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS 0x811 +/* video get cmd */ +#define AMSTREAM_GET_OMX_VPTS 0x860 +#define AMSTREAM_GET_TRICK_STAT 0x861 +#define AMSTREAM_GET_TRICK_VPTS 0x862 +#define AMSTREAM_GET_SYNC_ADISCON 0x863 +#define AMSTREAM_GET_SYNC_VDISCON 0x864 +#define AMSTREAM_GET_SYNC_ADISCON_DIFF 0x865 +#define AMSTREAM_GET_SYNC_VDISCON_DIFF 0x866 +#define AMSTREAM_GET_VIDEO_DISABLE 0x867 +#define AMSTREAM_GET_VIDEO_DISCONTINUE_REPORT 0x868 +#define AMSTREAM_GET_SCREEN_MODE 0x869 +#define AMSTREAM_GET_BLACKOUT_POLICY 0x86A +#define AMSTREAM_GET_FREERUN_MODE 0x86B +#define AMSTREAM_GET_3D_TYPE 0x86C +#define AMSTREAM_GET_VSYNC_SLOW_FACTOR 0x86D +/* amstream get ex cmd */ +#define AMSTREAM_GET_EX_VB_STATUS 0x900 +#define AMSTREAM_GET_EX_AB_STATUS 0x901 +#define AMSTREAM_GET_EX_VDECSTAT 0x902 +#define AMSTREAM_GET_EX_ADECSTAT 0x903 +#define AMSTREAM_GET_EX_UD_POC 0x904 +/* video get ex cmd */ +#define AMSTREAM_GET_EX_VF_STATUS 0x960 +#define AMSTREAM_GET_EX_VIDEO_AXIS 0x961 +#define AMSTREAM_GET_EX_VIDEO_CROP 0x962 +/* amstream get ptr cmd */ +#define AMSTREAM_GET_PTR_SUB_INFO 0xA00 + +struct am_ioctl_parm { + union { + unsigned int data_32; + unsigned long long data_64; + vformat_t data_vformat; + aformat_t data_aformat; + char data[8]; + }; + unsigned int cmd; + char reserved[4]; +}; + +struct am_ioctl_parm_ex { + union { + struct buf_status status; + struct vdec_status vstatus; + struct adec_status astatus; + + struct userdata_poc_info_t data_userdata_info; + char data[24]; + + }; + unsigned int cmd; + char reserved[4]; +}; + +struct am_ioctl_parm_ptr { + union { + struct audio_info *pdata_audio_info; + struct subtitle_info *pdata_sub_info; + void *pointer; + char data[8]; + }; + unsigned int cmd; + char reserved[4]; +}; + +void set_vdec_func(int (*vdec_func)(struct vdec_status *)); +void set_adec_func(int (*adec_func)(struct adec_status *)); + +#endif /* AMSTREAM_H */ + diff --git a/amavutils/include/amports/vformat.h b/amavutils/include/amports/vformat.h new file mode 100644 index 0000000..f12bdf8 --- a/dev/null +++ b/amavutils/include/amports/vformat.h @@ -0,0 +1,133 @@ +/** +* @file vformat.h +* @brief Porting from decoder driver for video format +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef VFORMAT_H +#define VFORMAT_H + +typedef enum { + VIDEO_DEC_FORMAT_UNKNOW, + VIDEO_DEC_FORMAT_MPEG4_3, + VIDEO_DEC_FORMAT_MPEG4_4, + VIDEO_DEC_FORMAT_MPEG4_5, + VIDEO_DEC_FORMAT_H264, + VIDEO_DEC_FORMAT_MJPEG, + VIDEO_DEC_FORMAT_MP4, + VIDEO_DEC_FORMAT_H263, + VIDEO_DEC_FORMAT_REAL_8, + VIDEO_DEC_FORMAT_REAL_9, + VIDEO_DEC_FORMAT_WMV3, + VIDEO_DEC_FORMAT_WVC1, + VIDEO_DEC_FORMAT_SW, + VIDEO_DEC_FORMAT_AVS, + VIDEO_DEC_FORMAT_H264_4K2K, + VIDEO_DEC_FORMAT_HEVC, + VIDEO_DEC_FORMAT_VP9 , + VIDEO_DEC_FORMAT_MAX +} vdec_type_t; + +typedef enum { + VFORMAT_UNKNOWN = -1, + VFORMAT_MPEG12 = 0, + VFORMAT_MPEG4, + VFORMAT_H264, + VFORMAT_MJPEG, + VFORMAT_REAL, + VFORMAT_JPEG, + VFORMAT_VC1, + VFORMAT_AVS, + VFORMAT_SW, + VFORMAT_H264MVC, + VFORMAT_H264_4K2K, + VFORMAT_HEVC, + VFORMAT_H264_ENC, + VFORMAT_JPEG_ENC, + VFORMAT_VP9, + +/*add new here before.*/ + VFORMAT_MAX, + VFORMAT_UNSUPPORT = VFORMAT_MAX +} vformat_t; + +#define IS_VFMT_VALID(vfmt) ((vfmt > VFORMAT_UNKNOWN) && (vfmt < VFORMAT_MAX)) +#define IS_NEED_VDEC_INFO(vfmt) ((vfmt == VFORMAT_MPEG4) || (vfmt == VFORMAT_REAL)) + +#define CODEC_TAG_MJPEG (0x47504a4d) +#define CODEC_TAG_mjpeg (0x47504a4c) +#define CODEC_TAG_jpeg (0x6765706a) +#define CODEC_TAG_mjpa (0x61706a6d) +#define CODEC_TAG_XVID (0x44495658) +#define CODEC_TAG_xvid (0x64697678) +#define CODEC_TAG_XVIX (0x58495658) +#define CODEC_TAG_xvix (0x78697678) +#define CODEC_TAG_MP4 (0x8e22ada) +#define CODEC_TAG_COL1 (0x314c4f43) +#define CODEC_TAG_DIV3 (0x33564944) +#define CODEC_TAG_MP43 (0x3334504d) +#define CODEC_TAG_M4S2 (0x3253344d) +#define CODEC_TAG_DIV4 (0x34564944) +#define CODEC_TAG_divx (0x78766964) +#define CODEC_TAG_DIVX (0x58564944) +#define CODEC_TAG_DIV5 (0x35564944) +#define CODEC_TAG_3IV2 (0x32564933) +#define CODEC_TAG_3iv2 (0x32766933) +#define CODEC_TAG_DX50 (0x30355844) +#define CODEC_TAG_DIV6 (0x36564944) +#define CODEC_TAG_RMP4 (0x34504d52) +#define CODEC_TAG_MP42 (0x3234504d) +#define CODEC_TAG_MPG4 (0x3447504d) +#define CODEC_TAG_MP4V (0x5634504d) +#define CODEC_TAG_mp4v (0x7634706d) +#define CODEC_TAG_AVC1 (0x31435641) +#define CODEC_TAG_avc1 (0x31637661) +#define CODEC_TAG_H264 (0x34363248) +#define CODEC_TAG_h264 (0x34363268) +#define CODEC_TAG_HEVC (0x43564548) +#define CODEC_TAG_hvc1 (0x31637668) +#define CODEC_TAG_hev1 (0x31766568) +#define CODEC_TAG_H263 (0x33363248) +#define CODEC_TAG_h263 (0x33363268) +#define CODEC_TAG_s263 (0x33363273) +#define CODEC_TAG_F263 (0x33363246) +#define CODEC_TAG_WMV1 (0x31564d57) +#define CODEC_TAG_WMV2 (0x32564d57) +#define CODEC_TAG_WMV3 (0x33564d57) +#define CODEC_TAG_WVC1 (0x31435657) +#define CODEC_TAG_WMVA (0x41564d57) +#define CODEC_TAG_FMP4 (0x34504d46) +#define CODEC_TAG_FVFW (0x57465646) +#define CODEC_TAG_VC_1 (0x312d4356) +#define CODEC_TAG_vc_1 (0x312d6376) +#define CODEC_TAG_DVHE (0x65687664) +#define CODEC_TAG_DOVI (0x49564f44) + +#endif /* VFORMAT_H */ diff --git a/amavutils/include/amthreadpool.h b/amavutils/include/amthreadpool.h new file mode 100644 index 0000000..4b6eabf --- a/dev/null +++ b/amavutils/include/amthreadpool.h @@ -0,0 +1,46 @@ +#ifndef AM_LIBPLAYER_THREAD_POOL +#define AM_LIBPLAYER_THREAD_POOL +#include <pthread.h> + +#define AMTHREADPOOL_SLEEP_US_MONOTONIC +///#define AMTHREADPOOL_DEBUG +int amthreadpool_thread_usleep_in(int us); +int amthreadpool_thread_usleep_in_monotonic(int us); +int amthreadpool_thread_wake(pthread_t pid); +int amthreadpool_pool_thread_cancel(pthread_t pid); +int amthreadpool_pool_thread_uncancel(pthread_t pid); +int amthreadpool_thread_cancel(pthread_t pid); +int amthreadpool_thread_uncancel(pthread_t pid); + +int amthreadpool_pthread_create(pthread_t * newthread, + __const pthread_attr_t * attr, + void * (*start_routine)(void *), + void * arg); +int amthreadpool_pthread_create_name(pthread_t * newthread, + __const pthread_attr_t * attr, + void * (*start_routine)(void *), + void * arg, const char *name); + +int amthreadpool_pthread_join(pthread_t thid, void ** ret_val); +int amthreadpool_system_init(void); +int amthreadpool_system_dump_info(void); +int amthreadpool_on_requare_exit(pthread_t pid); + + + +#ifdef AMTHREADPOOL_DEBUG +int amthreadpool_thread_usleep_debug(int us, const char *func, int line); +#define amthreadpool_thread_usleep(us)\ + amthreadpool_thread_usleep_debug(us,__FUNCTION__,__LINE__) +#else + +#ifdef AMTHREADPOOL_SLEEP_US_MONOTONIC +#define amthreadpool_thread_usleep(us)\ + amthreadpool_thread_usleep_in_monotonic(us) +#else +#define amthreadpool_thread_usleep(us)\ + amthreadpool_thread_usleep_in(us) +#endif +#endif +#endif + diff --git a/amavutils/include/audio_ctl.h b/amavutils/include/audio_ctl.h new file mode 100644 index 0000000..8b18caf --- a/dev/null +++ b/amavutils/include/audio_ctl.h @@ -0,0 +1,23 @@ +#ifndef AUDIO_CTL_H +#define AUDIO_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif +int media_set_adec_format(int format); +int media_get_adec_format(); +int media_set_adec_samplerate(int rate); +int media_get_adec_samplerate(); +int media_set_adec_channum(int num); +int media_get_adec_channum(); +int media_set_adec_pts(int pts); +int media_get_adec_pts(); +int media_set_adec_datawidth(int width); +int media_get_adec_datawidth(); +int media_get_audio_digital_output_mode(); + +#ifdef __cplusplus +} +#endif + +#endif
\ No newline at end of file diff --git a/amavutils/include/itemlist.h b/amavutils/include/itemlist.h new file mode 100644 index 0000000..940d538 --- a/dev/null +++ b/amavutils/include/itemlist.h @@ -0,0 +1,113 @@ +#ifndef _PLAYER_ITEMLIST_H_ +#define _PLAYER_ITEMLIST_H_ + +#include <list.h> +#include <pthread.h> + + +#define ITEMLIST_WITH_LOCK + +struct item { + struct list_head list; + unsigned long item_data; + unsigned long extdata[1]; + /*can be more space on alloc..*/ +}; + +struct itemlist { + struct list_head list; +#ifdef ITEMLIST_WITH_LOCK + pthread_mutex_t list_mutex; + int muti_threads_access; +#endif + int item_count; + int max_items; + int item_ext_buf_size; + int reject_same_item_data; +}; +#ifdef ITEMLIST_WITH_LOCK +#define ITEM_LOCK(pitems)\ + do{if(pitems->muti_threads_access)\ + pthread_mutex_lock(&pitems->list_mutex);\ + }while(0); + +#define ITEM_UNLOCK(pitems)\ + do{if(pitems->muti_threads_access)\ + pthread_mutex_unlock(&pitems->list_mutex);\ + }while(0); +#define ITEM_LOCK_INIT(pitems)\ + do{if(pitems->muti_threads_access)\ + pthread_mutex_init(&pitems->list_mutex,NULL);\ + }while(0); +#define ITEM_LOCK_DESTROY(pitems)\ + do{if(pitems->muti_threads_access)\ + pthread_mutex_destroy(&pitems->list_mutex);\ + }while(0); + +#else +#define ITEM_LOCK(pitems) +#define ITEM_UNLOCK(pitems) +#define ITEM_LOCK_INIT(pitems) +#define ITEM_LOCK_DESTROY(pitems) + +#endif + + +#define ITEM_EXT(item,n) (((item)->extdata)[n]) +#define ITEM_EXT64(item,n) (((int64_t*)((item)->extdata+1))[n]) + + +#define NEXT_ITEM(item) (list_entry(item->list.next, struct item, list)) +#define PREV_ITEM(item) list_entry(item->list.prev, struct item, list) + +typedef int (*data_free_fun)(void *); +typedef int(*item_is_match_fun)(struct item *item, struct item *tomatchitem); +typedef int(*printitem_fun)(struct item *item); + +int itemlist_init(struct itemlist *itemlist); +struct item * item_alloc(int ext); +void item_free(struct item *item); +int itemlist_deinit(struct itemlist *itemlist); + +int itemlist_del_item(struct itemlist *itemlist, struct item *item); +int itemlist_del_item_locked(struct itemlist *itemlist, struct item *item); + +int itemlist_add_tail(struct itemlist *itemlist, struct item *item); +struct item * itemlist_get_head(struct itemlist *itemlist); +struct item * itemlist_get_tail(struct itemlist *itemlist); +struct item * itemlist_peek_head(struct itemlist *itemlist); +struct item * itemlist_peek_tail(struct itemlist *itemlist); +struct item * itemlist_get_match_item(struct itemlist *itemlist, unsigned long data); +struct item * itemlist_find_match_item(struct itemlist *itemlist, unsigned long data); +int itemlist_del_match_data_item(struct itemlist *itemlist, unsigned long data); +int itemlist_have_match_data(struct itemlist *itemlist, unsigned long data); + + +int itemlist_clean(struct itemlist *itemlist, data_free_fun free_fun); +int itemlist_add_tail_data(struct itemlist *itemlist, unsigned long data); +int itemlist_add_tail_data_ext(struct itemlist *itemlist, unsigned long data, int extnum, unsigned long *extdata); + +int itemlist_get_head_data(struct itemlist *itemlist, unsigned long *data); +int itemlist_get_tail_data(struct itemlist *itemlist, unsigned long *data); +int itemlist_peek_head_data(struct itemlist *itemlist, unsigned long *data); +int itemlist_peek_tail_data(struct itemlist *itemlist, unsigned long *data); +int itemlist_clean_data(struct itemlist *itemlist, data_free_fun free_fun); +struct item * itemlist_find_match_item_ex(struct itemlist *itemlist, struct item *tomatch, item_is_match_fun match, int reveser); +int itemlist_item_insert(struct itemlist *itemlist, struct itemlist *position, struct itemlist *newitem, int flags); +int itemlist_print(struct itemlist *itemlist, printitem_fun print); + + +#define FOR_EACH_ITEM_IN_ITEMLIST(__itemlist,__item)\ + ITEM_LOCK((__itemlist));{\ + struct list_head *llist, *tmplist;\ + list_for_each_safe(llist, tmplist, &(__itemlist)->list) \ + {\ + (__item) = list_entry(llist, struct item, list);\ + +#define FOR_ITEM_END(__itemlist)\ + }\ + }ITEM_UNLOCK((__itemlist)) + + +#endif + diff --git a/amavutils/include/list.h b/amavutils/include/list.h new file mode 100644 index 0000000..f67a84b --- a/dev/null +++ b/amavutils/include/list.h @@ -0,0 +1,191 @@ +#ifndef LIST_HEADERS_H +#define LIST_HEADERS_H + +#define LIST_POISON1 ((void *) 0x00100100) +#define LIST_POISON2 ((void *) 0x00200200) + +struct list_head { + struct list_head *next; + struct list_head *prev; +}; + +typedef struct list_head list_t; + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} +static inline void __list_add(struct list_head *newh, + struct list_head *prev, + struct list_head *next) +{ + next->prev = newh; + newh->next = next; + newh->prev = prev; + prev->next = newh; +} + +static inline void __list_del(struct list_head *prev, + struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} +static inline void list_add(struct list_head *newh, struct list_head *head) +{ + __list_add(newh, head, head->next); +} + +static inline void list_add_tail(struct list_head *newh, struct list_head *head) +{ + __list_add(newh, head->prev, head); +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = (struct list_head *)LIST_POISON1; + entry->prev = (struct list_head *)LIST_POISON2; +} +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) (&((TYPE *)0)->MEMBER)) +#endif +#define prefetch(x) (x) + +#ifndef typeof +#define typeof(T) __typeof__(T) +#endif +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + + +/** +* list_entry - get the struct for this entry +* @ptr: the &struct list_head pointer. +* @type: the type of the struct this is embedded in. +* @member: the name of the list_struct within the struct. +*/ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; prefetch(pos->next), pos != (head); \ + pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_prev_safe(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; \ + prefetch(pos->prev), pos != (head); \ + pos = n, n = pos->prev) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +#endif + diff --git a/amavutils/include/media_ctl.h b/amavutils/include/media_ctl.h new file mode 100644 index 0000000..8f75276 --- a/dev/null +++ b/amavutils/include/media_ctl.h @@ -0,0 +1,36 @@ +#ifndef MEDIA_CTL_H +#define MEDIA_CTL_H + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <../mediaconfig/media_config.h> +#include <amports/amstream.h> +#include "../mediactl/common_ctl.h" +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct{ + const char *device; + const char *path; + int(*mediactl_setval)(const char* path, int val); + int(*mediactl_getval)(const char* path); + int(*mediactl_setstr)(const char* path, char* val); + int(*mediactl_getstr)(const char* path, char* buf,int size); +}MediaCtlPool; + +int mediactl_set_str_func(const char* path, char* val); +int mediactl_get_str_func(const char* path, char* valstr, int size); +int mediactl_set_int_func(const char* path, int val); +int mediactl_get_int_func(const char* path); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/amavutils/include/ppmgr/ppmgr.h b/amavutils/include/ppmgr/ppmgr.h new file mode 100644 index 0000000..b166297 --- a/dev/null +++ b/amavutils/include/ppmgr/ppmgr.h @@ -0,0 +1,24 @@ +/** +* @file ppmgr.h +* @brief Porting from ppmgr driver for codec ioctl commands +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#ifndef PPMGR_H +#define PPMGR_H + +#define PPMGR_IOC_MAGIC 'P' +//#define PPMGR_IOC_2OSD0 _IOW(PPMGR_IOC_MAGIC, 0x00, unsigned int) +//#define PPMGR_IOC_ENABLE_PP _IOW(PPMGR_IOC_MAGIC,0X01,unsigned int) +//#define PPMGR_IOC_CONFIG_FRAME _IOW(PPMGR_IOC_MAGIC,0X02,unsigned int) +#define PPMGR_IOC_GET_ANGLE _IOR(PPMGR_IOC_MAGIC,0X03,unsigned long) +#define PPMGR_IOC_SET_ANGLE _IOW(PPMGR_IOC_MAGIC,0X04,unsigned long) + +#endif /* PPMGR_H */ + diff --git a/amavutils/include/sub_ctl.h b/amavutils/include/sub_ctl.h new file mode 100644 index 0000000..c634596 --- a/dev/null +++ b/amavutils/include/sub_ctl.h @@ -0,0 +1,24 @@ +#ifndef SUB_CTL_H +#define SUB_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif + +int media_set_subtitle_fps(int fps); +int media_set_subtitle_total(int total); +int media_set_subtitle_enable(int enable); +int media_set_subtitle_index(int index); +int media_set_subtitle_width(int width); +int media_set_subtitle_height(int height); +int media_set_subtitle_type(int type); +int media_set_subtitle_curr(int num); +int media_set_subtitle_startpts(int startpts); +int media_set_subtitle_reset(int res); +int media_set_subtitle_size(int size); +int media_set_subtitle_subtype(int type); +#ifdef __cplusplus +} +#endif + +#endif
\ No newline at end of file diff --git a/amavutils/include/tsync_ctl.h b/amavutils/include/tsync_ctl.h new file mode 100644 index 0000000..27320e8 --- a/dev/null +++ b/amavutils/include/tsync_ctl.h @@ -0,0 +1,34 @@ +#ifndef TSYNC_CTL_H +#define TSYNC_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif +int media_set_tsync_enable(int enable); +int media_set_tsync_discontinue(int discontinue); +int media_set_tsync_vpause_flag(int val); +int media_set_tsync_pts_video(int val); +int media_set_tsync_pts_audio(int val); +int media_set_tsync_dobly_av_sync(int val); +int media_set_tsync_pts_pcrscr(int val); +int media_set_tsync_even_strt(char* buf); +int media_set_tsync_mode(int val); +int media_set_tsync_pcr_recover(int val); +int media_set_tsync_debug_pts_checkin(int val); +int media_set_tsync_debug_pts_checkout(int val); +int media_set_tsync_debug_video_pts(int val); +int media_set_tsync_debug_audio_pts(int val); +int media_set_tsync_av_threshold_min(int val); +int media_set_tsync_av_threshold_max(int val); +int media_set_tsync_last_checkin_apts(int val); +int media_set_tsync_firstvpts(int val); +int media_set_tsync_slowsync_enable(int val); +int media_set_tsync_startsync_mode(int val); +int media_set_tsync_firstapts(int val); +int media_set_tsync_checkin_firstvpts(int val); +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/amavutils/include/vfm_ctl.h b/amavutils/include/vfm_ctl.h new file mode 100644 index 0000000..81ac586 --- a/dev/null +++ b/amavutils/include/vfm_ctl.h @@ -0,0 +1,17 @@ +#ifndef VFM_CTL_H +#define VFM_CTL_H +#ifdef __cplusplus +extern "C" { +#endif +/*val --"rm default" or "add default decoder ...." */ +int media_set_vfm_map(const char* val); +int media_get_vfm_map(char* val,int size); +/* name --"default"; val -- "default decoder ..."*/ +int media_rm_vfm_map(const char* name,const char* val); +int media_add_vfm_map(const char* name,const char* val); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/amavutils/include/video_ctl.h b/amavutils/include/video_ctl.h new file mode 100644 index 0000000..a08fd11 --- a/dev/null +++ b/amavutils/include/video_ctl.h @@ -0,0 +1,81 @@ +#ifndef VIDEO_CTL_H +#define VIDEO_CTL_H +#ifdef __cplusplus +extern "C" { +#endif +#include "../mediactl/common_ctl.h" +int media_get_disable_video(); +int media_set_disable_video(int disable); +int media_get_black_policy(); +int media_set_black_policy(int val); +int media_get_screen_mode(); +int media_set_screen_mode(int mode); +int media_clear_video_buf(int val); +int media_set_amports_debugflags(int flag); +int media_get_amports_debugflags(); +int media_set_amports_def_4k_vstreambuf_sizeM(int size); +int media_get_amports_def_4k_vstreambuf_sizeM(); +int media_set_amports_def_vstreambuf_sizeM(int size); +int media_get_amports_def_vstreambuf_sizeM(); +int media_set_amports_slow_input(int flag); +int media_get_amports_slow_input(); +int media_set_video_pause_one_3d_fl_frame(int val); +int media_get_video_pause_one_3d_fl_frame(); +int media_set_video_debug_flag(int val); +int media_get_video_debug_flag(); +int media_set_video_force_3d_scaler(int val); +int media_get_video_force_3d_scaler(); +int media_set_vdieo_video_3d_format(int val); +int media_get_video_video_3d_format(); +int media_set_video_vsync_enter_line_max(int val); +int media_get_video_vsync_enter_line_max(); +int media_set_video_vsync_exit_line_max(int val); +int media_get_video_vsync_exit_line_max(); +int media_set_video_vsync_rdma_line_max(int val); +int media_get_video_vsync_rdma_line_max(); +int media_set_video_underflow(int val); +int media_get_video_underflow(); +int media_set_video_next_peek_underflow(int val); +int media_get_video_next_peek_underflow(); +int media_set_video_smooth_sync_enable(int val); +int media_get_video_smooth_sync_enable(); +int media_set_video_hdmi_in_onvideo(int val); +int media_get_video_hdmi_in_onvideo(); +int media_set_video_play_clone_rate(int val); +int media_get_video_play_clone_rate(); +int media_set_video_android_clone_rate(int val); +int media_get_video_android_clone_rate(); +int media_set_video_noneseamless_play_clone_rate(int val); +int media_get_video_noneseamless_play_clone_rate(); +int media_set_video_cur_dev_idx(int val); +int media_get_video_cur_dev_idx(); +int media_set_video_new_frame_count(int val); +int media_get_video_new_frame_count(); +int media_set_video_omx_pts(int val); +int media_get_video_omx_pts(); +int media_set_video_omx_pts_interval_upper(int val); +int media_get_video_omx_pts_interval_upper(); +int media_set_video_omx_pts_interval_lower(int val); +int media_get_video_omx_pts_interval_lower(); +int media_set_video_bypass_pps(int val); +int media_get_video_bypass_pps(); +int media_set_video_platform_type(int val); +int media_get_video_platform_type(); +int media_set_video_process_3d_type(int val); +int media_get_video_process_3d_type(); +int media_set_video_framepacking_support(int val); +int media_get_video_framepacking_support(); +int media_set_video_framepacking_width(int val); +int media_get_video_framepacking_width(); +int media_set_video_framepacking_height(int val); +int media_get_video_framepacking_height(); +int media_set_video_framepacking_blank(int val); +int media_get_video_framepacking_blank(); +int media_set_video_reverse(int val); +int media_get_video_reverse(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/amavutils/itemlist.c b/amavutils/itemlist.c new file mode 100644 index 0000000..6035784 --- a/dev/null +++ b/amavutils/itemlist.c @@ -0,0 +1,355 @@ +/******************************************** + * name : player_itemlis.c + * function: item fifo manage for muti threads + * date : 2011.3.23 + * author :zhouzhi + ********************************************/ + +#include <stdio.h> +#include <sys/time.h> +#include <time.h> +#include <pthread.h> +#include <stdlib.h> +#include <itemlist.h> + + + + +int itemlist_init(struct itemlist *itemlist) +{ + itemlist->item_count = 0; + INIT_LIST_HEAD(&itemlist->list); + ITEM_LOCK_INIT(itemlist); + return 0; +} +int itemlist_deinit(struct itemlist *itemlist) +{ + ITEM_LOCK_DESTROY(itemlist); + return 0; +} + +struct item * item_alloc(int ext) { + return malloc(sizeof(struct item) + ext); +} + + +void item_free(struct item *item) +{ + free(item); +} + + +int itemlist_add_tail(struct itemlist *itemlist, struct item *item) +{ + ITEM_LOCK(itemlist); + if (itemlist->max_items > 0 && itemlist->max_items <= itemlist->item_count) { + ITEM_UNLOCK(itemlist); + return -1; + } + list_add_tail(&item->list, &itemlist->list); + itemlist->item_count++; + ITEM_UNLOCK(itemlist); + return 0; +} + +struct item * itemlist_get_head(struct itemlist *itemlist) { + struct item *item = NULL; + struct list_head *list = NULL; + + ITEM_LOCK(itemlist); + if (!list_empty(&itemlist->list)) { + list = itemlist->list.next; + item = list_entry(list, struct item, list); + list_del(list); + itemlist->item_count--; + } + ITEM_UNLOCK(itemlist); + return item; +} + +struct item * itemlist_get_tail(struct itemlist *itemlist) { + struct item *item = NULL; + struct list_head *list = NULL; + + ITEM_LOCK(itemlist); + if (!list_empty(&itemlist->list)) { + list = itemlist->list.prev; + item = list_entry(list, struct item, list); + list_del(list); + itemlist->item_count--; + } + ITEM_UNLOCK(itemlist); + return item; +} + + +struct item * itemlist_peek_head(struct itemlist *itemlist) { + struct item *item = NULL; + struct list_head *list = NULL; + + ITEM_LOCK(itemlist); + if (!list_empty(&itemlist->list)) { + list = itemlist->list.next; + item = list_entry(list, struct item, list); + } + ITEM_UNLOCK(itemlist); + return item; +} + +struct item * itemlist_peek_tail(struct itemlist *itemlist) { + struct item *item = NULL; + struct list_head *list = NULL; + + ITEM_LOCK(itemlist); + if (!list_empty(&itemlist->list)) { + list = itemlist->list.prev; + item = list_entry(list, struct item, list); + } + ITEM_UNLOCK(itemlist); + return item; +} +int itemlist_del_item_locked(struct itemlist *itemlist, struct item *item) +{ + list_del(&item->list); + itemlist->item_count--; + return 0; +} + +int itemlist_del_item(struct itemlist *itemlist, struct item *item) +{ + ITEM_LOCK(itemlist); + itemlist_del_item_locked(itemlist, item); + ITEM_UNLOCK(itemlist); + return 0; +} + + +int itemlist_clean(struct itemlist *itemlist, data_free_fun free_fun) +{ + struct item *item = NULL; + struct list_head *llist, *tmplist; + ITEM_LOCK(itemlist); + list_for_each_safe(llist, tmplist, &itemlist->list) { + item = list_entry(llist, struct item, list); + if (free_fun != NULL && item->item_data != 0) { + free_fun((void *)item->item_data); + } + list_del(llist); + item_free(item); + itemlist->item_count--; + } + ITEM_UNLOCK(itemlist); + return 0; +} + +struct item * itemlist_get_match_item(struct itemlist *itemlist, unsigned long data) { + struct item *item = NULL; + struct list_head *llist, *tmplist; + struct item *finditem = NULL; + ITEM_LOCK(itemlist); + list_for_each_safe(llist, tmplist, &itemlist->list) { + item = list_entry(llist, struct item, list); + if (item->item_data == data) { + finditem = item; + break; + } + } + if (finditem != NULL) { + list_del(&finditem->list); + itemlist->item_count--; + } + ITEM_UNLOCK(itemlist); + return finditem; +} + +struct item * itemlist_find_match_item(struct itemlist *itemlist, unsigned long data) { + struct item *item = NULL; + struct list_head *llist, *tmplist; + struct item *finditem = NULL; + ITEM_LOCK(itemlist); + list_for_each_safe(llist, tmplist, &itemlist->list) { + item = list_entry(llist, struct item, list); + if (item->item_data == data) { + finditem = item; + break; + } + } + ITEM_UNLOCK(itemlist); + return finditem; +} + +/* +we think the item->data is grow, +we find the first item great or equal item->data; +*/ +struct item * itemlist_find_match_item_ex(struct itemlist *itemlist, struct item *tomatch, item_is_match_fun match, int reveser) { + struct item *item = NULL; + struct list_head *llist, *tmplist; + struct item *finditem = NULL; + ITEM_LOCK(itemlist); + if (reveser) { + list_for_each_entry_reverse(item, &itemlist->list, list) { + if (match(item, tomatch)) { + finditem = item; + break; + } + } + } else { + list_for_each_entry(item, &itemlist->list, list) { + if (match(item, tomatch)) { + finditem = item; + break; + } + } + } + + ITEM_UNLOCK(itemlist); + return finditem; +} + +int itemlist_add_tail_data_ext(struct itemlist *itemlist, unsigned long data, int extnum, unsigned long *extdata) +{ + struct item *item; + int i; + if (itemlist->reject_same_item_data && itemlist_have_match_data(itemlist, data)) { + return 0; /*have matched in list*/ + } + item = item_alloc(extnum * sizeof(unsigned long)); + if (item == NULL) { + return -12;//noMEM + } + item->item_data = data; + for (i = 0 ; i < extnum ; i++) { + item->extdata[i] = extdata[i]; + } + if (itemlist_add_tail(itemlist, item) != 0) { + item_free(item); + return -1; + } + return 0; +} +int itemlist_add_tail_data(struct itemlist *itemlist, unsigned long data) +{ + return itemlist_add_tail_data_ext(itemlist, data, 0, 0); +} + +int itemlist_get_head_data(struct itemlist *itemlist, unsigned long *data) +{ + struct item *item = NULL; + item = itemlist_get_head(itemlist); + if (item != NULL) { + *data = item->item_data; + item_free(item); + return 0; + } else { + return -1; + } +} + +int itemlist_get_tail_data(struct itemlist *itemlist, unsigned long *data) +{ + struct item *item = NULL; + item = itemlist_get_tail(itemlist); + if (item != NULL) { + *data = item->item_data; + return 0; + } else { + return -1; + } +} + + +int itemlist_peek_head_data(struct itemlist *itemlist, unsigned long *data) +{ + struct item *item = NULL; + item = itemlist_peek_head(itemlist); + if (item != NULL) { + *data = item->item_data; + return 0; + } else { + return -1; + } +} + + + + +int itemlist_peek_tail_data(struct itemlist *itemlist, unsigned long *data) +{ + struct item *item = NULL; + item = itemlist_peek_tail(itemlist); + if (item != NULL) { + *data = item->item_data; + return 0; + } else { + return -1; + } +} + + +int itemlist_clean_data(struct itemlist *itemlist, data_free_fun free_fun) +{ + return itemlist_clean(itemlist, free_fun); +} + +int itemlist_have_match_data(struct itemlist *itemlist, unsigned long data) +{ + struct item *item = NULL; + item = itemlist_find_match_item(itemlist, data); + return item != NULL; +} + + +int itemlist_del_match_data_item(struct itemlist *itemlist, unsigned long data) +{ + struct item *item = NULL; + item = itemlist_get_match_item(itemlist, data); + if (item) { + item_free(item); + return 0; + } + return -1; +} + +/* +postion must in the itemlist. +flags: 1: before position; + 2: after postion; + 3: replace postion; + else: + 2:after postion; +*/ +int itemlist_item_insert(struct itemlist *itemlist, struct itemlist *position, struct itemlist *newitem, int flags) +{ + ITEM_LOCK(itemlist); + if (flags != 3 && itemlist->max_items > 0 && itemlist->max_items <= itemlist->item_count) { + ITEM_UNLOCK(itemlist); + return -1; + } + if (flags == 1) { + list_add_tail(&newitem->list, &position->list); + } else { + list_add(&newitem->list, &position->list); + } + if (flags == 3) { + list_del(&position->list); + } else { + itemlist->item_count++; + } + ITEM_UNLOCK(itemlist); + return 0; +} + +int itemlist_print(struct itemlist *itemlist, printitem_fun print) +{ + struct item *item = NULL; + struct list_head *llist, *tmplist; + ITEM_LOCK(itemlist); + list_for_each_safe(llist, tmplist, &itemlist->list) { + item = list_entry(llist, struct item, list); + print(item); + } + ITEM_UNLOCK(itemlist); + return 0; +} + diff --git a/amavutils/mediaconfig/configs_api.h b/amavutils/mediaconfig/configs_api.h new file mode 100644 index 0000000..a6a72aa --- a/dev/null +++ b/amavutils/mediaconfig/configs_api.h @@ -0,0 +1,31 @@ +#ifndef AMLOGIC_MEDIA_CONFIG_API__ +#define AMLOGIC_MEDIA_CONFIG_API__ +#include <linux/ioctl.h> +#define MAX_ITEM_NAME 128 +#define MAX_PREFIX_NAME 128 +#define MAX_VALUE_NAME 256 +struct media_config_io_str { + union{ + int subcmd; + int ret; + }; + union { + int para[10]; + char cmd_path[MAX_PREFIX_NAME + MAX_ITEM_NAME + 4]; + }; + union { + char val[MAX_VALUE_NAME]; + char *ptr; + }; +}; + + +#define AML_CONFIG 'C' +#define MEDIA_CONFIG_SET_CMD_STR _IOW((AML_CONFIG), 0x1,\ + struct media_config_io_str) +#define MEDIA_CONFIG_GET_CMD_STR _IOWR((AML_CONFIG), 0x2,\ + struct media_config_io_str) + +#endif + + diff --git a/amavutils/mediaconfig/media_config.cpp b/amavutils/mediaconfig/media_config.cpp new file mode 100644 index 0000000..479e525 --- a/dev/null +++ b/amavutils/mediaconfig/media_config.cpp @@ -0,0 +1,187 @@ +#define LOG_TAG "meda_config_hw" +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <cutils/log.h> +#include <sys/ioctl.h> +#include <cutils/properties.h> +#include <pthread.h> +#include "media_config_hw.h" + +#define MEDIA_FD_INDEX 0 /*media.*/ +#define MEDIA_DECODER_FD_INDEX 1 /*media.decoder*/ +#define MEDIA_PARSER_FD_INDEX 2 /*media.parser*/ +#define MEDIA_VIDEO_FD_INDEX 3 /*media.video*/ +#define MEDIA_SYNC_FD_INDEX 4 /*media.sync*/ +#define MEDIA_CODEC_MM_FD_INDEX 5 /*media.code_mm*/ +#define MEDIA_AUDIO_FD_INDEX 6 /*media.audio*/ +#define MEDIA_FD_INDEX_MAX 7 /*MAX*/ + +struct device_info_t { + const char *dev; + pthread_mutex_t lock; + int fd; +}; + +static struct device_info_t device_info[] = { + {"/dev/media", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.decoder", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.parser", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.video", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.tsync", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.codec_mm", PTHREAD_MUTEX_INITIALIZER, -1}, + {"/dev/media.audio", PTHREAD_MUTEX_INITIALIZER, -1}, + {"nal", PTHREAD_MUTEX_INITIALIZER, -1}, +}; + + +static int require_fd_device_lock(struct device_info_t *dev) +{ + pthread_mutex_lock(&dev->lock); + if (dev->fd < 0) { + dev->fd = media_config_open(dev->dev, O_RDWR); + } + if (dev->fd < 0) { + pthread_mutex_unlock(&dev->lock); + } + return dev->fd; +} +static int release_fd_device_unlock(struct device_info_t *dev) +{ + pthread_mutex_unlock(&dev->lock); + return 0; +} + +static int local_media_set_cmd_str(int dev_index, const char *cmd, const char *val) +{ + int err; + struct device_info_t *dev; + + if (dev_index < 0 || dev_index >= MEDIA_FD_INDEX_MAX) { + return -1; + } + dev = &device_info[dev_index]; + err = require_fd_device_lock(dev); + if (err < 0) { + return err; + } + err = media_config_set_str(dev->fd, cmd, val); + release_fd_device_unlock(dev); + return err; +} + +static int local_media_get_cmd_str(int dev_index, const char *cmd, char *val, int len) +{ + int err; + struct device_info_t *dev; + if (dev_index < 0 || dev_index >= MEDIA_FD_INDEX_MAX) { + return -1; + } + dev = &device_info[dev_index]; + err = require_fd_device_lock(dev); + if (err < 0) { + return err; + } + err = media_config_get_str(dev->fd, cmd, val, len); + release_fd_device_unlock(dev); + return err; +} + +static int local_media_config_list(int dev_index, char *val, int len) +{ + int err; + struct device_info_t *dev; + if (dev_index < 0 || dev_index >= MEDIA_FD_INDEX_MAX) { + return -1; + } + dev = &device_info[dev_index]; + err = require_fd_device_lock(dev); + if (err < 0) { + return err; + } + err = media_config_list_cmd(dev->fd, val, len); + release_fd_device_unlock(dev); + return err; +} + +int media_config_list(char *val, int len) +{ + return local_media_config_list(MEDIA_FD_INDEX, val, len); +} + + +int media_set_cmd_str(const char *cmd, const char *val) +{ + + return local_media_set_cmd_str(MEDIA_FD_INDEX, cmd, val); +} +int media_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_FD_INDEX, cmd, val, len); +} + +int media_decoder_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_DECODER_FD_INDEX, cmd, val); +} +int media_decoder_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_DECODER_FD_INDEX, cmd, val, len); +} + +int media_parser_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_PARSER_FD_INDEX, cmd, val); +} + +int media_parser_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_PARSER_FD_INDEX, cmd, val, len); +} + +int media_video_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_VIDEO_FD_INDEX, cmd, val); +} + +int media_video_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_VIDEO_FD_INDEX, cmd, val, len); +} + +int media_sync_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_SYNC_FD_INDEX, cmd, val); +} + +int media_sync_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_SYNC_FD_INDEX, cmd, val, len); +} + +int media_codecmm_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_CODEC_MM_FD_INDEX, cmd, val); +} + +int media_codecmm_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_CODEC_MM_FD_INDEX, cmd, val, len); +} + +int media_audio_set_cmd_str(const char *cmd, const char *val) +{ + return local_media_set_cmd_str(MEDIA_AUDIO_FD_INDEX, cmd, val); +} + +int media_audio_get_cmd_str(const char *cmd, char *val, int len) +{ + return local_media_get_cmd_str(MEDIA_AUDIO_FD_INDEX, cmd, val, len); +} + + + + + diff --git a/amavutils/mediaconfig/media_config.h b/amavutils/mediaconfig/media_config.h new file mode 100644 index 0000000..2436d51 --- a/dev/null +++ b/amavutils/mediaconfig/media_config.h @@ -0,0 +1,19 @@ +#ifndef MEDIA_CONFIG_API___ +#define MEDIA_CONFIG_API___ +int media_config_list(char *val, int len); +int media_set_cmd_str(const char *cmd, const char *val); +int media_get_cmd_str(const char *cmd, char *val, int len); +int media_decoder_set_cmd_str(const char *cmd, const char *val); +int media_decoder_get_cmd_str(const char *cmd, char *val, int len); +int media_parser_set_cmd_str(const char *cmd, const char *val); +int media_parser_get_cmd_str(const char *cmd, char *val, int len); +int media_video_set_cmd_str(const char *cmd, const char *val); +int media_video_get_cmd_str(const char *cmd, char *val, int len); +int media_sync_set_cmd_str(const char *cmd, const char *val); +int media_sync_get_cmd_str(const char *cmd, char *val, int len); +int media_codecmm_set_cmd_str(const char *cmd, const char *val); +int media_codecmm_get_cmd_str(const char *cmd, char *val, int len); +int media_audio_set_cmd_str(const char *cmd, const char *val); +int media_audio_get_cmd_str(const char *cmd, char *val, int len); +#endif + diff --git a/amavutils/mediaconfig/media_config_hw.cpp b/amavutils/mediaconfig/media_config_hw.cpp new file mode 100644 index 0000000..59879dd --- a/dev/null +++ b/amavutils/mediaconfig/media_config_hw.cpp @@ -0,0 +1,74 @@ +#define LOG_TAG "meda_config_hw" + +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <cutils/log.h> +#include <sys/ioctl.h> +#include <cutils/properties.h> +#include "configs_api.h" + +int media_config_open(const char *path, int flags) +{ + int fd = open(path, flags); + if (fd < 0) { + if (-errno < 0) + fd = -errno; + ALOGE("open %s, failed %d, err=%s(%d)\n", + path, fd, strerror(errno), + -errno); + } + return fd; +} +int media_config_close(int fd) +{ + if (fd >= 0) { + close(fd); + } + return 0; +} + +int media_config_set_str(int fd, const char *cmd, const char *val) +{ + struct media_config_io_str io; + int ret; + io.subcmd = 0; + if (!cmd || !val) { + return -EIO; + } + strncpy(io.cmd_path, cmd, sizeof(io.cmd_path)); + strncpy(io.val, val, sizeof(io.val)); + ret = ioctl(fd, MEDIA_CONFIG_SET_CMD_STR, &io); + return ret; +} +int media_config_get_str(int fd, const char *cmd, char *val, int len) +{ + struct media_config_io_str io; + int ret; + io.subcmd = 0; + if (!cmd || !val) { + return -EIO; + } + strncpy(io.cmd_path, cmd, sizeof(io.cmd_path)); + io.val[0] = '\0'; + ret = ioctl(fd, MEDIA_CONFIG_GET_CMD_STR, &io); + if (ret == 0) { + int ret_len = io.ret; + if (ret_len > len) { + ret_len = len - 1; + } + strncpy(val, io.val, ret_len); + val[ret_len] = '\0'; + } + return ret; +} +int media_config_list_cmd(int fd, char *val, int len) +{ + int ret; + lseek(fd, 0, SEEK_SET); + ret = read(fd, val, len); + return ret; +} + + diff --git a/amavutils/mediaconfig/media_config_hw.h b/amavutils/mediaconfig/media_config_hw.h new file mode 100644 index 0000000..6535ac8 --- a/dev/null +++ b/amavutils/mediaconfig/media_config_hw.h @@ -0,0 +1,16 @@ +#ifndef MEDIA_CONFIG_HW___ +#define MEDIA_CONFIG_HW___ +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <cutils/log.h> +#include <sys/ioctl.h> +#include <cutils/properties.h> +int media_config_open(const char *path, int flags); +int media_config_close(int fd); +int media_config_set_str(int fd, const char *cmd, const char *val); +int media_config_get_str(int fd, const char *cmd, char *val, int len); +int media_config_list_cmd(int fd, char *val, int len); +#endif + diff --git a/amavutils/mediactl/audio_ctl.cpp b/amavutils/mediactl/audio_ctl.cpp new file mode 100644 index 0000000..15923ec --- a/dev/null +++ b/amavutils/mediactl/audio_ctl.cpp @@ -0,0 +1,74 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <audio_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif +/*adec*/ +int media_set_adec_format(int format) +{ + return media_set_ctl("media.adec.format",format); +} + +int media_get_adec_format() +{ + return media_get_ctl("media.adec.format"); +} + +int media_set_adec_samplerate(int rate) +{ + return media_set_ctl("media.adec.samplerate",rate); +} + +int media_get_adec_samplerate() +{ + return media_get_ctl("media.adec.samplerate"); +} + +int media_set_adec_channum(int num) +{ + return media_set_ctl("media.adec.channum",num); +} + +int media_get_adec_channum() +{ + return media_get_ctl("media.adec.channum"); +} + +int media_set_adec_pts(int pts) +{ + return media_set_ctl("media.adec.pts",pts); +} + +int media_get_adec_pts() +{ + return media_get_ctl("media.adec.pts"); +} + +int media_set_adec_datawidth(int width) +{ + return media_set_ctl("media.adec.datawidth",width); +} + +int media_get_adec_datawidth() +{ + return media_get_ctl("media.adec.datawidth"); +} + +int media_get_audio_digital_output_mode() +{ + return media_get_ctl("media.audio.audiodsp.digital_raw"); +} +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/amavutils/mediactl/common_ctl.cpp b/amavutils/mediactl/common_ctl.cpp new file mode 100644 index 0000000..8ba5016 --- a/dev/null +++ b/amavutils/mediactl/common_ctl.cpp @@ -0,0 +1,343 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <../mediaconfig/media_config.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#ifdef __cplusplus +extern "C" { +#endif + +int media_set_ctl(const char * path,int setval) +{ + char val[32]; + CTRL_PRINT("set %s =%d\n",path,setval); + sprintf(val, "%d", setval); + media_set_cmd_str(path, val); + return 0; +} + +int media_get_ctl(const char * path) +{ + char buf[32]; + int ret = 0; + int val = 0; + ret = media_get_cmd_str(path, buf, 32); + if (!ret) { + if (strstr(buf, "0x")) + sscanf(buf, "0x%x", &val); + else if (strstr(buf, "0X")) + sscanf(buf, "0X%x", &val); + else + sscanf(buf, "%d", &val); + } + CTRL_PRINT("get path=%s val =%d\n",path,val); + return val; +} + +int media_set_ctl_str(const char * path,char* setval) +{ CTRL_PRINT("setstr %s =%s\n",path,setval); + media_set_cmd_str(path, setval); + return 0; +} + +int media_get_ctl_str(const char * path, char* buf, int size) +{ + int ret = 0; + char getbuf[300]; + CTRL_PRINT("getstr path %s size=%d\n",path,size); + if (size >300) + size = 300; + ret = media_get_cmd_str(path, getbuf, size); + strncpy(buf,getbuf,size); + return ret; +} + + +int media_sync_set_ctl(const char * path,int setval) +{ + char val[32]; + CTRL_PRINT("set %s =%d\n",path,setval); + sprintf(val, "%d", setval); + media_sync_set_cmd_str(path, val); + return 0; +} + +int media_sync_get_ctl(const char * path) +{ + char buf[32]; + int ret = 0; + int val = 0; + ret = media_sync_get_cmd_str(path, buf, 32); + if (!ret) { + sscanf(buf, "%d", &val); + } + CTRL_PRINT("get val =%d\n",val); + return val == 1 ? val : 0; +} + +int media_sync_set_ctl_str(const char * path,char* setval) +{ + media_sync_set_cmd_str(path, setval); + return 0; +} + +int media_sync_get_ctl_str(const char * path, char* buf, int size) +{ + int ret = 0; + ret = media_sync_get_cmd_str(path, buf, size); + return ret; +} + +int media_video_set_ctl(const char * path,int setval) +{ + char val[32]; + CTRL_PRINT("set %s =%d\n",path,setval); + sprintf(val, "%d", setval); + media_video_set_cmd_str(path, val); + return 0; +} + +int media_video_get_ctl(const char * path) +{ + char buf[32]; + int ret = 0; + int val = 0; + ret = media_video_get_cmd_str(path, buf, 32); + if (!ret) { + sscanf(buf, "%d", &val); + } + CTRL_PRINT("get val =%d\n",val); + return val == 1 ? val : 0; +} + +int media_video_set_ctl_str(const char * path,char* setval) +{ + media_video_set_cmd_str(path, setval); + return 0; +} + +int media_video_get_ctl_str(const char * path, char* buf, int size) +{ + int ret = 0; + ret = media_video_get_cmd_str(path, buf, size); + return ret; +} + +int media_decoder_set_ctl(const char * path,int setval) +{ + char val[32]; + CTRL_PRINT("set %s =%d\n",path,setval); + sprintf(val, "%d", setval); + media_decoder_set_cmd_str(path, val); + return 0; +} + +int media_decoder_get_ctl(const char * path) +{ + char buf[32]; + int ret = 0; + int val = 0; + ret = media_decoder_get_cmd_str(path, buf, 32); + if (!ret) { + sscanf(buf, "%d", &val); + } + CTRL_PRINT("get val =%d\n",val); + return val == 1 ? val : 0; +} + +int media_decoder_set_ctl_str(const char * path,char* setval) +{ + media_decoder_set_cmd_str(path, setval); + return 0; +} + +int media_decoder_get_ctl_str(const char * path, char* buf, int size) +{ + int ret = 0; + ret = media_decoder_get_cmd_str(path, buf, size); + return ret; +} + +int media_open(const char *path, int flags) +{ + int fd = 0; + fd = open(path, flags); + if (fd < 0) { + CTRL_PRINT("open [%s] failed,ret = %d errno=%d\n", path, fd, errno); + return fd; + } + return fd; +} + +int media_close(int fd) +{ + int res = 0; + if (fd) { + res = close(fd); + } + return res; +} + +int media_control(int fd, int cmd, unsigned long paramter) +{ + int r; + + if (fd < 0) { + return -1; + } + r = ioctl(fd, cmd, paramter); + if (r < 0) { + CTRL_PRINT("send control failed,handle=%d,cmd=%x,paramter=%x, t=%x errno=%d\n", fd, cmd, paramter, r, errno); + return r; + } + return 0; +} + +int media_get_int(const char* dev, int cmd) +{ + int fd,res; + unsigned long para; + fd = media_open(dev,O_RDWR); + res = media_control(fd, cmd,(unsigned long)¶); + if (0 == res) + media_close(fd); + ALOGD("get para =%ld\n",para); + return para == 1 ? para : 0; +} +int media_set_int(const char* dev, int cmd, int setpara) +{ + int fd,res; + unsigned long para=setpara; + CTRL_PRINT("set para =%ld\n",para); + fd = media_open(dev,O_RDWR); + res = media_control(fd, cmd, (unsigned long)¶); + if (fd >= 0) + media_close(fd); + return res; +} + +int media_video_get_int(int cmd) +{ + return media_get_int("/dev/amvideo", cmd); +} + +int media_video_set_int(int cmd, int para) +{ + return media_set_int("/dev/amvideo", cmd, para); +} + +int media_vfm_set_ulong(int cmd, unsigned long para) +{ int fd,res; + fd = media_open("dev/vfm",O_RDWR); + if (fd < 0) + return fd; + res = media_control(fd, cmd, para); + if (fd >= 0) + media_close(fd); + return res; +} + + +int media_set_vfm_map_str(const char* val) +{ + int fd,res; + struct vfmctl setvfmctl; + if (val == NULL) + return -1; + setvfmctl.name[0] = '\0'; + strncpy(setvfmctl.val, val, sizeof(setvfmctl.val)); + return media_vfm_set_ulong(VFM_IOCTL_CMD_SET, (unsigned long)&setvfmctl); +} + +int media_get_vfm_map_str(char* val,int size) +{ + int fd,res,len; + struct vfmctl setvfmctl; + if (val == NULL) + return -1; + setvfmctl.name[0] = '\0'; + setvfmctl.val[0] = '\0'; + media_vfm_set_ulong(VFM_IOCTL_CMD_GET, (unsigned long)&setvfmctl); + len = sizeof(setvfmctl.val); + if (len > size) + len = size; + strncpy(val, setvfmctl.val, len); + CTRL_PRINT("get vfm:val %s \n",val); + return 0; +} + +int media_rm_vfm_map_str(const char* name,const char* val) +{ + int fd,res; + struct vfmctl setvfmctl; + if (val == NULL || name == NULL) + return -1; + strncpy(setvfmctl.name,name,sizeof(setvfmctl.name)); + strncpy(setvfmctl.val,val,sizeof(setvfmctl.val)); + CTRL_PRINT("rm vfm: cmd=%s,val %s \n",name,val); + return media_vfm_set_ulong(VFM_IOCTL_CMD_RM,(unsigned long)&setvfmctl); +} + +int media_add_vfm_map_str(const char* name,const char* val) +{ + int fd,res; + struct vfmctl setvfmctl; + if (val == NULL || name == NULL) + return -1; + strncpy(setvfmctl.name,name,sizeof(setvfmctl.name)); + strncpy(setvfmctl.val,val,sizeof(setvfmctl.val)); + CTRL_PRINT("add vfm: cmd=%s,val %s \n",name,val); + return media_vfm_set_ulong(VFM_IOCTL_CMD_ADD,(unsigned long)&setvfmctl); +} + +int media_codec_mm_set_ctl_str(const char * path,char* setval) +{ + media_codecmm_set_cmd_str(path, setval); + return 0; +} + +int media_codec_mm_get_ctl_str(const char * path, char* buf, int size) +{ + int ret = 0; + ret = media_codecmm_get_cmd_str(path, buf, size); + return ret; +} + + +int media_sub_getinfo(int type) +{ int fd,res; + struct subinfo_para_s subinfo; + subinfo.subinfo_type = (subinfo_para_e)type; + subinfo.subtitle_info= 0; + subinfo.data = NULL; + fd = media_open("/dev/amsubtitle",O_RDONLY ); + res = media_control(fd,AMSTREAM_IOC_GET_SUBTITLE_INFO, (unsigned long)&subinfo); + if (fd >= 0) + media_close(fd); + return subinfo.subtitle_info; + +} + +int media_sub_setinfo(int type, int info) +{ int fd,res; + struct subinfo_para_s subinfo; + subinfo.subinfo_type = (subinfo_para_e)type; + subinfo.subtitle_info= info; + subinfo.data = NULL; + fd = media_open("/dev/amsubtitle",O_WRONLY); + res = media_control(fd, AMSTREAM_IOC_SET_SUBTITLE_INFO, (unsigned long)&subinfo); + if (fd >= 0) + media_close(fd); + return res; +} + +#ifdef __cplusplus +} +#endif diff --git a/amavutils/mediactl/common_ctl.h b/amavutils/mediactl/common_ctl.h new file mode 100644 index 0000000..8f1e2f6 --- a/dev/null +++ b/amavutils/mediactl/common_ctl.h @@ -0,0 +1,95 @@ +#ifndef COMMON_CTL_H +#define COMMON_CTL_H + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <../mediaconfig/media_config.h> +#include <amports/amstream.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define UnSupport 0xFFFF +//#define CTRL_PRINT ALOGD +#define CTRL_PRINT +int media_open(const char *path, int flags); +int media_close(int fd); +int media_control(int fd, int cmd, unsigned long paramter); +int media_set_ctl(const char * path,int setval); +int media_get_ctl(const char * path); +int media_set_ctl_str(const char * path,char* setval); +int media_get_ctl_str(const char * path, char* buf, int size); +int media_sync_set_ctl(const char * path,int setval); +int media_sync_get_ctl(const char * path); +int media_sync_set_ctl_str(const char * path,char* setval); +int media_sync_get_ctl_str(const char * path, char* buf, int size); +int media_video_set_ctl(const char * path,int setval); +int media_video_get_ctl(const char * path); +int media_video_set_ctl_str(const char * path,char* setval); +int media_video_get_ctl_str(const char * path, char* buf, int size); +int media_decoder_set_ctl(const char * path,int setval); +int media_decoder_get_ctl(const char * path); +int media_decoder_set_ctl_str(const char * path,char* setval); +int media_decoder_get_ctl_str(const char * path, char* buf, int size); +int media_video_get_int(int cmd); +int media_video_set_int(int cmd, int para); +int media_vfm_get_ulong(int cmd); +int media_vfm_set_ulong(int cmd, unsigned long para); +int media_codec_mm_set_ctl_str(const char * path,char* setval); +int media_codec_mm_get_ctl_str(const char * path, char* buf, int size); +int media_get_vfm_map_str(char* val,int size); +int media_set_vfm_map_str(const char* val); +int media_rm_vfm_map_str(const char* name,const char* val); +int media_add_vfm_map_str(const char* name,const char* val); +int media_sub_getinfo(int type); +int media_sub_setinfo(int type, int info); +struct vfmctl{ +char name[10]; +char val[300]; +}; + +#define VFM_IOC_MAGIC 'V' +#define VFM_IOCTL_CMD_ADD _IOW((VFM_IOC_MAGIC), 0x00, struct vfmctl) +#define VFM_IOCTL_CMD_RM _IOW((VFM_IOC_MAGIC), 0x01, struct vfmctl) +#define VFM_IOCTL_CMD_DUMP _IOW((VFM_IOC_MAGIC), 0x02, struct vfmctl) +#define VFM_IOCTL_CMD_ADDDUMMY _IOW((VFM_IOC_MAGIC), 0x03, struct vfmctl) +#define VFM_IOCTL_CMD_SET _IOW(VFM_IOC_MAGIC, 0x04, struct vfmctl) +#define VFM_IOCTL_CMD_GET _IOWR(VFM_IOC_MAGIC, 0x05, struct vfmctl) + + +enum subinfo_para_e { + SUB_NULL = -1, + SUB_ENABLE = 0, + SUB_TOTAL, + SUB_WIDTH, + SUB_HEIGHT, + SUB_TYPE, + SUB_CURRENT, + SUB_INDEX, + SUB_WRITE_POS, + SUB_START_PTS, + SUB_FPS, + SUB_SUBTYPE, + SUB_RESET, + SUB_DATA_T_SIZE, + SUB_DATA_T_DATA +}; + +struct subinfo_para_s { + enum subinfo_para_e subinfo_type; + int subtitle_info; + char *data; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/amavutils/mediactl/media_ctl.cpp b/amavutils/mediactl/media_ctl.cpp new file mode 100644 index 0000000..3f7397a --- a/dev/null +++ b/amavutils/mediactl/media_ctl.cpp @@ -0,0 +1,526 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <../mediaconfig/media_config.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <media_ctl.h> +#include <video_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static int mediactl_set_black_policy(const char* path, int blackout) +{ + int para=blackout; + if (path == NULL) + return -1; + return media_video_set_int(AMSTREAM_IOC_SET_BLACKOUT_POLICY, para); +} + +static int mediactl_get_black_policy(const char* path) +{ + if (path == NULL) + return -1; + return media_video_get_int(AMSTREAM_IOC_GET_BLACKOUT_POLICY); +} + +static int mediactl_get_disable_video(const char* path) +{ + if (path == NULL) + return -1; + return media_video_get_int(AMSTREAM_IOC_GET_VIDEO_DISABLE); +} + +static int mediactl_set_disable_video(const char* path, int mode) +{ + int para=mode; + if (path == NULL) + return -1; + return media_video_set_int(AMSTREAM_IOC_SET_VIDEO_DISABLE, para); +} + +static int mediactl_set_screen_mode(const char* path, int mode) +{ + int para=mode; + if (path == NULL) + return -1; + return media_video_set_int(AMSTREAM_IOC_SET_SCREEN_MODE, para); +} + +static int mediactl_get_screen_mode(const char* path) +{ + if (path == NULL) + return -1; + return media_video_get_int(AMSTREAM_IOC_GET_SCREEN_MODE); +} + +static int mediactl_clear_video_buf( const char * path, int val) +{ + int para=val; + if (path == NULL) + return -1; + return media_video_set_int(AMSTREAM_IOC_CLEAR_VBUF, para); +} +int mediactl_get_subtitle_fps(const char* path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_FPS); +} + +int mediactl_set_subtitle_fps(const char * path,int fps) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_FPS, fps); +} + +int mediactl_get_subtitle_total(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_TOTAL); +} + +int mediactl_set_subtitle_total(const char * path, int total) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_TOTAL, total); +} + +int mediactl_get_subtitle_enable(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_ENABLE); +} + +int mediactl_set_subtitle_enable(const char * path,int enable) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_ENABLE, enable); +} + +int mediactl_get_subtitle_index(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_INDEX); +} + +int mediactl_set_subtitle_index(const char * path,int index) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_INDEX, index); +} + +int mediactl_get_subtitle_width(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_WIDTH); +} + +int mediactl_set_subtitle_width(const char * path, int width) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_WIDTH, width); +} + +int mediactl_get_subtitle_height(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_HEIGHT); +} + +int mediactl_set_subtitle_height(const char * path, int height) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_HEIGHT, height); +} + +int mediactl_get_subtitle_subtype(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_SUBTYPE); +} + +int mediactl_set_subtitle_subtype(const char * path, int type) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_SUBTYPE, type); +} + +int mediactl_get_subtitle_curr(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_CURRENT); +} + +int mediactl_set_subtitle_curr(const char * path, int num) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_CURRENT, num); +} + +int mediactl_get_subtitle_startpts(const char * path) +{ + if (path == NULL) + return -1; + return media_sub_getinfo(SUB_START_PTS); +} + +int mediactl_set_subtitle_startpts(const char * path, int startpts) +{ + if (path == NULL) + return -1; + return media_sub_setinfo(SUB_START_PTS, startpts); +} + +static MediaCtlPool Mediactl_SetPool[] = { + {"/sys/class/tsync/enable","media.tsync.enable", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/slowsync_enable","media.tsync.slowsync_enable", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/startsync_mode","media.tsync.startsync_mode", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/av_threshold_min","media.tsync.av_threshold_min", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/vpause_flag","media.tsync.vpause_flag", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/pts_pcrscr","media.tsync.pts_pcrscr", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/pts_video","media.tsync.pts_video", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/pts_audio","media.tsync.pts_audio", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/vpause_flag","media.tsync.vpause_flag", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/mode","media.tsync.mode", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/firstapts","media.tsync.firstapts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/event","media.tsync.event", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/discontinue","media.tsync.discontinue", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/dobly_av_sync","media.tsync.dobly_av_sync", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/pcr_recover","media.tsync.pcr_recover", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/debug_pts_checkin","media.tsync.debug_pts_checkin", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/debug_pts_checkout","media.tsync.debug_pts_checkout", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/debug_video_pts","media.tsync.debug_video_pts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/debug_audio_pts","media.tsync.debug_audio_pts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/av_threshold_max","media.tsync.av_threshold_max", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/last_checkin_apts","media.tsync.last_checkin_apts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/firstvpts","media.tsync.firstvpts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/tsync/checkin_firstvpts","media.tsync.checkin_firstvpts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/digital_raw","media.audio.audiodsp.digital_raw", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/ac3_drc_control","media.audio.audiodsp.ac3_drc_control", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/audio_samesource","media.audio.audiodsp.audio_samesource", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/codec_fatal_err","media.audio.audiodsp.codec_fatal_err", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/digital_codec","media.audio.audiodsp.digital_codec", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/audiodsp/dts_dec_control","media.audio.audiodsp.dts_dec_control", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/new_frame_count","media.video.new_frame_count", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/hdmi_in_onvideo","media.video.hdmi_in_onvideo", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/pause_one_3d_fl_frame","media.video.pause_one_3d_fl_frame", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/pause_one_3d_fl_frame","media.video.pause_one_3d_fl_frame", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/debug_flag","media.video.debug_flag", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/force_3d_scaler","media.video.force_3d_scaler", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/video_3d_format","media.video.video_3d_format", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/vsync_enter_line_max","media.video.vsync_enter_line_max", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/vsync_enter_line_max","media.video.vsync_enter_line_max", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/vsync_exit_line_max","media.video.vsync_exit_line_max", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/vsync_rdma_line_max","media.video.vsync_rdma_line_max", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/underflow","media.video.underflow", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/next_peek_underflow","media.video.next_peek_underflow", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/smooth_sync_enable","media.video.smooth_sync_enable", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/hdmi_in_onvideo","media.video.hdmi_in_onvideo", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/video_play_clone_rate","media.video.video_play_clone_rate", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/android_clone_rate","media.video.android_clone_rate", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/noneseamless_play_clone_rate","media.video.noneseamless_play_clone_rate", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/cur_dev_idx","media.video.cur_dev_idx", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/omx_pts","media.video.omx_pts", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/omx_pts_interval_upper","media.video.omx_pts_interval_upper", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/bypass_pps","media.video.bypass_pps", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/platform_type","media.video.platform_type", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/process_3d_type","media.video.process_3d_type", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/framepacking_support","media.video.framepacking_support", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/framepacking_width","media.video.framepacking_width", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/framepacking_height","media.video.framepacking_height", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/framepacking_blank","media.video.framepacking_blank", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvideo/parameters/reverse","media.video.reverse", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/double_write_mode","media.decoder.h265.double_write_mode", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/buf_alloc_width","media.decoder.h265.buf_alloc_width", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/buf_alloc_height","media.decoder.h265.buf_alloc_height", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/buffer_mode","media.decoder.h265.buffer_mode", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/dynamic_buf_num_margin","media.decoder.h265.dynamic_buf_num_margin", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_h265/parameters/debug","media.decoder.h265.debug", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_vp9/parameters/double_write_mode","media.decoder.vp9.double_write_mode", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_vp9/parameters/buf_alloc_width","media.decoder.vp9.buf_alloc_width", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/module/amvdec_vp9/parameters/buf_alloc_height","media.decoder.vp9.buf_alloc_height", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/vfm/map","media.vfm.map", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/video/video_seek_flag","media.video.video_seek_flag", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/video/slowsync_repeat_enable","media.video.slowsync_repeat_enable", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/video/show_first_frame_nosync","media.video.show_first_frame_nosync", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/amstream/videobufused","media.amports.videobufused", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/vdec/poweron_clock_level","media.decoder.vdec.poweron_clock_level", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/codec_mm/tvp_enable","media.codec_mm.trigger.tvp_enable", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/codec_mm/fastplay","media.codec_mm.trigger.fastplay", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/codec_mm/debug","media.codec_mm.trigger.debug", + media_set_ctl,media_get_ctl, + media_set_ctl_str,media_get_ctl_str}, + {"/sys/class/video/blackout_policy","/dev/amvideo", + mediactl_set_black_policy,mediactl_get_black_policy, + NULL,NULL}, + {"/sys/class/video/screen_mode","/dev/amvideo", + mediactl_set_screen_mode,mediactl_get_screen_mode, + NULL,NULL}, + {"/sys/class/video/disable_video","/dev/amvideo", + mediactl_set_disable_video,mediactl_get_disable_video, + NULL,NULL}, + {"/sys/class/video/clear_video_buf","/dev/amvideo", + mediactl_clear_video_buf,NULL, + NULL,NULL}, + {"/sys/class/subtitle/fps","/dev/amsubtitle", + mediactl_set_subtitle_fps,mediactl_get_subtitle_fps, + NULL,NULL}, + {"/sys/class/subtitle/total","/dev/amsubtitle", + mediactl_set_subtitle_total,mediactl_get_subtitle_total, + NULL,NULL}, + {"/sys/class/subtitle/curr","/dev/amsubtitle", + mediactl_set_subtitle_curr,mediactl_get_subtitle_curr, + NULL,NULL}, + {"/sys/class/subtitle/subtype","/dev/amsubtitle", + mediactl_set_subtitle_subtype,mediactl_get_subtitle_subtype, + NULL,NULL}, + {"/sys/class/subtitle/startpts","/dev/amsubtitle", + mediactl_set_subtitle_startpts,mediactl_get_subtitle_startpts, + NULL,NULL}, + {"/sys/class/subtitle/index","/dev/amsubtitle", + mediactl_set_subtitle_index,mediactl_get_subtitle_index, + NULL,NULL}, + {NULL, NULL, NULL, NULL, NULL, NULL} +}; + +int mediactl_set_str_func(const char* path, char* val) +{ + MediaCtlPool *p = Mediactl_SetPool; + int ret = UnSupport; + while (p && p->device) { + if (!strcmp(p->device, path)) { + if (p->mediactl_setstr) { + ret = p->mediactl_setstr(p->path,val); + } + break; + } + p++; + } + return ret; +} + +int mediactl_get_str_func(const char* path, char* valstr, int size) +{ + MediaCtlPool *p = Mediactl_SetPool; + int ret = UnSupport; + while (p && p->device) { + if (!strcmp(p->device, path)) { + if (p->mediactl_getstr) { + ret = p->mediactl_getstr(p->path,valstr,size); + } + break; + } + p++; + } + return ret; +} + +int mediactl_set_int_func(const char* path, int val) +{ + MediaCtlPool *p = Mediactl_SetPool; + int ret = UnSupport; + while (p && p->device) { + if (!strcmp(p->device, path)) { + if (p->mediactl_setval) { + ret = p->mediactl_setval(p->path,val); + } + break; + } + p++; + } + return ret; +} + +int mediactl_get_int_func(const char* path) +{ + MediaCtlPool *p = Mediactl_SetPool; + int ret = UnSupport; + while (p && p->device) { + if (!strcmp(p->device, path)) { + if (p->mediactl_getval) { + ret = p->mediactl_getval(p->path); + } + break; + } + p++; + } + return ret; +} + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/amavutils/mediactl/sub_ctl.cpp b/amavutils/mediactl/sub_ctl.cpp new file mode 100644 index 0000000..d0ce249 --- a/dev/null +++ b/amavutils/mediactl/sub_ctl.cpp @@ -0,0 +1,140 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <sub_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int media_get_subtitle_fps() +{ + return media_sub_getinfo(SUB_FPS); +} + +int media_set_subtitle_fps(int fps) +{ + return media_sub_setinfo(SUB_FPS, fps); +} + +int media_get_subtitle_total() +{ + return media_sub_getinfo(SUB_TOTAL); +} + +int media_set_subtitle_total(int total) +{ + return media_sub_setinfo(SUB_TOTAL, total); +} + +int media_get_subtitle_enable() +{ + return media_sub_getinfo(SUB_ENABLE); +} + +int media_set_subtitle_enable(int enable) +{ + return media_sub_setinfo(SUB_ENABLE, enable); +} + +int media_get_subtitle_index() +{ + return media_sub_getinfo(SUB_INDEX); +} + +int media_set_subtitle_index(int index) +{ + return media_sub_setinfo(SUB_INDEX, index); +} + +int media_get_subtitle_width() +{ + return media_sub_getinfo(SUB_WIDTH); +} + +int media_set_subtitle_width(int width) +{ + return media_sub_setinfo(SUB_WIDTH, width); +} + +int media_get_subtitle_height() +{ + return media_sub_getinfo(SUB_HEIGHT); +} + +int media_set_subtitle_height(int height) +{ + return media_sub_setinfo(SUB_HEIGHT, height); +} + +int media_get_subtitle_type() +{ + return media_sub_getinfo(SUB_TYPE); +} + +int media_set_subtitle_type(int type) +{ + return media_sub_setinfo(SUB_TYPE, type); +} + +int media_get_subtitle_subtype() +{ + return media_sub_getinfo(SUB_SUBTYPE); +} + +int media_set_subtitle_subtype(int type) +{ + return media_sub_setinfo(SUB_SUBTYPE, type); +} + +int media_get_subtitle_curr() +{ + return media_sub_getinfo(SUB_CURRENT); +} + +int media_set_subtitle_curr(int num) +{ + return media_sub_setinfo(SUB_CURRENT, num); +} + +int media_get_subtitle_startpts() +{ + return media_sub_getinfo(SUB_START_PTS); +} + +int media_set_subtitle_startpts(int startpts) +{ + return media_sub_setinfo(SUB_START_PTS, startpts); +} + +int media_get_subtitle_reset() +{ + return media_sub_getinfo(SUB_RESET); +} + +int media_set_subtitle_reset(int res) +{ + return media_sub_setinfo(SUB_RESET, res); +} + +int media_get_subtitle_size() +{ + return media_sub_getinfo(SUB_DATA_T_SIZE); +} + +int media_set_subtitle_size(int size) +{ + return media_sub_setinfo(SUB_DATA_T_SIZE, size); +} + +#ifdef __cplusplus +} +#endif diff --git a/amavutils/mediactl/tsync_ctl.cpp b/amavutils/mediactl/tsync_ctl.cpp new file mode 100644 index 0000000..1a06288 --- a/dev/null +++ b/amavutils/mediactl/tsync_ctl.cpp @@ -0,0 +1,235 @@ +#define LOG_TAG "tsync_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <tsync_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int media_set_tsync_enable(int enable) +{ + return media_sync_set_ctl("media.tsync.enable",enable); +} + +int media_get_tsync_enable() +{ + return media_sync_get_ctl("media.tsync.enable"); +} + +int media_set_tsync_discontinue(int discontinue) +{ + return media_sync_set_ctl("media.tsync.discontinue",discontinue); +} + +int media_get_pts_discontinue() +{ + return media_sync_get_ctl("media.tsync.discontinue"); +} + +int media_set_tsync_vpause_flag(int val) +{ + return media_sync_set_ctl("media.tsync.vpause_flag",val); +} + +int media_get_tsync_vpause_flag() +{ + return media_sync_get_ctl("media.tsync.vpause_flag"); +} + +int media_set_tsync_pts_video(int val) +{ + return media_sync_set_ctl("media.tsync.pts_video",val); +} + +int media_get_tsync_pts_video() +{ + return media_sync_get_ctl("media.tsync.pts_video"); +} + +int media_set_tsync_pts_audio(int val) +{ + return media_sync_set_ctl("media.tsync.pts_audio",val); +} + +int media_get_tsync_pts_audio() +{ + return media_sync_get_ctl("media.tsync.pts_audio"); +} + +int media_set_tsync_dobly_av_sync(int val) +{ + return media_sync_set_ctl("media.tsync.dobly_av_sync",val); +} + +int media_get_tsync_dobly_av_sync() +{ + return media_sync_get_ctl("media.tsync.dobly_av_sync"); +} + +int media_set_tsync_pts_pcrscr(int val) +{ + return media_sync_set_ctl("media.tsync.pts_pcrscr",val); +} + +int media_get_tsync_pts_pcrscr() +{ + return media_sync_get_ctl("media.tsync.pts_pcrscr"); +} + +int media_set_tsync_even_strt(char* buf) +{ + return media_sync_set_ctl_str("media.tsync.event",buf); +} + +int media_set_tsync_mode(int val) +{ + return media_sync_set_ctl("media.tsync.mode",val); +} + +int media_get_tsync_mode() +{ + return media_sync_get_ctl("media.tsync.mode"); +} + +int media_set_tsync_pcr_recover(int val) +{ + return media_sync_set_ctl("media.tsync.pcr_recover",val); +} + +int media_get_tsync_pcr_recover() +{ + return media_sync_get_ctl("media.tsync.pcr_recover"); +} + +int media_set_tsync_debug_pts_checkin(int val) +{ + return media_sync_set_ctl("media.tsync.debug_pts_checkin",val); +} + +int media_get_tsync_debug_pts_checkin() +{ + return media_sync_get_ctl("media.tsync.debug_pts_checkin"); +} + +int media_set_tsync_debug_pts_checkout(int val) +{ + return media_sync_set_ctl("media.tsync.debug_pts_checkout",val); +} + +int media_get_tsync_debug_pts_checkout() +{ + return media_sync_get_ctl("media.tsync.debug_pts_checkout"); +} + +int media_set_tsync_debug_video_pts(int val) +{ + return media_sync_set_ctl("media.tsync.debug_video_pts",val); +} + +int media_get_tsync_debug_video_pts() +{ + return media_sync_get_ctl("media.tsync.debug_video_pts"); +} + +int media_set_tsync_debug_audio_pts(int val) +{ + return media_sync_set_ctl("media.tsync.debug_audio_pts",val); +} + +int media_get_tsync_debug_audio_pts() +{ + return media_sync_get_ctl("media.tsync.debug_audio_pts"); +} + +int media_set_tsync_av_threshold_min(int val) +{ + return media_sync_set_ctl("media.tsync.av_threshold_min",val); +} + +int media_get_tsync_av_threshold_min() +{ + return media_sync_get_ctl("media.tsync.av_threshold_min"); +} + +int media_set_tsync_av_threshold_max(int val) +{ + return media_sync_set_ctl("media.tsync.av_threshold_max",val); +} + +int media_get_tsync_av_threshold_max() +{ + return media_sync_get_ctl("media.tsync.av_threshold_max"); +} + +int media_set_tsync_last_checkin_apts(int val) +{ + return media_sync_set_ctl("media.tsync.last_checkin_apts",val); +} + +int media_get_tsync_last_checkin_apts() +{ + return media_sync_get_ctl("media.tsync.last_checkin_apts"); +} + +int media_set_tsync_firstvpts(int val) +{ + return media_sync_set_ctl("media.tsync.firstvpts",val); +} + +int media_get_tsync_firstvpts() +{ + return media_sync_get_ctl("media.tsync.firstvpts"); +} + +int media_set_tsync_slowsync_enable(int val) +{ + return media_sync_set_ctl("media.tsync.slowsync_enable",val); +} + +int media_get_tsync_slowsync_enable() +{ + return media_sync_get_ctl("media.tsync.slowsync_enable"); +} + +int media_set_tsync_startsync_mode(int val) +{ + return media_sync_set_ctl("media.tsync.startsync_mode",val); +} + +int media_get_tsync_startsync_mode() +{ + return media_sync_get_ctl("media.tsync.startsync_mode"); +} + +int media_set_tsync_firstapts(int val) +{ + return media_sync_set_ctl("media.tsync.firstapts",val); +} + +int media_get_tsync_firstapts() +{ + return media_sync_get_ctl("media.tsync.firstapts"); +} + +int media_set_tsync_checkin_firstvpts(int val) +{ + return media_sync_set_ctl("media.tsync.checkin_firstvpts",val); +} + +int media_get_tsync_checkin_firstvpts() +{ + return media_sync_get_ctl("media.tsync.checkin_firstvpts"); +} + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/amavutils/mediactl/vfm_ctl.cpp b/amavutils/mediactl/vfm_ctl.cpp new file mode 100644 index 0000000..9264665 --- a/dev/null +++ b/amavutils/mediactl/vfm_ctl.cpp @@ -0,0 +1,40 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <video_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif +int media_set_vfm_map(const char* val) +{ + return media_set_vfm_map_str(val); +} +int media_get_vfm_map(char* val, int size) +{ + media_get_vfm_map_str(val,size); + return 0; +} + +int media_rm_vfm_map(const char* name, const char* val) +{ + return media_rm_vfm_map_str(name,val); +} + +int media_add_vfm_map(const char* name, const char* val) +{ + return media_add_vfm_map_str(name, val); +} + +#ifdef __cplusplus +} +#endif + diff --git a/amavutils/mediactl/video_ctl.cpp b/amavutils/mediactl/video_ctl.cpp new file mode 100644 index 0000000..d6d8a08 --- a/dev/null +++ b/amavutils/mediactl/video_ctl.cpp @@ -0,0 +1,363 @@ +#define LOG_TAG "media_ctl" +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <cutils/log.h> +#include <amports/amstream.h> +#include "common_ctl.h" +#include <video_ctl.h> + +#ifdef __cplusplus +extern "C" { +#endif +int media_get_disable_video() +{ + return media_video_get_int(AMSTREAM_IOC_GET_VIDEO_DISABLE); +} + +int media_set_disable_video(int disable) +{ + return media_video_set_int(AMSTREAM_IOC_SET_VIDEO_DISABLE, disable); +} + +int media_get_black_policy() +{ + return media_video_get_int(AMSTREAM_IOC_GET_BLACKOUT_POLICY); +} + +int media_set_black_policy(int val) +{ + return media_video_set_int(AMSTREAM_IOC_SET_BLACKOUT_POLICY, val); +} + +int media_get_screen_mode() +{ + return media_video_get_int(AMSTREAM_IOC_GET_SCREEN_MODE); +} + +int media_set_screen_mode(int mode) +{ + return media_video_set_int(AMSTREAM_IOC_SET_SCREEN_MODE, mode); +} + +int media_clear_video_buf(int val) +{ + return media_video_set_int(AMSTREAM_IOC_CLEAR_VBUF,val); +} + +int media_set_amports_debugflags(int flag) +{ + return media_set_ctl("media.amports.debugflags",flag); +} + +int media_get_amports_debugflags() +{ + return media_get_ctl("media.amports.debugflags"); +} + +int media_set_amports_def_4k_vstreambuf_sizeM(int size) +{ + return media_set_ctl("media.amports.def_4k_vstreambuf_sizeM",size); +} + +int media_get_amports_def_4k_vstreambuf_sizeM() +{ + return media_get_ctl("media.amports.def_4k_vstreambuf_sizeM"); +} + +int media_set_amports_def_vstreambuf_sizeM(int size) +{ + return media_set_ctl("media.amports.def_vstreambuf_sizeM",size); +} + +int media_get_amports_def_vstreambuf_sizeM() +{ + return media_get_ctl("media.damports.def_vstreambuf_sizeM"); +} + +int media_set_amports_slow_input(int flag) +{ + return media_set_ctl("media.amports.slow_input",flag); +} + +int media_get_amports_slow_input() +{ + return media_get_ctl("media.amports.slow_input"); +} +int media_set_video_pause_one_3d_fl_frame(int val) +{ + return media_video_set_ctl("media.video.pause_one_3d_fl_frame", val); +} + +int media_get_video_pause_one_3d_fl_frame() +{ + return media_video_get_ctl("media.video.pause_one_3d_fl_frame"); +} + +int media_set_video_debug_flag(int val) +{ + return media_video_set_ctl("media.video.debug_flag", val); +} + +int media_get_video_debug_flag() +{ + return media_video_get_ctl("media.video.debug_flag"); +} + +int media_set_video_force_3d_scaler(int val) +{ + return media_video_set_ctl("media.video.force_3d_scaler", val); +} + +int media_get_video_force_3d_scaler() +{ + return media_video_get_ctl("media.video.force_3d_scaler"); +} + +int media_set_vdieo_video_3d_format(int val) +{ + return media_video_set_ctl("media.video.video_3d_format", val); +} + +int media_get_video_video_3d_format() +{ + return media_video_get_ctl("media.video.video_3d_format"); +} + +int media_set_video_vsync_enter_line_max(int val) +{ + return media_video_set_ctl("media.video.vsync_enter_line_max", val); +} + +int media_get_video_vsync_enter_line_max() +{ + return media_video_get_ctl("media.video.vsync_enter_line_max"); +} + +int media_set_video_vsync_exit_line_max(int val) +{ + return media_sync_set_ctl("media.video.vsync_exit_line_max", val); +} + +int media_get_video_vsync_exit_line_max() +{ + return media_sync_get_ctl("media.video.vsync_exit_line_max"); +} + +int media_set_video_vsync_rdma_line_max(int val) +{ + return media_video_set_ctl("media.video.vsync_rdma_line_max", val); +} + +int media_get_video_vsync_rdma_line_max() +{ + return media_video_get_ctl("media.video.vsync_rdma_line_max"); +} + +int media_set_video_underflow(int val) +{ + return media_video_set_ctl("media.video.underflow", val); +} + +int media_get_video_underflow() +{ + return media_video_get_ctl("media.video.underflow"); +} + +int media_set_video_next_peek_underflow(int val) +{ + return media_video_set_ctl("media.video.next_peek_underflow", val); +} + +int media_get_video_next_peek_underflow() +{ + return media_video_get_ctl("media.video.next_peek_underflow"); +} + +int media_set_video_smooth_sync_enable(int val) +{ + return media_video_set_ctl("media.video.smooth_sync_enable", val); +} + +int media_get_video_smooth_sync_enable() +{ + return media_video_get_ctl("media.video.smooth_sync_enable"); +} + +int media_set_video_hdmi_in_onvideo(int val) +{ + return media_video_set_ctl("media.video.hdmi_in_onvideo", val); +} + +int media_get_video_hdmi_in_onvideo() +{ + return media_video_get_ctl("media.video.hdmi_in_onvideo"); +} + +int media_set_video_play_clone_rate(int val) +{ + return media_video_set_ctl("media.video.video_play_clone_rate", val); +} + +int media_get_video_play_clone_rate() +{ + return media_video_get_ctl("media.video.video_play_clone_rate"); +} + +int media_set_video_android_clone_rate(int val) +{ + return media_video_set_ctl("media.video.android_clone_rate", val); +} + +int media_get_video_android_clone_rate() +{ + return media_video_get_ctl("media.video.android_clone_rate"); +} + +int media_set_video_noneseamless_play_clone_rate(int val) +{ + return media_video_set_ctl("media.video.noneseamless_play_clone_rate", val); +} + +int media_get_video_noneseamless_play_clone_rate() +{ + return media_video_get_ctl("media.video.noneseamless_play_clone_rate"); +} + +int media_set_video_cur_dev_idx(int val) +{ + return media_video_set_ctl("media.video.cur_dev_idx", val); +} + +int media_get_video_cur_dev_idx() +{ + return media_video_get_ctl("media.video.cur_dev_idx"); +} + +int media_set_video_new_frame_count(int val) +{ + return media_video_set_ctl("media.video.new_frame_count", val); +} + +int media_get_video_new_frame_count() +{ + return media_video_get_ctl("media.video.new_frame_count"); +} + +int media_set_video_omx_pts(int val) +{ + return media_video_set_ctl("media.video.omx_pts", val); +} + +int media_get_video_omx_pts() +{ + return media_video_get_ctl("media.video.omx_pts"); +} + +int media_set_video_omx_pts_interval_upper(int val) +{ + return media_video_set_ctl("media.video.omx_pts_interval_upper", val); +} + +int media_get_video_omx_pts_interval_upper() +{ + return media_video_get_ctl("media.video.omx_pts_interval_upper"); +} + +int media_set_video_omx_pts_interval_lower(int val) +{ + return media_video_set_ctl("media.video.omx_pts_interval_lower", val); +} + +int media_get_video_omx_pts_interval_lower() +{ + return media_video_get_ctl("media.video.omx_pts_interval_lower"); +} + +int media_set_video_bypass_pps(int val) +{ + return media_video_set_ctl("media.video.bypass_pps", val); +} + +int media_get_video_bypass_pps() +{ + return media_video_get_ctl("media.video.bypass_pps"); +} + +int media_set_video_platform_type(int val) +{ + return media_video_set_ctl("media.video.platform_type", val); +} + +int media_get_video_platform_type() +{ + return media_video_get_ctl("media.video.platform_type"); +} + +int media_set_video_process_3d_type(int val) +{ + return media_video_set_ctl("media.video.process_3d_type", val); +} + +int media_get_video_process_3d_type() +{ + return media_video_get_ctl("media.video.process_3d_type"); +} + +int media_set_video_framepacking_support(int val) +{ + return media_video_set_ctl("media.video.framepacking_support", val); +} + +int media_get_video_framepacking_support() +{ + return media_video_get_ctl("media.video.framepacking_support"); +} + +int media_set_video_framepacking_width(int val) +{ + return media_video_set_ctl("media.video.framepacking_width", val); +} + +int media_get_video_framepacking_width() +{ + return media_video_get_ctl("media.video.framepacking_width"); +} + +int media_set_video_framepacking_height(int val) +{ + return media_video_set_ctl("media.video.framepacking_height", val); +} + +int media_get_video_framepacking_height() +{ + return media_video_get_ctl("media.video.framepacking_height"); +} + +int media_set_video_framepacking_blank(int val) +{ + return media_video_set_ctl("media.video.framepacking_blank", val); +} + +int media_get_video_framepacking_blank() +{ + return media_video_get_ctl("media.video.framepacking_blank"); +} + +int media_set_video_reverse(int val) +{ + return media_video_set_ctl("media.video.reverse", val); +} + +int media_get_video_reverse() +{ + return media_video_get_ctl("media.video.reverse"); +} + +#ifdef __cplusplus +} +#endif diff --git a/amavutils/tools/Android.mk b/amavutils/tools/Android.mk new file mode 100644 index 0000000..4f1e0e1 --- a/dev/null +++ b/amavutils/tools/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm +LOCAL_SRC_FILES := mediactl.cpp +LOCAL_SHARED_LIBRARIES := liblog libcutils libmedia.amlogic.hal +LOCAL_MODULE := mediactl +LOCAL_MODULE_TAGS := optional +include $(BUILD_EXECUTABLE) + diff --git a/amavutils/tools/mediactl.cpp b/amavutils/tools/mediactl.cpp new file mode 100644 index 0000000..bf71674 --- a/dev/null +++ b/amavutils/tools/mediactl.cpp @@ -0,0 +1,90 @@ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <errno.h> +#include <../mediaconfig/media_config.h> +#include <linux/ioctl.h> + +int print_usage(int argc, char **argv) +{ + printf("usage:\n"); + printf("\t%s -a # listall\n", argv[0]); + printf("\t%s -s media.xxxx 1 #set media.xxxx to 1 \n", argv[0]); + printf("\t%s media.xxx #get media.xxx setting\n", argv[0]); + exit(0); +} +int media_open(const char *path, int flags) +{ + int fd = 0; + fd = open(path, flags); + if (fd < 0) { + printf("open [%s] failed,ret = %d errno=%d\n", path, fd, errno); + return fd; + } + return fd; +} + +int media_close(int fd) +{ + int res = 0; + if (fd) { + res = close(fd); + } + return res; +} + +int main(int argc, char **argv) +{ + char *buf = (char *)malloc(128 * 1024); + if (argc <= 1) { + print_usage(argc, argv); + return 0; + } + if (!buf) { + printf("no mem....\n"); + return 0; + } + if (!strcmp(argv[1], "-a")) { + int i; + i = media_config_list(buf, 128 * 1024); + if (i > 0) { + puts(buf); + } else { + printf("dump failed.%s(%d)\n", strerror(-i), i); + } + return 0; + } else if (!strcmp(argv[1], "-s") && (argc == 3 || argc == 4)) { + int i = -1; + if (argc == 4) { + i = media_set_cmd_str(argv[2], argv[3]); + } else if (argc == 3 && strstr(argv[2], "=") != NULL) { + i = media_set_cmd_str(argv[2], strstr(argv[2], "=") + 1); + } else { + print_usage(argc, argv); + } + if (i < 0) { + printf("set config failed.%s(%d)\n", strerror(-i), i); + } else { + i = media_get_cmd_str(argv[2], buf, 128 * 1024); + if (i > 0) + printf("after set:[%s]=[%s]\n",argv[2],buf); + else + printf("set ok,bug getfailed.%s(%d)\n", strerror(i), i); + } + } else if (argc == 2) { + int i = media_get_cmd_str(argv[1], buf, 128 * 1024); + if (i > 0) { + printf("get: %s=%s\n", argv[1], buf); + } else { + printf("get config failed.%s(%d)\n", strerror(-i), i); + } + } else { + print_usage(argc, argv); + } + free(buf); + return 0; +} + diff --git a/amcodec/Android.mk b/amcodec/Android.mk new file mode 100644 index 0000000..f81faae --- a/dev/null +++ b/amcodec/Android.mk @@ -0,0 +1,56 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +AMADEC_PATH:=$(TOP)/hardware/amlogic/LibAudio/amadec/ + +LOCAL_SRC_FILES := \ + codec/codec_ctrl.c \ + codec/codec_h_ctrl.c \ + codec/codec_msg.c \ +# audio_ctl/audio_ctrl.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/codec \ + $(LOCAL_PATH)/../amavutils/include \ + $(AMADEC_PATH)/include \ + $(LOCAL_PATH)/audio_ctl + +LOCAL_ARM_MODE := arm +#LOCAL_STATIC_LIBRARIES := libamadec +LOCAL_MODULE:= libamcodec +include $(BUILD_STATIC_LIBRARY) + + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + codec/codec_ctrl.c \ + codec/codec_h_ctrl.c \ + codec/codec_msg.c \ +# audio_ctl/audio_ctrl.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/codec \ + $(LOCAL_PATH)/../amavutils/include \ + $(LOCAL_PATH)/audio_ctl \ + $(AMADEC_PATH)/include + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libmedia \ + libz \ + libbinder \ + libdl \ + libcutils \ + libc \ + liblog \ + libamavutils \ +# libamadec + +LOCAL_ARM_MODE := arm +LOCAL_MODULE:= libamcodec +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false +include $(BUILD_SHARED_LIBRARY) diff --git a/amcodec/audio_ctl/audio_ctrl.c b/amcodec/audio_ctl/audio_ctrl.c new file mode 100644 index 0000000..992d250 --- a/dev/null +++ b/amcodec/audio_ctl/audio_ctrl.c @@ -0,0 +1,431 @@ +/** +* @file audio_ctrl.c +* @brief codec control lib functions for audio +* @author Zhou Zhi <zhi.zhou@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <codec_error.h> +#include <codec.h> +#include "codec_h_ctrl.h" +#include "adec-external-ctrl.h" + +void audio_basic_init(void) +{ + audio_decode_basic_init(); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief audio_start Start audio decoder +*/ +/* --------------------------------------------------------------------------*/ +void audio_start(void **priv, arm_audio_info *a_ainfo) +{ + + audio_decode_init(priv, a_ainfo); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief audio_stop Stop audio decoder +*/ +/* --------------------------------------------------------------------------*/ +void audio_stop(void **priv) +{ + audio_decode_stop(*priv); + audio_decode_release(priv); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief audio_stop_async Stop audio decoder async without wait. +*/ +/* --------------------------------------------------------------------------*/ +void audio_stop_async(void **priv) +{ + audio_decode_stop(*priv); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief audio_pause Pause audio decoder +*/ +/* --------------------------------------------------------------------------*/ +void audio_pause(void *priv) +{ + audio_decode_pause(priv); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief audio_resume Resume audio decoder +*/ +/* --------------------------------------------------------------------------*/ +void audio_resume(void *priv) +{ + audio_decode_resume(priv); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_mutesta Get codec mute status +* +* @param[in] p Pointer of codec parameter structure +* +* @return audio command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_mutesta(codec_para_t *p) +{ + int ret; + ret = audio_output_muted(p->adec_priv); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_mute Set audio mute +* +* @param[in] p Pointer of codec parameter structure +* @param[in] mute mute command, 1 for mute, 0 for unmute +* +* @return audio command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_mute(codec_para_t *p, int mute) +{ + int ret; + + /* 1: mut output. 0: unmute output */ + ret = audio_decode_set_mute(p->adec_priv, mute); + + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_volume_range Get audio volume range +* +* @param[in] p Pointer of codec parameter structure +* @param[out] min Data to save the min volume +* @param[out] max Data to save the max volume +* +* @return not used, read failed +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_volume_range(codec_para_t *p, int *min, int *max) +{ + return -CODEC_ERROR_IO; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_volume Set audio volume +* +* @param[in] p Pointer of codec parameter structure +* @param[in] val Volume to be set +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_volume(codec_para_t *p, float val) +{ + int ret; + + ret = audio_decode_set_volume(p->adec_priv, val); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_volume Get audio volume +* +* @param[in] p Pointer of codec parameter structure +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_volume(codec_para_t *p, float *val) +{ + int ret; + ret = audio_decode_get_volume(p->adec_priv, val); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_pre_gain Set audio decoder pre-gain +* +* @param[in] p Pointer of codec parameter structure +* @param[in] gain gain to be set +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_pre_gain(codec_para_t *p, float gain) +{ + int ret; + + ret = audio_decode_set_pre_gain(p->adec_priv, gain); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_pre_gain Get audio decoder pre-gain +* +* @param[in] p Pointer of codec parameter structure +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_pre_gain(codec_para_t *p, float *gain) +{ + int ret; + ret = audio_decode_get_pre_gain(p->adec_priv, gain); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_pre_mute Set audio decoder pre-mute +* +* @param[in] p Pointer of codec parameter structure +* @param[in] gain gain to be set +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_pre_mute(codec_para_t *p, uint mute) +{ + int ret; + + ret = audio_decode_set_pre_mute(p->adec_priv, mute); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_pre_mute Get audio decoder pre-mute +* +* @param[in] p Pointer of codec parameter structure +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_pre_mute(codec_para_t *p, uint *mute) +{ + int ret; + ret = audio_decode_get_pre_mute(p->adec_priv, mute); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_volume Set audio volume seperately +* +* @param[in] p Pointer of codec parameter structure +* @param[in] lvol left Volume to be set +* @param[in] rvol right Volume to be set +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_lrvolume(codec_para_t *p, float lvol, float rvol) +{ + int ret; + + ret = audio_decode_set_lrvolume(p->adec_priv, lvol, rvol); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_volume Get audio left and right volume seperately +* +* @param[in] p Pointer of codec parameter structure +* +* @return command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_lrvolume(codec_para_t *p, float *lvol, float* rvol) +{ + int ret; + ret = audio_decode_get_lrvolume(p->adec_priv, lvol, rvol); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_volume_balance Set volume balance +* +* @param[in] p Pointer of codec parameter structure +* @param[in] balance Balance to be set +* +* @return not used, return failed +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_volume_balance(codec_para_t *p, int balance) +{ + return -CODEC_ERROR_IO; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_swap_left_right Swap audio left and right channel +* +* @param[in] p Pointer of codec parameter structure +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_swap_left_right(codec_para_t *p) +{ + int ret; + ret = audio_channels_swap(p->adec_priv); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_left_mono Set mono with left channel +* +* @param[in] p Pointer of codec parameter structure +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_left_mono(codec_para_t *p) +{ + int ret; + ret = audio_channel_left_mono(p->adec_priv); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_right_mono Set mono with right channel +* +* @param[in] p Pointer of codec parameter structure +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_right_mono(codec_para_t *p) +{ + int ret; + ret = audio_channel_right_mono(p->adec_priv); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_stereo Set stereo +* +* @param[in] p Pointer of codec parameter structure +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_stereo(codec_para_t *p) +{ + int ret; + ret = audio_channel_stereo(p->adec_priv); + return ret; +} + +/* @brief codec_lr_mix +* @param[in] p Pointer of codec parameter structure +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_lr_mix_set(codec_para_t *p, int enable) +{ + int ret; + ret = audio_channel_lrmix_flag_set(p->adec_priv, enable); + return ret; +} + +int codec_pcmpara_Applied_get(codec_para_t *p, int *pfs, int *pch,int *lfepresent) +{ + int ret; + ret = audio_decpara_get(p->adec_priv, pfs, pch,lfepresent); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_automute Set decoder to automute mode +* +* @param[in] auto_mute automute mode +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_audio_automute(void *priv, int auto_mute) +{ + int ret; + //char buf[16]; + //sprintf(buf,"automute:%d",auto_mute); + //ret=amadec_cmd(buf); + ret = audio_decode_automute(priv, auto_mute); + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_spectrum_switch Switch audio spectrum +* +* @param[in] p Pointer of codec parameter structure +* @param[in] isStart Start(1) or stop(0) spectrum +* @param[in] interval Spectrum interval +* +* @return Command result +*/ +/* --------------------------------------------------------------------------*/ +int codec_audio_spectrum_switch(codec_para_t *p, int isStart, int interval) +{ + int ret = -1; + char cmd[32]; + + if (isStart == 1) { + snprintf(cmd, 32, "spectrumon:%d", interval); + //ret=amadec_cmd(cmd); + } else if (isStart == 0) { + //ret=amadec_cmd("spectrumoff"); + } + + return ret; +} +int codec_get_soundtrack(codec_para_t *p, int* strack) +{ + return audio_get_soundtrack(p->adec_priv, strack); + +} + +int audio_set_avsync_threshold(void *priv, int threshold) +{ + return audio_set_av_sync_threshold(priv, threshold); +} +int codec_get_decoder_enable(codec_para_t *p) +{ + return audio_decoder_get_enable_status(p->adec_priv); +} +int codec_set_track_rate(codec_para_t *p,void *rate) +{ + return audio_decoder_set_trackrate(p->adec_priv,rate); +} + diff --git a/amcodec/audio_ctl/audio_ctrl.h b/amcodec/audio_ctl/audio_ctrl.h new file mode 100644 index 0000000..9d2cf9d --- a/dev/null +++ b/amcodec/audio_ctl/audio_ctrl.h @@ -0,0 +1,29 @@ +/** +* @file audio_ctrl.h +* @brief Function prototypes of audio control lib +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#ifndef AUDIO_CTRL_H +#define AUDIO_CTRL_H +void audio_start(void **priv, codec_para_t *pcodec); +void audio_stop(void **priv); +void audio_stop_async(void **priv); +void audio_pause(void *priv); +void audio_resume(void *priv); +void audio_basic_init(void); +int codec_set_track_rate(codec_para_t *p,void *rate); +int codec_get_decoder_enable(codec_para_t *p); +int codec_get_pre_mute(codec_para_t *p, uint *mute); +int codec_set_pre_mute(codec_para_t *p, uint mute); +int codec_get_pre_gain(codec_para_t *p, float *gain); +int codec_set_pre_gain(codec_para_t *p, float gain); +int audio_set_avsync_threshold(void *priv, int threshold); +#endif + diff --git a/amcodec/codec/Makefile b/amcodec/codec/Makefile new file mode 100644 index 0000000..1c55c7d --- a/dev/null +++ b/amcodec/codec/Makefile @@ -0,0 +1,5 @@ + +obj-y += codec_ctrl.o \ + codec_h_ctrl.o \ + codec_msg.o + diff --git a/amcodec/codec/codec_ctrl.c b/amcodec/codec/codec_ctrl.c new file mode 100644 index 0000000..872ba4e --- a/dev/null +++ b/amcodec/codec/codec_ctrl.c @@ -0,0 +1,2516 @@ +/** +* @file codec_ctrl.c +* @brief Codec control lib functions +* @author Zhou Zhi <zhi.zhou@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#include <stdio.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/poll.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <codec_error.h> +#include <codec_type.h> +#include <codec.h> +#include <audio_priv.h> +#include "codec_h_ctrl.h" +#include <adec-external-ctrl.h> +#include <Amvideoutils.h> +#include "codec_msg.h" +#include "../audio_ctl/audio_ctrl.h" +#include "amconfigutils.h" + +#define SUBTITLE_EVENT +#define TS_PACKET_SIZE 188 +#define DEMUX_PLAYER_SOURCE 1 + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_eos set eos flag +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] source set 1 for eos flag +* +* @return 0 for success, or fail type if < 0 +*/ + +int codec_set_eos(codec_para_t *pcodec, int is_eos) { + int r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_EOS, is_eos); + //if (r < 0) { + // return system_error_to_codec_error(r); + //} + CODEC_PRINT("codec_set_eos is_eos =%d\n", is_eos); + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_demux_source set ts demux source +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] source set 1 for player +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +static int codec_set_demux_source(codec_para_t *pcodec, int source) +{ + int ret = 0; + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_DEMUX, (unsigned long)source); + if (ret < 0) { + return ret; + } + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_change_buf_size Change buffer size of codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success of fail error type +*/ +/* --------------------------------------------------------------------------*/ +static int codec_change_buf_size(codec_para_t *pcodec) +{ + int r; + if (pcodec->abuf_size > 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_AB_SIZE, pcodec->abuf_size); + if (r < 0) { + return system_error_to_codec_error(r); + } + } + if (pcodec->vbuf_size > 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_VB_SIZE, pcodec->vbuf_size); + if (r < 0) { + return system_error_to_codec_error(r); + } + } + return CODEC_ERROR_NONE; +} +/* --------------------------------------------------------------------------*/ +/** +* @brief set_video_format Set video format to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_video_format(codec_para_t *pcodec) +{ + int format = pcodec->video_type; + int r; + + if (format < 0 || format > VFORMAT_MAX) { + return -CODEC_ERROR_VIDEO_TYPE_UNKNOW; + } + + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_VFORMAT, format); + if (pcodec->video_pid >= 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_VID, pcodec->video_pid); + if (r < 0) { + return system_error_to_codec_error(r); + } + } + if (r < 0) { + return system_error_to_codec_error(r); + } + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief set_video_codec_info Set video information(width, height...) to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_video_codec_info(codec_para_t *pcodec) +{ + dec_sysinfo_t am_sysinfo = pcodec->am_sysinfo; + int r; + r = codec_h_control(pcodec->handle, AMSTREAM_IOC_SYSINFO, (unsigned long)&am_sysinfo); + if (r < 0) { + return system_error_to_codec_error(r); + } + return 0; +} +/* --------------------------------------------------------------------------*/ +/** +* @brief set_audio_format Set audio format to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_audio_format(codec_para_t *pcodec) +{ + int format = pcodec->audio_type; + int r; + int codec_r; + + if (format < 0 || format > AFORMAT_MAX) { + return -CODEC_ERROR_AUDIO_TYPE_UNKNOW; + } + + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_AFORMAT, format); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + if (pcodec->audio_pid >= 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_AID, pcodec->audio_pid); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + } + if (pcodec->audio_samplerate > 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_SAMPLERATE, pcodec->audio_samplerate); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + } + if (pcodec->audio_channels > 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_ACHANNEL, pcodec->audio_channels); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + } + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief set_audio_info Set audio information to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_audio_info(codec_para_t *pcodec) +{ + int r; + int codec_r; + audio_info_t *audio_info = &pcodec->audio_info; + CODEC_PRINT("set_audio_info\n"); + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET_PTR, AMSTREAM_SET_PTR_AUDIO_INFO, (unsigned long)audio_info); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief set_sub_format Set subtitle format to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_sub_format(codec_para_t *pcodec) +{ + int r; + + if (pcodec->sub_pid >= 0) { + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_SID, pcodec->sub_pid); + if (r < 0) { + return system_error_to_codec_error(r); + } + + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_SUB_TYPE, pcodec->sub_type); + if (r < 0) { + return system_error_to_codec_error(r); + } + } + + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief set_ts_skip_byte Set the number of ts skip bytes, especially for m2ts file +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or error type +*/ +/* --------------------------------------------------------------------------*/ +static int set_ts_skip_byte(codec_para_t *pcodec) +{ + int r, skip_byte; + + skip_byte = pcodec->packet_size - TS_PACKET_SIZE; + + if (skip_byte < 0) { + skip_byte = 0; + } + + r = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_TS_SKIPBYTE, skip_byte); + if (r < 0) { + return system_error_to_codec_error(r); + } + + return 0; +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_check_new_cmd Check new cmd for ioctl +* +*/ +/* --------------------------------------------------------------------------*/ +static inline void codec_check_new_cmd(CODEC_HANDLE handle) +{ + if (!codec_h_is_support_new_cmd()) { + int r; + int version = 0; + r = codec_h_control(handle, AMSTREAM_IOC_GET_VERSION, (unsigned long)&version); + if ((r == 0) && (version >= 0x20000)) { + CODEC_PRINT("codec_init amstream version : %d.%d\n", (version & 0xffff0000) >> 16, version & 0xffff); + codec_h_set_support_new_cmd(1); + } else { + CODEC_PRINT("codec_init amstream use old cmd\n"); + codec_h_set_support_new_cmd(0); + } + + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_video_es_init Initialize the codec device for es video +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_video_es_init(codec_para_t *pcodec) +{ + CODEC_HANDLE handle; + int r; + int codec_r; + int flags = O_WRONLY; + if (!pcodec->has_video) { + return CODEC_ERROR_NONE; + } + + flags |= pcodec->noblock ? O_NONBLOCK : 0; + + if (pcodec->video_type == VFORMAT_HEVC || pcodec->video_type == VFORMAT_VP9) { + if (pcodec->dv_enable && pcodec->video_type == VFORMAT_HEVC) + handle = codec_h_open(CODEC_VIDEO_DVHEVC_DEVICE, flags); + else + handle = codec_h_open(CODEC_VIDEO_HEVC_DEVICE, flags); + } else { + if (pcodec->video_type == VFORMAT_H264 && pcodec->dv_enable) + handle = codec_h_open(CODEC_VIDEO_DVAVC_DEVICE, flags); + else + handle = codec_h_open(CODEC_VIDEO_ES_DEVICE, flags); + } + if (handle < 0) { + codec_r = system_error_to_codec_error(handle); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + pcodec->handle = handle; + + codec_check_new_cmd(handle); + + r = set_video_format(pcodec); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + r = set_video_codec_info(pcodec); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + r = codec_set_drmmode(pcodec, pcodec->drmmode); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + return CODEC_ERROR_NONE; +} + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_es_init Initialize the codec device for es audio +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_audio_es_init(codec_para_t *pcodec) +{ + CODEC_HANDLE handle; + int r; + int flags = O_WRONLY; + int codec_r; + if (!pcodec->has_audio) { + return CODEC_ERROR_NONE; + } + + flags |= pcodec->noblock ? O_NONBLOCK : 0; + handle = codec_h_open(CODEC_AUDIO_ES_DEVICE, flags); + if (handle < 0) { + codec_r = system_error_to_codec_error(handle); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + pcodec->handle = handle; + + codec_check_new_cmd(handle); + + r = set_audio_format(pcodec); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + + /*if ((pcodec->audio_type == AFORMAT_ADPCM) || (pcodec->audio_type == AFORMAT_WMAPRO) || (pcodec->audio_type == AFORMAT_WMA) || (pcodec->audio_type == AFORMAT_PCM_S16BE) + || (pcodec->audio_type == AFORMAT_PCM_S16LE) || (pcodec->audio_type == AFORMAT_PCM_U8)||(pcodec->audio_type == AFORMAT_AMR)) {*/ + if (IS_AUIDO_NEED_EXT_INFO(pcodec->audio_type)) { + r = set_audio_info(pcodec); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + } + + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_sub_es_init Initialize the codec device for es subtitle +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_sub_es_init(codec_para_t *pcodec) +{ +#ifdef SUBTITLE_EVENT + int r, codec_r; + + if (pcodec->has_sub) { + r = codec_init_sub(pcodec); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + pcodec->handle = pcodec->sub_handle; + + pcodec->sub_pid = 0xffff; // for es, sub id is identified for es parser + r = set_sub_format(pcodec); + if (r < 0) { + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + + } + +#endif + + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_ps_init Initialize the codec device for PS +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_ps_init(codec_para_t *pcodec) +{ + CODEC_HANDLE handle; + int r; + int flags = O_WRONLY; + int codec_r; + if (!((pcodec->has_video && IS_VALID_PID(pcodec->video_pid)) || + (pcodec->has_audio && IS_VALID_PID(pcodec->audio_pid)))) { + return -CODEC_ERROR_PARAMETER; + } + + flags |= pcodec->noblock ? O_NONBLOCK : 0; + handle = codec_h_open(CODEC_PS_DEVICE, flags); + if (handle < 0) { + codec_r = system_error_to_codec_error(handle); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + pcodec->handle = handle; + + codec_check_new_cmd(handle); + + if (pcodec->has_video) { + r = set_video_format(pcodec); + if (r < 0) { + goto error1; + } + if ((pcodec->video_type == VFORMAT_H264) + || (pcodec->video_type == VFORMAT_VC1) + || (pcodec->video_type == VFORMAT_MPEG12)) { + r = set_video_codec_info(pcodec); + if (r < 0) { + /*codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; */ + goto error1; + } + } + } + if (pcodec->has_audio) { + r = set_audio_format(pcodec); + if (r < 0) { + goto error1; + } + + /*if ((pcodec->audio_type == AFORMAT_ADPCM) || (pcodec->audio_type == AFORMAT_WMA) || (pcodec->audio_type == AFORMAT_WMAPRO) || (pcodec->audio_type == AFORMAT_PCM_S16BE) + || (pcodec->audio_type == AFORMAT_PCM_S16LE) || (pcodec->audio_type == AFORMAT_PCM_U8) + || (pcodec->audio_type == AFORMAT_PCM_BLURAY)||(pcodec->audio_type == AFORMAT_AMR)) {*/ + if (IS_AUIDO_NEED_EXT_INFO(pcodec->audio_type)) { + r = set_audio_info(pcodec); + if (r < 0) { + goto error1; + } + } + } +#ifdef SUBTITLE_EVENT + if (pcodec->has_sub) { + r = set_sub_format(pcodec); + if (r < 0) { + goto error1; + } + + r = codec_init_sub(pcodec); + if (r < 0) { + goto error1; + } + } +#endif + + return CODEC_ERROR_NONE; +error1: + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + +} + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_ts_init Initialize the codec device for TS +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_ts_init(codec_para_t *pcodec) +{ + CODEC_HANDLE handle; + int r; + int flags = O_WRONLY; + int codec_r; + if (!((pcodec->has_video && IS_VALID_PID(pcodec->video_pid)) || + (pcodec->has_audio && IS_VALID_PID(pcodec->audio_pid)))) { + return -CODEC_ERROR_PARAMETER; + } + + flags |= pcodec->noblock ? O_NONBLOCK : 0; + handle = codec_h_open(CODEC_TS_DEVICE, flags); + if (handle < 0) { + codec_r = system_error_to_codec_error(handle); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + pcodec->handle = handle; + + codec_check_new_cmd(handle); + + codec_set_demux_source(pcodec, DEMUX_PLAYER_SOURCE); + if (pcodec->has_video) { + r = set_video_format(pcodec); + if (r < 0) { + goto error1; + } + if ((pcodec->video_type == VFORMAT_H264) || (pcodec->video_type == VFORMAT_MPEG4) || (pcodec->video_type == VFORMAT_VC1) || (pcodec->video_type == VFORMAT_AVS) || (pcodec->video_type == VFORMAT_MPEG12)) { + r = set_video_codec_info(pcodec); + if (r < 0) { + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + } + } + } + if (pcodec->has_audio) { + r = set_audio_format(pcodec); + if (r < 0) { + goto error1; + } + + /*if ((pcodec->audio_type == AFORMAT_ADPCM) || (pcodec->audio_type == AFORMAT_WMA) || (pcodec->audio_type == AFORMAT_WMAPRO) || (pcodec->audio_type == AFORMAT_PCM_S16BE) + || (pcodec->audio_type == AFORMAT_PCM_S16LE) || (pcodec->audio_type == AFORMAT_PCM_U8) + || (pcodec->audio_type == AFORMAT_PCM_BLURAY)||(pcodec->audio_type == AFORMAT_AMR))*/ + if (pcodec->audio_info.valid) { + r = set_audio_info(pcodec); + if (r < 0) { + goto error1; + } + } + } + + r = set_ts_skip_byte(pcodec); + if (r < 0) { + goto error1; + } + +#ifdef SUBTITLE_EVENT + if (pcodec->has_sub) { + r = set_sub_format(pcodec); + if (r < 0) { + goto error1; + } + + r = codec_init_sub(pcodec); + if (r < 0) { + goto error1; + } + } +#endif + return CODEC_ERROR_NONE; +error1: + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; + +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_rm_init Initialize the codec device for RM +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +static inline int codec_rm_init(codec_para_t *pcodec) +{ + CODEC_HANDLE handle; + int r; + int flags = O_WRONLY; + int codec_r; + if (!((pcodec->has_video && IS_VALID_PID(pcodec->video_pid)) || + (pcodec->has_audio && IS_VALID_PID(pcodec->audio_pid)))) { + CODEC_PRINT("codec_rm_init failed! video=%d vpid=%d audio=%d apid=%d\n", pcodec->has_video, pcodec->video_pid, pcodec->has_audio, pcodec->audio_pid); + return -CODEC_ERROR_PARAMETER; + } + flags |= pcodec->noblock ? O_NONBLOCK : 0; + handle = codec_h_open(CODEC_RM_DEVICE, flags); + if (handle < 0) { + codec_r = system_error_to_codec_error(handle); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return CODEC_OPEN_HANDLE_FAILED; + } + + pcodec->handle = handle; + + codec_check_new_cmd(handle); + + if (pcodec->has_video) { + r = set_video_format(pcodec); + if (r < 0) { + goto error1; + } + + r = set_video_codec_info(pcodec); + if (r < 0) { + goto error1; + } + } + if (pcodec->has_audio) { + r = set_audio_format(pcodec); + if (r < 0) { + goto error1; + } + r = set_audio_info(pcodec); + if (r < 0) { + goto error1; + } + } + return CODEC_ERROR_NONE; + +error1: + codec_h_close(handle); + codec_r = system_error_to_codec_error(r); + print_error_msg(codec_r, errno, __FUNCTION__, __LINE__); + return codec_r; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_init Initialize the codec device based on stream type +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_init(codec_para_t *pcodec) +{ + int ret; + //if(pcodec->has_audio) + // audio_stop(); + pcodec->handle = -1; + pcodec->cntl_handle = -1; + pcodec->sub_handle = -1; + pcodec->audio_utils_handle = -1; + if (pcodec->audio_type == AFORMAT_MPEG1 || pcodec->audio_type == AFORMAT_MPEG2) { + pcodec->audio_type = AFORMAT_MPEG; + } + switch (pcodec->stream_type) { + case STREAM_TYPE_ES_VIDEO: + ret = codec_video_es_init(pcodec); + break; + case STREAM_TYPE_ES_AUDIO: + ret = codec_audio_es_init(pcodec); + break; + case STREAM_TYPE_ES_SUB: + ret = codec_sub_es_init(pcodec); + break; + case STREAM_TYPE_PS: + ret = codec_ps_init(pcodec); + break; + case STREAM_TYPE_TS: + ret = codec_ts_init(pcodec); + break; + case STREAM_TYPE_RM: + ret = codec_rm_init(pcodec); + break; + case STREAM_TYPE_UNKNOW: + default: + return -CODEC_ERROR_STREAM_TYPE_UNKNOW; + } + if (ret != 0) { + return ret; + } + + ret = codec_init_cntl(pcodec); + if (ret != CODEC_ERROR_NONE) { + return ret; + } + ret = codec_change_buf_size(pcodec); + if (ret != 0) { + return -CODEC_ERROR_SET_BUFSIZE_FAILED; + } + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_PORT_INIT, 0); + if (ret != 0) { + + return -CODEC_ERROR_INIT_FAILED; + } + if (pcodec->has_audio) { + arm_audio_info a_ainfo; + memset(&a_ainfo, 0, sizeof(arm_audio_info)); + a_ainfo.channels = pcodec->audio_channels; + a_ainfo.sample_rate = pcodec->audio_samplerate; + a_ainfo.format = pcodec->audio_type; + a_ainfo.handle = pcodec->handle; + a_ainfo.SessionID = pcodec->SessionID; + a_ainfo.dspdec_not_supported = pcodec->dspdec_not_supported; + a_ainfo.droppcm_flag = 0; + a_ainfo.bitrate = pcodec->audio_info.bitrate; + a_ainfo.block_align = pcodec->audio_info.block_align; + a_ainfo.codec_id = pcodec->audio_info.codec_id; + a_ainfo.automute = pcodec->automute_flag; + a_ainfo.has_video = pcodec->has_video; + if (IS_AUIDO_NEED_EXT_INFO(pcodec->audio_type)) { + if (pcodec->audio_type != AFORMAT_WMA && pcodec->audio_type != AFORMAT_WMAPRO && pcodec->audio_type != AFORMAT_WMAVOI) { + a_ainfo.extradata_size = pcodec->audio_info.extradata_size; + if (a_ainfo.extradata_size > 0 && a_ainfo.extradata_size <= AUDIO_EXTRA_DATA_SIZE) { + memcpy((char*)a_ainfo.extradata, pcodec->audio_info.extradata, a_ainfo.extradata_size); + } else { + a_ainfo.extradata_size = 0; + } + } else { + Asf_audio_info_t asfinfo = {0}; + asfinfo.bitrate = pcodec->audio_info.bitrate; + asfinfo.block_align = pcodec->audio_info.block_align; + asfinfo.channels = pcodec->audio_info.channels; + asfinfo.codec_id = pcodec->audio_info.codec_id; + asfinfo.sample_rate = pcodec->audio_info.sample_rate; + asfinfo.valid = pcodec->audio_info.valid; + if (pcodec->audio_info.extradata_size <= 512) { + memcpy(asfinfo.extradata, pcodec->audio_info.extradata, pcodec->audio_info.extradata_size); + asfinfo.extradata_size = pcodec->audio_info.extradata_size; + } + memcpy((char*)a_ainfo.extradata, &asfinfo, sizeof(Asf_audio_info_t)); + a_ainfo.extradata_size = sizeof(Asf_audio_info_t); + } + } + //DEBUG_TMP audio_start(&pcodec->adec_priv, &a_ainfo); + if (pcodec->avsync_threshold > 0) { + //DEBUG_TMP audio_set_avsync_threshold(pcodec->adec_priv, pcodec->avsync_threshold); + } + } + + return ret; +} + +void codec_audio_basic_init(void) +{ + //DEBUG_TMP audio_basic_init(); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_write Write data to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] buffer Buffer for data to be written +* @param[in] len Length of the data to be written +* +* @return Length of the written data, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_write(codec_para_t *pcodec, void *buffer, int len) +{ + return codec_h_write(pcodec->handle, buffer, len); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_read Read data from codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[out] buffer Buffer for data read from codec device +* @param[in] len Length of the data to be read +* +* @return Length of the read data, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_read(codec_para_t *pcodec, void *buffer, int len) +{ + return codec_h_read(pcodec->handle, buffer, len); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close Close codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_close(codec_para_t *pcodec) +{ + int res = 0; + if (pcodec->has_audio) { + //DEBUG_TMP audio_stop(&pcodec->adec_priv); + CODEC_PRINT("[%s]audio stop OK!\n", __FUNCTION__); + } +#ifdef SUBTITLE_EVENT + if (pcodec->has_sub && pcodec->sub_handle >= 0) { + res |= codec_close_sub_fd(pcodec->sub_handle); + } +#endif + + res |= codec_close_cntl(pcodec); + res |= codec_h_close(pcodec->handle); + return res; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close_audio Close audio decoder +* +* @param[in] pcodec Pointer of codec parameter structure +*/ +/* --------------------------------------------------------------------------*/ +void codec_close_audio(codec_para_t *pcodec) +{ + if (pcodec) { + pcodec->has_audio = 0; + //DEBUG_TMP audio_stop(&pcodec->adec_priv); + } + return; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close_audio Close audio decoder +* +* @param[in] pcodec Pointer of codec parameter structure +*/ +/* --------------------------------------------------------------------------*/ +void codec_close_audio_async(codec_para_t *pcodec) +{ + if (pcodec) { + //DEBUG_TMP audio_stop_async(&pcodec->adec_priv); + } + return; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_resume_audio Resume audio decoder to work (etc, after pause) +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] orig Original audio status (has audio or not) +*/ +/* --------------------------------------------------------------------------*/ +void codec_resume_audio(codec_para_t *pcodec, unsigned int orig) +{ + pcodec->has_audio = orig; + if (pcodec->has_audio) { + arm_audio_info a_ainfo; + memset(&a_ainfo, 0, sizeof(arm_audio_info)); + a_ainfo.channels = pcodec->audio_channels; + a_ainfo.sample_rate = pcodec->audio_samplerate; + a_ainfo.format = pcodec->audio_type; + a_ainfo.handle = pcodec->handle; + a_ainfo.dspdec_not_supported = pcodec->dspdec_not_supported; + a_ainfo.bitrate = pcodec->audio_info.bitrate; + a_ainfo.block_align = pcodec->audio_info.block_align; + a_ainfo.codec_id = pcodec->audio_info.codec_id; + a_ainfo.automute = pcodec->automute_flag; + a_ainfo.has_video = pcodec->has_video; + if (pcodec->switch_audio_flag) { + a_ainfo.droppcm_flag = pcodec->switch_audio_flag; + if (pcodec->stream_type == STREAM_TYPE_TS || pcodec->stream_type == STREAM_TYPE_PS) { + a_ainfo.droppcm_flag = 0; + } + pcodec->switch_audio_flag = 0; + } + if (IS_AUIDO_NEED_EXT_INFO(pcodec->audio_type)) { + if (pcodec->audio_type != AFORMAT_WMA && pcodec->audio_type != AFORMAT_WMAPRO && pcodec->audio_type != AFORMAT_WMAVOI) { + a_ainfo.extradata_size = pcodec->audio_info.extradata_size; + if (a_ainfo.extradata_size > 0 && a_ainfo.extradata_size <= AUDIO_EXTRA_DATA_SIZE) { + memcpy((char*)a_ainfo.extradata, pcodec->audio_info.extradata, a_ainfo.extradata_size); + } else { + a_ainfo.extradata_size = 0; + } + } else { + Asf_audio_info_t asfinfo = {0}; + asfinfo.bitrate = pcodec->audio_info.bitrate; + asfinfo.block_align = pcodec->audio_info.block_align; + asfinfo.channels = pcodec->audio_info.channels; + asfinfo.codec_id = pcodec->audio_info.codec_id; + asfinfo.sample_rate = pcodec->audio_info.sample_rate; + asfinfo.valid = pcodec->audio_info.valid; + if (pcodec->audio_info.extradata_size <= 512) { + memcpy(asfinfo.extradata, pcodec->audio_info.extradata, pcodec->audio_info.extradata_size); + asfinfo.extradata_size = pcodec->audio_info.extradata_size; + } + memcpy((char*)a_ainfo.extradata, &asfinfo, sizeof(Asf_audio_info_t)); + a_ainfo.extradata_size = sizeof(Asf_audio_info_t); + } + } + //DEBUG_TMP audio_start(&pcodec->adec_priv, &a_ainfo); + } + return; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_checkin_pts Checkin pts to codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] pts Pts to be checked in +* +* @return 0 for success, or fail type +*/ +/* --------------------------------------------------------------------------*/ +int codec_checkin_pts(codec_para_t *pcodec, unsigned long pts) +{ + //CODEC_PRINT("[%s:%d]pts=%x(%d)\n",__FUNCTION__,__LINE__,pts,pts/90000); + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_TSTAMP, pts); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_vbuf_state Get the state of video buffer by codec device +* +* @param[in] p Pointer of codec parameter structure +* @param[out] buf Pointer of buffer status structure to get video buffer state +* +* @return Success or fail type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_vbuf_state(codec_para_t *p, struct buf_status *buf) +{ + int r; + if (codec_h_is_support_new_cmd()) { + struct buf_status status; + r = codec_h_ioctl(p->handle, AMSTREAM_IOC_GET_EX, AMSTREAM_GET_EX_VB_STATUS, (unsigned long)&status); + memcpy(buf, &status, sizeof(*buf)); + } else { + struct am_io_param am_io; + r = codec_h_control(p->handle, AMSTREAM_IOC_VB_STATUS, (unsigned long)&am_io); + memcpy(buf, &am_io.status, sizeof(*buf)); + } + return system_error_to_codec_error(r); +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_abuf_state Get the state of audio buffer by codec device +* +* @param[in] p Pointer of codec parameter structure +* @param[out] buf Pointer of buffer status structure to get audio buffer state +* +* @return Success or fail type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_abuf_state(codec_para_t *p, struct buf_status *buf) +{ + int r; + if (codec_h_is_support_new_cmd()) { + struct buf_status status; + r = codec_h_ioctl(p->handle, AMSTREAM_IOC_GET_EX, AMSTREAM_GET_EX_AB_STATUS, (unsigned long)&status); + memcpy(buf, &status, sizeof(*buf)); + } else { + struct am_io_param am_io; + r = codec_h_control(p->handle, AMSTREAM_IOC_AB_STATUS, (unsigned long)&am_io); + memcpy(buf, &am_io.status, sizeof(*buf)); + } + return system_error_to_codec_error(r); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_vdec_state Get the state of video decoder by codec device +* +* @param[in] p Pointer of codec parameter structure +* @param[out] vdec Pointer of video decoder status structure +* +* @return Success or fail type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_vdec_state(codec_para_t *p, struct vdec_status *vdec) +{ + int r; + if (codec_h_is_support_new_cmd()) { + struct vdec_status vstatus; + r = codec_h_ioctl(p->handle, AMSTREAM_IOC_GET_EX, AMSTREAM_GET_EX_VDECSTAT, (unsigned long)&vstatus); + memcpy(vdec, &vstatus, sizeof(*vdec)); + } else { + struct am_io_param am_io; + r = codec_h_control(p->handle, AMSTREAM_IOC_VDECSTAT, (unsigned long)&am_io); + memcpy(vdec, &am_io.vstatus, sizeof(*vdec)); + } + if (r < 0) { + CODEC_PRINT("[codec_get_vdec_state]error[%d]: %s\n", r, codec_error_msg(system_error_to_codec_error(r))); + } + return system_error_to_codec_error(r); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_adec_state Get the state of audio decoder by codec device +* +* @param[in] p Pointer of codec parameter structure +* @param[out] adec Pointer of audio decoder status structure +* +* @return Success or fail type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_adec_state(codec_para_t *p, struct adec_status *adec) +{ + //DEBUG_TMP if (get_audio_decoder() == AUDIO_ARM_DECODER) { + //DEBUG_TMP return get_decoder_status(p->adec_priv, adec); + //DEBUG_TMP } + int r; + if (codec_h_is_support_new_cmd()) { + struct adec_status astatus; + r = codec_h_ioctl(p->handle, AMSTREAM_IOC_GET_EX, AMSTREAM_GET_EX_ADECSTAT, (unsigned long)&astatus); + if (r == 0) { + memcpy(adec, &astatus, sizeof(*adec)); + } + } else { + struct am_io_param am_io; + r = codec_h_control(p->handle, AMSTREAM_IOC_ADECSTAT, (unsigned long)&am_io); + if (r == 0) { + memcpy(adec, &am_io.astatus, sizeof(*adec)); + } + + } + return system_error_to_codec_error(r); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief video_pause Pause video playing by codec device +* +* @param[in] p Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +static int video_pause(codec_para_t *p) +{ + CODEC_PRINT("video_pause!\n"); + return codec_h_control(p->cntl_handle, AMSTREAM_IOC_VPAUSE, 1); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief video_resume Resume video playing by codec device +* +* @param[in] p Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +static int video_resume(codec_para_t *p) +{ + CODEC_PRINT("video_resume!\n"); + return codec_h_control(p->cntl_handle, AMSTREAM_IOC_VPAUSE, 0); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_pause Pause all playing(A/V) by codec device +* +* @param[in] p Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_pause(codec_para_t *p) +{ + int ret = CODEC_ERROR_NONE; + if (p) { + CODEC_PRINT("[codec_pause]p->has_audio=%d\n", p->has_audio); + if (p->has_audio) { + //DEBUG_TMP audio_pause(p->adec_priv); + } + if (p->has_video) { + ret = video_pause(p); + } + } else { + ret = CODEC_ERROR_PARAMETER; + } + return ret; +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_resume Resume playing(A/V) by codec device +* +* @param[in] p Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_resume(codec_para_t *p) +{ + int ret = CODEC_ERROR_NONE; + if (p) { + CODEC_PRINT("[codec_resume]p->has_audio=%d\n", p->has_audio); + if (p->has_audio) { + //DEBUG_TMP audio_resume(p->adec_priv); + } + if (p->has_video) { + ret = video_resume(p); + } + } else { + ret = CODEC_ERROR_PARAMETER; + } + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_reset Reset codec device +* +* @param[in] p Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_reset(codec_para_t *p) +{ + int ret; + ret = codec_close(p); + if (ret != 0) { + return ret; + } + ret = codec_init(p); + CODEC_PRINT("[%s:%d]ret=%x\n", __FUNCTION__, __LINE__, ret); + return system_error_to_codec_error(ret); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_init_sub Initialize subtile codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_init_sub(codec_para_t *pcodec) +{ + CODEC_HANDLE sub_handle; + int flags = O_WRONLY; + flags |= pcodec->noblock ? O_NONBLOCK : 0; + sub_handle = codec_h_open(CODEC_SUB_DEVICE, flags); + if (sub_handle < 0) { + CODEC_PRINT("get %s failed\n", CODEC_SUB_DEVICE); + return system_error_to_codec_error(sub_handle); + } + + pcodec->sub_handle = sub_handle; + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_open_sub_read Open read_subtitle device which is special for read subtile data +* +* @return Device handler, or error type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_open_sub_read(void) +{ + CODEC_HANDLE sub_handle; + + sub_handle = codec_h_open_rd(CODEC_SUB_READ_DEVICE); + if (sub_handle < 0) { + CODEC_PRINT("get %s failed\n", CODEC_SUB_READ_DEVICE); + return system_error_to_codec_error(sub_handle); + } + + return sub_handle; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close_sub Close subtile device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_close_sub(codec_para_t *pcodec) +{ + int res = CODEC_ERROR_NONE; + + if (pcodec) { + if (pcodec->sub_handle) { + res = codec_h_close(pcodec->sub_handle); + } + } + return res; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close_sub_fd Close subtile device by fd +* +* @param[in] sub_fd subtile device fd +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_close_sub_fd(CODEC_HANDLE sub_fd) +{ + int res = CODEC_ERROR_NONE; + + if (sub_fd) { + res = codec_h_close(sub_fd); + } + return res; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_poll_sub Polling subtile device if subtitle data is ready +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Polling result +*/ +/* --------------------------------------------------------------------------*/ +int codec_poll_sub(codec_para_t *pcodec) +{ + struct pollfd sub_poll_fd[1]; + + if (pcodec->sub_handle == 0) { + return 0; + } + + sub_poll_fd[0].fd = pcodec->sub_handle; + sub_poll_fd[0].events = POLLOUT; + + return poll(sub_poll_fd, 1, 10); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_poll_sub_fd Polling subtile device if subtitle data is ready by fd +* +* @param[in] sub_fd Subtitle device fd +* @param[in] timeout Timeout for polling +* +* @return Polling result +*/ +/* --------------------------------------------------------------------------*/ +int codec_poll_sub_fd(CODEC_HANDLE sub_fd, int timeout) +{ + struct pollfd sub_poll_fd[1]; + + if (sub_fd <= 0) { + return 0; + } + + sub_poll_fd[0].fd = sub_fd; + sub_poll_fd[0].events = POLLOUT; + + return poll(sub_poll_fd, 1, timeout); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sub_size Get the size of subtitle data which is ready +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Subtile ready data size, or fail error type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sub_size(codec_para_t *pcodec) +{ + int sub_size, r; + + if (pcodec->sub_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + r = codec_h_ioctl(pcodec->sub_handle, AMSTREAM_IOC_GET, AMSTREAM_GET_SUB_LENGTH, (unsigned long)&sub_size); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return sub_size; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sub_size_fd Get the size of subtitle data which is ready by fd +* +* @param[in] sub_fd Subtitle device fd +* +* @return Subtile ready data size, or fail error type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sub_size_fd(CODEC_HANDLE sub_fd) +{ + int sub_size, r; + + if (sub_fd <= 0) { + CODEC_PRINT("no sub handler\n"); + return 0; + } + + r = codec_h_ioctl(sub_fd, AMSTREAM_IOC_GET, AMSTREAM_GET_SUB_LENGTH, (unsigned long)&sub_size); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return sub_size; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_read_sub_data Read subtitle data from codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[out] buf Buffer for data read from subtitle codec device +* @param[in] length Data length to be read from subtitle codec device +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_read_sub_data(codec_para_t *pcodec, char *buf, unsigned int length) +{ + int data_size = length, r, read_done = 0; + + if (pcodec->sub_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + while (data_size) { + r = codec_h_read(pcodec->sub_handle, buf + read_done, data_size); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + data_size -= r; + read_done += r; + } + } + + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_read_sub_data_fd Read subtitle data from codec device by fd +* +* @param[in] sub_fd Subtitle device fd +* @param[out] buf Buffer for data read from subtitle codec device +* @param[in] length Data length to be read from subtile codec device +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_read_sub_data_fd(CODEC_HANDLE sub_fd, char *buf, unsigned int length) +{ + int data_size = length, r, read_done = 0; + + if (sub_fd <= 0) { + CODEC_PRINT("no sub handler\n"); + return 0; + } + + while (data_size) { + r = codec_h_read(sub_fd, buf + read_done, data_size); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + data_size -= r; + read_done += r; + } + } + + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_write_sub_data Write subtile data to subtitle device +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] buf Buffer for data to be written +* @param[in] length Length of the dat to be written +* +* @return Write length, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_write_sub_data(codec_para_t *pcodec, char *buf, unsigned int length) +{ + if (pcodec->sub_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + return codec_h_write(pcodec->sub_handle, buf, length); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_init_cntl Initialize the video control device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_init_cntl(codec_para_t *pcodec) +{ + CODEC_HANDLE cntl; + + + cntl = codec_h_open(CODEC_CNTL_DEVICE, O_RDWR); + if (cntl < 0) { + CODEC_PRINT("get %s failed\n", CODEC_CNTL_DEVICE); + return system_error_to_codec_error(cntl); + } + + pcodec->cntl_handle = cntl; + + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_close_cntl Close video control device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_close_cntl(codec_para_t *pcodec) +{ + int res = CODEC_ERROR_NONE; + + if (pcodec) { + if (pcodec->cntl_handle) { + res = codec_h_close(pcodec->cntl_handle); + } + } + return res; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_poll_cntl Polling video control device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Polling results +*/ +/* --------------------------------------------------------------------------*/ +int codec_poll_cntl(codec_para_t *pcodec) +{ + struct pollfd codec_poll_fd[1]; + + if (pcodec->cntl_handle == 0) { + return 0; + } + + codec_poll_fd[0].fd = pcodec->cntl_handle; + codec_poll_fd[0].events = POLLOUT; + + return poll(codec_poll_fd, 1, 10); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_cntl_state Get the status of video control device, especially for trickmode +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Video control device status or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_cntl_state(codec_para_t *pcodec) +{ + int cntl_state, r; + + if (pcodec->cntl_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + r = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_TRICK_STAT, (unsigned long)&cntl_state); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return cntl_state; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_cntl_mode Set the mode to video control device, especially for trickmode +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] mode Trick mode to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_TRICKMODE, (unsigned long)mode); +} + +int codec_set_mode(codec_para_t *pcodec, unsigned int mode) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_TRICKMODE, (unsigned long)mode); +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_cntl_avthresh Set the AV sync threshold which defines the max time difference between A/V +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] avthresh Threshold to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_AVTHRESH, (unsigned long)avthresh); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_cntl_syncthresh Set sync threshold control which defines the starting system time (hold video or not) +* when playing +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] syncthresh Sync threshold control +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SYNCTHRESH, (unsigned long)syncthresh); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_reset_audio Reset audio decoder, especially for audio switch +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_reset_audio(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_AUDIO_RESET, 0); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_reset_subtile Reset subtitle device, especially for subtitle swith +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_reset_subtile(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SUB_RESET, 0); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_audio_id Set audio pid by codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_audio_pid(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_AID, pcodec->audio_pid); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sub_id Set subtitle pid by codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sub_id(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_SID, pcodec->sub_pid); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sub_type Set subtitle type by codec device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sub_type(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_SUB_TYPE, pcodec->sub_type); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_reinit Re-initialize audio codec +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_audio_reinit(codec_para_t *pcodec) +{ + int ret; + ret = set_audio_format(pcodec); + if (!ret && pcodec->audio_info.valid) { + ret = set_audio_info(pcodec); + } + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_dec_reset Set decoder reset flag when reset +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_dec_reset(codec_para_t *pcodec) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_DEC_RESET, 0); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_isready check audio finish init ok +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 1 for ready, or not ready if = 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_audio_isready(codec_para_t *p) +{ + int audio_isready = 1; + if (!p) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + if (p->has_audio) { + //DEBUG_TMP audio_isready = audio_dec_ready(p->adec_priv); + } + + return audio_isready; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_audio_get_nb_frames get audiodsp decoded frame number +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return n decoded frames number, or return 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_audio_get_nb_frames(codec_para_t *p) +{ + int audio_nb_frames = -1; + if (!p) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + + if (p->has_audio) { + //DEBUG_TMP audio_nb_frames = audio_get_decoded_nb_frames(p->adec_priv); + } + //CODEC_PRINT("[%s]get audio decoded frame number[%d]!\n", __FUNCTION__, audio_nb_frames); + return audio_nb_frames; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_apts get audio pts +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return audio pts, or -1 if it failed +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_apts(codec_para_t *pcodec) +{ + unsigned int apts; + int ret; + + if (!pcodec) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_APTS, (unsigned long)&apts); + if (ret < 0) { + CODEC_PRINT("[%s]ioctl failed %d\n", __FUNCTION__, ret); + return -1; + } + + return apts; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_vpts get video pts +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return video pts, or -1 if it failed +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_vpts(codec_para_t *pcodec) +{ + unsigned int vpts; + int ret; + + if (!pcodec) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_VPTS, (unsigned long)&vpts); + if (ret < 0) { + CODEC_PRINT("[%s]ioctl failed %d\n", __FUNCTION__, ret); + return -1; + } + + return vpts; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_pcrscr get system pcrscr +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return system pcrscr, or -1 it failed +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_pcrscr(codec_para_t *pcodec) +{ + unsigned int pcrscr; + int ret; + + if (!pcodec) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_PCRSCR, (unsigned long)&pcrscr); + if (ret < 0) { + CODEC_PRINT("[%s]ioctl failed %d\n", __FUNCTION__, ret); + return -1; + } + + return pcrscr; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_pcrscr set system pcrscr +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] val system pcrscr value +* +* @return 0 is success , or -1 failed. +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_pcrscr(codec_para_t *pcodec, int val) +{ + unsigned int pcrscr; + int ret; + + if (!pcodec) { + CODEC_PRINT("[%s]ERROR invalid pointer!\n", __FUNCTION__); + return -1; + } + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_PCRSCR, val); + if (ret < 0) { + CODEC_PRINT("[%s]ioctl failed %d\n", __FUNCTION__, ret); + return -1; + } + + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_syncenable enable or disable av sync +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] enable Enable or disable to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_syncenable(codec_para_t *pcodec, int enable) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SYNCENABLE, (unsigned long)enable); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sync_audio_discont set sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] discontinue Discontinue state to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sync_audio_discont(codec_para_t *pcodec, int discontinue) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_SYNC_ADISCON, (unsigned long)discontinue); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sync_video_discont set sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] discontinue Discontinue state to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sync_video_discont(codec_para_t *pcodec, int discontinue) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_SYNC_VDISCON, (unsigned long)discontinue); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sync_audio_discont get audio sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return discontiue state, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sync_audio_discont(codec_para_t *pcodec) +{ + int discontinue = 0; + int ret; + + ret = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_SYNC_ADISCON, (unsigned long)&discontinue); + if (ret < 0) { + return ret; + } + return discontinue; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sync_video_discont get video sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return discontiue state, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sync_video_discont(codec_para_t *pcodec) +{ + int discontinue = 0; + int ret; + + ret = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_SYNC_VDISCON, (unsigned long)&discontinue); + if (ret < 0) { + return ret; + } + return discontinue; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sync_audio_discont_diff get audio sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return discontiue diff, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +unsigned long codec_get_sync_audio_discont_diff(codec_para_t *pcodec) +{ + unsigned long discontinue_diff = 0; + int ret; + + ret = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_SYNC_ADISCON_DIFF, (unsigned long)&discontinue_diff); + if (ret < 0) { + return ret; + } + return discontinue_diff; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sync_video_discont_diff get audio sync discontinue state +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return discontiue diff, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +unsigned long codec_get_sync_video_discont_diff(codec_para_t *pcodec) +{ + unsigned long discontinue_diff = 0; + int ret; + + ret = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_SYNC_VDISCON_DIFF, (unsigned long)&discontinue_diff); + if (ret < 0) { + return ret; + } + return discontinue_diff; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sync_audio_discont_diff set sync discontinue diff +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] discontinue_diff Discontinue diff to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sync_audio_discont_diff(codec_para_t *pcodec, unsigned long discontinue_diff) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_SYNC_ADISCON_DIFF, discontinue_diff); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_sync_video_discont_diff set sync discontinue diff +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] discontinue_diff Discontinue diff to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_sync_video_discont_diff(codec_para_t *pcodec, unsigned long discontinue_diff) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_SYNC_VDISCON_DIFF, discontinue_diff); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sub_num get the number of subtitle +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return the number of subtitle, or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sub_num(codec_para_t *pcodec) +{ + int sub_num = 0; + int ret; + + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_SUB_NUM, (unsigned long)&sub_num); + if (ret < 0) { + return ret; + } + return sub_num; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_sub_info get subtitle information +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[out] sub_info Pointer of subtitle_info_t to save the subtitle information +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_sub_info(codec_para_t *pcodec, subtitle_info_t *sub_info) +{ + int ret = 0; + int i; + if (!sub_info) { + CODEC_PRINT("[codec_get_sub_info] error, NULL pointer!\n"); + ret = CODEC_ERROR_INVAL; + return ret; + } + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET_PTR, AMSTREAM_GET_PTR_SUB_INFO, (unsigned long)sub_info); + if (ret < 0) { + return ret; + } + return ret; +} + +/******************************************************************************** +* +*the interface for av sync threshold setting +* +*********************************************************************************/ +int codec_set_av_threshold(codec_para_t *pcodec, int threshold) +{ + int ret = 0; + if (pcodec->has_audio) { + //DEBUG_TMP audio_set_av_sync_threshold(pcodec->adec_priv, threshold); + } else { + CODEC_PRINT("[codec_set_av_threshold] error, no audio!\n"); + ret = -1; + } + + return ret; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_freerun_mode Get the mode of video freerun +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Video free run mode or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_freerun_mode(codec_para_t *pcodec) +{ + int freerun_mode, r; + + if (pcodec->cntl_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + r = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_FREERUN_MODE, (unsigned long)&freerun_mode); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return freerun_mode; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_freerun_mode Set the mode to video freerun +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] mode Freerun mode to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_freerun_mode(codec_para_t *pcodec, unsigned int mode) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_FREERUN_MODE, (unsigned long)mode); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_init_audio_utils Initialize the audio utils device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_init_audio_utils(codec_para_t *pcodec) +{ + CODEC_HANDLE audio_utils; + + audio_utils = codec_h_open(CODEC_AUDIO_UTILS_DEVICE, O_RDONLY); + if (audio_utils < 0) { + CODEC_PRINT("get %s failed\n", CODEC_AUDIO_UTILS_DEVICE); + return system_error_to_codec_error(audio_utils); + } + + pcodec->audio_utils_handle = audio_utils; + + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_release_audio_utils Release the audio utils device +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_release_audio_utils(codec_para_t *pcodec) +{ + if (pcodec) { + if (pcodec->audio_utils_handle >= 0) { + codec_h_close(pcodec->audio_utils_handle); + } + } + + pcodec->audio_utils_handle = -1; + + return CODEC_ERROR_NONE; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_audio_resample_ena Set audio resample +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_audio_resample_ena(codec_para_t *pcodec, unsigned long mode) +{ + return codec_h_control(pcodec->audio_utils_handle, AMAUDIO_IOC_SET_RESAMPLE_ENA, mode); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_audio_resample_ena Set audio resample enable +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_audio_resample_ena(codec_para_t *pcodec) +{ + unsigned long audio_resample_ena; + int ret; + ret = codec_h_control(pcodec->audio_utils_handle, AMAUDIO_IOC_GET_RESAMPLE_ENA, (unsigned long)&audio_resample_ena); + if (ret < 0) { + return system_error_to_codec_error(ret); + } else { + return audio_resample_ena; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_audio_resample_type Set audio resample type +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_audio_resample_type(codec_para_t *pcodec, unsigned long type) +{ + return codec_h_control(pcodec->audio_utils_handle, AMAUDIO_IOC_SET_RESAMPLE_TYPE, type); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_video_delay_limited_ms Set video buffer max delayed,if> settings,write may wait& again, +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_video_delay_limited_ms(codec_para_t *pcodec, int delay_ms) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS, delay_ms); +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_video_delay_limited_ms Set video buffer max delayed,if> settings,write may wait& again, +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_video_delay_limited_ms(codec_para_t *pcodec, int *delay_ms) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS, (unsigned long)delay_ms); +} + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_video_delay_limited_ms Set video buffer max delayed,if> settings,write may wait& again, +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_audio_delay_limited_ms(codec_para_t *pcodec, int delay_ms) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS, delay_ms); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_audio_delay_limited_ms get video buffer max delayed,if> settings,write may wait& again, +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_audio_delay_limited_ms(codec_para_t *pcodec, int *delay_ms) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS, (unsigned long)delay_ms); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_audio_cur_delay_ms get current audio delay ms +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_audio_cur_delay_ms(codec_para_t *pcodec, int *delay_ms) +{ + int abuf_delay = 0; + int adec_delay = 0; + int ret = 0; + ret = codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_AUDIO_CUR_DELAY_MS, (unsigned long)&abuf_delay); + if (ret < 0) { + CODEC_PRINT("[%s]ioctl failed %d\n", __FUNCTION__, ret); + return -1; + } + if (pcodec->has_audio) { + //DEBUG_TMP adec_delay = audio_get_decoded_pcm_delay(pcodec->adec_priv); + if (adec_delay < 0) { + adec_delay = 0; + } + } + *delay_ms = abuf_delay + adec_delay; + return ret; +} + + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_video_cur_delay_ms get video current delay ms +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_video_cur_delay_ms(codec_para_t *pcodec, int *delay_ms) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_VIDEO_CUR_DELAY_MS, (unsigned long)delay_ms); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_audio_cur_delay_ms get vido latest bitrate. +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_video_cur_bitrate(codec_para_t *pcodec, int *bitrate) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS, (unsigned long)bitrate); +} + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_audio_cur_bitrate get audio latest bitrate. +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_audio_cur_bitrate(codec_para_t *pcodec, int *bitrate) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS, (unsigned long)bitrate); +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_video_checkin_bitrate get vido latest bitrate. +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_video_checkin_bitrate(codec_para_t *pcodec, int *bitrate) +{ + return codec_h_control(pcodec->handle, AMSTREAM_IOC_GET_VIDEO_CHECKIN_BITRATE_BPS, (unsigned long)bitrate); +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_audio_checkin_bitrate get audio latest bitrate. +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_audio_checkin_bitrate(codec_para_t *pcodec, int *bitrate) +{ + return codec_h_control(pcodec->handle, AMSTREAM_IOC_GET_AUDIO_CHECKIN_BITRATE_BPS, (unsigned long)bitrate); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_set_vsync_upint Set the mode to video freerun +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] mode vsync upint mode to be set +* +* @return 0 for success, or fail type if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_set_vsync_upint(codec_para_t *pcodec, unsigned int mode) +{ + return codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_SET_VSYNC_UPINT, (unsigned long)mode); +} +int codec_set_drmmode(codec_para_t *pcodec, unsigned int setval) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_SET, AMSTREAM_SET_DRMMODE, setval); +} + +/** + * + * + */ +int codec_get_last_checkout_apts(codec_para_t* pcodec, unsigned long *apts) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_LAST_CHECKOUT_APTS, (unsigned long)apts); +} + +int codec_get_last_checkin_apts(codec_para_t* pcodec, unsigned long* apts) +{ + return codec_h_ioctl(pcodec->handle, AMSTREAM_IOC_GET, AMSTREAM_GET_LAST_CHECKIN_APTS, (unsigned long)apts); +} + +/** + *@brief codec_get_pcm_level get the PCM data in buffer between DSP and output + * + * @param[in] pcodec Pointer of codec parameter structre + * @param[in] level Address to store "level" + * @return 0 for success, or fail type if<0 + */ + +int codec_get_pcm_level(codec_para_t* pcodec, unsigned int* level) +{ + return 0;//DEBUG_TMP audio_get_pcm_level(pcodec->adec_priv); +} + +int codec_set_skip_bytes(codec_para_t* pcodec, unsigned int bytes) +{ + return 0;//DEBUG_TMP audio_set_skip_bytes(pcodec->adec_priv, bytes); +} + +int codec_get_dsp_apts(codec_para_t* pcodec, unsigned int * apts) +{ + return 0;//DEBUG_TMP audio_get_pts(pcodec->adec_priv); +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_get_cntl_vpts Get the vpts in trickmode +* +* @param[in] pcodec Pointer of codec parameter structure +* +* @return Video pts or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_get_cntl_vpts(codec_para_t *pcodec) +{ + int cntl_vpts, r; + + if (pcodec->cntl_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + r = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_GET_TRICK_VPTS, (unsigned long)&cntl_vpts); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return cntl_vpts; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_disalbe_slowsync Set the slowsync disable or enable +* +* @param[in] pcodec Pointer of codec parameter structure +* @param[in] disalbe_slowsync disable slowsync or not +* +* @return 0 or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_disalbe_slowsync(codec_para_t *pcodec, int disable_slowsync) +{ + int cntl_vpts, r; + + if (pcodec->cntl_handle == 0) { + CODEC_PRINT("no control handler\n"); + return 0; + } + + r = codec_h_control(pcodec->cntl_handle, AMSTREAM_IOC_DISABLE_SLOW_SYNC, (unsigned long)disable_slowsync); + if (r < 0) { + return system_error_to_codec_error(r); + } else { + return 0; + } +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief add video position setting for xbmc APK +* +* @param[in] osd position value +* @param[in] rotation angle +* +* @return 0 success or fail error type +*/ +/* --------------------------------------------------------------------------*/ +int codec_utils_set_video_position(int x, int y, int w, int h, int rotation) +{ + amvideo_utils_set_virtual_position(x, y, w, h, rotation); + return 0; + +} + diff --git a/amcodec/codec/codec_h_ctrl.c b/amcodec/codec/codec_h_ctrl.c new file mode 100644 index 0000000..83c6a77 --- a/dev/null +++ b/amcodec/codec/codec_h_ctrl.c @@ -0,0 +1,586 @@ +/** +* @file codec_h_ctrl.c +* @brief functions of codec device handler operation +* @author Zhou Zhi <zhi.zhou@amlogic.com> +* @version 2.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <errno.h> +#include <codec_error.h> +#include <codec.h> +#include "codec_h_ctrl.h" +#include "amports/amstream.h" +//------------------------------ +#include <sys/times.h> +#define msleep(n) usleep(n*1000) +//-------------------------------- +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_open Open codec devices by file name +* +* @param[in] port_addr File name of codec device +* @param[in] flags Open flags +* +* @return The handler of codec device +*/ +/* --------------------------------------------------------------------------*/ +CODEC_HANDLE codec_h_open(const char *port_addr, int flags) +{ + int r; + int retry_open_times = 0; +retry_open: + r = open(port_addr, flags); + if (r < 0 /*&& r == EBUSY */) { + //-------------------------------- + retry_open_times++; + if (retry_open_times == 1) { + CODEC_PRINT("Init [%s] failed,ret = %d error=%d retry_open!\n", port_addr, r, errno); + } + msleep(10); + if (retry_open_times < 1000) { + goto retry_open; + } + CODEC_PRINT("retry_open [%s] failed,ret = %d error=%d used_times=%d*10(ms)\n", port_addr, r, errno, retry_open_times); + //-------------------------------- + //CODEC_PRINT("Init [%s] failed,ret = %d error=%d\n", port_addr, r, errno); + return r; + } + if (retry_open_times > 0) { + CODEC_PRINT("retry_open [%s] success,ret = %d error=%d used_times=%d*10(ms)\n", port_addr, r, errno, retry_open_times); + } + return (CODEC_HANDLE)r; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_open_rd Open codec devices by file name in read_only mode +* +* @param[in] port_addr File name of codec device +* +* @return THe handler of codec device +*/ +/* --------------------------------------------------------------------------*/ +CODEC_HANDLE codec_h_open_rd(const char *port_addr) +{ + int r; + r = open(port_addr, O_RDONLY); + if (r < 0) { + CODEC_PRINT("Init [%s] failed,ret = %d errno=%d\n", port_addr, r, errno); + return r; + } + return (CODEC_HANDLE)r; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_close Close codec devices +* +* @param[in] h Handler of codec device +* +* @return 0 for success +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_close(CODEC_HANDLE h) +{ + int r; + if (h >= 0) { + r = close(h); + if (r < 0) { + CODEC_PRINT("close failed,handle=%d,ret=%d errno=%d\n", h, r, errno); + } + } + return 0; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_control IOCTL commands for codec devices +* +* @param[in] h Codec device handler +* @param[in] cmd IOCTL commands +* @param[in] paramter IOCTL commands parameter +* +* @return 0 for success, non-0 for fail +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_control(CODEC_HANDLE h, int cmd, unsigned long paramter) +{ + int r; + + if (h < 0) { + return -1; + } + r = ioctl(h, cmd, paramter); + if (r < 0) { + CODEC_PRINT("send control failed,handle=%d,cmd=%x,paramter=%x, t=%x errno=%d\n", h, cmd, paramter, r, errno); + return r; + } + return 0; +} + +static struct codec_amd_table { + unsigned int cmd; + unsigned int parm_cmd; +} cmd_tables[] = { + /*amstream*/ + { AMSTREAM_IOC_VB_START, AMSTREAM_SET_VB_START }, + { AMSTREAM_IOC_VB_SIZE, AMSTREAM_SET_VB_SIZE }, + { AMSTREAM_IOC_AB_START, AMSTREAM_SET_AB_START }, + { AMSTREAM_IOC_AB_SIZE, AMSTREAM_SET_AB_SIZE }, + { AMSTREAM_IOC_VFORMAT, AMSTREAM_SET_VFORMAT }, + { AMSTREAM_IOC_AFORMAT, AMSTREAM_SET_AFORMAT }, + { AMSTREAM_IOC_VID, AMSTREAM_SET_VID }, + { AMSTREAM_IOC_AID, AMSTREAM_SET_AID }, + { AMSTREAM_IOC_VB_STATUS, AMSTREAM_GET_EX_VB_STATUS }, + { AMSTREAM_IOC_AB_STATUS, AMSTREAM_GET_EX_AB_STATUS }, + { AMSTREAM_IOC_ACHANNEL, AMSTREAM_SET_ACHANNEL }, + { AMSTREAM_IOC_SAMPLERATE, AMSTREAM_SET_SAMPLERATE }, + { AMSTREAM_IOC_DATAWIDTH, AMSTREAM_SET_DATAWIDTH }, + { AMSTREAM_IOC_TSTAMP, AMSTREAM_SET_TSTAMP }, + { AMSTREAM_IOC_VDECSTAT, AMSTREAM_GET_EX_VDECSTAT }, + { AMSTREAM_IOC_ADECSTAT, AMSTREAM_GET_EX_ADECSTAT }, + { AMSTREAM_IOC_PORT_INIT, AMSTREAM_PORT_INIT }, + { AMSTREAM_IOC_TRICKMODE, AMSTREAM_SET_TRICKMODE }, + { AMSTREAM_IOC_AUDIO_INFO, AMSTREAM_SET_PTR_AUDIO_INFO }, + { AMSTREAM_IOC_AUDIO_RESET, AMSTREAM_AUDIO_RESET }, + { AMSTREAM_IOC_SID, AMSTREAM_SET_SID }, + { AMSTREAM_IOC_SUB_RESET, AMSTREAM_SUB_RESET }, + { AMSTREAM_IOC_SUB_LENGTH, AMSTREAM_GET_SUB_LENGTH }, + { AMSTREAM_IOC_SET_DEC_RESET, AMSTREAM_DEC_RESET }, + { AMSTREAM_IOC_TS_SKIPBYTE, AMSTREAM_SET_TS_SKIPBYTE }, + { AMSTREAM_IOC_SUB_TYPE, AMSTREAM_SET_SUB_TYPE }, + { AMSTREAM_IOC_APTS, AMSTREAM_GET_APTS }, + { AMSTREAM_IOC_VPTS, AMSTREAM_GET_VPTS }, + { AMSTREAM_IOC_PCRSCR, AMSTREAM_GET_PCRSCR }, + { AMSTREAM_IOC_SET_PCRSCR, AMSTREAM_SET_PCRSCR }, + { AMSTREAM_IOC_SUB_NUM, AMSTREAM_GET_SUB_NUM }, + { AMSTREAM_IOC_SUB_INFO, AMSTREAM_GET_PTR_SUB_INFO }, + { AMSTREAM_IOC_UD_LENGTH, AMSTREAM_GET_UD_LENGTH }, + { AMSTREAM_IOC_UD_POC, AMSTREAM_GET_EX_UD_POC }, + { AMSTREAM_IOC_APTS_LOOKUP, AMSTREAM_GET_APTS_LOOKUP }, + { GET_FIRST_APTS_FLAG, AMSTREAM_GET_FIRST_APTS_FLAG }, + { AMSTREAM_IOC_SET_DEMUX, AMSTREAM_SET_DEMUX }, + { AMSTREAM_IOC_SET_DRMMODE, AMSTREAM_SET_DRMMODE }, + { AMSTREAM_IOC_TSTAMP_uS64, AMSTREAM_SET_TSTAMP_US64 }, + { AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS, AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS }, + { AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS, AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS }, + { AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS, AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS }, + { AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS, AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS }, + { AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS, AMSTREAM_GET_AUDIO_CUR_DELAY_MS }, + { AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS, AMSTREAM_GET_VIDEO_CUR_DELAY_MS }, + { AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS, AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS }, + { AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS, AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS }, + { AMSTREAM_IOC_SET_APTS, AMSTREAM_SET_APTS }, + { AMSTREAM_IOC_GET_LAST_CHECKIN_APTS, AMSTREAM_GET_LAST_CHECKIN_APTS }, + { AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS, AMSTREAM_GET_LAST_CHECKIN_VPTS }, + { AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS, AMSTREAM_GET_LAST_CHECKOUT_APTS }, + { AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS, AMSTREAM_GET_LAST_CHECKOUT_VPTS }, + { AMSTREAM_IOC_SET, AMSTREAM_SET_EOS}, + /*video cmd*/ + //{ AMSTREAM_IOC_TRICK_STAT, AMSTREAM_GET_TRICK_STAT }, + //{ AMSTREAM_IOC_VPAUSE, AMSTREAM_SET_VPAUSE }, + //{ AMSTREAM_IOC_AVTHRESH, AMSTREAM_SET_AVTHRESH }, + //{ AMSTREAM_IOC_SYNCTHRESH, AMSTREAM_SET_SYNCTHRESH }, + //{ AMSTREAM_IOC_CLEAR_VIDEO, AMSTREAM_SET_CLEAR_VIDEO }, + //{ AMSTREAM_IOC_SYNCENABLE, AMSTREAM_SET_SYNCENABLE }, + //{ AMSTREAM_IOC_GET_SYNC_ADISCON, AMSTREAM_GET_SYNC_ADISCON }, + //{ AMSTREAM_IOC_SET_SYNC_ADISCON, AMSTREAM_SET_SYNC_ADISCON }, + //{ AMSTREAM_IOC_GET_SYNC_VDISCON, AMSTREAM_GET_SYNC_VDISCON }, + //{ AMSTREAM_IOC_SET_SYNC_VDISCON, AMSTREAM_SET_SYNC_VDISCON }, + //{ AMSTREAM_IOC_GET_VIDEO_DISABLE, AMSTREAM_GET_VIDEO_DISABLE }, + //{ AMSTREAM_IOC_SET_VIDEO_DISABLE, AMSTREAM_SET_VIDEO_DISABLE }, + //{ AMSTREAM_IOC_SYNCENABLE, AMSTREAM_SET_SYNCENABLE }, + //{ AMSTREAM_IOC_GET_SYNC_ADISCON, AMSTREAM_GET_SYNC_ADISCON }, + //{ AMSTREAM_IOC_SET_SYNC_ADISCON, AMSTREAM_SET_SYNC_ADISCON }, + //{ AMSTREAM_IOC_GET_SYNC_VDISCON, AMSTREAM_GET_SYNC_VDISCON }, + //{ AMSTREAM_IOC_SET_SYNC_VDISCON, AMSTREAM_SET_SYNC_VDISCON }, + //{ AMSTREAM_IOC_GET_VIDEO_DISABLE, AMSTREAM_GET_VIDEO_DISABLE }, + //{ AMSTREAM_IOC_SET_VIDEO_DISABLE, AMSTREAM_SET_VIDEO_DISABLE }, + //{ AMSTREAM_IOC_GET_VIDEO_AXIS, AMSTREAM_GET_EX_VIDEO_AXIS }, + //{ AMSTREAM_IOC_SET_VIDEO_AXIS, AMSTREAM_SET_EX_VIDEO_AXIS }, + //{ AMSTREAM_IOC_GET_VIDEO_CROP, AMSTREAM_GET_EX_VIDEO_CROP }, + //{ AMSTREAM_IOC_SET_VIDEO_CROP, AMSTREAM_SET_EX_VIDEO_CROP }, + //{ AMSTREAM_IOC_PCRID, AMSTREAM_SET_PCRID }, + //{ AMSTREAM_IOC_SET_3D_TYPE, AMSTREAM_SET_3D_TYPE }, + //{ AMSTREAM_IOC_GET_3D_TYPE, AMSTREAM_GET_3D_TYPE }, + //{ AMSTREAM_IOC_GET_BLACKOUT_POLICY, AMSTREAM_GET_BLACKOUT_POLICY }, + //{ AMSTREAM_IOC_SET_BLACKOUT_POLICY, AMSTREAM_SET_BLACKOUT_POLICY }, + //{ AMSTREAM_IOC_GET_SCREEN_MODE, AMSTREAM_GET_SCREEN_MODE }, + //{ AMSTREAM_IOC_SET_SCREEN_MODE, AMSTREAM_SET_SCREEN_MODE }, + //{ AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT, AMSTREAM_GET_VIDEO_DISCONTINUE_REPORT }, + //{ AMSTREAM_IOC_SET_VIDEO_DISCONTINUE_REPORT, AMSTREAM_SET_VIDEO_DISCONTINUE_REPORT }, + //{ AMSTREAM_IOC_VF_STATUS, AMSTREAM_GET_VF_STATUS }, + //{ AMSTREAM_IOC_CLEAR_VBUF, AMSTREAM_CLEAR_VBUF }, + //{ AMSTREAM_IOC_GET_SYNC_ADISCON_DIFF, AMSTREAM_GET_SYNC_ADISCON_DIFF }, + //{ AMSTREAM_IOC_GET_SYNC_VDISCON_DIFF, AMSTREAM_GET_SYNC_VDISCON_DIFF }, + //{ AMSTREAM_IOC_SET_SYNC_ADISCON_DIFF, AMSTREAM_SET_SYNC_ADISCON_DIFF }, + //{ AMSTREAM_IOC_SET_SYNC_VDISCON_DIFF, AMSTREAM_SET_SYNC_VDISCON_DIFF }, + //{ AMSTREAM_IOC_GET_FREERUN_MODE, AMSTREAM_GET_FREERUN_MODE }, + //{ AMSTREAM_IOC_SET_FREERUN_MODE, AMSTREAM_SET_FREERUN_MODE }, + //{ AMSTREAM_IOC_SET_VSYNC_UPINT, AMSTREAM_SET_VSYNC_UPINT }, + //{ AMSTREAM_IOC_GET_VSYNC_SLOW_FACTOR, AMSTREAM_GET_VSYNC_SLOW_FACTOR }, + //{ AMSTREAM_IOC_SET_VSYNC_SLOW_FACTOR, AMSTREAM_SET_VSYNC_SLOW_FACTOR }, + //{ AMSTREAM_IOC_SET_OMX_VPTS, AMSTREAM_SET_OMX_VPTS }, + //{ AMSTREAM_IOC_GET_OMX_VPTS, AMSTREAM_GET_OMX_VPTS }, + //{ AMSTREAM_IOC_GET_TRICK_VPTS, AMSTREAM_GET_TRICK_VPTS }, + //{ AMSTREAM_IOC_DISABLE_SLOW_SYNC, AMSTREAM_GET_DISABLE_SLOW_SYNC }, + /* subtitle cmd */ + //{ AMSTREAM_IOC_GET_SUBTITLE_INFO, AMSTREAM_GET_SUBTITLE_INFO }, + //{ AMSTREAM_IOC_SET_SUBTITLE_INFO, AMSTREAM_SET_SUBTITLE_INFO }, + { 0, 0 }, +}; +int get_old_cmd(int cmd) +{ + struct codec_amd_table *p; + for (p = cmd_tables; p->cmd; p++) { + if (p->parm_cmd == cmd) { + return p->cmd; + } + } + return -1; +} + +static int codec_h_ioctl_set(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + int r; + int cmd_new = AMSTREAM_IOC_SET; + unsigned long parm_new; + switch (subcmd) { + case AMSTREAM_SET_VB_SIZE: + case AMSTREAM_SET_AB_SIZE: + case AMSTREAM_SET_VID: + case AMSTREAM_SET_ACHANNEL: + case AMSTREAM_SET_SAMPLERATE: + case AMSTREAM_SET_TSTAMP: + case AMSTREAM_SET_AID: + case AMSTREAM_SET_TRICKMODE: + case AMSTREAM_SET_SID: + case AMSTREAM_SET_TS_SKIPBYTE: + case AMSTREAM_SET_PCRSCR: + case AMSTREAM_SET_SUB_TYPE: + case AMSTREAM_SET_DEMUX: + case AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS: + case AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS: + case AMSTREAM_SET_DRMMODE: { + struct am_ioctl_parm parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.data_32 = paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + case AMSTREAM_SET_VFORMAT: { + struct am_ioctl_parm parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.data_vformat = paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + case AMSTREAM_SET_AFORMAT: { + struct am_ioctl_parm parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.data_aformat = paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + case AMSTREAM_PORT_INIT: + case AMSTREAM_AUDIO_RESET: + case AMSTREAM_SUB_RESET: + case AMSTREAM_DEC_RESET: { + struct am_ioctl_parm parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + default: { + struct am_ioctl_parm parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.data_32 = paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + } + + if (r < 0) { + CODEC_PRINT("codec_h_ioctl_set failed,handle=%d,cmd=%x,paramter=%x, t=%x errno=%d\n", h, subcmd, paramter, r, errno); + return r; + } + return 0; +} +static int codec_h_ioctl_set_ex(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + return 0; +} +static int codec_h_ioctl_set_ptr(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + int r; + int cmd_new = AMSTREAM_IOC_SET_PTR; + unsigned long parm_new; + switch (subcmd) { + case AMSTREAM_SET_PTR_AUDIO_INFO: { + struct am_ioctl_parm_ptr parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.pdata_audio_info = (struct audio_info *)paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + default: + r = -1; + break; + } + if (r < 0) { + CODEC_PRINT("codec_h_ioctl_set_ptr failed,handle=%d,subcmd=%x,paramter=%x, t=%x errno=%d\n", h, subcmd, paramter, r, errno); + return r; + } + return 0; +} +static int codec_h_ioctl_get(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + int r; + struct am_ioctl_parm parm; + unsigned long parm_new; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.data_32 = *(unsigned int *)paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, AMSTREAM_IOC_GET, parm_new); + if (r < 0) { + CODEC_PRINT("codec_h_ioctl_get failed,handle=%d,subcmd=%x,paramter=%x, t=%x errno=%d\n", h, subcmd, paramter, r, errno); + return r; + } + if (paramter != 0) { + *(unsigned int *)paramter = parm.data_32; + } + return 0; +} +static int codec_h_ioctl_get_ex(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + int r; + int cmd_new = AMSTREAM_IOC_GET_EX; + unsigned long parm_new; + switch (subcmd) { + case AMSTREAM_GET_EX_VB_STATUS: + case AMSTREAM_GET_EX_AB_STATUS: { + struct am_ioctl_parm_ex parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + if (r >= 0 && paramter != 0) { + memcpy((void *)paramter, &parm.status, sizeof(struct buf_status)); + } + } + break; + case AMSTREAM_GET_EX_VDECSTAT: { + struct am_ioctl_parm_ex parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + if (r >= 0 && paramter != 0) { + memcpy((void *)paramter, &parm.vstatus, sizeof(struct vdec_status)); + } + } + break; + case AMSTREAM_GET_EX_ADECSTAT: { + struct am_ioctl_parm_ex parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + if (r >= 0 && paramter != 0) { + memcpy((void *)paramter, &parm.astatus, sizeof(struct adec_status)); + } + } + break; + default: + r = -1; + break; + } + if (r < 0) { + CODEC_PRINT("codec_h_ioctl_get_ex failed,handle=%d,subcmd=%x,paramter=%x, t=%x errno=%d\n", h, subcmd, paramter, r, errno); + return r; + } + return 0; + +} +static int codec_h_ioctl_get_ptr(CODEC_HANDLE h, int subcmd, unsigned long paramter) +{ + int r; + int cmd_new = AMSTREAM_IOC_GET_PTR; + unsigned long parm_new; + switch (subcmd) { + case AMSTREAM_IOC_SUB_INFO: { + struct am_ioctl_parm_ptr parm; + memset(&parm, 0, sizeof(parm)); + parm.cmd = subcmd; + parm.pdata_sub_info = (struct subtitle_info *)paramter; + parm_new = (unsigned long)&parm; + r = ioctl(h, cmd_new, parm_new); + } + break; + default: + r = -1; + break; + } + if (r < 0) { + CODEC_PRINT("codec_h_ioctl_get_ptr failed,handle=%d,subcmd=%x,paramter=%x, t=%x errno=%d\n", h, subcmd, paramter, r, errno); + return r; + } + return 0; +} +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_control IOCTL commands for codec devices +* +* @param[in] h Codec device handler +* @param[in] cmd IOCTL commands +* @param[in] paramter IOCTL commands parameter +* +* @return 0 for success, non-0 for fail +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_ioctl(CODEC_HANDLE h, int cmd, int subcmd, unsigned long paramter) +{ + int r; + int cmd_new; + unsigned long parm_new; + if (h < 0) { + return -1; + } + //printf("[%s]l: %d --->cmd:%x, subcmd:%x\n", __func__, __LINE__, cmd, subcmd); + if (!codec_h_is_support_new_cmd()) { + int old_cmd = get_old_cmd(subcmd); + if (old_cmd == -1) { + return -1; + } + return codec_h_control(h, old_cmd, paramter); + } + switch (cmd) { + case AMSTREAM_IOC_SET: + r = codec_h_ioctl_set(h, subcmd, paramter); + break; + case AMSTREAM_IOC_SET_EX: + r = codec_h_ioctl_set_ex(h, subcmd, paramter); + break; + case AMSTREAM_IOC_SET_PTR: + r = codec_h_ioctl_set_ptr(h, subcmd, paramter); + break; + case AMSTREAM_IOC_GET: + r = codec_h_ioctl_get(h, subcmd, paramter); + break; + case AMSTREAM_IOC_GET_EX: + r = codec_h_ioctl_get_ex(h, subcmd, paramter); + break; + case AMSTREAM_IOC_GET_PTR: + r = codec_h_ioctl_get_ptr(h, subcmd, paramter); + break; + default: + r = ioctl(h, cmd, paramter); + break; + } + + if (r < 0) { + CODEC_PRINT("codec_h_ioctl failed,handle=%d,cmd=%x,subcmd=%x, paramter=%x, t=%x errno=%d\n", h, cmd, subcmd, paramter, r, errno); + return r; + } + return 0; +} + + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_read Read data from codec devices +* +* @param[in] handle Codec device handler +* @param[out] buffer Buffer for the data read from codec device +* @param[in] size Size of the data to be read +* +* @return read length or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_read(CODEC_HANDLE handle, void *buffer, int size) +{ + int r; + r = read(handle, buffer, size); + if (r < 0) { + CODEC_PRINT("read failed,handle=%d,ret=%d errno=%d\n", handle, r, errno); + } + return r; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_write Write data to codec devices +* +* @param[in] handle Codec device handler +* @param[out] buffer Buffer for the data to be written to codec device +* @param[in] size Size of the data to be written +* +* @return write length or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_write(CODEC_HANDLE handle, void *buffer, int size) +{ + int r; + r = write(handle, buffer, size); + if (r < 0 && errno != EAGAIN) { + CODEC_PRINT("write failed,handle=%d,ret=%d errno=%d\n", handle, r, errno); + } + return r; +} + +static int support_new_cmd = 0; +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_set_support_new_cmd set support new cmd +* +* @param[in] handle Codec device handler +* +* @return write length or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +void codec_h_set_support_new_cmd(int value) +{ + support_new_cmd = value; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_h_set_support_new_cmd set support new cmd +* +* @param[in] handle Codec device handler +* +* @return write length or fail if < 0 +*/ +/* --------------------------------------------------------------------------*/ +int codec_h_is_support_new_cmd() +{ + return support_new_cmd; +} + diff --git a/amcodec/codec/codec_h_ctrl.h b/amcodec/codec/codec_h_ctrl.h new file mode 100644 index 0000000..78690c0 --- a/dev/null +++ b/amcodec/codec/codec_h_ctrl.h @@ -0,0 +1,60 @@ +/** +* @file codec_h_ctrl.h +* @brief Definition of codec devices and function prototypes +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#ifndef CODEC_HEADER_H_H +#define CODEC_HEADER_H_H +#include <codec_type.h> +#include <codec_error.h> + +#define CODEC_DEBUG + +#ifdef CODEC_DEBUG +#ifdef ANDROID +#include <android/log.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#define LOG_TAG "amcodec" +#define CODEC_PRINT(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#else +#define CODEC_PRINT(f,s...) fprintf(stderr,f,##s) +#endif +#else +#define CODEC_PRINT(f,s...) +#endif + +#define CODEC_VIDEO_ES_DEVICE "/dev/amstream_vbuf" +#define CODEC_AUDIO_ES_DEVICE "/dev/amstream_abuf" +#define CODEC_TS_DEVICE "/dev/amstream_mpts" +#define CODEC_PS_DEVICE "/dev/amstream_mpps" +#define CODEC_RM_DEVICE "/dev/amstream_rm" +#define CODEC_CNTL_DEVICE "/dev/amvideo" +#define CODEC_SUB_DEVICE "/dev/amstream_sub" +#define CODEC_SUB_READ_DEVICE "/dev/amstream_sub_read" +#define CODEC_AUDIO_UTILS_DEVICE "/dev/amaudio_utils" +#define CODEC_VIDEO_HEVC_DEVICE "/dev/amstream_hevc" +#define CODEC_VIDEO_DVAVC_DEVICE "/dev/amstream_dves_avc" +#define CODEC_VIDEO_DVHEVC_DEVICE "/dev/amstream_dves_hevc" + + + +CODEC_HANDLE codec_h_open(const char *port_addr, int flags); +int codec_h_close(CODEC_HANDLE h); +int codec_h_write(CODEC_HANDLE , void *, int); +int codec_h_read(CODEC_HANDLE, void *, int); +int codec_h_control(CODEC_HANDLE h, int cmd, unsigned long paramter); +void codec_h_set_support_new_cmd(int value); +int codec_h_is_support_new_cmd(); +CODEC_HANDLE codec_h_open_rd(const char *port_addr); +int codec_h_ioctl(CODEC_HANDLE h, int cmd, int subcmd, unsigned long paramter); + +#endif diff --git a/amcodec/codec/codec_msg.c b/amcodec/codec/codec_msg.c new file mode 100644 index 0000000..432acab --- a/dev/null +++ b/amcodec/codec/codec_msg.c @@ -0,0 +1,231 @@ +/** +* @file codec_msg.c +* @brief Codec message covertion functions +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#include <stdio.h> +#include <stdio.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <codec_error.h> +#include <codec.h> +#include "codec_h_ctrl.h" + + +/* --------------------------------------------------------------------------*/ +/** +* @brief system_error_to_codec_error Convert system error to codec error types +* +* @param[in] error System error to be converted +* +* @return Codec error type +*/ +/* --------------------------------------------------------------------------*/ +int system_error_to_codec_error(int error) +{ + switch (error) { + case 0: + return CODEC_ERROR_NONE; + case EBUSY: + return -CODEC_ERROR_BUSY; + case ENOMEM: + return -CODEC_ERROR_NOMEM; + case ENODEV: + return -CODEC_ERROR_IO; + default: + return -(C_PAE | error); + } +} + +typedef struct { + int error_no; + char buf[256]; +} codec_errors_t; + +const codec_errors_t codec_errno[] = { + //codec error + {CODEC_ERROR_NONE, "codec no errors"}, + { -CODEC_ERROR_INVAL, "invalid handle or parameter"}, + { -CODEC_ERROR_BUSY, "codec is busy"}, + { -CODEC_ERROR_NOMEM, "no enough memory for codec"}, + { -CODEC_ERROR_IO, "codec io error"}, + { -CODEC_ERROR_PARAMETER, "Parameters error"}, + { -CODEC_ERROR_AUDIO_TYPE_UNKNOW, "Audio Type error"}, + { -CODEC_ERROR_VIDEO_TYPE_UNKNOW, "Video Type error"}, + { -CODEC_ERROR_STREAM_TYPE_UNKNOW, "Stream Type error"}, + { -CODEC_ERROR_INIT_FAILED, "Codec init failed"}, + { -CODEC_ERROR_SET_BUFSIZE_FAILED, "Codec change buffer size failed"}, + + //errno, definition in error.h + {EPERM, "Operation not permitted"}, // 1 + {ENOENT, "No such file or directory"}, // 2 + {ESRCH, "No such process"}, // 3 + {EINTR, "Interrupted system call"}, // 4 + {EIO, "I/O error"}, // 5 + {ENXIO, "No such device or address"}, // 6 + {E2BIG, "Arg list too long"}, // 7 + {ENOEXEC, "Exec format error"}, // 8 + {EBADF, "Bad file number"}, // 9 + {ECHILD, "No child processes"}, // 10 + {EAGAIN, "Try again"}, // 11 + {ENOMEM, "Out of memory"}, // 12 + {EACCES, "Permission denied"}, // 13 + {EFAULT, "Bad address"}, // 14 + {ENOTBLK, "Block device required"}, // 15 + {EBUSY, "Device or resource busy"}, // 16 + {EEXIST, "File exists"}, // 17 + {EXDEV, "Cross-device link"}, // 18 + {ENODEV, "No such device"}, // 19 + {ENOTDIR, "Not a directory"}, // 20 + {EISDIR, "Is a directory"}, // 21 + {EINVAL, "Invalid argument"}, // 22 + {ENFILE, "File table overflow"}, // 23 + {EMFILE, "Too many open files"}, // 24 + {ENOTTY, "Not a typewriter"}, // 25 + {ETXTBSY, "Text file busy"}, // 26 + {EFBIG, "File too large"}, // 27 + {ENOSPC, "No space left on device"}, // 28 + {ESPIPE, "Illegal seek"}, // 29 + {EROFS, "Read-only file system"}, // 30 + {EMLINK, "Too many links"}, // 31 + {EPIPE, "Broken pipe"}, // 32 + {EDOM, "Math argument out of domain of func"}, // 33 + {ERANGE, "Math result not representable"}, // 34 + {EDEADLK, "Resource deadlock would occur"}, // 35 + {ENAMETOOLONG, "File name too long"}, // 36 + {ENOLCK, "No record locks available"}, // 37 + {ENOSYS, "Function not implemented"}, // 38 + {ENOTEMPTY, "Directory not empty"}, // 39 + {ELOOP, "Too many symbolic links encountered"}, // 40 + {EWOULDBLOCK, "Operation would block"}, // 41 + {ENOMSG, "No message of desired type"}, // 42 + {EIDRM, "Identifier removed"}, // 43 + {ECHRNG, "Channel number out of range"}, // 44 + {EL2NSYNC, "Level 2 not synchronized"}, // 45 + {EL3HLT, "Level 3 halted"}, // 46 + {EL3RST, "Level 3 reset"}, // 47 + {ELNRNG, "Link number out of range"}, // 48 + {EUNATCH, "Protocol driver not attached"}, // 49 + {ENOCSI, "No CSI structure available"}, // 50 + {EL2HLT, "Level 2 halted"}, // 51 + {EBADE, "Invalid exchange"}, // 52 + {EBADR, "Invalid request descriptor"}, // 53 + {EXFULL, "Exchange full"}, // 54 + {ENOANO, "No anode"}, // 55 + {EBADRQC, "Invalid request code"}, // 56 + {EBADSLT, "Invalid slot"}, // 57 + {EDEADLOCK, "dead lock/link"}, // 58 + {EBFONT, "Bad font file format"}, // 59 + {ENOSTR, "Device not a stream"}, // 60 + {ENODATA, "No data available"}, // 61 + {ETIME, "Timer expired"}, // 62 + {ENOSR, "Out of streams resources"}, // 63 + {ENONET, "Machine is not on the network"}, // 64 + {ENOPKG, "Package not installed"}, // 65 + {EREMOTE, "Object is remote"}, // 66 + {ENOLINK, "Link has been severed "}, // 67 + {EADV, "Advertise error"}, // 68 + {ESRMNT, "Srmount error"}, // 69 + {ECOMM, "Communication error on send"}, // 70 + {EPROTO, "Protocol error"}, // 71 + {EMULTIHOP, "Multihop attempted"}, // 72 + {EDOTDOT, "RFS specific error"}, // 73 + {EBADMSG, "Not a data message"}, // 74 + {EOVERFLOW, "Value too large for defined data type"}, // 75 + {ENOTUNIQ, "Name not unique on network "}, // 76 + {EBADFD, "File descriptor in bad state"}, // 77 + {EREMCHG, "Remote address changed "}, // 78 + {ELIBACC, "Can not access a needed shared library"}, //79 + {ELIBBAD, "Accessing a corrupted shared library"}, // 80 + {ELIBSCN, ".lib section in a.out corrupted"}, // 81 + {ELIBMAX, "Attempting to link in too many shared libraries"}, // 82 + {ELIBEXEC, "Cannot exec a shared library directly"}, // 83 + {EILSEQ, "Illegal byte sequence"}, // 84 + {ERESTART, "Interrupted system call should be restarted"}, // 85 + {ESTRPIPE, "Streams pipe error "}, // 86 + {EUSERS, "Too many users"}, // 87 + {ENOTSOCK, "Socket operation on non-socket"}, // 88 + {EDESTADDRREQ, "Destination address required"}, // 89 + {EMSGSIZE, "Message too long"}, // 90 + {EPROTOTYPE, "Protocol wrong type for socket"}, // 91 + {ENOPROTOOPT, "Protocol not available"}, // 92 + //{EPROTONOSUPPORT, "Protocol not supported"}, // 93 + {ESOCKTNOSUPPORT, "Socket type not supported"}, // 94 + {EOPNOTSUPP, "Operation not supported on transport endpoint"}, // 95 + {EPFNOSUPPORT, "Protocol family not supported"}, // 96 + {EAFNOSUPPORT, "Address family not supported by protocol"}, // 97 + {EADDRINUSE, "Address already in use"}, // 98 + {EADDRNOTAVAIL, "Cannot assign requested address"}, // 99 + {ENETDOWN, "Network is down"}, // 100 + {ENETUNREACH, "Network is unreachable"}, // 101 + {ENETRESET, "Network dropped connection because of reset"}, // 102 + {ECONNABORTED, "Software caused connection abort"}, // 103 + {ECONNRESET, "Connection reset by peer"}, // 104 + {ENOBUFS, "No buffer space available"}, // 105 + {EISCONN, "Transport endpoint is already connected"}, // 106 + {ENOTCONN, "Transport endpoint is not connected"}, // 107 + {ESHUTDOWN, "Cannot send after transport endpoint shutdown"}, // 108 + {ETOOMANYREFS, "Too many references: cannot splice"}, // 109 + //{ETIMEDOUT, "Connection timed out"}, // 110 + //{ECONNREFUSED, "Connection refused"}, // 111 + {EHOSTDOWN, "Host is down"}, // 112 + {EHOSTUNREACH, "No route to host"}, // 113 + {EALREADY, "Operation already in progress"}, // 114 + //{EINPROGRESS, "Operation now in progress"}, // 115 + {ESTALE, "Stale NFS file handle"}, // 116 + {EUCLEAN, "Structure needs cleaning"}, // 117 + {ENOTNAM, "Not a XENIX named type file"}, // 118 + {ENAVAIL, "No XENIX semaphores available"}, // 119 + {EISNAM, "Is a named type file"}, // 120 + {EREMOTEIO, "Remote I/O error"}, // 121 + {EDQUOT, "Quota exceeded"}, // 122 + {ENOMEDIUM, "No medium found"}, // 123 + {EMEDIUMTYPE, "Wrong medium type"} // 124 +}; + +/* --------------------------------------------------------------------------*/ +/** +* @brief codec_error_msg Convert codec type to error message +* +* @param[in] error Codec error type +* +* @return Error message string +*/ +/* --------------------------------------------------------------------------*/ +const char * codec_error_msg(int error) +{ + unsigned int i; + for (i = 0; i < (sizeof(codec_errno) / sizeof(codec_errors_t)); i ++) { + if (error == codec_errno[i].error_no) { + return codec_errno[i].buf; + } + } + return "invalid operate"; +} + +/* --------------------------------------------------------------------------*/ +/** +* @brief print_error_msg Print error message in uniform format +* +* @param[in] error Codec error type +* @param[in] errno Codec error number, define in error.h +* @param[in] func Function where error happens +* @param[in] line Line where error happens +*/ +/* --------------------------------------------------------------------------*/ +void print_error_msg(int error, int syserr, char *func, int line) +{ + CODEC_PRINT("Error=%x errno=%d : %s,func=%s,line=%d\n", error, syserr, codec_error_msg(syserr), func, line); +} + + diff --git a/amcodec/include/amports/aformat.h b/amcodec/include/amports/aformat.h new file mode 100644 index 0000000..a446cbd --- a/dev/null +++ b/amcodec/include/amports/aformat.h @@ -0,0 +1,114 @@ +/** +* @file aformat.h +* @brief Porting from decoder driver for audio format +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef AFORMAT_H +#define AFORMAT_H + +typedef enum { + AFORMAT_UNKNOWN = -1, + AFORMAT_MPEG = 0, + AFORMAT_PCM_S16LE = 1, + AFORMAT_AAC = 2, + AFORMAT_AC3 = 3, + AFORMAT_ALAW = 4, + AFORMAT_MULAW = 5, + AFORMAT_DTS = 6, + AFORMAT_PCM_S16BE = 7, + AFORMAT_FLAC = 8, + AFORMAT_COOK = 9, + AFORMAT_PCM_U8 = 10, + AFORMAT_ADPCM = 11, + AFORMAT_AMR = 12, + AFORMAT_RAAC = 13, + AFORMAT_WMA = 14, + AFORMAT_WMAPRO = 15, + AFORMAT_PCM_BLURAY = 16, + AFORMAT_ALAC = 17, + AFORMAT_VORBIS = 18, + AFORMAT_AAC_LATM = 19, + AFORMAT_APE = 20, + AFORMAT_EAC3 = 21, + AFORMAT_PCM_WIFIDISPLAY = 22, + AFORMAT_DRA = 23, + AFORMAT_SIPR = 24, + AFORMAT_TRUEHD = 25, + AFORMAT_MPEG1 = 26, //AFORMAT_MPEG-->mp3,AFORMAT_MPEG1-->mp1,AFROMAT_MPEG2-->mp2 + AFORMAT_MPEG2 = 27, + AFORMAT_WMAVOI = 28, + AFORMAT_WMALOSSLESS =29, + AFORMAT_PCM_S24LE = 30, + AFORMAT_UNSUPPORT , + AFORMAT_MAX + +} aformat_t; + +#define AUDIO_EXTRA_DATA_SIZE (4096) +#define IS_AFMT_VALID(afmt) ((afmt > AFORMAT_UNKNOWN) && (afmt < AFORMAT_MAX)) + +#define IS_AUIDO_NEED_EXT_INFO(afmt) ((afmt == AFORMAT_ADPCM) \ + ||(afmt == AFORMAT_WMA) \ + ||(afmt == AFORMAT_WMAPRO) \ + ||(afmt == AFORMAT_PCM_S16BE) \ + ||(afmt == AFORMAT_PCM_S16LE) \ + ||(afmt == AFORMAT_PCM_U8) \ + ||(afmt == AFORMAT_PCM_BLURAY) \ + ||(afmt == AFORMAT_AMR)\ + ||(afmt == AFORMAT_ALAC)\ + ||(afmt == AFORMAT_AC3) \ + ||(afmt == AFORMAT_EAC3) \ + ||(afmt == AFORMAT_APE) \ + ||(afmt == AFORMAT_FLAC)\ + ||(afmt == AFORMAT_PCM_WIFIDISPLAY) \ + ||(afmt == AFORMAT_COOK) \ + ||(afmt == AFORMAT_RAAC)) \ + ||(afmt == AFORMAT_TRUEHD) \ + ||(afmt == AFORMAT_WMAVOI) \ + ||(afmt == AFORMAT_WMALOSSLESS) + +#define IS_AUDIO_NOT_SUPPORT_EXCEED_2CH(afmt) ((afmt == AFORMAT_RAAC) \ + ||(afmt == AFORMAT_COOK) \ + /*||(afmt == AFORMAT_FLAC)*/) + +#define IS_AUDIO_NOT_SUPPORT_EXCEED_6CH(afmt) ((afmt == AFORMAT_WMAPRO)) +#define IS_AUDIO_NOT_SUPPORT_EXCEED_FS48k(afmt) ((afmt == AFORMAT_WMAPRO)) + + +#define IS_AUIDO_NEED_PREFEED_HEADER(afmt) ((afmt == AFORMAT_VORBIS) ) +#define IS_AUDIO_NOT_SUPPORTED_BY_AUDIODSP(afmt,codec) \ + ((afmt == AFORMAT_AAC_LATM || afmt == AFORMAT_AAC) \ + &&codec->profile == 0/* FF_PROFILE_AAC_MAIN*/) + +#define IS_SUB_NEED_PREFEED_HEADER(sfmt) ((sfmt == CODEC_ID_DVD_SUBTITLE) ) + +#endif /* AFORMAT_H */ + diff --git a/amcodec/include/amports/amstream.h b/amcodec/include/amports/amstream.h new file mode 100644 index 0000000..47c0e90 --- a/dev/null +++ b/amcodec/include/amports/amstream.h @@ -0,0 +1,418 @@ +/** +* @file amstream.h +* @brief Porting from decoder driver for codec ioctl commands +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef AMSTREAM_H +#define AMSTREAM_H + +#include "amports/vformat.h" +#include "amports/aformat.h" + +#define PORT_FLAG_IN_USE 0x0001 +#define PORT_FLAG_VFORMAT 0x0002 +#define PORT_FLAG_AFORMAT 0x0004 +#define PORT_FLAG_FORMAT (PORT_FLAG_VFORMAT | PORT_FLAG_AFORMAT) +#define PORT_FLAG_VID 0x0008 +#define PORT_FLAG_AID 0x0010 +#define PORT_FLAG_ID (PORT_FLAG_VID | PORT_FLAG_AID) +#define PORT_FLAG_INITED 0x100 + +#define PORT_TYPE_VIDEO 0x01 +#define PORT_TYPE_AUDIO 0x02 +#define PORT_TYPE_MPTS 0x04 +#define PORT_TYPE_MPPS 0x08 +#define PORT_TYPE_ES 0x10 +#define PORT_TYPE_RM 0x20 + +#define AMSTREAM_IOC_MAGIC 'S' +#define AMSTREAM_IOC_VB_START _IOW((AMSTREAM_IOC_MAGIC), 0x00, int) +#define AMSTREAM_IOC_VB_SIZE _IOW((AMSTREAM_IOC_MAGIC), 0x01, int) +#define AMSTREAM_IOC_AB_START _IOW((AMSTREAM_IOC_MAGIC), 0x02, int) +#define AMSTREAM_IOC_AB_SIZE _IOW((AMSTREAM_IOC_MAGIC), 0x03, int) +#define AMSTREAM_IOC_VFORMAT _IOW((AMSTREAM_IOC_MAGIC), 0x04, int) +#define AMSTREAM_IOC_AFORMAT _IOW((AMSTREAM_IOC_MAGIC), 0x05, int) +#define AMSTREAM_IOC_VID _IOW((AMSTREAM_IOC_MAGIC), 0x06, int) +#define AMSTREAM_IOC_AID _IOW((AMSTREAM_IOC_MAGIC), 0x07, int) +#define AMSTREAM_IOC_VB_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x08, int) +#define AMSTREAM_IOC_AB_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x09, int) +#define AMSTREAM_IOC_SYSINFO _IOW((AMSTREAM_IOC_MAGIC), 0x0a, int) +#define AMSTREAM_IOC_ACHANNEL _IOW((AMSTREAM_IOC_MAGIC), 0x0b, int) +#define AMSTREAM_IOC_SAMPLERATE _IOW((AMSTREAM_IOC_MAGIC), 0x0c, int) +#define AMSTREAM_IOC_DATAWIDTH _IOW((AMSTREAM_IOC_MAGIC), 0x0d, int) +#define AMSTREAM_IOC_TSTAMP _IOW((AMSTREAM_IOC_MAGIC), 0x0e, int) +#define AMSTREAM_IOC_VDECSTAT _IOR((AMSTREAM_IOC_MAGIC), 0x0f, int) +#define AMSTREAM_IOC_ADECSTAT _IOR((AMSTREAM_IOC_MAGIC), 0x10, int) + +#define AMSTREAM_IOC_PORT_INIT _IO((AMSTREAM_IOC_MAGIC), 0x11) +#define AMSTREAM_IOC_TRICKMODE _IOW((AMSTREAM_IOC_MAGIC), 0x12, int) + +#define AMSTREAM_IOC_AUDIO_INFO _IOW((AMSTREAM_IOC_MAGIC), 0x13, int) +#define AMSTREAM_IOC_TRICK_STAT _IOR((AMSTREAM_IOC_MAGIC), 0x14, int) +#define AMSTREAM_IOC_AUDIO_RESET _IO((AMSTREAM_IOC_MAGIC), 0x15) +#define AMSTREAM_IOC_SID _IOW((AMSTREAM_IOC_MAGIC), 0x16, int) +#define AMSTREAM_IOC_VPAUSE _IOW((AMSTREAM_IOC_MAGIC), 0x17, int) +#define AMSTREAM_IOC_AVTHRESH _IOW((AMSTREAM_IOC_MAGIC), 0x18, int) +#define AMSTREAM_IOC_SYNCTHRESH _IOW((AMSTREAM_IOC_MAGIC), 0x19, int) +#define AMSTREAM_IOC_SUB_RESET _IOW((AMSTREAM_IOC_MAGIC), 0x1a, int) +#define AMSTREAM_IOC_SUB_LENGTH _IOR((AMSTREAM_IOC_MAGIC), 0x1b, int) +#define AMSTREAM_IOC_SET_DEC_RESET _IOW((AMSTREAM_IOC_MAGIC), 0x1c, int) +#define AMSTREAM_IOC_TS_SKIPBYTE _IOW((AMSTREAM_IOC_MAGIC), 0x1d, int) +#define AMSTREAM_IOC_SUB_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x1e, int) +#define AMSTREAM_IOC_CLEAR_VIDEO _IOW((AMSTREAM_IOC_MAGIC), 0x1f, int) + +#define AMSTREAM_IOC_APTS _IOR((AMSTREAM_IOC_MAGIC), 0x40, int) +#define AMSTREAM_IOC_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0x41, int) +#define AMSTREAM_IOC_PCRSCR _IOR((AMSTREAM_IOC_MAGIC), 0x42, int) +#define AMSTREAM_IOC_SYNCENABLE _IOW((AMSTREAM_IOC_MAGIC), 0x43, int) +#define AMSTREAM_IOC_GET_SYNC_ADISCON _IOR((AMSTREAM_IOC_MAGIC), 0x44, int) +#define AMSTREAM_IOC_SET_SYNC_ADISCON _IOW((AMSTREAM_IOC_MAGIC), 0x45, int) +#define AMSTREAM_IOC_GET_SYNC_VDISCON _IOR((AMSTREAM_IOC_MAGIC), 0x46, int) +#define AMSTREAM_IOC_SET_SYNC_VDISCON _IOW((AMSTREAM_IOC_MAGIC), 0x47, int) +#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR((AMSTREAM_IOC_MAGIC), 0x48, int) +#define AMSTREAM_IOC_SET_VIDEO_DISABLE _IOW((AMSTREAM_IOC_MAGIC), 0x49, int) +#define AMSTREAM_IOC_SET_PCRSCR _IOW((AMSTREAM_IOC_MAGIC), 0x4a, int) +#define AMSTREAM_IOC_GET_VIDEO_AXIS _IOR((AMSTREAM_IOC_MAGIC), 0x4b, int) +#define AMSTREAM_IOC_SET_VIDEO_AXIS _IOW((AMSTREAM_IOC_MAGIC), 0x4c, int) +#define AMSTREAM_IOC_GET_VIDEO_CROP _IOR((AMSTREAM_IOC_MAGIC), 0x4d, int) +#define AMSTREAM_IOC_SET_VIDEO_CROP _IOW((AMSTREAM_IOC_MAGIC), 0x4e, int) +#define AMSTREAM_IOC_PCRID _IOW((AMSTREAM_IOC_MAGIC), 0x4f, int) + +/* VPP.3D IOCTL command list^M */ +#define AMSTREAM_IOC_SET_3D_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x3c, unsigned int) +#define AMSTREAM_IOC_GET_3D_TYPE _IOW((AMSTREAM_IOC_MAGIC), 0x3d, unsigned int) + +#define AMSTREAM_IOC_SUB_NUM _IOR((AMSTREAM_IOC_MAGIC), 0x50, int) +#define AMSTREAM_IOC_SUB_INFO _IOR((AMSTREAM_IOC_MAGIC), 0x51, int) +#define AMSTREAM_IOC_GET_BLACKOUT_POLICY _IOR((AMSTREAM_IOC_MAGIC), 0x52, int) +#define AMSTREAM_IOC_SET_BLACKOUT_POLICY _IOW((AMSTREAM_IOC_MAGIC), 0x53, int) +#define AMSTREAM_IOC_UD_LENGTH _IOR((AMSTREAM_IOC_MAGIC), 0x54, int) +#define AMSTREAM_IOC_UD_POC _IOR((AMSTREAM_IOC_MAGIC), 0x55, int) +#define AMSTREAM_IOC_GET_SCREEN_MODE _IOR((AMSTREAM_IOC_MAGIC), 0x58, int) +#define AMSTREAM_IOC_SET_SCREEN_MODE _IOW((AMSTREAM_IOC_MAGIC), 0x59, int) +#define AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT _IOR((AMSTREAM_IOC_MAGIC), 0x5a, int) +#define AMSTREAM_IOC_SET_VIDEO_DISCONTINUE_REPORT _IOW((AMSTREAM_IOC_MAGIC), 0x5b, int) +#define AMSTREAM_IOC_VF_STATUS _IOR((AMSTREAM_IOC_MAGIC), 0x60, int) +#define AMSTREAM_IOC_CLEAR_VBUF _IO((AMSTREAM_IOC_MAGIC), 0x80) + +#define AMSTREAM_IOC_APTS_LOOKUP _IOR((AMSTREAM_IOC_MAGIC), 0x81, int) +#define GET_FIRST_APTS_FLAG _IOR((AMSTREAM_IOC_MAGIC), 0x82, int) +#define AMSTREAM_IOC_GET_SYNC_ADISCON_DIFF _IOR((AMSTREAM_IOC_MAGIC), 0x83, int) +#define AMSTREAM_IOC_GET_SYNC_VDISCON_DIFF _IOR((AMSTREAM_IOC_MAGIC), 0x84, int) +#define AMSTREAM_IOC_SET_SYNC_ADISCON_DIFF _IOW((AMSTREAM_IOC_MAGIC), 0x85, int) +#define AMSTREAM_IOC_SET_SYNC_VDISCON_DIFF _IOW((AMSTREAM_IOC_MAGIC), 0x86, int) +#define AMSTREAM_IOC_GET_FREERUN_MODE _IOR((AMSTREAM_IOC_MAGIC), 0x87, int) +#define AMSTREAM_IOC_SET_FREERUN_MODE _IOW((AMSTREAM_IOC_MAGIC), 0x88, int) +#define AMSTREAM_IOC_SET_VSYNC_UPINT _IOW((AMSTREAM_IOC_MAGIC), 0x89, int) +#define AMSTREAM_IOC_GET_VSYNC_SLOW_FACTOR _IOW((AMSTREAM_IOC_MAGIC), 0x8a, int) +#define AMSTREAM_IOC_SET_VSYNC_SLOW_FACTOR _IOW((AMSTREAM_IOC_MAGIC), 0x8b, int) +#define AMSTREAM_IOC_SET_DEMUX _IOW((AMSTREAM_IOC_MAGIC), 0x90, int) +#define AMSTREAM_IOC_SET_DRMMODE _IOW((AMSTREAM_IOC_MAGIC), 0x91, int) +#define AMSTREAM_IOC_TSTAMP_uS64 _IOW((AMSTREAM_IOC_MAGIC), 0x95, int) + +#define AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS _IOW((AMSTREAM_IOC_MAGIC), 0xa0, int) +#define AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa1, int) +#define AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS _IOW((AMSTREAM_IOC_MAGIC), 0xa2, int) +#define AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa3, int) +#define AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa4, int) +#define AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS _IOR((AMSTREAM_IOC_MAGIC), 0xa5, int) +#define AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS _IOR((AMSTREAM_IOC_MAGIC), 0xa6, int) +#define AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS _IOR((AMSTREAM_IOC_MAGIC), 0xa7, int) +#define AMSTREAM_IOC_SET_APTS _IOW((AMSTREAM_IOC_MAGIC), 0xa8, int) +#define AMSTREAM_IOC_GET_LAST_CHECKIN_APTS _IOR((AMSTREAM_IOC_MAGIC), 0xa9, int) +#define AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xaa, int) +#define AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS _IOR((AMSTREAM_IOC_MAGIC), 0xab, int) +#define AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xac, int) +/* subtitle.c get/set subtitle info */ +#define AMSTREAM_IOC_GET_SUBTITLE_INFO _IOR((AMSTREAM_IOC_MAGIC), 0xad, int) +#define AMSTREAM_IOC_SET_SUBTITLE_INFO _IOW((AMSTREAM_IOC_MAGIC), 0xae, int) +#define AMSTREAM_IOC_SET_OMX_VPTS _IOW((AMSTREAM_IOC_MAGIC), 0xaf, int) +#define AMSTREAM_IOC_GET_OMX_VPTS _IOW((AMSTREAM_IOC_MAGIC), 0xb0, int) + +#define AMSTREAM_IOC_GET_TRICK_VPTS _IOR((AMSTREAM_IOC_MAGIC), 0xf0, int) +#define AMSTREAM_IOC_DISABLE_SLOW_SYNC _IOW((AMSTREAM_IOC_MAGIC), 0xf1, int) + +#define AMSTREAM_IOC_GET_AUDIO_CHECKIN_BITRATE_BPS _IOR(AMSTREAM_IOC_MAGIC, 0xf2, int) +#define AMSTREAM_IOC_GET_VIDEO_CHECKIN_BITRATE_BPS _IOR(AMSTREAM_IOC_MAGIC, 0xf3, int) + +#define AMSTREAM_IOC_GET_VERSION _IOR((AMSTREAM_IOC_MAGIC), 0xc0, int) +#define AMSTREAM_IOC_GET _IOWR((AMSTREAM_IOC_MAGIC), 0xc1, struct am_ioctl_parm) +#define AMSTREAM_IOC_SET _IOW((AMSTREAM_IOC_MAGIC), 0xc2, struct am_ioctl_parm) +#define AMSTREAM_IOC_GET_EX _IOWR((AMSTREAM_IOC_MAGIC), 0xc3, struct am_ioctl_parm_ex) +#define AMSTREAM_IOC_SET_EX _IOW((AMSTREAM_IOC_MAGIC), 0xc4, struct am_ioctl_parm_ex) +#define AMSTREAM_IOC_GET_PTR _IOWR((AMSTREAM_IOC_MAGIC), 0xc5, struct am_ioctl_parm_ptr) +#define AMSTREAM_IOC_SET_PTR _IOW((AMSTREAM_IOC_MAGIC), 0xc6, struct am_ioctl_parm_ptr) + +#define AMAUDIO_IOC_MAGIC 'A' +#define AMAUDIO_IOC_SET_RESAMPLE_ENA _IOW(AMAUDIO_IOC_MAGIC, 0x19, unsigned long) +#define AMAUDIO_IOC_GET_RESAMPLE_ENA _IOR(AMAUDIO_IOC_MAGIC, 0x1a, unsigned long) +#define AMAUDIO_IOC_SET_RESAMPLE_TYPE _IOW(AMAUDIO_IOC_MAGIC, 0x1b, unsigned long) +#define AMAUDIO_IOC_GET_RESAMPLE_TYPE _IOR(AMAUDIO_IOC_MAGIC, 0x1c, unsigned long) +#define AMAUDIO_IOC_SET_RESAMPLE_DELTA _IOW(AMAUDIO_IOC_MAGIC, 0x1d, unsigned long) + +struct buf_status { + int size; + int data_len; + int free_len; + unsigned int read_pointer; + unsigned int write_pointer; +}; + +/*struct vdec_status.status*/ +#define STAT_TIMER_INIT 0x01 +#define STAT_MC_LOAD 0x02 +#define STAT_ISR_REG 0x04 +#define STAT_VF_HOOK 0x08 +#define STAT_TIMER_ARM 0x10 +#define STAT_VDEC_RUN 0x20 +//-/*struct vdec_status.status on error*/ + +#define PARSER_FATAL_ERROR (0x10<<16) +#define DECODER_ERROR_VLC_DECODE_TBL (0x20<<16) +#define PARSER_ERROR_WRONG_HEAD_VER (0x40<<16) +#define PARSER_ERROR_WRONG_PACKAGE_SIZE (0x80<<16) +#define DECODER_FATAL_ERROR_SIZE_OVERFLOW (0x100<<16) +#define DECODER_FATAL_ERROR_UNKNOW (0x200<<16) +#define DECODER_FATAL_ERROR_NO_MEM (0x400<<16) + + +#define DECODER_ERROR_MASK (0xffff<<16) +struct vdec_status { + unsigned int width; + unsigned int height; + unsigned int fps; + unsigned int error_count; + unsigned int status; +}; + +struct adec_status { + unsigned int channels; + unsigned int sample_rate; + unsigned int resolution; + unsigned int error_count; + unsigned int status; +}; + +struct am_io_param { + union { + int data; + int id;//get bufstatus? //or others + }; + + int len; //buffer size; + + union { + char buf[1]; + struct buf_status status; + struct vdec_status vstatus; + struct adec_status astatus; + }; +}; +struct subtitle_info { + + unsigned char id; + + unsigned char width; + + unsigned char height; + + unsigned char type; +}; + +struct userdata_poc_info_t { + + unsigned int poc_info; + + unsigned int poc_number; +}; + +/******************************************************************* +* 0x100~~0x1FF : set cmd +* 0x200~~0x2FF : set ex cmd +* 0x300~~0x3FF : set ptr cmd +* 0x400~~0x7FF : set reserved cmd +* 0x800~~0x8FF : get cmd +* 0x900~~0x9FF : get ex cmd +* 0xA00~~0xAFF : get ptr cmd +* 0xBFF~~0xFFF : get reserved cmd +* 0xX00~~0xX5F : amstream cmd(X: cmd type) +* 0xX60~~0xXAF : video cmd(X: cmd type) +* 0xXAF~~0xXFF : reserved cmd(X: cmd type) +*******************************************************************/ +/* amstream set cmd */ +#define AMSTREAM_SET_VB_START 0x101 +#define AMSTREAM_SET_VB_SIZE 0x102 +#define AMSTREAM_SET_AB_START 0x103 +#define AMSTREAM_SET_AB_SIZE 0x104 +#define AMSTREAM_SET_VFORMAT 0x105 +#define AMSTREAM_SET_AFORMAT 0x106 +#define AMSTREAM_SET_VID 0x107 +#define AMSTREAM_SET_AID 0x108 +#define AMSTREAM_SET_SID 0x109 +#define AMSTREAM_SET_PCRID 0x10A +#define AMSTREAM_SET_ACHANNEL 0x10B +#define AMSTREAM_SET_SAMPLERATE 0x10C +#define AMSTREAM_SET_DATAWIDTH 0x10D +#define AMSTREAM_SET_TSTAMP 0x10E +#define AMSTREAM_SET_TSTAMP_US64 0x10F +#define AMSTREAM_SET_APTS 0x110 +#define AMSTREAM_PORT_INIT 0x111 +#define AMSTREAM_SET_TRICKMODE 0x112 /* amstream,video */ +#define AMSTREAM_AUDIO_RESET 0x013 +#define AMSTREAM_SUB_RESET 0x114 +#define AMSTREAM_DEC_RESET 0x115 +#define AMSTREAM_SET_TS_SKIPBYTE 0x116 +#define AMSTREAM_SET_SUB_TYPE 0x117 +#define AMSTREAM_SET_PCRSCR 0x118 +#define AMSTREAM_SET_DEMUX 0x119 +#define AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS 0x11A +#define AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS 0x11B +#define AMSTREAM_SET_DRMMODE 0x11C +/* video set cmd */ +#define AMSTREAM_SET_OMX_VPTS 0x160 +#define AMSTREAM_SET_VPAUSE 0x161 +#define AMSTREAM_SET_AVTHRESH 0x162 +#define AMSTREAM_SET_SYNCTHRESH 0x163 +#define AMSTREAM_SET_SYNCENABLE 0x164 +#define AMSTREAM_SET_SYNC_ADISCON 0x165 +#define AMSTREAM_SET_SYNC_VDISCON 0x166 +#define AMSTREAM_SET_SYNC_ADISCON_DIFF 0x167 +#define AMSTREAM_SET_SYNC_VDISCON_DIFF 0x168 +#define AMSTREAM_SET_VIDEO_DISABLE 0x169 +#define AMSTREAM_SET_VIDEO_DISCONTINUE_REPORT 0x16A +#define AMSTREAM_SET_SCREEN_MODE 0x16B +#define AMSTREAM_SET_BLACKOUT_POLICY 0x16C +#define AMSTREAM_CLEAR_VBUF 0x16D +#define AMSTREAM_SET_CLEAR_VIDEO 0x16E +#define AMSTREAM_SET_FREERUN_MODE 0x16F +#define AMSTREAM_SET_DISABLE_SLOW_SYNC 0x170 +#define AMSTREAM_SET_3D_TYPE 0x171 +#define AMSTREAM_SET_VSYNC_UPINT 0x172 +#define AMSTREAM_SET_VSYNC_SLOW_FACTOR 0x173 +#define AMSTREAM_SET_FRAME_BASE_PATH 0x174 +#define AMSTREAM_SET_EOS 0x175 + + +/* video set ex cmd */ +#define AMSTREAM_SET_EX_VIDEO_AXIS 0x260 +#define AMSTREAM_SET_EX_VIDEO_CROP 0x261 +/* amstream set ptr cmd */ +#define AMSTREAM_SET_PTR_AUDIO_INFO 0x300 + +/* amstream get cmd */ +#define AMSTREAM_GET_SUB_LENGTH 0x800 +#define AMSTREAM_GET_UD_LENGTH 0x801 +#define AMSTREAM_GET_APTS_LOOKUP 0x802 +#define AMSTREAM_GET_FIRST_APTS_FLAG 0x803 +#define AMSTREAM_GET_APTS 0x804 +#define AMSTREAM_GET_VPTS 0x805 +#define AMSTREAM_GET_PCRSCR 0x806 +#define AMSTREAM_GET_LAST_CHECKIN_APTS 0x807 +#define AMSTREAM_GET_LAST_CHECKIN_VPTS 0x808 +#define AMSTREAM_GET_LAST_CHECKOUT_APTS 0x809 +#define AMSTREAM_GET_LAST_CHECKOUT_VPTS 0x80A +#define AMSTREAM_GET_SUB_NUM 0x80B +#define AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS 0x80C +#define AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS 0x80D +#define AMSTREAM_GET_AUDIO_CUR_DELAY_MS 0x80E +#define AMSTREAM_GET_VIDEO_CUR_DELAY_MS 0x80F +#define AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS 0x810 +#define AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS 0x811 +/* video get cmd */ +#define AMSTREAM_GET_OMX_VPTS 0x860 +#define AMSTREAM_GET_TRICK_STAT 0x861 +#define AMSTREAM_GET_TRICK_VPTS 0x862 +#define AMSTREAM_GET_SYNC_ADISCON 0x863 +#define AMSTREAM_GET_SYNC_VDISCON 0x864 +#define AMSTREAM_GET_SYNC_ADISCON_DIFF 0x865 +#define AMSTREAM_GET_SYNC_VDISCON_DIFF 0x866 +#define AMSTREAM_GET_VIDEO_DISABLE 0x867 +#define AMSTREAM_GET_VIDEO_DISCONTINUE_REPORT 0x868 +#define AMSTREAM_GET_SCREEN_MODE 0x869 +#define AMSTREAM_GET_BLACKOUT_POLICY 0x86A +#define AMSTREAM_GET_FREERUN_MODE 0x86B +#define AMSTREAM_GET_3D_TYPE 0x86C +#define AMSTREAM_GET_VSYNC_SLOW_FACTOR 0x86D +/* amstream get ex cmd */ +#define AMSTREAM_GET_EX_VB_STATUS 0x900 +#define AMSTREAM_GET_EX_AB_STATUS 0x901 +#define AMSTREAM_GET_EX_VDECSTAT 0x902 +#define AMSTREAM_GET_EX_ADECSTAT 0x903 +#define AMSTREAM_GET_EX_UD_POC 0x904 +/* video get ex cmd */ +#define AMSTREAM_GET_EX_VF_STATUS 0x960 +#define AMSTREAM_GET_EX_VIDEO_AXIS 0x961 +#define AMSTREAM_GET_EX_VIDEO_CROP 0x962 +/* amstream get ptr cmd */ +#define AMSTREAM_GET_PTR_SUB_INFO 0xA00 + +struct am_ioctl_parm { + union { + unsigned int data_32; + unsigned long long data_64; + vformat_t data_vformat; + aformat_t data_aformat; + char data[8]; + }; + unsigned int cmd; + char reserved[4]; +}; + +struct am_ioctl_parm_ex { + union { + struct buf_status status; + struct vdec_status vstatus; + struct adec_status astatus; + + struct userdata_poc_info_t data_userdata_info; + char data[24]; + + }; + unsigned int cmd; + char reserved[4]; +}; + +struct am_ioctl_parm_ptr { + union { + struct audio_info *pdata_audio_info; + struct subtitle_info *pdata_sub_info; + void *pointer; + char data[8]; + }; + unsigned int cmd; + char reserved[4]; +}; + +void set_vdec_func(int (*vdec_func)(struct vdec_status *)); +void set_adec_func(int (*adec_func)(struct adec_status *)); + +#endif /* AMSTREAM_H */ + diff --git a/amcodec/include/amports/vformat.h b/amcodec/include/amports/vformat.h new file mode 100644 index 0000000..f12bdf8 --- a/dev/null +++ b/amcodec/include/amports/vformat.h @@ -0,0 +1,133 @@ +/** +* @file vformat.h +* @brief Porting from decoder driver for video format +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +/* + * AMLOGIC Audio/Video streaming port driver. + * + * 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 named License, + * or 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 + * + * Author: Tim Yao <timyao@amlogic.com> + * + */ + +#ifndef VFORMAT_H +#define VFORMAT_H + +typedef enum { + VIDEO_DEC_FORMAT_UNKNOW, + VIDEO_DEC_FORMAT_MPEG4_3, + VIDEO_DEC_FORMAT_MPEG4_4, + VIDEO_DEC_FORMAT_MPEG4_5, + VIDEO_DEC_FORMAT_H264, + VIDEO_DEC_FORMAT_MJPEG, + VIDEO_DEC_FORMAT_MP4, + VIDEO_DEC_FORMAT_H263, + VIDEO_DEC_FORMAT_REAL_8, + VIDEO_DEC_FORMAT_REAL_9, + VIDEO_DEC_FORMAT_WMV3, + VIDEO_DEC_FORMAT_WVC1, + VIDEO_DEC_FORMAT_SW, + VIDEO_DEC_FORMAT_AVS, + VIDEO_DEC_FORMAT_H264_4K2K, + VIDEO_DEC_FORMAT_HEVC, + VIDEO_DEC_FORMAT_VP9 , + VIDEO_DEC_FORMAT_MAX +} vdec_type_t; + +typedef enum { + VFORMAT_UNKNOWN = -1, + VFORMAT_MPEG12 = 0, + VFORMAT_MPEG4, + VFORMAT_H264, + VFORMAT_MJPEG, + VFORMAT_REAL, + VFORMAT_JPEG, + VFORMAT_VC1, + VFORMAT_AVS, + VFORMAT_SW, + VFORMAT_H264MVC, + VFORMAT_H264_4K2K, + VFORMAT_HEVC, + VFORMAT_H264_ENC, + VFORMAT_JPEG_ENC, + VFORMAT_VP9, + +/*add new here before.*/ + VFORMAT_MAX, + VFORMAT_UNSUPPORT = VFORMAT_MAX +} vformat_t; + +#define IS_VFMT_VALID(vfmt) ((vfmt > VFORMAT_UNKNOWN) && (vfmt < VFORMAT_MAX)) +#define IS_NEED_VDEC_INFO(vfmt) ((vfmt == VFORMAT_MPEG4) || (vfmt == VFORMAT_REAL)) + +#define CODEC_TAG_MJPEG (0x47504a4d) +#define CODEC_TAG_mjpeg (0x47504a4c) +#define CODEC_TAG_jpeg (0x6765706a) +#define CODEC_TAG_mjpa (0x61706a6d) +#define CODEC_TAG_XVID (0x44495658) +#define CODEC_TAG_xvid (0x64697678) +#define CODEC_TAG_XVIX (0x58495658) +#define CODEC_TAG_xvix (0x78697678) +#define CODEC_TAG_MP4 (0x8e22ada) +#define CODEC_TAG_COL1 (0x314c4f43) +#define CODEC_TAG_DIV3 (0x33564944) +#define CODEC_TAG_MP43 (0x3334504d) +#define CODEC_TAG_M4S2 (0x3253344d) +#define CODEC_TAG_DIV4 (0x34564944) +#define CODEC_TAG_divx (0x78766964) +#define CODEC_TAG_DIVX (0x58564944) +#define CODEC_TAG_DIV5 (0x35564944) +#define CODEC_TAG_3IV2 (0x32564933) +#define CODEC_TAG_3iv2 (0x32766933) +#define CODEC_TAG_DX50 (0x30355844) +#define CODEC_TAG_DIV6 (0x36564944) +#define CODEC_TAG_RMP4 (0x34504d52) +#define CODEC_TAG_MP42 (0x3234504d) +#define CODEC_TAG_MPG4 (0x3447504d) +#define CODEC_TAG_MP4V (0x5634504d) +#define CODEC_TAG_mp4v (0x7634706d) +#define CODEC_TAG_AVC1 (0x31435641) +#define CODEC_TAG_avc1 (0x31637661) +#define CODEC_TAG_H264 (0x34363248) +#define CODEC_TAG_h264 (0x34363268) +#define CODEC_TAG_HEVC (0x43564548) +#define CODEC_TAG_hvc1 (0x31637668) +#define CODEC_TAG_hev1 (0x31766568) +#define CODEC_TAG_H263 (0x33363248) +#define CODEC_TAG_h263 (0x33363268) +#define CODEC_TAG_s263 (0x33363273) +#define CODEC_TAG_F263 (0x33363246) +#define CODEC_TAG_WMV1 (0x31564d57) +#define CODEC_TAG_WMV2 (0x32564d57) +#define CODEC_TAG_WMV3 (0x33564d57) +#define CODEC_TAG_WVC1 (0x31435657) +#define CODEC_TAG_WMVA (0x41564d57) +#define CODEC_TAG_FMP4 (0x34504d46) +#define CODEC_TAG_FVFW (0x57465646) +#define CODEC_TAG_VC_1 (0x312d4356) +#define CODEC_TAG_vc_1 (0x312d6376) +#define CODEC_TAG_DVHE (0x65687664) +#define CODEC_TAG_DOVI (0x49564f44) + +#endif /* VFORMAT_H */ diff --git a/amcodec/include/audio_priv.h b/amcodec/include/audio_priv.h new file mode 100644 index 0000000..054fa69 --- a/dev/null +++ b/amcodec/include/audio_priv.h @@ -0,0 +1,18 @@ +/** +* @file audio_priv.h +* @brief Funtion prototypes of audio lib +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#ifndef CODEC_PRIV_H_ +#define CODEC_PRIV_H_ +void audio_start(void **priv, codec_para_t *pcodec); +void audio_stop(void **priv); +void audio_pause(void *priv); +void audio_resume(void *priv); +#endif diff --git a/amcodec/include/codec.h b/amcodec/include/codec.h new file mode 100644 index 0000000..404f10c --- a/dev/null +++ b/amcodec/include/codec.h @@ -0,0 +1,131 @@ +/** +* @file codec.h +* @brief Function prototypes of codec lib +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#ifndef CODEC_CTRL_H_ +#define CODEC_CTRL_H_ + +#include <codec_type.h> +#include <codec_error.h> + + +int codec_init(codec_para_t *); +int codec_close(codec_para_t *); +void codec_close_audio_async(codec_para_t *pcodec); +void codec_audio_basic_init(void); +void codec_close_audio(codec_para_t *); +void codec_resume_audio(codec_para_t *, unsigned int); +int codec_reset(codec_para_t *); +int codec_init_sub(codec_para_t *); +int codec_open_sub_read(void); +int codec_close_sub(codec_para_t *); +int codec_close_sub_fd(CODEC_HANDLE); +int codec_reset_subtile(codec_para_t *pcodec); +int codec_poll_sub(codec_para_t *); +int codec_poll_sub_fd(CODEC_HANDLE, int); +int codec_get_sub_size(codec_para_t *); +int codec_get_sub_size_fd(CODEC_HANDLE); +int codec_read_sub_data(codec_para_t *, char *, unsigned int); +int codec_read_sub_data_fd(CODEC_HANDLE, char *, unsigned int); +int codec_write_sub_data(codec_para_t *, char *, unsigned int); +int codec_init_cntl(codec_para_t *); +int codec_close_cntl(codec_para_t *); +int codec_poll_cntl(codec_para_t *); +int codec_get_cntl_state(codec_para_t *); +int codec_get_cntl_vpts(codec_para_t *pcodec); +int codec_set_cntl_mode(codec_para_t *, unsigned int); +int codec_set_mode(codec_para_t *, unsigned int); +int codec_set_cntl_avthresh(codec_para_t *, unsigned int); +int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh); +int codec_reset_audio(codec_para_t *pcodec); +int codec_set_audio_pid(codec_para_t *pcodec); +int codec_set_sub_id(codec_para_t *pcodec); +int codec_set_sub_type(codec_para_t *pcodec); +int codec_audio_reinit(codec_para_t *pcodec); +int codec_set_dec_reset(codec_para_t *pcodec); +int codec_set_eos(codec_para_t *pcodec, int is_eos); + +int codec_write(codec_para_t *pcodec, void *buffer, int len); +int codec_checkin_pts(codec_para_t *pcodec, unsigned long pts); +int codec_get_vbuf_state(codec_para_t *, struct buf_status *); +int codec_get_abuf_state(codec_para_t *, struct buf_status *); +int codec_get_vdec_state(codec_para_t *, struct vdec_status *); +int codec_get_adec_state(codec_para_t *, struct adec_status *); + +int codec_pause(codec_para_t *); +int codec_resume(codec_para_t *); +int codec_audio_search(codec_para_t *p); +int codec_set_mute(codec_para_t *p, int mute); +int codec_get_volume_range(codec_para_t *, int *min, int *max); +int codec_set_volume(codec_para_t *, float val); +int codec_get_volume(codec_para_t *, float *val); +int codec_set_lrvolume(codec_para_t *, float lvol, float rvol); +int codec_get_lrvolume(codec_para_t *, float *lvol, float* rvol); +int codec_get_mutesta(codec_para_t *); +int codec_set_volume_balance(codec_para_t *, int); /*left0-100)right*/ +int codec_swap_left_right(codec_para_t *); +int codec_left_mono(codec_para_t *p); +int codec_right_mono(codec_para_t *p); +int codec_stereo(codec_para_t *p); +int codec_lr_mix_set(codec_para_t *p, int enable); +int codec_get_soundtrack(codec_para_t *p, int* strack); +int codec_audio_automute(void *priv, int auto_mute); +int codec_audio_spectrum_switch(codec_para_t *p, int isStart, int interval); +int codec_audio_isready(codec_para_t *p); +int codec_audio_get_nb_frames(codec_para_t *p); +int codec_audio_set_audioinfo(codec_para_t *p); +int codec_pcmpara_Applied_get(codec_para_t *p, int *pfs, int *pch,int *lfepresent); + +int codec_get_apts(codec_para_t *pcodec); +int codec_get_vpts(codec_para_t *pcodec); +int codec_get_pcrscr(codec_para_t *pcodec); +int codec_set_pcrscr(codec_para_t *pcodec, int val); +int codec_set_syncenable(codec_para_t *pcodec, int enable); +int codec_set_sync_audio_discont(codec_para_t *pcodec, int discontinue); +int codec_get_sync_audio_discont(codec_para_t *pcodec); +int codec_set_sync_video_discont(codec_para_t *pcodec, int discontinue); +int codec_get_sync_video_discont(codec_para_t *pcodec); +unsigned long codec_get_sync_audio_discont_diff(codec_para_t *pcodec); +unsigned long codec_get_sync_video_discont_diff(codec_para_t *pcodec); +int codec_set_sync_audio_discont_diff(codec_para_t *pcodec, unsigned long discontinue_diff); +int codec_set_sync_video_discont_diff(codec_para_t *pcodec, unsigned long discontinue_diff); +int codec_get_sub_num(codec_para_t *pcodec); +int codec_get_sub_info(codec_para_t *pcodec, subtitle_info_t *sub_info); + +int codec_set_av_threshold(codec_para_t *pcodec, int threshold); + +int codec_get_freerun_mode(codec_para_t *pcodec); +int codec_set_freerun_mode(codec_para_t *pcodec, unsigned int mode); + +int codec_init_audio_utils(codec_para_t *pcodec); +int codec_release_audio_utils(codec_para_t *pcodec); +int codec_set_audio_resample_ena(codec_para_t *pcodec, unsigned long mode); +int codec_get_audio_resample_ena(codec_para_t *pcodec); +int codec_set_audio_resample_type(codec_para_t *pcodec, unsigned long type); + +int codec_set_video_delay_limited_ms(codec_para_t *pcodec, int delay_ms); +int codec_get_video_delay_limited_ms(codec_para_t *pcodec, int *delay_ms); +int codec_set_audio_delay_limited_ms(codec_para_t *pcodec, int delay_ms); +int codec_get_audio_delay_limited_ms(codec_para_t *pcodec, int *delay_ms); +int codec_get_audio_cur_delay_ms(codec_para_t *pcodec, int *delay_ms); +int codec_get_video_cur_delay_ms(codec_para_t *pcodec, int *delay_ms); +int codec_get_video_cur_bitrate(codec_para_t *pcodec, int *bitrate); +int codec_get_audio_cur_bitrate(codec_para_t *pcodec, int *bitrate); + +int codec_set_vsync_upint(codec_para_t *pcodec, unsigned int mode); + +int codec_get_last_checkout_apts(codec_para_t* pcodec, unsigned long *apts); +int codec_get_last_checkin_apts(codec_para_t* pcodec, unsigned long *apts); +int codec_disalbe_slowsync(codec_para_t *pcodec, int disable_slowsync); +int codec_utils_set_video_position(int x, int y, int w, int h, int rotation); +int codec_amsub_read_outdata(codec_para_t *pcodec,amsub_info_t *amsub_info); +void codec_close_subtitle(codec_para_t *pcodec); +void codec_resume_subtitle(codec_para_t *pcodec, unsigned int has_sub); +#endif diff --git a/amcodec/include/codec_error.h b/amcodec/include/codec_error.h new file mode 100644 index 0000000..fd78c5b --- a/dev/null +++ b/amcodec/include/codec_error.h @@ -0,0 +1,37 @@ +/** +* @file codec_error.h +* @brief Codec error type definitions +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#ifndef CODEC_ERROR_H_ +#define CODEC_ERROR_H_ + +#define C_PAE (0x01000000) + +#define CODEC_ERROR_NONE ( 0) +#define CODEC_ERROR_INVAL (C_PAE | 1) +#define CODEC_ERROR_NOMEM (C_PAE | 2) +#define CODEC_ERROR_BUSY (C_PAE | 3) +#define CODEC_ERROR_IO (C_PAE | 4) +#define CODEC_ERROR_PARAMETER (C_PAE | 5) +#define CODEC_ERROR_AUDIO_TYPE_UNKNOW (C_PAE | 6) +#define CODEC_ERROR_VIDEO_TYPE_UNKNOW (C_PAE | 7) +#define CODEC_ERROR_STREAM_TYPE_UNKNOW (C_PAE | 8) +#define CODEC_ERROR_VDEC_TYPE_UNKNOW (C_PAE | 9) + +#define CODEC_ERROR_INIT_FAILED (C_PAE | 10) +#define CODEC_ERROR_SET_BUFSIZE_FAILED (C_PAE | 11) +#define CODEC_OPEN_HANDLE_FAILED (C_PAE | 12) + + + + +#endif + diff --git a/amcodec/include/codec_msg.h b/amcodec/include/codec_msg.h new file mode 100644 index 0000000..121a874 --- a/dev/null +++ b/amcodec/include/codec_msg.h @@ -0,0 +1,19 @@ +/** +* @file codec_msg.h +* @brief Function prototype of codec error +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#ifndef CODEC_MSG_H +#define CODEC_MSG_H + +const char * codec_error_msg(int error); +int system_error_to_codec_error(int error); +void print_error_msg(int error, int syserr, char *func, int line); + +#endif diff --git a/amcodec/include/codec_type.h b/amcodec/include/codec_type.h new file mode 100644 index 0000000..44412e2 --- a/dev/null +++ b/amcodec/include/codec_type.h @@ -0,0 +1,174 @@ +/** +* @file codec_type.h +* @brief Definitions of codec type and structures +* @author Zhang Chen <chen.zhang@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ +#ifndef CODEC_TYPE_H_ +#define CODEC_TYPE_H_ + +#include "amports/amstream.h" +#include "amports/vformat.h" +#include "amports/aformat.h" +#include "ppmgr/ppmgr.h" +#include <stdlib.h> + +typedef int CODEC_HANDLE; + +typedef enum { + STREAM_TYPE_UNKNOW, + STREAM_TYPE_ES_VIDEO, + STREAM_TYPE_ES_AUDIO, + STREAM_TYPE_ES_SUB, + STREAM_TYPE_PS, + STREAM_TYPE_TS, + STREAM_TYPE_RM, +} stream_type_t; + +typedef struct { + unsigned int format; ///< video format, such as H264, MPEG2... + unsigned int width; ///< video source width + unsigned int height; ///< video source height + unsigned int rate; ///< video source frame duration + unsigned int extra; ///< extra data information of video stream + unsigned int status; ///< status of video stream + unsigned int ratio; ///< aspect ratio of video source + void * param; ///< other parameters for video decoder + unsigned long long ratio64; ///< aspect ratio of video source +} dec_sysinfo_t; + +typedef struct { + int valid; ///< audio extradata valid(1) or invalid(0), set by dsp + int sample_rate; ///< audio stream sample rate + int channels; ///< audio stream channels + int bitrate; ///< audio stream bit rate + int codec_id; ///< codec format id + int block_align; ///< audio block align from ffmpeg + int extradata_size; ///< extra data size + char extradata[AUDIO_EXTRA_DATA_SIZE];; ///< extra data information for decoder +} audio_info_t; + +typedef struct { + int valid; ///< audio extradata valid(1) or invalid(0), set by dsp + int sample_rate; ///< audio stream sample rate + int channels; ///< audio stream channels + int bitrate; ///< audio stream bit rate + int codec_id; ///< codec format id + int block_align; ///< audio block align from ffmpeg + int extradata_size; ///< extra data size + char extradata[512];; ///< extra data information for decoder +} Asf_audio_info_t; + +typedef struct { + CODEC_HANDLE handle; ///< codec device handler + CODEC_HANDLE cntl_handle; ///< video control device handler + CODEC_HANDLE sub_handle; ///< subtile device handler + CODEC_HANDLE audio_utils_handle; ///< audio utils handler + stream_type_t stream_type; ///< stream type(es, ps, rm, ts) +unsigned int has_video: + 1; ///< stream has video(1) or not(0) +unsigned int has_audio: + 1; ///< stream has audio(1) or not(0) +unsigned int has_sub: + 1; ///< stream has subtitle(1) or not(0) +unsigned int noblock: + 1; ///< codec device is NONBLOCK(1) or not(0) +unsigned int dv_enable: + 1; ///< videois dv data. + + int video_type; ///< stream video type(H264, VC1...) + int audio_type; ///< stream audio type(PCM, WMA...) + int sub_type; ///< stream subtitle type(TXT, SSA...) + int video_pid; ///< stream video pid + int audio_pid; ///< stream audio pid + int sub_pid; ///< stream subtitle pid + int audio_channels; ///< stream audio channel number + int audio_samplerate; ///< steram audio sample rate + int vbuf_size; ///< video buffer size of codec device + int abuf_size; ///< audio buffer size of codec device + dec_sysinfo_t am_sysinfo; ///< system information for video + audio_info_t audio_info; ///< audio information pass to audiodsp + int packet_size; ///< data size per packet + int avsync_threshold; ///<for adec in ms> + void * adec_priv; ///<for adec> + void * amsub_priv; // <for amsub> + int SessionID; + int dspdec_not_supported;//check some profile that audiodsp decoder can not support,we switch to arm decoder + int switch_audio_flag; //<switch audio flag switching(1) else(0) + int automute_flag; + char *sub_filename; + int associate_dec_supported;//support associate or not + int mixing_level; + unsigned int drmmode; +} codec_para_t; + +typedef struct { + signed char id; + unsigned char width; + unsigned char height; + unsigned char type; +} subtitle_info_t; +#define MAX_SUB_NUM (32) + +#define IS_VALID_PID(t) (t>=0 && t<=0x1fff) +#define IS_VALID_STREAM(t) (t>0 && t<=0x1fff) +#define IS_VALID_ATYPE(t) (t>=0 && t<AFORMAT_MAX) +#define IS_VALID_VTYPE(t) (t>=0 && t<VFORMAT_MAX) + +//pass to arm audio decoder +typedef struct { + int sample_rate; ///< audio stream sample rate + int channels; ///< audio stream channels + int format; ///< codec format id + int bitrate; + int block_align; + int codec_id; //original codecid corespingding to ffmepg + int handle; ///< codec device handler + int extradata_size; ///< extra data size + char extradata[AUDIO_EXTRA_DATA_SIZE]; + int SessionID; + int dspdec_not_supported;//check some profile that audiodsp decoder can not support,we switch to arm decoder + int droppcm_flag; // drop pcm flag, if switch audio (1) + int automute; + unsigned int has_video; + int associate_dec_supported;//support associate or not + int mixing_level; +} arm_audio_info; + + +typedef struct { + int sub_type; + int sub_pid; + int stream_type; // to judge sub how to get data + char *sub_filename; + unsigned int curr_timeMs; //for idx+sub + unsigned int next_pts; //for idx+sub + + unsigned int pts; + unsigned int m_delay; + unsigned short sub_start_x; + unsigned short sub_start_y; + unsigned short sub_width; + unsigned short sub_height; + char * odata; // point to decoder data + unsigned buffer_size; +} amsub_info_t; + +//audio decoder type, default arc +#define AUDIO_ARC_DECODER 0 +#define AUDIO_ARM_DECODER 1 +#define AUDIO_FFMPEG_DECODER 2 +#define AUDIO_ARMWFD_DECODER 3 + +int codec_set_drmmode(codec_para_t *pcodec, unsigned int setval); +int codec_get_video_checkin_bitrate(codec_para_t *pcodec, int *bitrate); +int codec_get_audio_checkin_bitrate(codec_para_t *pcodec, int *bitrate); +int codec_set_skip_bytes(codec_para_t* pcodec, unsigned int bytes); +int codec_get_dsp_apts(codec_para_t* pcodec, unsigned int * apts); +int codec_get_pcm_level(codec_para_t* pcodec, unsigned int* level); +#endif diff --git a/amcodec/include/ppmgr/ppmgr.h b/amcodec/include/ppmgr/ppmgr.h new file mode 100644 index 0000000..b166297 --- a/dev/null +++ b/amcodec/include/ppmgr/ppmgr.h @@ -0,0 +1,24 @@ +/** +* @file ppmgr.h +* @brief Porting from ppmgr driver for codec ioctl commands +* @author Tim Yao <timyao@amlogic.com> +* @version 1.0.0 +* @date 2011-02-24 +*/ +/* Copyright (C) 2007-2011, Amlogic Inc. +* All right reserved +* +*/ + +#ifndef PPMGR_H +#define PPMGR_H + +#define PPMGR_IOC_MAGIC 'P' +//#define PPMGR_IOC_2OSD0 _IOW(PPMGR_IOC_MAGIC, 0x00, unsigned int) +//#define PPMGR_IOC_ENABLE_PP _IOW(PPMGR_IOC_MAGIC,0X01,unsigned int) +//#define PPMGR_IOC_CONFIG_FRAME _IOW(PPMGR_IOC_MAGIC,0X02,unsigned int) +#define PPMGR_IOC_GET_ANGLE _IOR(PPMGR_IOC_MAGIC,0X03,unsigned long) +#define PPMGR_IOC_SET_ANGLE _IOW(PPMGR_IOC_MAGIC,0X04,unsigned long) + +#endif /* PPMGR_H */ + diff --git a/amvdec/Android.mk b/amvdec/Android.mk new file mode 100644 index 0000000..0edee59 --- a/dev/null +++ b/amvdec/Android.mk @@ -0,0 +1,57 @@ + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.c)) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/../amavutils/include \ + $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libmedia \ + libz \ + libbinder \ + libcutils \ + libc \ + libamavutils \ + liblog + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamvdec +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.c)) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/../amavutils/include \ + $(JNI_H_INCLUDE) + + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libmedia \ + libz \ + libbinder \ + libcutils \ + libc \ + libamavutils \ + liblog + +#LOCAL_SHARED_LIBRARIES += libandroid_runtime libnativehelper + +LOCAL_MODULE := libamvdec +LOCAL_MODULE_TAGS := optional +LOCAL_ARM_MODE := arm +LOCAL_PRELINK_MODULE := false +include $(BUILD_SHARED_LIBRARY) diff --git a/amvdec/amlv4l.c b/amvdec/amlv4l.c new file mode 100644 index 0000000..5589f44 --- a/dev/null +++ b/amvdec/amlv4l.c @@ -0,0 +1,219 @@ +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include "amlv4l.h" +#include "amvdec_priv.h" +#define V4LDEVICE_NAME "/dev/video10" + +static int amlv4l_unmapbufs(amvideo_dev_t *dev); +static int amlv4l_mapbufs(amvideo_dev_t *dev); +int amlv4l_setfmt(amvideo_dev_t *dev, struct v4l2_format *fmt); +int amlv4l_stop(amvideo_dev_t *dev); +int amlv4l_release(amvideo_dev_t *dev); +int amlv4l_init(amvideo_dev_t *dev, int type, int width, int height, int fmt) +{ + int ret; + amlv4l_dev_t *v4l = dev->devpriv; + struct v4l2_format v4lfmt; + ret = open(V4LDEVICE_NAME, O_RDWR | O_NONBLOCK); + if (ret < 0) { + LOGE("v4l device opend failed!,ret=%d,%s(%d)\n", ret, strerror(errno), errno); + return errno; + } + v4l->v4l_fd = ret; + v4l->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l->width = width; + v4l->height = height; + v4l->pixformat = fmt; + v4lfmt.type = v4l->type; + v4lfmt.fmt.pix.width = v4l->width; + v4lfmt.fmt.pix.height = v4l->height; + v4lfmt.fmt.pix.pixelformat = v4l->pixformat; + ret = amlv4l_setfmt(dev, &v4lfmt); + if (ret != 0) { + goto error_out; + } + ret = amlv4l_mapbufs(dev); +error_out: + return ret; +} + +static int amlv4l_ioctl(amvideo_dev_t *dev, int request, void *arg) +{ + int ret; + amlv4l_dev_t *v4l = dev->devpriv; + ret = ioctl(v4l->v4l_fd, request, arg); + if (ret == -1 && errno) { + LOGE("amlv4l_ioctlfailed!,request=%x,ret=%d,%s(%d)\n", request, ret, strerror(errno), errno); + ret = -errno; + } + return ret; +} + +int amlv4l_release(amvideo_dev_t *dev) +{ + int ret = -1; + amlv4l_dev_t *v4l = dev->devpriv; + if (v4l->v4l_fd < 0) { + return 0; + } + amlv4l_stop(dev); + amlv4l_unmapbufs(dev); + if (v4l->v4l_fd >= 0) { + ret = close(v4l->v4l_fd); + } + v4l->v4l_fd = -1; + free(dev); + if (ret == -1 && errno) { + ret = -errno; + } + + return ret; +} + +int amlv4l_dequeue_buf(amvideo_dev_t *dev, vframebuf_t *vf) +{ + struct v4l2_buffer vbuf; + int ret; + amlv4l_dev_t *v4l = dev->devpriv; + vbuf.type = v4l->type; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = v4l->bufferNum; + ret = amlv4l_ioctl(dev, VIDIOC_DQBUF, &vbuf); + if (!ret && vbuf.index < v4l->bufferNum) { + memcpy(vf, &v4l->vframe[vbuf.index], sizeof(vframebuf_t)); + } + return ret; +} + +int amlv4l_queue_buf(amvideo_dev_t *dev, vframebuf_t *vf) +{ + struct v4l2_buffer vbuf; + int ret; + amlv4l_dev_t *v4l = dev->devpriv; + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = vf->index; + return amlv4l_ioctl(dev, VIDIOC_QBUF, &vbuf); +} + +int amlv4l_start(amvideo_dev_t *dev) +{ + int type; + amlv4l_dev_t *v4l = dev->devpriv; + type = v4l->type; + return amlv4l_ioctl(dev, VIDIOC_STREAMON, &type); +} + +int amlv4l_stop(amvideo_dev_t *dev) +{ + int type; + amlv4l_dev_t *v4l = dev->devpriv; + type = v4l->type; + return amlv4l_ioctl(dev, VIDIOC_STREAMOFF, &type); +} + + +int amlv4l_setfmt(amvideo_dev_t *dev, struct v4l2_format *fmt) +{ + return amlv4l_ioctl(dev, VIDIOC_S_FMT, fmt); +} + + +static int amlv4l_unmapbufs(amvideo_dev_t *dev) +{ + int i, ret; + amlv4l_dev_t *v4l = dev->devpriv; + vframebuf_t *vf = v4l->vframe; + ret = 0; + if (!vf) { + return 0; + } + for (i = 0; i < v4l->bufferNum; i++) { + if (vf[i].vbuf == NULL || vf[i].vbuf == MAP_FAILED) { + continue; + } + ret = munmap(vf[i].vbuf, vf[i].length); + vf[i].vbuf = NULL; + } + free(v4l->vframe); + v4l->vframe = NULL; + return ret; +} + +static int amlv4l_mapbufs(amvideo_dev_t *dev) +{ + struct v4l2_buffer vbuf; + int ret; + int i; + amlv4l_dev_t *v4l = dev->devpriv; + vframebuf_t *vf; + struct v4l2_requestbuffers req; + + req.count = 4; + req.type = v4l->type;; + req.memory = v4l->memory_mode; ; + ret = amlv4l_ioctl(dev, VIDIOC_REQBUFS, &req); + if (ret != 0) { + LOGE("VIDIOC_REQBUFS failed,ret=%d\n", ret); + return ret; + } + v4l->bufferNum = req.count; + vf = (vframebuf_t *)malloc(sizeof(vframebuf_t) * req.count); + if (!vf) { + goto errors_out; + } + v4l->vframe = vf; + vbuf.type = v4l->type; + vbuf.memory = v4l->memory_mode; + for (i = 0; i < v4l->bufferNum; i++) { + vbuf.index = i; + ret = amlv4l_ioctl(dev, VIDIOC_QUERYBUF, &vbuf); + if (ret < 0) { + LOGE("VIDIOC_QUERYBUF,ret=%d\n", ret); + goto errors_out; + } + + vf[i].index = i; + vf[i].offset = vbuf.m.offset; + vf[i].pts = 0; + vf[i].duration = 0; + vf[i].vbuf = mmap(NULL, vbuf.length, PROT_READ | PROT_WRITE, MAP_SHARED, v4l->v4l_fd, vbuf.m.offset); + if (vf[i].vbuf == NULL || vf[i].vbuf == MAP_FAILED) { + LOGE("mmap failed,index=%d,ret=%p, errstr=%s\n", i, vf[i].vbuf, strerror(errno)); + ret = -errno; + goto errors_out; + } + vf[i].length = vbuf.length; + LOGI("mmaped buf %d,off=%d,vbuf=%p,len=%d\n", vf[i].index, vf[i].offset, vf[i].vbuf, vf[i].length); + } + LOGI("mmap ok,bufnum=%d\n", i); + return 0; +errors_out: + amlv4l_unmapbufs(dev); + return ret; +} + +amvideo_dev_t *new_amlv4l(void) +{ + //... + amvideo_dev_t *dev; + amlv4l_dev_t *v4l; + dev = malloc(sizeof(amvideo_dev_t) + sizeof(amlv4l_dev_t)); + memset(dev, 0, sizeof(amvideo_dev_t) + sizeof(amlv4l_dev_t)); + dev->devpriv = (void *)((unsigned long)(&dev->devpriv) + 4); + v4l = dev->devpriv; + v4l->memory_mode = V4L2_MEMORY_MMAP; + dev->ops.init = amlv4l_init; + dev->ops.release = amlv4l_release; + dev->ops.dequeuebuf = amlv4l_dequeue_buf; + dev->ops.queuebuf = amlv4l_queue_buf; + dev->ops.start = amlv4l_start; + dev->ops.stop = amlv4l_stop; + /**/ + return dev; +} + diff --git a/amvdec/amlv4l.h b/amvdec/amlv4l.h new file mode 100644 index 0000000..279a3fd --- a/dev/null +++ b/amvdec/amlv4l.h @@ -0,0 +1,18 @@ +#ifndef AMLV4L_HEAD_A__ +#define AMLV4L_HEAD_A__ +#include <amvideo.h> + +typedef struct amlv4l_dev { + int v4l_fd; + unsigned int bufferNum; + vframebuf_t *vframe; + int type; + int width; + int height; + int pixformat; + int memory_mode; +} amlv4l_dev_t; +amvideo_dev_t *new_amlv4l(void); +int amlv4l_release(amvideo_dev_t *dev); + +#endif//AMLV4L_HEAD_A__
\ No newline at end of file diff --git a/amvdec/amvdec_priv.h b/amvdec/amvdec_priv.h new file mode 100644 index 0000000..e242610 --- a/dev/null +++ b/amvdec/amvdec_priv.h @@ -0,0 +1,17 @@ +#ifndef AMVDEC_PRIV_HEADER__ +#define AMVDEC_PRIV_HEADER__ + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <linux/videodev2.h> +#include <android/log.h> + +#define TAG "amvdec" +#define XLOG(V,T,...) __android_log_print(V,T,__VA_ARGS__) +#define LOGI(...) XLOG(ANDROID_LOG_INFO,TAG,__VA_ARGS__) +#define LOGE(...) XLOG(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) + + +#endif diff --git a/amvdec/amvideo.c b/amvdec/amvideo.c new file mode 100644 index 0000000..3aaa469 --- a/dev/null +++ b/amvdec/amvideo.c @@ -0,0 +1,70 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <amvideo.h> +#include <Amavutils.h> +#include "amvdec_priv.h" +#include "amlv4l.h" + + +amvideo_dev_t *new_amvideo(int flags) +{ + amvideo_dev_t *dev = NULL; + if (flags & FLAGS_V4L_MODE) { + dev = new_amlv4l(); + if (!dev) { + LOGE("alloc v4l devices failed.\n"); + } else { + dev->mode = FLAGS_V4L_MODE; + } + } + return dev; +} +int amvideo_setparameters(amvideo_dev_t *dev, int cmd, void * parameters) +{ + return 0; +} +int amvideo_init(amvideo_dev_t *dev, int flags, int width, int height, int fmt) +{ + int ret = -1; + if (dev->ops.init) { + ret = dev->ops.init(dev, O_RDWR | O_NONBLOCK, width, height, fmt); + LOGE("amvideo_init ret=%d\n", ret); + } + return ret; +} +int amvideo_start(amvideo_dev_t *dev) +{ + if (dev->ops.start) { + return dev->ops.start(dev); + } + return 0; +} +int amvideo_stop(amvideo_dev_t *dev) +{ + if (dev->ops.stop) { + return dev->ops.stop(dev); + } + return 0; +} +int amvideo_release(amvideo_dev_t *dev) +{ + if (dev->mode == FLAGS_V4L_MODE) { + amlv4l_release(dev); + } + return 0; +} +int amlv4l_dequeuebuf(amvideo_dev_t *dev, vframebuf_t*vf) +{ + if (dev->ops.dequeuebuf) { + return dev->ops.dequeuebuf(dev, vf); + } + return -1; +} +int amlv4l_queuebuf(amvideo_dev_t *dev, vframebuf_t*vf) +{ + if (dev->ops.queuebuf) { + return dev->ops.queuebuf(dev, vf); + } + return 0; +} diff --git a/amvdec/include/amvideo.h b/amvdec/include/amvideo.h new file mode 100644 index 0000000..1b5f8af --- a/dev/null +++ b/amvdec/include/amvideo.h @@ -0,0 +1,50 @@ +#ifndef AMVDEC_AMVIDEO_HEADER_SS +#define AMVDEC_AMVIDEO_HEADER_SS +#include <stdlib.h> +#include <linux/videodev2.h> +#define FLAGS_OVERLAY_MODE (1) +#define FLAGS_V4L_MODE (2) + + +struct amvideo_dev; +typedef struct vframebuf { + char * vbuf; + int index; + int offset; + int length; + int64_t pts; + int duration; +} vframebuf_t; + +struct amvideo_dev_ops { + int (*setparameters)(struct amvideo_dev *dev, int cmd, void*para); + int (*init)(struct amvideo_dev *dev, int flags, int width, int height, int fmt); + int (*release)(struct amvideo_dev *dev); + int (*dequeuebuf)(struct amvideo_dev *dev, vframebuf_t*vf); + int (*queuebuf)(struct amvideo_dev *dev, vframebuf_t*vf); + int (*start)(struct amvideo_dev *dev); + int (*stop)(struct amvideo_dev *dev); +}; + +typedef struct amvideo_dev { + char devname[8]; + int mode; + struct amvideo_dev_ops ops; + void *devpriv; +} amvideo_dev_t; + + +typedef struct amvideo { + amvideo_dev_t *dev; +} amvideo_t; + + +amvideo_dev_t *new_amvideo(int flags); +int amvideo_setparameters(amvideo_dev_t *dev, int cmd, void * parameters); +int amvideo_init(amvideo_dev_t *dev, int flags, int width, int height, int fmt); +int amvideo_start(amvideo_dev_t *dev); +int amvideo_stop(amvideo_dev_t *dev); +int amvideo_release(amvideo_dev_t *dev); +int amlv4l_dequeuebuf(amvideo_dev_t *dev, vframebuf_t*vf); +int amlv4l_queuebuf(amvideo_dev_t *dev, vframebuf_t*vf); +#endif diff --git a/amvdec/include/ionvideo.h b/amvdec/include/ionvideo.h new file mode 100644 index 0000000..4ff2908 --- a/dev/null +++ b/amvdec/include/ionvideo.h @@ -0,0 +1,51 @@ +#ifndef IONVDEC_AMVIDEO_HEADER_SS +#define IONVDEC_AMVIDEO_HEADER_SS +#include <stdlib.h> +//#include <linux/videodev2.h> +#include "videodev2.h" +#define FLAGS_OVERLAY_MODE (1) +#define FLAGS_V4L_MODE (2) + +struct ionvideo_dev; +typedef struct vframebuf { + char * vbuf; + int fd; + int index; + int offset; + int length; + int64_t pts; + int duration; +} vframebuf_t; + +struct ionvideo_dev_ops { + int (*setparameters)(struct ionvideo_dev *dev, int cmd, void*para); + int (*getparameters)(struct ionvideo_dev *dev, struct v4l2_format *fmt); + int (*init)(struct ionvideo_dev *dev, int flags, int width, int height, int fmt, int buffernum); + int (*release)(struct ionvideo_dev *dev); + int (*dequeuebuf)(struct ionvideo_dev *dev, vframebuf_t*vf); + int (*queuebuf)(struct ionvideo_dev *dev, vframebuf_t*vf); + int (*start)(struct ionvideo_dev *dev); + int (*stop)(struct ionvideo_dev *dev); +}; + +typedef struct ionvideo_dev { + char devname[8]; + int mode; + struct ionvideo_dev_ops ops; + void *devpriv; +} ionvideo_dev_t; + +typedef struct ionvideo { + ionvideo_dev_t *dev; +} ionvideo_t; + +ionvideo_dev_t *new_ionvideo(int flags); +int ionvideo_setparameters(ionvideo_dev_t *dev, int cmd, void * parameters); +int ionvideo_getparameters(ionvideo_dev_t *dev, int *width, int *height, int *pixelformat); +int ionvideo_init(ionvideo_dev_t *dev, int flags, int width, int height, int fmt, int buffernum); +int ionvideo_start(ionvideo_dev_t *dev); +int ionvideo_stop(ionvideo_dev_t *dev); +int ionvideo_release(ionvideo_dev_t *dev); +int ionv4l_dequeuebuf(ionvideo_dev_t *dev, vframebuf_t*vf); +int ionv4l_queuebuf(ionvideo_dev_t *dev, vframebuf_t*vf); +#endif diff --git a/amvdec/include/v4l2-common.h b/amvdec/include/v4l2-common.h new file mode 100644 index 0000000..7194171 --- a/dev/null +++ b/amvdec/include/v4l2-common.h @@ -0,0 +1,71 @@ +/* + * include/linux/v4l2-common.h + * + * Common V4L2 and V4L2 subdev definitions. + * + * Users are advised to #include this file either through videodev2.h + * (V4L2) or through v4l2-subdev.h (V4L2 subdev) rather than to refer + * to this file directly. + * + * Copyright (C) 2012 Nokia Corporation + * Contact: Sakari Ailus <sakari.ailus@iki.fi> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __V4L2_COMMON__ +#define __V4L2_COMMON__ + +/* + * + * Selection interface definitions + * + */ + +/* Current cropping area */ +#define V4L2_SEL_TGT_CROP 0x0000 +/* Default cropping area */ +#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 +/* Cropping bounds */ +#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 +/* Current composing area */ +#define V4L2_SEL_TGT_COMPOSE 0x0100 +/* Default composing area */ +#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 +/* Composing bounds */ +#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 +/* Current composing area plus all padding pixels */ +#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 + +/* Backward compatibility target definitions --- to be removed. */ +#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP +#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE +#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE +#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS + +/* Selection flags */ +#define V4L2_SEL_FLAG_GE (1 << 0) +#define V4L2_SEL_FLAG_LE (1 << 1) +#define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2) + +/* Backward compatibility flag definitions --- to be removed. */ +#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE +#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE +#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG + +#endif /* __V4L2_COMMON__ */ diff --git a/amvdec/include/v4l2-controls.h b/amvdec/include/v4l2-controls.h new file mode 100644 index 0000000..17948a2 --- a/dev/null +++ b/amvdec/include/v4l2-controls.h @@ -0,0 +1,803 @@ +/* + * Video for Linux Two controls header file + * + * Copyright (C) 1999-2012 the contributors + * + * 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. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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. + * + * The contents of this header was split off from videodev2.h. All control + * definitions should be added to this header, which is included by + * videodev2.h. + */ + +#ifndef __LINUX_V4L2_CONTROLS_H +#define __LINUX_V4L2_CONTROLS_H + +/* Control classes */ +#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ +#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ +#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ +#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ +#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ +#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */ +#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */ +#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */ + +/* User-class control IDs */ + +#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) + +/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) +#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, + V4L2_COLORFX_NEGATIVE = 3, + V4L2_COLORFX_EMBOSS = 4, + V4L2_COLORFX_SKETCH = 5, + V4L2_COLORFX_SKY_BLUE = 6, + V4L2_COLORFX_GRASS_GREEN = 7, + V4L2_COLORFX_SKIN_WHITEN = 8, + V4L2_COLORFX_VIVID = 9, + V4L2_COLORFX_AQUA = 10, + V4L2_COLORFX_ART_FREEZE = 11, + V4L2_COLORFX_SILHOUETTE = 12, + V4L2_COLORFX_SOLARIZATION = 13, + V4L2_COLORFX_ANTIQUE = 14, + V4L2_COLORFX_SET_CBCR = 15, +}; +#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) + +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) + +#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) + +#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) +#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) + +#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) +#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) + +#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) +#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43) + + +/* MPEG-class control IDs */ + +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) + +/* MPEG streams, specific to multiplexed streams */ +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +enum v4l2_mpeg_stream_type { + V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ +}; +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +enum v4l2_mpeg_stream_vbi_fmt { + V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ + V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ +}; + +/* MPEG audio controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +enum v4l2_mpeg_audio_sampling_freq { + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +enum v4l2_mpeg_audio_encoding { + V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, +}; +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +enum v4l2_mpeg_audio_l1_bitrate { + V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, + V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, + V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, + V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, + V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, + V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, + V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, + V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, + V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, + V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, + V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, + V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, + V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +enum v4l2_mpeg_audio_l2_bitrate { + V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, + V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, + V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, + V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, + V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, + V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, + V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, + V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, + V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, + V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, + V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, + V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, + V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +enum v4l2_mpeg_audio_l3_bitrate { + V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +enum v4l2_mpeg_audio_mode { + V4L2_MPEG_AUDIO_MODE_STEREO = 0, + V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, + V4L2_MPEG_AUDIO_MODE_DUAL = 2, + V4L2_MPEG_AUDIO_MODE_MONO = 3, +}; +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +enum v4l2_mpeg_audio_mode_extension { + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, +}; +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +enum v4l2_mpeg_audio_emphasis { + V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, + V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +enum v4l2_mpeg_audio_crc { + V4L2_MPEG_AUDIO_CRC_NONE = 0, + V4L2_MPEG_AUDIO_CRC_CRC16 = 1, +}; +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) +enum v4l2_mpeg_audio_dec_playback { + V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) + +/* MPEG video controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +enum v4l2_mpeg_video_encoding { + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, +}; +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +enum v4l2_mpeg_video_aspect { + V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, + V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, + V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, + V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, +}; +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +enum v4l2_mpeg_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, +}; +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) +#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) +#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) +#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) +#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) +#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) +enum v4l2_mpeg_video_header_mode { + V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, + +}; +#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) +#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) +enum v4l2_mpeg_video_multi_slice_mode { + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) +#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) +#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225) + +#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) +#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) +#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) +#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) +#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) +#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) +#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) +#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) +#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) +#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) +enum v4l2_mpeg_video_h264_entropy_mode { + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) +#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) +enum v4l2_mpeg_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, + V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, + V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, + V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, + V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, + V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, + V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, + V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, + V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, +}; +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) +enum v4l2_mpeg_video_h264_loop_filter_mode { + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, +}; +#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) +enum v4l2_mpeg_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, + V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, + V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, + V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, + V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, +}; +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) +enum v4l2_mpeg_video_h264_vui_sar_idc { + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, +}; +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE+368) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE+369) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE+370) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE+371) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE+372) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE+373) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE+374) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE+375) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE+376) +#define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE+377) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE+378) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE+379) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE+380) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) +#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) +#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) +#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) +#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) +enum v4l2_mpeg_video_mpeg4_level { + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) +enum v4l2_mpeg_video_mpeg4_profile { + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) + +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +enum v4l2_mpeg_cx2341x_video_median_filter_type { + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) + +/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ +#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) + +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) +enum v4l2_mpeg_mfc51_video_frame_skip_mode { + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) +enum v4l2_mpeg_mfc51_video_force_frame_type { + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) + + +/* Camera class control IDs */ + +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + +#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) +#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) + +#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19) + +#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20) +enum v4l2_auto_n_preset_white_balance { + V4L2_WHITE_BALANCE_MANUAL = 0, + V4L2_WHITE_BALANCE_AUTO = 1, + V4L2_WHITE_BALANCE_INCANDESCENT = 2, + V4L2_WHITE_BALANCE_FLUORESCENT = 3, + V4L2_WHITE_BALANCE_FLUORESCENT_H = 4, + V4L2_WHITE_BALANCE_HORIZON = 5, + V4L2_WHITE_BALANCE_DAYLIGHT = 6, + V4L2_WHITE_BALANCE_FLASH = 7, + V4L2_WHITE_BALANCE_CLOUDY = 8, + V4L2_WHITE_BALANCE_SHADE = 9, +}; + +#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22) + +#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24) +enum v4l2_iso_sensitivity_auto_type { + V4L2_ISO_SENSITIVITY_MANUAL = 0, + V4L2_ISO_SENSITIVITY_AUTO = 1, +}; + +#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25) +enum v4l2_exposure_metering { + V4L2_EXPOSURE_METERING_AVERAGE = 0, + V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1, + V4L2_EXPOSURE_METERING_SPOT = 2, +}; + +#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26) +enum v4l2_scene_mode { + V4L2_SCENE_MODE_NONE = 0, + V4L2_SCENE_MODE_BACKLIGHT = 1, + V4L2_SCENE_MODE_BEACH_SNOW = 2, + V4L2_SCENE_MODE_CANDLE_LIGHT = 3, + V4L2_SCENE_MODE_DAWN_DUSK = 4, + V4L2_SCENE_MODE_FALL_COLORS = 5, + V4L2_SCENE_MODE_FIREWORKS = 6, + V4L2_SCENE_MODE_LANDSCAPE = 7, + V4L2_SCENE_MODE_NIGHT = 8, + V4L2_SCENE_MODE_PARTY_INDOOR = 9, + V4L2_SCENE_MODE_PORTRAIT = 10, + V4L2_SCENE_MODE_SPORTS = 11, + V4L2_SCENE_MODE_SUNSET = 12, + V4L2_SCENE_MODE_TEXT = 13, +}; + +#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_LOCK_EXPOSURE (1 << 0) +#define V4L2_LOCK_WHITE_BALANCE (1 << 1) +#define V4L2_LOCK_FOCUS (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28) +#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29) +#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30) +#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0) +#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0) +#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1) +#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31) +enum v4l2_auto_focus_range { + V4L2_AUTO_FOCUS_RANGE_AUTO = 0, + V4L2_AUTO_FOCUS_RANGE_NORMAL = 1, + V4L2_AUTO_FOCUS_RANGE_MACRO = 2, + V4L2_AUTO_FOCUS_RANGE_INFINITY = 3, +}; + + +/* FM Modulator class control IDs */ + +#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) +#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) + +#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) +#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) +#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) +#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) +#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) + +#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) +#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) +#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) + +#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) +#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) +#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) +#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) +#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) + +#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) +#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) +#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) + +#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) +enum v4l2_preemphasis { + V4L2_PREEMPHASIS_DISABLED = 0, + V4L2_PREEMPHASIS_50_uS = 1, + V4L2_PREEMPHASIS_75_uS = 2, +}; +#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) +#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) + + +/* Flash and privacy (indicator) light controls */ + +#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) +#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) + +#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) +enum v4l2_flash_led_mode { + V4L2_FLASH_LED_MODE_NONE, + V4L2_FLASH_LED_MODE_FLASH, + V4L2_FLASH_LED_MODE_TORCH, +}; + +#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) +enum v4l2_flash_strobe_source { + V4L2_FLASH_STROBE_SOURCE_SOFTWARE, + V4L2_FLASH_STROBE_SOURCE_EXTERNAL, +}; + +#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) +#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) +#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) + +#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) +#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) +#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) +#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) + +#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) +#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) +#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) +#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) +#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) +#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) +#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) + +#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) +#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) + + +/* JPEG-class control IDs */ + +#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) +#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) + +#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) +enum v4l2_jpeg_chroma_subsampling { + V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, + V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, + V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, + V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, + V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, +}; +#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) +#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) + +#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) +#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) +#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) +#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) +#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) +#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) + +/* Image source controls */ +#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1) + +#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1) +#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2) +#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3) + + +/* Image processing controls */ + +#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900) +#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1) + +#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1) +#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2) +#define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3) + +#endif diff --git a/amvdec/include/videodev2.h b/amvdec/include/videodev2.h new file mode 100644 index 0000000..12c2c5b --- a/dev/null +++ b/amvdec/include/videodev2.h @@ -0,0 +1,2033 @@ +/* + * Video for Linux Two header file + * + * Copyright (C) 1999-2012 the contributors + * + * 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. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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. + * + * Header file for v4l or V4L2 drivers and applications + * with public API. + * All kernel-specific stuff were moved to media/v4l2-dev.h, so + * no #if __KERNEL tests are allowed here + * + * See http://linuxtv.org for more info + * + * Author: Bill Dirks <bill@thedirks.org> + * Justin Schoeman + * Hans Verkuil <hverkuil@xs4all.nl> + * et al. + */ +#ifndef _UAPI__LINUX_VIDEODEV2_H +#define _UAPI__LINUX_VIDEODEV2_H + +#ifndef __KERNEL__ +#include <sys/time.h> +#endif +#include <linux/compiler.h> +#include <linux/ioctl.h> +#include <linux/types.h> +#include <v4l2-common.h> +#include <v4l2-controls.h> + +/* + * Common stuff for both V4L1 and V4L2 + * Moved from videodev.h + */ +#define VIDEO_MAX_FRAME 32 +#define VIDEO_MAX_PLANES 8 + +#ifndef __KERNEL__ + +/* These defines are V4L1 specific and should not be used with the V4L2 API! + They will be removed from this header in the future. */ + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ +#endif + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a, b, c, d)\ + ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ + V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field + first and the top field is + transmitted first */ + V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field + first and the bottom field is + transmitted first */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, + V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, +#if 1 + /* Experimental */ + V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, +#endif + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, + /* Deprecated, do not use */ + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +#define V4L2_TYPE_IS_MULTIPLANAR(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + +#define V4L2_TYPE_IS_OUTPUT(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ + || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, + V4L2_TUNER_DIGITAL_TV = 3, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, + V4L2_MEMORY_DMABUF = 4, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/** + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP + * + * @driver: name of the driver module (e.g. "bttv") + * @card: name of the card (e.g. "Hauppauge WinTV") + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) + * @version: KERNEL_VERSION + * @capabilities: capabilities of the physical device as a whole + * @device_caps: capabilities accessed via this particular device (node) + * @reserved: reserved fields for future extensions + */ +struct v4l2_capability { + __u8 driver[16]; + __u8 card[32]; + __u8 bus_info[32]; + __u32 version; + __u32 capabilities; + __u32 device_caps; + __u32 reserved[3]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ +#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ +#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ +#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ + +/* Is a video capture device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 +/* Is a video output device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 +/* Is a video mem-to-mem device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000 +/* Is a video mem-to-mem device */ +#define V4L2_CAP_VIDEO_M2M 0x00008000 + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ +#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format { + __u32 width; + __u32 height; + __u32 pixelformat; + __u32 field; /* enum v4l2_field */ + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + __u32 colorspace; /* enum v4l2_colorspace */ + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ + +/* RGB formats */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ + +/* Grey formats */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ +#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ +#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ + +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + +/* Palette formats */ +#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ + +/* Luminance+Chrominance formats */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ +#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ +#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ +#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ +#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ +#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */ + +/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ +/* 10bit raw bayer DPCM compressed to 8 bits */ +#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8') +#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8') +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') +#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') +/* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */ +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ +#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ +#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ +#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */ +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ +#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ +#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ +#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ +#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ +#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ +#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ +#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ +#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ +#define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */ + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc { + __u32 index; /* Format number */ + __u32 type; /* enum v4l2_buf_type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 +#define V4L2_FMT_FLAG_EMULATED 0x0002 + +#if 1 +/* Experimental Frame Size and frame rate enumeration */ +/* + * F R A M E S I Z E E N U M E R A T I O N + */ +enum v4l2_frmsizetypes { + V4L2_FRMSIZE_TYPE_DISCRETE = 1, + V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, + V4L2_FRMSIZE_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmsize_discrete { + __u32 width; /* Frame width [pixel] */ + __u32 height; /* Frame height [pixel] */ +}; + +struct v4l2_frmsize_stepwise { + __u32 min_width; /* Minimum frame width [pixel] */ + __u32 max_width; /* Maximum frame width [pixel] */ + __u32 step_width; /* Frame width step size [pixel] */ + __u32 min_height; /* Minimum frame height [pixel] */ + __u32 max_height; /* Maximum frame height [pixel] */ + __u32 step_height; /* Frame height step size [pixel] */ +}; + +struct v4l2_frmsizeenum { + __u32 index; /* Frame size number */ + __u32 pixel_format; /* Pixel format */ + __u32 type; /* Frame size type the device supports. */ + + union { /* Frame size */ + struct v4l2_frmsize_discrete discrete; + struct v4l2_frmsize_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; + +/* + * F R A M E R A T E E N U M E R A T I O N + */ +enum v4l2_frmivaltypes { + V4L2_FRMIVAL_TYPE_DISCRETE = 1, + V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, + V4L2_FRMIVAL_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmival_stepwise { + struct v4l2_fract min; /* Minimum frame interval [s] */ + struct v4l2_fract max; /* Maximum frame interval [s] */ + struct v4l2_fract step; /* Frame interval step size [s] */ +}; + +struct v4l2_frmivalenum { + __u32 index; /* Frame format index */ + __u32 pixel_format; /* Pixel format */ + __u32 width; /* Frame width */ + __u32 height; /* Frame height */ + __u32 type; /* Frame interval type the device supports. */ + + union { /* Frame interval */ + struct v4l2_fract discrete; + struct v4l2_frmival_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; +#endif + +/* + * T I M E C O D E + */ +struct v4l2_timecode { + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + +struct v4l2_jpegcompression { + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer applications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers { + __u32 count; + __u32 type; /* enum v4l2_buf_type */ + __u32 memory; /* enum v4l2_memory */ + __u32 reserved[2]; +}; + +/** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) + * @length: size of this plane (NOT the payload) in bytes + * @mem_offset: when memory in the associated struct v4l2_buffer is + * V4L2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a "cookie" that + * should be passed to mmap() called on the video node) + * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * pointing to this plane + * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file + * descriptor associated with this plane + * @data_offset: offset in the plane to the start of data; usually 0, + * unless there is a header in front of the data + * + * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer + * with two planes can have one plane for Y, and another for interleaved CbCr + * components. Each plane can reside in a separate memory buffer, or even in + * a completely separate memory node (e.g. in embedded devices). + */ +struct v4l2_plane { + __u32 bytesused; + __u32 length; + union { + __u32 mem_offset; + unsigned long userptr; + __s32 fd; + } m; + __u32 data_offset; + __u32 reserved[11]; +}; + +/** + * struct v4l2_buffer - video buffer info + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @bytesused: number of bytes occupied by data in the buffer (payload); + * unused (set to 0) for multiplanar buffers + * @flags: buffer informational flags + * @field: enum v4l2_field; field order of the image in the buffer + * @timestamp: frame timestamp + * @timecode: frame timecode + * @sequence: sequence count of this frame + * @memory: enum v4l2_memory; the method, in which the actual video data is + * passed + * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; + * offset from the start of the device memory for this plane, + * (or a "cookie" that should be passed to mmap() as offset) + * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; + * a userspace pointer pointing to this buffer + * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; + * a userspace file descriptor associated with this buffer + * @planes: for multiplanar buffers; userspace pointer to the array of plane + * info structs for this buffer + * @length: size in bytes of the buffer (NOT its payload) for single-plane + * buffers (when type != *_MPLANE); number of elements in the + * planes array for multi-plane buffers + * @input: input number from which the video data has has been captured + * + * Contains data exchanged by application and driver using one of the Streaming + * I/O methods. + */ +struct v4l2_buffer { + __u32 index; + __u32 type; + __u32 bytesused; + __u32 flags; + __u32 field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + __u32 memory; + union { + __u32 offset; + unsigned long userptr; + struct v4l2_plane *planes; + __s32 fd; + } m; + __u32 length; + __u32 reserved2; + __u32 reserved; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +/* Buffer is ready, but the data contained within is corrupted. */ +#define V4L2_BUF_FLAG_ERROR 0x0040 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ +#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ +/* Cache handling flags */ +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 + +/** + * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor + * + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * @fd: file descriptor associated with DMABUF (set by driver) + * + * Contains data used for exporting a video buffer as DMABUF file descriptor. + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF + * (identical to the cookie used to mmap() the buffer to userspace). All + * reserved fields must be set to zero. The field reserved0 is expected to + * become a structure 'type' allowing an alternative layout of the structure + * content. Therefore this field should not be used for any other extensions. + */ +struct v4l2_exportbuffer { + __u32 type; /* enum v4l2_buf_type */ + __u32 index; + __u32 plane; + __u32 flags; + __s32 fd; + __u32 reserved[11]; +}; + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer { + __u32 capability; + __u32 flags; + /* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void *base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 +#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 +#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 +#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 +#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 +#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 +#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 +#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 + +struct v4l2_clip { + struct v4l2_rect c; + struct v4l2_clip __user *next; +}; + +struct v4l2_window { + struct v4l2_rect w; + __u32 field; /* enum v4l2_field */ + __u32 chromakey; + struct v4l2_clip __user *clips; + __u32 clipcount; + void __user *bitmap; + __u8 global_alpha; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm { + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; + +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm { + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap { + __u32 type; /* enum v4l2_buf_type */ + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + __u32 type; /* enum v4l2_buf_type */ + struct v4l2_rect c; +}; + +/** + * struct v4l2_selection - selection info + * @type: buffer type (do not use *_MPLANE types) + * @target: Selection target, used to choose one of possible rectangles; + * defined in v4l2-common.h; V4L2_SEL_TGT_* . + * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. + * @r: coordinates of selection window + * @reserved: for future use, rounds structure size to 64 bytes, set to zero + * + * Hardware may use multiple helper windows to process a video stream. + * The structure is used to exchange this selection areas between + * an application and a driver. + */ +struct v4l2_selection { + __u32 type; + __u32 target; + __u32 flags; + struct v4l2_rect r; + __u32 reserved[9]; +}; + + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */ +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ +#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) +#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* FIXME: + Although std_id is 64 bits, there is an issue on PPC32 architecture that + makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding + this value to 32 bits. + As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), + it should work fine. However, if needed to add more than two standards, + v4l2-common.c should be fixed. + */ + +/* + * Some macros to merge video standards in order to make live easier for the + * drivers and V4L2 applications + */ + +/* + * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is + * Missing here. + */ +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) +/* Secam macros */ +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1) +/* All Secam Standards */ +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_DK |\ + V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +/* PAL macros */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +/* + * "Common" PAL - This macro is there to be compatible with the old + * V4L1 concept of "PAL": /BGDKHI. + * Several PAL standards are mising here: /M, /N and /Nc + */ +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +/* Chroma "agnostic" standards */ +#define V4L2_STD_B (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_SECAM_B) +#define V4L2_STD_G (V4L2_STD_PAL_G |\ + V4L2_STD_SECAM_G) +#define V4L2_STD_H (V4L2_STD_PAL_H |\ + V4L2_STD_SECAM_H) +#define V4L2_STD_L (V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +#define V4L2_STD_GH (V4L2_STD_G |\ + V4L2_STD_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK |\ + V4L2_STD_SECAM_DK) +#define V4L2_STD_BG (V4L2_STD_B |\ + V4L2_STD_G) +#define V4L2_STD_MN (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_NTSC) + +/* Standards where MTS/BTSC stereo could be found */ +#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ + V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc) + +/* Standards for Countries with 60Hz Line frequency */ +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC |\ + V4L2_STD_NTSC_443) +/* Standards for Countries with 50Hz Line frequency */ +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ + V4L2_STD_ATSC_16_VSB) +/* Macros with none and all analog standards */ +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard { + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + +/* The DV Preset API is deprecated in favor of the DV Timings API. + New drivers shouldn't use this anymore! */ + +/* + * V I D E O T I M I N G S D V P R E S E T + */ +struct v4l2_dv_preset { + __u32 preset; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T S E N U M E R A T I O N + */ +struct v4l2_dv_enum_preset { + __u32 index; + __u32 preset; + __u8 name[32]; /* Name of the preset timing */ + __u32 width; + __u32 height; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T V A L U E S + */ +#define V4L2_DV_INVALID 0 +#define V4L2_DV_480P59_94 1 /* BT.1362 */ +#define V4L2_DV_576P50 2 /* BT.1362 */ +#define V4L2_DV_720P24 3 /* SMPTE 296M */ +#define V4L2_DV_720P25 4 /* SMPTE 296M */ +#define V4L2_DV_720P30 5 /* SMPTE 296M */ +#define V4L2_DV_720P50 6 /* SMPTE 296M */ +#define V4L2_DV_720P59_94 7 /* SMPTE 274M */ +#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ +#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I25 11 /* BT.1120 */ +#define V4L2_DV_1080I50 12 /* SMPTE 296M */ +#define V4L2_DV_1080I60 13 /* SMPTE 296M */ +#define V4L2_DV_1080P24 14 /* SMPTE 296M */ +#define V4L2_DV_1080P25 15 /* SMPTE 296M */ +#define V4L2_DV_1080P30 16 /* SMPTE 296M */ +#define V4L2_DV_1080P50 17 /* BT.1120 */ +#define V4L2_DV_1080P60 18 /* BT.1120 */ + +/* + * D V B T T I M I N G S + */ + +/** struct v4l2_bt_timings - BT.656/BT.1120 timing data + * @width: total width of the active video in pixels + * @height: total height of the active video in lines + * @interlaced: Interlaced or progressive + * @polarities: Positive or negative polarities + * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @hfrontporch:Horizontal front porch in pixels + * @hsync: Horizontal Sync length in pixels + * @hbackporch: Horizontal back porch in pixels + * @vfrontporch:Vertical front porch in lines + * @vsync: Vertical Sync length in lines + * @vbackporch: Vertical back porch in lines + * @il_vfrontporch:Vertical front porch for the even field + * (aka field 2) of interlaced field formats + * @il_vsync: Vertical Sync length for the even field + * (aka field 2) of interlaced field formats + * @il_vbackporch:Vertical back porch for the even field + * (aka field 2) of interlaced field formats + * @standards: Standards the timing belongs to + * @flags: Flags + * @reserved: Reserved fields, must be zeroed. + * + * A note regarding vertical interlaced timings: height refers to the total + * height of the active video frame (= two fields). The blanking timings refer + * to the blanking of each field. So the height of the total frame is + * calculated as follows: + * + * tot_height = height + vfrontporch + vsync + vbackporch + + * il_vfrontporch + il_vsync + il_vbackporch + * + * The active height of each field is height / 2. + */ +struct v4l2_bt_timings { + __u32 width; + __u32 height; + __u32 interlaced; + __u32 polarities; + __u64 pixelclock; + __u32 hfrontporch; + __u32 hsync; + __u32 hbackporch; + __u32 vfrontporch; + __u32 vsync; + __u32 vbackporch; + __u32 il_vfrontporch; + __u32 il_vsync; + __u32 il_vbackporch; + __u32 standards; + __u32 flags; + __u32 reserved[14]; +} __attribute__((packed)); + +/* Interlaced or progressive format */ +#define V4L2_DV_PROGRESSIVE 0 +#define V4L2_DV_INTERLACED 1 + +/* Polarities. If bit is not set, it is assumed to be negative polarity */ +#define V4L2_DV_VSYNC_POS_POL 0x00000001 +#define V4L2_DV_HSYNC_POS_POL 0x00000002 + +/* Timings standards */ +#define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */ +#define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */ +#define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */ +#define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */ + +/* Flags */ + +/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary + GTF' curve (GTF). In both cases the horizontal and/or vertical blanking + intervals are reduced, allowing a higher resolution over the same + bandwidth. This is a read-only flag. */ +#define V4L2_DV_FL_REDUCED_BLANKING (1 << 0) +/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple + of six. These formats can be optionally played at 1 / 1.001 speed. + This is a read-only flag. */ +#define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1) +/* CEA-861 specific: only valid for video transmitters, the flag is cleared + by receivers. + If the framerate of the format is a multiple of six, then the pixelclock + used to set up the transmitter is divided by 1.001 to make it compatible + with 60 Hz based standards such as NTSC and PAL-M that use a framerate of + 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate + such frequencies, then the flag will also be cleared. */ +#define V4L2_DV_FL_REDUCED_FPS (1 << 2) +/* Specific to interlaced formats: if set, then field 1 is really one half-line + longer and field 2 is really one half-line shorter, so each field has + exactly the same number of half-lines. Whether half-lines can be detected + or used depends on the hardware. */ +#define V4L2_DV_FL_HALF_LINE (1 << 0) + + +/** struct v4l2_dv_timings - DV timings + * @type: the type of the timings + * @bt: BT656/1120 timings + */ +struct v4l2_dv_timings { + __u32 type; + union { + struct v4l2_bt_timings bt; + __u32 reserved[32]; + }; +} __attribute__((packed)); + +/* Values for the type field */ +#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ + + +/** struct v4l2_enum_dv_timings - DV timings enumeration + * @index: enumeration index + * @reserved: must be zeroed + * @timings: the timings for the given index + */ +struct v4l2_enum_dv_timings { + __u32 index; + __u32 reserved[3]; + struct v4l2_dv_timings timings; +}; + +/** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities + * @min_width: width in pixels + * @max_width: width in pixels + * @min_height: height in lines + * @max_height: height in lines + * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @standards: Supported standards + * @capabilities: Supported capabilities + * @reserved: Must be zeroed + */ +struct v4l2_bt_timings_cap { + __u32 min_width; + __u32 max_width; + __u32 min_height; + __u32 max_height; + __u64 min_pixelclock; + __u64 max_pixelclock; + __u32 standards; + __u32 capabilities; + __u32 reserved[16]; +} __attribute__((packed)); + +/* Supports interlaced formats */ +#define V4L2_DV_BT_CAP_INTERLACED (1 << 0) +/* Supports progressive formats */ +#define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1) +/* Supports CVT/GTF reduced blanking */ +#define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2) +/* Supports custom formats */ +#define V4L2_DV_BT_CAP_CUSTOM (1 << 3) + +/** struct v4l2_dv_timings_cap - DV timings capabilities + * @type: the type of the timings (same as in struct v4l2_dv_timings) + * @bt: the BT656/1120 timings capabilities + */ +struct v4l2_dv_timings_cap { + __u32 type; + __u32 reserved[3]; + union { + struct v4l2_bt_timings_cap bt; + __u32 raw_data[32]; + }; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input { + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* enum v4l2_tuner_type */ + v4l2_std_id std; + __u32 status; + __u32 capabilities; + __u32 reserved[3]; +}; + +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - sensor orientation */ +/* If sensor is mounted upside down set both bits */ +#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ +#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* capabilities flags */ +#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_IN_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_IN_CAP_CUSTOM_TIMINGS V4L2_IN_CAP_DV_TIMINGS /* For compatibility */ +#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output { + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 capabilities; + __u32 reserved[3]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* capabilities flags */ +#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_OUT_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_OUT_CAP_CUSTOM_TIMINGS V4L2_OUT_CAP_DV_TIMINGS /* For compatibility */ +#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * C O N T R O L S + */ +struct v4l2_control { + __u32 id; + __s32 value; +}; + +struct v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + }; +} __attribute__((packed)); + +struct v4l2_ext_controls { + __u32 ctrl_class; + __u32 count; + __u32 error_idx; + __u32 reserved[2]; + struct v4l2_ext_control *controls; +}; + +#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, + V4L2_CTRL_TYPE_INTEGER64 = 5, + V4L2_CTRL_TYPE_CTRL_CLASS = 6, + V4L2_CTRL_TYPE_STRING = 7, + V4L2_CTRL_TYPE_BITMASK = 8, + V4L2_CTRL_TYPE_INTEGER_MENU = 9, +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl { + __u32 id; + __u32 type; /* enum v4l2_ctrl_type */ + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu { + __u32 id; + __u32 index; + union { + __u8 name[32]; /* Whatever */ + __s64 value; + }; + __u32 reserved; +} __attribute__((packed)); + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 +#define V4L2_CTRL_FLAG_VOLATILE 0x0080 + +/* Query flag, to be ORed with the control ID */ +#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 + +/* User-class control IDs defined by V4L2 */ +#define V4L2_CID_MAX_CTRLS 1024 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + + +/* DV-class control IDs defined by V4L2 */ +#define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900) +#define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1) + +#define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1) +#define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2) +#define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3) +#define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4) +enum v4l2_dv_tx_mode { + V4L2_DV_TX_MODE_DVI_D = 0, + V4L2_DV_TX_MODE_HDMI = 1, +}; +#define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5) +enum v4l2_dv_rgb_range { + V4L2_DV_RGB_RANGE_AUTO = 0, + V4L2_DV_RGB_RANGE_LIMITED = 1, + V4L2_DV_RGB_RANGE_FULL = 2, +}; + +#define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100) +#define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101) + +/* + * T U N I N G + */ +struct v4l2_tuner { + __u32 index; + __u8 name[32]; + __u32 type; /* enum v4l2_tuner_type */ + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004 +#define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 +#define V4L2_TUNER_CAP_RDS 0x0080 +#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 +#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 +#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400 +#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 +#define V4L2_TUNER_SUB_RDS 0x0010 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 +#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 + +struct v4l2_frequency { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 frequency; + __u32 reserved[8]; +}; + +#define V4L2_BAND_MODULATION_VSB (1 << 1) +#define V4L2_BAND_MODULATION_FM (1 << 2) +#define V4L2_BAND_MODULATION_AM (1 << 3) + +struct v4l2_frequency_band { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 index; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 modulation; + __u32 reserved[9]; +}; + +struct v4l2_hw_freq_seek { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 seek_upward; + __u32 wrap_around; + __u32 spacing; + __u32 rangelow; + __u32 rangehigh; + __u32 reserved[5]; +}; + +/* + * R D S + */ + +struct v4l2_rds_data { + __u8 lsb; + __u8 msb; + __u8 block; +} __attribute__((packed)); + +#define V4L2_RDS_BLOCK_MSK 0x7 +#define V4L2_RDS_BLOCK_A 0 +#define V4L2_RDS_BLOCK_B 1 +#define V4L2_RDS_BLOCK_C 2 +#define V4L2_RDS_BLOCK_D 3 +#define V4L2_RDS_BLOCK_C_ALT 4 +#define V4L2_RDS_BLOCK_INVALID 7 + +#define V4L2_RDS_BLOCK_CORRECTED 0x40 +#define V4L2_RDS_BLOCK_ERROR 0x80 + +/* + * A U D I O + */ +struct v4l2_audio { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * M P E G S E R V I C E S + * + * NOTE: EXPERIMENTAL API + */ +#if 1 +#define V4L2_ENC_IDX_FRAME_I (0) +#define V4L2_ENC_IDX_FRAME_P (1) +#define V4L2_ENC_IDX_FRAME_B (2) +#define V4L2_ENC_IDX_FRAME_MASK (0xf) + +struct v4l2_enc_idx_entry { + __u64 offset; + __u64 pts; + __u32 length; + __u32 flags; + __u32 reserved[2]; +}; + +#define V4L2_ENC_IDX_ENTRIES (64) +struct v4l2_enc_idx { + __u32 entries; + __u32 entries_cap; + __u32 reserved[4]; + struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; +}; + + +#define V4L2_ENC_CMD_START (0) +#define V4L2_ENC_CMD_STOP (1) +#define V4L2_ENC_CMD_PAUSE (2) +#define V4L2_ENC_CMD_RESUME (3) + +/* Flags for V4L2_ENC_CMD_STOP */ +#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) + +struct v4l2_encoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u32 data[8]; + } raw; + }; +}; + +/* Decoder commands */ +#define V4L2_DEC_CMD_START (0) +#define V4L2_DEC_CMD_STOP (1) +#define V4L2_DEC_CMD_PAUSE (2) +#define V4L2_DEC_CMD_RESUME (3) + +/* Flags for V4L2_DEC_CMD_START */ +#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) + +/* Flags for V4L2_DEC_CMD_PAUSE */ +#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) + +/* Flags for V4L2_DEC_CMD_STOP */ +#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) +#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) + +/* Play format requirements (returned by the driver): */ + +/* The decoder has no special format requirements */ +#define V4L2_DEC_START_FMT_NONE (0) +/* The decoder requires full GOPs */ +#define V4L2_DEC_START_FMT_GOP (1) + +/* The structure must be zeroed before use by the application + This ensures it can be extended safely in the future. */ +struct v4l2_decoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u64 pts; + } stop; + + struct { + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; + __u32 format; + } start; + + struct { + __u32 data[16]; + } raw; + }; +}; +#endif + + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +/* Raw VBI */ +struct v4l2_vbi_format { + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1 << 0) +#define V4L2_VBI_INTERLACED (1 << 1) + +/* Sliced VBI + * + * This implements is a proposal V4L2 API to allow SLICED VBI + * required for some hardware encoders. It should change without + * notice in the definitive implementation. + */ + +struct v4l2_sliced_vbi_format { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 io_size; + __u32 reserved[2]; /* must be zero */ +}; + +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_B (0x0001) +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x0400) +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x1000) +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x4000) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) + +struct v4l2_sliced_vbi_cap { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 type; /* enum v4l2_buf_type */ + __u32 reserved[3]; /* must be 0 */ +}; + +struct v4l2_sliced_vbi_data { + __u32 id; + __u32 field; /* 0: first field, 1: second field */ + __u32 line; /* 1-23 */ + __u32 reserved; /* must be 0 */ + __u8 data[48]; +}; + +/* + * Sliced VBI data inserted into MPEG Streams + */ + +/* + * V4L2_MPEG_STREAM_VBI_FMT_IVTV: + * + * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an + * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI + * data + * + * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header + * definitions are not included here. See the MPEG-2 specifications for details + * on these headers. + */ + +/* Line type IDs */ +#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) +#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) +#define V4L2_MPEG_VBI_IVTV_WSS_625 (5) +#define V4L2_MPEG_VBI_IVTV_VPS (7) + +struct v4l2_mpeg_vbi_itv0_line { + __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ + __u8 data[42]; /* Sliced VBI data for the line */ +} __attribute__((packed)); + +struct v4l2_mpeg_vbi_itv0 { + __le32 linemask[2]; /* Bitmasks of VBI service lines present */ + struct v4l2_mpeg_vbi_itv0_line line[35]; +} __attribute__((packed)); + +struct v4l2_mpeg_vbi_ITV0 { + struct v4l2_mpeg_vbi_itv0_line line[36]; +} __attribute__((packed)); + +#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" +#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" + +struct v4l2_mpeg_vbi_fmt_ivtv { + __u8 magic[4]; + union { + struct v4l2_mpeg_vbi_itv0 itv0; + struct v4l2_mpeg_vbi_ITV0 ITV0; + }; +} __attribute__((packed)); + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/** + * struct v4l2_plane_pix_format - additional, per-plane format definition + * @sizeimage: maximum size in bytes required for data, for which + * this plane will be used + * @bytesperline: distance in bytes between the leftmost pixels in two + * adjacent lines + */ +struct v4l2_plane_pix_format { + __u32 sizeimage; + __u16 bytesperline; + __u16 reserved[7]; +} __attribute__((packed)); + +/** + * struct v4l2_pix_format_mplane - multiplanar format definition + * @width: image width in pixels + * @height: image height in pixels + * @pixelformat: little endian four character code (fourcc) + * @field: enum v4l2_field; field order (for interlaced video) + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat + * @plane_fmt: per-plane information + * @num_planes: number of planes for this format + */ +struct v4l2_pix_format_mplane { + __u32 width; + __u32 height; + __u32 pixelformat; + __u32 field; + __u32 colorspace; + + struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; + __u8 num_planes; + __u8 reserved[11]; +} __attribute__((packed)); + +/** + * struct v4l2_format - stream data format + * @type: enum v4l2_buf_type; type of the data stream + * @pix: definition of an image format + * @pix_mp: definition of a multiplanar image format + * @win: definition of an overlaid image + * @vbi: raw VBI capture or output parameters + * @sliced: sliced VBI capture or output parameters + * @raw_data: placeholder for future extensions and custom formats + */ +struct v4l2_format { + __u32 type; + union { + struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ + struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ + struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ + struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ + struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm { + __u32 type; /* enum v4l2_buf_type */ + union { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + +/* + * E V E N T S + */ + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_VSYNC 1 +#define V4L2_EVENT_EOS 2 +#define V4L2_EVENT_CTRL 3 +#define V4L2_EVENT_FRAME_SYNC 4 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* Payload for V4L2_EVENT_VSYNC */ +struct v4l2_event_vsync { + /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ + __u8 field; +} __attribute__((packed)); + +/* Payload for V4L2_EVENT_CTRL */ +#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) +#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) + +struct v4l2_event_ctrl { + __u32 changes; + __u32 type; + union { + __s32 value; + __s64 value64; + }; + __u32 flags; + __s32 minimum; + __s32 maximum; + __s32 step; + __s32 default_value; +}; + +struct v4l2_event_frame_sync { + __u32 frame_sequence; +}; + +struct v4l2_event { + __u32 type; + union { + struct v4l2_event_vsync vsync; + struct v4l2_event_ctrl ctrl; + struct v4l2_event_frame_sync frame_sync; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + struct timespec timestamp; + __u32 id; + __u32 reserved[8]; +}; + +#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) +#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) + +struct v4l2_event_subscription { + __u32 type; + __u32 id; + __u32 flags; + __u32 reserved[5]; +}; + +/* + * A D V A N C E D D E B U G G I N G + * + * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! + * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! + */ + +/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ + +#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ +#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ +#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ + +struct v4l2_dbg_match { + __u32 type; /* Match type */ + union { /* Match this chip, meaning determined by type */ + __u32 addr; + char name[32]; + }; +} __attribute__((packed)); + +struct v4l2_dbg_register { + struct v4l2_dbg_match match; + __u32 size; /* register size in bytes */ + __u64 reg; + __u64 val; +} __attribute__((packed)); + +/* VIDIOC_DBG_G_CHIP_IDENT */ +struct v4l2_dbg_chip_ident { + struct v4l2_dbg_match match; + __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */ + __u32 revision; /* chip revision, chip specific */ +} __attribute__((packed)); + +/** + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument + * @index: on return, index of the first created buffer + * @count: entry: number of requested buffers, + * return: number of created buffers + * @memory: enum v4l2_memory; buffer memory type + * @format: frame format, for which buffers are requested + * @reserved: future extensions + */ +struct v4l2_create_buffers { + __u32 index; + __u32 count; + __u32 memory; + struct v4l2_format format; + __u32 reserved[8]; +}; + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO('V', 1) +#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) +#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW('V', 14, int) +#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) +#define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer) +#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW('V', 18, int) +#define VIDIOC_STREAMOFF _IOW('V', 19, int) +#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR('V', 38, int) +#define VIDIOC_S_INPUT _IOWR('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */ +#define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */ +#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) +#define VIDIOC_LOG_STATUS _IO('V', 70) +#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) +#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) +#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) +#if 1 +#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) +#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) +#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) +#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) +#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) +#endif + +#if 1 +/* Experimental, meant for debugging, testing and internal use. + Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + You must be root to use these ioctls. Never use these in applications! */ +#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) +#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) + +/* Experimental, meant for debugging, testing and internal use. + Never use this ioctl in applications! */ +#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) +#endif + +#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) + +/* These four DV Preset ioctls are deprecated in favor of the DV Timings + ioctls. */ +#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) +#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) +#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) +#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) +#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) +#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) +#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) + +/* Experimental, the below two ioctls may change over the next couple of kernel + versions */ +#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) +#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) + +/* Experimental selection API */ +#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) +#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) + +/* Experimental, these two ioctls may change over the next couple of kernel + versions. */ +#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) +#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) + +/* Experimental, these three ioctls may change over the next couple of kernel + versions. */ +#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) +#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) +#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) + +/* Experimental, this ioctl may change over the next couple of kernel + versions. */ +#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band) + +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + +#endif /* _UAPI__LINUX_VIDEODEV2_H */ diff --git a/amvdec/ionv4l.c b/amvdec/ionv4l.c new file mode 100644 index 0000000..12f2e07 --- a/dev/null +++ b/amvdec/ionv4l.c @@ -0,0 +1,173 @@ +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include "ionv4l.h" +#include "ionvdec_priv.h" +#define V4LDEVICE_NAME "/dev/video13" +#define CLEAR(s) memset(&s, 0, sizeof(s)) + +static int ionv4l_unmapbufs(ionvideo_dev_t *dev); +static int ionv4l_mapbufs(ionvideo_dev_t *dev); +int ionv4l_setfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt); +int ionv4l_stop(ionvideo_dev_t *dev); +int ionv4l_init(ionvideo_dev_t *dev, int type, int width, int height, int fmt, int buffernum) +{ + int ret; + ionv4l_dev_t *v4l = dev->devpriv; + struct v4l2_format v4lfmt; + v4l->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l->width = width; + v4l->height = height; + v4l->pixformat = fmt; + v4l->buffer_num = buffernum; + v4lfmt.type = v4l->type; + v4lfmt.fmt.pix.width = v4l->width; + v4lfmt.fmt.pix.height = v4l->height; + v4lfmt.fmt.pix.pixelformat = v4l->pixformat; + ret = ionv4l_setfmt(dev, &v4lfmt); + if (ret != 0) { + goto error_out; + } + ret = ionv4l_mapbufs(dev); +error_out: + return ret; +} + +static int ionv4l_ioctl(ionvideo_dev_t *dev, int request, void *arg) +{ + int ret; + ionv4l_dev_t *v4l = dev->devpriv; + ret = ioctl(v4l->v4l_fd, request, arg); + if (ret == -1 && errno) { + ret = -errno; + } + return ret; +} + +int ionv4l_release(ionvideo_dev_t *dev) +{ + int ret = -1; + ionv4l_dev_t *v4l = dev->devpriv; + if (v4l->v4l_fd < 0) { + return 0; + } + ionv4l_stop(dev); + ionv4l_unmapbufs(dev); + if (v4l->v4l_fd >= 0) { + ret = close(v4l->v4l_fd); + } + v4l->v4l_fd = -1; + free(dev); + if (ret == -1 && errno) { + ret = -errno; + } + + return ret; +} + +int ionv4l_dequeue_buf(ionvideo_dev_t *dev, vframebuf_t *vf) +{ + struct v4l2_buffer vbuf; + CLEAR(vbuf); + int ret; + ionv4l_dev_t *v4l = dev->devpriv; + vbuf.type = v4l->type; + vbuf.memory = v4l->memory_mode; + vbuf.length = vf->length; + ret = ionv4l_ioctl(dev, VIDIOC_DQBUF, &vbuf); + if (!ret && vbuf.index < v4l->buffer_num) { + vf->pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF; + vf->pts <<= 32; + vf->pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF; + vf->fd = vbuf.m.fd; + vf->index = vbuf.index; + } + + return ret; +} + +int ionv4l_queue_buf(ionvideo_dev_t *dev, vframebuf_t *vf) +{ + struct v4l2_buffer vbuf; + CLEAR(vbuf); + int ret; + ionv4l_dev_t *v4l = dev->devpriv; + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_DMABUF; + vbuf.index = vf->index; + vbuf.m.fd = vf->fd; + vbuf.length = vf->length; + return ionv4l_ioctl(dev, VIDIOC_QBUF, &vbuf); +} + +int ionv4l_start(ionvideo_dev_t *dev) +{ + int type; + ionv4l_dev_t *v4l = dev->devpriv; + type = v4l->type; + return ionv4l_ioctl(dev, VIDIOC_STREAMON, &type); +} + +int ionv4l_stop(ionvideo_dev_t *dev) +{ + int type; + ionv4l_dev_t *v4l = dev->devpriv; + type = v4l->type; + return ionv4l_ioctl(dev, VIDIOC_STREAMOFF, &type); +} + +int ionv4l_setfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt) +{ + return ionv4l_ioctl(dev, VIDIOC_S_FMT, fmt); +} + +int ionv4l_getfmt(ionvideo_dev_t *dev, struct v4l2_format *fmt) +{ + return ionv4l_ioctl(dev, VIDIOC_G_FMT, fmt); +} + +static int ionv4l_unmapbufs(ionvideo_dev_t *dev) +{ + return 0; +} + +static int ionv4l_mapbufs(ionvideo_dev_t *dev) +{ + int ret; + struct v4l2_requestbuffers rb; + CLEAR(rb); + ionv4l_dev_t *v4l = dev->devpriv; + rb.count = v4l->buffer_num; + rb.type = v4l->type; + rb.memory = v4l->memory_mode; + return ionv4l_ioctl(dev, VIDIOC_REQBUFS, &rb); +} + +ionvideo_dev_t *new_ionv4l(void) +{ + ionvideo_dev_t *dev; + ionv4l_dev_t *v4l; + dev = malloc(sizeof(ionvideo_dev_t) + sizeof(ionv4l_dev_t)); + memset(dev, 0, sizeof(ionvideo_dev_t) + sizeof(ionv4l_dev_t)); + dev->devpriv = (void *)((long)(&dev->devpriv) + 4); + v4l = dev->devpriv; + v4l->memory_mode = V4L2_MEMORY_DMABUF; + dev->ops.init = ionv4l_init; + dev->ops.release = ionv4l_release; + dev->ops.dequeuebuf = ionv4l_dequeue_buf; + dev->ops.queuebuf = ionv4l_queue_buf; + dev->ops.start = ionv4l_start; + dev->ops.stop = ionv4l_stop; + dev->ops.getparameters = ionv4l_getfmt; + v4l->v4l_fd = open(V4LDEVICE_NAME, O_RDWR | O_NONBLOCK); + if (v4l->v4l_fd < 0) { + free(dev); + LOGE("v4l device opend failed!,%s(%d)\n", strerror(errno), errno); + return NULL; + } + return dev; +} + diff --git a/amvdec/ionv4l.h b/amvdec/ionv4l.h new file mode 100644 index 0000000..c687cc0 --- a/dev/null +++ b/amvdec/ionv4l.h @@ -0,0 +1,18 @@ +#ifndef IONV4L_HEAD_A__ +#define IONV4L_HEAD_A__ +#include <ionvideo.h> + +typedef struct ionv4l_dev { + int v4l_fd; + unsigned int buffer_num; + vframebuf_t *vframe; + int type; + int width; + int height; + int pixformat; + int memory_mode; +} ionv4l_dev_t; +ionvideo_dev_t *new_ionv4l(void); +int ionv4l_release(ionvideo_dev_t *dev); + +#endif//IONV4L_HEAD_A__ diff --git a/amvdec/ionvdec_priv.h b/amvdec/ionvdec_priv.h new file mode 100644 index 0000000..767eefe --- a/dev/null +++ b/amvdec/ionvdec_priv.h @@ -0,0 +1,17 @@ +#ifndef IONVDEC_PRIV_HEADER__ +#define IONVDEC_PRIV_HEADER__ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> +#include <string.h> +#include <videodev2.h> +#include <android/log.h> + +#define TAG "ionvdec" +#define XLOG(V,T,...) __android_log_print(V,T,__VA_ARGS__) +#define LOGI(...) XLOG(ANDROID_LOG_INFO,TAG,__VA_ARGS__) +#define LOGE(...) XLOG(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) + +#endif diff --git a/amvdec/ionvideo.c b/amvdec/ionvideo.c new file mode 100644 index 0000000..7832731 --- a/dev/null +++ b/amvdec/ionvideo.c @@ -0,0 +1,82 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ionvideo.h> +#include "ionvdec_priv.h" +#include "ionv4l.h" + +ionvideo_dev_t *new_ionvideo(int flags) +{ + ionvideo_dev_t *dev = NULL; + if (flags & FLAGS_V4L_MODE) { + dev = new_ionv4l(); + if (dev) { + dev->mode = FLAGS_V4L_MODE; + } + } + return dev; +} +int ionvideo_setparameters(ionvideo_dev_t *dev, int cmd, void * parameters) +{ + return 0; +} +int ionvideo_getparameters(ionvideo_dev_t *dev, int *width, int *height, int *pixelformat) +{ + struct v4l2_format v4lfmt; + int ret = 0; + + v4lfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (dev->ops.getparameters) { + ret = dev->ops.getparameters(dev, &v4lfmt); + if (ret) { + return ret; + } + *width = v4lfmt.fmt.pix.width; + *height = v4lfmt.fmt.pix.height; + *pixelformat = v4lfmt.fmt.pix.pixelformat; + } + return 0; +} +int ionvideo_init(ionvideo_dev_t *dev, int flags, int width, int height, int fmt, int buffernum) +{ + int ret = -1; + if (dev->ops.init) { + ret = dev->ops.init(dev, O_RDWR | O_NONBLOCK, width, height, fmt, buffernum); + } + return ret; +} +int ionvideo_start(ionvideo_dev_t *dev) +{ + if (dev->ops.start) { + return dev->ops.start(dev); + } + return 0; +} +int ionvideo_stop(ionvideo_dev_t *dev) +{ + if (dev->ops.stop) { + return dev->ops.stop(dev); + } + return 0; +} +int ionvideo_release(ionvideo_dev_t *dev) +{ + if (dev->mode == FLAGS_V4L_MODE) { + ionv4l_release(dev); + } + return 0; +} +int ionv4l_dequeuebuf(ionvideo_dev_t *dev, vframebuf_t*vf) +{ + if (dev->ops.dequeuebuf) { + return dev->ops.dequeuebuf(dev, vf); + } + return -1; +} +int ionv4l_queuebuf(ionvideo_dev_t *dev, vframebuf_t*vf) +{ + if (dev->ops.queuebuf) { + return dev->ops.queuebuf(dev, vf); + } + return 0; +} diff --git a/drivers/Makefile b/drivers/Makefile deleted file mode 100644 index f2a5148..0000000 --- a/drivers/Makefile +++ b/dev/null @@ -1,4 +0,0 @@ -obj-y += common/ -obj-y += frame_provider/ -obj-y += frame_sink/ -obj-y += stream_input/ diff --git a/drivers/common/Makefile b/drivers/common/Makefile deleted file mode 100644 index 77ce080..0000000 --- a/drivers/common/Makefile +++ b/dev/null @@ -1,2 +0,0 @@ -obj-y += media_clock/ -obj-y += firmware/ diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c deleted file mode 100644 index f2e7fa6..0000000 --- a/drivers/common/chips/chips.c +++ b/dev/null @@ -1,158 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/chips/chips.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/module.h> -#include <linux/types.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> - -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/old_cpu_version.h> -#include "../../stream_input/amports/amports_priv.h" -#include "../../frame_provider/decoder/utils/vdec.h" -#include "chips.h" -#include <linux/amlogic/media/utils/log.h> - -#define VIDEO_FIRMWARE_FATHER_NAME "video" - -/* -*#define MESON_CPU_MAJOR_ID_M6 0x16 -*#define MESON_CPU_MAJOR_ID_M6TV 0x17 -*#define MESON_CPU_MAJOR_ID_M6TVL 0x18 -*#define MESON_CPU_MAJOR_ID_M8 0x19 -*#define MESON_CPU_MAJOR_ID_MTVD 0x1A -*#define MESON_CPU_MAJOR_ID_M8B 0x1B -*#define MESON_CPU_MAJOR_ID_MG9TV 0x1C -*#define MESON_CPU_MAJOR_ID_M8M2 0x1D -*#define MESON_CPU_MAJOR_ID_GXBB 0x1F -*#define MESON_CPU_MAJOR_ID_GXTVBB 0x20 -*#define MESON_CPU_MAJOR_ID_GXL 0x21 -*#define MESON_CPU_MAJOR_ID_GXM 0x22 -*#define MESON_CPU_MAJOR_ID_TXL 0x23 -*/ -struct type_name { - - int type; - - const char *name; -}; -static const struct type_name cpu_type_name[] = { - {MESON_CPU_MAJOR_ID_M6, "m6"}, - {MESON_CPU_MAJOR_ID_M6TV, "m6tv"}, - {MESON_CPU_MAJOR_ID_M6TVL, "m6tvl"}, - {MESON_CPU_MAJOR_ID_M8, "m8"}, - {MESON_CPU_MAJOR_ID_MTVD, "mtvd"}, - {MESON_CPU_MAJOR_ID_M8B, "m8b"}, - {MESON_CPU_MAJOR_ID_MG9TV, "mg9tv"}, - {MESON_CPU_MAJOR_ID_M8M2, "m8"}, - {MESON_CPU_MAJOR_ID_GXBB, "gxbb"}, - {MESON_CPU_MAJOR_ID_GXTVBB, "gxtvbb"}, - {MESON_CPU_MAJOR_ID_GXL, "gxl"}, - {MESON_CPU_MAJOR_ID_GXM, "gxm"}, - {MESON_CPU_MAJOR_ID_TXL, "txl"}, - {0, NULL}, -}; - -static const char *get_type_name(const struct type_name *typename, int size, - int type) -{ - - const char *name = "unknown"; - - int i; - - for (i = 0; i < size; i++) { - - if (type == typename[i].type) - - name = typename[i].name; - - } - - return name; -} - -const char *get_cpu_type_name(void) -{ - - return get_type_name(cpu_type_name, - sizeof(cpu_type_name) / sizeof(struct type_name), - get_cpu_type()); -} -EXPORT_SYMBOL(get_cpu_type_name); - -/* -*enum vformat_e { -* VFORMAT_MPEG12 = 0, -* VFORMAT_MPEG4, -* VFORMAT_H264, -* VFORMAT_MJPEG, -* VFORMAT_REAL, -* VFORMAT_JPEG, -* VFORMAT_VC1, -* VFORMAT_AVS, -* VFORMAT_YUV, -* VFORMAT_H264MVC, -* VFORMAT_H264_4K2K, -* VFORMAT_HEVC, -* VFORMAT_H264_ENC, -* VFORMAT_JPEG_ENC, -* VFORMAT_VP9, -* VFORMAT_MAX -*}; -*/ -static const struct type_name vformat_type_name[] = { - {VFORMAT_MPEG12, "mpeg12"}, - {VFORMAT_MPEG4, "mpeg4"}, - {VFORMAT_H264, "h264"}, - {VFORMAT_MJPEG, "mjpeg"}, - {VFORMAT_REAL, "real"}, - {VFORMAT_JPEG, "jpeg"}, - {VFORMAT_VC1, "vc1"}, - {VFORMAT_AVS, "avs"}, - {VFORMAT_YUV, "yuv"}, - {VFORMAT_H264MVC, "h264mvc"}, - {VFORMAT_H264_4K2K, "h264_4k"}, - {VFORMAT_HEVC, "hevc"}, - {VFORMAT_H264_ENC, "h264_enc"}, - {VFORMAT_JPEG_ENC, "jpeg_enc"}, - {VFORMAT_VP9, "vp9"}, - {VFORMAT_YUV, "yuv"}, - {0, NULL}, -}; - -const char *get_video_format_name(enum vformat_e type) -{ - - return get_type_name(vformat_type_name, - sizeof(vformat_type_name) / sizeof(struct type_name), type); -} -EXPORT_SYMBOL(get_video_format_name); - -static struct chip_vdec_info_s current_chip_info; - -struct chip_vdec_info_s *get_current_vdec_chip(void) -{ - - return ¤t_chip_info; -} -EXPORT_SYMBOL(get_current_vdec_chip); - diff --git a/drivers/common/chips/chips.h b/drivers/common/chips/chips.h deleted file mode 100644 index 7a9faba..0000000 --- a/drivers/common/chips/chips.h +++ b/dev/null @@ -1,39 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/chips/chips.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 UCODE_MANAGER_HEADER -#define UCODE_MANAGER_HEADER -#include "../firmware/firmware.h" -#include "../media_clock/clk/clk_priv.h" - -struct chip_vdec_info_s { - - int cpu_type; - - struct video_firmware_s *firmware; - - struct chip_vdec_clk_s *clk_mgr[VDEC_MAX]; - - struct clk_set_setting *clk_setting_array; -}; - -const char *get_cpu_type_name(void); -const char *get_video_format_name(enum vformat_e type); - -struct chip_vdec_info_s *get_current_vdec_chip(void); - -#endif diff --git a/drivers/common/firmware/Makefile b/drivers/common/firmware/Makefile deleted file mode 100644 index 748039c..0000000 --- a/drivers/common/firmware/Makefile +++ b/dev/null @@ -1,3 +0,0 @@ -obj-m += firmware.o -firmware-objs += firmware_drv.o -firmware-objs += firmware_type.o diff --git a/drivers/common/firmware/firmware.h b/drivers/common/firmware/firmware.h deleted file mode 100644 index b7d56d7..0000000 --- a/drivers/common/firmware/firmware.h +++ b/dev/null @@ -1,113 +0,0 @@ -/* - * drivers/amlogic/media/common/firmware/firmware.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 __VIDEO_FIRMWARE_HEADER_ -#define __VIDEO_FIRMWARE_HEADER_ -#include <linux/types.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/cdev.h> -#include "firmware_type.h" -#include <linux/amlogic/media/utils/vformat.h> - - -struct firmware_mgr_s { - struct list_head head; - spinlock_t lock; -}; - -struct firmware_info_s { - struct list_head node; - char name[32]; - char path[64]; - enum firmware_type_e type; - struct firmware_s *data; -}; - -struct ucode_info_s { - int cpu; - enum firmware_type_e type; - const char *name; -}; - -struct firmware_header_s { - int magic; - int checksum; - char name[32]; - char cpu[16]; - char format[32]; - char version[32]; - char author[32]; - char date[32]; - char commit[16]; - int data_size; - unsigned int time; - char reserved[128]; -}; - -struct firmware_s { - union { - struct firmware_header_s header; - char buf[512]; - }; - char data[0]; -}; - - -struct package_header_s { - int magic; - int size; - int checksum; - char reserved[128]; -}; - -struct package_s { - union { - struct package_header_s header; - char buf[256]; - }; - char data[0]; -}; - -struct info_header_s { - char name[32]; - char format[32]; - char cpu[32]; - int length; -}; - -struct package_info_s { - union { - struct info_header_s header; - char buf[256]; - }; - char data[0]; -}; - - -struct firmware_dev_s { - struct cdev cdev; - struct device *dev; - dev_t dev_no; -}; - -int get_decoder_firmware_data(enum vformat_e type, - const char *file_name, char *buf, int size); -int get_data_from_name(const char *name, char *buf); -int get_firmware_data(enum firmware_type_e type, char *buf); - -#endif diff --git a/drivers/common/firmware/firmware_cfg.h b/drivers/common/firmware/firmware_cfg.h deleted file mode 100644 index be919ff..0000000 --- a/drivers/common/firmware/firmware_cfg.h +++ b/dev/null @@ -1,32 +0,0 @@ -/* - * drivers/amlogic/media/common/firmware/firmware_cfg.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. - * -*/ - -/*all firmwares in one bin.*/ -{MESON_CPU_MAJOR_ID_GXBB, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXTVBB, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXM, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_TXL, VIDEO_PACKAGE, "video_ucode.bin"}, - -/*firmware for a special format, to replace the format in the package.*/ -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_HEVC, "h265.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_H264, "h264.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_H264_MULTI, "h264_multi.bin"}, -{MESON_CPU_MAJOR_ID_GXM, VIDEO_ENC_H264, "gx_h264_enc.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_ENC_H264, "gx_h264_enc.bin"}, - - diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c deleted file mode 100644 index 56420e1..0000000 --- a/drivers/common/firmware/firmware_drv.c +++ b/dev/null @@ -1,682 +0,0 @@ -/* - * drivers/amlogic/media/common/firmware/firmware.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/module.h> -#include <linux/types.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/slab.h> - -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/old_cpu_version.h> -#include "../../stream_input/amports/amports_priv.h" -#include "../../frame_provider/decoder/utils/vdec.h" -#include "firmware.h" -#include "../chips/chips.h" -#include <linux/string.h> -#include <linux/amlogic/media/utils/log.h> -#include <linux/firmware.h> -#include <linux/amlogic/major.h> -#include <linux/cdev.h> -#include <linux/crc32.h> - -#define CLASS_NAME "firmware_codec" -#define DEV_NAME "firmware_vdec" -#define DIR "video" -#define FRIMWARE_SIZE (64*1024) /*64k*/ -#define BUFF_SIZE (512*1024) - -#define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K') -#define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E') - -static DEFINE_MUTEX(mutex); - -static struct ucode_info_s ucode_info[] = { -#include "firmware_cfg.h" -}; - -static const struct file_operations firmware_fops = { - .owner = THIS_MODULE -}; - -struct firmware_mgr_s *g_mgr; -struct firmware_dev_s *g_dev; - -static u32 debug = 0; - -int get_firmware_data(enum firmware_type_e type, char *buf) -{ - int data_len, ret = -1; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); - return 0; - } - - list_for_each_entry(info, &mgr->head, node) { - if (type != info->type) - continue; - - data_len = info->data->header.data_size; - memcpy(buf, info->data->data, data_len); - ret = data_len; - - break; - } - - return ret; -} -EXPORT_SYMBOL(get_firmware_data); - -int get_data_from_name(const char *name, char *buf) -{ - int data_len, ret = -1; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - char *firmware_name = __getname(); - - if (IS_ERR_OR_NULL(firmware_name)) - return -ENOMEM; - - strcat(firmware_name, name); - strcat(firmware_name, ".bin"); - - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); - return 0; - } - - list_for_each_entry(info, &mgr->head, node) { - if (strcmp(firmware_name, info->name)) - continue; - - data_len = info->data->header.data_size; - memcpy(buf, info->data->data, data_len); - ret = data_len; - - break; - } - - __putname(firmware_name); - - return ret; -} -EXPORT_SYMBOL(get_data_from_name); - -static int request_firmware_from_sys(const char *file_name, - char *buf, int size) -{ - int ret = -1; - const struct firmware *firmware; - - pr_info("Try load %s ...\n", file_name); - - ret = request_firmware(&firmware, file_name, g_dev->dev); - if (ret < 0) { - pr_info("Error : %d can't load the %s.\n", ret, file_name); - goto err; - } - - if (firmware->size > size) { - pr_info("Not enough memory size for ucode.\n"); - ret = -ENOMEM; - goto release; - } - - memcpy(buf, (char *)firmware->data, firmware->size); - - pr_info("load firmware size : %zd, Name : %s.\n", - firmware->size, file_name); - ret = firmware->size; -release: - release_firmware(firmware); -err: - return ret; -} - -int request_decoder_firmware_on_sys(enum vformat_e type, - const char *file_name, char *buf, int size) -{ - int ret; - - ret = get_data_from_name(file_name, buf); - if (ret < 0) - pr_info("Get firmware fail.\n"); - - if (ret > size) { - pr_info("Not enough memory.\n"); - return -ENOMEM; - } - - return ret; -} -int get_decoder_firmware_data(enum vformat_e type, - const char *file_name, char *buf, int size) -{ - int ret; - - ret = request_decoder_firmware_on_sys(type, file_name, buf, size); - if (ret < 0) - pr_info("get_decoder_firmware_data %s for format %d failed!\n", - file_name, type); - - return ret; -} -EXPORT_SYMBOL(get_decoder_firmware_data); - -static unsigned long firmware_mgr_lock(struct firmware_mgr_s *mgr) -{ - unsigned long flags; - - spin_lock_irqsave(&mgr->lock, flags); - return flags; -} - -static void firmware_mgr_unlock(struct firmware_mgr_s *mgr, unsigned long flags) -{ - spin_unlock_irqrestore(&mgr->lock, flags); -} - -static void add_info(struct firmware_info_s *info) -{ - unsigned long flags; - struct firmware_mgr_s *mgr = g_mgr; - - flags = firmware_mgr_lock(mgr); - list_add(&info->node, &mgr->head); - firmware_mgr_unlock(mgr, flags); -} - -static void del_info(struct firmware_info_s *info) -{ - unsigned long flags; - struct firmware_mgr_s *mgr = g_mgr; - - flags = firmware_mgr_lock(mgr); - list_del(&info->node); - firmware_mgr_unlock(mgr, flags); -} - -static void walk_firmware_info(void) -{ - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); - return ; - } - - list_for_each_entry(info, &mgr->head, node) { - if (IS_ERR_OR_NULL(info->data)) - continue; - - pr_info("path : %s.\n", info->path); - pr_info("name : %s.\n", info->name); - pr_info("version : %s.\n", - info->data->header.version); - pr_info("checksum : 0x%x.\n", - info->data->header.checksum); - pr_info("data size : %d.\n", - info->data->header.data_size); - pr_info("author : %s.\n", - info->data->header.author); - pr_info("date : %s.\n", - info->data->header.date); - pr_info("commit : %s.\n\n", - info->data->header.commit); - } -} - -static ssize_t info_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - - if (list_empty(&mgr->head)) { - pbuf += sprintf(pbuf, "No firmware.\n"); - goto out; - } - - list_for_each_entry(info, &mgr->head, node) { - if (IS_ERR_OR_NULL(info->data)) - continue; - - pr_info( "%10s : %s\n", "name", info->name); - pr_info( "%10s : %d\n", "size", - info->data->header.data_size); - pr_info( "%10s : %s\n", "ver", - info->data->header.version); - pr_info( "%10s : 0x%x\n", "sum", - info->data->header.checksum); - pr_info( "%10s : %s\n", "commit", - info->data->header.commit); - pr_info( "%10s : %s\n", "author", - info->data->header.author); - pr_info( "%10s : %s\n\n", "date", - info->data->header.date); - } -out: - return pbuf - buf; -} - -static int set_firmware_info(void) -{ - int ret = 0, i, len; - struct firmware_info_s *info; - int info_size = ARRAY_SIZE(ucode_info); - int cpu = get_cpu_type(); - char *path = __getname(); - const char *name; - - if (IS_ERR_OR_NULL(path)) - return -ENOMEM; - - for (i = 0; i < info_size; i++) { - if (cpu != ucode_info[i].cpu) - continue; - - name = ucode_info[i].name; - if (IS_ERR_OR_NULL(name)) - break; - - len = snprintf(path, PATH_MAX, "%s/%s", DIR, - ucode_info[i].name); - if (len >= PATH_MAX) - continue; - - info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL); - if (IS_ERR_OR_NULL(info)) { - __putname(path); - return -ENOMEM; - } - - strcpy(info->path, path); - strcpy(info->name, name); - info->type = ucode_info[i].type; - info->data = NULL; - - add_info(info); - } - - __putname(path); - - return ret; -} - -static int firmware_probe(char *buf) -{ - int magic = 0; - - memcpy(&magic, buf, sizeof(int)); - return magic; -} - -static int checksum(struct firmware_s *firmware) -{ - unsigned int crc; - - crc = crc32_le(~0U, firmware->data, firmware->header.data_size); - - if (debug) - pr_info("firmware crc result : 0x%x\n", crc ^ ~0U); - - return firmware->header.checksum != (crc ^ ~0U) ? 0 : 1; -} - -static int check_repeat(struct firmware_s *data, enum firmware_type_e type) -{ - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); - return -1; - } - - list_for_each_entry(info, &mgr->head, node) { - if (info->type != type) - continue; - - if (IS_ERR_OR_NULL(info->data)) - info->data = data; - - return 1; - } - - return 0; -} - -static int firmware_parse_package(char *buf, int size) -{ - int ret = 0; - struct package_info_s *pack_info; - struct firmware_info_s *info; - struct firmware_s *data; - char *pack_data; - int info_len, len; - char *path = __getname(); - - if (IS_ERR_OR_NULL(path)) - return -ENOMEM; - - pack_data = ((struct package_s *)buf)->data; - pack_info = (struct package_info_s *)pack_data; - info_len = sizeof(struct package_info_s); - - for (;;) { - if (!pack_info->header.length) - break; - - len = snprintf(path, PATH_MAX, "%s/%s", DIR, - pack_info->header.name); - if (len >= PATH_MAX) - continue; - - info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL); - if (IS_ERR_OR_NULL(info)) { - ret = -ENOMEM; - goto out; - } - - data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL); - if (IS_ERR_OR_NULL(data)) { - kfree(info); - ret = -ENOMEM; - goto out; - } - - strcpy(info->path, path); - strcpy(info->name, pack_info->header.name); - info->type = get_firmware_type(pack_info->header.format); - - len = pack_info->header.length; - memcpy(data, pack_info->data, len); - - pack_data += (pack_info->header.length + info_len); - pack_info = (struct package_info_s *)pack_data; - - ret = checksum(data); - if (!ret) { - pr_info("check sum fail !\n"); - kfree(data); - kfree(info); - goto out; - } - - ret = check_repeat(data, info->type); - if (ret < 0) { - kfree(data); - kfree(info); - goto out; - } - - if (ret) { - kfree(info); - continue; - } - - info->data = data; - add_info(info); - } -out: - __putname(path); - - return ret; -} - -static int firmware_parse_code(struct firmware_info_s *info, - char *buf, int size) -{ - if (!IS_ERR_OR_NULL(info->data)) - kfree(info->data); - - info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL); - if (IS_ERR_OR_NULL(info->data)) - return -ENOMEM; - - memcpy(info->data, buf, size); - - if (!checksum(info->data)) { - pr_info("check sum fail !\n"); - kfree(info->data); - return -1; - } - - return 0; -} - -static int get_firmware_from_sys(const char *path, - char *buf, int size) -{ - int len = 0; - - len = request_firmware_from_sys(path, buf, size); - if (len < 0) - pr_info("get data from fsys fail.\n"); - - return len; -} - -static int set_firmware_data(void) -{ - int ret = 0, magic = 0; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info, *temp; - char *buf = NULL; - int size; - - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); - return 0; - } - - buf = vmalloc(BUFF_SIZE); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - list_for_each_entry_safe(info, temp, &mgr->head, node) { - size = get_firmware_from_sys(info->path, buf, BUFF_SIZE); - magic = firmware_probe(buf); - - switch (magic) { - case PACK: - ret = firmware_parse_package(buf, size); - - del_info(info); - kfree(info); - break; - - case CODE: - ret = firmware_parse_code(info, buf, size); - break; - - default: - del_info(info); - pr_info("invaild type.\n"); - } - - memset(buf, 0, BUFF_SIZE); - } - - if (debug) - walk_firmware_info(); - - vfree(buf); - - return ret; -} - -static int firmware_pre_load(void) -{ - int ret = -1; - - ret = set_firmware_info(); - if (ret < 0) { - pr_info("Get path fail.\n"); - goto err; - } - - ret = set_firmware_data(); - if (ret < 0) { - pr_info("Set data fail.\n"); - goto err; - } -err: - return ret; -} - -static int firmware_mgr_init(void) -{ - g_mgr = kzalloc(sizeof(struct firmware_mgr_s), GFP_KERNEL); - if (IS_ERR_OR_NULL(g_mgr)) - return -ENOMEM; - - INIT_LIST_HEAD(&g_mgr->head); - spin_lock_init(&g_mgr->lock); - - return 0; -} - -static struct class_attribute firmware_class_attrs[] = { - __ATTR_RO(info), - __ATTR_NULL -}; - -static struct class firmware_class = { - .name = CLASS_NAME, - .class_attrs = firmware_class_attrs, -}; - -static int firmware_driver_init(void) -{ - int ret = -1; - - g_dev = kzalloc(sizeof(struct firmware_dev_s), GFP_KERNEL); - if (IS_ERR_OR_NULL(g_dev)) - return -ENOMEM; - - g_dev->dev_no = MKDEV(AMSTREAM_MAJOR, 100); - - ret = register_chrdev_region(g_dev->dev_no, 1, DEV_NAME); - if (ret < 0) { - pr_info("Can't get major number %d.\n", AMSTREAM_MAJOR); - goto err; - } - - cdev_init(&g_dev->cdev, &firmware_fops); - g_dev->cdev.owner = THIS_MODULE; - - ret = cdev_add(&g_dev->cdev, g_dev->dev_no, 1); - if (ret) { - pr_info("Error %d adding cdev fail.\n", ret); - goto err; - } - - ret = class_register(&firmware_class); - if (ret < 0) { - pr_info("Failed in creating class.\n"); - goto err; - } - - g_dev->dev = device_create(&firmware_class, NULL, - g_dev->dev_no, NULL, DEV_NAME); - if (IS_ERR_OR_NULL(g_dev->dev)) { - pr_info("Create device failed.\n"); - ret = -ENODEV; - goto err; - } - - pr_info("Registered firmware driver success.\n"); -err: - return ret; -} - -static void firmware_info_clean(void) -{ - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - unsigned long flags; - - flags = firmware_mgr_lock(mgr); - while (!list_empty(&mgr->head)) { - info = list_entry(mgr->head.next, - struct firmware_info_s, node); - list_del(&info->node); - kfree(info->data); - kfree(info); - } - firmware_mgr_unlock(mgr, flags); - - kfree(g_mgr); -} - -static void firmware_driver_exit(void) -{ - cdev_del(&g_dev->cdev); - device_destroy(&firmware_class, g_dev->dev_no); - class_unregister(&firmware_class); - unregister_chrdev_region(g_dev->dev_no, 1); - kfree(g_dev); -} - -static int __init firmware_module_init(void) -{ - int ret = -1; - - ret = firmware_driver_init(); - if (ret) { - pr_info("Error %d firmware driver init fail.\n", ret); - goto err; - } - - ret = firmware_mgr_init(); - if (ret) { - pr_info("Error %d firmware mgr init fail.\n", ret); - goto err; - } - - ret = firmware_pre_load(); - if (ret) { - pr_info("Error %d firmware pre load fail.\n", ret); - goto err; - } -err: - return ret; -} - -static void __exit firmware_module_exit(void) -{ - firmware_info_clean(); - firmware_driver_exit(); - pr_info("Firmware driver cleaned up.\n"); -} - -module_param(debug, uint, 0664); - -module_init(firmware_module_init); -module_exit(firmware_module_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>"); diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c deleted file mode 100644 index cf5e306..0000000 --- a/drivers/common/firmware/firmware_type.c +++ b/dev/null @@ -1,57 +0,0 @@ -#include "firmware_type.h" - -static const struct type_name_s type_name[] = { - {VIDEO_DEC_MPEG12, "mpeg12"}, - {VIDEO_DEC_MPEG4_3, "divx311"}, - {VIDEO_DEC_MPEG4_4, "divx4x"}, - {VIDEO_DEC_MPEG4_5, "xvid"}, - {VIDEO_DEC_H263, "h263"}, - {VIDEO_DEC_MJPEG, "mjpeg"}, - {VIDEO_DEC_MJPEG_MULTI, "mjpeg_multi"}, - {VIDEO_DEC_REAL_V8, "real_v8"}, - {VIDEO_DEC_REAL_V9, "real_v9"}, - {VIDEO_DEC_VC1, "vc1"}, - {VIDEO_DEC_AVS, "avs"}, - {VIDEO_DEC_H264, "h264"}, - {VIDEO_DEC_H264_4k2K, "h264_4k2k"}, - {VIDEO_DEC_H264_4k2K_SINGLE, "h264_4k2k_single"}, - {VIDEO_DEC_H264_MVC, "h264_mvc"}, - {VIDEO_DEC_H264_MULTI, "h264_multi"}, - {VIDEO_DEC_HEVC, "hevc"}, - {VIDEO_DEC_HEVC_MMU, "hevc_mmu"}, - {VIDEO_DEC_VP9, "vp9"}, - {VIDEO_DEC_VP9_MMU, "vp9_mmu"}, - {VIDEO_ENC_H264, "h264_enc"}, - {VIDEO_ENC_JPEG, "jpeg_enc"}, - {FIRMWARE_MAX, "unknown"}, -}; - - -const char *get_firmware_type_name(enum firmware_type_e type) -{ - const char *name = "unknown"; - int i, size = ARRAY_SIZE(type_name); - - for (i = 0; i < size; i++) { - if (type == type_name[i].type) - name = type_name[i].name; - } - - return name; -} -EXPORT_SYMBOL(get_firmware_type_name); - -enum firmware_type_e get_firmware_type(const char *name) -{ - enum firmware_type_e type = FIRMWARE_MAX; - int i, size = ARRAY_SIZE(type_name); - - for (i = 0; i < size; i++) { - if (!strcmp(name, type_name[i].name)) - type = type_name[i].type; - } - - return type; -} -EXPORT_SYMBOL(get_firmware_type); - diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h deleted file mode 100644 index 74c962f..0000000 --- a/drivers/common/firmware/firmware_type.h +++ b/dev/null @@ -1,41 +0,0 @@ -#ifndef __VIDEO_FIRMWARE_FORMAT_ -#define __VIDEO_FIRMWARE_FORMAT_ - -#include <linux/slab.h> - -enum firmware_type_e { - VIDEO_DEC_MPEG12, - VIDEO_DEC_MPEG4_3, - VIDEO_DEC_MPEG4_4, - VIDEO_DEC_MPEG4_5, - VIDEO_DEC_H263, - VIDEO_DEC_MJPEG, - VIDEO_DEC_MJPEG_MULTI, - VIDEO_DEC_REAL_V8, - VIDEO_DEC_REAL_V9, - VIDEO_DEC_VC1, - VIDEO_DEC_AVS, - VIDEO_DEC_H264, - VIDEO_DEC_H264_4k2K, - VIDEO_DEC_H264_4k2K_SINGLE, - VIDEO_DEC_H264_MVC, - VIDEO_DEC_H264_MULTI, - VIDEO_DEC_HEVC, - VIDEO_DEC_HEVC_MMU, - VIDEO_DEC_VP9, - VIDEO_DEC_VP9_MMU, - VIDEO_ENC_H264, - VIDEO_ENC_JPEG, - VIDEO_PACKAGE, - FIRMWARE_MAX -}; - -struct type_name_s { - enum firmware_type_e type; - const char *name; -}; - -const char *get_firmware_type_name(enum firmware_type_e type); -enum firmware_type_e get_firmware_type(const char *name); - -#endif diff --git a/drivers/common/media_clock/Makefile b/drivers/common/media_clock/Makefile deleted file mode 100644 index 25c9a10..0000000 --- a/drivers/common/media_clock/Makefile +++ b/dev/null @@ -1,5 +0,0 @@ -obj-m += media_clock.o -media_clock-objs += ../chips/chips.o -media_clock-objs += clk/clkgx.o -media_clock-objs += clk/clk.o -media_clock-objs += switch/amports_gate.o diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c deleted file mode 100644 index 18d308f..0000000 --- a/drivers/common/media_clock/clk/clk.c +++ b/dev/null @@ -1,405 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/clk/clk.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/module.h> -#include <linux/types.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> - -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/old_cpu_version.h> -#include "../../../stream_input/amports/amports_priv.h" -#include "../../../frame_provider/decoder/utils/vdec.h" -#include "../../chips/chips.h" -#include "clk_priv.h" -#include <linux/amlogic/media/utils/log.h> - -#define p_vdec() (get_current_vdec_chip()->clk_mgr[VDEC_1]) -#define p_vdec2() (get_current_vdec_chip()->clk_mgr[VDEC_2]) -#define p_vdec_hcodec() (get_current_vdec_chip()->clk_mgr[VDEC_HCODEC]) -#define p_vdec_hevc() (get_current_vdec_chip()->clk_mgr[VDEC_HEVC]) - -static int clock_source_wxhxfps_saved[VDEC_MAX + 1]; - -#define IF_HAVE_RUN(p, fn)\ - do {\ - if (p && p->fn)\ - p->fn();\ - } while (0) -/* -*#define IF_HAVE_RUN_P1_RET(p, fn, p1)\ -* do {\ -* pr_debug("%s-----%d\n", __func__, clk);\ -* if (p && p->fn)\ -* return p->fn(p1);\ -* else\ -* return -1;\ -* } while (0) -* -*#define IF_HAVE_RUN_RET(p, fn)\ -* do {\ -* if (p && p->fn)\ -* return p->fn();\ -* else\ -* return 0;\ -* } while (0) -*/ - -int vdec_clock_init(void) -{ - if (p_vdec() && p_vdec()->clock_init) - return p_vdec()->clock_init(); - else - return 0; -} -EXPORT_SYMBOL(vdec_clock_init); - -/* -*clk ==0 : -* to be release. -* released shared clk, -*clk ==1 :default low clk -*clk ==2 :default high clk -*/ -int vdec_clock_set(int clk) -{ - pr_debug("%s-----%d\n", __func__, clk); - if (p_vdec() && p_vdec()->clock_set) - return p_vdec()->clock_set(clk); - else - return -1; -} -EXPORT_SYMBOL(vdec_clock_set); - -void vdec_clock_enable(void) -{ - vdec_clock_set(1); -} -EXPORT_SYMBOL(vdec_clock_enable); - -void vdec_clock_hi_enable(void) -{ - vdec_clock_set(2); -} -EXPORT_SYMBOL(vdec_clock_hi_enable); - -void vdec_clock_on(void) -{ - IF_HAVE_RUN(p_vdec(), clock_on); -} -EXPORT_SYMBOL(vdec_clock_on); - -void vdec_clock_off(void) -{ - IF_HAVE_RUN(p_vdec(), clock_off); - clock_source_wxhxfps_saved[VDEC_1] = 0; -} -EXPORT_SYMBOL(vdec_clock_off); - -int vdec2_clock_set(int clk) -{ - pr_debug("%s-----%d\n", __func__, clk); - if (p_vdec2() && p_vdec2()->clock_set) - return p_vdec2()->clock_set(clk); - else - return -1; -} -EXPORT_SYMBOL(vdec2_clock_set); - -void vdec2_clock_enable(void) -{ - vdec2_clock_set(1); -} -EXPORT_SYMBOL(vdec2_clock_enable); - -void vdec2_clock_hi_enable(void) -{ - vdec2_clock_set(2); -} -EXPORT_SYMBOL(vdec2_clock_hi_enable); - -void vdec2_clock_on(void) -{ - IF_HAVE_RUN(p_vdec2(), clock_on); -} -EXPORT_SYMBOL(vdec2_clock_on); - -void vdec2_clock_off(void) -{ - IF_HAVE_RUN(p_vdec2(), clock_off); - clock_source_wxhxfps_saved[VDEC_2] = 0; -} -EXPORT_SYMBOL(vdec2_clock_off); - -int hcodec_clock_set(int clk) -{ - pr_debug("%s-----%d\n", __func__, clk); - if (p_vdec_hcodec() && p_vdec_hcodec()->clock_set) - return p_vdec_hcodec()->clock_set(clk); - else - return -1; -} -EXPORT_SYMBOL(hcodec_clock_set); - -void hcodec_clock_enable(void) -{ - hcodec_clock_set(1); -} -EXPORT_SYMBOL(hcodec_clock_enable); - -void hcodec_clock_hi_enable(void) -{ - hcodec_clock_set(2); -} -EXPORT_SYMBOL(hcodec_clock_hi_enable); - -void hcodec_clock_on(void) -{ - IF_HAVE_RUN(p_vdec_hcodec(), clock_on); -} -EXPORT_SYMBOL(hcodec_clock_on); - -void hcodec_clock_off(void) -{ - IF_HAVE_RUN(p_vdec_hcodec(), clock_off); - clock_source_wxhxfps_saved[VDEC_HCODEC] = 0; -} -EXPORT_SYMBOL(hcodec_clock_off); - -int hevc_clock_init(void) -{ - if (p_vdec_hevc() && p_vdec_hevc()->clock_init) - return p_vdec_hevc()->clock_init(); - else - return 0; -} -EXPORT_SYMBOL(hevc_clock_init); - -int hevc_clock_set(int clk) -{ - pr_debug("%s-----%d\n", __func__, clk); - if (p_vdec_hevc() && p_vdec_hevc()->clock_set) - return p_vdec_hevc()->clock_set(clk); - else - return -1; -} -EXPORT_SYMBOL(hevc_clock_set); - -void hevc_clock_enable(void) -{ - hevc_clock_set(1); -} -EXPORT_SYMBOL(hevc_clock_enable); - -void hevc_clock_hi_enable(void) -{ - hevc_clock_set(2); -} -EXPORT_SYMBOL(hevc_clock_hi_enable); - -void hevc_clock_on(void) -{ - IF_HAVE_RUN(p_vdec_hevc(), clock_on); -} -EXPORT_SYMBOL(hevc_clock_on); - -void hevc_clock_off(void) -{ - IF_HAVE_RUN(p_vdec_hevc(), clock_off); - clock_source_wxhxfps_saved[VDEC_HEVC] = 0; -} -EXPORT_SYMBOL(hevc_clock_off); - -int vdec_source_get(enum vdec_type_e core) -{ - return clock_source_wxhxfps_saved[core]; -} -EXPORT_SYMBOL(vdec_source_get); - -int vdec_clk_get(enum vdec_type_e core) -{ - return get_current_vdec_chip()->clk_mgr[core]->clock_get(core); -} -EXPORT_SYMBOL(vdec_clk_get); - -int get_clk_with_source(int format, int w_x_h_fps) -{ - struct clk_set_setting *p_setting; - int i; - int clk = -2; - - p_setting = get_current_vdec_chip()->clk_setting_array; - if (!p_setting || format < 0 || format > VFORMAT_MAX) { - pr_info("error on get_clk_with_source ,%p,%d\n", - p_setting, format); - return -1; /*no setting found. */ - } - p_setting = &p_setting[format]; - for (i = 0; i < MAX_CLK_SET; i++) { - if (p_setting->set[i].wh_X_fps > w_x_h_fps) { - clk = p_setting->set[i].clk_Mhz; - break; - } - } - return clk; -} -EXPORT_SYMBOL(get_clk_with_source); - -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); - int ret_clk; - - if (clk < 0) { - pr_info("can't get valid clk for source ,%d,%d,%d\n", - width, height, fps); - if (format >= 1920 && width >= 1080 && fps >= 30) - clk = 2; /*default high clk */ - else - clk = 0; /*default clk. */ - } - if (width * height * fps == 0) - clk = 0; - /* - *clk == 0 - *is used for set default clk; - *if used supper clk. - *changed to default min clk. - */ - - if (format == VFORMAT_HEVC || format == VFORMAT_VP9) { - ret_clk = hevc_clock_set(clk); - clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps; - } else if (format == VFORMAT_H264_ENC && format == VFORMAT_JPEG_ENC) { - ret_clk = hcodec_clock_set(clk); - clock_source_wxhxfps_saved[VDEC_HCODEC] = width * height * fps; - } else if (format == VFORMAT_H264_4K2K && - get_cpu_type() == MESON_CPU_MAJOR_ID_M8) { - ret_clk = vdec2_clock_set(clk); - clock_source_wxhxfps_saved[VDEC_2] = width * height * fps; - ret_clk = vdec_clock_set(clk); - clock_source_wxhxfps_saved[VDEC_1] = width * height * fps; - } else { - ret_clk = vdec_clock_set(clk); - clock_source_wxhxfps_saved[VDEC_1] = width * height * fps; - } - return ret_clk; -} -EXPORT_SYMBOL(vdec_source_changed_for_clk_set); - -static int register_vdec_clk_mgr_per_cpu(int cputype, - enum vdec_type_e vdec_type, struct chip_vdec_clk_s *t_mgr) -{ - - struct chip_vdec_clk_s *mgr; - - if (cputype != get_cpu_type() || vdec_type >= VDEC_MAX) { - /* - *pr_info("ignore vdec clk mgr for vdec[%d] cpu=%d\n", - *vdec_type, cputype); - */ - return 0; /* ignore don't needed firmare. */ - } - mgr = kmalloc(sizeof(struct chip_vdec_clk_s), GFP_KERNEL); - if (!mgr) - return -ENOMEM; - *mgr = *t_mgr; - /* - *pr_info("register vdec clk mgr for vdec[%d]\n", vdec_type); - */ - if (mgr->clock_init) { - if (mgr->clock_init()) { - kfree(mgr); - return -ENOMEM; - } - } - get_current_vdec_chip()->clk_mgr[vdec_type] = mgr; - return 0; -} - -int register_vdec_clk_mgr(int cputype[], enum vdec_type_e vdec_type, - struct chip_vdec_clk_s *t_mgr) -{ - int i = 0; - - while (cputype[i] > 0) { - register_vdec_clk_mgr_per_cpu(cputype[i], vdec_type, t_mgr); - i++; - } - return 0; -} -EXPORT_SYMBOL(register_vdec_clk_mgr); - -int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type) -{ - kfree(get_current_vdec_chip()->clk_mgr[vdec_type]); - - return 0; -} -EXPORT_SYMBOL(unregister_vdec_clk_mgr); - -static int register_vdec_clk_setting_per_cpu(int cputype, - struct clk_set_setting *setting, int size) -{ - - struct clk_set_setting *p_setting; - - if (cputype != get_cpu_type()) { - /* - *pr_info("ignore clk_set_setting for cpu=%d\n", - *cputype); - */ - return 0; /* ignore don't needed this setting . */ - } - p_setting = kmalloc(size, GFP_KERNEL); - if (!p_setting) - return -ENOMEM; - memcpy(p_setting, setting, size); - - pr_info("register clk_set_setting cpu[%d]\n", cputype); - - get_current_vdec_chip()->clk_setting_array = p_setting; - return 0; -} - -int register_vdec_clk_setting(int cputype[], - struct clk_set_setting *p_seting, int size) -{ - int i = 0; - - while (cputype[i] > 0) { - register_vdec_clk_setting_per_cpu(cputype[i], p_seting, size); - i++; - } - return 0; -} -EXPORT_SYMBOL(register_vdec_clk_setting); - -int unregister_vdec_clk_setting(void) -{ - kfree(get_current_vdec_chip()->clk_setting_array); - - return 0; -} -EXPORT_SYMBOL(unregister_vdec_clk_setting); - diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h deleted file mode 100644 index 1c979b4..0000000 --- a/drivers/common/media_clock/clk/clk.h +++ b/dev/null @@ -1,155 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/clk/clk.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_CHIP_CLK_HEADER -#define VDEC_CHIP_CLK_HEADER -#include <linux/types.h> -#include <linux/init.h> -#include <linux/module.h> -#include "clk_priv.h" -#include <linux/amlogic/media/clk/gp_pll.h> - -#ifndef INCLUDE_FROM_ARCH_CLK_MGR -int vdec_clock_init(void); -int vdec_clock_set(int clk); -int vdec2_clock_set(int clk); - -int hcodec_clock_set(int clk); -int hevc_clock_init(void); -int hevc_clock_set(int clk); - -void vdec_clock_on(void); -void vdec_clock_off(void); -void vdec2_clock_on(void); - -void vdec2_clock_off(void); -void hcodec_clock_on(void); -void hcodec_clock_off(void); -void hevc_clock_on(void); -void hevc_clock_off(void); - -int vdec_source_get(enum vdec_type_e core); -int vdec_clk_get(enum vdec_type_e core); - -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); - -void vdec_clock_enable(void); -void vdec_clock_hi_enable(void); -void hcodec_clock_enable(void); -void hcodec_clock_hi_enable(void); -void hevc_clock_enable(void); -void hevc_clock_hi_enable(void); -void vdec2_clock_enable(void); -void vdec2_clock_hi_enable(void); -void set_clock_gate(struct gate_switch_node *nodes, int num); - -#endif -int register_vdec_clk_mgr(int cputype[], - enum vdec_type_e vdec_type, struct chip_vdec_clk_s *t_mgr); - -int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type); - -int register_vdec_clk_setting(int cputype[], - struct clk_set_setting *p_seting, int size); - -int unregister_vdec_clk_setting(void); - -#ifdef INCLUDE_FROM_ARCH_CLK_MGR -static struct chip_vdec_clk_s vdec_clk_mgr __initdata = { - .clock_init = vdec_clock_init, - .clock_set = vdec_clock_set, - .clock_on = vdec_clock_on, - .clock_off = vdec_clock_off, - .clock_get = vdec_clock_get, -}; - -#ifdef VDEC_HAS_VDEC2 -static struct chip_vdec_clk_s vdec2_clk_mgr __initdata = { - .clock_set = vdec2_clock_set, - .clock_on = vdec2_clock_on, - .clock_off = vdec2_clock_off, - .clock_get = vdec_clock_get, -}; -#endif - -#ifdef VDEC_HAS_HEVC -static struct chip_vdec_clk_s vdec_hevc_clk_mgr __initdata = { - .clock_init = hevc_clock_init, - .clock_set = hevc_clock_set, - .clock_on = hevc_clock_on, - .clock_off = hevc_clock_off, - .clock_get = vdec_clock_get, -}; -#endif - -#ifdef VDEC_HAS_VDEC_HCODEC -static struct chip_vdec_clk_s vdec_hcodec_clk_mgr __initdata = { - .clock_set = hcodec_clock_set, - .clock_on = hcodec_clock_on, - .clock_off = hcodec_clock_off, - .clock_get = vdec_clock_get, -}; -#endif - -static int __init vdec_init_clk(void) -{ - int cpus[] = CLK_FOR_CPU; - register_vdec_clk_mgr(cpus, VDEC_1, &vdec_clk_mgr); -#ifdef VDEC_HAS_VDEC2 - register_vdec_clk_mgr(cpus, VDEC_2, &vdec2_clk_mgr); -#endif -#ifdef VDEC_HAS_HEVC - register_vdec_clk_mgr(cpus, VDEC_HEVC, &vdec_hevc_clk_mgr); -#endif -#ifdef VDEC_HAS_VDEC_HCODEC - register_vdec_clk_mgr(cpus, VDEC_HCODEC, &vdec_hcodec_clk_mgr); -#endif - -#ifdef VDEC_HAS_CLK_SETTINGS - register_vdec_clk_setting(cpus, - clks_for_formats, sizeof(clks_for_formats)); -#endif - return 0; -} - -static void __exit vdec_clk_exit(void) -{ - unregister_vdec_clk_mgr(VDEC_1); -#ifdef VDEC_HAS_VDEC2 - unregister_vdec_clk_mgr(VDEC_2); -#endif -#ifdef VDEC_HAS_HEVC - unregister_vdec_clk_mgr(VDEC_HEVC); -#endif -#ifdef VDEC_HAS_VDEC_HCODEC - unregister_vdec_clk_mgr(VDEC_HCODEC); -#endif -#ifdef VDEC_HAS_CLK_SETTINGS - unregister_vdec_clk_setting(); -#endif - pr_info("media clock exit.\n"); -} - -#define ARCH_VDEC_CLK_INIT()\ - module_init(vdec_init_clk) - -#define ARCH_VDEC_CLK_EXIT()\ - module_exit(vdec_clk_exit) - -#endif -#endif diff --git a/drivers/common/media_clock/clk/clk_priv.h b/drivers/common/media_clock/clk/clk_priv.h deleted file mode 100644 index 1898e6d..0000000 --- a/drivers/common/media_clock/clk/clk_priv.h +++ b/dev/null @@ -1,38 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/clk/clk_priv.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 AMPORTS_CLK_PRIV_HEADER -#define AMPORTS_CLK_PRIV_HEADER - -struct clk_set { - u32 wh_X_fps; /* [x*y*fps */ - u32 clk_Mhz; /*min MHZ */ -}; -#define MAX_CLK_SET 6 -struct clk_set_setting { - struct clk_set set[MAX_CLK_SET]; -}; - -struct chip_vdec_clk_s { - int (*clock_get)(enum vdec_type_e core); - int (*clock_init)(void); - int (*clock_set)(int clk); - void (*clock_on)(void); - void (*clock_off)(void); - void (*clock_prepare_switch)(void); -}; -#endif diff --git a/drivers/common/media_clock/clk/clkgx.c b/drivers/common/media_clock/clk/clkgx.c deleted file mode 100644 index 8520738..0000000 --- a/drivers/common/media_clock/clk/clkgx.c +++ b/dev/null @@ -1,620 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/clk/clkgx.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/init.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/amlogic/media/clk/gp_pll.h> -#include <linux/amlogic/media/utils/vdec_reg.h> -#include <linux/amlogic/media/utils/amports_config.h> -#include "../../../frame_provider/decoder/utils/vdec.h" -#include <linux/amlogic/media/registers/register.h> -#include "clk_priv.h" -#include <linux/amlogic/media/utils/log.h> - -#include <linux/amlogic/media/registers/register_ops.h> -#include "../switch/amports_gate.h" -#define MHz (1000000) - -struct clk_mux_s { - struct gate_switch_node *vdec_mux_node; - struct gate_switch_node *hcodec_mux_node; - struct gate_switch_node *hevc_mux_node; -}; - -struct clk_mux_s gclk; - -void vdec1_set_clk(int source, int div) -{ - pr_info("vdec1_set_clk %d, %d\n", source, div); - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (source << 9) | (div - 1), 0, 16); -} -EXPORT_SYMBOL(vdec1_set_clk); - -void hcodec_set_clk(int source, int div) -{ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, - (source << 9) | (div - 1), 16, 16); -} -EXPORT_SYMBOL(hcodec_set_clk); - -void vdec2_set_clk(int source, int div) -{ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, - (source << 9) | (div - 1), 0, 16); -} -EXPORT_SYMBOL(vdec2_set_clk); - -void hevc_set_clk(int source, int div) -{ - pr_info("hevc_set_clk %d, %d\n", source, div); - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, - (source << 9) | (div - 1), 16, 16); -} -EXPORT_SYMBOL(hevc_set_clk); - -void vdec_get_clk_source(int clk, int *source, int *div, int *rclk) -{ -#define source_div4 (0) -#define source_div3 (1) -#define source_div5 (2) -#define source_div7 (3) - if (clk > 500) { - *source = source_div3; - *div = 1; - *rclk = 667; - } else if (clk >= 500) { - *source = source_div4; - *div = 1; - *rclk = 500; - } else if (clk >= 400) { - *source = source_div5; - *div = 1; - *rclk = 400; - } else if (clk >= 333) { - *source = source_div3; - *div = 2; - *rclk = 333; - } else if (clk >= 200) { - *source = source_div5; - *div = 2; - *rclk = 200; - } else if (clk >= 166) { - *source = source_div4; - *div = 3; - *rclk = 166; - } else if (clk >= 133) { - *source = source_div5; - *div = 3; - *rclk = 133; - } else if (clk >= 100) { - *source = source_div5; - *div = 4; - *rclk = 100; - } else if (clk >= 50) { - *source = source_div5; - *div = 8; - *rclk = 50; - } else { - *source = source_div5; - *div = 20; - *rclk = 10; - } -} -EXPORT_SYMBOL(vdec_get_clk_source); - -/* set gp0 648M vdec use gp0 clk*/ -#define VDEC1_648M() \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (6 << 9) | (0), 0, 16) - -#define HEVC_648M() \ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, (6 << 9) | (0), 16, 16) - -/*set gp0 1296M vdec use gp0 clk div2*/ -#define VDEC1_648M_DIV() \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (6 << 9) | (1), 0, 16) - -#define HEVC_648M_DIV() \ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, (6 << 9) | (1), 16, 16) - -#define VDEC1_WITH_GP_PLL() \ - ((READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0xe00) == 0xc00) -#define HEVC_WITH_GP_PLL() \ - ((READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0xe000000) == 0xc000000) - -#define VDEC1_CLOCK_ON() \ - do { if (is_meson_m8_cpu()) { \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 8, 1); \ - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); \ - } else { \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 8, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 0, 15, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 0, 8, 1); \ - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); \ - } \ - } while (0) - -#define VDEC2_CLOCK_ON() do {\ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 1, 8, 1); \ - WRITE_VREG(DOS_GCLK_EN1, 0x3ff);\ - } while (0) - -#define HCODEC_CLOCK_ON() do {\ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 24, 1); \ - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);\ - } while (0) -#define HEVC_CLOCK_ON() do {\ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 1, 24, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 0, 31, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 0, 24, 1); \ - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);\ - } while (0) -#define VDEC1_SAFE_CLOCK() do {\ - WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, \ - READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x7f, 0, 7); \ - WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 1, 8, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 1, 15, 1);\ - } while (0) - -#define VDEC1_CLOCK_OFF() \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 0, 8, 1) -#define VDEC2_CLOCK_OFF() \ - WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1) -#define HCODEC_CLOCK_OFF() \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 0, 24, 1) -#define HEVC_SAFE_CLOCK() do { \ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, \ - (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) >> 16) & 0x7f, 16, 7);\ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, \ - (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) >> 25) & 0x7f, 25, 7);\ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 1, 24, 1); \ - WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 1, 31, 1);\ - } while (0) - -#define HEVC_CLOCK_OFF() WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 24, 1) - -static int clock_real_clk[VDEC_MAX + 1]; - -/* -*enum vformat_e { -* VFORMAT_MPEG12 = 0, -* VFORMAT_MPEG4, -* VFORMAT_H264, -* VFORMAT_MJPEG, -* VFORMAT_REAL, -* VFORMAT_JPEG, -* VFORMAT_VC1, -* VFORMAT_AVS, -* VFORMAT_YUV, -* VFORMAT_H264MVC, -* VFORMAT_H264_4K2K, -* VFORMAT_HEVC, -* VFORMAT_H264_ENC, -* VFORMAT_JPEG_ENC, -* VFORMAT_VP9, -* VFORMAT_MAX -*}; -*sample: -*{{1280*720*30, 100}, {1920*1080*30, 166}, {1920*1080*60, 333}, -* {4096*2048*30, 600}, {4096*2048*60, 600}, {INT_MAX, 600},} -*mean: -*width * height * fps -*<720p30fps clk=100MHZ -*>=720p30fps & < 1080p30fps clk=166MHZ -*>=1080p 30fps & < 1080p60fps clk=333MHZ -*/ -static struct clk_set_setting clks_for_formats[] = { - { /*[VFORMAT_MPEG12] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_MPEG4] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_H264] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 21, 166}, - {1920 * 1080 * 30, 333}, - {1920 * 1080 * 60, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_MJPEG] */ - {{1280 * 720 * 30, 200}, {1920 * 1080 * 30, 200}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_REAL] */ - {{1280 * 720 * 20, 200}, {1920 * 1080 * 30, 500}, - {1920 * 1080 * 60, 500}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_JPEG] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_VC1] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_AVS] */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166}, - {1920 * 1080 * 60, 333}, - {4096 * 2048 * 30, 600}, {4096 * 2048 * 60, - 600}, {INT_MAX, 600}, - } - }, - { /*[VFORMAT_YUV] */ - {{1280 * 720 * 30, 100}, {INT_MAX, 100}, - {0, 0}, {0, 0}, {0, 0}, {0, 0}, - } - }, - { /*VFORMAT_H264MVC */ - {{1280 * 720 * 30, 333}, {1920 * 1080 * 30, 333}, - {4096 * 2048 * 60, 600}, - {INT_MAX, 630}, {0, 0}, {0, 0}, - } - }, - { /*VFORMAT_H264_4K2K */ - {{1280 * 720 * 30, 600}, {4096 * 2048 * 60, 630}, - {INT_MAX, 630}, - {0, 0}, {0, 0}, {0, 0}, - } - }, - { /*VFORMAT_HEVC */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 60, 600}, - {4096 * 2048 * 25, 630}, - {4096 * 2048 * 30, 630}, {4096 * 2048 * 60, - 630}, {INT_MAX, 630}, - } - }, - { /*VFORMAT_H264_ENC */ - {{1280 * 720 * 30, 0}, {INT_MAX, 0}, - {0, 0}, {0, 0}, {0, 0}, {0, 0}, - } - }, - { /*VFORMAT_JPEG_ENC */ - {{1280 * 720 * 30, 0}, {INT_MAX, 0}, - {0, 0}, {0, 0}, {0, 0}, {0, 0}, - } - }, - { /*VFORMAT_VP9 */ - {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 100}, - {1920 * 1080 * 60, 166}, - {4096 * 2048 * 30, 333}, {4096 * 2048 * 60, - 630}, {INT_MAX, 630}, - } - }, - -}; - -void set_clock_gate(struct gate_switch_node *nodes, int num) -{ - struct gate_switch_node *node = NULL; - - do { - node = &nodes[num - 1]; - if (IS_ERR_OR_NULL(node)) - pr_info("get mux clk err.\n"); - - if (!strcmp(node->name, "clk_vdec_mux")) - gclk.vdec_mux_node = node; - else if (!strcmp(node->name, "clk_hcodec_mux")) - gclk.hcodec_mux_node = node; - else if (!strcmp(node->name, "clk_hevc_mux")) - gclk.hevc_mux_node = node; - } while(--num); -} -EXPORT_SYMBOL(set_clock_gate); - -static int vdec_set_clk(int dec, int rate) -{ - struct clk *clk = NULL; - - switch (dec) { - case VDEC_1: - clk = gclk.vdec_mux_node->clk; - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); - break; - - case VDEC_HCODEC: - clk = gclk.hcodec_mux_node->clk; - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15); - break; - - case VDEC_2: - clk = gclk.vdec_mux_node->clk; - WRITE_VREG(DOS_GCLK_EN1, 0x3ff); - break; - - case VDEC_HEVC: - clk = gclk.hevc_mux_node->clk; - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); - break; - - case VDEC_MAX: - break; - - default: - pr_info("invaild vdec type.\n"); - } - - if (IS_ERR_OR_NULL(clk)) { - pr_info("the mux clk err.\n"); - return -1; - } - - clk_set_rate(clk, rate); - - return 0; -} - -static int vdec_clock_init(void) -{ - return 0; -} - -static int vdec_clock_set(int clk) -{ - if (clk == 1) - clk = 200; - else if (clk == 2) { - if (clock_real_clk[VDEC_1] != 648) - clk = 500; - else - clk = 648; - } else if (clk == 0) { - if (clock_real_clk[VDEC_1] == 667 || - (clock_real_clk[VDEC_1] == 648) || - clock_real_clk[VDEC_1] <= 0) - clk = 200; - else - clk = clock_real_clk[VDEC_1]; - } - - if ((clk > 500 && clk != 667)) { - if (clock_real_clk[VDEC_1] == 648) - return 648; - clk = 667; - } - - vdec_set_clk(VDEC_1, clk * MHz); - - clock_real_clk[VDEC_1] = clk; - - pr_info("vdec mux clock is %lu Hz\n", - clk_get_rate(gclk.vdec_mux_node->clk)); - - return clk; -} - -static int hevc_clock_init(void) -{ - return 0; -} - -static int hevc_clock_set(int clk) -{ - if (clk == 1) - clk = 200; - else if (clk == 2) { - if (clock_real_clk[VDEC_HEVC] != 648) - clk = 500; - else - clk = 648; - } else if (clk == 0) { - if (clock_real_clk[VDEC_HEVC] == 667 || - (clock_real_clk[VDEC_HEVC] == 648) || - clock_real_clk[VDEC_HEVC] <= 0) - clk = 200; - else - clk = clock_real_clk[VDEC_HEVC]; - } - - if ((clk > 500 && clk != 667)) { - if (clock_real_clk[VDEC_HEVC] == 648) - return 648; - clk = 667; - } - - vdec_set_clk(VDEC_HEVC, clk * MHz); - - clock_real_clk[VDEC_HEVC] = clk; - - pr_info("hevc mux clock is %lu Hz\n", - clk_get_rate(gclk.hevc_mux_node->clk)); - - return clk; -} - -static int hcodec_clock_set(int clk) -{ - if (clk == 1) - clk = 200; - else if (clk == 2) { - if (clock_real_clk[VDEC_HCODEC] != 648) - clk = 500; - else - clk = 648; - } else if (clk == 0) { - if (clock_real_clk[VDEC_HCODEC] == 667 || - (clock_real_clk[VDEC_HCODEC] == 648) || - clock_real_clk[VDEC_HCODEC] <= 0) - clk = 200; - else - clk = clock_real_clk[VDEC_HCODEC]; - } - - if ((clk > 500 && clk != 667)) { - if (clock_real_clk[VDEC_HCODEC] == 648) - return 648; - clk = 667; - } - - vdec_set_clk(VDEC_HCODEC, clk * MHz); - - clock_real_clk[VDEC_HCODEC] = clk; - - pr_info("hcodec mux clock is %lu Hz\n", - clk_get_rate(gclk.hcodec_mux_node->clk)); - - return clk; -} - -static void vdec_clock_on(void) -{ - spin_lock_irqsave(&gclk.vdec_mux_node->lock, - gclk.vdec_mux_node->flags); - if (!gclk.vdec_mux_node->ref_count) - clk_prepare_enable(gclk.vdec_mux_node->clk); - - gclk.vdec_mux_node->ref_count++; - spin_unlock_irqrestore(&gclk.vdec_mux_node->lock, - gclk.vdec_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.vdec_mux_node->name, - gclk.vdec_mux_node->ref_count); -} - -static void vdec_clock_off(void) -{ - spin_lock_irqsave(&gclk.vdec_mux_node->lock, - gclk.vdec_mux_node->flags); - gclk.vdec_mux_node->ref_count--; - if (!gclk.vdec_mux_node->ref_count) - clk_disable_unprepare(gclk.vdec_mux_node->clk); - - clock_real_clk[VDEC_1] = 0; - spin_unlock_irqrestore(&gclk.vdec_mux_node->lock, - gclk.vdec_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.vdec_mux_node->name, - gclk.vdec_mux_node->ref_count); -} - -static void hcodec_clock_on(void) -{ - spin_lock_irqsave(&gclk.hcodec_mux_node->lock, - gclk.hcodec_mux_node->flags); - if (!gclk.hcodec_mux_node->ref_count) - clk_prepare_enable(gclk.hcodec_mux_node->clk); - - gclk.hcodec_mux_node->ref_count++; - spin_unlock_irqrestore(&gclk.hcodec_mux_node->lock, - gclk.hcodec_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.hcodec_mux_node->name, - gclk.hcodec_mux_node->ref_count); -} - -static void hcodec_clock_off(void) -{ - spin_lock_irqsave(&gclk.hcodec_mux_node->lock, - gclk.hcodec_mux_node->flags); - gclk.hcodec_mux_node->ref_count--; - if (!gclk.hcodec_mux_node->ref_count) - clk_disable_unprepare(gclk.hcodec_mux_node->clk); - - spin_unlock_irqrestore(&gclk.hcodec_mux_node->lock, - gclk.hcodec_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.hcodec_mux_node->name, - gclk.hcodec_mux_node->ref_count); -} - -static void hevc_clock_on(void) -{ - spin_lock_irqsave(&gclk.hevc_mux_node->lock, - gclk.hevc_mux_node->flags); - if (!gclk.hevc_mux_node->ref_count) - clk_prepare_enable(gclk.hevc_mux_node->clk); - - gclk.hevc_mux_node->ref_count++; - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); - spin_unlock_irqrestore(&gclk.hevc_mux_node->lock, - gclk.hevc_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.hevc_mux_node->name, - gclk.hevc_mux_node->ref_count); -} - -static void hevc_clock_off(void) -{ - spin_lock_irqsave(&gclk.hevc_mux_node->lock, - gclk.hevc_mux_node->flags); - gclk.hevc_mux_node->ref_count--; - if (!gclk.hevc_mux_node->ref_count) - clk_disable_unprepare(gclk.hevc_mux_node->clk); - - clock_real_clk[VDEC_HEVC] = 0; - spin_unlock_irqrestore(&gclk.hevc_mux_node->lock, - gclk.hevc_mux_node->flags); - - pr_info("the %-15s clock off, ref cnt: %d\n", - gclk.hevc_mux_node->name, - gclk.hevc_mux_node->ref_count); -} - -static int vdec_clock_get(enum vdec_type_e core) -{ - if (core >= VDEC_MAX) - return 0; - - return clock_real_clk[core]; -} - -#define INCLUDE_FROM_ARCH_CLK_MGR - -/*#define VDEC_HAS_VDEC2*/ -#define VDEC_HAS_HEVC -#define VDEC_HAS_VDEC_HCODEC -#define VDEC_HAS_CLK_SETTINGS -#define CLK_FOR_CPU {\ - MESON_CPU_MAJOR_ID_GXBB,\ - MESON_CPU_MAJOR_ID_GXTVBB,\ - MESON_CPU_MAJOR_ID_GXL,\ - MESON_CPU_MAJOR_ID_GXM,\ - MESON_CPU_MAJOR_ID_TXL,\ - 0} -#include "clk.h" -ARCH_VDEC_CLK_INIT(); -ARCH_VDEC_CLK_EXIT(); - -MODULE_LICENSE("GPL"); diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c deleted file mode 100644 index ade914a..0000000 --- a/drivers/common/media_clock/switch/amports_gate.c +++ b/dev/null @@ -1,189 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/switch/amports_gate.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/compiler.h> -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/clk.h> -#include "amports_gate.h" -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../../stream_input/amports/amports_priv.h" -#include "../../../frame_provider/decoder/utils/vdec.h" -#include "../clk/clk.h" - - -#define DEBUG_REF 1 -#define GATE_RESET_OK - -#ifdef GATE_RESET_OK - -struct gate_switch_node gates[] = { - { - .name = "demux", - }, - { - .name = "parser_top", - }, - { - .name = "vdec", - }, - { - .name = "clk_vdec_mux", - }, - { - .name = "clk_hcodec_mux", - }, - { - .name = "clk_hevc_mux", - }, -}; - -/* -mesonstream { - compatible = "amlogic, codec, streambuf"; - dev_name = "mesonstream"; - status = "okay"; - clocks = <&clkc CLKID_DOS_PARSER - &clkc CLKID_DEMUX - &clkc CLKID_DOS - &clkc CLKID_VDEC_MUX - &clkc CLKID_HCODEC_MUX - &clkc CLKID_HEVC_MUX>; - clock-names = "parser_top", - "demux", - "vdec", - "clk_vdec_mux", - "clk_hcodec_mux", - "clk_hevc_mux"; -}; -*/ - -int amports_clock_gate_init(struct device *dev) -{ - int i; - - for (i = 0; i < sizeof(gates) / sizeof(struct gate_switch_node); i++) { - 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 %p\n", - gates[i].name, - gates[i].clk); - } else { - pr_info("get gate %s control ok %p\n", - gates[i].name, - gates[i].clk); - } - gates[i].ref_count = 0; - spin_lock_init(&gates[i].lock); - } - - set_clock_gate(gates, ARRAY_SIZE(gates)); - - return 0; -} -EXPORT_SYMBOL(amports_clock_gate_init); - -static int amports_gate_clk(struct gate_switch_node *gate_node, int enable) -{ - spin_lock_irqsave(&gate_node->lock, gate_node->flags); - if (enable) { - if (gate_node->ref_count == 0) - clk_prepare_enable(gate_node->clk); - - gate_node->ref_count++; - - if (DEBUG_REF) - pr_info("the %-15s clock on, ref cnt: %d\n", - gate_node->name, gate_node->ref_count); - } else { - gate_node->ref_count--; - if (gate_node->ref_count == 0) - clk_disable_unprepare(gate_node->clk); - - if (DEBUG_REF) - pr_info("the %-15s clock off, ref cnt: %d\n", - gate_node->name, gate_node->ref_count); - } - spin_unlock_irqrestore(&gate_node->lock, gate_node->flags); - return 0; -} - -int amports_switch_gate(const char *name, int enable) -{ - int i; - - for (i = 0; i < sizeof(gates) / sizeof(struct gate_switch_node); i++) { - if (!strcmp(name, gates[i].name)) { - - /*pr_info("openclose:%d gate %s control\n", enable, - gates[i].name);*/ - - if (gates[i].clk) - amports_gate_clk(&gates[i], enable); - } - } - return 0; -} -EXPORT_SYMBOL(amports_switch_gate); - -#else -/* -*can used for debug. -*on chip bringup. -*/ -int amports_clock_gate_init(struct device *dev) -{ - static int gate_inited; - - if (gate_inited) - return 0; -/* -*#define HHI_GCLK_MPEG0 0x1050 -*#define HHI_GCLK_MPEG1 0x1051 -*#define HHI_GCLK_MPEG2 0x1052 -*#define HHI_GCLK_OTHER 0x1054 -*#define HHI_GCLK_AO 0x1055 -*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG0, 1, 1, 1);/*dos*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG1, 1, 25, 1);/*U_parser_top()*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG1, 0xff, 6, 8);/*aiu()*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG1, 1, 4, 1);/*demux()*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG1, 1, 2, 1);/*audio in()*/ - WRITE_HHI_REG_BITS(HHI_GCLK_MPEG2, 1, 25, 1);/*VPU Interrupt*/ - gate_inited++; - - - - return 0; -} -EXPORT_SYMBOL(amports_clock_gate_init); - -static int amports_switch_gate(struct gate_switch_node *gate_node, int enable) -{ - return 0; -} - -int amports_switch_gate(const char *name, int enable) -{ - amports_switch_gate(0, 0); - return 0; -} -EXPORT_SYMBOL(amports_switch_gate); - -#endif diff --git a/drivers/common/media_clock/switch/amports_gate.h b/drivers/common/media_clock/switch/amports_gate.h deleted file mode 100644 index 75270ab..0000000 --- a/drivers/common/media_clock/switch/amports_gate.h +++ b/dev/null @@ -1,33 +0,0 @@ -/* - * drivers/amlogic/media/common/arch/switch/amports_gate.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 AMPORT_GATE_H -#define AMPORT_GATE_H -#include <linux/device.h> - -struct gate_switch_node { - struct clk *clk; - const char *name; - spinlock_t lock; - unsigned long flags; - int ref_count; -}; - -extern int amports_clock_gate_init(struct device *dev); -extern int amports_switch_gate(const char *name, int enable); - -#endif diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile deleted file mode 100644 index 371e088..0000000 --- a/drivers/frame_provider/Makefile +++ b/dev/null @@ -1 +0,0 @@ -obj-y += decoder/ diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile deleted file mode 100644 index 3a5774a..0000000 --- a/drivers/frame_provider/decoder/Makefile +++ b/dev/null @@ -1,16 +0,0 @@ -obj-y += utils/ -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12) += mpeg12/vmpeg12.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4) += mpeg4/vmpeg4.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4_MULTI) += mpeg4/vmpeg4_multi.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_VC1) += vc1/vvc1.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264) += h264/vh264.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI) += h264_multi/ -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC) += h264/vh264_mvc.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_4K2K) += h264/vh264_4k2k.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC) += h264/vh264_mvc.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H265) += h265/vh265.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_VP9) += vp9/vvp9.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG) += mjpeg/vmjpeg.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI) += mjpeg/vmjpeg_multi.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_REAL) += real/vreal.o -obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS) += avs/ diff --git a/drivers/frame_provider/decoder/avs/Makefile b/drivers/frame_provider/decoder/avs/Makefile deleted file mode 100644 index cf154c9..0000000 --- a/drivers/frame_provider/decoder/avs/Makefile +++ b/dev/null @@ -1,2 +0,0 @@ -obj-m += vavs.o -vavs-objs += avs.o avsp_trans.o diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c deleted file mode 100644 index aed8497..0000000 --- a/drivers/frame_provider/decoder/avs/avs.c +++ b/dev/null @@ -1,1541 +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/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/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/parser/streambuf_reg.h" -#include "../utils/amvdec.h" -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include <linux/slab.h> -#include "avs.h" - -#define DRIVER_NAME "amvdec_avs" -#define MODULE_NAME "amvdec_avs" - -#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define NV21 -#endif - -#define USE_AVS_SEQ_INFO -#define HANDLE_AVS_IRQ -#define DEBUG_PTS - -#define I_PICTURE 0 -#define P_PICTURE 1 -#define B_PICTURE 2 - -/* #define ORI_BUFFER_START_ADDR 0x81000000 */ -#define ORI_BUFFER_START_ADDR 0x80000000 - -#define INTERLACE_FLAG 0x80 -#define TOP_FIELD_FIRST_FLAG 0x40 - -/* protocol registers */ -#define AVS_PIC_RATIO AV_SCRATCH_0 -#define AVS_PIC_WIDTH AV_SCRATCH_1 -#define AVS_PIC_HEIGHT AV_SCRATCH_2 -#define AVS_FRAME_RATE AV_SCRATCH_3 - -#define AVS_ERROR_COUNT AV_SCRATCH_6 -#define AVS_SOS_COUNT AV_SCRATCH_7 -#define AVS_BUFFERIN AV_SCRATCH_8 -#define AVS_BUFFEROUT AV_SCRATCH_9 -#define AVS_REPEAT_COUNT AV_SCRATCH_A -#define AVS_TIME_STAMP AV_SCRATCH_B -#define AVS_OFFSET_REG AV_SCRATCH_C -#define MEM_OFFSET_REG AV_SCRATCH_F -#define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G - -#define VF_POOL_SIZE 32 -#define PUT_INTERVAL (HZ/100) - -#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ -#define INT_AMVENCODER INT_DOS_MAILBOX_1 -#else -/* #define AMVENC_DEV_VERSION "AML-MT" */ -#define INT_AMVENCODER INT_MAILBOX_1A -#endif - -#define VPP_VD1_POSTBLEND (1 << 10) - -static int debug_flag; - -static int firmware_sel; /* 0, normal; 1, old ucode */ - -int avs_get_debug_flag(void) -{ - return debug_flag; -} - -static struct vframe_s *vavs_vf_peek(void *); -static struct vframe_s *vavs_vf_get(void *); -static void vavs_vf_put(struct vframe_s *, void *); -static int vavs_vf_states(struct vframe_states *states, void *); - -static const char vavs_dec_id[] = "vavs-dev"; - -#define PROVIDER_NAME "decoder.avs" -static DEFINE_SPINLOCK(lock); -static DEFINE_MUTEX(vavs_mutex); - -static const struct vframe_operations_s vavs_vf_provider = { - .peek = vavs_vf_peek, - .get = vavs_vf_get, - .put = vavs_vf_put, - .vf_states = vavs_vf_states, -}; - -static struct vframe_provider_s vavs_vf_prov; - -#define VF_BUF_NUM_MAX 16 - -/*static u32 vf_buf_num = 4*/ -static u32 vf_buf_num = 4; -static u32 vf_buf_num_used; -static u32 canvas_base = 128; -#ifdef NV21 - int canvas_num = 2; /*NV21*/ -#else - int canvas_num = 3; -#endif -static u32 work_buf_size; - -static struct vframe_s vfpool[VF_POOL_SIZE]; -/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/ -static struct vframe_s *cur_vfpool; -static unsigned char recover_flag; -static s32 vfbuf_use[VF_BUF_NUM_MAX]; -static u32 saved_resolution; -static u32 frame_width, frame_height, frame_dur, frame_prog; -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start; -static u32 buf_size, buf_offset; -static u32 avi_flag; -static u32 vavs_ratio; -static u32 pic_type; -static u32 pts_by_offset = 1; -static u32 total_frame; -static u32 next_pts; -static unsigned char throw_pb_flag; -#ifdef DEBUG_PTS -static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; -#endif - -static u32 radr, rval; -static struct dec_sysinfo vavs_amstream_dec_info; - -#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; - -#endif - -static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); -static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); -static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); - -static 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 */ - 96000 / 24, /* 24000/1001 (23.967) */ - 96000 / 24, - 96000 / 25, - 96000 / 30, /* 30000/1001 (29.97) */ - 96000 / 30, - 96000 / 50, - 96000 / 60, /* 60000/1001 (59.94) */ - 96000 / 60, - /* > 8 reserved, use 24 */ - 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24, - 96000 / 24, 96000 / 24, 96000 / 24 -}; - -static void set_frame_info(struct vframe_s *vf, unsigned *duration) -{ - int ar = 0; - - unsigned pixel_ratio = READ_VREG(AVS_PIC_RATIO); -#ifndef USE_AVS_SEQ_INFO - if (vavs_amstream_dec_info.width > 0 - && vavs_amstream_dec_info.height > 0) { - vf->width = vavs_amstream_dec_info.width; - vf->height = vavs_amstream_dec_info.height; - } else -#endif - { - vf->width = READ_VREG(AVS_PIC_WIDTH); - vf->height = READ_VREG(AVS_PIC_HEIGHT); - frame_width = vf->width; - frame_height = vf->height; - /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/ - } - -#ifndef USE_AVS_SEQ_INFO - if (vavs_amstream_dec_info.rate > 0) - *duration = vavs_amstream_dec_info.rate; - else -#endif - { - *duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf]; - /* pr_info("%s: duration = %d\n", __func__, *duration); */ - frame_dur = *duration; - } - - if (vavs_ratio == 0) { - /* always stretch to 16:9 */ - vf->ratio_control |= (0x90 << - DISP_RATIO_ASPECT_RATIO_BIT); - } else { - switch (pixel_ratio) { - case 1: - ar = (vf->height * vavs_ratio) / vf->width; - break; - case 2: - ar = (vf->height * 3 * vavs_ratio) / (vf->width * 4); - break; - case 3: - ar = (vf->height * 9 * vavs_ratio) / (vf->width * 16); - break; - case 4: - ar = (vf->height * 100 * vavs_ratio) / (vf->width * - 221); - break; - default: - ar = (vf->height * vavs_ratio) / vf->width; - break; - } - } - - ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX); - - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); - /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */ - - vf->flag = 0; -} - -#ifdef HANDLE_AVS_IRQ -static irqreturn_t vavs_isr(int irq, void *dev_id) -#else -static void vavs_isr(void) -#endif -{ - u32 reg; - struct vframe_s *vf; - u32 dur; - u32 repeat_count; - u32 picture_type; - u32 buffer_index; - u32 picture_struct; - unsigned int pts, pts_valid = 0, offset; - if (debug_flag & AVS_DEBUG_UCODE) { - if (READ_VREG(AV_SCRATCH_E) != 0) { - pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E), - READ_VREG(AV_SCRATCH_D)); - WRITE_VREG(AV_SCRATCH_E, 0); - } - } -#ifdef AVSP_LONG_CABAC - if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) { -#ifdef PERFORMANCE_DEBUG - pr_info("%s:schedule long_cabac_wd_work\r\n", __func__); -#endif - schedule_work(&long_cabac_wd_work); - } -#endif - reg = READ_VREG(AVS_BUFFEROUT); - - if (reg) { - picture_struct = READ_VREG(AV_SCRATCH_5); - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS_BUFFEROUT=%x, picture_struct is 0x%x\n", - reg, picture_struct); - if (pts_by_offset) { - offset = READ_VREG(AVS_OFFSET_REG); - if (debug_flag & AVS_DEBUG_PRINT) - pr_info("AVS OFFSET=%x\n", offset); - if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) - == 0) { - pts_valid = 1; -#ifdef DEBUG_PTS - pts_hit++; -#endif - } else { -#ifdef DEBUG_PTS - pts_missed++; -#endif - } - } - - repeat_count = READ_VREG(AVS_REPEAT_COUNT); - if (firmware_sel == 0) - buffer_index = - ((reg & 0x7) + - (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; - else - buffer_index = - ((reg & 0x7) - 1) & 3; - - picture_type = (reg >> 3) & 7; -#ifdef DEBUG_PTS - if (picture_type == I_PICTURE) { - /* pr_info("I offset 0x%x, pts_valid %d\n", - offset, pts_valid); */ - if (!pts_valid) - pts_i_missed++; - else - pts_i_hit++; - } -#endif - - if (throw_pb_flag && picture_type != I_PICTURE) { - - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("picture type %d throwed\n", - picture_type); - } - WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index)); - } else if (reg & INTERLACE_FLAG) { /* interlace */ - throw_pb_flag = 0; - - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("interlace, picture type %d\n", - picture_type); - } - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - set_frame_info(vf, &dur); - vf->bufWidth = 1920; - pic_type = 2; - if ((I_PICTURE == picture_type) && pts_valid) { - vf->pts = pts; - if ((repeat_count > 1) && avi_flag) { - /* next_pts = pts + - (vavs_amstream_dec_info.rate * - repeat_count >> 1)*15/16; */ - next_pts = - pts + - (dur * repeat_count >> 1) * - 15 / 16; - } else - next_pts = 0; - } else { - vf->pts = next_pts; - if ((repeat_count > 1) && avi_flag) { - /* vf->duration = - vavs_amstream_dec_info.rate * - repeat_count >> 1; */ - vf->duration = dur * repeat_count >> 1; - if (next_pts != 0) { - next_pts += - ((vf->duration) - - ((vf->duration) >> 4)); - } - } else { - /* vf->duration = - vavs_amstream_dec_info.rate >> 1; */ - vf->duration = dur >> 1; - next_pts = 0; - } - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->duration_pulldown = 0; - vf->type = - (reg & TOP_FIELD_FIRST_FLAG) - ? VIDTYPE_INTERLACE_TOP - : VIDTYPE_INTERLACE_BOTTOM; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->type_original = vf->type; - - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", - buffer_index, vf->canvas0Addr); - } - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - set_frame_info(vf, &dur); - vf->bufWidth = 1920; - - vf->pts = next_pts; - if ((repeat_count > 1) && avi_flag) { - /* vf->duration = vavs_amstream_dec_info.rate * - repeat_count >> 1; */ - vf->duration = dur * repeat_count >> 1; - if (next_pts != 0) { - next_pts += - ((vf->duration) - - ((vf->duration) >> 4)); - } - } else { - /* vf->duration = vavs_amstream_dec_info.rate - >> 1; */ - vf->duration = dur >> 1; - next_pts = 0; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->duration_pulldown = 0; - vf->type = - (reg & TOP_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_BOTTOM : - VIDTYPE_INTERLACE_TOP; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->type_original = vf->type; - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - total_frame++; - } else { /* progressive */ - throw_pb_flag = 0; - - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("progressive picture type %d\n", - picture_type); - } - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - set_frame_info(vf, &dur); - vf->bufWidth = 1920; - pic_type = 1; - - if ((I_PICTURE == picture_type) && pts_valid) { - vf->pts = pts; - if ((repeat_count > 1) && avi_flag) { - /* next_pts = pts + - (vavs_amstream_dec_info.rate * - repeat_count)*15/16; */ - next_pts = - pts + - (dur * repeat_count) * 15 / 16; - } else - next_pts = 0; - } else { - vf->pts = next_pts; - if ((repeat_count > 1) && avi_flag) { - /* vf->duration = - vavs_amstream_dec_info.rate * - repeat_count; */ - vf->duration = dur * repeat_count; - if (next_pts != 0) { - next_pts += - ((vf->duration) - - ((vf->duration) >> 4)); - } - } else { - /* vf->duration = - vavs_amstream_dec_info.rate; */ - vf->duration = dur; - next_pts = 0; - } - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->duration_pulldown = 0; - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->type_original = vf->type; - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("buffer_index %d, canvas addr %x\n", - buffer_index, vf->canvas0Addr); - } - - vfbuf_use[buffer_index]++; - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - total_frame++; - } - - /* pr_info("PicType = %d, PTS = 0x%x\n", - picture_type, vf->pts); */ - WRITE_VREG(AVS_BUFFEROUT, 0); - } - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - -#ifdef HANDLE_AVS_IRQ - return IRQ_HANDLED; -#else - return; -#endif -} -/* -static int run_flag = 1; -static int step_flag; -*/ -static int error_recovery_mode; /*0: blocky 1: mosaic*/ -/* -static uint error_watchdog_threshold=10; -static uint error_watchdog_count; -static uint error_watchdog_buf_threshold = 0x4000000; -*/ -static uint long_cabac_busy; - -static struct vframe_s *vavs_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (recover_flag) - return NULL; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; - -} - -static struct vframe_s *vavs_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (recover_flag) - return NULL; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; - -} - -static void vavs_vf_put(struct vframe_s *vf, void *op_arg) -{ - int i; - if (recover_flag) - return; - - for (i = 0; i < VF_POOL_SIZE; i++) { - if (vf == &cur_vfpool[i]) - break; - } - if (i < VF_POOL_SIZE) - kfifo_put(&recycle_q, (const struct vframe_s *)vf); - -} - -int vavs_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; /* vavs_amstream_dec_info.width; */ - vstatus->height = frame_height; /* vavs_amstream_dec_info.height; */ - if (0 != frame_dur /*vavs_amstream_dec_info.rate */) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = 96000; - vstatus->error_count = READ_VREG(AVS_ERROR_COUNT); - vstatus->status = stat; - - return 0; -} - -/****************************************/ -static void vavs_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - int vf_buf_num_avail = 0; - vf_buf_num_used = vf_buf_num; - if (buf_size <= 0x00400000) { - /* SD only */ - canvas_width = 768; - canvas_height = 576; - decbuf_y_size = 0x80000; - decbuf_uv_size = 0x20000; - decbuf_size = 0x100000; - vf_buf_num_avail = - ((buf_size - work_buf_size) / decbuf_size) - 1; - pr_info - ("avs(SD):buf_start %p, size %x, offset %x avail %d\n", - (void *)buf_start, buf_size, buf_offset, - vf_buf_num_avail); - } else { - /* HD & SD */ - canvas_width = 1920; - canvas_height = 1088; - decbuf_y_size = 0x200000; - decbuf_uv_size = 0x80000; - decbuf_size = 0x300000; - vf_buf_num_avail = - ((buf_size - work_buf_size) / decbuf_size) - 1; - pr_info("avs: buf_start %p, buf_size %x, buf_offset %x buf avail %d\n", - (void *)buf_start, buf_size, buf_offset, - vf_buf_num_avail); - } - if (vf_buf_num_used > vf_buf_num_avail) - vf_buf_num_used = vf_buf_num_avail; - - if (firmware_sel == 0) - buf_offset = buf_offset + ((vf_buf_num_used + 1) * decbuf_size); - - if (READ_MPEG_REG(VPP_MISC) & VPP_VD1_POSTBLEND) { - struct canvas_s cur_canvas; - - canvas_read((READ_MPEG_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < vf_buf_num_used; i++) { - if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) { -#ifdef NV21 - canvas_config(canvas_base + canvas_num * i + 0, - buf_start + - vf_buf_num_used * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_base + canvas_num * i + 1, - buf_start + - vf_buf_num_used * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(canvas_num * i + 0, - buf_start + 4 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_num * i + 1, - buf_start + 4 * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_num * i + 2, - buf_start + 4 * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#endif - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("canvas config %d, addr %p\n", - vf_buf_num_used, - (void *)(buf_start + - vf_buf_num_used * decbuf_size)); - } - - } else { -#ifdef NV21 - canvas_config(canvas_base + canvas_num * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_base + canvas_num * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(canvas_num * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_num * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(canvas_num * i + 2, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#endif - if (debug_flag & AVS_DEBUG_PRINT) { - pr_info("canvas config %d, addr %p\n", i, - (void *)(buf_start + - i * decbuf_size)); - } - } - } -} - -void vavs_recover(void) -{ - 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) - WRITE_VREG(AV_SCRATCH_5, 0); - - if (firmware_sel == 0) { - /* fixed canvas index */ - WRITE_VREG(AV_SCRATCH_0, canvas_base); - WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used); - } else { - int ii; - for (ii = 0; ii < 4; ii++) { - WRITE_VREG(AV_SCRATCH_0 + ii, - (canvas_base + canvas_num * ii) | - ((canvas_base + canvas_num * ii + 1) - << 8) | - ((canvas_base + canvas_num * ii + 1) - << 16) - ); - } - } - - /* notify ucode the buffer offset */ - WRITE_VREG(AV_SCRATCH_F, buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(AVS_SOS_COUNT, 0); - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); - if (error_recovery_mode) - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); - else - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ - WRITE_VREG(AV_SCRATCH_D, 0); -#endif - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#ifdef PIC_DC_NEED_CLEAR - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); -#endif - -#ifdef AVSP_LONG_CABAC - if (firmware_sel == 0) { - WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); - WRITE_VREG(LONG_CABAC_REQ, 0); - WRITE_VREG(LONG_CABAC_PIC_SIZE, 0); - WRITE_VREG(LONG_CABAC_SRC_ADDR, 0); - } -#endif - -} - -static void vavs_prot_init(void) -{ -#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_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - READ_MPEG_REG(RESET0_REGISTER); - WRITE_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - - WRITE_MPEG_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); -#endif - - /***************** reset vld **********************************/ - WRITE_VREG(POWER_CTL_VLD, 0x10); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); - WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); - /*************************************************************/ - - vavs_canvas_init(); - if (firmware_sel == 0) - WRITE_VREG(AV_SCRATCH_5, 0); -#ifdef NV21 - if (firmware_sel == 0) { - /* fixed canvas index */ - WRITE_VREG(AV_SCRATCH_0, canvas_base); - WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used); - } else { - int ii; - for (ii = 0; ii < 4; ii++) { - WRITE_VREG(AV_SCRATCH_0 + ii, - (canvas_base + canvas_num * ii) | - ((canvas_base + canvas_num * ii + 1) - << 8) | - ((canvas_base + canvas_num * ii + 1) - << 16) - ); - } - /* - WRITE_VREG(AV_SCRATCH_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 */ - WRITE_VREG(AV_SCRATCH_F, buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(AVS_SOS_COUNT, 0); - WRITE_VREG(AVS_BUFFERIN, 0); - WRITE_VREG(AVS_BUFFEROUT, 0); - if (error_recovery_mode) - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); - else - WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); -#if 1 /* def DEBUG_UCODE */ - WRITE_VREG(AV_SCRATCH_D, 0); -#endif - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#ifdef PIC_DC_NEED_CLEAR - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); -#endif - -#ifdef AVSP_LONG_CABAC - if (firmware_sel == 0) { - WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); - WRITE_VREG(LONG_CABAC_REQ, 0); - WRITE_VREG(LONG_CABAC_PIC_SIZE, 0); - WRITE_VREG(LONG_CABAC_SRC_ADDR, 0); - } -#endif -} - -#if 0 -#ifdef AVSP_LONG_CABAC -static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); -#endif -#endif - -static void vavs_local_init(void) -{ - int i; - - vavs_ratio = vavs_amstream_dec_info.ratio; - - avi_flag = (unsigned long) vavs_amstream_dec_info.param; - - frame_width = frame_height = frame_dur = frame_prog = 0; - - throw_pb_flag = 1; - - total_frame = 0; - saved_resolution = 0; - next_pts = 0; - -#ifdef DEBUG_PTS - pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0; -#endif - INIT_KFIFO(display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &vfpool[i]; - vfpool[i].index = vf_buf_num; - vfpool[i].bufWidth = 1920; - kfifo_put(&newframe_q, vf); - } - for (i = 0; i < vf_buf_num; i++) - vfbuf_use[i] = 0; - - cur_vfpool = vfpool; - -} - -static int vavs_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - spin_lock_irqsave(&lock, flags); - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&newframe_q); - states->buf_avail_num = kfifo_len(&display_q); - states->buf_recycle_num = kfifo_len(&recycle_q); - spin_unlock_irqrestore(&lock, flags); - return 0; -} - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER -static void vavs_ppmgr_reset(void) -{ - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - - vavs_local_init(); - - pr_info("vavs: vf_ppmgr_reset\n"); -} -#endif - -static void vavs_local_reset(void) -{ - mutex_lock(&vavs_mutex); - recover_flag = 1; - pr_info("error, local reset\n"); - amvdec_stop(); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - vavs_local_init(); - vavs_recover(); - amvdec_start(); - recover_flag = 0; -#if 0 - error_watchdog_count = 0; - - pr_info("pc %x stream buf wp %x rp %x level %x\n", - READ_VREG(MPC_E), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); -#endif - mutex_unlock(&vavs_mutex); -} - -static void vavs_put_timer_func(unsigned long arg) -{ - struct timer_list *timer = (struct timer_list *)arg; - -#ifndef HANDLE_AVS_IRQ - vavs_isr(); -#endif - - if (READ_VREG(AVS_SOS_COUNT)) { - if (!error_recovery_mode) { - if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) { - mutex_lock(&vavs_mutex); - pr_info("vavs fatal error reset !\n"); - amvdec_stop(); -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vavs_ppmgr_reset(); -#else - vf_light_unreg_provider(&vavs_vf_prov); - vavs_local_init(); - vf_reg_provider(&vavs_vf_prov); -#endif - vavs_recover(); - amvdec_start(); - mutex_unlock(&vavs_mutex); - } else { - vavs_local_reset(); - } - } - } -#if 0 - if (long_cabac_busy == 0 && - error_watchdog_threshold > 0 && - kfifo_len(&display_q) == 0 && - READ_VREG(VLD_MEM_VIFIFO_LEVEL) > - error_watchdog_buf_threshold) { - pr_info("newq %d dispq %d recyq %d\r\n", - kfifo_len(&newframe_q), - kfifo_len(&display_q), - kfifo_len(&recycle_q)); - pr_info("pc %x stream buf wp %x rp %x level %x\n", - READ_VREG(MPC_E), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - error_watchdog_count++; - if (error_watchdog_count >= error_watchdog_threshold) - vavs_local_reset(); - } else - error_watchdog_count = 0; -#endif - if (radr != 0) { - if (rval != 0) { - WRITE_VREG(radr, rval); - pr_info("WRITE_VREG(%x,%x)\n", radr, rval); - } else - pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr)); - rval = 0; - radr = 0; - } - - if (!kfifo_is_empty(&recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) { - struct vframe_s *vf; - if (kfifo_get(&recycle_q, &vf)) { - if ((vf->index < vf_buf_num) && - (--vfbuf_use[vf->index] == 0)) { - WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); - vf->index = vf_buf_num; - } - kfifo_put(&newframe_q, - (const struct vframe_s *)vf); - } - - } - if (frame_dur > 0 && saved_resolution != - frame_width * frame_height * (96000 / frame_dur)) { - int fps = 96000 / frame_dur; - saved_resolution = frame_width * frame_height * fps; - if (firmware_sel == 0 && - (debug_flag & AVS_DEBUG_USE_FULL_SPEED)) { - vdec_source_changed(VFORMAT_AVS, - 4096, 2048, 60); - } else { - vdec_source_changed(VFORMAT_AVS, - frame_width, frame_height, fps); - } - - } - - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -#ifdef AVSP_LONG_CABAC - -static void long_cabac_do_work(struct work_struct *work) -{ - int status = 0; -#ifdef PERFORMANCE_DEBUG - pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n", - __func__, - kfifo_len(&newframe_q), - kfifo_len(&display_q), - kfifo_len(&recycle_q) - ); -#endif - mutex_lock(&vavs_mutex); - long_cabac_busy = 1; - while (READ_VREG(LONG_CABAC_REQ)) { - if (process_long_cabac() < 0) { - status = -1; - break; - } - } - long_cabac_busy = 0; - mutex_unlock(&vavs_mutex); -#ifdef PERFORMANCE_DEBUG - pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n", - __func__, - kfifo_len(&newframe_q), - kfifo_len(&display_q), - kfifo_len(&recycle_q) - ); -#endif - if (status < 0) { - pr_info("transcoding error, local reset\r\n"); - vavs_local_reset(); - } - -} -#endif - -#if 0 -#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 -#endif - -static s32 vavs_init(void) -{ - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - pr_info("vavs_init\n"); - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - amvdec_enable(); - - vavs_local_init(); - - size = get_firmware_data(VIDEO_DEC_AVS, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vavs_prot_init(); - -#ifdef HANDLE_AVS_IRQ - if (vdec_request_irq(VDEC_IRQ_1, vavs_isr, - "vavs-irq", (void *)vavs_dec_id)) { - amvdec_disable(); - pr_info("vavs irq register error.\n"); - return -ENOENT; - } -#endif - - stat |= STAT_ISR_REG; - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL); - vf_reg_provider(&vavs_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL); - vf_reg_provider(&vavs_vf_prov); -#endif - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long) - vavs_amstream_dec_info.rate)); - - stat |= STAT_VF_HOOK; - - 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; - -#ifdef AVSP_LONG_CABAC - if (firmware_sel == 0) - INIT_WORK(&long_cabac_wd_work, long_cabac_do_work); -#endif - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int amvdec_avs_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - if (pdata == NULL) { - pr_info("amvdec_avs memory resource undefined.\n"); - return -EFAULT; - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - firmware_sel = 1; - - if (firmware_sel == 1) { - vf_buf_num = 4; - canvas_base = 0; - canvas_num = 3; - } else { - /*if(vf_buf_num <= 4) - canvas_base = 0; - else */ - canvas_base = 128; - canvas_num = 2; /*NV21*/ - } - -#ifdef AVSP_LONG_CABAC - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1 - - (MAX_CODED_FRAME_SIZE * 2) - - LOCAL_HEAP_SIZE; - avsp_heap_adr = codec_mm_phys_to_virt( - pdata->mem_start + buf_size); -#else - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; -#endif - - if (buf_start > ORI_BUFFER_START_ADDR) - buf_offset = buf_start - ORI_BUFFER_START_ADDR; - else - buf_offset = buf_start; - - if (pdata->sys_info) - vavs_amstream_dec_info = *pdata->sys_info; - - pr_info("%s (%d,%d) %d\n", __func__, vavs_amstream_dec_info.width, - vavs_amstream_dec_info.height, vavs_amstream_dec_info.rate); - - pdata->dec_status = vavs_dec_status; - - if (vavs_init() < 0) { - pr_info("amvdec_avs init failed.\n"); - - return -ENODEV; - } - - return 0; -} - -static int amvdec_avs_remove(struct platform_device *pdev) -{ - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); - stat &= ~STAT_ISR_REG; - } - - if (stat & STAT_TIMER_ARM) { - del_timer_sync(&recycle_timer); - 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 (stat & STAT_VF_HOOK) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vavs_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - amvdec_disable(); - - pic_type = 0; -#ifdef DEBUG_PTS - pr_info("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit, - pts_missed, pts_i_hit, pts_i_missed); - pr_info("total frame %d, avi_flag %d, rate %d\n", total_frame, avi_flag, - vavs_amstream_dec_info.rate); -#endif - - return 0; -} - -/****************************************/ - -static struct platform_driver amvdec_avs_driver = { - .probe = amvdec_avs_probe, - .remove = amvdec_avs_remove, - .driver = { - .name = DRIVER_NAME, - } -}; - -static struct codec_profile_t amvdec_avs_profile = { - .name = "avs", - .profile = "" -}; - -static int __init amvdec_avs_driver_init_module(void) -{ - pr_debug("amvdec_avs module init\n"); - - if (platform_driver_register(&amvdec_avs_driver)) { - pr_info("failed to register amvdec_avs driver\n"); - return -ENODEV; - } - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) - amvdec_avs_profile.profile = "avs+"; - - vcodec_profile_register(&amvdec_avs_profile); - - return 0; -} - -static void __exit amvdec_avs_driver_remove_module(void) -{ - pr_debug("amvdec_avs module remove.\n"); - - platform_driver_unregister(&amvdec_avs_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n"); - -/****************************************** -module_param(run_flag, uint, 0664); -MODULE_PARM_DESC(run_flag, "\n run_flag\n"); - -module_param(step_flag, uint, 0664); -MODULE_PARM_DESC(step_flag, "\n step_flag\n"); -*******************************************/ - -module_param(debug_flag, uint, 0664); -MODULE_PARM_DESC(debug_flag, "\n debug_flag\n"); - -module_param(error_recovery_mode, uint, 0664); -MODULE_PARM_DESC(error_recovery_mode, "\n error_recovery_mode\n"); - -/****************************************** -module_param(error_watchdog_threshold, uint, 0664); -MODULE_PARM_DESC(error_watchdog_threshold, "\n error_watchdog_threshold\n"); - -module_param(error_watchdog_buf_threshold, uint, 0664); -MODULE_PARM_DESC(error_watchdog_buf_threshold, - "\n error_watchdog_buf_threshold\n"); -*******************************************/ - -module_param(pic_type, uint, 0444); -MODULE_PARM_DESC(pic_type, "\n amdec_vas picture type\n"); - -module_param(radr, uint, 0664); -MODULE_PARM_DESC(radr, "\nradr\n"); - -module_param(rval, uint, 0664); -MODULE_PARM_DESC(rval, "\nrval\n"); - -module_param(vf_buf_num, uint, 0664); -MODULE_PARM_DESC(vf_buf_num, "\nvf_buf_num\n"); - -module_param(vf_buf_num_used, uint, 0664); -MODULE_PARM_DESC(vf_buf_num_used, "\nvf_buf_num_used\n"); - -module_param(canvas_base, uint, 0664); -MODULE_PARM_DESC(canvas_base, "\ncanvas_base\n"); - -module_param(work_buf_size, uint, 0664); -MODULE_PARM_DESC(work_buf_size, "\nwork_buf_size\n"); - -module_param(firmware_sel, uint, 0664); -MODULE_PARM_DESC(firmware_sel, "\firmware_sel\n"); - - -module_init(amvdec_avs_driver_init_module); -module_exit(amvdec_avs_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC AVS Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/avs/avs.h b/drivers/frame_provider/decoder/avs/avs.h deleted file mode 100644 index d415645..0000000 --- a/drivers/frame_provider/decoder/avs/avs.h +++ b/dev/null @@ -1,70 +0,0 @@ -#ifndef AVS_H_ -#define AVS_H_ - -#define AVSP_LONG_CABAC -/*#define BITSTREAM_READ_TMP_NO_CACHE*/ - -#ifdef AVSP_LONG_CABAC -#define MAX_CODED_FRAME_SIZE 1500000 /*!< bytes for one frame*/ -#define LOCAL_HEAP_SIZE (1024*1024*10) -/* -#define MAX_CODED_FRAME_SIZE 240000 -#define MAX_CODED_FRAME_SIZE 700000 -*/ -#define SVA_STREAM_BUF_SIZE 1024 - -extern void *es_write_addr_virt; -extern dma_addr_t es_write_addr_phy; - -extern void *bitstream_read_tmp; -extern dma_addr_t bitstream_read_tmp_phy; -extern void *avsp_heap_adr; - -int avs_get_debug_flag(void); - -int process_long_cabac(void); - -/* bit [6] - skip_mode_flag - bit [5:4] - picture_type - bit [3] - picture_structure (0-Field, 1-Frame) - bit [2] - fixed_picture_qp - bit [1] - progressive_sequence - bit [0] - active -*/ -#define LONG_CABAC_REQ AV_SCRATCH_K -#define LONG_CABAC_SRC_ADDR AV_SCRATCH_H -#define LONG_CABAC_DES_ADDR AV_SCRATCH_I -/* bit[31:16] - vertical_size - bit[15:0] - horizontal_size -*/ -#define LONG_CABAC_PIC_SIZE AV_SCRATCH_J - -#endif - -/* -#define PERFORMANCE_DEBUG -#define DUMP_DEBUG -*/ -#define AVS_DEBUG_PRINT 0x01 -#define AVS_DEBUG_UCODE 0x02 -#define AVS_DEBUG_OLD_ERROR_HANDLE 0x10 -#define AVS_DEBUG_USE_FULL_SPEED 0x80 -#define AEC_DUMP 0x100 -#define STREAM_INFO_DUMP 0x200 -#define SLICE_INFO_DUMP 0x400 -#define MB_INFO_DUMP 0x800 -#define MB_NUM_DUMP 0x1000 -#define BLOCK_NUM_DUMP 0x2000 -#define COEFF_DUMP 0x4000 -#define ES_DUMP 0x8000 -#define DQUANT_DUMP 0x10000 -#define STREAM_INFO_DUMP_MORE 0x20000 -#define STREAM_INFO_DUMP_MORE2 0x40000 - -extern void *es_write_addr_virt; -extern void *bitstream_read_tmp; -extern dma_addr_t bitstream_read_tmp_phy; -int read_bitstream(unsigned char *Buf, int size); -int u_v(int LenInBits, char *tracestring); - -#endif diff --git a/drivers/frame_provider/decoder/avs/avsp_trans.c b/drivers/frame_provider/decoder/avs/avsp_trans.c deleted file mode 100644 index 3c7f3ab..0000000 --- a/drivers/frame_provider/decoder/avs/avsp_trans.c +++ b/dev/null @@ -1,4944 +0,0 @@ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/platform_device.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/canvas/canvas.h> -#include <linux/amlogic/media/vfm/vframe.h> -#include <linux/amlogic/media/vfm/vframe_provider.h> -#include <linux/amlogic/media/vfm/vframe_receiver.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include <linux/slab.h> -/* #include <mach/am_regs.h> */ -#include <linux/module.h> -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../../stream_input/parser/streambuf_reg.h" -#include "../utils/amvdec.h" -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" - -#include "avs.h" -#ifdef AVSP_LONG_CABAC - -#define DECODING_SANITY_CHECK - -#define TRACE 0 -#define LIWR_FIX 0 -#define pow2(a, b) (1<<b) -#define io_printf pr_info - -static unsigned char *local_heap_adr; -static int local_heap_size; -static int local_heap_pos; -static int transcoding_error_flag; - -unsigned char *local_alloc(int num, int size) -{ - unsigned char *ret_buf = NULL; - int alloc_size = num * size; - if ((local_heap_pos + alloc_size) <= local_heap_size) { - ret_buf = local_heap_adr + local_heap_pos; - local_heap_pos += alloc_size; - } else { - pr_info( - "!!!local_alloc(%d) error, local_heap (size %d) is not enough\r\n", - alloc_size, local_heap_size); - } - return ret_buf; -} - -int local_heap_init(int size) -{ - /*local_heap_adr = &local_heap[0];*/ - local_heap_adr = (unsigned char *)(avsp_heap_adr + - MAX_CODED_FRAME_SIZE); - memset(local_heap_adr, 0, LOCAL_HEAP_SIZE); - - local_heap_size = LOCAL_HEAP_SIZE; - local_heap_pos = 0; - return 0; -} - -void local_heap_uninit(void) -{ - local_heap_adr = NULL; - local_heap_size = 0; - local_heap_pos = 0; -} - -#define CODE2D_ESCAPE_SYMBOL 59 - -const int vlc_golomb_order[3][7][2] = - -{{{2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{3, 9}, {2, 9}, { - 2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{2, 9}, {0, 9}, - {1, 9}, {1, 9}, {0, 9}, {-1, -1}, {-1, -1}, }, }; - -const int MaxRun[3][7] = {{22, 14, 9, 6, 4, 2, 1}, {25, 18, 13, 9, 6, 4, 3}, { - 24, 19, 10, 7, 4, -1, -1} }; - -const int refabslevel[19][26] = {{4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1}, {7, 4, 4, 3, 3, 3, 3, 3, 2, - 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, 3, 2, 2, -1, -1, - -1 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, 7, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2}, {5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 5, 4, 4, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, - 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {17, 8, 4, - 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1}, {6, 4, 3, - 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, -1, -1, -1, -1, -1, -1}, {10, 6, 4, 4, 3, 3, - 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {14, 7, 4, 3, 3, 2, - 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}, {20, 7, 3, 2, - 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} }; - -static const int incvlc_intra[7] = {0, 1, 2, 4, 7, 10, 3000}; -static const int incvlc_chroma[5] = {0, 1, 2, 4, 3000}; - -const int AVS_2DVLC_INTRA[7][26][27] = {{{0, 22, 38, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {2, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 44, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {6, 50, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {8, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {14, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {18, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {46, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {52, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {56, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 4, 15, 27, 41, - 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, 2, 17, 35, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, 6, 25, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 9, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 11, 39, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 13, 45, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 19, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 21, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 31, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 37, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 47, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 2, 6, - 13, 17, 27, 35, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 4, 11, 21, 33, 49, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, 9, 23, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 15, - 29, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, 39, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, 25, 43, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, 31, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 41, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, 57, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, }, {{8, 0, 2, 4, 9, 11, 17, 21, 25, 33, 39, 45, 55, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 6, 13, 19, - 29, 35, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 15, 27, 41, 57, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 23, 37, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 31, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 43, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, }, {{6, 0, 2, 4, 7, 9, 11, 15, 17, - 21, 23, 29, 33, 35, 43, 47, 49, 57, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, 13, 19, 27, 31, 37, 45, 55, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - 25, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 39, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 53, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0, - 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 27, 31, 33, 37, 41, - 45, 49, 51, 55, -1, -1, -1, -1, -1}, {-1, 21, 29, 35, 43, 47, - 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, 39, 57, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, }, {{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, - 21, 23, 25, 27, 29, 31, 35, 37, 39, 41, 43, 47, 49, 51, 53, 57}, - {-1, 33, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} } }; - -const int AVS_2DVLC_CHROMA[5][26][27] = {{{0, 14, 32, 56, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {2, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}, {6, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {38, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {50, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {52, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0, 1, 5, 15, 29, - 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 3, 21, 45, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1}, {-1, 7, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 9, 41, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 11, 53, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 31, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 33, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, - {{2, 0, 3, 7, 11, 17, 27, 33, 47, 53, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, { - -1, 5, 13, 21, 37, 55, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 9, 23, 41, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 15, 31, 57, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - 19, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, 25, 45, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 29, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, 39, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, }, {{0, 1, 3, 5, 7, 11, 15, 19, 23, 29, - 35, 43, 47, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}, {-1, 9, 13, 21, 31, 39, 51, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 17, 27, - 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, 25, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, 33, 55, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 45, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, 49, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, 57, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1}, {-1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1}, }, - {{0, 1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 27, 29, 33, 37, 41, - 43, 51, 55, -1, -1, -1, -1, -1, -1, -1}, {-1, - 17, 25, 31, 39, 45, 53, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, 35, 49, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}, } }; - -const int UE[64][2] = {{1, 1}, {2, 3}, {3, 3}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, { - 8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, - 7}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9}, - {22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, { - 29, 9}, {30, 9}, {31, 9}, {32, 11}, {33, 11}, { - 34, 11}, {35, 11}, {36, 11}, {37, 11}, {38, 11}, - {39, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45, - 11}, {46, 11}, {47, 11}, {48, 11}, {49, 11}, { - 50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11}, - {55, 11}, {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61, - 11}, {62, 11}, {63, 11}, {64, 13} }; - -unsigned int src_start; -unsigned int des_start; - -#ifdef AVSP_LONG_CABAC - -unsigned char *es_buf; -int es_buf_ptr; -int es_write_addr; -#else -FILE *f_es; -#endif -int es_ptr; -unsigned int es_res; -int es_res_ptr; -unsigned int previous_es; - -void init_es(void) -{ - -#ifdef AVSP_LONG_CABAC - es_write_addr = des_start; - es_buf[0] = 0x00; - es_buf[1] = 0x00; - es_buf[2] = 0x01; - es_buf_ptr = 3; - es_ptr = 3; -#else - f_es = fopen("es.out", "wb"); - if (f_es == NULL) - io_printf(" ERROR : Can not open es.out for write\n"); - putc(0x00, f_es); - putc(0x00, f_es); - putc(0x01, f_es); - - es_ptr = 3; -#endif - es_res = 0; - es_res_ptr = 0; - previous_es = 0xff; - -} - -void push_es(int value, int num) -{ - unsigned char wr_es_data; - int push_num; - int push_value; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & ES_DUMP) - io_printf(" push_es : value : 0x%x, num : %d\n", value, num); -#endif - while (num > 0) { - if (num >= 8) - push_num = 8; - else - push_num = num; - - num = num - push_num; - push_value = (value >> num); - - es_res = (es_res << push_num) | push_value; - es_res_ptr = es_res_ptr + push_num; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & ES_DUMP) - io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n", - es_res, es_res_ptr); -#endif - - while (es_res_ptr >= 8) { - es_res_ptr = es_res_ptr & 7; - wr_es_data = (es_res >> es_res_ptr) & 0xff; - if ((previous_es == 0) & (wr_es_data < 4)) { - io_printf( - " Insert 2'b10 for emu at position : %d\n", - es_ptr); - - es_res_ptr = es_res_ptr + 2; - wr_es_data = 2; - } -#ifdef AVSP_LONG_CABAC -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & ES_DUMP) - pr_info("es_buf[%d] = 0x%02x\r\n", - es_buf_ptr, wr_es_data); -#endif - es_buf[es_buf_ptr++] = wr_es_data; -#else - putc(wr_es_data, f_es); -#endif - es_ptr++; - previous_es = ((previous_es << 8) | wr_es_data) - & 0xffff; - } - - } -} - -#define MIN_QP 0 -#define MAX_QP 63 - -#ifdef BLOCK_SIZE -#undef BLOCK_SIZE -#endif - -#define BLOCK_SIZE 4 -#define B8_SIZE 8 -#define MB_BLOCK_SIZE 16 - -#define BLOCK_MULTIPLE (MB_BLOCK_SIZE/(BLOCK_SIZE*2)) - -#define DECODE_COPY_MB 0 -#define DECODE_MB 1 - -#define NO_INTRA_PMODE 5 -#define INTRA_PMODE_4x4 10 -#define NO_INTRA_PMODE_4x4 19 -/* 8x8 intra prediction modes */ -#define VERT_PRED 0 -#define HOR_PRED 1 -#define DC_PRED 2 -#define DOWN_LEFT_PRED 3 -#define DOWN_RIGHT_PRED 4 - -#define VERT_PRED_4x4 0 -#define HOR_PRED_4x4 1 -#define DC_PRED_4x4 2 -#define DOWN_LEFT_PRED_4x4 3 -#define DOWN_RIGHT_PRED_4x4 4 - -#define HOR_DOWN_PRED_4x4 5 -#define VERT_LEFT_PRED_4x4 6 -#define HOR_UP_PRED_4x4 7 -#define VERT_RIGHT_PRED_4x4 8 - -#define DC_PRED_8 0 -#define HOR_PRED_8 1 -#define VERT_PRED_8 2 -#define PLANE_8 3 - -#define LUMA_16DC 0 -#define LUMA_16AC 1 -#define LUMA_8x8 2 -#define LUMA_8x4 3 -#define LUMA_4x8 4 -#define LUMA_4x4 5 -#define CHROMA_DC 6 -#define CHROMA_AC 7 -#define NUM_BLOCK_TYPES 8 - -#define I_PICTURE_START_CODE 0xB3 -#define PB_PICTURE_START_CODE 0xB6 -#define SLICE_START_CODE_MIN 0x00 -#define SLICE_START_CODE_MAX 0xAF -#define USER_DATA_START_CODE 0xB2 -#define SEQUENCE_HEADER_CODE 0xB0 -#define EXTENSION_START_CODE 0xB5 -#define SEQUENCE_END_CODE 0xB1 -#define VIDEO_EDIT_CODE 0xB7 - -#define EOS 1 -#define SOP 2 -#define SOS 3 -#define P8x8 8 -#define I8MB 9 -#define I4MB 10 -#define IBLOCK 11 -#define SI4MB 12 -#define MAXMODE 13 - -#define IS_INTRA(MB) ((MB)->mb_type == I8MB || (MB)->mb_type == I4MB) -#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB) -#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB) -#define IS_INTER(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB) -#define IS_INTERMV(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB\ - && (MB)->mb_type != 0) - -#define IS_DIRECT(MB) ((MB)->mb_type == 0 && (img->type == B_IMG)) -#define IS_COPY(MB) ((MB)->mb_type == 0 && (img->type == P_IMG)) -#define IS_P8x8(MB) ((MB)->mb_type == P8x8) - -#define P_IMG 0 -#define B_IMG 1 -#define I_IMG 2 - -#define FIELD 0 -#define FRAME 1 - -#define SE_CABP 21 -struct decoding_environment_s { - unsigned int dbuffer; - int dbits_to_go; - unsigned char *dcodestrm; - int *dcodestrm_len; -}; - -struct bi_context_type_s { - unsigned char MPS; - unsigned int LG_PMPS; - unsigned char cycno; -}; - - -/********************************************************************** - * C O N T E X T S F O R R M S Y N T A X E L E M E N T S - ********************************************************************** - */ - -#define NUM_MB_TYPE_CTX 11 -#define NUM_B8_TYPE_CTX 9 -#define NUM_MV_RES_CTX 10 -#define NUM_REF_NO_CTX 6 -#define NUM_DELTA_QP_CTX 4 -#define NUM_MB_AFF_CTX 4 - -struct motion_info_contexts_s { - struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX]; - struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX]; - struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX]; - struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX]; - struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX]; - struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX]; -#ifdef TEST_WEIGHTING_AEC -struct bi_context_type_s mb_weighting_pred; -#endif -}; - -#define NUM_IPR_CTX 2 -#define NUM_CIPR_CTX 4 -#define NUM_CBP_CTX 4 -#define NUM_BCBP_CTX 4 -#define NUM_MAP_CTX 16 -#define NUM_LAST_CTX 16 - -#define NUM_ONE_CTX 5 -#define NUM_ABS_CTX 5 - -struct texture_info_contexts { - struct bi_context_type_s ipr_contexts[NUM_IPR_CTX]; - struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX]; - struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX]; - struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX]; - struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX]; - struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX]; - struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX]; - struct bi_context_type_s fld_last_contexts - [NUM_BLOCK_TYPES][NUM_LAST_CTX]; - struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX]; - struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX]; -}; -struct img_par; - -struct syntaxelement { - int type; - int value1; - int value2; - int len; - int inf; - unsigned int bitpattern; - int context; - int k; - int golomb_grad; - int golomb_maxlevels; -#if TRACE -#define TRACESTRING_SIZE 100 - char tracestring[TRACESTRING_SIZE]; -#endif - - void (*mapping)(int len, int info, int *value1, int *value2); - - void (*reading)(struct syntaxelement *, struct img_par *, - struct decoding_environment_s *); - -}; - -struct bitstream_s { - - int read_len; - int code_len; - - int frame_bitoffset; - int bitstream_length; - - unsigned char *stream_buffer; -}; - -struct datapartition { - - struct bitstream_s *bitstream; - struct decoding_environment_s de_aec; - - int (*read_syntax_element)(struct syntaxelement *, struct img_par *, - struct datapartition *); -/*!< virtual function; - actual method depends on chosen data partition and - entropy coding method */ -}; - -struct slice_s { - int picture_id; - int qp; - int picture_type; - int start_mb_nr; - int max_part_nr; - int num_mb; - - struct datapartition *part_arr; - struct motion_info_contexts_s *mot_ctx; - struct texture_info_contexts *tex_ctx; - int field_ctx[3][2]; -}; - -struct img_par { - int number; - int current_mb_nr; - int max_mb_nr; - int current_slice_nr; - int tr; - int qp; - int type; - - int typeb; - - int width; - int height; - int width_cr; - int height_cr; - int source_bitdepth; - int mb_y; - int mb_x; - int block_y; - int pix_y; - int pix_x; - int pix_c_y; - int block_x; - int pix_c_x; - - int ***mv; - int mpr[16][16]; - - int m7[16][16]; - int m8[/*2*/4][8][8]; - int cof[4][/*6*/8][4][4]; - int cofu[4]; - int **ipredmode; - int quad[256]; - int cod_counter; - - int ***dfmv; - int ***dbmv; - int **fw_reffrarr; - int **bw_reffrarr; - - int ***mv_frm; - int **fw_reffrarr_frm; - int **bw_reffrarr_frm; - int imgtr_next_p; - int imgtr_last_p; - int tr_frm; - int tr_fld; - int imgtr_last_prev_p; - - int no_forward_reference; - int seq_header_indicate; - int b_discard_flag; - - int ***fw_mv; - int ***bw_mv; - int subblock_x; - int subblock_y; - - int buf_cycle; - - int direct_type; - - int ***mv_top; - int ***mv_bot; - int **fw_reffrarr_top; - int **bw_reffrarr_top; - int **fw_reffrarr_bot; - int **bw_reffrarr_bot; - - int **ipredmode_top; - int **ipredmode_bot; - int ***fw_mv_top; - int ***fw_mv_bot; - int ***bw_mv_top; - int ***bw_mv_bot; - int ***dfmv_top; - int ***dbmv_top; - int ***dfmv_bot; - int ***dbm_bot; - - int toppoc; - int bottompoc; - int framepoc; - unsigned int frame_num; - - unsigned int pic_distance; - int delta_pic_order_cnt_bottom; - - signed int pic_distance_msb; - unsigned int prev_pic_distance_lsb; - signed int curr_pic_distance_msb; - unsigned int this_poc; - - int pic_width_inmbs; - int pic_height_inmbs; - int pic_size_inmbs; - - int block8_x, block8_y; - int structure; - int pn; - int buf_used; - int buf_size; - int picture_structure; - int advanced_pred_mode_disable; - int types; - int current_mb_nr_fld; - - int p_field_enhanced; - int b_field_enhanced; - - int slice_weighting_flag; - int lum_scale[4]; - int lum_shift[4]; - int chroma_scale[4]; - int chroma_shift[4]; - int mb_weighting_flag; - int weighting_prediction; - int mpr_weight[16][16]; - int top_bot; - int bframe_number; - - int auto_crop_right; - int auto_crop_bottom; - - struct slice_s *current_slice; - int is_v_block; - int is_intra_block; - - int new_seq_header_flag; - int new_sequence_flag; - int last_pic_bbv_delay; - - int sequence_end_flag; - int is_top_field; - - int abt_flag; - int qp_shift; - -#ifdef EIGHTH -int eighth_subpixel_flag; -int subpixel_precision; -int unit_length; -int subpixel_mask; - -int max_mvd; -int min_mvd; -#endif - -}; - -struct macroblock { - int qp; - int slice_nr; - int delta_quant; - struct macroblock *mb_available[3][3]; - /*!< pointer to neighboring MBs in a 3x3 window of current MB, - which is located at [1][1] - NULL pointer identifies neighboring MBs which are unavailable */ - - int mb_type; - int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2]; - int cbp, cbp_blk, cbp01; - unsigned long cbp_bits; - - int b8mode[4]; - int b8pdir[4]; - int mb_type_2; - int c_ipred_mode_2; - int dct_mode; - - int c_ipred_mode; - int lf_disable; - int lf_alpha_c0_offset; - int lf_beta_offset; - - int CABT[4]; - int CABP[4]; - int cbp_4x4[4]; - - int skip_flag; - - struct macroblock *mb_available_up; - struct macroblock *mb_available_left; - int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d; - int mbavail_a, mbavail_b, mbavail_c, mbavail_d; - -}; - -struct macroblock *mb_data; - -struct img_par *img; - -struct bitstream_s *curr_stream; - -struct datapartition *alloc_partition(int n); - -unsigned int vld_mem_start_addr; -unsigned int vld_mem_end_addr; - -int marker_bit; - -int progressive_sequence; -int horizontal_size; -int vertical_size; - -int second_ifield; -int pre_img_type; - -/* slice_header() */ -int slice_vertical_position; -int slice_vertical_position_extension; -int fixed_picture_qp; -int fixed_slice_qp; -int slice_qp; - -/* - ************************************************************************* - * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in - the global UsedBits variable - * Input: - tracestring - the string for the trace file - bitstream - the stream to be read from - * Output: - * Return: the value of the coded syntax element - * Attention: - ************************************************************************* - */ -/*! - * definition of AVS syntaxelements - * order of elements follow dependencies for picture reconstruction - */ -/*! - * \brief Assignment of old TYPE partition elements to new - * elements - * - * old element | new elements - * TYPE_HEADER | SE_HEADER, SE_PTYPE - * TYPE_MBHEADER | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE - * TYPE_MVD | SE_MVD - * TYPE_CBP | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER - * SE_DELTA_QUANT_INTRA - * TYPE_COEFF_Y | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA, - SE_LUM_DC_INTER, SE_LUM_AC_INTER - * TYPE_2x2DC | SE_CHR_DC_INTRA, SE_CHR_DC_INTER - * TYPE_COEFF_C | SE_CHR_AC_INTRA, SE_CHR_AC_INTER - * TYPE_EOS | SE_EOS - */ - -#define SE_HEADER 0 -#define SE_PTYPE 1 -#define SE_MBTYPE 2 -#define SE_REFFRAME 3 -#define SE_INTRAPREDMODE 4 -#define SE_MVD 5 -#define SE_CBP_INTRA 6 -#define SE_LUM_DC_INTRA 7 -#define SE_CHR_DC_INTRA 8 -#define SE_LUM_AC_INTRA 9 -#define SE_CHR_AC_INTRA 10 -#define SE_CBP_INTER 11 -#define SE_LUM_DC_INTER 12 -#define SE_CHR_DC_INTER 13 -#define SE_LUM_AC_INTER 14 -#define SE_CHR_AC_INTER 15 -#define SE_DELTA_QUANT_INTER 16 -#define SE_DELTA_QUANT_INTRA 17 -#define SE_BFRAME 18 -#define SE_EOS 19 -#define SE_MAX_ELEMENTS 20 -#define SE_CBP01 21 -int chroma_format; -/* - ************************************************************************* - * Function:Reads bits from the bitstream buffer - * Input: - byte buffer[] - containing VLC-coded data bits - int totbitoffset - bit offset from start of partition - int bytecount - total bytes in bitstream - int numbits - number of bits to read - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int get_bits(unsigned char buffer[], int totbitoffset, int *info, int bytecount, - int numbits) -{ - register int inf; - long byteoffset; - int bitoffset; - - int bitcounter = numbits; - - byteoffset = totbitoffset / 8; - bitoffset = 7 - (totbitoffset % 8); - - inf = 0; - while (numbits) { - inf <<= 1; - inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset; - numbits--; - bitoffset--; - if (bitoffset < 0) { - byteoffset++; - bitoffset += 8; - if (byteoffset > bytecount) - return -1; - } - } - - *info = inf; - - - return bitcounter; -} - -/* - ************************************************************************* - * Function:read FLC codeword from UVLC-partition - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int read_syntaxelement_flc(struct syntaxelement *sym) -{ - int frame_bitoffset = curr_stream->frame_bitoffset; - unsigned char *buf = curr_stream->stream_buffer; - int bitstreamlengthinbytes = curr_stream->bitstream_length; - - if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes, - sym->len)) < 0) - return -1; - - curr_stream->frame_bitoffset += sym->len; - sym->value1 = sym->inf; - -#if TRACE - tracebits2(sym->tracestring, sym->len, sym->inf); -#endif - - return 1; -} - -/* - ************************************************************************* - * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in - the global UsedBits variable - * Input: - tracestring - the string for the trace file - bitstream - the stream to be read from - * Output: - * Return: the value of the coded syntax element - * Attention: - ************************************************************************* - */ -int u_1(char *tracestring) -{ - return u_v(1, tracestring); -} - -/* - ************************************************************************* - * Function:mapping rule for ue(v) syntax elements - * Input:lenght and info - * Output:number in the code table - * Return: - * Attention: - ************************************************************************* - */ -void linfo_ue(int len, int info, int *value1, int *dummy) -{ - *value1 = (int)pow2(2, (len / 2)) + info - 1; -} - -int u_v(int leninbits, char *tracestring) -{ - struct syntaxelement symbol, *sym = &symbol; - -#ifdef AVSP_LONG_CABAC -#else - assert(curr_stream->stream_buffer != NULL); -#endif - sym->type = SE_HEADER; - sym->mapping = linfo_ue; - sym->len = leninbits; - read_syntaxelement_flc(sym); - - return sym->inf; -} - -/* - ************************************************************************* - * Function:mapping rule for se(v) syntax elements - * Input:lenght and info - * Output:signed mvd - * Return: - * Attention: - ************************************************************************* - */ - -void linfo_se(int len, int info, int *value1, int *dummy) -{ - int n; - n = (int)pow2(2, (len / 2)) + info - 1; - *value1 = (n + 1) / 2; - if ((n & 0x01) == 0) - *value1 = -*value1; - -} - -/* - ************************************************************************* - * Function:lenght and info - * Input: - * Output:cbp (intra) - * Return: - * Attention: - ************************************************************************* - */ - -void linfo_cbp_intra(int len, int info, int *cbp, int *dummy) -{ -} - -const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18}, - {9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12}, - {7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, { - 48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59}, - {26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23, - 24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56, - 52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, { - 27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47}, - {42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57, - 56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, { - 15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22}, - {34, 32}, {13, 20}, {20, 23}, {0, 2} }; - -unsigned int s1, t1, value_s, value_t; -unsigned char dec_bypass, dec_final; - -#define get_byte() { \ - dbuffer = dcodestrm[(*dcodestrm_len)++];\ - dbits_to_go = 7; \ -} - -#define dbuffer (dep->dbuffer) -#define dbits_to_go (dep->dbits_to_go) -#define dcodestrm (dep->dcodestrm) -#define dcodestrm_len (dep->dcodestrm_len) - -#define B_BITS 10 - -#define LG_PMPS_SHIFTNO 2 - -#define HALF (1 << (B_BITS-1)) -#define QUARTER (1 << (B_BITS-2)) - -unsigned int biari_decode_symbol(struct decoding_environment_s *dep, - struct bi_context_type_s *bi_ct) -{ - register unsigned char bit; - register unsigned char s_flag; - register unsigned char is_lps = 0; - register unsigned char cwr; - register unsigned char cycno = bi_ct->cycno; - register unsigned int lg_pmps = bi_ct->LG_PMPS; - register unsigned int t_rlps; - register unsigned int s2, t2; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n", - bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct); -#endif - - bit = bi_ct->MPS; - - cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5; - - if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) { - s2 = s1; - t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 0; - } else { - s2 = s1 + 1; - t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 1; - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" s2 : %d, t2 : %03X\n", s2, t2); -#endif - - if (s2 > value_s || (s2 == value_s && value_t >= t2)) { - is_lps = 1; - bit = !bit; - - t_rlps = (s_flag == 0) ? - (lg_pmps >> LG_PMPS_SHIFTNO) : - (t1 + (lg_pmps >> LG_PMPS_SHIFTNO)); - - if (s2 == value_s) - value_t = (value_t - t2); - else { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - value_t = 256 + value_t - t2; - - } - - while (t_rlps < QUARTER) { - t_rlps = t_rlps << 1; - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - - s1 = 0; - t1 = t_rlps & 0xff; - - value_s = 0; - while (value_t < QUARTER) { - int j; - if (--dbits_to_go < 0) - get_byte(); - j = (dbuffer >> dbits_to_go) & 0x01; - - value_t = (value_t << 1) | j; - value_s++; - } - value_t = value_t & 0xff; - } else { - - s1 = s2; - t1 = t2; - } - - if (dec_bypass) - return bit; - - if (is_lps) - cycno = (cycno <= 2) ? (cycno + 1) : 3; - else if (cycno == 0) - cycno = 1; - bi_ct->cycno = cycno; - - if (is_lps) { - switch (cwr) { - case 3: - lg_pmps = lg_pmps + 197; - break; - case 4: - lg_pmps = lg_pmps + 95; - break; - default: - lg_pmps = lg_pmps + 46; - } - - if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps; - bi_ct->MPS = !(bi_ct->MPS); - } - } else { -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n", - lg_pmps - (unsigned int)(lg_pmps>>cwr) - - (unsigned int)(lg_pmps>>(cwr+2)), - lg_pmps, - (unsigned int)(lg_pmps>>cwr), - (unsigned int)(lg_pmps>>(cwr+2)) - ); -#endif - lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr) - - (unsigned int)(lg_pmps >> (cwr + 2)); - } - - bi_ct->LG_PMPS = lg_pmps; - - return bit; -} - -unsigned int biari_decode_symbolw(struct decoding_environment_s *dep, - struct bi_context_type_s *bi_ct1, - struct bi_context_type_s *bi_ct2) -{ - register unsigned char bit1, bit2; - register unsigned char pred_mps, bit; - register unsigned int lg_pmps; - register unsigned char cwr1, cycno1 = bi_ct1->cycno; - register unsigned char cwr2, cycno2 = bi_ct2->cycno; - register unsigned int lg_pmps1 = bi_ct1->LG_PMPS; - register unsigned int lg_pmps2 = - bi_ct2->LG_PMPS; - register unsigned int t_rlps; - register unsigned char s_flag, is_lps = 0; - register unsigned int s2, t2; - - - bit1 = bi_ct1->MPS; - bit2 = bi_ct2->MPS; - - cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5; - cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5; - - if (bit1 == bit2) { - pred_mps = bit1; - lg_pmps = (lg_pmps1 + lg_pmps2) / 2; - } else { - if (lg_pmps1 < lg_pmps2) { - pred_mps = bit1; - lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1 - - ((lg_pmps2 - lg_pmps1) >> 1); - } else { - pred_mps = bit2; - lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1 - - ((lg_pmps1 - lg_pmps2) >> 1); - } - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n", - lg_pmps, pred_mps); -#endif - if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) { - s2 = s1; - t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 0; - } else { - s2 = s1 + 1; - t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO); - s_flag = 1; - } - - bit = pred_mps; - if (s2 > value_s || (s2 == value_s && value_t >= t2)) { - is_lps = 1; - bit = !bit; - t_rlps = (s_flag == 0) ? - (lg_pmps >> LG_PMPS_SHIFTNO) : - (t1 + (lg_pmps >> LG_PMPS_SHIFTNO)); - - if (s2 == value_s) - value_t = (value_t - t2); - else { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - value_t = 256 + value_t - t2; - } - - while (t_rlps < QUARTER) { - t_rlps = t_rlps << 1; - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - s1 = 0; - t1 = t_rlps & 0xff; - - value_s = 0; - while (value_t < QUARTER) { - int j; - if (--dbits_to_go < 0) - get_byte(); - j = (dbuffer >> dbits_to_go) & 0x01; - - value_t = (value_t << 1) | j; - value_s++; - } - value_t = value_t & 0xff; - } else { - s1 = s2; - t1 = t2; - } - - if (bit != bit1) { - cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3; - } else { - if (cycno1 == 0) - cycno1 = 1; - } - - if (bit != bit2) { - cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3; - } else { - if (cycno2 == 0) - cycno2 = 1; - } - bi_ct1->cycno = cycno1; - bi_ct2->cycno = cycno2; - - { - - if (bit == bit1) { - lg_pmps1 = - lg_pmps1 - - (unsigned int)(lg_pmps1 - >> cwr1) - - (unsigned int)(lg_pmps1 - >> (cwr1 - + 2)); - } else { - switch (cwr1) { - case 3: - lg_pmps1 = lg_pmps1 + 197; - break; - case 4: - lg_pmps1 = lg_pmps1 + 95; - break; - default: - lg_pmps1 = lg_pmps1 + 46; - } - - if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1 - - lg_pmps1; - bi_ct1->MPS = !(bi_ct1->MPS); - } - } - bi_ct1->LG_PMPS = lg_pmps1; - - if (bit == bit2) { - lg_pmps2 = - lg_pmps2 - - (unsigned int)(lg_pmps2 - >> cwr2) - - (unsigned int)(lg_pmps2 - >> (cwr2 - + 2)); - } else { - switch (cwr2) { - case 3: - lg_pmps2 = lg_pmps2 + 197; - break; - case 4: - lg_pmps2 = lg_pmps2 + 95; - break; - default: - lg_pmps2 = lg_pmps2 + 46; - } - - if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) { - lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1 - - lg_pmps2; - bi_ct2->MPS = !(bi_ct2->MPS); - } - } - bi_ct2->LG_PMPS = lg_pmps2; - } - - - return bit; -} - -/*! - ************************************************************************ - * \brief - * biari_decode_symbol_eq_prob(): - * \return - * the decoded symbol - ************************************************************************ - */ -unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep) -{ - unsigned char bit; - struct bi_context_type_s octx; - struct bi_context_type_s *ctx = &octx; - ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1; - ctx->MPS = 0; - ctx->cycno = 0xfe; - dec_bypass = 1; - bit = biari_decode_symbol(dep, ctx); - dec_bypass = 0; - return bit; -} - -unsigned int biari_decode_final(struct decoding_environment_s *dep) -{ - unsigned char bit; - struct bi_context_type_s octx; - struct bi_context_type_s *ctx = &octx; - ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO; - ctx->MPS = 0; - ctx->cycno = 0xff; - dec_final = 1; - bit = biari_decode_symbol(dep, ctx); - dec_final = 0; - return bit; -} - -int i_8(char *tracestring) -{ - int frame_bitoffset = curr_stream->frame_bitoffset; - unsigned char *buf = curr_stream->stream_buffer; - int bitstreamlengthinbytes = curr_stream->bitstream_length; - struct syntaxelement symbol, *sym = &symbol; -#ifdef AVSP_LONG_CABAC -#else - assert(curr_stream->stream_buffer != NULL); -#endif - - sym->len = 8; - sym->type = SE_HEADER; - sym->mapping = linfo_ue; - - if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes, - sym->len)) < 0) - return -1; - curr_stream->frame_bitoffset += sym->len; - sym->value1 = sym->inf; - if (sym->inf & 0x80) - sym->inf = -(~((int)0xffffff00 | sym->inf) + 1); -#if TRACE - tracebits2(sym->tracestring, sym->len, sym->inf); -#endif - return sym->inf; -} - -/*! - ************************************************************************ - * \brief - * arideco_bits_read - ************************************************************************ - */ -int arideco_bits_read(struct decoding_environment_s *dep) -{ - - return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go); -} - -/*! - ************************************************************************ - * \brief - * arithmetic decoding - ************************************************************************ - */ -int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img, - struct datapartition *this_data_part) -{ - int curr_len; - struct decoding_environment_s *dep_dp = &(this_data_part->de_aec); - - curr_len = arideco_bits_read(dep_dp); - - se->reading(se, img, dep_dp); - - se->len = (arideco_bits_read(dep_dp) - curr_len); - return se->len; -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the - * run length info of the skip mb - ************************************************************************ - */ -void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct bi_context_type_s *pctx; - int ctx, symbol; - pctx = img->current_slice->tex_ctx->one_contexts[0]; - symbol = 0; - ctx = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 3) - ctx = 3; - } - se->value1 = symbol; -#if TRACE - fprintf(p_trace, "@%d%s\t\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode a pair of - * intra prediction modes of a given MB. - ************************************************************************ - */ -int mapd_intrap[5] = {0, 2, 3, 4, 1}; -void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct bi_context_type_s *pctx; - int ctx, symbol; - pctx = img->current_slice->tex_ctx->one_contexts[1]; - symbol = 0; - ctx = 0; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx); -#endif - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 3) - ctx = 3; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & AEC_DUMP) - io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx); -#endif - if (symbol == 4) - break; - } - se->value1 = mapd_intrap[symbol] - 1; - -#if TRACE - fprintf(p_trace, "@%d %s\t\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif -} - -/*! - ************************************************************************ - * \brief - * decoding of unary binarization using one or 2 distinct - * models for the first and all remaining bins; no terminating - * "0" for max_symbol - *********************************************************************** - */ -unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp, - struct bi_context_type_s *ctx, - int ctx_offset, unsigned int max_symbol) -{ - unsigned int l; - unsigned int symbol; - struct bi_context_type_s *ictx; - - symbol = biari_decode_symbol(dep_dp, ctx); - - if (symbol == 0) - return 0; - else { - if (max_symbol == 1) - return symbol; - symbol = 0; - ictx = ctx + ctx_offset; - do { - l = biari_decode_symbol(dep_dp, ictx); - symbol++; - } while ((l != 0) && (symbol < max_symbol - 1)); - if ((l != 0) && (symbol == max_symbol - 1)) - symbol++; - return symbol; - } -} - -/*! - ************************************************************************ - * \brief - * decoding of unary binarization using one or 2 distinct - * models for the first and all remaining bins - *********************************************************************** - */ -unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp, - struct bi_context_type_s *ctx, int ctx_offset) -{ - unsigned int l; - unsigned int symbol; - struct bi_context_type_s *ictx; - - symbol = 1 - biari_decode_symbol(dep_dp, ctx); - - if (symbol == 0) - return 0; - else { - symbol = 0; - ictx = ctx + ctx_offset; - do { - l = 1 - biari_decode_symbol(dep_dp, ictx); - symbol++; - } while (l != 0); - return symbol; - } -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the chroma - * intra prediction mode of a given MB. - ************************************************************************ - */ -void read_cipredmode_aec(struct syntaxelement *se, - struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct texture_info_contexts *ctx = img->current_slice->tex_ctx; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - int act_ctx, a, b; - int act_sym = se->value1; - - if (curr_mb->mb_available_up == NULL) - b = 0; - else { - /*if ( (curr_mb->mb_available_up)->mb_type==IPCM) - b=0; - else*/ - b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0); - } - - if (curr_mb->mb_available_left == NULL) - a = 0; - else { - /* if ( (curr_mb->mb_available_left)->mb_type==IPCM) - a=0; - else*/ - a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0); - } - - act_ctx = a + b; - - - act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx); - - if (act_sym != 0) - act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3, - 0, 2) + 1; - - se->value1 = act_sym; - -#if TRACE - fprintf(p_trace, "@%d %s\t\t%d\n", - symbol_count++, se->tracestring, se->value1); - fflush(p_trace); -#endif - -} - -int slice_header(char *buf, int startcodepos, int length) -{ - int i; - - int weight_para_num = 0; - int mb_row; - int mb_column; - int mb_index; - int mb_width, mb_height; - - mb_column = 0; - - memcpy(curr_stream->stream_buffer, buf, length); - curr_stream->code_len = curr_stream->bitstream_length = length; - - curr_stream->read_len = - curr_stream->frame_bitoffset = (startcodepos) * 8; - slice_vertical_position = u_v(8, "slice vertical position"); - - push_es(slice_vertical_position, 8); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 8-bits slice_vertical_position : %d\n", - slice_vertical_position); -#endif - - if (vertical_size > 2800) { - slice_vertical_position_extension = u_v(3, - "slice vertical position extension"); - push_es(slice_vertical_position_extension, 3); - - } - - if (vertical_size > 2800) - mb_row = (slice_vertical_position_extension << 7) - + slice_vertical_position; - else - mb_row = slice_vertical_position; - - mb_width = (horizontal_size + 15) / 16; - if (!progressive_sequence) - mb_height = 2 * ((vertical_size + 31) / 32); - else - mb_height = (vertical_size + 15) / 16; - - - mb_index = mb_row * mb_width + mb_column; - - if (!img->picture_structure && img->type == I_IMG - && (mb_index >= mb_width * mb_height / 2)) { - second_ifield = 1; - img->type = P_IMG; - pre_img_type = P_IMG; - } - - { - if (!fixed_picture_qp) { - fixed_slice_qp = u_v(1, "fixed_slice_qp"); - push_es(fixed_slice_qp, 1); -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 1-bit fixed_slice_qp : %d\n", - fixed_slice_qp); -#endif - slice_qp = u_v(6, "slice_qp"); - push_es(slice_qp, 6); -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" * 6-bits slice_qp : %d\n", - slice_qp); -#endif - - img->qp = slice_qp; - } - - if (img->type != I_IMG) { - img->slice_weighting_flag = u_v(1, - "slice weighting flag"); - - if (img->slice_weighting_flag) { - - if (second_ifield && !img->picture_structure) - weight_para_num = 1; - else if (img->type == P_IMG - && img->picture_structure) - weight_para_num = 2; - else if (img->type == P_IMG - && !img->picture_structure) - weight_para_num = 4; - else if (img->type == B_IMG - && img->picture_structure) - weight_para_num = 2; - else if (img->type == B_IMG - && !img->picture_structure) - weight_para_num = 4; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" - weight_para_num : %d\n", - weight_para_num); -#endif - for (i = 0; i < weight_para_num; i++) { - img->lum_scale[i] = u_v(8, - "luma scale"); - - img->lum_shift[i] = i_8("luma shift"); - - marker_bit = u_1("insert bit"); - - - { - img->chroma_scale[i] = u_v(8, - "chroma scale"); - - img->chroma_shift[i] = i_8( - "chroma shift"); - - marker_bit = u_1("insert bit"); - - } - } - img->mb_weighting_flag = u_v(1, - "MB weighting flag"); - - } - } - } - - -#if 1 - return mb_index; -#endif -} - -void no_mem_exit(char *where) -{ - io_printf("%s\r\n", where); -} - -unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; - -struct inputstream_s { - /*FILE *f;*/ - unsigned char buf[SVA_STREAM_BUF_SIZE]; - unsigned int uclear_bits; - unsigned int upre_3bytes; - int ibyte_position; - int ibuf_bytesnum; - int iclear_bitsnum; - int istuff_bitsnum; - int ibits_count; -}; - -struct inputstream_s IRABS; -struct inputstream_s *p_irabs = &IRABS; - -struct stat_bits { - int curr_frame_bits; - int prev_frame_bits; - int emulate_bits; - int prev_emulate_bits; - int last_unit_bits; - int bitrate; - int total_bitrate[1000]; - int coded_pic_num; - int time_s; -}; - -struct stat_bits *stat_bits_ptr; - -unsigned char *temp_slice_buf; -int start_codeposition; -int first_slice_length; -int first_slice_startpos; - -int bitstream_buf_used; -int startcode_offset; - -int bitstream_read_ptr; - -int demulate_enable; - -int last_dquant; - -int total_mb_count; - -int current_mb_skip; - -int skip_mode_flag; - -int current_mb_intra; - -/* - ************************************************************************* - * Function: Check start code's type - * Input: - * Output: - * Return: - * Author: XZHENG, 20080515 - ************************************************************************* - */ -void check_type(int startcode) -{ - startcode = startcode & 0x000000ff; - switch (startcode) { - case 0xb0: - case 0xb2: - case 0xb5: - demulate_enable = 0; - break; - default: - demulate_enable = 1; - break; - } - -} -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: 0 : OK - -1 : arrive at stream end - -2 : meet another start code - * Attention: - ************************************************************************* - */ -int clear_nextbyte(struct inputstream_s *p) -{ - int i, k, j; - unsigned char temp[3]; - i = p->ibyte_position; - k = p->ibuf_bytesnum - i; - if (k < 3) { - for (j = 0; j < k; j++) - temp[j] = p->buf[i + j]; - - p->ibuf_bytesnum = read_bitstream(p->buf + k, - SVA_STREAM_BUF_SIZE - k); - bitstream_buf_used++; - if (p->ibuf_bytesnum == 0) { - if (k > 0) { - while (k > 0) { - p->upre_3bytes = ((p->upre_3bytes << 8) - | p->buf[i]) - & 0x00ffffff; - if (p->upre_3bytes < 4 - && demulate_enable) { - p->uclear_bits = - (p->uclear_bits - << 6) - | (p->buf[i] - >> 2); - p->iclear_bitsnum += 6; - stat_bits_ptr->emulate_bits - += 2; - } else { - p->uclear_bits = (p->uclear_bits - << 8) - | p->buf[i]; - p->iclear_bitsnum += 8; - } - p->ibyte_position++; - k--; - i++; - } - return 0; - } else { - return -1; - } - } else { - for (j = 0; j < k; j++) - p->buf[j] = temp[j]; - p->ibuf_bytesnum += k; - i = p->ibyte_position = 0; - } - } - if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1) - return -2; - p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff; - if (p->upre_3bytes < 4 && demulate_enable) { - p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2); - p->iclear_bitsnum += 6; - stat_bits_ptr->emulate_bits += 2; - } else { - p->uclear_bits = (p->uclear_bits << 8) | p->buf[i]; - p->iclear_bitsnum += 8; - } - p->ibyte_position++; - return 0; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: 0 : OK - -1 : arrive at stream end - -2 : meet another start code - * Attention: - ************************************************************************* - */ -int read_n_bit(struct inputstream_s *p, int n, int *v) -{ - int r; - unsigned int t; - while (n > p->iclear_bitsnum) { - r = clear_nextbyte(p); - if (r) { - if (r == -1) { - if (p->ibuf_bytesnum - p->ibyte_position > 0) - break; - } - return r; - } - } - t = p->uclear_bits; - r = 32 - p->iclear_bitsnum; - *v = (t << r) >> (32 - n); - p->iclear_bitsnum -= n; - return 0; -} - -#ifdef AVSP_LONG_CABAC -unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE]; -int tmp_buf_wr_ptr; -int tmp_buf_rd_ptr; -int tmp_buf_count; -#endif -void open_irabs(struct inputstream_s *p) -{ - p->uclear_bits = 0xffffffff; - p->ibyte_position = 0; - p->ibuf_bytesnum = 0; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count = 0; - p->upre_3bytes = 0; - - bitstream_buf_used = 0; - bitstream_read_ptr = (src_start - 16) & 0xfffffff0; - -#ifdef AVSP_LONG_CABAC - tmp_buf_count = 0; - tmp_buf_wr_ptr = 0; - tmp_buf_rd_ptr = 0; -#endif - -} - -void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr, - int move_size) -{ - int move_bytes_left = move_size; - unsigned int move_read_addr; - unsigned int move_write_addr = move_to_addr; - - int move_byte; - unsigned int data32; - - while (move_from_addr > vld_mem_end_addr) { - move_from_addr = move_from_addr + vld_mem_start_addr - - vld_mem_end_addr - 8; - } - move_read_addr = move_from_addr; - while (move_bytes_left > 0) { - move_byte = move_bytes_left; - if (move_byte > 512) - move_byte = 512; - if ((move_read_addr + move_byte) > vld_mem_end_addr) - move_byte = (vld_mem_end_addr + 8) - move_read_addr; - - WRITE_VREG(LMEM_DMA_ADR, move_read_addr); - WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2); - WRITE_VREG(LMEM_DMA_CTRL, 0xc200); - - data32 = 0x8000; - while (data32 & 0x8000) - data32 = READ_VREG(LMEM_DMA_CTRL); - - WRITE_VREG(LMEM_DMA_ADR, move_write_addr); - WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2); - WRITE_VREG(LMEM_DMA_CTRL, 0x8200); - - data32 = 0x8000; - while (data32 & 0x8000) - data32 = READ_VREG(LMEM_DMA_CTRL); - - data32 = 0x0fff; - while (data32 & 0x0fff) - data32 = READ_VREG(WRRSP_LMEM); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & STREAM_INFO_DUMP) - io_printf(" 2 MOVE %d Bytes from 0x%x to 0x%x\n", - move_byte, move_read_addr, move_write_addr); -#endif - - move_read_addr = move_read_addr + move_byte; - if (move_read_addr > vld_mem_end_addr) - move_read_addr = vld_mem_start_addr; - move_write_addr = move_write_addr + move_byte; - move_bytes_left = move_bytes_left - move_byte; - } - -} - -int read_bitstream(unsigned char *buf, int size) -{ - int i; - -#ifdef AVSP_LONG_CABAC - - unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp; - if (tmp_buf_count < size) { - dma_sync_single_for_cpu(amports_get_dma_device(), - bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE, - DMA_FROM_DEVICE); - - move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy, - SVA_STREAM_BUF_SIZE); - - for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) { - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 1] >> 24) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 1] >> 16) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 0] >> 24) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = - (TMP_BUF_32[2 * i + 0] >> 16) & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0) - & 0xff; - if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_wr_ptr = 0; - } - tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE; - bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE; - } - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & STREAM_INFO_DUMP) - io_printf(" Read %d bytes from %d, size left : %d\n", - size, tmp_buf_rd_ptr, tmp_buf_count); -#endif - for (i = 0; i < size; i++) { - buf[i] = TMP_BUF[tmp_buf_rd_ptr++]; - if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE)) - tmp_buf_rd_ptr = 0; - } - tmp_buf_count = tmp_buf_count - size; - -#else - for (i = 0; i < size; i++) - buf[i] = tmp_stream[bitstream_read_ptr + i]; - bitstream_read_ptr = bitstream_read_ptr + size; -#endif - - return size; -} - -int next_startcode(struct inputstream_s *p) -{ - int i, m; - unsigned char a = 0, b = 0; - m = 0; - - while (1) { - if (p->ibyte_position >= p->ibuf_bytesnum - 2) { - m = p->ibuf_bytesnum - p->ibyte_position; - if (m < 0) - return -2; - if (m == 1) - b = p->buf[p->ibyte_position + 1]; - if (m == 2) { - b = p->buf[p->ibyte_position + 1]; - a = p->buf[p->ibyte_position]; - } - p->ibuf_bytesnum = read_bitstream(p->buf, - SVA_STREAM_BUF_SIZE); - p->ibyte_position = 0; - bitstream_buf_used++; - } - - if (p->ibuf_bytesnum + m < 3) - return -1; - - if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) { - p->ibyte_position = 2; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) { - p->ibyte_position = 1; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) { - p->ibyte_position = 2; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - - for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) { - if (p->buf[i] == 0 && p->buf[i + 1] == 0 - && p->buf[i + 2] == 1) { - p->ibyte_position = i + 3; - p->iclear_bitsnum = 0; - p->istuff_bitsnum = 0; - p->ibits_count += 24; - p->upre_3bytes = 1; - return 0; - } - p->ibits_count += 8; - } - p->ibyte_position = i; - } -} - -int get_oneunit(char *buf, int *startcodepos, int *length) -{ - int i, j, k; - i = next_startcode(p_irabs); - - if (i != 0) { - if (i == -1) - io_printf( - "\narrive at stream end and start code is not found!"); - if (i == -2) - io_printf("\np->ibyte_position error!"); - - } - startcode_offset = - p_irabs->ibyte_position - - 3 + (bitstream_buf_used-1) - * SVA_STREAM_BUF_SIZE; - buf[0] = 0; - buf[1] = 0; - buf[2] = 1; - *startcodepos = 3; - i = read_n_bit(p_irabs, 8, &j); - buf[3] = (char)j; - - check_type(buf[3]); - if (buf[3] == SEQUENCE_END_CODE) { - *length = 4; - return -1; - } - k = 4; - while (1) { - i = read_n_bit(p_irabs, 8, &j); - if (i < 0) - break; - buf[k++] = (char)j; - if (k >= (MAX_CODED_FRAME_SIZE - 1)) - break; - } - if (p_irabs->iclear_bitsnum > 0) { - int shift; - shift = 8 - p_irabs->iclear_bitsnum; - i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j); - - if (j != 0) - buf[k++] = (char)(j << shift); - stat_bits_ptr->last_unit_bits += shift; - } - *length = k; - return k; -} - -/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/ -/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/ -int header(void) -{ - unsigned char *buf; - int startcodepos, length; - - unsigned char *tmp_buf; - tmp_buf = (unsigned char *)avsp_heap_adr; - - buf = &tmp_buf[0]; - while (1) { - start_codeposition = get_oneunit(buf, &startcodepos, &length); - - switch (buf[startcodepos]) { - case SEQUENCE_HEADER_CODE: - io_printf( - "# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case EXTENSION_START_CODE: - io_printf( - "# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case USER_DATA_START_CODE: - io_printf( - "# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case VIDEO_EDIT_CODE: - io_printf( - "# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case I_PICTURE_START_CODE: - io_printf( - "# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case PB_PICTURE_START_CODE: - io_printf( - "# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - case SEQUENCE_END_CODE: - io_printf( - "# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); - break; - default: - io_printf( - "# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n", - buf[startcodepos], startcode_offset, - startcode_offset); -#if 0 - io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_START_PTR)); - io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_CURR_PTR)); - io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_END_PTR)); - io_printf("VLD_MEM_VIFIFO_WP %x\r\n" - READ_VREG(VLD_MEM_VIFIFO_WP)); - io_printf("VLD_MEM_VIFIFO_RP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n" - READ_VREG(VLD_MEM_VBUF_RD_PTR)); - io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL)); - io_printf("PARSER_VIDEO_HOLE %x\r\n", - READ_MPEG_REG(PARSER_VIDEO_HOLE)); -#endif - if ((buf[startcodepos] >= SLICE_START_CODE_MIN - && buf[startcodepos] - <= SLICE_START_CODE_MAX) - && ((!img->seq_header_indicate) - || (img->type == B_IMG - && img->b_discard_flag - == 1 - && !img->no_forward_reference))) { - break; - } else if (buf[startcodepos] >= SLICE_START_CODE_MIN) { - - first_slice_length = length; - first_slice_startpos = startcodepos; - - temp_slice_buf = &tmp_buf[0]; - return SOP; - } else { - io_printf("Can't find start code"); - return -EOS; - } - } - } - -} - -/* - ************************************************************************* - * Function:Allocates a Bitstream - * Input: - * Output:allocated Bitstream point - * Return: - * Attention: - ************************************************************************* - */ -struct bitstream_s *alloc_bitstream(void) -{ - struct bitstream_s *bitstream; - - bitstream = (struct bitstream_s *)local_alloc(1, - sizeof(struct bitstream_s)); - if (bitstream == NULL) { - io_printf( - "AllocBitstream: Memory allocation for Bitstream failed"); - } - bitstream->stream_buffer = (unsigned char *)local_alloc( - MAX_CODED_FRAME_SIZE, - sizeof(unsigned char)); - if (bitstream->stream_buffer == NULL) { - io_printf( - "AllocBitstream: Memory allocation for streamBuffer failed"); - } - - return bitstream; -} - -void biari_init_context_logac(struct bi_context_type_s *ctx) -{ - ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1; - ctx->MPS = 0; - ctx->cycno = 0; -} - -#define BIARI_CTX_INIT1_LOG(jj, ctx)\ -{\ - for (j = 0; j < jj; j++)\ - biari_init_context_logac(&(ctx[j]));\ -} - -#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - biari_init_context_logac(&(ctx[i][j]));\ -} - -#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - for (k = 0; k < kk; k++)\ - biari_init_context_logac(&(ctx[i][j][k]));\ -} - -#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\ -{\ - for (i = 0; i < ii; i++)\ - for (j = 0; j < jj; j++)\ - for (k = 0; k < kk; k++)\ - for (l = 0; l < ll; l++)\ - biari_init_context_logac\ - (&(ctx[i][j][k][l]));\ -} - -void init_contexts(struct img_par *img) -{ - struct motion_info_contexts_s *mc = img->current_slice->mot_ctx; - struct texture_info_contexts *tc = img->current_slice->tex_ctx; - int i, j; - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & SLICE_INFO_DUMP) - io_printf(" ---- init_contexts ----\n"); -#endif - - BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts); - BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts); - BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts); - BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts); - - BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts); - BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts); - BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, - tc->fld_last_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts); - BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts); -#ifdef TEST_WEIGHTING_AEC - biari_init_context_logac(&mc->mb_weighting_pred); -#endif -} - -/*! - ************************************************************************ - * \brief - * Allocation of contexts models for the motion info - * used for arithmetic decoding - * - ************************************************************************ - */ -struct motion_info_contexts_s *create_contexts_motioninfo(void) -{ - struct motion_info_contexts_s *deco_ctx; - - deco_ctx = (struct motion_info_contexts_s *)local_alloc(1, - sizeof(struct motion_info_contexts_s)); - if (deco_ctx == NULL) - no_mem_exit("create_contexts_motioninfo: deco_ctx"); - - return deco_ctx; -} - -/*! - ************************************************************************ - * \brief - * Allocates of contexts models for the texture info - * used for arithmetic decoding - ************************************************************************ - */ -struct texture_info_contexts *create_contexts_textureinfo(void) -{ - struct texture_info_contexts *deco_ctx; - - deco_ctx = (struct texture_info_contexts *)local_alloc(1, - sizeof(struct texture_info_contexts)); - if (deco_ctx == NULL) - no_mem_exit("create_contexts_textureinfo: deco_ctx"); - - return deco_ctx; -} - -struct datapartition *alloc_partition(int n) -{ - struct datapartition *part_arr, *datapart; - int i; - - part_arr = - (struct datapartition *)local_alloc(n, sizeof(struct datapartition)); - if (part_arr == NULL) { - no_mem_exit( - "alloc_partition: Memory allocation for Data Partition failed"); - } - -#if LIWR_FIX - part_arr[0].bitstream = NULL; -#else - for (i = 0; i < n; i++) { - datapart = &(part_arr[i]); - datapart->bitstream = (struct bitstream_s *)local_alloc(1, - sizeof(struct bitstream_s)); - if (datapart->bitstream == NULL) { - no_mem_exit( - "alloc_partition: Memory allocation for Bitstream failed"); - } - } -#endif - return part_arr; -} - -void malloc_slice(struct img_par *img) -{ - struct slice_s *currslice; - - img->current_slice = - (struct slice_s *)local_alloc(1, sizeof(struct slice_s)); - currslice = img->current_slice; - if (currslice == NULL) - no_mem_exit( - "Memory allocation for struct slice_s datastruct Failed" - ); - if (1) { - - currslice->mot_ctx = create_contexts_motioninfo(); - currslice->tex_ctx = create_contexts_textureinfo(); - } -#if LIWR_FIX - currslice->max_part_nr = 1; -#else - currslice->max_part_nr = 3; -#endif - currslice->part_arr = alloc_partition(currslice->max_part_nr); -} - -void init(struct img_par *img) -{ - int i; - - for (i = 0; i < 256; i++) - img->quad[i] = i * i; -} - -/* - ************************************************************************* - * Function:Allocate 2D memory array -> int array2D[rows][columns] - * Input: - * Output: memory size in bytes - * Return: - * Attention: - ************************************************************************* - */ - -int get_mem2Dint(int ***array2D, int rows, int columns) -{ - int i; - - *array2D = (int **)local_alloc(rows, sizeof(int *)); - if (*array2D == NULL) - no_mem_exit("get_mem2Dint: array2D"); - (*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int)); - if ((*array2D)[0] == NULL) - no_mem_exit("get_mem2Dint: array2D"); - - for (i = 1; i < rows; i++) - (*array2D)[i] = (*array2D)[i - 1] + columns; - - return rows * columns * sizeof(int); -} - -void initial_decode(void) -{ - int i, j; - int img_height = (vertical_size + img->auto_crop_bottom); - int memory_size = 0; - - malloc_slice(img); - mb_data = (struct macroblock *)local_alloc( - (img->width / MB_BLOCK_SIZE) - * (img_height /*vertical_size*/ - / MB_BLOCK_SIZE), sizeof(struct macroblock)); - if (mb_data == NULL) - no_mem_exit("init_global_buffers: mb_data"); - - if (progressive_sequence) - memory_size += get_mem2Dint(&(img->ipredmode), - img->width / B8_SIZE * 2 + 4, - vertical_size / B8_SIZE * 2 + 4); - else - memory_size += get_mem2Dint(&(img->ipredmode), - img->width / B8_SIZE * 2 + 4, - (vertical_size + 32) / (2 * B8_SIZE) * 4 + 4); - - for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) { - for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++) - img->ipredmode[i][j] = -1; - } - - init(img); - img->number = 0; - img->type = I_IMG; - img->imgtr_last_p = 0; - img->imgtr_next_p = 0; - - img->new_seq_header_flag = 1; - img->new_sequence_flag = 1; - -} - -void aec_new_slice(void) -{ - last_dquant = 0; -} - -/*! - ************************************************************************ - * \brief - * Initializes the DecodingEnvironment for the arithmetic coder - ************************************************************************ - */ - -void arideco_start_decoding(struct decoding_environment_s *dep, - unsigned char *cpixcode, - int firstbyte, int *cpixcode_len, int slice_type) -{ - - dcodestrm = cpixcode; - dcodestrm_len = cpixcode_len; - *dcodestrm_len = firstbyte; - - s1 = 0; - t1 = QUARTER - 1; - value_s = 0; - - value_t = 0; - - { - int i; - dbits_to_go = 0; - for (i = 0; i < B_BITS - 1; i++) { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) - | ((dbuffer >> dbits_to_go) & 0x01); - } - } - - while (value_t < QUARTER) { - if (--dbits_to_go < 0) - get_byte(); - - value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01); - value_s++; - } - value_t = value_t & 0xff; - - dec_final = dec_bypass = 0; - - - -} - -/* - ************************************************************************* - * Function:Checks the availability of neighboring macroblocks of - the current macroblock for prediction and context determination; - marks the unavailable MBs for intra prediction in the - ipredmode-array by -1. Only neighboring MBs in the causal - past of the current MB are checked. - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void checkavailabilityofneighbors(struct img_par *img) -{ - int i, j; - const int mb_width = img->width / MB_BLOCK_SIZE; - const int mb_nr = img->current_mb_nr; - struct macroblock *curr_mb = &mb_data[mb_nr]; - int check_value; - int remove_prediction; - - curr_mb->mb_available_up = NULL; - curr_mb->mb_available_left = NULL; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - mb_data[mb_nr].mb_available[i][j] = NULL; - - mb_data[mb_nr].mb_available[1][1] = curr_mb; - - if (img->pix_x >= MB_BLOCK_SIZE) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - 1].slice_nr; - - if (remove_prediction) - - { - - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 1) * 2] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 1) * 2 + 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 2) * 2] = -1; - img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y - + 2) * 2 + 1] = -1; - } - if (!remove_prediction) - curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]); - - } - - check_value = (img->pix_y >= MB_BLOCK_SIZE); - if (check_value) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width].slice_nr; - - if (remove_prediction) { - img->ipredmode - [(img->block_x + 1) * 2][(img->block_y + 1) - * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y - + 1) * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y - + 1) * 2 - 1] = -1; - img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y - + 1) * 2 - 1] = -1; - } - - if (!remove_prediction) { - curr_mb->mb_available[0][1] = - &(mb_data[mb_nr - mb_width]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) { - remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width - 1].slice_nr; - - if (remove_prediction) { - img->ipredmode[img->block_x * 2 + 1][img->block_y * 2 - + 1] = -1; - } - if (!remove_prediction) { - curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width - - 1]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE - && img->pix_x < (img->width - MB_BLOCK_SIZE)) { - if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr) - curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width - + 1]); - } - - if (1) { - curr_mb->mbaddr_a = mb_nr - 1; - curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs; - curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1; - curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1; - - curr_mb->mbavail_a = - (curr_mb->mb_available[1][0] != NULL) ? 1 : 0; - curr_mb->mbavail_b = - (curr_mb->mb_available[0][1] != NULL) ? 1 : 0; - curr_mb->mbavail_c = - (curr_mb->mb_available[0][2] != NULL) ? 1 : 0; - curr_mb->mbavail_d = - (curr_mb->mb_available[0][0] != NULL) ? 1 : 0; - - } - -} - -void checkavailabilityofneighborsaec(void) -{ - - int i, j; - const int mb_width = img->width / MB_BLOCK_SIZE; - const int mb_nr = img->current_mb_nr; - struct macroblock *curr_mb = &(mb_data[mb_nr]); - int check_value; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - mb_data[mb_nr].mb_available[i][j] = NULL; - mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]); - - if (img->pix_x >= MB_BLOCK_SIZE) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - 1].slice_nr; - if (!remove_prediction) - curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]); - } - - check_value = (img->pix_y >= MB_BLOCK_SIZE); - if (check_value) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width].slice_nr; - - if (!remove_prediction) { - curr_mb->mb_available[0][1] = - &(mb_data[mb_nr - mb_width]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) { - int remove_prediction = curr_mb->slice_nr - != mb_data[mb_nr - mb_width - 1].slice_nr; - if (!remove_prediction) { - curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width - - 1]); - } - } - - if (img->pix_y >= MB_BLOCK_SIZE - && img->pix_x < (img->width - MB_BLOCK_SIZE)) { - if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr) - curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width - + 1]); - } - curr_mb->mb_available_left = curr_mb->mb_available[1][0]; - curr_mb->mb_available_up = curr_mb->mb_available[0][1]; - curr_mb->mbaddr_a = mb_nr - 1; - curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs; - curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1; - curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1; - - curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0; - curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0; - curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0; - curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0; -} - -/* - ************************************************************************* - * Function:initializes the current macroblock - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void start_macroblock(struct img_par *img) -{ - int i, j, k, l; - struct macroblock *curr_mb; - -#ifdef AVSP_LONG_CABAC -#else - -#endif - - curr_mb = &mb_data[img->current_mb_nr]; - - /* Update coordinates of the current macroblock */ - img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE); - img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_NUM_DUMP) - io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n", - img->current_mb_nr, img->mb_x, img->mb_y, es_ptr); -#endif - - - total_mb_count = total_mb_count + 1; - - /* Define vertical positions */ - img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */ - img->block8_y = img->mb_y * BLOCK_SIZE / 2; - img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */ - if (chroma_format == 2) - img->pix_c_y = img->mb_y * - MB_BLOCK_SIZE; /* chroma macroblock position */ - else - img->pix_c_y = img->mb_y * - MB_BLOCK_SIZE / 2; /* chroma macroblock position */ - - /* Define horizontal positions */ - img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */ - img->block8_x = img->mb_x * BLOCK_SIZE / 2; - img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */ - img->pix_c_x = img->mb_x * - MB_BLOCK_SIZE / 2; /* chroma pixel position */ - - checkavailabilityofneighbors(img); - - /*<!*******EDIT START BY lzhang ******************/ - - if (1) - checkavailabilityofneighborsaec(); - /*<!*******EDIT end BY lzhang ******************/ - - curr_mb->qp = img->qp; - curr_mb->mb_type = 0; - curr_mb->delta_quant = 0; - curr_mb->cbp = 0; - curr_mb->cbp_blk = 0; - curr_mb->c_ipred_mode = DC_PRED_8; - curr_mb->c_ipred_mode_2 = DC_PRED_8; - - for (l = 0; l < 2; l++) - for (j = 0; j < BLOCK_MULTIPLE; j++) - for (i = 0; i < BLOCK_MULTIPLE; i++) - for (k = 0; k < 2; k++) - curr_mb->mvd[l][j][i][k] = 0; - - curr_mb->cbp_bits = 0; - - for (j = 0; j < MB_BLOCK_SIZE; j++) - for (i = 0; i < MB_BLOCK_SIZE; i++) - img->m7[i][j] = 0; - - for (j = 0; j < 2 * BLOCK_SIZE; j++) - for (i = 0; i < 2 * BLOCK_SIZE; i++) { - img->m8[0][i][j] = 0; - img->m8[1][i][j] = 0; - img->m8[2][i][j] = 0; - img->m8[3][i][j] = 0; - } - - curr_mb->lf_disable = 1; - - img->weighting_prediction = 0; -} - -/* - ************************************************************************* - * Function:init macroblock I and P frames - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void init_macroblock(struct img_par *img) -{ - int i, j; - - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - img->ipredmode[img->block_x * 2 + i + 2][img->block_y - * 2 + j + 2] = -1; - } - } - -} - -/* - ************************************************************************* - * Function:Interpret the mb mode for I-Frames - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void interpret_mb_mode_i(struct img_par *img) -{ - int i; - - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - int num = 4; - - curr_mb->mb_type = I8MB; - - - current_mb_intra = 1; - - for (i = 0; i < 4; i++) { - curr_mb->b8mode[i] = IBLOCK; - curr_mb->b8pdir[i] = -1; - } - - for (i = num; i < 4; i++) { - curr_mb->b8mode[i] = - curr_mb->mb_type_2 == P8x8 ? - 4 : curr_mb->mb_type_2; - curr_mb->b8pdir[i] = 0; - } -} - -const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1, - 1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3}, - {0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0, - 0, 0, 0, 0, 6, 0, 0}, - {0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8} - -}; - -const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0 - -}; - -const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4}; - -void read_ipred_block_modes(struct img_par *img, int b8) -{ - int bi, bj, dec; - struct syntaxelement curr_se; - struct macroblock *curr_mb; - int j2; - int mostprobableintrapredmode; - int upintrapredmode; - int uprightintrapredmode; - int leftintrapredmode; - int leftdownintrapredmode; - int intrachromapredmodeflag; - - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - - curr_mb = mb_data + img->current_mb_nr; - intrachromapredmodeflag = IS_INTRA(curr_mb); - - curr_se.type = SE_INTRAPREDMODE; -#if TRACE - strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE); -#endif - - if (b8 < 4) { - if (curr_mb->b8mode[b8] == IBLOCK) { - intrachromapredmodeflag = 1; - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = read_intrapredmode_aec; - dp->read_syntax_element(&curr_se, img, dp); - - if (curr_se.value1 == -1) - push_es(1, 1); - else - push_es(curr_se.value1, 3); - - - } - bi = img->block_x + (b8 & 1); - bj = img->block_y + (b8 / 2); - - upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2 - + 1]; - uprightintrapredmode = - img->ipredmode[(bi + 1) * 2 + 1][(bj) - * 2 + 1]; - leftintrapredmode = - img->ipredmode[(bi) * 2 + 1][(bj + 1) - * 2]; - leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj - + 1) * 2 + 1]; - - if ((upintrapredmode < 0) || (leftintrapredmode < 0)) { - mostprobableintrapredmode = DC_PRED; - } else if ((upintrapredmode < NO_INTRA_PMODE) - && (leftintrapredmode < - NO_INTRA_PMODE)) { - mostprobableintrapredmode = - upintrapredmode - < leftintrapredmode ? - upintrapredmode : - leftintrapredmode; - } else if (upintrapredmode < NO_INTRA_PMODE) { - mostprobableintrapredmode = upintrapredmode; - } else if (leftintrapredmode < NO_INTRA_PMODE) { - mostprobableintrapredmode = leftintrapredmode; - } else { - mostprobableintrapredmode = - pred_4x4[leftintrapredmode - - INTRA_PMODE_4x4][upintrapredmode - - INTRA_PMODE_4x4]; - mostprobableintrapredmode = - pred_4x4to8x8[mostprobableintrapredmode]; - } - - - - dec = - (curr_se.value1 == -1) ? - mostprobableintrapredmode : - curr_se.value1 - + (curr_se.value1 - >= mostprobableintrapredmode); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" - ipredmode[%d] : %d\n", b8, dec); -#endif - - img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec; - img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec; - img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec; - img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] = - dec; - - j2 = bj; - } - } else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) { - - curr_se.type = SE_INTRAPREDMODE; -#if TRACE - strncpy(curr_se.tracestring, - "Chroma intra pred mode", TRACESTRING_SIZE); -#endif - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = read_cipredmode_aec; - dp->read_syntax_element(&curr_se, img, dp); - } else - - { - } - curr_mb->c_ipred_mode = curr_se.value1; - - push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]); - -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" * UE c_ipred_mode read : %d\n", - curr_mb->c_ipred_mode); -#endif - - if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) { -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf("%d\n", img->current_mb_nr); -#endif - pr_info("illegal chroma intra pred mode!\n"); - } - } -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the coded - * block pattern of a given MB. - ************************************************************************ - */ -void readcp_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct texture_info_contexts *ctx = img->current_slice->tex_ctx; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - - int mb_x, mb_y; - int a, b; - int curr_cbp_ctx, curr_cbp_idx; - int cbp = 0; - int cbp_bit; - int mask; - - for (mb_y = 0; mb_y < 4; mb_y += 2) { - for (mb_x = 0; mb_x < 4; mb_x += 2) { - if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK) - curr_cbp_idx = 0; - else - curr_cbp_idx = 1; - - if (mb_y == 0) { - if (curr_mb->mb_available_up == NULL) - b = 0; - else { - b = ((((curr_mb->mb_available_up)->cbp - & (1 << (2 + mb_x / 2))) - == 0) ? 1 : 0); - } - - } else - b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0); - - if (mb_x == 0) { - if (curr_mb->mb_available_left == NULL) - a = 0; - else { - a = - ((((curr_mb->mb_available_left)->cbp - & (1 - << (2 - * (mb_y - / 2) - + 1))) - == 0) ? - 1 : 0); - } - } else - a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0); - curr_cbp_ctx = a + 2 * b; - mask = (1 << (mb_y + mb_x / 2)); - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[0] + curr_cbp_ctx); - - if (cbp_bit) - cbp += mask; - } - } - curr_cbp_ctx = 0; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - - if (cbp_bit) { - curr_cbp_ctx = 1; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - if (cbp_bit) { - cbp += 48; - - } else { - curr_cbp_ctx = 1; - cbp_bit = biari_decode_symbol(dep_dp, - ctx->cbp_contexts[1] + curr_cbp_ctx); - cbp += (cbp_bit == 1) ? 32 : 16; - - } - } - - se->value1 = cbp; - if (!cbp) - last_dquant = 0; - - - -} - -/*! - ************************************************************************ - * \brief - * This function is used to arithmetically decode the delta qp - * of a given MB. - ************************************************************************ - */ -void readdquant_aec(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx; - - int act_ctx; - int act_sym; - int dquant; - - - act_ctx = ((last_dquant != 0) ? 1 : 0); - - act_sym = 1 - - biari_decode_symbol(dep_dp, - ctx->delta_qp_contexts + act_ctx); - if (act_sym != 0) { - act_ctx = 2; - act_sym = unary_bin_decode(dep_dp, - ctx->delta_qp_contexts + act_ctx, 1); - act_sym++; - } - act_sym &= 0x3f; - push_es(UE[act_sym][0], UE[act_sym][1]); - - dquant = (act_sym + 1) / 2; - if ((act_sym & 0x01) == 0) - dquant = -dquant; - se->value1 = dquant; - - last_dquant = dquant; - -} - -int csyntax; - -#define CHECKDELTAQP {\ - if (img->qp+curr_mb->delta_quant > 63\ - || img->qp+curr_mb->delta_quant < 0) {\ - csyntax = 0;\ - transcoding_error_flag = 1;\ - io_printf("error(0) (%3d|%3d) @ MB%d\n",\ - curr_mb->delta_quant,\ - img->qp+curr_mb->delta_quant,\ - img->picture_structure == 0 \ - ? img->current_mb_nr_fld : img->current_mb_nr);\ - } } - -int dct_level[65]; -int dct_run[65]; -int pair_pos; -int dct_pairs = -1; -const int t_chr[5] = {0, 1, 2, 4, 3000}; - -void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img, - struct decoding_environment_s *dep_dp) -{ - int pairs, rank, pos; - int run, level, abslevel, symbol; - int sign; - - if (dct_pairs < 0) { - struct bi_context_type_s (*primary)[NUM_MAP_CTX]; - struct bi_context_type_s *pctx; - struct bi_context_type_s *pCTX2; - int ctx, ctx2, offset; - if (se->context == LUMA_8x8) { - if (img->picture_structure == 0) { - primary = - img->current_slice->tex_ctx->fld_map_contexts; - } else { - primary = - img->current_slice->tex_ctx->map_contexts; - } - } else { - if (img->picture_structure == 0) { - primary = - img->current_slice->tex_ctx->fld_last_contexts; - } else { - primary = - img->current_slice->tex_ctx->last_contexts; - } - } - - rank = 0; - pos = 0; - for (pairs = 0; pairs < 65; pairs++) { -#ifdef DECODING_SANITY_CHECK - /*max index is NUM_BLOCK_TYPES - 1*/ - pctx = primary[rank & 0x7]; -#else - pctx = primary[rank]; -#endif - if (rank > 0) { -#ifdef DECODING_SANITY_CHECK - /*max index is NUM_BLOCK_TYPES - 1*/ - pCTX2 = primary[(5 + (pos >> 5)) & 0x7]; -#else - pCTX2 = primary[5 + (pos >> 5)]; -#endif - ctx2 = (pos >> 1) & 0x0f; - ctx = 0; - - - if (biari_decode_symbolw(dep_dp, pctx + ctx, - pCTX2 + ctx2)) { - break; - } - } - - ctx = 1; - symbol = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) { - symbol += 1; - ctx++; - if (ctx >= 2) - ctx = 2; - } - abslevel = symbol + 1; - - if (biari_decode_symbol_eq_prob(dep_dp)) { - level = -abslevel; - sign = 1; - } else { - level = abslevel; - sign = 0; - } -#if TRACE - tracebits2("level", 1, level); -#endif - - if (abslevel == 1) - offset = 4; - else - offset = 6; - symbol = 0; - ctx = 0; - while (biari_decode_symbol(dep_dp, pctx + ctx + offset) - == 0) { - symbol += 1; - ctx++; - if (ctx >= 1) - ctx = 1; - } - run = symbol; - -#if TRACE - tracebits2("run", 1, run); -#endif - dct_level[pairs] = level; - dct_run[pairs] = run; - if (abslevel > t_chr[rank]) { - if (abslevel <= 2) - rank = abslevel; - else if (abslevel <= 4) - rank = 3; - else - rank = 4; - } - pos += (run + 1); - if (pos >= 64) - pos = 63; - } - dct_pairs = pairs; - pair_pos = dct_pairs; - } - - if (dct_pairs > 0) { - se->value1 = dct_level[pair_pos - 1]; - se->value2 = dct_run[pair_pos - 1]; - pair_pos--; - } else { - - se->value1 = se->value2 = 0; - } - - if ((dct_pairs--) == 0) - pair_pos = 0; -} - -int b8_ctr; -#if 0 -int curr_residual_chroma[4][16][16]; -int curr_residual_luma[16][16]; -#endif - -const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1, - 1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1, - 4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4, - 0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3, - 4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6, - 0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4, - 6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6, - 6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, - 6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, { - 3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, { - 4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, { - 1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, { - 5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, { - 3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, { - 4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, { - 7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, { - 6, 7}, {7, 7} } }; - -const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3, - 0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2, - 3}, {3, 3} }; - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void encode_golomb_word(unsigned int symbol, unsigned int grad0, - unsigned int max_levels, unsigned int *res_bits, - unsigned int *res_len) -{ - unsigned int level, res, numbits; - - res = 1UL << grad0; - level = 1UL; - numbits = 1UL + grad0; - - while (symbol >= res && level < max_levels) { - symbol -= res; - res = res << 1; - level++; - numbits += 2UL; - } - - if (level >= max_levels) { - if (symbol >= res) - symbol = res - 1UL; - } - - *res_bits = res | symbol; - *res_len = numbits; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void encode_multilayer_golomb_word(unsigned int symbol, - const unsigned int *grad, const unsigned int *max_levels, - unsigned int *res_bits, unsigned int *res_len) -{ - unsigned accbits, acclen, bits, len, tmp; - - accbits = acclen = 0UL; - - while (1) { - encode_golomb_word(symbol, *grad, *max_levels, &bits, &len); - accbits = (accbits << len) | bits; - acclen += len; -#ifdef AVSP_LONG_CABAC -#else - assert(acclen <= 32UL); -#endif - tmp = *max_levels - 1UL; - - if (!((len == (tmp << 1) + (*grad)) - && (bits == (1UL << (tmp + *grad)) - 1UL))) - break; - - tmp = *max_levels; - symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL; - grad++; - max_levels++; - } - *res_bits = accbits; - *res_len = acclen; -} - -/* - ************************************************************************* - * Function: - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream) -{ - unsigned int bits, len, i; - unsigned int grad[4], max_lev[4]; - - if (!(se->golomb_maxlevels & ~0xFF)) - encode_golomb_word(se->value1, se->golomb_grad, - se->golomb_maxlevels, &bits, &len); - else { - for (i = 0UL; i < 4UL; i++) { - grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL; - max_lev[i] = (se->golomb_maxlevels >> (i << 3)) - & 0xFFUL; - } - encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits, - &len); - } - - se->len = len; - se->bitpattern = bits; - - if (write_to_stream) - push_es(bits, len); - return se->len; -} - -/* - ************************************************************************* - * Function:Get coded block pattern and coefficients (run/level) - from the bitstream - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -void read_cbpandcoeffsfrom_nal(struct img_par *img) -{ - - int tablenum; - int inumblk; - int inumcoeff; - int symbol2D; - int escape_level_diff; - const int (*AVS_2DVLC_table_intra)[26][27]; - const int (*AVS_2DVLC_table_chroma)[26][27]; - int write_to_stream; - struct syntaxelement currse_enc; - struct syntaxelement *e_currse = &currse_enc; - - int coeff_save[65][2]; - int coeff_ptr; - - int ii, jj; - int mb_nr = img->current_mb_nr; - - int m2, jg2; - struct macroblock *curr_mb = &mb_data[mb_nr]; - - int block8x8; - - int block_x, block_y; - - struct slice_s *currslice = img->current_slice; - int level, run, coef_ctr, len, k, i0, j0, uv, qp; - - int boff_x, boff_y, start_scan; - struct syntaxelement curr_se; - struct datapartition *dp; - - AVS_2DVLC_table_intra = AVS_2DVLC_INTRA; - AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA; - write_to_stream = 1; - - dct_pairs = -1; - - curr_mb->qp = img->qp; - qp = curr_mb->qp; - - - for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */ - for (block_x = 0; block_x < 4; block_x += 2) { - block8x8 = 2 * (block_y / 2) + block_x / 2; - if (curr_mb->cbp & (1 << block8x8)) { - tablenum = 0; - inumblk = 1; - inumcoeff = 65; - coeff_save[0][0] = 0; - coeff_save[0][1] = 0; - coeff_ptr = 1; - - b8_ctr = block8x8; - - boff_x = (block8x8 % 2) << 3; - boff_y = (block8x8 / 2) << 3; - - img->subblock_x = boff_x >> 2; - img->subblock_y = boff_y >> 2; - - start_scan = 0; - coef_ctr = start_scan - 1; - level = 1; - img->is_v_block = 0; - img->is_intra_block = IS_INTRA(curr_mb); - for (k = start_scan; - (k < 65) && (level != 0); - k++) { - - curr_se.context = LUMA_8x8; - curr_se.type = - (IS_INTRA(curr_mb)) ? - SE_LUM_AC_INTRA : - SE_LUM_AC_INTER; - - dp = &(currslice->part_arr[0]); - curr_se.reading = - readrunlevel_aec_ref; - dp-> - read_syntax_element(&curr_se, - img, dp); - level = curr_se.value1; - run = curr_se.value2; - len = curr_se.len; - - if (level != 0) { - coeff_save[coeff_ptr][0] = - run; - coeff_save[coeff_ptr][1] = - level; - coeff_ptr++; - } - - - - if (level != 0) {/* leave if len = 1 */ - coef_ctr += run + 1; - if ((img->picture_structure - == FRAME)) { - ii = - SCAN[img->picture_structure] - [coef_ctr][0]; - jj = - SCAN[img->picture_structure] - [coef_ctr][1]; - } else { - ii = - SCAN[img->picture_structure] - [coef_ctr][0]; - jj = - SCAN[img->picture_structure] - [coef_ctr][1]; - } - - } - } - - while (coeff_ptr > 0) { - run = - coeff_save[coeff_ptr - - 1][0]; - level = - coeff_save[coeff_ptr - - 1][1]; - - coeff_ptr--; - - symbol2D = CODE2D_ESCAPE_SYMBOL; - if (level > -27 && level < 27 - && run < 26) { - if (tablenum == 0) - - symbol2D = - AVS_2DVLC_table_intra - [tablenum] - [run][abs( - level) - - 1]; - else - - symbol2D = - AVS_2DVLC_table_intra - [tablenum] - [run][abs( - level)]; - if (symbol2D >= 0 - && level - < 0) - symbol2D++; - if (symbol2D < 0) - - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - else { - - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - - - e_currse->type = SE_LUM_AC_INTER; - e_currse->value1 = symbol2D; - e_currse->value2 = 0; - - e_currse->golomb_grad = - vlc_golomb_order - [0][tablenum][0]; - e_currse->golomb_maxlevels = - vlc_golomb_order - [0][tablenum][1]; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - if (symbol2D - >= CODE2D_ESCAPE_SYMBOL) { - - e_currse->type = - SE_LUM_AC_INTER; - e_currse->golomb_grad = - 1; - e_currse->golomb_maxlevels = - 11; - escape_level_diff = - abs( - level) - - ((run - > MaxRun[0][tablenum]) ? - 1 : - refabslevel[tablenum][run]); - e_currse->value1 = - escape_level_diff; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - } - - if (abs(level) - > incvlc_intra[tablenum]) { - if (abs(level) <= 2) - tablenum = - abs( - level); - else if (abs(level) <= 4) - tablenum = 3; - else if (abs(level) <= 7) - tablenum = 4; - else if (abs(level) - <= 10) - tablenum = 5; - else - tablenum = 6; - } - } - - - } - } - } - - - - m2 = img->mb_x * 2; - jg2 = img->mb_y * 2; - - - uv = -1; - block_y = 4; -#if 0 - qp = QP_SCALE_CR[curr_mb->qp]; -#endif - for (block_x = 0; block_x < 4; block_x += 2) { - - uv++; - - - b8_ctr = (uv + 4); - if ((curr_mb->cbp >> (uv + 4)) & 0x1) { - - tablenum = 0; - inumblk = 1; - inumcoeff = 65; - coeff_save[0][0] = 0; - coeff_save[0][1] = 0; - coeff_ptr = 1; - - coef_ctr = -1; - level = 1; - img->subblock_x = 0; - img->subblock_y = 0; - curr_se.context = CHROMA_AC; - curr_se.type = (IS_INTRA(curr_mb) ? - SE_CHR_AC_INTRA : - SE_CHR_AC_INTER); - dp = &(currslice->part_arr[0]); - curr_se.reading = readrunlevel_aec_ref; - img->is_v_block = uv; - img->is_intra_block = IS_INTRA(curr_mb); - for (k = 0; (k < 65) && (level != 0); k++) { - - dp->read_syntax_element - (&curr_se, img, dp); - level = curr_se.value1; - run = curr_se.value2; - len = curr_se.len; - - if (level != 0) { - coeff_save[coeff_ptr][0] = run; - coeff_save[coeff_ptr][1] = - level; - coeff_ptr++; - } - - - if (level != 0) { - coef_ctr = coef_ctr + run + 1; - if ((img->picture_structure - == FRAME) - /*&& (!curr_mb->mb_field)*/) { - i0 = - SCAN[img->picture_structure] - [coef_ctr][0]; - j0 = - SCAN[img->picture_structure] - [coef_ctr][1]; - } else { - i0 = - SCAN[img->picture_structure] - [coef_ctr][0]; - j0 = - SCAN[img->picture_structure] - [coef_ctr][1]; - } - - } - } - - while (coeff_ptr > 0) { - - run = coeff_save[coeff_ptr - 1][0]; - level = coeff_save[coeff_ptr - 1][1]; - - coeff_ptr--; - - symbol2D = CODE2D_ESCAPE_SYMBOL; - if (level > -27 && level < 27 - && run < 26) { - if (tablenum == 0) - - symbol2D = - AVS_2DVLC_table_chroma - [tablenum][run][abs( - level) - - 1]; - else - symbol2D = - AVS_2DVLC_table_chroma - [tablenum][run][abs( - level)]; - if (symbol2D >= 0 - && level < 0) - symbol2D++; - if (symbol2D < 0) - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - else { - symbol2D = - (CODE2D_ESCAPE_SYMBOL - + (run - << 1) - + ((level - > 0) ? - 1 : - 0)); - } - - e_currse->type = SE_LUM_AC_INTER; - e_currse->value1 = symbol2D; - e_currse->value2 = 0; - e_currse->golomb_grad = - vlc_golomb_order[2] - [tablenum][0]; - e_currse->golomb_maxlevels = - vlc_golomb_order[2] - [tablenum][1]; - - writesyntaxelement_golomb(e_currse, - write_to_stream); - - /* - if (write_to_stream) - { - bitCount[BITS_COEFF_UV_MB]+=e_currse->len; - e_currse++; - curr_mb->currSEnr++; - } - no_bits+=e_currse->len; - - - if (icoef == 0) break; - */ - - if (symbol2D >= CODE2D_ESCAPE_SYMBOL) { - - e_currse->type = SE_LUM_AC_INTER; - e_currse->golomb_grad = 0; - e_currse->golomb_maxlevels = 11; - escape_level_diff = - abs(level) - - ((run - > MaxRun[2][tablenum]) ? - 1 : - refabslevel[tablenum - + 14][run]); - e_currse->value1 = - escape_level_diff; - - writesyntaxelement_golomb( - e_currse, - write_to_stream); - - } - - if (abs(level) - > incvlc_chroma[tablenum]) { - if (abs(level) <= 2) - tablenum = abs(level); - else if (abs(level) <= 4) - tablenum = 3; - else - tablenum = 4; - } - } - - } - } -} - -/* - ************************************************************************* - * Function:Get the syntax elements from the NAL - * Input: - * Output: - * Return: - * Attention: - ************************************************************************* - */ - -int read_one_macroblock(struct img_par *img) -{ - int i, j; - - struct syntaxelement curr_se; - struct macroblock *curr_mb = &mb_data[img->current_mb_nr]; - - int cabp_flag; - - int tempcbp; - int fixqp; - - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - - fixqp = (fixed_picture_qp || fixed_slice_qp); - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) { - img->m8[0][i][j] = 0; - img->m8[1][i][j] = 0; - img->m8[2][i][j] = 0; - img->m8[3][i][j] = 0; - } - - current_mb_skip = 0; - - curr_mb->qp = img->qp; - curr_se.type = SE_MBTYPE; - curr_se.mapping = linfo_ue; - - curr_mb->mb_type_2 = 0; - - if (img->type == I_IMG) - curr_mb->mb_type = 0; - - interpret_mb_mode_i(img); - - init_macroblock(img); - - if ((IS_INTRA(curr_mb)) && (img->abt_flag)) { - -#if TRACE - strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE); -#endif - - curr_se.len = 1; - curr_se.type = SE_CABP; - read_syntaxelement_flc(&curr_se); - cabp_flag = curr_se.value1; - if (cabp_flag == 0) { - curr_mb->CABP[0] = 0; - curr_mb->CABP[1] = 0; - curr_mb->CABP[2] = 0; - curr_mb->CABP[3] = 0; - } else { - for (i = 0; i < 4; i++) { - curr_se.len = 1; - curr_se.type = SE_CABP; - read_syntaxelement_flc(&curr_se); - curr_mb->CABP[i] = curr_se.value1; - } - } - - } else { - curr_mb->CABP[0] = 0; - curr_mb->CABP[1] = 0; - curr_mb->CABP[2] = 0; - curr_mb->CABP[3] = 0; - - } - - if (IS_INTRA(curr_mb)) { - for (i = 0; i < /*5*/(chroma_format + 4); i++) - - read_ipred_block_modes(img, i); - } - - curr_se.type = SE_CBP_INTRA; - curr_se.mapping = linfo_cbp_intra; - -#if TRACE - snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP"); -#endif - - if (img->type == I_IMG || IS_INTER(curr_mb)) { - curr_se.golomb_maxlevels = 0; - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = readcp_aec; - dp->read_syntax_element(&curr_se, img, dp); - } - - - curr_mb->cbp = curr_se.value1; - push_es(UE[NCBP[curr_se.value1][0]][0], - UE[NCBP[curr_se.value1][0]][1]); - - } - -# if 1 - if (curr_mb->cbp != 0) - tempcbp = 1; - else - tempcbp = 0; -#else - - if (chroma_format == 2) { -#if TRACE - snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422"); -#endif - curr_se.mapping = /*linfo_se*/linfo_ue; - curr_se.type = SE_CBP_INTRA; - readsyntaxelement_uvlc(&curr_se, inp); - curr_mb->cbp01 = curr_se.value1; - io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01); - } - - if (chroma_format == 2) { - if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0) - tempcbp = 1; - else - tempcbp = 0; - - } else { - if (curr_mb->cbp != 0) - tempcbp = 1; - else - tempcbp = 0; - } - -#endif - - if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) { - curr_mb->CABT[0] = curr_mb->CABP[0]; - curr_mb->CABT[1] = curr_mb->CABP[1]; - curr_mb->CABT[2] = curr_mb->CABP[2]; - curr_mb->CABT[3] = curr_mb->CABP[3]; - } else { - - curr_mb->CABT[0] = 0; - curr_mb->CABT[1] = 0; - curr_mb->CABT[2] = 0; - curr_mb->CABT[3] = 0; - - if (!fixqp && (tempcbp)) { - if (IS_INTER(curr_mb)) - curr_se.type = SE_DELTA_QUANT_INTER; - else - curr_se.type = SE_DELTA_QUANT_INTRA; - -#if TRACE - snprintf(curr_se.tracestring, - TRACESTRING_SIZE, "Delta quant "); -#endif - - if (1) { - dp = &(currslice->part_arr[0]); - curr_se.reading = readdquant_aec; - dp->read_syntax_element(&curr_se, img, dp); - } - - curr_mb->delta_quant = curr_se.value1; -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) { - io_printf(" * SE delta_quant read : %d\n", - curr_mb->delta_quant); - } -#endif - CHECKDELTAQP - - img->qp = (img->qp - MIN_QP + curr_mb->delta_quant - + (MAX_QP - MIN_QP + 1)) - % (MAX_QP - MIN_QP + 1) + MIN_QP; - } - - if (fixqp) { - curr_mb->delta_quant = 0; - img->qp = (img->qp - MIN_QP + curr_mb->delta_quant - + (MAX_QP - MIN_QP + 1)) - % (MAX_QP - MIN_QP + 1) + MIN_QP; - - } -#ifdef DUMP_DEBUG - if (avs_get_debug_flag() & MB_INFO_DUMP) - io_printf(" - img->qp : %d\n", img->qp); -#endif - } - - read_cbpandcoeffsfrom_nal(img); - return DECODE_MB; -} - -/*! - ************************************************************************ - * \brief - * finding end of a slice in case this is not the end of a frame - * - * Unsure whether the "correction" below actually solves an off-by-one - * problem or whether it introduces one in some cases :-( Anyway, - * with this change the bit stream format works with AEC again. - * StW, 8.7.02 - ************************************************************************ - */ -int aec_startcode_follows(struct img_par *img, int eos_bit) -{ - struct slice_s *currslice = img->current_slice; - struct datapartition *dp; - unsigned int bit; - struct decoding_environment_s *dep_dp; - - dp = &(currslice->part_arr[0]); - dep_dp = &(dp->de_aec); - - if (eos_bit) - bit = biari_decode_final(dep_dp); - else - bit = 0; - - return bit == 1 ? 1 : 0; -} - -#ifdef AVSP_LONG_CABAC -int process_long_cabac(void) -#else -void main(void) -#endif -{ - int data32; - int current_header; - int i; - int tmp; - - int byte_startposition; - int aec_mb_stuffing_bit; - struct slice_s *currslice; -#ifdef PERFORMANCE_DEBUG - pr_info("enter %s\r\n", __func__); -#endif - transcoding_error_flag = 0; - es_buf = es_write_addr_virt; - - if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) - return -1; - - img = (struct img_par *)local_alloc(1, sizeof(struct img_par)); - if (img == NULL) - no_mem_exit("main: img"); - stat_bits_ptr = (struct stat_bits *)local_alloc(1, - sizeof(struct stat_bits)); - if (stat_bits_ptr == NULL) - no_mem_exit("main: stat_bits"); - - curr_stream = alloc_bitstream(); - - chroma_format = 1; - demulate_enable = 0; - img->seq_header_indicate = 1; - -#ifdef AVSP_LONG_CABAC - data32 = READ_VREG(LONG_CABAC_REQ); - progressive_sequence = (data32 >> 1) & 1; - fixed_picture_qp = (data32 >> 2) & 1; - img->picture_structure = (data32 >> 3) & 1; - img->type = (data32 >> 4) & 3; - skip_mode_flag = (data32 >> 6) & 1; - - src_start = READ_VREG(LONG_CABAC_SRC_ADDR); - des_start = READ_VREG(LONG_CABAC_DES_ADDR); - - data32 = READ_VREG(LONG_CABAC_PIC_SIZE); - horizontal_size = (data32 >> 0) & 0xffff; - vertical_size = (data32 >> 16) & 0xffff; - - vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR); - vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR); - -#else - progressive_sequence = 0; - fixed_picture_qp = 0; - img->picture_structure = 0; - img->type = I_IMG; - skip_mode_flag = 1; - horizontal_size = 1920; - vertical_size = 1080; - - src_start = 0; -#endif - - if (horizontal_size % 16 != 0) - img->auto_crop_right = 16 - (horizontal_size % 16); - else - img->auto_crop_right = 0; - - if (!progressive_sequence) { - if (vertical_size % 32 != 0) - img->auto_crop_bottom = 32 - (vertical_size % 32); - else - img->auto_crop_bottom = 0; - } else { - if (vertical_size % 16 != 0) - img->auto_crop_bottom = 16 - (vertical_size % 16); - else - img->auto_crop_bottom = 0; - } - - img->width = (horizontal_size + img->auto_crop_right); - if (img->picture_structure) - img->height = (vertical_size + img->auto_crop_bottom); - else - img->height = (vertical_size + img->auto_crop_bottom) / 2; - img->width_cr = (img->width >> 1); - - img->pic_width_inmbs = img->width / MB_BLOCK_SIZE; - img->pic_height_inmbs = img->height / MB_BLOCK_SIZE; - img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs; - - io_printf( - "[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n", - src_start, des_start, horizontal_size, vertical_size); -#if 0 - io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_START_PTR)); - io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_CURR_PTR)); - io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_END_PTR)); - io_printf("VLD_MEM_VIFIFO_WP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_WP)); - io_printf("VLD_MEM_VIFIFO_RP %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_RP)); - io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n", - READ_VREG(VLD_MEM_VBUF_RD_PTR)); - io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n", - READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL)); -#endif - io_printf( - "[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n", - progressive_sequence, fixed_picture_qp, skip_mode_flag); - io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n", - img->picture_structure, img->type); - - open_irabs(p_irabs); - - initial_decode(); - - init_es(); - - current_header = header(); - io_printf("[LONG CABAC] header Return : %d\n", current_header); - - tmp = slice_header(temp_slice_buf, first_slice_startpos, - first_slice_length); - - init_contexts(img); - aec_new_slice(); - byte_startposition = (curr_stream->frame_bitoffset) / 8; - - currslice = img->current_slice; - - if (1) { - for (i = 0; i < 1; i++) { - img->current_slice->part_arr[i].read_syntax_element = - read_syntaxelement_aec; - img->current_slice->part_arr[i].bitstream = curr_stream; - } - curr_stream = currslice->part_arr[0].bitstream; - } - if ((curr_stream->frame_bitoffset) % 8 != 0) - byte_startposition++; - - arideco_start_decoding(&img->current_slice->part_arr[0].de_aec, - curr_stream->stream_buffer, (byte_startposition), - &(curr_stream->read_len), img->type); - - img->current_mb_nr = 0; - total_mb_count = 0; - while (img->current_mb_nr < img->pic_size_inmbs) - - { - start_macroblock(img); - read_one_macroblock(img); - if (img->cod_counter <= 0) - aec_mb_stuffing_bit = aec_startcode_follows(img, 1); - img->current_mb_nr++; - } - - push_es(0xff, 8); - io_printf(" Total ES_LENGTH : %d\n", es_ptr); - -#ifdef AVSP_LONG_CABAC - push_es(0xff, 64); - - if (transcoding_error_flag == 0) { -#if 1 - dma_sync_single_for_device(amports_get_dma_device(), - es_write_addr_phy, - es_ptr, DMA_TO_DEVICE); - - wmb(); /**/ -#endif - WRITE_VREG(LONG_CABAC_REQ, 0); - } -#else - fclose(f_es); -#endif - - local_heap_uninit(); -#ifdef PERFORMANCE_DEBUG - pr_info("exit %s\r\n", __func__); -#endif - return (transcoding_error_flag == 0) ? 0 : -1; -} -#endif diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c deleted file mode 100644 index 1e88bed..0000000 --- a/drivers/frame_provider/decoder/h264/vh264.c +++ b/dev/null @@ -1,2963 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/h264/vh264.c - * - * Copyright (C) 2016 Amlogic, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * -*/ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/kfifo.h> -#include <linux/platform_device.h> - -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/vfm/vframe.h> -#include <linux/amlogic/media/vfm/vframe_provider.h> -#include <linux/amlogic/media/vfm/vframe_receiver.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/frame_sync/tsync.h> -#include <linux/workqueue.h> -#include <linux/dma-mapping.h> -#include <linux/atomic.h> -#include <linux/module.h> -#include <linux/slab.h> -#include "../../../stream_input/amports/amports_priv.h" -#include <linux/amlogic/media/canvas/canvas.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#include "../utils/vdec.h" -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../utils/amvdec.h" -#include "../utils/decoder_bmmu_box.h" -#include "vh264.h" -#include "../../../stream_input/parser/streambuf.h" -#include <linux/delay.h> -#include <linux/amlogic/media/video_sink/video.h> - -/*#include <linux/amlogic/ge2d/ge2d.h>*/ - -#define DRIVER_NAME "amvdec_h264" -#define MODULE_NAME "amvdec_h264" -#define MEM_NAME "codec_264" -#define HANDLE_H264_IRQ -/* #define DEBUG_PTS */ -#if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */ -#define DROP_B_FRAME_FOR_1080P_50_60FPS -#endif -#define RATE_MEASURE_NUM 8 -#define RATE_CORRECTION_THRESHOLD 5 -#define RATE_24_FPS 4004 /* 23.97 */ -#define RATE_25_FPS 3840 /* 25 */ -#define DUR2PTS(x) ((x)*90/96) -#define PTS2DUR(x) ((x)*96/90) -#define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96) -#define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2 -#define VDEC_CLOCK_ADJUST_FRAME 50 - -static inline bool close_to(int a, int b, int m) -{ - return (abs(a - b) < m) ? true : false; -} - -static DEFINE_MUTEX(vh264_mutex); -/* 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 0x1000000 -#define V_BUF_ADDR_OFFSET_NEW (0x1ee000) -#define V_BUF_ADDR_OFFSET (0x13e000) - -#define PIC_SINGLE_FRAME 0 -#define PIC_TOP_BOT_TOP 1 -#define PIC_BOT_TOP_BOT 2 -#define PIC_DOUBLE_FRAME 3 -#define PIC_TRIPLE_FRAME 4 -#define PIC_TOP_BOT 5 -#define PIC_BOT_TOP 6 -#define PIC_INVALID 7 - -#define EXTEND_SAR 0xff - -#define VF_POOL_SIZE 64 -#define VF_BUF_NUM 24 -#define PUT_INTERVAL (HZ/100) -#define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL) - -#define SWITCHING_STATE_OFF 0 -#define SWITCHING_STATE_ON_CMD3 1 -#define SWITCHING_STATE_ON_CMD1 2 -#define SWITCHING_STATE_ON_CMD1_PENDING 3 - - -#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001 -#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002 -#define DEC_CONTROL_FLAG_DISABLE_FAST_POC 0x0004 - -#define INCPTR(p) ptr_atomic_wrap_inc(&p) - -#define SLICE_TYPE_I 2 -#define SLICE_TYPE_P 5 -#define SLICE_TYPE_B 6 - -struct buffer_spec_s { - unsigned int y_addr; - unsigned int u_addr; - unsigned int v_addr; - - int y_canvas_index; - int u_canvas_index; - int v_canvas_index; - - unsigned int y_canvas_width; - unsigned int u_canvas_width; - unsigned int v_canvas_width; - - unsigned int y_canvas_height; - unsigned int u_canvas_height; - unsigned int v_canvas_height; - - unsigned long phy_addr; - int alloc_count; -}; - -#define spec2canvas(x) \ - (((x)->v_canvas_index << 16) | \ - ((x)->u_canvas_index << 8) | \ - ((x)->y_canvas_index << 0)) - -static struct vframe_s *vh264_vf_peek(void *); -static struct vframe_s *vh264_vf_get(void *); -static void vh264_vf_put(struct vframe_s *, void *); -static int vh264_vf_states(struct vframe_states *states, void *); -static int vh264_event_cb(int type, void *data, void *private_data); - -static void vh264_prot_init(void); -static void vh264_local_init(void); -static void vh264_put_timer_func(unsigned long arg); -static void stream_switching_done(void); - -static const char vh264_dec_id[] = "vh264-dev"; - -#define PROVIDER_NAME "decoder.h264" - -static const struct vframe_operations_s vh264_vf_provider_ops = { - .peek = vh264_vf_peek, - .get = vh264_vf_get, - .put = vh264_vf_put, - .event_cb = vh264_event_cb, - .vf_states = vh264_vf_states, -}; - -static struct vframe_provider_s vh264_vf_prov; -/*TODO irq*/ -#if 1 -static u32 frame_buffer_size; -static u32 frame_width, frame_height, frame_dur, frame_prog, frame_packing_type, - last_duration; -static u32 saved_resolution; -static u32 last_mb_width, last_mb_height; -#else -static u32 frame_buffer_size; -static u32 frame_width, frame_height, frame_dur, frame_prog, last_duration; -static u32 last_mb_width, last_mb_height; -static u32 frame_packing_type; -#endif -static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); -static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); -static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); -static DECLARE_KFIFO(delay_display_q, struct vframe_s *, VF_POOL_SIZE); - -static struct vframe_s vfpool[VF_POOL_SIZE]; -static s32 vfbuf_use[VF_BUF_NUM]; -static struct buffer_spec_s buffer_spec[VF_BUF_NUM]; -static struct buffer_spec_s fense_buffer_spec[2]; -#define MAX_BLK_BUFFERS (VF_BUF_NUM + 3) -#define FENSE_BUFFER_IDX(n) (VF_BUF_NUM + n) -static struct vframe_s fense_vf[2]; - -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start, buf_end; -static u32 buf_size; -static s32 buf_offset; -static u32 ucode_map_start; -static u32 pts_outside; -static u32 sync_outside; -static u32 dec_control; -static u32 vh264_ratio; -static u32 vh264_rotation; -static u32 use_idr_framerate; -static u32 high_bandwith; - -static u32 seq_info; -static u32 timing_info_present_flag; -static u32 fixed_frame_rate_flag; -static u32 fixed_frame_rate_check_count; -static u32 aspect_ratio_info; -static u32 num_units_in_tick; -static u32 time_scale; -static u32 h264_ar; -static u32 decoder_debug_flag; -static u32 dpb_size_adj = 6; - -#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS -static u32 last_interlaced; -#endif -static bool is_4k; -static unsigned char h264_first_pts_ready; -static bool h264_first_valid_pts_ready; -static u32 h264pts1, h264pts2; -static u32 h264_pts_count, duration_from_pts_done, duration_on_correcting; -static u32 vh264_error_count; -static u32 vh264_no_disp_count; -static u32 fatal_error_flag; -static u32 fatal_error_reset; -static u32 max_refer_buf = 1; -static u32 decoder_force_reset; -static unsigned int no_idr_error_count; -static unsigned int no_idr_error_max = 60; -static unsigned int enable_switch_fense = 1; -#define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k) -#if 0 -static u32 vh264_no_disp_wd_count; -#endif -static u32 vh264_running; -static s32 vh264_stream_switching_state; -static s32 vh264_eos; -static struct vframe_s *p_last_vf; -static s32 iponly_early_mode; -static void *mm_blk_handle; - -/*TODO irq*/ -#if 1 -static u32 last_pts, last_pts_remainder; -#else -static u32 last_pts; -#endif -static bool check_pts_discontinue; -static u32 wait_buffer_counter; -static u32 video_signal_from_vui; - -static uint error_recovery_mode; -static uint error_recovery_mode_in = 3; -static uint error_recovery_mode_use = 3; - -static uint mb_total = 0, mb_width = 0, mb_height; -static uint saved_idc_level; -#define UCODE_IP_ONLY 2 -#define UCODE_IP_ONLY_PARAM 1 -static uint ucode_type; - -#ifdef DEBUG_PTS -static unsigned long pts_missed, pts_hit; -#endif -static uint debugfirmware; - -static atomic_t vh264_active = ATOMIC_INIT(0); -static int vh264_reset; -static struct work_struct error_wd_work; -static struct work_struct stream_switching_work; -static struct work_struct set_parameter_work; - -static struct dec_sysinfo vh264_amstream_dec_info; -static dma_addr_t mc_dma_handle; -static void *mc_cpu_addr; -static u32 first_offset; -static u32 first_pts; -static u64 first_pts64; -static bool first_pts_cached; -static void *sei_data_buffer; -static dma_addr_t sei_data_buffer_phys; -static int clk_adj_frame_count; - -#define MC_OFFSET_HEADER 0x0000 -#define MC_OFFSET_DATA 0x1000 -#define MC_OFFSET_MMCO 0x2000 -#define MC_OFFSET_LIST 0x3000 -#define MC_OFFSET_SLICE 0x4000 - -#define MC_TOTAL_SIZE (20*SZ_1K) -#define MC_SWAP_SIZE (4*SZ_1K) - -#define MODE_ERROR 0 -#define MODE_FULL 1 - -static DEFINE_SPINLOCK(lock); -static DEFINE_SPINLOCK(prepare_lock); -static DEFINE_SPINLOCK(recycle_lock); - -static bool block_display_q; -static int vh264_stop(int mode); -static s32 vh264_init(void); - -#define DFS_HIGH_THEASHOLD 3 - -static bool pts_discontinue; -#if 0//DEBUG_TMP - -static struct ge2d_context_s *ge2d_videoh264_context; - -static int ge2d_videoh264task_init(void) -{ - if (ge2d_videoh264_context == NULL) - ge2d_videoh264_context = create_ge2d_work_queue(); - - if (ge2d_videoh264_context == NULL) { - pr_info("create_ge2d_work_queue video task failed\n"); - return -1; - } - return 0; -} - -static int ge2d_videoh264task_release(void) -{ - if (ge2d_videoh264_context) { - destroy_ge2d_work_queue(ge2d_videoh264_context); - ge2d_videoh264_context = NULL; - } - return 0; -} - -static int ge2d_canvas_dup(struct canvas_s *srcy, struct canvas_s *srcu, - struct canvas_s *des, int format, u32 srcindex, - u32 desindex) -{ - - struct config_para_ex_s ge2d_config; - /* pr_info("[%s]h264 ADDR srcy[0x%lx] srcu[0x%lx] des[0x%lx]\n", - * __func__, srcy->addr, srcu->addr, des->addr); - */ - memset(&ge2d_config, 0, sizeof(struct config_para_ex_s)); - - ge2d_config.alu_const_color = 0; - ge2d_config.bitmask_en = 0; - ge2d_config.src1_gb_alpha = 0; - - ge2d_config.src_planes[0].addr = srcy->addr; - ge2d_config.src_planes[0].w = srcy->width; - ge2d_config.src_planes[0].h = srcy->height; - - ge2d_config.src_planes[1].addr = srcu->addr; - ge2d_config.src_planes[1].w = srcu->width; - ge2d_config.src_planes[1].h = srcu->height; - - ge2d_config.dst_planes[0].addr = des->addr; - ge2d_config.dst_planes[0].w = des->width; - ge2d_config.dst_planes[0].h = des->height; - - ge2d_config.src_para.canvas_index = srcindex; - ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.src_para.format = format; - ge2d_config.src_para.fill_color_en = 0; - ge2d_config.src_para.fill_mode = 0; - ge2d_config.src_para.color = 0; - ge2d_config.src_para.top = 0; - ge2d_config.src_para.left = 0; - ge2d_config.src_para.width = srcy->width; - ge2d_config.src_para.height = srcy->height; - - ge2d_config.dst_para.canvas_index = desindex; - ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config.dst_para.format = format; - ge2d_config.dst_para.fill_color_en = 0; - ge2d_config.dst_para.fill_mode = 0; - ge2d_config.dst_para.color = 0; - ge2d_config.dst_para.top = 0; - ge2d_config.dst_para.left = 0; - ge2d_config.dst_para.width = srcy->width; - ge2d_config.dst_para.height = srcy->height; - - if (ge2d_context_config_ex(ge2d_videoh264_context, &ge2d_config) < 0) { - pr_info("ge2d_context_config_ex failed\n"); - return -1; - } - - stretchblt_noalpha(ge2d_videoh264_context, 0, 0, srcy->width, - srcy->height, 0, 0, srcy->width, srcy->height); - - return 0; -} -#endif - -static inline int fifo_level(void) -{ - return VF_POOL_SIZE - kfifo_len(&newframe_q); -} - - -void spec_set_canvas(struct buffer_spec_s *spec, - unsigned width, unsigned height) -{ - canvas_config(spec->y_canvas_index, - spec->y_addr, - width, height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - - canvas_config(spec->u_canvas_index, - spec->u_addr, - width, height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -} - -static void prepare_display_q(void) -{ - unsigned long flags; - int count; - - spin_lock_irqsave(&prepare_lock, flags); - - if (block_display_q) { - spin_unlock_irqrestore(&prepare_lock, flags); - return; - } - - spin_unlock_irqrestore(&prepare_lock, flags); - - count = (int)VF_POOL_SIZE - - kfifo_len(&delay_display_q) - - kfifo_len(&display_q) - - kfifo_len(&recycle_q) - - kfifo_len(&newframe_q); - - if ((vh264_stream_switching_state != SWITCHING_STATE_OFF) - || !EN_SWITCH_FENCE()) - count = 0; - else - count = (count < 2) ? 0 : 2; - - while (kfifo_len(&delay_display_q) > count) { - struct vframe_s *vf; - - if (kfifo_get(&delay_display_q, &vf)) { - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } - } -} - -static struct vframe_s *vh264_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vh264_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; -} - -static void vh264_vf_put(struct vframe_s *vf, void *op_arg) -{ - unsigned long flags; - - spin_lock_irqsave(&recycle_lock, flags); - - if ((vf != &fense_vf[0]) && (vf != &fense_vf[1])) - kfifo_put(&recycle_q, (const struct vframe_s *)vf); - - spin_unlock_irqrestore(&recycle_lock, flags); -} - -static int vh264_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(&vh264_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vh264_local_init(); - vh264_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vh264_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -static int vh264_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) + - kfifo_len(&delay_display_q); - states->buf_recycle_num = kfifo_len(&recycle_q); - - spin_unlock_irqrestore(&lock, flags); - - return 0; -} - -#if 0 -static tvin_trans_fmt_t convert_3d_format(u32 type) -{ - const tvin_trans_fmt_t conv_tab[] = { - 0, /* checkerboard */ - 0, /* column alternation */ - TVIN_TFMT_3D_LA, /* row alternation */ - TVIN_TFMT_3D_LRH_OLER, /* side by side */ - TVIN_TFMT_3D_FA /* top bottom */ - }; - - return (type <= 4) ? conv_tab[type] : 0; -} -#endif - -static void set_frame_info(struct vframe_s *vf) -{ - vf->width = frame_width; - vf->height = frame_height; - vf->duration = frame_dur; - vf->ratio_control = - (min(h264_ar, (u32) DISP_RATIO_ASPECT_RATIO_MAX)) << - DISP_RATIO_ASPECT_RATIO_BIT; - vf->orientation = vh264_rotation; - vf->flag = 0; - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_3D_PROCESS - vf->trans_fmt = 0; - if ((vf->trans_fmt == TVIN_TFMT_3D_LRF) || - (vf->trans_fmt == TVIN_TFMT_3D_LA)) { - vf->left_eye.start_x = 0; - vf->left_eye.start_y = 0; - vf->left_eye.width = frame_width / 2; - vf->left_eye.height = frame_height; - - vf->right_eye.start_x = 0; - vf->right_eye.start_y = 0; - vf->right_eye.width = frame_width / 2; - vf->right_eye.height = frame_height; - } else if ((vf->trans_fmt == TVIN_TFMT_3D_LRH_OLER) || - (vf->trans_fmt == TVIN_TFMT_3D_TB)) { - vf->left_eye.start_x = 0; - vf->left_eye.start_y = 0; - vf->left_eye.width = frame_width / 2; - vf->left_eye.height = frame_height; - - vf->right_eye.start_x = 0; - vf->right_eye.start_y = 0; - vf->right_eye.width = frame_width / 2; - vf->right_eye.height = frame_height; - } -#endif - -} - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER -static void vh264_ppmgr_reset(void) -{ - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - - vh264_local_init(); - - pr_info("vh264dec: vf_ppmgr_reset\n"); -} -#endif - -static int get_max_dpb_size(int level_idc, int mb_width, int mb_height) -{ - int size, r; - - switch (level_idc) { - case 10: - r = 1485; - break; - case 11: - r = 3375; - break; - case 12: - case 13: - case 20: - r = 8910; - break; - case 21: - r = 17820; - break; - case 22: - case 30: - r = 30375; - break; - case 31: - r = 67500; - break; - case 32: - r = 76800; - break; - case 40: - case 41: - case 42: - r = 122880; - break; - case 50: - r = 414000; - break; - case 51: - case 52: - r = 691200; - break; - default: - return 0; - } - size = (mb_width * mb_height + - (mb_width * mb_height / 2)) * 256 * 10; - r = (r * 1024 + size-1) / size; - r = min(r, 16); - /*pr_info("max_dpb %d size:%d\n", r, size);*/ - return r; -} -static void vh264_set_params(struct work_struct *work) -{ - int aspect_ratio_info_present_flag, aspect_ratio_idc; - int max_dpb_size, actual_dpb_size, max_reference_size; - int i, mb_mv_byte, start_addr; - unsigned long addr; - unsigned int post_canvas; - unsigned int frame_mbs_only_flag; - unsigned int chroma_format_idc, chroma444, video_signal; - unsigned int crop_infor, crop_bottom, crop_right, level_idc; - u32 disp_addr = 0xffffffff; - //struct canvas_s cur_canvas; - - if (!atomic_read(&vh264_active)) - return; - mutex_lock(&vh264_mutex); - if (vh264_stream_switching_state == SWITCHING_STATE_ON_CMD1) - vh264_stream_switching_state = SWITCHING_STATE_ON_CMD1_PENDING; - post_canvas = get_post_canvas(); - clk_adj_frame_count = 0; - /* set to max decoder clock rate at the beginning */ - vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); - timing_info_present_flag = 0; - mb_width = READ_VREG(AV_SCRATCH_1); - seq_info = READ_VREG(AV_SCRATCH_2); - aspect_ratio_info = READ_VREG(AV_SCRATCH_3); - num_units_in_tick = READ_VREG(AV_SCRATCH_4); - time_scale = READ_VREG(AV_SCRATCH_5); - level_idc = READ_VREG(AV_SCRATCH_A); - if (level_idc > 0) - saved_idc_level = level_idc; - else if (saved_idc_level > 0) - level_idc = saved_idc_level; - video_signal = READ_VREG(AV_SCRATCH_H); - video_signal_from_vui = - ((video_signal & 0xffff) << 8) | - ((video_signal & 0xff0000) >> 16) | - ((video_signal & 0x3f000000)); -/* -* pr_info("video_signal_type_present_flag 0x%x\n", -* (video_signal_from_vui >> 29) & 1); -* pr_info("video_format 0x%x\n", -* (video_signal_from_vui >> 26) & 7); -* pr_info("video_full_range_flag 0x%x\n", -* (video_signal_from_vui >> 25) & 1); -* pr_info("color_description_present_flag 0x%x\n", -* (video_signal_from_vui >> 24) & 1); -* pr_info("color_primaries 0x%x\n", -* (video_signal_from_vui >> 16) & 0xff); -* pr_info("transfer_characteristic 0x%x\n", -* (video_signal_from_vui >> 8) & 0xff); -* pr_info("matrix_coefficient 0x%x\n", -* video_signal_from_vui & 0xff); -*/ - - mb_total = (mb_width >> 8) & 0xffff; - max_reference_size = (mb_width >> 24) & 0x7f; - mb_mv_byte = (mb_width & 0x80000000) ? 24 : 96; - if (ucode_type == UCODE_IP_ONLY_PARAM) - mb_mv_byte = 96; - mb_width = mb_width & 0xff; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - if (!mb_width && mb_total) - mb_width = 256; - } - mb_height = mb_total / mb_width; - last_duration = 0; - /* AV_SCRATCH_2 - * bit 15: frame_mbs_only_flag - *bit 13-14: chroma_format_idc - */ - frame_mbs_only_flag = (seq_info >> 15) & 0x01; - chroma_format_idc = (seq_info >> 13) & 0x03; - chroma444 = (chroma_format_idc == 3) ? 1 : 0; - - /* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1 - * @AV_SCRATCH_6.15-0 = (top << 8 | bottom ) << - * (2 - frame_mbs_only_flag) - */ - crop_infor = READ_VREG(AV_SCRATCH_6); - crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag); - crop_right = ((crop_infor >> 16) & 0xff) >> (2 - frame_mbs_only_flag); - - /* if width or height from outside is not equal to mb, then use mb */ - /* add: for seeking stream with other resolution */ - if ((last_mb_width && (last_mb_width != mb_width)) - || (mb_width != ((frame_width + 15) >> 4))) - frame_width = 0; - if ((last_mb_height && (last_mb_height != mb_height)) - || (mb_height != ((frame_height + 15) >> 4))) - frame_height = 0; - last_mb_width = mb_width; - last_mb_height = mb_height; - - if ((frame_width == 0) || (frame_height == 0) || crop_infor) { - frame_width = mb_width << 4; - frame_height = mb_height << 4; - if (frame_mbs_only_flag) { - frame_height = - frame_height - (2 >> chroma444) * - min(crop_bottom, - (unsigned int)((8 << chroma444) - 1)); - frame_width = - frame_width - (2 >> chroma444) * min(crop_right, - (unsigned - int)((8 << chroma444) - 1)); - } else { - frame_height = - frame_height - (4 >> chroma444) * - min(crop_bottom, - (unsigned int)((8 << chroma444) - - 1)); - frame_width = - frame_width - (4 >> chroma444) * min(crop_right, - (unsigned - int)((8 << - chroma444) - - 1)); - } -#if 0 - pr_info - ("frame_mbs_only_flag %d, crop_bottom %d, frame_height %d, ", - frame_mbs_only_flag, crop_bottom, frame_height); - pr_info - ("mb_height %d,crop_right %d, frame_width %d, mb_width %d\n", - mb_height, crop_right, frame_width, mb_width); -#endif - if (frame_height == 1088) - frame_height = 1080; - } - - mb_width = (mb_width + 3) & 0xfffffffc; - mb_height = (mb_height + 3) & 0xfffffffc; - mb_total = mb_width * mb_height; - - /*max_reference_size <= max_dpb_size <= actual_dpb_size*/ - is_4k = (mb_total > 8160) ? true:false; - - if (is_4k || dpb_size_adj) { - /*4k2k*/ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - max_dpb_size = get_max_dpb_size( - level_idc, mb_width, mb_height); - actual_dpb_size = max_dpb_size + 5; - if (dpb_size_adj) - actual_dpb_size - = max_reference_size + dpb_size_adj; - if (actual_dpb_size > VF_BUF_NUM) - actual_dpb_size = VF_BUF_NUM; - pr_info - ("actual_dpb_size %d max_ref_size %d\n", - actual_dpb_size, max_reference_size); - } else { - vh264_running = 0; - fatal_error_flag = - DECODER_FATAL_ERROR_SIZE_OVERFLOW; - mutex_unlock(&vh264_mutex); - pr_err("oversize ! mb_total %d,\n", mb_total); - return; - } - } else { - actual_dpb_size = (frame_buffer_size - mb_total * mb_mv_byte * - max_reference_size) / (mb_total * 384); - actual_dpb_size = min(actual_dpb_size, VF_BUF_NUM); - max_dpb_size = get_max_dpb_size(level_idc, mb_width, mb_height); - if (max_reference_size > 1) - max_dpb_size = max_reference_size - 1; - else - max_dpb_size = max_reference_size; - if (actual_dpb_size < (max_dpb_size + 4)) { - actual_dpb_size = max_dpb_size + 4; - if (actual_dpb_size > VF_BUF_NUM) - actual_dpb_size = VF_BUF_NUM; - } - pr_info("actual_dpb_size %d max_dpb_size %d\n", - actual_dpb_size, max_dpb_size); - } - if (max_dpb_size == 0) - max_dpb_size = actual_dpb_size; - else - max_dpb_size = min(max_dpb_size, actual_dpb_size); - max_reference_size = min(max_reference_size, actual_dpb_size-1); - max_dpb_size = max(max_reference_size, max_dpb_size); - max_reference_size++; - - start_addr = addr = buf_start; - if (is_4k) - addr += ((mb_total << 8) + (mb_total << 7));/*keep last frame */ - WRITE_VREG(AV_SCRATCH_1, addr); - WRITE_VREG(AV_SCRATCH_3, post_canvas); /* should be modified later */ - //canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), &cur_canvas); - //disp_addr = (cur_canvas.addr + 7) >> 3;//DEBUG_TMP - if ((addr + mb_total * mb_mv_byte * max_reference_size) - >= buf_end) { - fatal_error_flag = - DECODER_FATAL_ERROR_NO_MEM; - vh264_running = 0; - mutex_unlock(&vh264_mutex); - pr_err("mv buf not enough!\n"); - return; - } - addr += mb_total * mb_mv_byte * max_reference_size; - WRITE_VREG(AV_SCRATCH_4, addr); - if (!(READ_VREG(AV_SCRATCH_F) & 0x1)) { - bool use_alloc = is_4k ? true:false; - int alloc_count = 0; - - for (i = 0; i < actual_dpb_size; i++) { - if (((addr + (mb_total << 8) + (mb_total << 7)) - >= buf_end) && (!use_alloc)) { - pr_info("start alloc for %d\n", i); - use_alloc = true; - } - if (use_alloc) { -#ifdef DOUBLE_WRITE - int page_count = - PAGE_ALIGN((mb_total << 8) + (mb_total - << 7) + (mb_total << 6) + - (mb_total << 5)) / PAGE_SIZE; -#else - int page_count = - PAGE_ALIGN((mb_total << 8) + - (mb_total << 7)) / PAGE_SIZE; -#endif - buffer_spec[i].alloc_count = page_count; - if (!decoder_bmmu_box_alloc_idx_wait( - mm_blk_handle, - i, - page_count << PAGE_SHIFT, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - )) { - buffer_spec[i].phy_addr = - decoder_bmmu_box_get_phy_addr( - mm_blk_handle, - i); - pr_info("CMA malloc ok %d\n", i); - alloc_count++; - } else { - buffer_spec[i].alloc_count = 0; - fatal_error_flag = - DECODER_FATAL_ERROR_NO_MEM; - vh264_running = 0; - mutex_unlock(&vh264_mutex); - pr_err("CMA not enough mem! %d\n", - i); - return; - } - addr = buffer_spec[i].phy_addr; - } else { - if (buffer_spec[i].phy_addr) { - decoder_bmmu_box_free_idx( - mm_blk_handle, - i); - buffer_spec[i].phy_addr = 0; - buffer_spec[i].alloc_count = 0; - } - } - /*4k keep last frame */ - if (is_4k && ((addr + 7) >> 3) == disp_addr) - addr = start_addr; - if (i <= 21) { - buffer_spec[i].y_addr = addr; - addr += mb_total << 8; - buffer_spec[i].u_addr = addr; - buffer_spec[i].v_addr = addr; - addr += mb_total << 7; - vfbuf_use[i] = 0; - - buffer_spec[i].y_canvas_index = 128 + i * 2; - buffer_spec[i].u_canvas_index = 128 + i * 2 + 1; - buffer_spec[i].v_canvas_index = 128 + i * 2 + 1; - - buffer_spec[i].y_canvas_width = mb_width << 4; - buffer_spec[i].y_canvas_height = mb_height << 4; - buffer_spec[i].u_canvas_width = mb_width << 4; - buffer_spec[i].u_canvas_height = mb_height << 4; - buffer_spec[i].v_canvas_width = mb_width << 4; - buffer_spec[i].v_canvas_height = mb_height << 4; - - canvas_config(128 + i * 2, - buffer_spec[i].y_addr, - mb_width << 4, mb_height << 4, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(128 + i * 2 + 1, - buffer_spec[i].u_addr, - mb_width << 4, mb_height << 3, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - WRITE_VREG(ANC0_CANVAS_ADDR + i, - spec2canvas(&buffer_spec[i])); - } else { - buffer_spec[i].y_canvas_index = - 2 * (i - 21) + 4; - buffer_spec[i].y_addr = addr; - addr += mb_total << 8; - buffer_spec[i].u_canvas_index = - 2 * (i - 21) + 5; - buffer_spec[i].v_canvas_index = - 2 * (i - 21) + 5; - buffer_spec[i].u_addr = addr; - addr += mb_total << 7; - vfbuf_use[i] = 0; - - buffer_spec[i].y_canvas_width = mb_width << 4; - buffer_spec[i].y_canvas_height = mb_height << 4; - buffer_spec[i].u_canvas_width = mb_width << 4; - buffer_spec[i].u_canvas_height = mb_height << 4; - buffer_spec[i].v_canvas_width = mb_width << 4; - buffer_spec[i].v_canvas_height = mb_height << 4; - - spec_set_canvas(&buffer_spec[i] - , mb_width << 4, mb_height << 4); - WRITE_VREG(ANC0_CANVAS_ADDR + i - , spec2canvas(&buffer_spec[i])); - } - } - } else - addr = buf_start + mb_total * 384 * actual_dpb_size; - - timing_info_present_flag = seq_info & 0x2; - fixed_frame_rate_flag = 0; - aspect_ratio_info_present_flag = seq_info & 0x1; - aspect_ratio_idc = (seq_info >> 16) & 0xff; - - if (timing_info_present_flag) { - fixed_frame_rate_flag = seq_info & 0x40; - - if (((num_units_in_tick * 120) >= time_scale - && ((!sync_outside) || (!frame_dur))) && - num_units_in_tick - && time_scale) { - if (use_idr_framerate || !frame_dur - || !duration_from_pts_done || vh264_running) { - u32 frame_dur_es = - div_u64(96000ULL * 2 * - num_units_in_tick, - time_scale); - - /* 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 - pr_info("H.264: timing_info not present\n"); - - if (aspect_ratio_info_present_flag) { - if (aspect_ratio_idc == EXTEND_SAR) { - h264_ar = - div_u64(256ULL * (aspect_ratio_info >> 16) * - frame_height, - (aspect_ratio_info & 0xffff) * - frame_width); - } else { - /* pr_info("v264dec: aspect_ratio_idc = %d\n", - * aspect_ratio_idc); - */ - - switch (aspect_ratio_idc) { - case 1: - h264_ar = 0x100 * frame_height / frame_width; - break; - case 2: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 12); - break; - case 3: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 10); - break; - case 4: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 16); - break; - case 5: - h264_ar = 0x100 * frame_height * 33 / - (frame_width * 40); - break; - case 6: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 24); - break; - case 7: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 20); - break; - case 8: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 32); - break; - case 9: - h264_ar = 0x100 * frame_height * 33 / - (frame_width * 80); - break; - case 10: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 18); - break; - case 11: - h264_ar = 0x100 * frame_height * 11 / - (frame_width * 15); - break; - case 12: - h264_ar = 0x100 * frame_height * 33 / - (frame_width * 64); - break; - case 13: - h264_ar = 0x100 * frame_height * 99 / - (frame_width * 160); - break; - case 14: - h264_ar = 0x100 * frame_height * 3 / - (frame_width * 4); - break; - case 15: - h264_ar = 0x100 * frame_height * 2 / - (frame_width * 3); - break; - case 16: - h264_ar = 0x100 * frame_height * 1 / - (frame_width * 2); - break; - default: - if (vh264_ratio >> 16) { - h264_ar = (frame_height * - (vh264_ratio & 0xffff) * - 0x100 + - ((vh264_ratio >> 16) * - frame_width / 2)) / - ((vh264_ratio >> 16) * - frame_width); - } else { - h264_ar = frame_height * 0x100 / - frame_width; - } - break; - } - } - } else { - pr_info("v264dec: aspect_ratio not available from source\n"); - if (vh264_ratio >> 16) { - /* high 16 bit is width, low 16 bit is height */ - h264_ar = - ((vh264_ratio & 0xffff) * frame_height * 0x100 + - (vh264_ratio >> 16) * frame_width / 2) / - ((vh264_ratio >> 16) * frame_width); - } else - h264_ar = frame_height * 0x100 / frame_width; - } - - WRITE_VREG(AV_SCRATCH_0, - (max_reference_size << 24) | (actual_dpb_size << 16) | - (max_dpb_size << 8)); - if (vh264_stream_switching_state != SWITCHING_STATE_OFF) { - vh264_stream_switching_state = SWITCHING_STATE_OFF; - pr_info("Leaving switching mode.\n"); - } - mutex_unlock(&vh264_mutex); -} - -static unsigned pts_inc_by_duration(unsigned *new_pts, unsigned *new_pts_rem) -{ - unsigned r, rem; - - r = last_pts + DUR2PTS(frame_dur); - rem = last_pts_remainder + DUR2PTS_REM(frame_dur); - - if (rem >= 96) { - r++; - rem -= 96; - } - - if (new_pts) - *new_pts = r; - if (new_pts_rem) - *new_pts_rem = rem; - - return r; -} -static inline bool vh264_isr_parser(struct vframe_s *vf, - unsigned int pts_valid, unsigned int buffer_index, - unsigned int pts) -{ - unsigned int pts_duration = 0; - - if (h264_first_pts_ready == 0) { - if (pts_valid == 0) { - vfbuf_use[buffer_index]++; - vf->index = buffer_index; - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - return false; - } - - h264pts1 = pts; - h264_pts_count = 0; - h264_first_pts_ready = 1; - } else { - if (pts < h264pts1) { - if (h264_pts_count > 24) { - pr_info("invalid h264pts1, reset\n"); - h264pts1 = pts; - h264_pts_count = 0; - } - } - if (pts_valid && (pts > h264pts1) && (h264_pts_count > 24) - && (duration_from_pts_done == 0)) { - unsigned int - old_duration = frame_dur; - h264pts2 = pts; - - pts_duration = (h264pts2 - h264pts1) * 16 / - (h264_pts_count * 15); - - if ((pts_duration != frame_dur) - && (!pts_outside)) { - if (use_idr_framerate) { - bool pts_c_24 = close_to(pts_duration, - RATE_24_FPS, - RATE_CORRECTION_THRESHOLD); - bool frm_c_25 = close_to(frame_dur, - RATE_25_FPS, - RATE_CORRECTION_THRESHOLD); - bool pts_c_25 = close_to(pts_duration, - RATE_25_FPS, - RATE_CORRECTION_THRESHOLD); - bool frm_c_24 = close_to(frame_dur, - RATE_24_FPS, - RATE_CORRECTION_THRESHOLD); - if ((pts_c_24 && frm_c_25) - || (pts_c_25 && frm_c_24)) { - pr_info - ("H.264:Correct frame dur "); - pr_info - (" from %d to duration based ", - frame_dur); - pr_info - ("on PTS %d ---\n", - pts_duration); - frame_dur = pts_duration; - duration_from_pts_done = 1; - } else if (((frame_dur < 96000 / 240) - && (pts_duration > 96000 / 240)) - || (!duration_on_correcting && - !frm_c_25 && !frm_c_24)) { - /* fft: if the frame rate is - * not regular, use the - * calculate rate insteadof. - */ - pr_info - ("H.264:Correct frame dur "); - pr_info - (" from %d to duration based ", - frame_dur); - pr_info - ("on PTS %d ---\n", - pts_duration); - frame_dur = pts_duration; - duration_on_correcting = 1; - } - } else { - if (close_to(pts_duration, - frame_dur, 2000)) { - frame_dur = pts_duration; - pr_info - ("used calculate frame rate,"); - pr_info("on duration =%d\n", - frame_dur); - } else { - pr_info - ("don't use calculate frame "); - pr_info - ("rate pts_duration =%d\n", - pts_duration); - } - } - } - - if (duration_from_pts_done == 0) { - if (close_to - (pts_duration, - old_duration, - RATE_CORRECTION_THRESHOLD)) { - pr_info - ("finished correct frame dur"); - pr_info - (" new=%d,old_duration=%d,cnt=%d\n", - pts_duration, - old_duration, - h264_pts_count); - duration_from_pts_done = 1; - } else { /*not the same,redo it. */ - if (!close_to(pts_duration, - old_duration, 1000) && - !close_to(pts_duration, - frame_dur, 1000) && - close_to(pts_duration, - last_duration, 200)) { - /* yangle: frame_dur must - * wrong,recover it. - */ - frame_dur = pts_duration; - } - - pr_info - ("restart correct frame duration "); - pr_info - ("new=%d,old_duration=%d,cnt=%d\n", - pts_duration, - old_duration, - h264_pts_count); - h264pts1 = h264pts2; - h264_pts_count = 0; - duration_from_pts_done = 0; - } - } - last_duration = pts_duration; - } - } - return true; -} -#ifdef HANDLE_H264_IRQ -static irqreturn_t vh264_isr(int irq, void *dev_id) -#else -static void vh264_isr(void) -#endif -{ - unsigned int buffer_index; - struct vframe_s *vf; - unsigned int cpu_cmd; - unsigned int pts, pts_lookup_save, pts_valid_save, pts_valid = 0; - unsigned int pts_us64_valid = 0; - u64 pts_us64; - bool force_interlaced_frame = false; - unsigned int sei_itu35_flags; - static const unsigned int idr_num = - FIX_FRAME_RATE_CHECK_IDRFRAME_NUM; - static const unsigned int flg_1080_itl = - DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE; - static const unsigned int flg_576_itl = - DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE; - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - if (0 == (stat & STAT_VDEC_RUN)) { - pr_info("decoder is not running\n"); -#ifdef HANDLE_H264_IRQ - return IRQ_HANDLED; -#else - return; -#endif - } - - cpu_cmd = READ_VREG(AV_SCRATCH_0); - -#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS - if ((frame_dur < 2004) && - (frame_width >= 1400) && - (frame_height >= 1000) && (last_interlaced == 0)) - SET_VREG_MASK(AV_SCRATCH_F, 0x8); -#endif - if ((decoder_force_reset == 1) - || ((error_recovery_mode != 1) - && (no_idr_error_count >= no_idr_error_max) - && (ucode_type != UCODE_IP_ONLY_PARAM))) { - vh264_running = 0; - pr_info("force reset decoder %d!!!\n", no_idr_error_count); - schedule_work(&error_wd_work); - decoder_force_reset = 0; - no_idr_error_count = 0; - } else if ((cpu_cmd & 0xff) == 1) { - if (unlikely - (vh264_running - && (kfifo_len(&newframe_q) != VF_POOL_SIZE))) { - /* a cmd 1 sent during decoding w/o getting a cmd 3. */ - /* should not happen but the original code has such - * case, do the same process - */ - if ((READ_VREG(AV_SCRATCH_1) & 0xff) - == 1) {/*invalid mb_width*/ - vh264_running = 0; - fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; - /* this is fatal error, need restart */ - pr_info("cmd 1 fatal error happened\n"); - schedule_work(&error_wd_work); - } else { - vh264_stream_switching_state = SWITCHING_STATE_ON_CMD1; - pr_info("Enter switching mode cmd1.\n"); - schedule_work(&stream_switching_work); - } - return IRQ_HANDLED; - } - pr_info("Enter set parameter cmd1.\n"); - schedule_work(&set_parameter_work); - return IRQ_HANDLED; - } else if ((cpu_cmd & 0xff) == 2) { - int frame_mb_only, pic_struct_present, pic_struct, prog_frame, - poc_sel, idr_flag, eos, error; - int i, status, num_frame, b_offset; - int current_error_count, slice_type; - - vh264_running = 1; - vh264_no_disp_count = 0; - num_frame = (cpu_cmd >> 8) & 0xff; - frame_mb_only = seq_info & 0x8000; - pic_struct_present = seq_info & 0x10; - - current_error_count = READ_VREG(AV_SCRATCH_D); - if (vh264_error_count != current_error_count) { - /* pr_info("decoder error happened, count %d\n", - * current_error_count); - */ - vh264_error_count = current_error_count; - } - - for (i = 0; (i < num_frame) && (!vh264_eos); i++) { - status = READ_VREG(AV_SCRATCH_1 + i); - buffer_index = status & 0x1f; - error = status & 0x200; - slice_type = (READ_VREG(AV_SCRATCH_H) >> (i * 4)) & 0xf; - - if ((error_recovery_mode_use & 2) && error) - check_pts_discontinue = true; - if (ucode_type == UCODE_IP_ONLY_PARAM - && iponly_early_mode) - continue; - if ((p_last_vf != NULL) - && (p_last_vf->index == buffer_index)) - continue; - - if (buffer_index >= VF_BUF_NUM) - continue; - - pic_struct = (status >> 5) & 0x7; - prog_frame = status & 0x100; - poc_sel = status & 0x200; - idr_flag = status & 0x400; - frame_packing_type = (status >> 12) & 0x7; - eos = (status >> 15) & 1; - - if (eos) - vh264_eos = 1; - - b_offset = (status >> 16) & 0xffff; - - if (error) - no_idr_error_count++; - if (idr_flag || - (!error && (slice_type != SLICE_TYPE_I))) - no_idr_error_count = 0; - - if (decoder_debug_flag) { - pr_info - ("slice_type %x idr %x error %x count %d", - slice_type, idr_flag, error, - no_idr_error_count); - pr_info(" prog %x pic_struct %x offset %x\n", - prog_frame, pic_struct, b_offset); - } -#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS - last_interlaced = prog_frame ? 0 : 1; -#endif - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - if (clk_adj_frame_count < VDEC_CLOCK_ADJUST_FRAME) - clk_adj_frame_count++; - - set_frame_info(vf); - - switch (i) { - case 0: - b_offset |= - (READ_VREG(AV_SCRATCH_A) & 0xffff) - << 16; - break; - case 1: - b_offset |= - READ_VREG(AV_SCRATCH_A) & 0xffff0000; - break; - case 2: - b_offset |= - (READ_VREG(AV_SCRATCH_B) & 0xffff) - << 16; - break; - case 3: - b_offset |= - READ_VREG(AV_SCRATCH_B) & 0xffff0000; - break; - case 4: - b_offset |= - (READ_VREG(AV_SCRATCH_C) & 0xffff) - << 16; - break; - case 5: - b_offset |= - READ_VREG(AV_SCRATCH_C) & 0xffff0000; - break; - default: - break; - } - - /* add 64bit pts us ; */ - if (unlikely - ((b_offset == first_offset) - && (first_pts_cached))) { - pts = first_pts; - pts_us64 = first_pts64; - first_pts_cached = false; - pts_valid = 1; - pts_us64_valid = 1; -#ifdef DEBUG_PTS - pts_hit++; -#endif - } else if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, b_offset, &pts, 0, - &pts_us64) == 0) { - pts_valid = 1; - pts_us64_valid = 1; -#ifdef DEBUG_PTS - pts_hit++; -#endif - } else { - pts_valid = 0; - pts_us64_valid = 0; -#ifdef DEBUG_PTS - pts_missed++; -#endif - } - - /* on second IDR frame,check the diff between pts - * compute from duration and pts from lookup , - * if large than frame_dur,we think it is uncorrect. - */ - pts_lookup_save = pts; - pts_valid_save = pts_valid; - if (fixed_frame_rate_flag - && (fixed_frame_rate_check_count <= - idr_num)) { - if (idr_flag && pts_valid) { - fixed_frame_rate_check_count++; - /* pr_info("diff:%d\n", - * last_pts - pts_lookup_save); - */ - if ((fixed_frame_rate_check_count == - idr_num) && - (abs(pts - (last_pts + - DUR2PTS(frame_dur))) > - DUR2PTS(frame_dur))) { - fixed_frame_rate_flag = 0; - pr_info("pts sync mode play\n"); - } - - if (fixed_frame_rate_flag - && (fixed_frame_rate_check_count - > idr_num)) { - pr_info - ("fix_frame_rate mode play\n"); - } - } - } - - if (READ_VREG(AV_SCRATCH_F) & 2) { - /* for I only mode, ignore the PTS information - * and only uses frame duration for each I - * frame decoded - */ - if (p_last_vf) - pts_valid = 0; - /* also skip frame duration calculation - * based on PTS - */ - duration_from_pts_done = 1; - /* and add a default duration for 1/30 second - * if there is no valid frame - * duration available - */ - if (frame_dur == 0) - frame_dur = 96000 / 30; - } - - if (sync_outside == 0) { - if (!vh264_isr_parser(vf, - pts_valid, buffer_index, pts)) - continue; - - h264_pts_count++; - } else { - if (!idr_flag) - pts_valid = 0; - } - - if (pts_valid && !pts_discontinue) { - pts_discontinue = - (abs(last_pts - pts) >= - tsync_vpts_discontinuity_margin()); - } - /* if use_idr_framerate or fixed frame rate, only - * use PTS for IDR frames except for pts discontinue - */ - if (timing_info_present_flag && - frame_dur && - (use_idr_framerate || - (fixed_frame_rate_flag != 0)) - && pts_valid && h264_first_valid_pts_ready - && (!pts_discontinue)) { - pts_valid = - (slice_type == SLICE_TYPE_I) ? 1 : 0; - } - - if (!h264_first_valid_pts_ready && pts_valid) { - h264_first_valid_pts_ready = true; - last_pts = pts - DUR2PTS(frame_dur); - last_pts_remainder = 0; - } - /* calculate PTS of next frame and smooth - * PTS for fixed rate source - */ - if (pts_valid) { - if ((fixed_frame_rate_flag) && - (!pts_discontinue) && - (abs(pts_inc_by_duration(NULL, NULL) - - pts) - < DUR2PTS(frame_dur))) { - pts = pts_inc_by_duration(&pts, - &last_pts_remainder); - } else - last_pts_remainder = 0; - - } else { - if (fixed_frame_rate_flag && !pts_discontinue && - (fixed_frame_rate_check_count > idr_num) && - pts_valid_save && (sync_outside == 0) && - (abs(pts_inc_by_duration(NULL, NULL) - pts) - > DUR2PTS(frame_dur))) { - duration_from_pts_done = 0; - pr_info("recalc frame_dur\n"); - } else - pts = pts_inc_by_duration(&pts, - &last_pts_remainder); - pts_valid = 1; - } - - if ((dec_control & - flg_1080_itl) - && (frame_width == 1920) - && (frame_height >= 1080) - && (vf->duration == 3203)) - force_interlaced_frame = true; - else if ((dec_control & - flg_576_itl) - && (frame_width == 720) - && (frame_height == 576) - && (vf->duration == 3840)) - force_interlaced_frame = true; - - /* for frames with PTS, check if there is PTS - * discontinue based on previous frames - * (including error frames), - * force no VPTS discontinue reporting if we saw - *errors earlier but only once. - */ - if ((pts_valid) && (check_pts_discontinue) - && (!error)) { - if (pts_discontinue) { - vf->flag = 0; - check_pts_discontinue = false; - } else if ((pts - last_pts) < 90000) { - vf->flag = VFRAME_FLAG_NO_DISCONTINUE; - check_pts_discontinue = false; - } - } - - last_pts = pts; - - if (fixed_frame_rate_flag - && (fixed_frame_rate_check_count <= - idr_num) - && (sync_outside == 0) - && pts_valid_save) - pts = pts_lookup_save; - - if (pic_struct_present) { - if ((pic_struct == PIC_TOP_BOT) - || (pic_struct == PIC_BOT_TOP)) - prog_frame = 0; - } - - if ((!force_interlaced_frame) - && (prog_frame - || (pic_struct_present - && pic_struct - <= PIC_TRIPLE_FRAME))) { - if (pic_struct_present) { - if (pic_struct == PIC_TOP_BOT_TOP - || pic_struct - == PIC_BOT_TOP_BOT) { - vf->duration += - vf->duration >> 1; - } else if (pic_struct == - PIC_DOUBLE_FRAME) - vf->duration += vf->duration; - else if (pic_struct == - PIC_TRIPLE_FRAME) { - vf->duration += - vf->duration << 1; - } - } - - last_pts = - last_pts + DUR2PTS(vf->duration - - frame_dur); - - vf->index = buffer_index; - vf->type = - VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; - vf->duration_pulldown = 0; - vf->signal_type = video_signal_from_vui; - vf->index = buffer_index; - vf->pts = (pts_valid) ? pts : 0; - if (pts_us64_valid == 1) - vf->pts_us64 = pts_us64; - else - vf->pts_us64 = div64_u64(((u64)vf->pts)*100, 9); - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&buffer_spec[buffer_index]); - vf->type_original = vf->type; - vfbuf_use[buffer_index]++; - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); - if ((error_recovery_mode_use & 2) && error) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - } else { - p_last_vf = vf; - pts_discontinue = false; - kfifo_put(&delay_display_q, - (const struct vframe_s *)vf); - } - } else { - if (pic_struct_present - && pic_struct == PIC_TOP_BOT) - vf->type = VIDTYPE_INTERLACE_TOP; - else if (pic_struct_present - && pic_struct == PIC_BOT_TOP) - vf->type = VIDTYPE_INTERLACE_BOTTOM; - else { - vf->type = - poc_sel ? - VIDTYPE_INTERLACE_BOTTOM : - VIDTYPE_INTERLACE_TOP; - } - vf->type |= VIDTYPE_VIU_NV21; - vf->type |= VIDTYPE_INTERLACE_FIRST; - - high_bandwith |= - ((codec_mm_get_total_size() < 80 * SZ_1M) - & ((READ_VREG(AV_SCRATCH_N) & 0xf) == 3) - & ((frame_width * frame_height) >= 1920*1080)); - if (high_bandwith) - vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH; - - vf->duration >>= 1; - vf->duration_pulldown = 0; - vf->signal_type = video_signal_from_vui; - vf->index = buffer_index; - vf->pts = (pts_valid) ? pts : 0; - if (pts_us64_valid == 1) - vf->pts_us64 = pts_us64; - else - vf->pts_us64 = div64_u64(((u64)vf->pts)*100, 9); - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&buffer_spec[buffer_index]); - vf->type_original = vf->type; - vfbuf_use[buffer_index]++; - vf->ready_jiffies64 = jiffies_64; - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); - if ((error_recovery_mode_use & 2) && error) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - continue; - } else { - pts_discontinue = false; - kfifo_put(&delay_display_q, - (const struct vframe_s *)vf); - } - - if (READ_VREG(AV_SCRATCH_F) & 2) - continue; - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no avail buffer slot."); - return IRQ_HANDLED; - } - - set_frame_info(vf); - - if (pic_struct_present - && pic_struct == PIC_TOP_BOT) - vf->type = VIDTYPE_INTERLACE_BOTTOM; - else if (pic_struct_present - && pic_struct == PIC_BOT_TOP) - vf->type = VIDTYPE_INTERLACE_TOP; - else { - vf->type = - poc_sel ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM; - } - - vf->type |= VIDTYPE_VIU_NV21; - vf->duration >>= 1; - vf->duration_pulldown = 0; - vf->signal_type = video_signal_from_vui; - vf->index = buffer_index; - vf->pts = 0; - vf->pts_us64 = 0; - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&buffer_spec[buffer_index]); - vf->type_original = vf->type; - vfbuf_use[buffer_index]++; - if (high_bandwith) - vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH; - - p_last_vf = vf; - vf->ready_jiffies64 = jiffies_64; - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); - kfifo_put(&delay_display_q, - (const struct vframe_s *)vf); - } - } - - WRITE_VREG(AV_SCRATCH_0, 0); - } else if ((cpu_cmd & 0xff) == 3) { - vh264_running = 1; - vh264_stream_switching_state = SWITCHING_STATE_ON_CMD3; - - pr_info("Enter switching mode cmd3.\n"); - schedule_work(&stream_switching_work); - - } else if ((cpu_cmd & 0xff) == 4) { - vh264_running = 1; - /* reserved for slice group */ - WRITE_VREG(AV_SCRATCH_0, 0); - } else if ((cpu_cmd & 0xff) == 5) { - vh264_running = 1; - /* reserved for slice group */ - WRITE_VREG(AV_SCRATCH_0, 0); - } else if ((cpu_cmd & 0xff) == 6) { - vh264_running = 0; - fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; - /* this is fatal error, need restart */ - pr_info("fatal error happened\n"); - if (!fatal_error_reset) - schedule_work(&error_wd_work); - } else if ((cpu_cmd & 0xff) == 7) { - vh264_running = 0; - frame_width = (READ_VREG(AV_SCRATCH_1) + 1) * 16; - pr_info("Over decoder supported size, width = %d\n", - frame_width); - fatal_error_flag = DECODER_FATAL_ERROR_SIZE_OVERFLOW; - } else if ((cpu_cmd & 0xff) == 8) { - vh264_running = 0; - frame_height = (READ_VREG(AV_SCRATCH_1) + 1) * 16; - pr_info("Over decoder supported size, height = %d\n", - frame_height); - fatal_error_flag = DECODER_FATAL_ERROR_SIZE_OVERFLOW; - } else if ((cpu_cmd & 0xff) == 9) { - first_offset = READ_VREG(AV_SCRATCH_1); - if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, first_offset, &first_pts, 0, - &first_pts64) == 0) - first_pts_cached = true; - WRITE_VREG(AV_SCRATCH_0, 0); - - } else if ((cpu_cmd & 0xff) == 0xa) { - int b_offset = READ_VREG(AV_SCRATCH_2); - buffer_index = READ_VREG(AV_SCRATCH_1); - /*pr_info("iponly output %d b_offset %x\n", - buffer_index,b_offset);*/ - if (kfifo_get(&newframe_q, &vf) == 0) { - WRITE_VREG(AV_SCRATCH_0, 0); - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - if (pts_lookup_offset_us64 (PTS_TYPE_VIDEO, b_offset, - &pts, 0, &pts_us64) != 0) - vf->pts_us64 = vf->pts = 0; - else { - vf->pts_us64 = pts_us64; - vf->pts = pts; - } - - set_frame_info(vf); - vf->type = VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; - vf->duration_pulldown = 0; - vf->signal_type = video_signal_from_vui; - vf->index = buffer_index; - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&buffer_spec[buffer_index]); - vf->type_original = vf->type; - vf->mem_handle = decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - buffer_index); - vfbuf_use[buffer_index]++; - p_last_vf = vf; - pts_discontinue = false; - iponly_early_mode = 1; - kfifo_put(&delay_display_q, - (const struct vframe_s *)vf); - WRITE_VREG(AV_SCRATCH_0, 0); - } - - sei_itu35_flags = READ_VREG(AV_SCRATCH_J); - if (sei_itu35_flags & (1 << 15)) { /* data ready */ - /* int ltemp; */ - /* unsigned char *daddr; */ - unsigned int sei_itu35_wp = (sei_itu35_flags >> 16) & 0xffff; - unsigned int sei_itu35_data_length = sei_itu35_flags & 0x7fff; - struct userdata_poc_info_t user_data_poc; - -#if 0 - /* dump lmem for debug */ - WRITE_VREG(0x301, 0x8000); - WRITE_VREG(0x31d, 0x2); - for (ltemp = 0; ltemp < 64; ltemp++) { - laddr = 0x20 + ltemp; - WRITE_VREG(0x31b, laddr); - pr_info("mem 0x%x data 0x%x\n", laddr, - READ_VREG(0x31c) & 0xffff); - } -#endif -#if 0 - for (ltemp = 0; ltemp < sei_itu35_wp; ltemp++) { - daddr = - (unsigned char *)phys_to_virt( - sei_data_buffer_phys + - ltemp); - /* daddr = (unsigned char *)(sei_data_buffer + - * ltemp); - */ - pr_info("0x%x\n", *daddr); - } -#endif - /* pr_info("pocinfo 0x%x, top poc %d, wp 0x%x, length %d\n", - * READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M), - * sei_itu35_wp, sei_itu35_data_length); - */ - user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L); - user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M); - set_userdata_poc(user_data_poc); - WRITE_VREG(AV_SCRATCH_J, 0); - wakeup_userdata_poll(sei_itu35_wp, - (unsigned long)sei_data_buffer, - USER_DATA_SIZE, sei_itu35_data_length); - } -#ifdef HANDLE_H264_IRQ - return IRQ_HANDLED; -#else - return; -#endif -} - -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; - - enum receviver_start_e state = RECEIVER_INACTIVE; - - if (vh264_reset) { - pr_info("operation forbidden in timer !\n"); - goto exit; - } - - prepare_display_q(); - - 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; -#ifndef HANDLE_H264_IRQ - vh264_isr(); -#endif - - if (vh264_stream_switching_state != SWITCHING_STATE_OFF) - wait_buffer_counter = 0; - else { - reg_val = READ_VREG(AV_SCRATCH_9); - wait_buffer_status = reg_val & (1 << 31); - wait_i_pass_frames = reg_val & 0xff; - if (wait_buffer_status) { - if (kfifo_is_empty(&display_q) && - kfifo_is_empty(&delay_display_q) && - kfifo_is_empty(&recycle_q) && - (state == RECEIVER_INACTIVE)) { - pr_info("$$$$decoder is waiting for buffer\n"); - if (++wait_buffer_counter > 4) { - amvdec_stop(); - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vh264_ppmgr_reset(); -#else - vf_light_unreg_provider(&vh264_vf_prov); - vh264_local_init(); - vf_reg_provider(&vh264_vf_prov); -#endif - vh264_prot_init(); - amvdec_start(); - } - } else - wait_buffer_counter = 0; - } else if (wait_i_pass_frames > 1000) { - pr_info("i passed frames > 1000\n"); - amvdec_stop(); -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vh264_ppmgr_reset(); -#else - vf_light_unreg_provider(&vh264_vf_prov); - vh264_local_init(); - vf_reg_provider(&vh264_vf_prov); -#endif - vh264_prot_init(); - amvdec_start(); - } - } - -#if 0 - if (!wait_buffer_status) { - if (vh264_no_disp_count++ > NO_DISP_WD_COUNT) { - pr_info("$$$decoder did not send frame out\n"); - amvdec_stop(); -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vh264_ppmgr_reset(); -#else - vf_light_unreg_provider(PROVIDER_NAME); - vh264_local_init(); - vf_reg_provider(vh264_vf_prov); -#endif - vh264_prot_init(); - amvdec_start(); - - vh264_no_disp_count = 0; - vh264_no_disp_wd_count++; - } - } -#endif - - while (!kfifo_is_empty(&recycle_q) && - ((READ_VREG(AV_SCRATCH_7) == 0) - || (READ_VREG(AV_SCRATCH_8) == 0)) - && (vh264_stream_switching_state == SWITCHING_STATE_OFF)) { - struct vframe_s *vf; - - if (kfifo_get(&recycle_q, &vf)) { - if ((vf->index >= 0) && (vf->index < VF_BUF_NUM)) { - if (--vfbuf_use[vf->index] == 0) { - if (READ_VREG(AV_SCRATCH_7) == 0) { - WRITE_VREG(AV_SCRATCH_7, - vf->index + 1); - } else { - WRITE_VREG(AV_SCRATCH_8, - vf->index + 1); - } - } - - vf->index = VF_BUF_NUM; - kfifo_put(&newframe_q, - (const struct vframe_s *)vf); - } - } - } - - if (vh264_stream_switching_state != SWITCHING_STATE_OFF) { - while (!kfifo_is_empty(&recycle_q)) { - struct vframe_s *vf; - - if (kfifo_get(&recycle_q, &vf)) { - if ((vf->index >= 0 && - (vf->index < VF_BUF_NUM))) { - vf->index = VF_BUF_NUM; - kfifo_put(&newframe_q, - (const struct vframe_s *)vf); - } - } - } - - WRITE_VREG(AV_SCRATCH_7, 0); - WRITE_VREG(AV_SCRATCH_8, 0); - - if (kfifo_len(&newframe_q) == VF_POOL_SIZE) - stream_switching_done(); - } - - if (ucode_type != UCODE_IP_ONLY_PARAM && - (clk_adj_frame_count > VDEC_CLOCK_ADJUST_FRAME) && - frame_dur > 0 && saved_resolution != - frame_width * frame_height * (96000 / frame_dur)) { - int fps = 96000 / frame_dur; - - if (frame_dur < 10) /*dur is too small ,think it errors fps*/ - fps = 60; - saved_resolution = frame_width * frame_height * fps; - vdec_source_changed(VFORMAT_H264, - frame_width, frame_height, fps); - } -exit: - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vh264_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; - vstatus->height = frame_height; - if (frame_dur != 0) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = READ_VREG(AV_SCRATCH_D); - vstatus->status = stat; - if (fatal_error_reset) - vstatus->status |= fatal_error_flag; - return 0; -} - -int vh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) -{ - if (trickmode == TRICKMODE_I) { - WRITE_VREG(AV_SCRATCH_F, - (READ_VREG(AV_SCRATCH_F) & 0xfffffffc) | 2); - trickmode_i = 1; - } else if (trickmode == TRICKMODE_NONE) { - WRITE_VREG(AV_SCRATCH_F, READ_VREG(AV_SCRATCH_F) & 0xfffffffc); - trickmode_i = 0; - } - - return 0; -} - -static void vh264_prot_init(void) -{ - - 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_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - READ_MPEG_REG(RESET0_REGISTER); - WRITE_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - - WRITE_MPEG_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)); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(AV_SCRATCH_0, 0); - WRITE_VREG(AV_SCRATCH_1, buf_offset); - WRITE_VREG(AV_SCRATCH_G, mc_dma_handle); - WRITE_VREG(AV_SCRATCH_7, 0); - WRITE_VREG(AV_SCRATCH_8, 0); - WRITE_VREG(AV_SCRATCH_9, 0); - WRITE_VREG(AV_SCRATCH_N, 0); - - error_recovery_mode_use = - (error_recovery_mode != - 0) ? error_recovery_mode : error_recovery_mode_in; - WRITE_VREG(AV_SCRATCH_F, - (READ_VREG(AV_SCRATCH_F) & 0xffffffc3) | - (READ_VREG(AV_SCRATCH_F) & 0xffffff43) | - ((error_recovery_mode_use & 0x1) << 4)); - if (dec_control & DEC_CONTROL_FLAG_DISABLE_FAST_POC) - SET_VREG_MASK(AV_SCRATCH_F, 1 << 7); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); - if (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(AV_SCRATCH_I, (u32)(sei_data_buffer_phys - buf_offset)); - WRITE_VREG(AV_SCRATCH_J, 0); - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) && !is_meson_mtvd_cpu()) { - /* pr_info("vh264 meson8 prot init\n"); */ - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); - } - /* #endif */ -} - -static void vh264_local_init(void) -{ - int i; - - vh264_ratio = vh264_amstream_dec_info.ratio; - /* vh264_ratio = 0x100; */ - - vh264_rotation = (((unsigned long) vh264_amstream_dec_info.param) - >> 16) & 0xffff; - - frame_buffer_size = AVIL_DPB_BUFF_SIZE + buf_size - DEFAULT_MEM_SIZE; - frame_prog = 0; - frame_width = vh264_amstream_dec_info.width; - frame_height = vh264_amstream_dec_info.height; - frame_dur = vh264_amstream_dec_info.rate; - pts_outside = ((unsigned long) vh264_amstream_dec_info.param) & 0x01; - sync_outside = ((unsigned long) vh264_amstream_dec_info.param & 0x02) - >> 1; - use_idr_framerate = ((unsigned long) vh264_amstream_dec_info.param - & 0x04) >> 2; - max_refer_buf = !(((unsigned long) vh264_amstream_dec_info.param - & 0x10) >> 4); - if (!mm_blk_handle) - mm_blk_handle = decoder_bmmu_box_alloc_box( - DRIVER_NAME, - 0, - MAX_BLK_BUFFERS, - 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | - CODEC_MM_FLAGS_FOR_VDECODER); - - pr_info - ("H264 sysinfo: %dx%d duration=%d, pts_outside=%d, ", - frame_width, frame_height, frame_dur, pts_outside); - pr_debug("sync_outside=%d, use_idr_framerate=%d\n", - sync_outside, use_idr_framerate); - - if ((unsigned long) vh264_amstream_dec_info.param & 0x08) - ucode_type = UCODE_IP_ONLY_PARAM; - else - ucode_type = 0; - - if ((unsigned long) vh264_amstream_dec_info.param & 0x20) - error_recovery_mode_in = 1; - else - error_recovery_mode_in = 3; - - if (!vh264_running) { - last_mb_width = 0; - last_mb_height = 0; - } - - for (i = 0; i < VF_BUF_NUM; i++) - vfbuf_use[i] = 0; - - INIT_KFIFO(display_q); - INIT_KFIFO(delay_display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &vfpool[i]; - - vfpool[i].index = VF_BUF_NUM; - vfpool[i].bufWidth = 1920; - kfifo_put(&newframe_q, vf); - } - -#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS - last_interlaced = 1; -#endif - h264_first_pts_ready = 0; - h264_first_valid_pts_ready = false; - h264pts1 = 0; - h264pts2 = 0; - h264_pts_count = 0; - duration_from_pts_done = 0; - vh264_error_count = READ_VREG(AV_SCRATCH_D); - - p_last_vf = NULL; - check_pts_discontinue = false; - last_pts = 0; - wait_buffer_counter = 0; - vh264_no_disp_count = 0; - fatal_error_flag = 0; - high_bandwith = 0; - vh264_stream_switching_state = SWITCHING_STATE_OFF; -#ifdef DEBUG_PTS - pts_missed = 0; - pts_hit = 0; -#endif - pts_discontinue = false; - no_idr_error_count = 0; -} - -static s32 vh264_init(void) -{ - int trickmode_fffb = 0; - int firmwareloaded = 0; - int i; - - /* pr_info("\nvh264_init\n"); */ - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - vh264_running = 0;/* init here to reset last_mb_width&last_mb_height */ - vh264_eos = 0; - duration_on_correcting = 0; - first_pts = 0; - first_pts64 = 0; - first_offset = 0; - first_pts_cached = false; - fixed_frame_rate_check_count = 0; - saved_resolution = 0; - iponly_early_mode = 0; - saved_idc_level = 0; - vh264_local_init(); - - query_video_status(0, &trickmode_fffb); - -#if 0 - if (!trickmode_fffb) { - void __iomem *p = - ioremap_nocache(ucode_map_start, V_BUF_ADDR_OFFSET); - if (p != NULL) { - memset(p, 0, V_BUF_ADDR_OFFSET); - iounmap(p); - } - } -#endif - - 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(); - - pr_err("vh264_init: Can not allocate mc memory.\n"); - return -ENOMEM; - } - - pr_debug("264 ucode swap area: phyaddr %p, cpu vaddr %p\n", - (void *)mc_dma_handle, mc_cpu_addr); - if (debugfirmware) { - int r0, r1, r2, r3, r4, r5; - char firmwarename[32]; - - pr_debug("start load debug %d firmware ...\n", debugfirmware); - - snprintf(firmwarename, 32, "%s%d", "vh264_mc", debugfirmware); - r0 = amvdec_loadmc_ex(VFORMAT_H264, firmwarename, NULL); - -#define DEBUGGET_FW(t, name, buf, size, ret)\ - do {\ - snprintf(firmwarename, 32, "%s%d", name,\ - debugfirmware);\ - ret = get_decoder_firmware_data(t,\ - firmwarename, buf, size);\ - } while (0) - /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_HEADER, vh264_header_mc, - *MC_SWAP_SIZE); - */ - DEBUGGET_FW(VFORMAT_H264, "vh264_header_mc", - (u8 *) mc_cpu_addr + MC_OFFSET_HEADER, - MC_SWAP_SIZE, r1); - - /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_DATA, vh264_data_mc, - *MC_SWAP_SIZE); - */ - DEBUGGET_FW(VFORMAT_H264, "vh264_data_mc", - (u8 *) mc_cpu_addr + MC_OFFSET_DATA, MC_SWAP_SIZE, r2); - /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_MMCO, vh264_mmco_mc, - *MC_SWAP_SIZE); - */ - DEBUGGET_FW(VFORMAT_H264, "vh264_mmco_mc", - (u8 *) mc_cpu_addr + MC_OFFSET_MMCO, MC_SWAP_SIZE, r3); - /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_LIST, vh264_list_mc, - *MC_SWAP_SIZE); - */ - DEBUGGET_FW(VFORMAT_H264, "vh264_list_mc", - (u8 *) mc_cpu_addr + MC_OFFSET_LIST, MC_SWAP_SIZE, r4); - /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_SLICE, vh264_slice_mc, - *MC_SWAP_SIZE); - */ - DEBUGGET_FW(VFORMAT_H264, "vh264_slice_mc", - (u8 *) mc_cpu_addr + MC_OFFSET_SLICE, MC_SWAP_SIZE, r5); - - if (r0 < 0 || r1 < 0 || r2 < 0 || r3 < 0 || r4 < 0 || r5 < 0) { - pr_err("264 load debugfirmware err %d,%d,%d,%d,%d,%d\n", - r0, r1, r2, r3, r4, r5); - amvdec_disable(); - if (mc_cpu_addr) { - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, mc_cpu_addr, - mc_dma_handle); - mc_cpu_addr = NULL; - } - return -EBUSY; - } - firmwareloaded = 1; - } else { - int ret = -1, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - size = get_firmware_data(VIDEO_DEC_H264, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf); - memcpy((u8 *) mc_cpu_addr + MC_OFFSET_HEADER, - buf + 0x4000, MC_SWAP_SIZE); - memcpy((u8 *) mc_cpu_addr + MC_OFFSET_DATA, - buf + 0x2000, MC_SWAP_SIZE); - memcpy((u8 *) mc_cpu_addr + MC_OFFSET_MMCO, - buf + 0x6000, MC_SWAP_SIZE); - memcpy((u8 *) mc_cpu_addr + MC_OFFSET_LIST, - buf + 0x3000, MC_SWAP_SIZE); - memcpy((u8 *) mc_cpu_addr + MC_OFFSET_SLICE, - buf + 0x5000, MC_SWAP_SIZE); - - vfree(buf); - - if (ret < 0) { - pr_err("h264 load orignal firmware error %d.\n", ret); - amvdec_disable(); - if (mc_cpu_addr) { - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, mc_cpu_addr, - mc_dma_handle); - mc_cpu_addr = NULL; - } - return -EBUSY; - } - } - - stat |= STAT_MC_LOAD; - if (enable_switch_fense) { - for (i = 0; i < ARRAY_SIZE(fense_buffer_spec); i++) { - struct buffer_spec_s *s = &fense_buffer_spec[i]; - s->alloc_count = 3 * SZ_1M / PAGE_SIZE; - if (!decoder_bmmu_box_alloc_idx_wait( - mm_blk_handle, - FENSE_BUFFER_IDX(i), - 3 * SZ_1M, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - )) { - s->phy_addr = decoder_bmmu_box_get_phy_addr( - mm_blk_handle, - FENSE_BUFFER_IDX(i)); - } else { - return -ENOMEM; - } - s->y_canvas_index = 2 * i; - s->u_canvas_index = 2 * i + 1; - s->v_canvas_index = 2 * i + 1; - } - } - /* enable AMRISC side protocol */ - vh264_prot_init(); - -#ifdef HANDLE_H264_IRQ - /*TODO irq */ - - if (vdec_request_irq(VDEC_IRQ_1, vh264_isr, - "vh264-irq", (void *)vh264_dec_id)) { - pr_err("vh264 irq register error.\n"); - amvdec_disable(); - return -ENOENT; - } -#endif - - stat |= STAT_ISR_REG; - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vh264_vf_prov, PROVIDER_NAME, &vh264_vf_provider_ops, - NULL); - vf_reg_provider(&vh264_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vh264_vf_prov, PROVIDER_NAME, &vh264_vf_provider_ops, - NULL); - vf_reg_provider(&vh264_vf_prov); -#endif - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)frame_dur)); - - 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; - - vh264_stream_switching_state = SWITCHING_STATE_OFF; - - stat |= STAT_VDEC_RUN; - wmb(); /* Ensure fetchbuf contents visible */ - - /* -- start decoder */ - amvdec_start(); - - init_userdata_fifo(); - - return 0; -} - -static int vh264_stop(int mode) -{ - - - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - WRITE_VREG(ASSIST_MBOX1_MASK, 0); - /*TODO irq */ - - vdec_free_irq(VDEC_IRQ_1, (void *)vh264_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 (mode == MODE_FULL) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, - NULL); - } - - vf_unreg_provider(&vh264_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - 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; - } - } - if (sei_data_buffer != NULL) { - dma_free_coherent( - amports_get_dma_device(), - USER_DATA_SIZE, - sei_data_buffer, - sei_data_buffer_phys); - sei_data_buffer = NULL; - sei_data_buffer_phys = 0; - } - amvdec_disable(); - if (mm_blk_handle) { - decoder_bmmu_box_free(mm_blk_handle); - mm_blk_handle = NULL; - } - memset(&fense_buffer_spec, 0, sizeof(fense_buffer_spec)); - memset(&buffer_spec, 0, sizeof(buffer_spec)); - return 0; -} - -static void error_do_work(struct work_struct *work) -{ - mutex_lock(&vh264_mutex); - - /* - * we need to lock vh264_stop/vh264_init. - * because we will call amvdec_h264_remove on this step; - * then we may call more than once on - * free_irq/deltimer/..and some other. - */ - if (atomic_read(&vh264_active)) { - amvdec_stop(); - vh264_reset = 1; -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vh264_ppmgr_reset(); -#else - vf_light_unreg_provider(&vh264_vf_prov); - - vh264_local_init(); - - vf_reg_provider(&vh264_vf_prov); -#endif - msleep(30); - vh264_local_init(); - vh264_prot_init(); - - amvdec_start(); - vh264_reset = 0; - } - - mutex_unlock(&vh264_mutex); -} - -static void stream_switching_done(void) -{ - int state = vh264_stream_switching_state; - - WRITE_VREG(AV_SCRATCH_7, 0); - WRITE_VREG(AV_SCRATCH_8, 0); - WRITE_VREG(AV_SCRATCH_9, 0); - - if (state == SWITCHING_STATE_ON_CMD1) { - pr_info("Enter set parameter cmd1 switching_state %x.\n", - vh264_stream_switching_state); - schedule_work(&set_parameter_work); - return; - } else if (state == SWITCHING_STATE_ON_CMD1_PENDING) - return; - - vh264_stream_switching_state = SWITCHING_STATE_OFF; - - wmb(); /* Ensure fetchbuf contents visible */ - - if (state == SWITCHING_STATE_ON_CMD3) - WRITE_VREG(AV_SCRATCH_0, 0); - - pr_info("Leaving switching mode.\n"); -} - -/* construt a new frame as a copy of last frame so frame receiver can - * release all buffer resources to decoder. - */ -static void stream_switching_do(struct work_struct *work) -{ - int mb_total_num, mb_width_num, mb_height_num, i = 0; - struct vframe_s *vf = NULL; - u32 y_index, u_index, src_index, des_index, y_desindex, u_desindex; - struct canvas_s csy, csu, cyd; - unsigned long flags; - bool delay = true; - - if (!atomic_read(&vh264_active)) - return; - - if (vh264_stream_switching_state == SWITCHING_STATE_OFF) - return; - - spin_lock_irqsave(&prepare_lock, flags); - - block_display_q = true; - - spin_unlock_irqrestore(&prepare_lock, flags); - - mb_total_num = mb_total; - mb_width_num = mb_width; - mb_height_num = mb_height; - - while (is_4k || kfifo_len(&delay_display_q) > 2) { - if (kfifo_get(&delay_display_q, &vf)) { - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } else - break; - } - - if (!kfifo_get(&delay_display_q, &vf)) { - vf = p_last_vf; - delay = false; - } - - while (vf) { - int buffer_index; - - buffer_index = vf->index & 0xff; - - /* construct a clone of the frame from last frame */ -#if 0 - pr_info("src yaddr[0x%x] index[%d] width[%d] heigth[%d]\n", - buffer_spec[buffer_index].y_addr, - buffer_spec[buffer_index].y_canvas_index, - buffer_spec[buffer_index].y_canvas_width, - buffer_spec[buffer_index].y_canvas_height); - - pr_info("src uaddr[0x%x] index[%d] width[%d] heigth[%d]\n", - buffer_spec[buffer_index].u_addr, - buffer_spec[buffer_index].u_canvas_index, - buffer_spec[buffer_index].u_canvas_width, - buffer_spec[buffer_index].u_canvas_height); -#endif - if (EN_SWITCH_FENCE()) { - y_index = buffer_spec[buffer_index].y_canvas_index; - u_index = buffer_spec[buffer_index].u_canvas_index; - - canvas_read(y_index, &csy); - canvas_read(u_index, &csu); - - 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); - 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); - - y_desindex = fense_buffer_spec[i].y_canvas_index; - u_desindex = fense_buffer_spec[i].u_canvas_index; - - canvas_read(y_desindex, &cyd); - - src_index = ((y_index & 0xff) | - ((u_index << 8) & 0x0000ff00)); - des_index = ((y_desindex & 0xff) | - ((u_desindex << 8) & 0x0000ff00)); -#if 0//DEBUG_TMP - ge2d_canvas_dup(&csy, &csu, &cyd, - GE2D_FORMAT_M24_NV21, - src_index, - des_index); -#endif - } - vf->mem_handle = decoder_bmmu_box_get_mem_handle( - mm_blk_handle, - FENSE_BUFFER_IDX(i)); - fense_vf[i] = *vf; - fense_vf[i].index = -1; - - if (EN_SWITCH_FENCE()) - fense_vf[i].canvas0Addr = - spec2canvas(&fense_buffer_spec[i]); - else - fense_vf[i].flag |= VFRAME_FLAG_SWITCHING_FENSE; - - /* send clone to receiver */ - kfifo_put(&display_q, - (const struct vframe_s *)&fense_vf[i]); - - /* early recycle frames for last session */ - if (delay) - vh264_vf_put(vf, NULL); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - - i++; - - if (!kfifo_get(&delay_display_q, &vf)) - break; - } - - block_display_q = false; - - pr_info("Switching fense frame post\n"); -} - -static int amvdec_h264_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - mutex_lock(&vh264_mutex); - - if (pdata == NULL) { - pr_info("\namvdec_h264 memory resource undefined.\n"); - mutex_unlock(&vh264_mutex); - return -EFAULT; - } - - ucode_map_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - if (buf_size < DEFAULT_MEM_SIZE) { - pr_info("\namvdec_h264 memory size not enough.\n"); - mutex_unlock(&vh264_mutex); - return -ENOMEM; - } - - buf_offset = pdata->mem_start - DEF_BUF_START_ADDR; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) - buf_start = V_BUF_ADDR_OFFSET_NEW + pdata->mem_start; - else - buf_start = V_BUF_ADDR_OFFSET + pdata->mem_start; - buf_end = pdata->mem_end; - if (pdata->sys_info) - vh264_amstream_dec_info = *pdata->sys_info; - if (NULL == sei_data_buffer) { - sei_data_buffer = - dma_alloc_coherent(amports_get_dma_device(), - USER_DATA_SIZE, - &sei_data_buffer_phys, GFP_KERNEL); - if (!sei_data_buffer) { - pr_info("%s: Can not allocate sei_data_buffer\n", - __func__); - mutex_unlock(&vh264_mutex); - return -ENOMEM; - } - /* pr_info("buffer 0x%x, phys 0x%x, remap 0x%x\n", - * sei_data_buffer, sei_data_buffer_phys, - * (u32)sei_data_buffer_remap); - */ - } - pr_debug("amvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx buf_size %x\n", - pdata->mem_start, buf_offset, buf_start, buf_size); - pdata->dec_status = vh264_dec_status; - pdata->set_trickmode = vh264_set_trickmode; - - if (vh264_init() < 0) { - pr_info("\namvdec_h264 init failed.\n"); - mutex_unlock(&vh264_mutex); - return -ENODEV; - } - - INIT_WORK(&error_wd_work, error_do_work); - INIT_WORK(&stream_switching_work, stream_switching_do); - INIT_WORK(&set_parameter_work, vh264_set_params); - - atomic_set(&vh264_active, 1); - - mutex_unlock(&vh264_mutex); - - return 0; -} - -static int amvdec_h264_remove(struct platform_device *pdev) -{ - atomic_set(&vh264_active, 0); - cancel_work_sync(&set_parameter_work); - cancel_work_sync(&error_wd_work); - cancel_work_sync(&stream_switching_work); - mutex_lock(&vh264_mutex); - vh264_stop(MODE_FULL); - vdec_source_changed(VFORMAT_H264, 0, 0, 0); - atomic_set(&vh264_active, 0); -#ifdef DEBUG_PTS - pr_info - ("pts missed %ld, pts hit %ld, pts_outside %d, duration %d, ", - pts_missed, pts_hit, pts_outside, frame_dur); - pr_info("sync_outside %d, use_idr_framerate %d\n", - sync_outside, use_idr_framerate); -#endif - mutex_unlock(&vh264_mutex); - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_h264_profile = { - .name = "h264", - .profile = "" -}; - -static int __init amvdec_h264_driver_init_module(void) -{ - pr_debug("amvdec_h264 module init\n"); - - /*ge2d_videoh264task_init();mask*/ - - if (platform_driver_register(&amvdec_h264_driver)) { - pr_err("failed to register amvdec_h264 driver\n"); - return -ENODEV; - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB - && (codec_mm_get_total_size() > 80 * SZ_1M)) { - amvdec_h264_profile.profile = "4k"; - dpb_size_adj = 0; - } - if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXBB) - dpb_size_adj = 0; - - vcodec_profile_register(&amvdec_h264_profile); - return 0; -} - -static void __exit amvdec_h264_driver_remove_module(void) -{ - pr_debug("amvdec_h264 module remove.\n"); - - platform_driver_unregister(&amvdec_h264_driver); - - /*ge2d_videoh264task_release();mask*/ -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_h264 stat\n"); -module_param(error_recovery_mode, uint, 0664); -MODULE_PARM_DESC(error_recovery_mode, "\n amvdec_h264 error_recovery_mode\n"); -module_param(sync_outside, uint, 0664); -MODULE_PARM_DESC(sync_outside, "\n amvdec_h264 sync_outside\n"); -module_param(dec_control, uint, 0664); -MODULE_PARM_DESC(dec_control, "\n amvdec_h264 decoder control\n"); -module_param(fatal_error_reset, uint, 0664); -MODULE_PARM_DESC(fatal_error_reset, - "\n amvdec_h264 decoder reset when fatal error happens\n"); -module_param(max_refer_buf, uint, 0664); -MODULE_PARM_DESC(max_refer_buf, - "\n amvdec_h264 dec buffering or not for reference frame\n"); -module_param(ucode_type, uint, 0664); -MODULE_PARM_DESC(ucode_type, - "\n amvdec_h264 dec buffering or not for reference frame\n"); -module_param(debugfirmware, uint, 0664); -MODULE_PARM_DESC(debugfirmware, "\n amvdec_h264 debug load firmware\n"); -module_param(fixed_frame_rate_flag, uint, 0664); -MODULE_PARM_DESC(fixed_frame_rate_flag, - "\n amvdec_h264 fixed_frame_rate_flag\n"); -module_param(decoder_debug_flag, uint, 0664); -MODULE_PARM_DESC(decoder_debug_flag, - "\n amvdec_h264 decoder_debug_flag\n"); - -module_param(dpb_size_adj, uint, 0664); -MODULE_PARM_DESC(dpb_size_adj, - "\n amvdec_h264 dpb_size_adj\n"); - - -module_param(decoder_force_reset, uint, 0664); -MODULE_PARM_DESC(decoder_force_reset, - "\n amvdec_h264 decoder force reset\n"); -module_param(no_idr_error_max, uint, 0664); -MODULE_PARM_DESC(no_idr_error_max, - "\n print no_idr_error_max\n"); -module_param(enable_switch_fense, uint, 0664); -MODULE_PARM_DESC(enable_switch_fense, - "\n enable switch fense\n"); - - -module_init(amvdec_h264_driver_init_module); -module_exit(amvdec_h264_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC H264 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Chen Zhang <chen.zhang@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/h264/vh264.h b/drivers/frame_provider/decoder/h264/vh264.h deleted file mode 100644 index 45d2849..0000000 --- a/drivers/frame_provider/decoder/h264/vh264.h +++ b/dev/null @@ -1,25 +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 s32 vh264_init(void); */ - -extern s32 vh264_release(void); - -#endif /* VMPEG4_H */ diff --git a/drivers/frame_provider/decoder/h264/vh264_4k2k.c b/drivers/frame_provider/decoder/h264/vh264_4k2k.c deleted file mode 100644 index 1c56b03..0000000 --- a/drivers/frame_provider/decoder/h264/vh264_4k2k.c +++ b/dev/null @@ -1,1839 +0,0 @@ -/* - * 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> - -#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" - -#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 - -#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 void 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 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_recieved; -static struct vframe_s *p_last_vf; - -#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, decoder_buffer_start, decoder_buffer_end; -static unsigned long reserved_buffer; - -#define DECODE_BUFFER_NUM_MAX 32 -#define DISPLAY_BUFFER_NUM 6 - -#define video_domain_addr(adr) (adr&0x7fffffff) -#define DECODER_WORK_SPACE_SIZE 0x400000 - -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[DECODE_BUFFER_NUM_MAX + - DISPLAY_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 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; - - return; -} - -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; -} - -int init_canvas(int start_addr, long dpb_size, int dpb_number, int mb_width, - int mb_height, struct buffer_spec_s *buffer_spec) -{ - unsigned long dpb_addr, addr; - int i; - int mb_total; - int canvas_addr = ANC0_CANVAS_ADDR; - int vdec2_canvas_addr = VDEC2_ANC0_CANVAS_ADDR; - int index = AMVDEC_H264_4K2K_CANVAS_INDEX; - u32 disp_addr = 0xffffffff; - bool use_alloc = false; - int alloc_count = 0; - struct canvas_s cur_canvas; - - dpb_addr = start_addr + dpb_size; - - mb_total = mb_width * mb_height; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - - mutex_lock(&vh264_4k2k_mutex); - - for (i = 0; i < dpb_number; i++) { - 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)); - } - - if (((dpb_addr + (mb_total << 8) + (mb_total << 7)) >= - decoder_buffer_end) && (!use_alloc)) { - pr_info("start alloc for %d/%d\n", i, dpb_number); - use_alloc = true; - } - - if (use_alloc) { -#ifdef DOUBLE_WRITE - int page_count = - PAGE_ALIGN((mb_total << 8) + (mb_total << 7) + - (mb_total << 6) + - (mb_total << 5)) / PAGE_SIZE; -#else - int page_count = - PAGE_ALIGN((mb_total << 8) + - (mb_total << 7)) / PAGE_SIZE; -#endif - - if (buffer_spec[i].phy_addr) { - if (page_count != buffer_spec[i].alloc_count) { - pr_info("Delay release CMA buffer%d\n", - i); - - /*dma_release_from_contiguous(cma_dev, - buffer_spec[i]. - alloc_pages, - buffer_spec[i]. - alloc_count); - */ - 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; - } else - pr_info("Re-use CMA buffer %d\n", i); - } - - if (!buffer_spec[i].phy_addr) { - if (codec_mm_get_free_size() - < (page_count * PAGE_SIZE)) { - pr_err - ("CMA not enough free keep buf! %d\n", - i); - try_free_keep_video(1); - } - if (!codec_mm_enough_for_size( - page_count * PAGE_SIZE, 1)) { - buffer_spec[i].alloc_count = 0; - fatal_error = - DECODER_FATAL_ERROR_NO_MEM; - mutex_unlock(&vh264_4k2k_mutex); - return -1; - } - buffer_spec[i].alloc_count = page_count; - buffer_spec[i].phy_addr = - codec_mm_alloc_for_dma( - MEM_NAME, buffer_spec[i].alloc_count, - 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | - CODEC_MM_FLAGS_FOR_VDECODER); - } - alloc_count++; - - if (!buffer_spec[i].phy_addr) { - buffer_spec[i].alloc_count = 0; - pr_info - ("264 4K2K decoder memory alloc failed %d.\n", - i); - mutex_unlock(&vh264_4k2k_mutex); - return -1; - } - addr = buffer_spec[i].phy_addr; - dpb_addr = addr; - } else { - 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; - } - - addr = dpb_addr; - dpb_addr += dpb_size; -#ifdef DOUBLE_WRITE - dpb_addr += dpb_size / 4; -#endif - } - - if (((addr + 7) >> 3) == disp_addr) - addr = start_addr; - - 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); - - addr += mb_total << 5; - index++; -#endif - } - - mutex_unlock(&vh264_4k2k_mutex); - - pr_info - ("H264 4k2k decoder canvas allocation successful, "); - pr_info("%d CMA blocks allocated, canvas %d-%d\n", - alloc_count, AMVDEC_H264_4K2K_CANVAS_INDEX, index - 1); - - 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; - int dpb_start_addr, ref_start_addr, 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); - - ref_start_addr = decoder_buffer_start; - 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; - dpb_start_addr = - ref_start_addr + (ref_size * (max_reference_frame_num + 1)) * 2; - /* dpb_start_addr = reserved_buffer + dpb_size; */ - - pr_info - ("dpb_start_addr=0x%x, dpb_size=%d, total_dec_frame_buffering=%d, ", - dpb_start_addr, dpb_size, total_dec_frame_buffering); - pr_info("mb_width=%d, mb_height=%d\n", - mb_width, mb_height); - - ret = init_canvas(dpb_start_addr, 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 */ -#if 0 - - pr_info("Debug: send a fake picture to config VPP %dx%d\n", frame_width, - frame_height); - WRITE_VREG(DOS_SCRATCH0, 4); - WRITE_VREG(DOS_SCRATCH1, 0x004c); - - if (kfifo_get(&newframe_q, &vf)) { - vfbuf_use[0]++; - vf->index = 0; - vf->pts = 0; - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&buffer_spec[0]); - set_frame_info(vf); - kfifo_put(&display_q, (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } - /* ///////////// FAKE END */ -#endif -} - -static irqreturn_t vh264_4k2k_isr(int irq, void *dev_id) -{ - int drop_status, display_buff_id, display_POC, slice_type, error; - unsigned stream_offset; - struct vframe_s *vf = NULL; - int ret = READ_VREG(MAILBOX_COMMAND); - - 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))) { - pts_lookup_offset_us64(PTS_TYPE_VIDEO, - stream_offset, - &vf->pts, - 0, - &vf->pts_us64); - } -#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_recovery_mode & 2) && error) - || (!first_i_recieved - && (slice_type != SLICE_TYPE_I))) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - } else { - p_last_vf = vf; - first_i_recieved = 1; - kfifo_put(&display_q, - (const struct vframe_s *)vf); - - 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_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_recieved) { - 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 >= 0) - && (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); - } - } - if (first_i_recieved &&/*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; - } - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vh264_4k2k_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; - vstatus->height = frame_height; - if (frame_dur != 0) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = 0; - vstatus->status = stat | fatal_error; - 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); - /*TODO for M8 - amvenc_dos_top_reg_fix();*/ - } -#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 void vh264_4k2k_local_init(void) -{ - int i; - -#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_recieved = 0; - INIT_WORK(&alloc_work, do_alloc_work); - - return; -} - -static s32 vh264_4k2k_init(void) -{ - int ret = -1, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - pr_info("\nvh264_4k2k_init\n"); - - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - vh264_4k2k_local_init(); - - 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 (amvdec_loadmc_ex(VFORMAT_H264_4K2K, NULL, buf) < 0) { - amvdec_disable(); - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); - mc_cpu_addr = NULL; - 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); - - if (ret < 0) { - amvdec_disable(); - if (!H264_4K2K_SINGLE_CORE) - amvdec2_disable(); - pr_info("vh264_4k2k load firmware error.\n"); - if (mc_cpu_addr) { - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle); - mc_cpu_addr = NULL; - } - - return -EBUSY; - } - 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; - - return 0; -} - -static int vh264_4k2k_stop(void) -{ - int i; - u32 disp_addr = 0xffffffff; - struct canvas_s cur_canvas; - - 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_VSYNC_RDMA - msleep(100); -#endif - if (!get_blackout_policy()) { - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = cur_canvas.addr; - } - - for (i = 0; i < ARRAY_SIZE(buffer_spec); i++) { - if (buffer_spec[i].phy_addr) { - if (disp_addr == - (u32)buffer_spec[i].phy_addr) - pr_info("Skip releasing CMA buffer %d\n", i); - else { - 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; - } - } - - if (buffer_spec[i].y_addr == disp_addr) { - pr_info("4K2K dec stop, keeping buffer index = %d\n", - i); - } - } - - 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); -} - -#if 0 /* (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8) && (HAS_HDEC) */ -/* extern void AbortEncodeWithVdec2(int abort); */ -#endif - -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; - } - - work_space_adr = pdata->mem_start; - decoder_buffer_start = pdata->mem_start + DECODER_WORK_SPACE_SIZE; - decoder_buffer_end = pdata->mem_end + 1; - - if (pdata->sys_info) - vh264_4k2k_amstream_dec_info = *pdata->sys_info; - cma_dev = pdata->cma_dev; - - pr_info("H.264 4k2k decoder mem resource 0x%x -- 0x%x\n", - (u32)decoder_buffer_start, (u32)decoder_buffer_end); - 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 1 /* (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8) && (has_hdec()) */ - int count = 0; - if (get_vdec2_usage() != USAGE_NONE) - /* AbortEncodeWithVdec2(1); */ /*TODO*/ - while ((get_vdec2_usage() != USAGE_NONE) && (count < 10)) { - msleep(50); - count++; - } - - if (get_vdec2_usage() != USAGE_NONE) { - pr_info - ("\namvdec_h264_4k2k - vdec2 is used by encode now.\n"); - mutex_unlock(&vh264_4k2k_mutex); - return -EBUSY; - } -#endif - - if (vdec_on(VDEC_2)) { /* ++++ */ - vdec_poweroff(VDEC_2); /* ++++ */ - mdelay(10); - } -#if 1 /* (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8) && (has_hdec()) */ - set_vdec2_usage(USAGE_DEC_4K2K); - /* AbortEncodeWithVdec2(0); */ /*TODO*/ -#endif - 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"); -#if 1/* (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8) && (has_hdec()) */ - if (!H264_4K2K_SINGLE_CORE) { - set_vdec2_usage(USAGE_NONE); - /*AbortEncodeWithVdec2(0);*/ /*TODO*/ - } -#endif - mutex_unlock(&vh264_4k2k_mutex); - 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); - 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); - - 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); -#if 1/*(MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8) && (has_hdec())*/ - set_vdec2_usage(USAGE_NONE); -#endif - } -#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); - - 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 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_type() < MESON_CPU_MAJOR_ID_GXTVBB) - vcodec_profile_register(&amvdec_h264_4k2k_profile); - - 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 deleted file mode 100644 index 1683c31..0000000 --- a/drivers/frame_provider/decoder/h264/vh264_mvc.c +++ b/dev/null @@ -1,1594 +0,0 @@ -/* - * drivers/amlogic/amports/vh264mvc.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/platform_device.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/canvas/canvas.h> -#include <linux/amlogic/media/vfm/vframe.h> -#include <linux/amlogic/media/vfm/vframe_provider.h> -#include <linux/amlogic/media/vfm/vframe_receiver.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/workqueue.h> -#include <linux/dma-mapping.h> -#include <linux/atomic.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" -#include "../utils/amvdec.h" - -#define TIME_TASK_PRINT_ENABLE 0x100 -#define PUT_PRINT_ENABLE 0x200 - -#define DRIVER_NAME "amvdec_h264mvc" -#define MODULE_NAME "amvdec_h264mvc" - -#define HANDLE_h264mvc_IRQ - -#define DEBUG_PTS -#define DEBUG_SKIP - -#define PUT_INTERVAL (HZ/100) - -#define STAT_TIMER_INIT 0x01 -#define STAT_MC_LOAD 0x02 -#define STAT_ISR_REG 0x04 -#define STAT_VF_HOOK 0x08 -#define STAT_TIMER_ARM 0x10 -#define STAT_VDEC_RUN 0x20 - -#define DROPPING_THREAD_HOLD 4 -#define DROPPING_FIRST_WAIT 16 -#define DISPLAY_INVALID_POS -65536 - -#define INIT_DROP_FRAME_CNT 8 - -static int vh264mvc_vf_states(struct vframe_states *states, void *); -static struct vframe_s *vh264mvc_vf_peek(void *); -static struct vframe_s *vh264mvc_vf_get(void *); -static void vh264mvc_vf_put(struct vframe_s *, void *); -static int vh264mvc_event_cb(int type, void *data, void *private_data); - -static void vh264mvc_prot_init(void); -static void vh264mvc_local_init(void); -static void vh264mvc_put_timer_func(unsigned long arg); - -static const char vh264mvc_dec_id[] = "vh264mvc-dev"; - -#define PROVIDER_NAME "decoder.h264mvc" - -static const struct vframe_operations_s vh264mvc_vf_provider = { - .peek = vh264mvc_vf_peek, - .get = vh264mvc_vf_get, - .put = vh264mvc_vf_put, - .event_cb = vh264mvc_event_cb, - .vf_states = vh264mvc_vf_states, -}; - -static struct vframe_provider_s vh264mvc_vf_prov; - -static u32 frame_width, frame_height, frame_dur; -static u32 saved_resolution; -static struct timer_list recycle_timer; -static u32 stat; -static u32 pts_outside; -static u32 sync_outside; -static u32 vh264mvc_ratio; -static u32 h264mvc_ar; -static u32 no_dropping_cnt; -static s32 init_drop_cnt; - -#ifdef DEBUG_SKIP -static unsigned long view_total, view_dropped; -#endif - -#ifdef DEBUG_PTS -static unsigned long pts_missed, pts_hit; -#endif - -static atomic_t vh264mvc_active = ATOMIC_INIT(0); -static struct work_struct error_wd_work; - -static struct dec_sysinfo vh264mvc_amstream_dec_info; -static dma_addr_t mc_dma_handle; -static void *mc_cpu_addr; - -static DEFINE_SPINLOCK(lock); - -static int vh264mvc_stop(void); -static s32 vh264mvc_init(void); - -/*************************** -* new -***************************/ - -/* 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 CANVAS_START AV_SCRATCH_6 -#define BUFFER_RECYCLE AV_SCRATCH_7 -#define DROP_CONTROL AV_SCRATCH_8 -#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 SIM_RESERV_D AV_SCRATCH_D -#define WORKSPACE_START AV_SCRATCH_E -#define SIM_RESERV_F AV_SCRATCH_F -#define DECODE_ERROR_CNT AV_SCRATCH_G -#define CURRENT_UCODE AV_SCRATCH_H -#define CURRENT_SPS_PPS AV_SCRATCH_I/* bit[15:9]-SPS, bit[8:0]-PPS */ -#define DECODE_SKIP_PICTURE AV_SCRATCH_J -#define UCODE_START_ADDR AV_SCRATCH_K -#define SIM_RESERV_L AV_SCRATCH_L -#define REF_START_VIEW_0 AV_SCRATCH_M -#define REF_START_VIEW_1 AV_SCRATCH_N - -/******************************************** - * Mailbox command - ********************************************/ -#define CMD_FINISHED 0 -#define CMD_ALLOC_VIEW_0 1 -#define CMD_ALLOC_VIEW_1 2 -#define CMD_FRAME_DISPLAY 3 -#define CMD_FATAL_ERROR 4 - -#define CANVAS_INDEX_START 0x78 -/* /AMVDEC_H264MVC_CANVAS_INDEX */ - -#define MC_TOTAL_SIZE (28*SZ_1K) -#define MC_SWAP_SIZE (4*SZ_1K) - -unsigned DECODE_BUFFER_START = 0x00200000; -unsigned DECODE_BUFFER_END = 0x05000000; - -#define DECODE_BUFFER_NUM_MAX 16 -#define DISPLAY_BUFFER_NUM 4 - -static unsigned int ANC_CANVAS_ADDR; -static unsigned int index; -static unsigned int dpb_start_addr[3]; -static unsigned int ref_start_addr[2]; -static unsigned int max_dec_frame_buffering[2]; -static unsigned int total_dec_frame_buffering[2]; -static unsigned int level_idc, max_reference_frame_num, mb_width, mb_height; -static unsigned int dpb_size, ref_size; - -static int display_buff_id; -static int display_view_id; -static int display_POC; -static int stream_offset; - -#define video_domain_addr(adr) (adr&0x7fffffff) -static unsigned work_space_adr; -static unsigned work_space_size = 0xa0000; - -struct buffer_spec_s { - unsigned int y_addr; - unsigned int u_addr; - unsigned int v_addr; - - int y_canvas_index; - int u_canvas_index; - int v_canvas_index; -}; -static struct buffer_spec_s buffer_spec0[DECODE_BUFFER_NUM_MAX + - DISPLAY_BUFFER_NUM]; -static struct buffer_spec_s buffer_spec1[DECODE_BUFFER_NUM_MAX + - DISPLAY_BUFFER_NUM]; - -/* - dbg_mode: - bit 0: 1, print debug information - bit 4: 1, recycle buffer without displaying; - bit 5: 1, buffer single frame step , set dbg_cmd to 1 to step - -*/ -static int dbg_mode; -static int dbg_cmd; -static int view_mode = - 3; /* 0, left; 1 ,right ; 2, left<->right 3, right<->left */ -static int drop_rate = 2; -static int drop_thread_hold; -/**/ -#define MVC_BUF_NUM (DECODE_BUFFER_NUM_MAX+DISPLAY_BUFFER_NUM) -struct mvc_buf_s { - struct list_head list; - struct vframe_s vframe; - int display_POC; - int view0_buff_id; - int view1_buff_id; - int view0_drop; - int view1_drop; - int stream_offset; - unsigned pts; -} /*mvc_buf_t */; - -#define spec2canvas(x) \ - (((x)->v_canvas_index << 16) | \ - ((x)->u_canvas_index << 8) | \ - ((x)->y_canvas_index << 0)) - -#define to_mvcbuf(vf) \ - container_of(vf, struct mvc_buf_s, vframe) - -static int vf_buf_init_flag; - -static void init_vf_buf(void) -{ - - vf_buf_init_flag = 1; -} - -static void uninit_vf_buf(void) -{ - -} - -/* #define QUEUE_SUPPORT */ - -struct mvc_info_s { - int view0_buf_id; - int view1_buf_id; - int view0_drop; - int view1_drop; - int display_pos; - int used; - int slot; - unsigned stream_offset; -}; - -#define VF_POOL_SIZE 20 -static struct vframe_s vfpool[VF_POOL_SIZE]; -static struct mvc_info_s vfpool_idx[VF_POOL_SIZE]; -static s32 view0_vfbuf_use[DECODE_BUFFER_NUM_MAX]; -static s32 view1_vfbuf_use[DECODE_BUFFER_NUM_MAX]; - -static s32 fill_ptr, get_ptr, putting_ptr, put_ptr; -static s32 dirty_frame_num; -static s32 enable_recycle; - -static s32 init_drop_frame_id[INIT_DROP_FRAME_CNT]; -#define INCPTR(p) ptr_atomic_wrap_inc(&p) -static inline void ptr_atomic_wrap_inc(u32 *ptr) -{ - u32 i = *ptr; - - i++; - - if (i >= VF_POOL_SIZE) - i = 0; - - *ptr = i; -} - -static void set_frame_info(struct vframe_s *vf) -{ - unsigned int ar = 0; - - vf->width = frame_width; - vf->height = frame_height; - vf->duration = frame_dur; - vf->duration_pulldown = 0; - - if (vh264mvc_ratio == 0) { - /* always stretch to 16:9 */ - vf->ratio_control |= (0x90 << - DISP_RATIO_ASPECT_RATIO_BIT); - } else { - /* h264mvc_ar = ((float)frame_height/frame_width) - *customer_ratio; */ - ar = min_t(u32, h264mvc_ar, DISP_RATIO_ASPECT_RATIO_MAX); - - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); - } - - return; -} - -static int vh264mvc_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - int i; - spin_lock_irqsave(&lock, flags); - states->vf_pool_size = VF_POOL_SIZE; - - i = put_ptr - fill_ptr; - if (i < 0) - i += VF_POOL_SIZE; - states->buf_free_num = i; - - i = putting_ptr - put_ptr; - if (i < 0) - i += VF_POOL_SIZE; - states->buf_recycle_num = i; - - i = fill_ptr - get_ptr; - if (i < 0) - i += VF_POOL_SIZE; - states->buf_avail_num = i; - - spin_unlock_irqrestore(&lock, flags); - return 0; -} - -void send_drop_cmd(void) -{ - int ready_cnt = 0; - int temp_get_ptr = get_ptr; - int temp_fill_ptr = fill_ptr; - while (temp_get_ptr != temp_fill_ptr) { - if ((vfpool_idx[temp_get_ptr].view0_buf_id >= 0) - && (vfpool_idx[temp_get_ptr].view1_buf_id >= 0) - && (vfpool_idx[temp_get_ptr].view0_drop == 0) - && (vfpool_idx[temp_get_ptr].view1_drop == 0)) - ready_cnt++; - INCPTR(temp_get_ptr); - } - if (dbg_mode & 0x40) { - pr_info("ready_cnt is %d ; no_dropping_cnt is %d\n", ready_cnt, - no_dropping_cnt); - } - if ((no_dropping_cnt >= DROPPING_FIRST_WAIT) - && (ready_cnt < drop_thread_hold)) - WRITE_VREG(DROP_CONTROL, (1 << 31) | (drop_rate)); - else - WRITE_VREG(DROP_CONTROL, 0); -} - -#if 0 -int get_valid_frame(void) -{ - int ready_cnt = 0; - int temp_get_ptr = get_ptr; - int temp_fill_ptr = fill_ptr; - while (temp_get_ptr != temp_fill_ptr) { - if ((vfpool_idx[temp_get_ptr].view0_buf_id >= 0) - && (vfpool_idx[temp_get_ptr].view1_buf_id >= 0) - && (vfpool_idx[temp_get_ptr].view0_drop == 0) - && (vfpool_idx[temp_get_ptr].view1_drop == 0)) - ready_cnt++; - INCPTR(temp_get_ptr); - } - return ready_cnt; -} -#endif -static struct vframe_s *vh264mvc_vf_peek(void *op_arg) -{ - - if (get_ptr == fill_ptr) - return NULL; - send_drop_cmd(); - return &vfpool[get_ptr]; - -} - -static struct vframe_s *vh264mvc_vf_get(void *op_arg) -{ - - struct vframe_s *vf; - int view0_buf_id; - int view1_buf_id; - if (get_ptr == fill_ptr) - return NULL; - - view0_buf_id = vfpool_idx[get_ptr].view0_buf_id; - view1_buf_id = vfpool_idx[get_ptr].view1_buf_id; - vf = &vfpool[get_ptr]; - - if ((view0_buf_id >= 0) && (view1_buf_id >= 0)) { - if (view_mode == 0 || view_mode == 1) { - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - 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; - - vf->left_eye.start_x = 0; - vf->left_eye.start_y = 0; - vf->left_eye.width = vf->width; - vf->left_eye.height = vf->height; - vf->right_eye.start_x = 0; - 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; - - if (view_mode == 2) { - vf->canvas0Addr = - spec2canvas(&buffer_spec1[ - view1_buf_id]); - vf->canvas1Addr = - spec2canvas(&buffer_spec0[ - view0_buf_id]); - } else { - 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)) - && ((no_dropping_cnt >= DROPPING_FIRST_WAIT))) - vf->frame_dirty = 1; - else - vf->frame_dirty = 0; - - INCPTR(get_ptr); - - if (vf) { - if (frame_width == 0) - frame_width = vh264mvc_amstream_dec_info.width; - if (frame_height == 0) - frame_height = vh264mvc_amstream_dec_info.height; - - vf->width = frame_width; - vf->height = frame_height; - } - if ((no_dropping_cnt < DROPPING_FIRST_WAIT) && (vf->frame_dirty == 0)) - no_dropping_cnt++; - return vf; - -} - -static void vh264mvc_vf_put(struct vframe_s *vf, void *op_arg) -{ - - if (vf_buf_init_flag == 0) - return; - if (vf->frame_dirty) { - - vf->frame_dirty = 0; - dirty_frame_num++; - enable_recycle = 0; - if (dbg_mode & PUT_PRINT_ENABLE) { - pr_info("invalid: dirty_frame_num is !!! %d\n", - dirty_frame_num); - } - } else { - INCPTR(putting_ptr); - while (dirty_frame_num > 0) { - INCPTR(putting_ptr); - dirty_frame_num--; - } - enable_recycle = 1; - if (dbg_mode & PUT_PRINT_ENABLE) { - pr_info("valid: dirty_frame_num is @@@ %d\n", - dirty_frame_num); - } - /* send_drop_cmd(); */ - } - -} - -static int vh264mvc_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(&vh264mvc_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vh264mvc_local_init(); - vh264mvc_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vh264mvc_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -/**/ -static long init_canvas(int start_addr, long dpb_size, int dpb_number, - int mb_width, int mb_height, - struct buffer_spec_s *buffer_spec) -{ - - int dpb_addr, addr; - int i; - int mb_total; - - /* cav_con canvas; */ - - dpb_addr = start_addr; - - mb_total = mb_width * mb_height; - - for (i = 0; i < dpb_number; i++) { - WRITE_VREG(ANC_CANVAS_ADDR, - index | ((index + 1) << 8) | - ((index + 2) << 16)); - ANC_CANVAS_ADDR++; - - addr = dpb_addr; - 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].u_addr = addr; - buffer_spec[i].u_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].v_addr = addr; - buffer_spec[i].v_canvas_index = index; - canvas_config(index, - addr, - mb_width << 3, - mb_height << 3, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - - addr += mb_total << 6; - index++; - - dpb_addr = dpb_addr + dpb_size; - if (dpb_addr >= DECODE_BUFFER_END) - return -1; - } - - return dpb_addr; -} - -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: - size = 70778880; - break; - default: - break; - } - - size /= pic_size; - size = size + 1; /* For MVC need onr 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; -} - -int check_in_list(int pos, int *slot) -{ - int i; - int ret = 0; - for (i = 0; i < VF_POOL_SIZE; i++) { - if ((vfpool_idx[i].display_pos == pos) - && (vfpool_idx[i].used == 0)) { - ret = 1; - *slot = vfpool_idx[i].slot; - break; - } - } - return ret; -} - -#ifdef HANDLE_h264mvc_IRQ -static irqreturn_t vh264mvc_isr(int irq, void *dev_id) -#else -static void vh264mvc_isr(void) -#endif -{ - int drop_status; - struct vframe_s *vf; - unsigned int pts, pts_valid = 0; - u64 pts_us64; - int ret = READ_VREG(MAILBOX_COMMAND); - /* pr_info("vh264mvc_isr, cmd =%x\n", ret); */ - switch (ret & 0xff) { - case CMD_ALLOC_VIEW_0: - if (dbg_mode & 0x1) { - pr_info - ("Start H264 display buffer allocation for view 0\n"); - } - if ((dpb_start_addr[0] != -1) | (dpb_start_addr[1] != -1)) { - dpb_start_addr[0] = -1; - dpb_start_addr[1] = -1; - } - dpb_start_addr[0] = DECODE_BUFFER_START; - ret = READ_VREG(MAILBOX_DATA_0); - level_idc = (ret >> 24) & 0xff; - max_reference_frame_num = (ret >> 16) & 0xff; - mb_width = (ret >> 8) & 0xff; - mb_height = (ret >> 0) & 0xff; - max_dec_frame_buffering[0] = - get_max_dec_frame_buf_size(level_idc, - max_reference_frame_num, - mb_width, mb_height); - - total_dec_frame_buffering[0] = - max_dec_frame_buffering[0] + DISPLAY_BUFFER_NUM; - - 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; - - if (dbg_mode & 0x1) { - pr_info("dpb_size: 0x%x\n", dpb_size); - pr_info("ref_size: 0x%x\n", ref_size); - pr_info("total_dec_frame_buffering[0] : 0x%x\n", - total_dec_frame_buffering[0]); - pr_info("max_reference_frame_num: 0x%x\n", - max_reference_frame_num); - } - ref_start_addr[0] = dpb_start_addr[0] + - (dpb_size * total_dec_frame_buffering[0]); - dpb_start_addr[1] = ref_start_addr[0] + - (ref_size * (max_reference_frame_num + 1)); - - if (dbg_mode & 0x1) { - pr_info("dpb_start_addr[0]: 0x%x\n", dpb_start_addr[0]); - pr_info("ref_start_addr[0]: 0x%x\n", ref_start_addr[0]); - pr_info("dpb_start_addr[1]: 0x%x\n", dpb_start_addr[1]); - } - if (dpb_start_addr[1] >= DECODE_BUFFER_END) { - pr_info(" No enough memory for alloc view 0\n"); - goto exit; - } - - index = CANVAS_INDEX_START; - ANC_CANVAS_ADDR = ANC0_CANVAS_ADDR; - - ret = - init_canvas(dpb_start_addr[0], dpb_size, - total_dec_frame_buffering[0], mb_width, - mb_height, buffer_spec0); - - if (ret == -1) { - pr_info(" Un-expected memory alloc problem\n"); - goto exit; - } - - WRITE_VREG(REF_START_VIEW_0, - video_domain_addr(ref_start_addr[0])); - WRITE_VREG(MAILBOX_DATA_0, - (max_dec_frame_buffering[0] << 8) | - (total_dec_frame_buffering[0] << 0) - ); - WRITE_VREG(MAILBOX_DATA_1, ref_size); - WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); - - if (dbg_mode & 0x1) { - pr_info - ("End H264 display buffer allocation for view 0\n"); - } - if (frame_width == 0) { - if (vh264mvc_amstream_dec_info.width) - frame_width = vh264mvc_amstream_dec_info.width; - else - frame_width = mb_width << 4; - } - if (frame_height == 0) { - frame_height = mb_height << 4; - if (frame_height == 1088) - frame_height = 1080; - } - break; - case CMD_ALLOC_VIEW_1: - if (dbg_mode & 0x1) { - pr_info - ("Start H264 display buffer allocation for view 1\n"); - } - if ((dpb_start_addr[0] == -1) | (dpb_start_addr[1] == -1)) { - pr_info("Error: allocation view 1 before view 0 !!!\n"); - break; - } - ret = READ_VREG(MAILBOX_DATA_0); - level_idc = (ret >> 24) & 0xff; - max_reference_frame_num = (ret >> 16) & 0xff; - mb_width = (ret >> 8) & 0xff; - mb_height = (ret >> 0) & 0xff; - max_dec_frame_buffering[1] = - get_max_dec_frame_buf_size(level_idc, - max_reference_frame_num, - mb_width, mb_height); - if (max_dec_frame_buffering[1] != max_dec_frame_buffering[0]) { - pr_info - (" Warning: view0/1 max_dec_frame_buffering "); - pr_info("different : 0x%x/0x%x, Use View0\n", - max_dec_frame_buffering[0], - max_dec_frame_buffering[1]); - max_dec_frame_buffering[1] = max_dec_frame_buffering[0]; - } - - total_dec_frame_buffering[1] = - max_dec_frame_buffering[1] + DISPLAY_BUFFER_NUM; - - 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; - - if (dbg_mode & 0x1) { - pr_info("dpb_size: 0x%x\n", dpb_size); - pr_info("ref_size: 0x%x\n", ref_size); - pr_info("total_dec_frame_buffering[1] : 0x%x\n", - total_dec_frame_buffering[1]); - pr_info("max_reference_frame_num: 0x%x\n", - max_reference_frame_num); - } - ref_start_addr[1] = dpb_start_addr[1] + - (dpb_size * total_dec_frame_buffering[1]); - dpb_start_addr[2] = ref_start_addr[1] + - (ref_size * (max_reference_frame_num + 1)); - - if (dbg_mode & 0x1) { - pr_info("dpb_start_addr[1]: 0x%x\n", dpb_start_addr[1]); - pr_info("ref_start_addr[1]: 0x%x\n", ref_start_addr[1]); - pr_info("dpb_start_addr[2]: 0x%x\n", dpb_start_addr[2]); - } - if (dpb_start_addr[2] >= DECODE_BUFFER_END) { - pr_info(" No enough memory for alloc view 1\n"); - goto exit; - } - - index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3; - ANC_CANVAS_ADDR = - ANC0_CANVAS_ADDR + total_dec_frame_buffering[0]; - - ret = - init_canvas(dpb_start_addr[1], dpb_size, - total_dec_frame_buffering[1], mb_width, - mb_height, buffer_spec1); - - if (ret == -1) { - pr_info(" Un-expected memory alloc problem\n"); - goto exit; - } - - WRITE_VREG(REF_START_VIEW_1, - video_domain_addr(ref_start_addr[1])); - WRITE_VREG(MAILBOX_DATA_0, - (max_dec_frame_buffering[1] << 8) | - (total_dec_frame_buffering[1] << 0) - ); - WRITE_VREG(MAILBOX_DATA_1, ref_size); - WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); - - if (dbg_mode & 0x1) { - pr_info - ("End H264 display buffer allocation for view 1\n"); - } - if (frame_width == 0) { - if (vh264mvc_amstream_dec_info.width) - frame_width = vh264mvc_amstream_dec_info.width; - else - frame_width = mb_width << 4; - } - if (frame_height == 0) { - frame_height = mb_height << 4; - if (frame_height == 1088) - frame_height = 1080; - } - break; - case CMD_FRAME_DISPLAY: - ret = READ_VREG(MAILBOX_DATA_0); - display_buff_id = (ret >> 0) & 0x3f; - display_view_id = (ret >> 6) & 0x3; - drop_status = (ret >> 8) & 0x1; - display_POC = READ_VREG(MAILBOX_DATA_1); - stream_offset = READ_VREG(MAILBOX_DATA_2); - /* if (display_view_id == 0) */ - WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED); - -#ifdef DEBUG_SKIP - view_total++; - if (drop_status) - view_dropped++; -#endif - if (dbg_mode & 0x1) { - pr_info - (" H264 display frame ready - View : %x, Buffer : %x\n", - display_view_id, display_buff_id); - pr_info - (" H264 display frame POC -- Buffer : %x, POC : %x\n", - display_buff_id, display_POC); - pr_info("H264 display frame ready\n"); - } - if (dbg_mode & 0x10) { - if ((dbg_mode & 0x20) == 0) { - while (READ_VREG(BUFFER_RECYCLE) != 0) - ; - WRITE_VREG(BUFFER_RECYCLE, - (display_view_id << 8) | - (display_buff_id + 1)); - display_buff_id = -1; - display_view_id = -1; - display_POC = -1; - } - } else { - unsigned char in_list_flag = 0; - - int slot = 0; - in_list_flag = check_in_list(display_POC, &slot); - - if ((dbg_mode & 0x40) && (drop_status)) { - pr_info - ("drop_status:%dview_id=%d,buff_id=%d,", - drop_status, display_view_id, display_buff_id); - pr_info - ("offset=%d, display_POC = %d,fill_ptr=0x%x\n", - stream_offset, display_POC, fill_ptr); - } - - if ((in_list_flag) && (stream_offset != 0)) { - pr_info - ("error case ,display_POC is %d, slot is %d\n", - display_POC, slot); - in_list_flag = 0; - } - if (!in_list_flag) { - if (display_view_id == 0) { - vfpool_idx[fill_ptr].view0_buf_id = - display_buff_id; - view0_vfbuf_use[display_buff_id]++; - vfpool_idx[fill_ptr].stream_offset = - stream_offset; - vfpool_idx[fill_ptr].view0_drop = - drop_status; - } - if (display_view_id == 1) { - vfpool_idx[fill_ptr].view1_buf_id = - display_buff_id; - vfpool_idx[fill_ptr].view1_drop = - drop_status; - view1_vfbuf_use[display_buff_id]++; - } - vfpool_idx[fill_ptr].slot = fill_ptr; - vfpool_idx[fill_ptr].display_pos = display_POC; - - } else { - if (display_view_id == 0) { - vfpool_idx[slot].view0_buf_id = - display_buff_id; - view0_vfbuf_use[display_buff_id]++; - vfpool_idx[slot].stream_offset = - stream_offset; - vfpool_idx[slot].view0_drop = - drop_status; - - } - if (display_view_id == 1) { - vfpool_idx[slot].view1_buf_id = - display_buff_id; - view1_vfbuf_use[display_buff_id]++; - vfpool_idx[slot].view1_drop = - drop_status; - } - vf = &vfpool[slot]; -#if 0 - if (pts_lookup_offset - (PTS_TYPE_VIDEO, - vfpool_idx[slot].stream_offset, - &vf->pts, - 0) != 0) - vf->pts = 0; -#endif - if (vfpool_idx[slot].stream_offset == 0) { - pr_info - ("error case, invalid stream offset\n"); - } - if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, - vfpool_idx[slot].stream_offset, &pts, - 0x10000, &pts_us64) == 0) - pts_valid = 1; - else - pts_valid = 0; - vf->pts = (pts_valid) ? pts : 0; - vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - /* vf->pts = vf->pts_us64 ? vf->pts_us64 - : vf->pts ; */ - /* vf->pts = vf->pts_us64; */ - if (dbg_mode & 0x80) - pr_info("vf->pts:%d\n", vf->pts); - vfpool_idx[slot].used = 1; - INCPTR(fill_ptr); - set_frame_info(vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - } - } - break; - case CMD_FATAL_ERROR: - pr_info("fatal error !!!\n"); - schedule_work(&error_wd_work); - break; - default: - break; - } -exit: -#ifdef HANDLE_h264mvc_IRQ - return IRQ_HANDLED; -#else - return; -#endif -} - -static void vh264mvc_put_timer_func(unsigned long arg) -{ - struct timer_list *timer = (struct timer_list *)arg; - - int valid_frame = 0; - if (enable_recycle == 0) { - if (dbg_mode & TIME_TASK_PRINT_ENABLE) { - /* valid_frame = get_valid_frame(); */ - pr_info("dirty_frame_num is %d , valid frame is %d\n", - dirty_frame_num, valid_frame); - - } - /* goto RESTART; */ - } - - while ((putting_ptr != put_ptr) && (READ_VREG(BUFFER_RECYCLE) == 0)) { - int view0_buf_id = vfpool_idx[put_ptr].view0_buf_id; - int view1_buf_id = vfpool_idx[put_ptr].view1_buf_id; - if ((view0_buf_id >= 0) && - (view0_vfbuf_use[view0_buf_id] == 1)) { - if (dbg_mode & 0x100) { - pr_info - ("round 0: put_ptr is %d ;view0_buf_id is %d\n", - put_ptr, view0_buf_id); - } - WRITE_VREG(BUFFER_RECYCLE, - (0 << 8) | (view0_buf_id + 1)); - view0_vfbuf_use[view0_buf_id] = 0; - vfpool_idx[put_ptr].view0_buf_id = -1; - vfpool_idx[put_ptr].view0_drop = 0; - } else if ((view1_buf_id >= 0) - && (view1_vfbuf_use[view1_buf_id] == 1)) { - if (dbg_mode & 0x100) { - pr_info - ("round 1: put_ptr is %d ;view1_buf_id %d==\n", - put_ptr, view1_buf_id); - } - WRITE_VREG(BUFFER_RECYCLE, - (1 << 8) | (view1_buf_id + 1)); - view1_vfbuf_use[view1_buf_id] = 0; - vfpool_idx[put_ptr].display_pos = DISPLAY_INVALID_POS; - vfpool_idx[put_ptr].view1_buf_id = -1; - vfpool_idx[put_ptr].view1_drop = 0; - vfpool_idx[put_ptr].used = 0; - INCPTR(put_ptr); - } - } - - - 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_H264MVC, - frame_width, frame_height, fps * 2); - } - - /* RESTART: */ - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vh264mvc_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; - vstatus->height = frame_height; - if (frame_dur != 0) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = READ_VREG(AV_SCRATCH_D); - vstatus->status = stat; - return 0; -} - -int vh264mvc_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) -{ - if (trickmode == TRICKMODE_I) { - WRITE_VREG(AV_SCRATCH_F, - (READ_VREG(AV_SCRATCH_F) & 0xfffffffc) | 2); - trickmode_i = 1; - } else if (trickmode == TRICKMODE_NONE) { - WRITE_VREG(AV_SCRATCH_F, READ_VREG(AV_SCRATCH_F) & 0xfffffffc); - trickmode_i = 0; - } - - return 0; -} - -static void H264_DECODE_INIT(void) -{ - int i; - i = READ_VREG(DECODE_SKIP_PICTURE); - -#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_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - READ_MPEG_REG(RESET0_REGISTER); - WRITE_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - WRITE_MPEG_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); -#endif - - /* Wait for some time for RESET */ - READ_VREG(DECODE_SKIP_PICTURE); - READ_VREG(DECODE_SKIP_PICTURE); - - WRITE_VREG(DECODE_SKIP_PICTURE, i); - - /* 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); - /* disable COEF_GT_64 , error_m4_table and voff_rw_err */ - 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 */ - - /* 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)); -#if 0 - WRITE_VREG(POWER_CTL_VLD, - READ_VREG(POWER_CTL_VLD) | (0 << 10) | - (1 << 9) | (1 << 6)); -#else - WRITE_VREG(POWER_CTL_VLD, ((1 << 10) | /* disable cabac_step_2 */ - (1 << 9) | /* viff_drop_flag_en */ - (1 << 6) /* h264_000003_en */ - ) - ); -#endif - WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */ - - WRITE_VREG(CANVAS_START, CANVAS_INDEX_START); -#if 1 - /* Start Address of Workspace (UCODE, temp_data...) */ - WRITE_VREG(WORKSPACE_START, - video_domain_addr(work_space_adr)); -#else - /* Start Address of Workspace (UCODE, temp_data...) */ - WRITE_VREG(WORKSPACE_START, - 0x05000000); -#endif - /* 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 vh264mvc_prot_init(void) -{ - while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) - ; - while (READ_VREG(LMEM_DMA_CTRL) & 0x8000) - ; /* reg address is 0x350 */ - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - H264_DECODE_INIT(); - -#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - 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); - -#else - WRITE_MPEG_REG(RESET0_REGISTER, 0x80); /* RESET MCPU */ -#endif - - WRITE_VREG(MAILBOX_COMMAND, 0); - WRITE_VREG(BUFFER_RECYCLE, 0); - WRITE_VREG(DROP_CONTROL, 0); - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); -#endif -} - -static void vh264mvc_local_init(void) -{ - int i; - display_buff_id = -1; - display_view_id = -1; - display_POC = -1; - no_dropping_cnt = 0; - init_drop_cnt = INIT_DROP_FRAME_CNT; - - for (i = 0; i < INIT_DROP_FRAME_CNT; i++) - init_drop_frame_id[i] = 0; - -#ifdef DEBUG_PTS - pts_missed = 0; - pts_hit = 0; -#endif - -#ifdef DEBUG_SKIP - view_total = 0; - view_dropped = 0; -#endif - - /* vh264mvc_ratio = vh264mvc_amstream_dec_info.ratio; */ - vh264mvc_ratio = 0x100; - - /* frame_width = vh264mvc_amstream_dec_info.width; */ - /* frame_height = vh264mvc_amstream_dec_info.height; */ - frame_dur = vh264mvc_amstream_dec_info.rate; - if (frame_dur == 0) - frame_dur = 96000 / 24; - - pts_outside = ((unsigned long) vh264mvc_amstream_dec_info.param) & 0x01; - sync_outside = ((unsigned long) vh264mvc_amstream_dec_info.param & 0x02) - >> 1; - - /**/ dpb_start_addr[0] = -1; - dpb_start_addr[1] = -1; - max_dec_frame_buffering[0] = -1; - 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; - } - - for (i = 0; i < VF_POOL_SIZE; i++) { - vfpool_idx[i].display_pos = -1; - vfpool_idx[i].view0_buf_id = DISPLAY_INVALID_POS; - vfpool_idx[i].view1_buf_id = -1; - vfpool_idx[i].view0_drop = 0; - vfpool_idx[i].view1_drop = 0; - vfpool_idx[i].used = 0; - } - for (i = 0; i < VF_POOL_SIZE; i++) - memset(&vfpool[i], 0, sizeof(struct vframe_s)); - init_vf_buf(); - return; -} - -static s32 vh264mvc_init(void) -{ - int ret = -1, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - pr_info("\nvh264mvc_init\n"); - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - vh264mvc_local_init(); - - 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_mvc init: Can not allocate mc memory.\n"); - return -ENOMEM; - } - - WRITE_VREG(UCODE_START_ADDR, mc_dma_handle); - - size = get_firmware_data(VIDEO_DEC_H264_MVC, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf); - - /*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); - - vfree(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; - return -EBUSY; - } - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vh264mvc_prot_init(); - -#ifdef HANDLE_h264mvc_IRQ - if (vdec_request_irq(VDEC_IRQ_1, vh264mvc_isr, - "vh264mvc-irq", (void *)vh264mvc_dec_id)) { - pr_info("vh264mvc irq register error.\n"); - amvdec_disable(); - return -ENOENT; - } -#endif - - stat |= STAT_ISR_REG; - - vf_provider_init(&vh264mvc_vf_prov, PROVIDER_NAME, - &vh264mvc_vf_provider, NULL); - vf_reg_provider(&vh264mvc_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); - - 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; - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int vh264mvc_stop(void) -{ - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - WRITE_VREG(ASSIST_MBOX1_MASK, 0); -#ifdef HANDLE_h264mvc_IRQ - vdec_free_irq(VDEC_IRQ_1, (void *)vh264mvc_dec_id); -#endif - stat &= ~STAT_ISR_REG; - } - - if (stat & STAT_TIMER_ARM) { - del_timer_sync(&recycle_timer); - stat &= ~STAT_TIMER_ARM; - } - - if (stat & STAT_VF_HOOK) { - ulong flags; - spin_lock_irqsave(&lock, flags); - spin_unlock_irqrestore(&lock, flags); - vf_unreg_provider(&vh264mvc_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - 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(); - - uninit_vf_buf(); - return 0; -} - -static void error_do_work(struct work_struct *work) -{ - if (atomic_read(&vh264mvc_active)) { - vh264mvc_stop(); - vh264mvc_init(); - } -} - -static int amvdec_h264mvc_probe(struct platform_device *pdev) -{ - struct resource mem; - int buf_size; - - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - pr_info("amvdec_h264mvc probe start.\n"); - -#if 0 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - pr_info("\namvdec_h264mvc memory resource undefined.\n"); - return -EFAULT; - } -#endif - - if (pdata == NULL) { - pr_info("\namvdec_h264mvc memory resource undefined.\n"); - return -EFAULT; - } - mem.start = pdata->mem_start; - mem.end = pdata->mem_end; - - buf_size = mem.end - mem.start + 1; - /* buf_offset = mem->start - DEF_BUF_START_ADDR; */ - work_space_adr = mem.start; - DECODE_BUFFER_START = work_space_adr + work_space_size; - DECODE_BUFFER_END = mem.start + buf_size; - - pr_info - ("work_space_adr %x, DECODE_BUFFER_START %x, DECODE_BUFFER_END %x\n", - work_space_adr, DECODE_BUFFER_START, DECODE_BUFFER_END); - if (pdata->sys_info) - vh264mvc_amstream_dec_info = *pdata->sys_info; - - pdata->dec_status = vh264mvc_dec_status; - /* pdata->set_trickmode = vh264mvc_set_trickmode; */ - - if (vh264mvc_init() < 0) { - pr_info("\namvdec_h264mvc init failed.\n"); - - return -ENODEV; - } - - INIT_WORK(&error_wd_work, error_do_work); - - atomic_set(&vh264mvc_active, 1); - - pr_info("amvdec_h264mvc probe end.\n"); - - return 0; -} - -static int amvdec_h264mvc_remove(struct platform_device *pdev) -{ - pr_info("amvdec_h264mvc_remove\n"); - cancel_work_sync(&error_wd_work); - vh264mvc_stop(); - frame_width = 0; - frame_height = 0; - vdec_source_changed(VFORMAT_H264MVC, 0, 0, 0); - atomic_set(&vh264mvc_active, 0); - -#ifdef DEBUG_PTS - pr_info - ("pts missed %ld, pts hit %ld, pts_outside %d, ", - pts_missed, pts_hit, pts_outside); - pr_info("duration %d, sync_outside %d\n", - frame_dur, sync_outside); -#endif - -#ifdef DEBUG_SKIP - pr_info("view_total = %ld, dropped %ld\n", view_total, view_dropped); -#endif - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_hmvc_profile = { - .name = "hmvc", - .profile = "" -}; - -static int __init amvdec_h264mvc_driver_init_module(void) -{ - pr_debug("amvdec_h264mvc module init\n"); - - if (platform_driver_register(&amvdec_h264mvc_driver)) { - pr_err("failed to register amvdec_h264mvc driver\n"); - return -ENODEV; - } - - vcodec_profile_register(&amvdec_hmvc_profile); - - return 0; -} - -static void __exit amvdec_h264mvc_driver_remove_module(void) -{ - pr_debug("amvdec_h264mvc module remove.\n"); - - platform_driver_unregister(&amvdec_h264mvc_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_h264mvc stat\n"); - -module_param(dbg_mode, uint, 0664); -MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc dbg mode\n"); - -module_param(view_mode, uint, 0664); -MODULE_PARM_DESC(view_mode, "\n amvdec_h264mvc view mode\n"); - -module_param(dbg_cmd, uint, 0664); -MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc cmd mode\n"); - -module_param(drop_rate, uint, 0664); -MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc drop rate\n"); - -module_param(drop_thread_hold, uint, 0664); -MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc drop thread hold\n"); -module_init(amvdec_h264mvc_driver_init_module); -module_exit(amvdec_h264mvc_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC h264mvc Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Chen Zhang <chen.zhang@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/h264_multi/Makefile b/drivers/frame_provider/decoder/h264_multi/Makefile deleted file mode 100644 index 17cb87e..0000000 --- a/drivers/frame_provider/decoder/h264_multi/Makefile +++ b/dev/null @@ -1,2 +0,0 @@ -obj-m += vh264_multi.o -vh264_multi-objs += vmh264.o h264_dpb.o diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c deleted file mode 100644 index b3e8f0f..0000000 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/dev/null @@ -1,5238 +0,0 @@ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../utils/vdec.h" -#include "../utils/amvdec.h" - -#include "h264_dpb.h" - -/* #define OLD_OUTPUT_CODE */ -#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[512]; - int len = 0; - va_list args; - va_start(args, fmt); - if ((index & 0x100) == 0) - len = sprintf(buf, "%d: ", index); - vsnprintf(buf + len, 512-len, fmt, args); - pr_info("%s", buf); - va_end(args); - } - 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; \ - } \ - } - -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 dump_dpb(struct DecodedPictureBuffer *p_Dpb); - -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_ERROR, - "%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_ERROR, - "%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]; - sps->num_ref_frames = p_H264_Dpb-> - dpb_param.l.data[MAX_REFERENCE_FRAME_NUM]; - 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); - - 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; - } - /* pSlice->adaptive_ref_pic_buffering_flag; */ - sps->log2_max_frame_num_minus4 = - p_H264_Dpb->dpb_param.l.data[LOG2_MAX_FRAME_NUM] - 4; - - 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]=%d, num_ref_idx_active[1]=%d nal_reference_idc %d\n", - __func__, pSlice->slice_type, - pSlice->num_ref_idx_active[LIST_0], - pSlice->num_ref_idx_active[LIST_1], - pSlice->nal_reference_idc); -#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; - if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) - pSlice->num_ref_idx_active[LIST_1] = MAX_LIST_SIZE - 1; -#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 - 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 == FALSE) { - /* 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 == FALSE) { - /* 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 == FALSE) - 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]; - 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) { - /*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); - return; - } - - picture->colocated_buf_index = -1; - picture->buf_spec_num = -1; - - 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; - - store_picture_in_dpb(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; -} - -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); - } - -} - -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->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; -#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; - - 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]"); */ - } - } - } - } - 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) -{ - 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 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 (%d) num_ref_frames = %d (%d)\n", - __func__, p_Dpb->size, active_sps->max_dpb_size, - p_Dpb->num_ref_frames, - 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; -#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; -#endif - - - 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; - 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; - } - - 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; - /* 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) -{ - 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); -#if 1 -/* rain */ -/* p->buf_spec_num = fs->index; */ - fs->buf_spec_num = p->buf_spec_num; - fs->colocated_buf_index = p->colocated_buf_index; -#endif - switch (p->structure) { - case FRAME: - fs->frame = p; - fs->is_used = 3; - 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->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 (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 (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; - - 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; -} - -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->frame = NULL; - f->top_field = NULL; - f->bottom_field = NULL; - - /* free(f); */ - } -} - -static 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; - -} - -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 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 Slice *currSlice) -{ - unsigned int i; - 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++) { - 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++) { - 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++) { - 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) { - 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) { - 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++) { - if (p_Dpb->fs_ltref[i]->is_long_term & 1) { - 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) { - 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 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->is_used = 0; - fs->is_long_term = 0; - fs->is_reference = 0; - fs->is_orig_reference = 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; - p_Dpb->used_size--; -} - -static 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 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; -} - -void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - int ret = 0; - unsigned char print_flag = 0; - do { - ret = remove_unused_frame_from_dpb(p_H264_Dpb); - if (ret != 0) - print_flag = 1; - } while (ret != 0); - if (print_flag) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, "%s\r\n", __func__); - dump_dpb(p_Dpb); - } -} - -#ifdef OUTPUT_BUFFER_IN_C -int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned 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 i; - 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__); - 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; - 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; - } - } -} - -#ifdef OLD_OUTPUT_CODE -static int output_one_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb) -{ - struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; - int poc, pos; - /* diagnostics */ - 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 output frame, DPB empty. %d\n", 150); - } - - /* find smallest POC */ - get_smallest_poc(p_Dpb, &poc, &pos); - - if (pos == -1) - return 0; - - /* call the output function */ - /* dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "output frame with frame_num #%d, poc %d" - "(dpb. p_Dpb->size = %d, p_Dpb->used_size = %d)\n", - p_Dpb->fs[pos]->frame_num, p_Dpb->fs[pos]->frame->poc, - p_Dpb->size, p_Dpb->used_size); - */ - -#if 0 - /* ??? */ - /* picture error concealment */ - if (p_Vid->conceal_mode != 0) { - if (p_Dpb->last_output_poc == 0) - write_lost_ref_after_idr(p_Dpb, pos); -#if (MVC_EXTENSION_ENABLE) - write_lost_non_ref_pic(p_Dpb, poc, - p_Vid->p_out_mvc[p_Dpb->layer_id]); -#else - write_lost_non_ref_pic(p_Dpb, poc, p_Vid->p_out); -#endif - } -#endif -/* JVT-P072 ends */ - -#if 0 -/* ??? */ -#if (MVC_EXTENSION_ENABLE) - write_stored_frame(p_Vid, p_Dpb->fs[pos], - p_Vid->p_out_mvc[p_Dpb->layer_id]); -#else - write_stored_frame(p_Vid, p_Dpb->fs[pos], p_Vid->p_out); -#endif -#endif - /* picture error concealment */ - if (p_Vid->conceal_mode == 0) { - if (p_Dpb->last_output_poc >= poc) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "output POC must be in ascending order %d\n", - 150); - } - } - - p_Dpb->last_output_poc = poc; - - /* free frame store and move empty store to end of buffer */ -/* #ifdef OUTPUT_BUFFER_IN_C */ - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - if (prepare_display_buf(p_H264_Dpb->vdec, - p_Dpb->fs[pos]) >= 0) { - p_Dpb->fs[pos]->pre_output = 1; - } - } -/* #else */ - else { - if (!is_used_for_reference(p_Dpb->fs[pos])) { - release_colocate_buf(p_H264_Dpb, - p_Dpb->fs[pos]->colocated_buf_index); /*rain*/ - p_Dpb->fs[pos]->colocated_buf_index = -1; - - release_buf_spec_num(p_H264_Dpb->vdec, - p_Dpb->fs[pos]->buf_spec_num); - p_Dpb->fs[pos]->buf_spec_num = -1; - - remove_frame_from_dpb(p_H264_Dpb, pos); - } -/* #endif */ - } - return 1; -} - -#else -/* none OLD_OUTPUT_CODE */ - -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; - 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)) - none_displayed_num++; - } - if (none_displayed_num < p_H264_Dpb->reorder_pic_num) - 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 - p_Dpb->last_output_poc = poc; - - if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) - p_Dpb->fs[pos]->pre_output = 1; - - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s[%d] poc %d\n", __func__, pos, poc); - - return 1; - -} -#endif - - -static 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 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]); - - if (h264_debug_flag & OUTPUT_CURRENT_BUF) - set_frame_output_flag(p_H264_Dpb, i); - - } - - while (remove_unused_frame_from_dpb(p_H264_Dpb)) - ; - - /* output frames in POC order */ -#ifndef OLD_OUTPUT_CODE - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - while (output_frames(p_H264_Dpb, 1)) - ; - } -#else - while (p_Dpb->used_size && output_one_frame_from_dpb(p_H264_Dpb)) - ; -#endif - - 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; -} - -static void update_ref_list(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned 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 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 %d %d\n", __func__, p_Dpb->ref_frames_in_buffer, - p_Dpb->ltref_frames_in_buffer); - - if (p->no_output_of_prior_pics_flag) { -#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 i; - struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb, - struct h264_dpb_stru, mDPB); - - /* assert (!p->idr_flag); */ - dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s\n", __func__); - - /* if this is a reference pic with sliding window, - unmark first ref frame */ - if (p_Dpb->ref_frames_in_buffer == imax( - 1, p_Dpb->num_ref_frames) - p_Dpb->ltref_frames_in_buffer) { - 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); - } -} - -static void dump_dpb(struct DecodedPictureBuffer *p_Dpb) -{ - unsigned i; - struct h264_dpb_stru *p_H264_Dpb = - container_of(p_Dpb, struct h264_dpb_stru, mDPB); - if ((h264_debug_flag & PRINT_FLAG_DUMP_DPB) == 0) - return; - for (i = 0; i < p_Dpb->used_size; i++) { - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB, - "("); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "fn=%d ", p_Dpb->fs[i]->frame_num); - if (p_Dpb->fs[i]->is_used & 1) { - if (p_Dpb->fs[i]->top_field) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "T: poc=%d ", - p_Dpb->fs[i]->top_field->poc); - else - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "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_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "B: poc=%d ", - p_Dpb->fs[i]->bottom_field->poc); - else - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "B: poc=%d ", - p_Dpb->fs[i]->frame->bottom_poc); - } - if (p_Dpb->fs[i]->is_used == 3) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "F: poc=%d ", - p_Dpb->fs[i]->frame->poc); - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "G: poc=%d) ", p_Dpb->fs[i]->poc); - if (p_Dpb->fs[i]->is_reference) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "ref (%d) ", p_Dpb->fs[i]->is_reference); - if (p_Dpb->fs[i]->is_long_term) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "lt_ref (%d) ", p_Dpb->fs[i]->is_reference); - if (p_Dpb->fs[i]->is_output) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "out "); - if (p_Dpb->fs[i]->pre_output) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "for_out "); - if (p_Dpb->fs[i]->is_used == 3) { - if (p_Dpb->fs[i]->frame->non_existing) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "ne "); - } -#if (MVC_EXTENSION_ENABLE) - if (p_Dpb->fs[i]->is_reference) - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "view_id (%d) ", p_Dpb->fs[i]->view_id); -#endif - dpb_print(p_H264_Dpb->decoder_index, - PRINT_FLAG_DUMP_DPB | 0x100, - "\n"); - } -} - - -/*! - ************************************************************************ - * \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) -{ - 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++) { - if (p->structure == FRAME) { - if ((p_Dpb->fs_ref[i]->is_reference == 3) && - (p_Dpb->fs_ref[i]->is_long_term == 0)) { - 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))) { - 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) { - 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))) { - 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) { - p_Dpb->fs_ref[i]->frame-> - used_for_reference = 0; - } - return; - } - } - } - } -} - -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 - * 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 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)(curr_pic_num >> 1)) - unmark_for_long_term_reference(p_Dpb->fs_ltref[i]); -} - -static void unmark3_top(struct DecodedPictureBuffer *p_Dpb, - unsigned 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 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 curr_frame_num, - int curr_pic_num) -{ - struct VideoParameters *p_Vid = p_Dpb->p_Vid; - unsigned 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++) { - if (p_Dpb->fs_ref[i]->is_reference == 3) { - 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++) { - if (p_Dpb->fs_ref[i]->is_reference & 1) { - 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) { - 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) { - 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) { - 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 i; - enum PictureStructure structure = FRAME; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_reference & 1) { - if (p_Dpb->fs_ref[i]->top_field-> - pic_num == picNumX) { - structure = TOP_FIELD; - break; - } - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { - 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 - } -} - - -void store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p) -{ - /* 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 i; -#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 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); - update_ref_list(p_Dpb); - update_ltref_list(p_Dpb); - dump_dpb(p_Dpb); - p_Dpb->last_picture = NULL; - return; - } - } - } - } - } - /* 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; - } - -#ifndef OLD_OUTPUT_CODE - while (remove_unused_frame_from_dpb(p_H264_Dpb)) - ; - - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - while (output_frames(p_H264_Dpb, 0)) - ; - } -#else - /* OLD_OUTPUT_CODE */ - - /* first try to remove unused frames */ - if (p_Dpb->used_size == p_Dpb->size) { -#if 0 - /* ??? */ - /* picture error concealment */ - if (p_Vid->conceal_mode != 0) - conceal_non_ref_pics(p_Dpb, 2); -#endif - remove_unused_frame_from_dpb(p_H264_Dpb); - -#if 0 - /* ??? */ - if (p_Vid->conceal_mode != 0) - sliding_window_poc_management(p_Dpb, p); -#endif - } - - /* then output frames until one can be removed */ -/* #ifdef OUTPUT_BUFFER_IN_C */ - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - if (p_Dpb->used_size > (p_Dpb->size - 5)) - output_one_frame_from_dpb(p_H264_Dpb); - } else { -/* #else */ - while (p_Dpb->used_size == p_Dpb->size) { -#if 0 - /* non-reference frames may be output directly */ - if (!p->used_for_reference) { - get_smallest_poc(p_Dpb, &poc, &pos); - if ((-1 == pos) || (p->poc < poc)) { -#if (MVC_EXTENSION_ENABLE) - if (p_Vid->profile_idc >= MVC_HIGH) - dpb_print( - p_H264_Dpb->decoder_index, - PRINT_FLAG_DPB_DETAIL, - "Display order might not be correct, %d, %d\n", - p->view_id, p->poc); -#endif -#if 0 -/* ??? */ -#if (MVC_EXTENSION_ENABLE) - direct_output(p_Vid, p, p_Vid-> - p_out_mvc[p_Dpb->layer_id]); -#else - direct_output(p_Vid, p, p_Vid->p_out); -#endif -#endif - return; - } - } -#endif - /* flush a frame */ - output_one_frame_from_dpb(p_H264_Dpb); - } - - } -/* #endif */ - /* OLD_OUTPUT_CODE */ -#endif - - /* 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++) { - 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); - } - } - } - /* 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); - return; - } - - insert_picture_in_dpb(p_H264_Dpb, p_Dpb->fs[p_Dpb->used_size], p); - if (h264_debug_flag & OUTPUT_CURRENT_BUF) { - prepare_display_buf(p_H264_Dpb->vdec, - p_Dpb->fs[p_Dpb->used_size]); - set_frame_output_flag(p_H264_Dpb, p_Dpb->used_size); - - } - - /* 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); - - dump_dpb(p_Dpb); -} - -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++) { - 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 (NULL == fs_list0) - no_mem_exit("init_lists: fs_list0"); - fs_listlt = calloc(p_Dpb->size, sizeof(struct FrameStore *)); - if (NULL == fs_listlt) - 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++) { - 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 VideoParameters *p_Vid, - struct Slice *currSlice) -{ - unsigned j; - int i; - - 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) { - 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) { - 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++) { - 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++) { - 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 (NULL == fs_list0) - no_mem_exit("init_lists: fs_list0"); - fs_list1 = calloc(p_Dpb->size, - sizeof(struct FrameStore *)); - if (NULL == fs_list1) - no_mem_exit("init_lists: fs_list1"); - fs_listlt = calloc(p_Dpb->size, - sizeof(struct FrameStore *)); - if (NULL == fs_listlt) - 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++) { - 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++) { - 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 i; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (currSlice->structure == FRAME) { - if (p_Dpb->fs_ref[i]->is_reference == 3) - 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 { - if (p_Dpb->fs_ref[i]->is_reference & 1) - 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) - 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-> - 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-> - 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-> - 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)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(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"); - } - } - - 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++) { - 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"); - } - } - - /* 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; - 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; - dump_dpb(p_Dpb); -} - -#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 = FALSE; - - 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 |= (NULL == dec_picture); - - 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 - -int remove_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); - } - free_picture(p_H264_Dpb, pic); - return 0; -} - -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->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 new_pic_flag = 0; - struct Slice *currSlice = &p_H264_Dpb->mSlice; - struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo; -#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 - - slice_prepare(p_H264_Dpb, &p_H264_Dpb->mDPB, &p_H264_Dpb->mVideo, - &p_H264_Dpb->mSPS, &p_H264_Dpb->mSlice); - - /* 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 && - currSlice->frame_num != p_Vid->pre_frame_num && - currSlice->frame_num != - (p_Vid->pre_frame_num + 1) % p_Vid->max_frame_num) { - /*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)*/ - fill_frame_num_gap(p_Vid, currSlice); - } - - 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) { - 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 */ - p_H264_Dpb->mVideo.dec_picture->offset_delimiter_lo = - p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_LO]; - p_H264_Dpb->mVideo.dec_picture->offset_delimiter_hi = - p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_HI]; - - 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->mSlice); - - 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-> - used_for_reference) { - p_H264_Dpb->mVideo.dec_picture-> - colocated_buf_index = - allocate_colocate_buf( - p_H264_Dpb); - } - } -#endif - } - } - - 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->mVideo, &p_H264_Dpb->mSlice); - - if (new_pic_flag) - return 1; - - return 0; -} diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h deleted file mode 100644 index e58f084..0000000 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/dev/null @@ -1,788 +0,0 @@ -#ifndef H264_DPB_H_ -#define H264_DPB_H_ - -#define ERROR_CHECK - -#define OUTPUT_BUFFER_IN_C - -#define PRINT_FLAG_ERROR 0x0 -#define PRINT_FLAG_DPB 0X0001 -#define PRINT_FLAG_DPB_DETAIL 0x0002 -#define PRINT_FLAG_DUMP_DPB 0x0004 -#define PRINT_FLAG_UCODE_EVT 0x0008 -#define PRINT_FLAG_VDEC_STATUS 0x0010 -#define PRINT_FLAG_VDEC_DETAIL 0x0020 -#define PRINT_FLAG_UCODE_DBG 0x0040 -#define PRINT_FLAG_TIME_STAMP 0x0080 -#define PRINT_FLAG_RUN_SCHEDULE 0x0100 -#define PRINT_FLAG_DEBUG_POC 0x0200 -#define PRINT_FLAG_VDEC_DATA 0x0400 -#define DISABLE_ERROR_HANDLE 0x10000 -#define OUTPUT_CURRENT_BUF 0x20000 -#define ONLY_RESET_AT_START 0x40000 -#define LOAD_UCODE_ALWAYS 0x80000 -#define FORCE_NO_SLICE 0x100000 -#define REINIT_DPB_TEST 0x200000 - - -#define MVC_EXTENSION_ENABLE 0 -#define PRINTREFLIST 0 - -#define MAX_LIST_SIZE 33 - -#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_DECODE_BUFEMPTY 0x20 -#define H264_DECODE_TIMEOUT 0x21 -#define H264_SEARCH_BUFEMPTY 0x22 - /* 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 { -#define H_TIME_STAMP_START 0X00 -#define H_TIME_STAMP_END 0X17 -#define PTS_ZERO_0 0X18 -#define PTS_ZERO_1 0X19 -#define FIXED_FRAME_RATE_FLAG 0X1A - -#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 -#define POC_SELECT_NEED_SWAP 0X6C -#define POC_SELECT_SWAP 0X6D -#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]; - } 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 -}; - -#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 -}; - -struct SPSParameters { - 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; -}; - -#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]; -}; - -struct OldSliceParams { - unsigned field_pic_flag; - unsigned frame_num; - int nal_ref_idc; - unsigned 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 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 PicWidthInMbs; - unsigned 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; - - int offset_delimiter_lo; - int offset_delimiter_hi; - - u32 pts; - u64 pts64; -}; - -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 frame_num; - unsigned 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; -#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 pts; - u64 pts64; -}; - -int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame); - - -/* #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 size; - unsigned used_size; - unsigned ref_frames_in_buffer; - unsigned 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 num_ref_frames; - - struct FrameStore *last_picture; - unsigned 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 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]; - -}; - - -extern unsigned int h264_debug_flag; -extern unsigned int h264_debug_mask; - -int dpb_print(int indext, 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); - -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); - -void store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *p); - -int remove_picture(struct h264_dpb_stru *p_H264_Dpb, - struct StorablePicture *pic); - -void bufmgr_post(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); - -#endif diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c deleted file mode 100644 index 59b7457..0000000 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/dev/null @@ -1,2776 +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. - * -*/ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/kfifo.h> -#include <linux/platform_device.h> - -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/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 "../utils/vdec_input.h" - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../utils/vdec.h" -#include "../utils/amvdec.h" -#include "../h264/vh264.h" -#include "../../../stream_input/parser/streambuf.h" -#include <linux/delay.h> - -#undef pr_info -#define pr_info printk - -#define DEBUG_UCODE -#define USE_CMA -#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" -#define MODULE_NAME "ammvdec_h264" - -#define CHECK_INTERVAL (HZ/100) - -#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 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 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 H264_DEV_NUM 5 - -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 unsigned int dec_control; -static unsigned int force_rate_streambase; -static unsigned int force_rate_framebase; -static unsigned int fixed_frame_rate_mode; -static unsigned int error_recovery_mode_in; -static unsigned int start_decode_buf_level = 0x8000; - -static unsigned int reorder_dpb_size_margin = 6; -static unsigned int reference_buf_margin = 4; - -static unsigned int decode_timeout_val = 50; -static unsigned int radr; -static unsigned int rval; -static unsigned int max_decode_instance_num = H264_DEV_NUM; -static unsigned int decode_frame_count[H264_DEV_NUM]; -static unsigned int max_process_time[H264_DEV_NUM]; -static unsigned int max_get_frame_interval[H264_DEV_NUM]; - /* bit[3:0]: - 0, run ; 1, pause; 3, step - bit[4]: - 1, schedule run - */ -static unsigned int step[H264_DEV_NUM]; - -#define is_in_parsing_state(status) \ - ((status == H264_ACTION_SEARCH_HEAD) || \ - ((status & 0xf0) == 0x80)) - -static inline bool close_to(int a, int b, int m) -{ - return (abs(a - b) < m) ? true : false; -} - -/* #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 0x1000000 -#define V_BUF_ADDR_OFFSET (0x13e000) - -#define PIC_SINGLE_FRAME 0 -#define PIC_TOP_BOT_TOP 1 -#define PIC_BOT_TOP_BOT 2 -#define PIC_DOUBLE_FRAME 3 -#define PIC_TRIPLE_FRAME 4 -#define PIC_TOP_BOT 5 -#define PIC_BOT_TOP 6 -#define PIC_INVALID 7 - -#define EXTEND_SAR 0xff - -#define VF_POOL_SIZE 64 -#define MAX_VF_BUF_NUM 28 -#define PUT_INTERVAL (HZ/100) -#define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL) - -#define SWITCHING_STATE_OFF 0 -#define SWITCHING_STATE_ON_CMD3 1 -#define SWITCHING_STATE_ON_CMD1 2 - -#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001 -#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002 - -#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: - 0, free; 1, used by dpb; 2, - used for display; - 3 isolated (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 NV21 - struct canvas_config_s canvas_config[2]; -#else - struct canvas_config_s canvas_config[3]; -#endif -#ifdef USE_CMA - /* struct page *cma_alloc_pages; */ - unsigned long cma_alloc_addr; - int cma_alloc_count; -#endif - unsigned int buf_adr; -}; - -#define spec2canvas(x) \ - (((x)->v_canvas_index << 16) | \ - ((x)->u_canvas_index << 8) | \ - ((x)->y_canvas_index << 0)) - -static struct vframe_s *vh264_vf_peek(void *); -static struct vframe_s *vh264_vf_get(void *); -static void vh264_vf_put(struct vframe_s *, void *); -static int vh264_vf_states(struct vframe_states *states, void *); -static int vh264_event_cb(int type, void *data, void *private_data); -static void vh264_work(struct work_struct *work); - -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 - -/* -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_INFO M4_CONTROL_REG /* 0xc29 */ -#define DPB_STATUS_REG AV_SCRATCH_J -#define MBY_MBX MB_MOTION_MODE /*0xc07*/ - -struct vdec_h264_hw_s { - spinlock_t lock; - - struct platform_device *platform_dev; - struct device *cma_dev; - /* struct page *cma_alloc_pages; */ - unsigned long cma_alloc_addr; - int cma_alloc_count; - /* struct page *collocate_cma_alloc_pages; */ - unsigned long collocate_cma_alloc_addr; - int collocate_cma_alloc_count; - - ulong lmem_addr; - dma_addr_t lmem_addr_remap; - - DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - - struct vframe_s vfpool[VF_POOL_SIZE]; - struct buffer_spec_s buffer_spec[MAX_VF_BUF_NUM]; - int buffer_spec_num; - struct vframe_s switching_fense_vf; - struct h264_dpb_stru dpb; - u8 init_flag; - u8 set_params_done; - u32 max_reference_size; - u32 decode_pic_count; - int start_search_pos; - - 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 timing_info_present_flag; - u32 fixed_frame_rate_flag; - u32 fixed_frame_rate_check_count; - 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 duration_on_correcting; - u32 last_checkout_pts; - u32 fatal_error_flag; - u32 fatal_error_reset; - 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 saved_resolution; - 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; - - void *sei_data_buffer; - dma_addr_t sei_data_buffer_phys; - - uint error_recovery_mode; - uint mb_total; - uint mb_width; - uint mb_height; - - uint ucode_type; - dma_addr_t mc_dma_handle; - void *mc_cpu_addr; - int vh264_reset; - - atomic_t vh264_active; - - struct dec_sysinfo vh264_amstream_dec_info; - - struct work_struct error_wd_work; - - int dec_result; - struct work_struct work; - - void (*vdec_cb)(struct vdec_s *, void *); - void *vdec_cb_arg; - - struct timer_list check_timer; - - /**/ - unsigned last_frame_time; - - /* timeout handle */ - unsigned long int start_process_time; - unsigned last_mby_mbx; - unsigned last_ucode_watchdog_reg_val; - unsigned decode_timeout_count; - unsigned timeout_num; - unsigned search_dataempty_num; - unsigned decode_timeout_num; - unsigned decode_dataempty_num; - unsigned buffer_empty_recover_num; - - /**/ - - /*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; -}; - - -static void vh264_local_init(struct vdec_h264_hw_s *hw); -static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw); -static int vh264_stop(struct vdec_h264_hw_s *hw, int mode); -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); - -unsigned char have_free_buf_spec(struct vdec_s *vdec) -{ - int i; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - if ((h264_debug_flag&OUTPUT_CURRENT_BUF) == 0) { - for (i = 0; i < hw->buffer_spec_num; i++) { - if (hw->buffer_spec[i].used == 0) - return 1; - } - return 0; - } else - return 1; -} - -#if 0 -static void buf_spec_recover(struct vdec_h264_hw_s *hw) -{ /* do not clear buf_spec used by display */ - int i; - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_DPB, "%s\n", __func__); - for (i = 0; i < hw->buffer_spec_num; i++) { - if (hw->buffer_spec[i].used == 2) - hw->buffer_spec[i].used = 3; - else - hw->buffer_spec[i].used = 0; - } -} -#endif - -int get_free_buf_idx(struct vdec_s *vdec) -{ - int i; - int index = -1; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - if ((h264_debug_flag&OUTPUT_CURRENT_BUF) == 0) { - for (i = hw->start_search_pos; i < hw->buffer_spec_num; i++) { - if (hw->buffer_spec[i].used == 0) { - hw->buffer_spec[i].used = 1; - hw->start_search_pos = i+1; - index = i; - break; - } - } - if (index < 0) { - for (i = 0; i < hw->start_search_pos; i++) { - if (hw->buffer_spec[i].used == 0) { - hw->buffer_spec[i].used = 1; - hw->start_search_pos = i+1; - index = i; - break; - } - } - } - } else { - index = hw->start_search_pos; - hw->start_search_pos++; - } - - if (hw->start_search_pos >= hw->buffer_spec_num) - hw->start_search_pos = 0; - - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s, buf_spec_num %d\n", __func__, index); - - return index; -} - -int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s buf_spec_num %d\n", - __func__, buf_spec_num); - if (buf_spec_num >= 0 && buf_spec_num < hw->buffer_spec_num) - hw->buffer_spec[buf_spec_num].used = 0; - return 0; -} - -static int get_buf_spec_idx_by_canvas_config(struct vdec_h264_hw_s *hw, - struct canvas_config_s *cfg) -{ - int i; - for (i = 0; i < hw->buffer_spec_num; i++) { - if (hw->buffer_spec[i].canvas_config[0].phy_addr - == cfg->phy_addr) - return i; - } - return -1; -} - -int prepare_display_buf(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; - - if (kfifo_get(&hw->newframe_q, &vf) == 0) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s fatal error, no available buffer slot.\n", - __func__); - return -1; - } - - if (vf) { - int buffer_index = frame->buf_spec_num; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_DPB_DETAIL, - "%s, fs[%d] poc %d, buf_spec_num %d\n", - __func__, frame->index, frame->poc, - frame->buf_spec_num); - vf->index = frame->index; - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; - vf->duration_pulldown = 0; - vf->pts = frame->pts; - vf->pts_us64 = frame->pts64; - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(&hw->buffer_spec[buffer_index]); - set_frame_info(hw, vf, buffer_index); - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - hw->buffer_spec[buffer_index].used = 2; - - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - decode_frame_count[hw->dpb.decoder_index]++; - } - - 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) -{ - dpb_print(decindex, PRINT_FLAG_UCODE_EVT, - "%s: %s (original %s), %s, mb_aff_frame_flag %d poc %d, pic_num %d, buf_spec_num %d\n", - info, - picture_structure_name[pic->structure], - pic->coded_frame ? "Frame" : "Field", - (slice_type < 0) ? "" : slice_type_name[slice_type], - pic->mb_aff_frame_flag, - pic->poc, - pic->pic_num, - pic->buf_spec_num); -} - -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[hw->dpb.decoder_index]) - max_process_time[hw->dpb.decoder_index] = process_time; - } -} - -void config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic) -{ - /* static int count = 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; - -#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 */ - - unsigned long canvas_adr; - unsigned ref_reg_val; - unsigned one_ref_cfg = 0; - int h264_buffer_info_data_write_count; - int i, j; - unsigned colocate_wr_adr; - unsigned colocate_rd_adr; - unsigned char use_direct_8x8; - - 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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s: pic_num is %d, poc is %d (%d, %d, %d), buf_spec_num %d\n", - __func__, pic->pic_num, pic->poc, pic->frame_poc, - pic->top_poc, pic->bottom_poc, pic->buf_spec_num); - print_pic_info(hw->dpb.decoder_index, "cur", pic, pSlice->slice_type); - - WRITE_VREG(CURR_CANVAS_CTRL, pic->buf_spec_num << 24); - - canvas_adr = READ_VREG(CURR_CANVAS_CTRL) & 0xffffff; - - WRITE_VREG(REC_CANVAS_ADDR, canvas_adr); - WRITE_VREG(DBKR_CANVAS_ADDR, canvas_adr); - WRITE_VREG(DBKW_CANVAS_ADDR, canvas_adr); - - 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 (i = 0; i < hw->buffer_spec_num; i++) { - int 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 */ - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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; - - for (i = 0; i < (unsigned int)(pSlice->listXsize[0]); i++) { - /*ref list 0 */ - struct StorablePicture *ref = pSlice->listX[0][i]; - unsigned cfg; - /* bit[6:5] - frame/field info, - * 01 - top, 10 - bottom, 11 - frame - */ -#ifdef ERROR_CHECK - if (ref == NULL) - return; -#endif - if (ref->structure == TOP_FIELD) - cfg = 0x1; - else if (ref->structure == BOTTOM_FIELD) - cfg = 0x2; - else /* FRAME */ - cfg = 0x3; - one_ref_cfg = (ref->buf_spec_num & 0x1f) | (cfg << 5); - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - - if (j == 4) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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(hw->dpb.decoder_index, "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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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 cfg; - /* bit[6:5] - frame/field info, - * 01 - top, 10 - bottom, 11 - frame - */ -#ifdef ERROR_CHECK - if (ref == NULL) - return; -#endif - if (ref->structure == TOP_FIELD) - cfg = 0x1; - else if (ref->structure == BOTTOM_FIELD) - cfg = 0x2; - else /* FRAME */ - cfg = 0x3; - one_ref_cfg = (ref->buf_spec_num & 0x1f) | (cfg << 5); - ref_reg_val <<= 8; - ref_reg_val |= one_ref_cfg; - j++; - - if (j == 4) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "H264_BUFFER_INFO_DATA: %x\n", - ref_reg_val); - WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val); - j = 0; - } - print_pic_info(hw->dpb.decoder_index, "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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, index is %d\n", - pic->colocated_buf_index); - val = colocate_wr_adr + colocate_adr_offset; - WRITE_VREG(H264_CO_MB_WR_ADDR, val); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "WRITE_VREG(H264_CO_MB_WR_ADDR) = 0xffffffff\n"); - } -#else - 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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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 * pic->buf_spec_num) >> - (use_direct_8x8 ? 2 : 0)); - - if ((colocate_wr_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, pic index is %d\n", - pic->buf_spec_num); - val = colocate_wr_adr + colocate_adr_offset; - WRITE_VREG(H264_CO_MB_WR_ADDR, val); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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; - 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; -#ifdef ERROR_CHECK - if (colocate_pic == NULL) - return; -#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; - } -#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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - " 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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - " 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(hw->dpb.decoder_index, - PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, index is %d\n", - colocate_pic->colocated_buf_index); - /* 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_adr_offset) >> 3) | - (l10_structure << 30) | - (cur_colocate_ref_type << 29); - WRITE_VREG(H264_CO_MB_RD_ADDR, val); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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_adr_offset, - colocate_pic->structure, - colocate_pic->mb_aff_frame_flag); - } else - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "Error, reference pic has no colocated buf\n"); -#else - colocate_rd_adr = p_H264_Dpb->colocated_mv_addr_start + - ((p_H264_Dpb->colocated_buf_size * - colocate_pic->buf_spec_num) - >> (use_direct_8x8 ? 2 : 0)); - if ((colocate_rd_adr + p_H264_Dpb->colocated_buf_size) > - p_H264_Dpb->colocated_mv_addr_end) - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "Error, colocate buf is not enough, pic index is %d\n", - colocate_pic->buf_spec_num); - /* 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_adr_offset)>>3) | - (l10_structure << 30) | (cur_colocate_ref_type << 29); - WRITE_VREG(H264_CO_MB_RD_ADDR, val); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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 - } -} - -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; - struct vdec_s *vdec = op_arg; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - if (!hw) - return NULL; - - if (kfifo_peek(&hw->display_q, &vf)) - return vf; - - 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; - - if (!hw) - return NULL; - - if (kfifo_get(&hw->display_q, &vf)) { - int time = jiffies; - unsigned int frame_interval = - 1000*(time - hw->last_frame_time)/HZ; - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s from fs[%d], poc %d buf_spec_num %d vf %p\n", - __func__, vf->index, - p_H264_Dpb->mFrameStore[vf->index].poc, - p_H264_Dpb->mFrameStore[vf->index] - .buf_spec_num, vf); - } - if (hw->last_frame_time > 0) { - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_TIME_STAMP, - "%s duration %d pts %d interval %dms\r\n", - __func__, vf->duration, vf->pts, frame_interval); - if (frame_interval > - max_get_frame_interval[hw->dpb.decoder_index]) - max_get_frame_interval[hw->dpb.decoder_index] - = frame_interval; - } - hw->last_frame_time = time; - return vf; - } - - return NULL; -} - -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; - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int buf_spec_num; - - if ((h264_debug_flag & OUTPUT_CURRENT_BUF) == 0) { - buf_spec_num = - get_buf_spec_idx_by_canvas_config(hw, - &vf->canvas0_config[0]); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s to fs[%d], poc %d buf_spec_num %d used %d\n", - __func__, vf->index, - p_H264_Dpb->mFrameStore[vf->index].poc, - buf_spec_num, - hw->buffer_spec[buf_spec_num].used); - - if (hw->buffer_spec[buf_spec_num].used != 3) - set_frame_output_flag(&hw->dpb, vf->index); - } - - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - -#define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG - if (hw->buffer_empty_flag) - WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1); -} - -static int vh264_event_cb(int type, void *data, void *private_data) -{ - return 0; -} - -static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf, - u32 index) -{ - int force_rate = input_frame_based(hw_to_vdec(hw)) ? - force_rate_framebase : force_rate_streambase; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s (%d,%d) dur %d, vf %p, index %d\n", __func__, - hw->frame_width, hw->frame_height, hw->frame_dur, vf, index); - - 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->flag = 0; - - vf->canvas0Addr = vf->canvas1Addr = -1; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->plane_num = 3; -#endif - vf->canvas0_config[0] = hw->buffer_spec[index].canvas_config[0]; - vf->canvas0_config[1] = hw->buffer_spec[index].canvas_config[1]; -#ifndef NV21 - vf->canvas0_config[2] = hw->buffer_spec[index].canvas_config[2]; -#endif - vf->canvas1_config[0] = hw->buffer_spec[index].canvas_config[0]; - vf->canvas1_config[1] = hw->buffer_spec[index].canvas_config[1]; -#ifndef NV21 - vf->canvas1_config[2] = hw->buffer_spec[index].canvas_config[2]; -#endif - - return; -} - -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; - - return size; -} - -static int vh264_set_params(struct vdec_h264_hw_s *hw) -{ - int mb_width, mb_total; - int max_reference_size, level_idc; - int i, mb_height, addr; - int mb_mv_byte; - struct vdec_s *vdec = hw_to_vdec(hw); - int reg_val; - int ret = 0; -#ifdef USE_CMA - unsigned int buf_size; -#endif - - if (hw->set_params_done) { - WRITE_VREG(AV_SCRATCH_0, - (hw->max_reference_size << 24) | - (hw->buffer_spec_num << 16) | - (hw->buffer_spec_num << 8)); - return 0; - } - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, "%s\n", - __func__); - -#ifndef USE_CMA - addr = hw->buf_start; -#endif - - /* Read AV_SCRATCH_1 */ - reg_val = READ_VREG(AV_SCRATCH_1); - hw->seq_info = READ_VREG(AV_SCRATCH_2); - hw->num_units_in_tick = READ_VREG(AV_SCRATCH_4); - hw->time_scale = READ_VREG(AV_SCRATCH_5); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, "get %x\n", - reg_val); - mb_mv_byte = (reg_val & 0x80000000) ? 24 : 96; - - mb_width = reg_val & 0xff; - mb_total = (reg_val >> 8) & 0xffff; - if (!mb_width && mb_total) /*for 4k2k*/ - mb_width = 256; - - mb_height = mb_total/mb_width; -#if 1 - /* if (hw->frame_width == 0 || hw->frame_height == 0) { */ - hw->frame_width = mb_width * 16; - hw->frame_height = mb_height * 16; - /* } */ - - if (hw->frame_dur == 0) - hw->frame_dur = 96000 / 30; -#endif - - mb_width = (mb_width+3) & 0xfffffffc; - mb_height = (mb_height+3) & 0xfffffffc; - mb_total = mb_width * mb_height; - - reg_val = READ_VREG(AV_SCRATCH_B); - level_idc = reg_val & 0xff; - max_reference_size = (reg_val >> 8) & 0xff; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "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); - - - hw->mb_total = mb_total; - hw->mb_width = mb_width; - hw->mb_height = mb_height; - - hw->dpb.reorder_pic_num = - get_max_dec_frame_buf_size(level_idc, - max_reference_size, mb_width, mb_height); - hw->buffer_spec_num = - hw->dpb.reorder_pic_num - + reorder_dpb_size_margin; - hw->max_reference_size = max_reference_size + reference_buf_margin; - - if (hw->buffer_spec_num > MAX_VF_BUF_NUM) { - hw->buffer_spec_num = MAX_VF_BUF_NUM; - hw->dpb.reorder_pic_num = hw->buffer_spec_num - - reorder_dpb_size_margin; - } - hw->dpb.mDPB.size = hw->buffer_spec_num; - hw->dpb.max_reference_size = hw->max_reference_size; - - pr_info("%s buf_spec_num %d reorder_pic_num %d collocate_buf_num %d\r\n", - __func__, hw->buffer_spec_num, - hw->dpb.reorder_pic_num, - hw->max_reference_size); - -#ifdef USE_CMA - buf_size = (hw->mb_total << 8) + (hw->mb_total << 7); -#endif - for (i = 0; i < hw->buffer_spec_num; i++) { - int canvas = vdec->get_canvas(i, 2); - -#ifdef USE_CMA - if (hw->buffer_spec[i].cma_alloc_count == 0) { - hw->buffer_spec[i].cma_alloc_count = - PAGE_ALIGN(buf_size) / PAGE_SIZE; - hw->buffer_spec[i].cma_alloc_addr = - codec_mm_alloc_for_dma(MEM_NAME, - hw->buffer_spec[i].cma_alloc_count, - 16, CODEC_MM_FLAGS_FOR_VDECODER); - } - - if (!hw->buffer_spec[i].cma_alloc_addr) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "CMA alloc failed, request buf size 0x%lx\n", - hw->buffer_spec[i].cma_alloc_count * PAGE_SIZE); - hw->buffer_spec[i].cma_alloc_count = 0; - ret = -1; - break; - } - hw->buffer_spec[i].buf_adr = - hw->buffer_spec[i].cma_alloc_addr; - addr = hw->buffer_spec[i].buf_adr; -#else - hw->buffer_spec[i].buf_adr = addr; -#endif - - hw->buffer_spec[i].used = 0; - 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_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); - - canvas_config(hw->buffer_spec[i].y_canvas_index, - hw->buffer_spec[i].y_addr, - hw->mb_width << 4, - hw->mb_height << 4, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - - 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 = - CANVAS_BLKMODE_32X32; - - canvas_config(hw->buffer_spec[i].u_canvas_index, - hw->buffer_spec[i].u_addr, - hw->mb_width << 4, - hw->mb_height << 3, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - - 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 = - CANVAS_BLKMODE_32X32; - - WRITE_VREG(ANC0_CANVAS_ADDR + i, - spec2canvas(&hw->buffer_spec[i])); - - pr_info("config canvas (%d)\r\n", i); - } - - -#ifdef USE_CMA - if (hw->collocate_cma_alloc_count == 0) { - hw->collocate_cma_alloc_count = - PAGE_ALIGN(hw->mb_total * mb_mv_byte * - hw->max_reference_size) / PAGE_SIZE; - hw->collocate_cma_alloc_addr = - codec_mm_alloc_for_dma(MEM_NAME, - hw->collocate_cma_alloc_count, - 16, CODEC_MM_FLAGS_FOR_VDECODER); - } - - if (!hw->collocate_cma_alloc_addr) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "codec_mm alloc failed, request buf size 0x%lx\n", - hw->collocate_cma_alloc_count * PAGE_SIZE); - hw->collocate_cma_alloc_count = 0; - ret = -1; - } else { - hw->dpb.colocated_mv_addr_start = - hw->collocate_cma_alloc_addr; - hw->dpb.colocated_mv_addr_end = - hw->dpb.colocated_mv_addr_start + - (hw->mb_total * mb_mv_byte * hw->max_reference_size); - pr_info("callocate cma %d, %lx, %x\n", - hw->collocate_cma_alloc_count, - hw->collocate_cma_alloc_addr, - hw->dpb.colocated_mv_addr_start); - } -#else - hw->dpb.colocated_mv_addr_start = addr; - hw->dpb.colocated_mv_addr_end = addr + (hw->mb_total * mb_mv_byte - * hw->max_reference_size); -#endif - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "colocated_mv_addr_start %x colocated_mv_addr_end %x\n", - hw->dpb.colocated_mv_addr_start, - hw->dpb.colocated_mv_addr_end); - - hw->timing_info_present_flag = hw->seq_info & 0x2; - hw->fixed_frame_rate_flag = 0; - if (hw->timing_info_present_flag) { - hw->fixed_frame_rate_flag = hw->seq_info & 0x40; - - 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; - pr_info("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 infomation - is more reliable - if ((frame_dur * 2) != frame_dur_es) { - frame_dur = frame_dur_es; - }*/ - } - } - } else { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "H.264: timing_info not present\n"); - } - - if (hw->pts_unstable && (hw->fixed_frame_rate_flag == 0)) { - if (((RATE_2397_FPS == hw->frame_dur) - && (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(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "force fix frame rate\n"); - hw->fixed_frame_rate_flag = 0x40; - } - } - - hw->set_params_done = 1; - - WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) | - (hw->buffer_spec_num<<16) | - (hw->buffer_spec_num<<8)); - - return ret; -} - -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; - - if ((kfifo_len(&hw->newframe_q) <= 0) || - ((hw->set_params_done) && (!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) == 0))) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%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; - - bufmgr_h264_remove_unused_frame(p_H264_Dpb); - } - - return buffer_available; -} - -static irqreturn_t vh264_isr(struct vdec_s *vdec) -{ - unsigned int dec_dpb_status; - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private); - struct h264_dpb_stru *p_H264_Dpb = &hw->dpb; - int i; - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - if (!hw) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "decoder is not running\n"); - return IRQ_HANDLED; - } - - p_H264_Dpb->vdec = vdec; - dec_dpb_status = READ_VREG(DPB_STATUS_REG); - - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s DPB_STATUS_REG: %x, sb (%x %x %x) bitcnt %x\n", - __func__, - dec_dpb_status, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), - READ_VREG(VIFF_BIT_CNT)); - - if (dec_dpb_status == H264_CONFIG_REQUEST) { - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE); -#ifdef USE_CMA - if (hw->set_params_done) { - WRITE_VREG(AV_SCRATCH_0, - (hw->max_reference_size<<24) | - (hw->buffer_spec_num<<16) | - (hw->buffer_spec_num<<8)); - } else { - hw->dec_result = DEC_RESULT_CONFIG_PARAM; - schedule_work(&hw->work); - } -#else - if (vh264_set_params(hw) < 0) { - hw->fatal_error_flag = DECODER_FATAL_ERROR_UNKNOW; - if (!hw->fatal_error_reset) - schedule_work(&hw->error_wd_work); - } -#endif - } else if (dec_dpb_status == H264_SLICE_HEAD_DONE) { - int slice_header_process_status = 0; - unsigned short *p = (unsigned short *)hw->lmem_addr; - - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, - DMA_FROM_DEVICE); -#if 0 - if (p_H264_Dpb->mVideo.dec_picture == NULL) { - if (!is_buffer_available(vdec)) { - hw->buffer_empty_flag = 1; - dpb_print(hw->dpb.decoder_index, - 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 - 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]; - } - } -#endif - dpb_print(hw->dpb.decoder_index, 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)); - - slice_header_process_status = - h264_slice_header_process(p_H264_Dpb); - - if (p_H264_Dpb->mVideo.dec_picture) { - if (slice_header_process_status == 1) { - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_UCODE_EVT, - "==================> frame count %d\n", - hw->decode_pic_count+1); - } - config_decode_buf(hw, p_H264_Dpb->mVideo.dec_picture); - } - 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_ucode_watchdog_reg_val = 0; - hw->decode_timeout_count = 2; - } else if (dec_dpb_status == H264_PIC_DATA_DONE) { - if (p_H264_Dpb->mVideo.dec_picture) { - if (hw->chunk) { - p_H264_Dpb->mVideo.dec_picture->pts = - hw->chunk->pts; - p_H264_Dpb->mVideo.dec_picture->pts64 = - hw->chunk->pts64; - } else { - struct StorablePicture *pic = - p_H264_Dpb->mVideo.dec_picture; - u32 offset = pic->offset_delimiter_lo | - (pic->offset_delimiter_hi << 16); - if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, - offset, &pic->pts, 0, &pic->pts64)) { - pic->pts = 0; - pic->pts64 = 0; - } - } - store_picture_in_dpb(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture); - - bufmgr_post(p_H264_Dpb); - - p_H264_Dpb->mVideo.dec_picture = NULL; - /* dump_dpb(&p_H264_Dpb->mDPB); */ - } - - if ((h264_debug_flag&ONLY_RESET_AT_START) == 0) - amvdec_stop(); - hw->decode_pic_count++, - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s H264_PIC_DATA_DONE decode slice count %d\n", - __func__, - hw->decode_pic_count); - /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); */ - hw->dec_result = DEC_RESULT_DONE; - reset_process_time(hw); - 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: - if (p_H264_Dpb->mVideo.dec_picture) { - remove_picture(p_H264_Dpb, - p_H264_Dpb->mVideo.dec_picture); - p_H264_Dpb->mVideo.dec_picture = NULL; - } - - if (input_frame_based(vdec) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) { - if (h264_debug_flag & - DISABLE_ERROR_HANDLE) { - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_ERROR, - "%s decoding error, level 0x%x\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL)); - goto send_again; - } - if ((h264_debug_flag & ONLY_RESET_AT_START) == 0) - amvdec_stop(); - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_UCODE_EVT, - "%s %s\n", __func__, - (dec_dpb_status == H264_SEARCH_BUFEMPTY) ? - "H264_SEARCH_BUFEMPTY" : - (dec_dpb_status == H264_DECODE_BUFEMPTY) ? - "H264_DECODE_BUFEMPTY" : "H264_DECODE_TIMEOUT"); - 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++; - else if (dec_dpb_status == H264_DECODE_BUFEMPTY) - hw->decode_dataempty_num++; - - - reset_process_time(hw); - schedule_work(&hw->work); - } else { - /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */ - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_AGAIN\n", __func__); -send_again: - hw->dec_result = DEC_RESULT_AGAIN; - schedule_work(&hw->work); - } - } else if (dec_dpb_status == H264_DATA_REQUEST) { - if (input_frame_based(vdec)) { - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_VDEC_STATUS, - "%s H264_DATA_REQUEST\n", __func__); - hw->dec_result = DEC_RESULT_GET_DATA; - schedule_work(&hw->work); - } else - goto empty_proc; - } - - /* ucode debug */ - if (READ_VREG(DEBUG_REG1) & 0x10000) { - int i; - unsigned short *p = (unsigned short *)hw->lmem_addr; - - dma_sync_single_for_cpu( - amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, - DMA_FROM_DEVICE); - - pr_info("LMEM<tag %x>:\n", READ_VREG(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 ", p[i+3-ii]); - if (((i+ii) & 0xf) == 0) - pr_info("\n"); - } - WRITE_VREG(DEBUG_REG1, 0); - } else if (READ_VREG(DEBUG_REG1) != 0) { - pr_info("dbg%x: %x\n", READ_VREG(DEBUG_REG1), - READ_VREG(DEBUG_REG2)); - WRITE_VREG(DEBUG_REG1, 0); - } - /**/ - - return IRQ_HANDLED; -} - -static void timeout_process(struct vdec_h264_hw_s *hw) -{ - hw->timeout_num++; - if ((h264_debug_flag & ONLY_RESET_AT_START) == 0) - amvdec_stop(); - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_ERROR, "%s decoder timeout\n", __func__); - hw->dec_result = DEC_RESULT_DONE; - reset_process_time(hw); - schedule_work(&hw->work); -} - -static void check_timer_func(unsigned long arg) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)arg; - - if ((h264_debug_cmd & 0x100) != 0 && - hw_to_vdec(hw)->id == (h264_debug_cmd & 0xff)) { - hw->dec_result = DEC_RESULT_DONE; - schedule_work(&hw->work); - pr_info("vdec %d is forced to be disconnected\n", - h264_debug_cmd & 0xff); - h264_debug_cmd = 0; - return; - } - - if (hw_to_vdec(hw)->next_status == VDEC_STATUS_DISCONNECTED) { - hw->dec_result = DEC_RESULT_DONE; - schedule_work(&hw->work); - pr_info("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 ((input_frame_based(hw_to_vdec(hw)) || - (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) && - ((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) && - (decode_timeout_val > 0) && - (hw->start_process_time > 0) && - ((1000 * (jiffies - hw->start_process_time) / HZ) - > decode_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)) { - if (hw->last_mby_mbx == mby_mbx) { - if (hw->decode_timeout_count > 0) - hw->decode_timeout_count--; - if (hw->decode_timeout_count == 0) - timeout_process(hw); - } - } else if (is_in_parsing_state(dpb_status)) { - if (hw->last_ucode_watchdog_reg_val == - READ_VREG(UCODE_WATCHDOG_REG)) { - if (hw->decode_timeout_count > 0) - hw->decode_timeout_count--; - if (hw->decode_timeout_count == 0) - timeout_process(hw); - } - } - hw->last_ucode_watchdog_reg_val = - READ_VREG(UCODE_WATCHDOG_REG); - hw->last_mby_mbx = mby_mbx; - } - - hw->check_timer.expires = jiffies + CHECK_INTERVAL; - - add_timer(&hw->check_timer); -} - -static int dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - vstatus->width = hw->frame_width; - vstatus->height = hw->frame_height; - if (hw->frame_dur != 0) - vstatus->fps = 96000 / hw->frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = READ_VREG(AV_SCRATCH_D); - vstatus->status = hw->stat; - /* if (fatal_error_reset) - vstatus->status |= hw->fatal_error_flag; */ - return 0; -} - -static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw) -{ - int i; - - /* if (hw->init_flag == 0) { */ - if (h264_debug_flag & 0x40000000) { - /* if (1) */ - dpb_print(hw->dpb.decoder_index, 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_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - READ_MPEG_REG(RESET0_REGISTER); - WRITE_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - - WRITE_MPEG_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 - -#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 - if (hw->decode_pic_count > 0) { - WRITE_VREG(AV_SCRATCH_7, (hw->max_reference_size << 24) | - (hw->buffer_spec_num << 16) | - (hw->buffer_spec_num << 8)); - for (i = 0; i < hw->buffer_spec_num; i++) { - canvas_config(hw->buffer_spec[i].y_canvas_index, - hw->buffer_spec[i].y_addr, - hw->mb_width << 4, - hw->mb_height << 4, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - - canvas_config(hw->buffer_spec[i].u_canvas_index, - hw->buffer_spec[i].u_addr, - hw->mb_width << 4, - hw->mb_height << 3, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - - WRITE_VREG(ANC0_CANVAS_ADDR + i, - spec2canvas(&hw->buffer_spec[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); - 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, (READ_VREG(AV_SCRATCH_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_addr_remap); -#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); - return 0; -} - -static unsigned char amvdec_enable_flag; -static void vh264_local_init(struct vdec_h264_hw_s *hw) -{ - int i; - hw->decode_timeout_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; - } - - pr_info - ("H264 sysinfo: %dx%d duration=%d, pts_outside=%d, ", - hw->frame_width, hw->frame_height, hw->frame_dur, hw->pts_outside); - pr_info("sync_outside=%d, use_idr_framerate=%d\n", - hw->sync_outside, hw->use_idr_framerate); - - if ((unsigned long) hw->vh264_amstream_dec_info.param & 0x08) - hw->ucode_type = UCODE_IP_ONLY_PARAM; - else - hw->ucode_type = 0; - - if ((unsigned long) hw->vh264_amstream_dec_info.param & 0x20) - error_recovery_mode_in = 1; - else - error_recovery_mode_in = 3; - - 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[i]; - hw->vfpool[i].index = -1; /* VF_BUF_NUM; */ - hw->vfpool[i].bufWidth = 1920; - kfifo_put(&hw->newframe_q, vf); - } - - hw->duration_from_pts_done = 0; - - hw->p_last_vf = NULL; - hw->fatal_error_flag = 0; - hw->vh264_stream_switching_state = SWITCHING_STATE_OFF; - - INIT_WORK(&hw->work, vh264_work); - - return; -} - -static s32 vh264_init(struct vdec_h264_hw_s *hw) -{ - /* int trickmode_fffb = 0; */ - int firmwareloaded = 0; - - hw->init_flag = 0; - hw->set_params_done = 0; - hw->start_process_time = 0; - - /* pr_info("\nvh264_init\n"); */ - /* init_timer(&hw->recycle_timer); */ - - /* timer init */ - 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; - - hw->duration_on_correcting = 0; - hw->fixed_frame_rate_check_count = 0; - hw->saved_resolution = 0; - - vh264_local_init(hw); - - if (!amvdec_enable_flag) { - amvdec_enable_flag = true; - amvdec_enable(); - } - - /* -- 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(); - - 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); - if (!firmwareloaded) { - int ret = 0, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - pr_info("start load orignal firmware ...\n"); - - size = get_firmware_data(VIDEO_DEC_H264_MULTI, buf); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return -1; - } - - /*ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf);*/ - - /*header*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_HEADER, - buf + 0x4000, MC_SWAP_SIZE); - /*data*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_DATA, - buf + 0x2000, MC_SWAP_SIZE); - /*mmco*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MMCO, - buf + 0x6000, MC_SWAP_SIZE); - /*list*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_LIST, - buf + 0x3000, MC_SWAP_SIZE); - /*slice*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_SLICE, - buf + 0x5000, MC_SWAP_SIZE); - /*main*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN, - buf, 0x2000); - /*data*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x2000, - buf + 0x2000, 0x1000); - /*slice*/ - memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x3000, - buf + 0x5000, 0x1000); - - vfree(buf); - - if (ret < 0) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "264 load orignal firmware error.\n"); - amvdec_disable(); - if (hw->mc_cpu_addr) { - dma_free_coherent(amports_get_dma_device(), - MC_TOTAL_SIZE, hw->mc_cpu_addr, - hw->mc_dma_handle); - hw->mc_cpu_addr = NULL; - } - return -EBUSY; - } - } - -#if 1 /* #ifdef BUFFER_MGR_IN_C */ - dpb_init_global(&hw->dpb, - hw_to_vdec(hw)->id, 0, 0); - hw->lmem_addr = __get_free_page(GFP_KERNEL); - if (!hw->lmem_addr) { - pr_info("%s: failed to alloc lmem_addr\n", __func__); - return -ENOMEM; - } else { - hw->lmem_addr_remap = dma_map_single( - amports_get_dma_device(), - (void *)hw->lmem_addr, - PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hw->lmem_addr_remap)) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "%s: failed to map lmem_addr\n", __func__); - free_page(hw->lmem_addr); - hw->lmem_addr = 0; - hw->lmem_addr_remap = 0; - return -ENOMEM; - } - - pr_info("%s, vaddr=%lx phy_addr=%p\n", - __func__, hw->lmem_addr, (void *)hw->lmem_addr_remap); - } - /* 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, int mode) -{ - int i; - - 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; - } - } -#ifdef USE_CMA - if (hw->cma_alloc_addr) { - pr_info("codec_mm release buffer 0x%lx\n", hw->cma_alloc_addr); - codec_mm_free_for_dma(MEM_NAME, hw->cma_alloc_addr); - hw->cma_alloc_count = 0; - } - - if (hw->collocate_cma_alloc_addr) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "codec_mm release collocate buffer 0x%lx\n", - hw->collocate_cma_alloc_addr); - codec_mm_free_for_dma(MEM_NAME, hw->collocate_cma_alloc_addr); - hw->collocate_cma_alloc_count = 0; - } - - for (i = 0; i < hw->buffer_spec_num; i++) { - if (hw->buffer_spec[i].cma_alloc_addr) { - pr_info("codec_mm release buffer_spec[%d], 0x%lx\n", i, - hw->buffer_spec[i].cma_alloc_addr); - codec_mm_free_for_dma(MEM_NAME, - hw->buffer_spec[i].cma_alloc_addr); - hw->buffer_spec[i].cma_alloc_count = 0; - } - } - -#endif - - if (hw->lmem_addr_remap) { - dma_unmap_single(amports_get_dma_device(), - hw->lmem_addr_remap, - PAGE_SIZE, DMA_FROM_DEVICE); - hw->lmem_addr_remap = 0; - } - if (hw->lmem_addr) { - free_page(hw->lmem_addr); - hw->lmem_addr = 0; - } - cancel_work_sync(&hw->work); - - /* amvdec_disable(); */ - - return 0; -} - -static void vh264_work(struct work_struct *work) -{ - struct vdec_h264_hw_s *hw = container_of(work, - struct vdec_h264_hw_s, work); - struct vdec_s *vdec = hw_to_vdec(hw); - - /* finished decoding one frame or error, - * notify vdec core to switch context - */ - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_DETAIL, - "%s %x %x %x\n", __func__, - READ_VREG(0xc47), READ_VREG(0xc45), READ_VREG(0xc46)); - -#ifdef USE_CMA - if (hw->dec_result == DEC_RESULT_CONFIG_PARAM) { - if (vh264_set_params(hw) < 0) { - hw->fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; - if (!hw->fatal_error_reset) - schedule_work(&hw->error_wd_work); - } - return; - } else -#endif - if ((hw->dec_result == DEC_RESULT_GET_DATA) || - (hw->dec_result == DEC_RESULT_GET_DATA_RETRY)) { - if (hw->dec_result == DEC_RESULT_GET_DATA) { - dpb_print(hw->dpb.decoder_index, 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)); - vdec_vframe_dirty(vdec, hw->chunk); - vdec_clean_input(vdec); - } - - if (is_buffer_available(vdec)) { - int r; - r = vdec_prepare_input(vdec, &hw->chunk); - if (r < 0) { - hw->dec_result = DEC_RESULT_GET_DATA_RETRY; - - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_VDEC_DETAIL, - "ammvdec_vh264: Insufficient data\n"); - - schedule_work(&hw->work); - return; - } - hw->dec_result = DEC_RESULT_NONE; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s: chunk size 0x%x\n", - __func__, hw->chunk->size); - WRITE_VREG(POWER_CTL_VLD, - READ_VREG(POWER_CTL_VLD) | - (0 << 10) | (1 << 9) | (1 << 6)); - WRITE_VREG(H264_DECODE_INFO, (1<<13)); - WRITE_VREG(H264_DECODE_SIZE, hw->chunk->size); - WRITE_VREG(VIFF_BIT_CNT, (hw->chunk->size * 8)); - vdec_enable_input(vdec); - - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); - } else{ - hw->dec_result = DEC_RESULT_GET_DATA_RETRY; - - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_DETAIL, - "ammvdec_vh264: Insufficient data\n"); - - schedule_work(&hw->work); - } - return; - } else if (hw->dec_result == DEC_RESULT_DONE) { - /* if (!hw->ctx_valid) - hw->ctx_valid = 1; */ - dpb_print(hw->dpb.decoder_index, 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)); - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - } else { - dpb_print(hw->dpb.decoder_index, 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)); - } - - del_timer_sync(&hw->check_timer); - hw->stat &= ~STAT_TIMER_ARM; - - /* mark itself has all HW resource released and input released */ - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_CONNECTED); - - if (hw->vdec_cb) - hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg); -} - -static bool run_ready(struct vdec_s *vdec) -{ - if (vdec->master) - return false; - - if ((!input_frame_based(vdec)) && (start_decode_buf_level > 0)) { - u32 rp, wp; - u32 level; - - rp = READ_MPEG_REG(PARSER_VIDEO_RP); - wp = READ_MPEG_REG(PARSER_VIDEO_WP); - - if (wp < rp) - level = vdec->input.size + wp - rp; - else - level = wp - rp; - - if (level < start_decode_buf_level) { - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *)vdec->private; - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_DETAIL, - "%s vififo level low %x(<%x) (lev%x wp%x rp%x)\n", - __func__, level, - start_decode_buf_level, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP)); - return 0; - } - } - - if (h264_debug_flag & 0x20000000) { - /* pr_info("%s, a\n", __func__); */ - return 1; - } else { - return is_buffer_available(vdec); - } -} - -static void run(struct vdec_s *vdec, - void (*callback)(struct vdec_s *, void *), void *arg) -{ - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *)vdec->private; - int size; - - hw->vdec_cb_arg = arg; - hw->vdec_cb = callback; - - /* hw->chunk = vdec_prepare_input(vdec); */ - size = vdec_prepare_input(vdec, &hw->chunk); - if ((size < 0) || - (input_frame_based(vdec) && hw->chunk == NULL)) { - hw->dec_result = DEC_RESULT_AGAIN; - - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_DETAIL, - "ammvdec_vh264: Insufficient data\n"); - - schedule_work(&hw->work); - return; - } - - hw->dec_result = DEC_RESULT_NONE; -#if 0 - if ((!input_frame_based(vdec)) && (start_decode_buf_level > 0)) { - if (READ_VREG(VLD_MEM_VIFIFO_LEVEL) < - start_decode_buf_level) { - dpb_print(hw->dpb.decoder_index, - PRINT_FLAG_VDEC_DETAIL, - "%s: VIFIFO_LEVEL %x is low (<%x)\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - start_decode_buf_level); - - hw->dec_result = DEC_RESULT_AGAIN; - schedule_work(&hw->work); - return; - } - } -#endif - - if (input_frame_based(vdec)) { - u8 *data = ((u8 *)hw->chunk->block->start_virt) + - hw->chunk->offset; - - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s: size 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", - __func__, 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]); - } else - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_VDEC_STATUS, - "%s: %x %x %x size 0x%x\n", - __func__, - READ_VREG(VLD_MEM_VIFIFO_LEVEL), - READ_VREG(VLD_MEM_VIFIFO_WP), - READ_VREG(VLD_MEM_VIFIFO_RP), size); - - hw->start_process_time = jiffies; - - if (((h264_debug_flag & ONLY_RESET_AT_START) == 0) || - (hw->init_flag == 0)) { - if (amvdec_vdec_loadmc_ex(vdec, "vmh264_mc") < 0) { - amvdec_enable_flag = false; - amvdec_disable(); - pr_info("%s: Error amvdec_vdec_loadmc fail\n", - __func__); - return; - } - - if (vh264_hw_ctx_restore(hw) < 0) { - schedule_work(&hw->work); - return; - } - if (input_frame_based(vdec)) { - WRITE_VREG(H264_DECODE_INFO, (1<<13)); - WRITE_VREG(H264_DECODE_SIZE, hw->chunk->size); - WRITE_VREG(VIFF_BIT_CNT, (hw->chunk->size * 8)); - } else { - if (size <= 0) - size = 0x7fffffff; /*error happen*/ - WRITE_VREG(H264_DECODE_INFO, (1<<13)); - WRITE_VREG(H264_DECODE_SIZE, size); - WRITE_VREG(VIFF_BIT_CNT, size * 8); - } - - vdec_enable_input(vdec); - - add_timer(&hw->check_timer); - - amvdec_start(); - - /* if (hw->init_flag) { */ - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); - /* } */ - - hw->init_flag = 1; - } else { - WRITE_VREG(H264_DECODE_INFO, (1 << 13)); - vdec_enable_input(vdec); - - WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); - } -} - -static void reset(struct vdec_s *vdec) -{ - pr_info("ammvdec_h264: reset.\n"); - -#if 0 - struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - - hw->init_flag = 0; - hw->set_params_done = 0; - - vh264_local_init(hw); - - dpb_init_global(&hw->dpb); -#endif -} - -static int ammvdec_h264_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct vdec_h264_hw_s *hw = NULL; - - if (pdata == NULL) { - pr_info("\nammvdec_h264 memory resource undefined.\n"); - return -EFAULT; - } - - hw = (struct vdec_h264_hw_s *)devm_kzalloc(&pdev->dev, - sizeof(struct vdec_h264_hw_s), GFP_KERNEL); - if (hw == NULL) { - pr_info("\nammvdec_h264 device data allocation failed\n"); - return -ENOMEM; - } - - pdata->private = hw; - pdata->dec_status = dec_status; - /* pdata->set_trickmode = set_trickmode; */ - pdata->run_ready = run_ready; - pdata->run = run; - pdata->reset = reset; - pdata->irq_handler = vh264_isr; - - pdata->id = pdev->id; - - if (pdata->use_vfm_path) - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - else if (vdec_dual(pdata)) { - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME : - VFM_DEC_DVBL_PROVIDER_NAME); - } else - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - PROVIDER_NAME ".%02x", pdev->id & 0xff); - - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vf_provider_ops, pdata); - - platform_set_drvdata(pdev, pdata); - - hw->platform_dev = pdev; -#ifndef USE_CMA - hw->buf_start = pdata->mem_start; - hw->buf_size = pdata->mem_end - pdata->mem_start + 1; - /* hw->ucode_map_start = pdata->mem_start; */ - if (hw->buf_size < DEFAULT_MEM_SIZE) { - pr_info("\nammvdec_h264 memory size not enough.\n"); - return -ENOMEM; - } -#endif - -#ifdef USE_CMA - hw->cma_dev = pdata->cma_dev; - if (hw->cma_alloc_count == 0) { - hw->cma_alloc_count = PAGE_ALIGN(V_BUF_ADDR_OFFSET) / PAGE_SIZE; - hw->cma_alloc_addr = codec_mm_alloc_for_dma(MEM_NAME, - hw->cma_alloc_count, - 4, CODEC_MM_FLAGS_FOR_VDECODER); - } - if (!hw->cma_alloc_addr) { - dpb_print(hw->dpb.decoder_index, PRINT_FLAG_ERROR, - "codec_mm alloc failed, request buf size 0x%lx\n", - hw->cma_alloc_count * PAGE_SIZE); - hw->cma_alloc_count = 0; - return -ENOMEM; - } - hw->buf_offset = hw->cma_alloc_addr - DEF_BUF_START_ADDR; -#else - hw->buf_offset = pdata->mem_start - DEF_BUF_START_ADDR; - hw->buf_start = V_BUF_ADDR_OFFSET + pdata->mem_start; -#endif - - if (pdata->sys_info) - hw->vh264_amstream_dec_info = *pdata->sys_info; - if (NULL == hw->sei_data_buffer) { - hw->sei_data_buffer = - dma_alloc_coherent(amports_get_dma_device(), - USER_DATA_SIZE, - &hw->sei_data_buffer_phys, GFP_KERNEL); - if (!hw->sei_data_buffer) { - pr_info("%s: Can not allocate sei_data_buffer\n", - __func__); - return -ENOMEM; - } - /* pr_info("buffer 0x%x, phys 0x%x, remap 0x%x\n", - sei_data_buffer, sei_data_buffer_phys, - (u32)sei_data_buffer_remap); */ - } -#ifdef USE_CMA - pr_info("ammvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx\n", - pdata->mem_start, hw->buf_offset, hw->cma_alloc_addr); -#else - pr_info("ammvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx\n", - pdata->mem_start, hw->buf_offset, hw->buf_start); -#endif - - vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); - - if (vh264_init(hw) < 0) { - pr_info("\nammvdec_h264 init failed.\n"); - return -ENODEV; - } - atomic_set(&hw->vh264_active, 1); - - return 0; -} - -static int ammvdec_h264_remove(struct platform_device *pdev) -{ - struct vdec_h264_hw_s *hw = - (struct vdec_h264_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - - atomic_set(&hw->vh264_active, 0); - - if (hw->stat & STAT_TIMER_ARM) { - del_timer_sync(&hw->check_timer); - hw->stat &= ~STAT_TIMER_ARM; - } - - vh264_stop(hw, MODE_FULL); - - /* vdec_source_changed(VFORMAT_H264, 0, 0, 0); */ - - atomic_set(&hw->vh264_active, 0); - - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t ammvdec_h264_profile = { - .name = "mh264", - .profile = "" -}; - -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"); - return -ENODEV; - } - vcodec_profile_register(&ammvdec_h264_profile); - return 0; -} - -static void __exit ammvdec_h264_driver_remove_module(void) -{ - pr_info("ammvdec_h264 module remove.\n"); - - platform_driver_unregister(&ammvdec_h264_driver); -} - -/****************************************/ - -module_param(h264_debug_flag, uint, 0664); -MODULE_PARM_DESC(h264_debug_flag, "\n ammvdec_h264 h264_debug_flag\n"); - -module_param(start_decode_buf_level, uint, 0664); -MODULE_PARM_DESC(start_decode_buf_level, - "\n ammvdec_h264 start_decode_buf_level\n"); - -module_param(fixed_frame_rate_mode, uint, 0664); -MODULE_PARM_DESC(fixed_frame_rate_mode, "\namvdec_h264 fixed_frame_rate_mode\n"); - -module_param(decode_timeout_val, uint, 0664); -MODULE_PARM_DESC(decode_timeout_val, "\n amvdec_h264 decode_timeout_val\n"); - -module_param(reorder_dpb_size_margin, uint, 0664); -MODULE_PARM_DESC(reorder_dpb_size_margin, "\n ammvdec_h264 reorder_dpb_size_margin\n"); - -module_param(reference_buf_margin, uint, 0664); -MODULE_PARM_DESC(reference_buf_margin, "\n ammvdec_h264 reference_buf_margin\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(h264_debug_mask, uint, 0664); -MODULE_PARM_DESC(h264_debug_mask, "\n amvdec_h264 h264_debug_mask\n"); - -module_param(h264_debug_cmd, uint, 0664); -MODULE_PARM_DESC(h264_debug_cmd, "\n amvdec_h264 h264_debug_cmd\n"); - -module_param(force_rate_streambase, int, 0664); -MODULE_PARM_DESC(force_rate_streambase, "\n amvdec_h264 force_rate_streambase\n"); - -module_param(dec_control, int, 0664); -MODULE_PARM_DESC(dec_control, "\n amvdec_h264 dec_control\n"); - -module_param(force_rate_framebase, int, 0664); -MODULE_PARM_DESC(force_rate_framebase, "\n amvdec_h264 force_rate_framebase\n"); - -/* -module_param(trigger_task, uint, 0664); -MODULE_PARM_DESC(trigger_task, "\n amvdec_h264 trigger_task\n"); -*/ -module_param_array(decode_frame_count, uint, &max_decode_instance_num, 0664); - -module_param_array(max_process_time, uint, &max_decode_instance_num, 0664); - -module_param_array(max_get_frame_interval, uint, - &max_decode_instance_num, 0664); - -module_param_array(step, uint, &max_decode_instance_num, 0664); - -module_init(ammvdec_h264_driver_init_module); -module_exit(ammvdec_h264_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC H264 Video Decoder Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c deleted file mode 100644 index 7e09b7b..0000000 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/dev/null @@ -1,8969 +0,0 @@ -/* - * drivers/amlogic/amports/vh265.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/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.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 "../../../stream_input/amports/amports_priv.h" -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include "../utils/decoder_mmu_box.h" -#include "../utils/decoder_bmmu_box.h" -#include "../utils/config_parser.h" - -/*#define HEVC_PIC_STRUCT_SUPPORT*/ -#define MULTI_INSTANCE_SUPPORT - - - -#define MMU_COMPRESS_HEADER_SIZE 0x48000 -#define MAX_FRAME_4K_NUM 0x1200 -#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4) -#define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7 -#define HEVC_CM_HEADER_START_ADDR 0x3628 -#define HEVC_SAO_MMU_VH1_ADDR 0x363b -#define HEVC_SAO_MMU_VH0_ADDR 0x363a -#define HEVC_SAO_MMU_STATUS 0x3639 - - - -#define MEM_NAME "codec_265" -/* #include <mach/am_regs.h> */ -#include <linux/amlogic/media/utils/vdec_reg.h> - -#include "../utils/vdec.h" -#include "../utils/amvdec.h" -#include <linux/amlogic/media/video_sink/video.h> - -#define SUPPORT_10BIT -/* #define ERROR_HANDLE_DEBUG */ -#if 0/*MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8B*/ -#undef SUPPORT_4K2K -#else -#define SUPPORT_4K2K -#endif - -#ifndef STAT_KTHREAD -#define STAT_KTHREAD 0x40 -#endif - -#ifdef MULTI_INSTANCE_SUPPORT -#define MAX_DECODE_INSTANCE_NUM 12 -#define MULTI_DRIVER_NAME "ammvdec_h265" -#endif -#define DRIVER_NAME "amvdec_h265" -#define MODULE_NAME "amvdec_h265" - -#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) -#define HEVC_SIZE (4096*2304) - -struct hevc_state_s; -static int hevc_print(struct hevc_state_s *hevc, - int debug_flag, const char *fmt, ...); -static int hevc_print_cont(struct hevc_state_s *hevc, - int debug_flag, const char *fmt, ...); -static int vh265_vf_states(struct vframe_states *states, void *); -static struct vframe_s *vh265_vf_peek(void *); -static struct vframe_s *vh265_vf_get(void *); -static void vh265_vf_put(struct vframe_s *, void *); -static int vh265_event_cb(int type, void *data, void *private_data); - -static int vh265_stop(struct hevc_state_s *hevc); -#ifdef MULTI_INSTANCE_SUPPORT -static int vmh265_stop(struct hevc_state_s *hevc); -static s32 vh265_init(struct vdec_s *vdec); -static bool run_ready(struct vdec_s *vdec); -static void reset_process_time(struct hevc_state_s *hevc); -static void start_process_time(struct hevc_state_s *hevc); -static void timeout_process(struct hevc_state_s *hevc); -#else -static s32 vh265_init(struct hevc_state_s *hevc); -#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(unsigned long arg); -static void config_decode_mode(struct hevc_state_s *hevc); - -static const char vh265_dec_id[] = "vh265-dev"; - -#define PROVIDER_NAME "decoder.h265" -#define MULTI_INSTANCE_PROVIDER_NAME "vdec.h265" - -static const struct vframe_operations_s vh265_vf_provider = { - .peek = vh265_vf_peek, - .get = vh265_vf_get, - .put = vh265_vf_put, - .event_cb = vh265_event_cb, - .vf_states = vh265_vf_states, -}; - -static struct vframe_provider_s vh265_vf_prov; - -static u32 bit_depth_luma; -static u32 bit_depth_chroma; -static u32 video_signal_type; - -static unsigned int start_decode_buf_level = 0x8000; - -static unsigned int decode_timeout_val; -#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000 - -static const char * const video_format_names[] = { - "component", "PAL", "NTSC", "SECAM", - "MAC", "unspecified", "unspecified", "unspecified" -}; - -static const char * const color_primaries_names[] = { - "unknown", "bt709", "undef", "unknown", - "bt470m", "bt470bg", "smpte170m", "smpte240m", - "film", "bt2020" -}; - -static const char * const transfer_characteristics_names[] = { - "unknown", "bt709", "undef", "unknown", - "bt470m", "bt470bg", "smpte170m", "smpte240m", - "linear", "log100", "log316", "iec61966-2-4", - "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", - "smpte-st-2084", "smpte-st-428" -}; - -static const char * const matrix_coeffs_names[] = { - "GBR", "bt709", "undef", "unknown", - "fcc", "bt470bg", "smpte170m", "smpte240m", - "YCgCo", "bt2020nc", "bt2020c" -}; - -#ifdef SUPPORT_10BIT -#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 LOSLESS_COMPRESS_MODE -/* 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 - 0x10, double write only -*/ -static u32 double_write_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 workaround_enable; -static u32 force_w_h; -#endif -static u32 force_fps; -static u32 pts_unstable; -#define H265_DEBUG_BUFMGR 0x01 -#define H265_DEBUG_BUFMGR_MORE 0x02 -#define H265_DEBUG_UCODE 0x04 -#define H265_DEBUG_REG 0x08 -#define H265_DEBUG_MAN_SEARCH_NAL 0x10 -#define H265_DEBUG_MAN_SKIP_NAL 0x20 -#define H265_DEBUG_DISPLAY_CUR_FRAME 0x40 -#define H265_DEBUG_FORCE_CLK 0x80 -#define H265_DEBUG_SEND_PARAM_WITH_REG 0x100 -#define H265_DEBUG_NO_DISPLAY 0x200 -#define H265_DEBUG_DISCARD_NAL 0x400 -#define H265_DEBUG_OUT_PTS 0x800 -#define H265_DEBUG_PRINT_SEI 0x2000 -#define H265_DEBUG_PIC_STRUCT 0x4000 -#define H265_DEBUG_DIS_LOC_ERROR_PROC 0x10000 -#define H265_DEBUG_DIS_SYS_ERROR_PROC 0x20000 -#define H265_DEBUG_DUMP_PIC_LIST 0x40000 -#define H265_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000 -#define H265_DEBUG_HW_RESET 0x100000 -#define H265_DEBUG_ERROR_TRIG 0x400000 -#define H265_DEBUG_NO_EOS_SEARCH_DONE 0x800000 -#define H265_DEBUG_NOT_USE_LAST_DISPBUF 0x1000000 -#define H265_DEBUG_IGNORE_CONFORMANCE_WINDOW 0x2000000 -#define H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x4000000 -#ifdef MULTI_INSTANCE_SUPPORT -#define IGNORE_PARAM_FROM_CONFIG 0x08000000 -#define PRINT_FRAMEBASE_DATA 0x10000000 -#define PRINT_FLAG_VDEC_STATUS 0x20000000 -#define PRINT_FLAG_VDEC_DETAIL 0x40000000 -#endif -#define MAX_BUF_NUM 24 -#define MAX_REF_PIC_NUM 24 -#define MAX_REF_ACTIVE 16 - -#define BMMU_MAX_BUFFERS (MAX_BUF_NUM + 1) -#define BMMU_WORKSPACE_ID (MAX_BUF_NUM) - -const u32 h265_version = 201602101; -static u32 debug_mask = 0xffffffff; -static u32 debug; -static u32 radr; -static u32 rval; -static u32 dbg_cmd; -static u32 dbg_skip_decode_index; -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 */ -static u32 dbg_nal_skip_count; -#endif -/*for debug*/ -static u32 decode_stop_pos; -static u32 decode_stop_pos_pre; -static u32 decode_pic_begin; -static uint slice_parse_begin; -static u32 step; -#ifdef MIX_STREAM_SUPPORT -#ifdef SUPPORT_4K2K -static u32 buf_alloc_width = 4096; -static u32 buf_alloc_height = 2304; -#else -static u32 buf_alloc_width = 1920; -static u32 buf_alloc_height = 1088; -#endif -static u32 dynamic_buf_num_margin; -#else -static u32 buf_alloc_width; -static u32 buf_alloc_height; -static u32 dynamic_buf_num_margin = 8; -#endif -static u32 max_buf_num = 16; -static u32 buf_alloc_size; -static u32 re_config_pic_flag; -/* -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 h265) 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[1:0]PB_skip_mode: 0, start decoding at begin; -1, start decoding after first I; -2, only decode and display none error picture; -3, start decoding and display after IDR,etc -bit[31:16] PB_skip_count_after_decoding (decoding but not display), -only for mode 0 and 1. - */ -static u32 nal_skip_policy = 2; - -/* -bit 0, 1: only display I picture; -bit 1, 1: only decode I picture; -*/ -static u32 i_only_flag; - -/* -use_cma: 1, use both reserver memory and cma for buffers -2, only use cma for buffers -*/ -static u32 use_cma = 2; - -#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf)) -static u32 prefix_aux_buf_size; -static u32 suffix_aux_buf_size; - -static u32 max_decoding_time; -/* -error handling -*/ -/*error_handle_policy: -bit 0: 0, auto skip error_skip_nal_count nals before error recovery; -1, skip error_skip_nal_count nals before error recovery; -bit 1 (valid only when bit0 == 1): -1, wait vps/sps/pps after error recovery; -bit 2 (valid only when bit0 == 0): -0, auto search after error recovery (hevc_recover() called); -1, manual search after error recovery -(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2)) - -bit 4: 0, set error_mark after reset/recover - 1, do not set error_mark after reset/recover -bit 5: 0, check total lcu for every picture - 1, do not check total lcu - -*/ - -static u32 error_handle_policy; -static u32 error_skip_nal_count = 6; -static u32 error_handle_threshold = 30; -static u32 error_handle_nal_skip_threshold = 10; -static u32 error_handle_system_threshold = 30; -static u32 interlace_enable = 1; - /* - parser_sei_enable: - bit 0, sei; - bit 1, sei_suffix (fill aux buf) - bit 2, fill sei to aux buf (when bit 0 is 1) - bit 8, debug flag - */ -static u32 parser_sei_enable; -#ifdef CONFIG_AM_VDEC_DV -static u32 parser_dolby_vision_enable; -#endif -/* this is only for h265 mmu enable */ - -#ifdef CONFIG_MULTI_DEC -static u32 mmu_enable; -#else -static u32 mmu_enable = 1; -#endif - -#ifdef MULTI_INSTANCE_SUPPORT -static u32 work_buf_size = 48 * 1024 * 1024; -static unsigned int max_decode_instance_num - = MAX_DECODE_INSTANCE_NUM; -static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM]; -static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM]; -static unsigned int max_get_frame_interval[MAX_DECODE_INSTANCE_NUM]; - -#ifdef CONFIG_MULTI_DEC -static unsigned char get_idx(struct hevc_state_s *hevc); -#endif - -#ifdef CONFIG_AM_VDEC_DV -static u32 dv_toggle_prov_name; - -static u32 dv_debug; -#endif -#endif - - -#ifdef CONFIG_MULTI_DEC -#define get_dbg_flag(hevc) ((debug_mask & (1 << hevc->index)) ? debug : 0) -#define get_dbg_flag2(hevc) ((debug_mask & (1 << get_idx(hevc))) ? debug : 0) -#else -#define get_dbg_flag(hevc) debug -#define get_dbg_flag2(hevc) debug -#define get_double_write_mode(hevc) double_write_mode -#define get_buf_alloc_width(hevc) buf_alloc_width -#define get_buf_alloc_height(hevc) buf_alloc_height -#define get_dynamic_buf_num_margin(hevc) dynamic_buf_num_margin -#endif -#define get_buffer_mode(hevc) buffer_mode - - -DEFINE_SPINLOCK(lock); -struct task_struct *h265_task = NULL; -#undef DEBUG_REG -#ifdef DEBUG_REG -void WRITE_VREG_DBG(unsigned adr, unsigned val) -{ - WRITE_VREG(adr, val); -} - -#undef WRITE_VREG -#define WRITE_VREG WRITE_VREG_DBG -#endif - -static DEFINE_MUTEX(vh265_mutex); - - -/************************************************** - -h265 buffer management include - -***************************************************/ -enum NalUnitType { - NAL_UNIT_CODED_SLICE_TRAIL_N = 0, /* 0 */ - NAL_UNIT_CODED_SLICE_TRAIL_R, /* 1 */ - - NAL_UNIT_CODED_SLICE_TSA_N, /* 2 */ - /* Current name in the spec: TSA_R */ - NAL_UNIT_CODED_SLICE_TLA, /* 3 */ - - NAL_UNIT_CODED_SLICE_STSA_N, /* 4 */ - NAL_UNIT_CODED_SLICE_STSA_R, /* 5 */ - - NAL_UNIT_CODED_SLICE_RADL_N, /* 6 */ - /* Current name in the spec: RADL_R */ - NAL_UNIT_CODED_SLICE_DLP, /* 7 */ - - NAL_UNIT_CODED_SLICE_RASL_N, /* 8 */ - /* Current name in the spec: RASL_R */ - NAL_UNIT_CODED_SLICE_TFD, /* 9 */ - - NAL_UNIT_RESERVED_10, - NAL_UNIT_RESERVED_11, - NAL_UNIT_RESERVED_12, - NAL_UNIT_RESERVED_13, - NAL_UNIT_RESERVED_14, - NAL_UNIT_RESERVED_15, - - /* Current name in the spec: BLA_W_LP */ - NAL_UNIT_CODED_SLICE_BLA, /* 16 */ - /* Current name in the spec: BLA_W_DLP */ - NAL_UNIT_CODED_SLICE_BLANT, /* 17 */ - NAL_UNIT_CODED_SLICE_BLA_N_LP, /* 18 */ - /* Current name in the spec: IDR_W_DLP */ - NAL_UNIT_CODED_SLICE_IDR, /* 19 */ - NAL_UNIT_CODED_SLICE_IDR_N_LP, /* 20 */ - NAL_UNIT_CODED_SLICE_CRA, /* 21 */ - NAL_UNIT_RESERVED_22, - NAL_UNIT_RESERVED_23, - - NAL_UNIT_RESERVED_24, - NAL_UNIT_RESERVED_25, - NAL_UNIT_RESERVED_26, - NAL_UNIT_RESERVED_27, - NAL_UNIT_RESERVED_28, - NAL_UNIT_RESERVED_29, - NAL_UNIT_RESERVED_30, - NAL_UNIT_RESERVED_31, - - NAL_UNIT_VPS, /* 32 */ - NAL_UNIT_SPS, /* 33 */ - NAL_UNIT_PPS, /* 34 */ - NAL_UNIT_ACCESS_UNIT_DELIMITER, /* 35 */ - NAL_UNIT_EOS, /* 36 */ - NAL_UNIT_EOB, /* 37 */ - NAL_UNIT_FILLER_DATA, /* 38 */ - NAL_UNIT_SEI, /* 39 Prefix SEI */ - NAL_UNIT_SEI_SUFFIX, /* 40 Suffix SEI */ - NAL_UNIT_RESERVED_41, - NAL_UNIT_RESERVED_42, - NAL_UNIT_RESERVED_43, - NAL_UNIT_RESERVED_44, - NAL_UNIT_RESERVED_45, - NAL_UNIT_RESERVED_46, - NAL_UNIT_RESERVED_47, - NAL_UNIT_UNSPECIFIED_48, - NAL_UNIT_UNSPECIFIED_49, - NAL_UNIT_UNSPECIFIED_50, - NAL_UNIT_UNSPECIFIED_51, - NAL_UNIT_UNSPECIFIED_52, - NAL_UNIT_UNSPECIFIED_53, - NAL_UNIT_UNSPECIFIED_54, - NAL_UNIT_UNSPECIFIED_55, - NAL_UNIT_UNSPECIFIED_56, - NAL_UNIT_UNSPECIFIED_57, - NAL_UNIT_UNSPECIFIED_58, - NAL_UNIT_UNSPECIFIED_59, - NAL_UNIT_UNSPECIFIED_60, - NAL_UNIT_UNSPECIFIED_61, - NAL_UNIT_UNSPECIFIED_62, - NAL_UNIT_UNSPECIFIED_63, - NAL_UNIT_INVALID, -}; - -/* --------------------------------------------------- */ -/* Amrisc Software Interrupt */ -/* --------------------------------------------------- */ -#define AMRISC_STREAM_EMPTY_REQ 0x01 -#define AMRISC_PARSER_REQ 0x02 -#define AMRISC_MAIN_REQ 0x04 - -/* --------------------------------------------------- */ -/* HEVC_DEC_STATUS define */ -/* --------------------------------------------------- */ -#define HEVC_DEC_IDLE 0x0 -#define HEVC_NAL_UNIT_VPS 0x1 -#define HEVC_NAL_UNIT_SPS 0x2 -#define HEVC_NAL_UNIT_PPS 0x3 -#define HEVC_NAL_UNIT_CODED_SLICE_SEGMENT 0x4 -#define HEVC_CODED_SLICE_SEGMENT_DAT 0x5 -#define HEVC_SLICE_DECODING 0x6 -#define HEVC_NAL_UNIT_SEI 0x7 -#define HEVC_SLICE_SEGMENT_DONE 0x8 -#define HEVC_NAL_SEARCH_DONE 0x9 -#define HEVC_DECPIC_DATA_DONE 0xa -#define HEVC_DECPIC_DATA_ERROR 0xb -#define HEVC_SEI_DAT 0xc -#define HEVC_SEI_DAT_DONE 0xd -#define HEVC_NAL_DECODE_DONE 0xe - -#define HEVC_DATA_REQUEST 0x12 - -#define HEVC_DECODE_BUFEMPTY 0x20 -#define HEVC_DECODE_TIMEOUT 0x21 -#define HEVC_SEARCH_BUFEMPTY 0x22 - -#define HEVC_FIND_NEXT_PIC_NAL 0x50 -#define HEVC_FIND_NEXT_DVEL_NAL 0x51 - -#define HEVC_DUMP_LMEM 0x30 - -#define HEVC_4k2k_60HZ_NOT_SUPPORT 0x80 -#define HEVC_DISCARD_NAL 0xf0 -#define HEVC_ACTION_ERROR 0xfe -#define HEVC_ACTION_DONE 0xff - -/* --------------------------------------------------- */ -/* 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 -}; - -/************************************************** - -h265 buffer management - -***************************************************/ -/* #define BUFFER_MGR_ONLY */ -/* #define CONFIG_HEVC_CLK_FORCED_ON */ -/* #define ENABLE_SWAP_TEST */ -#define MCRCC_ENABLE -#define INVALID_POC 0x80000000 - -#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 -#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 -#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2 -#define HEVC_VPS_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 -#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7 -#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8 -#define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9 -#define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A -#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B -#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C -#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D -#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E -#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F -#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F -#ifdef ENABLE_SWAP_TEST -#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L -#endif - -/*#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M*/ -/*#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N*/ -#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N - /*do not define ENABLE_SWAP_TEST*/ -#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L -#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_M - -#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/fetch SEI in ucode; - 1, parse/fetch SEI in ucode -bit [18]: for NAL_SEI_SUFFIX when bit0 is 0: - 0, do not fetch NAL_SEI_SUFFIX to aux buf; - 1, fetch NAL_SEL_SUFFIX data to aux buf -bit [19]: - 0, parse NAL_SEI in ucode - 1, fetch NAL_SEI to aux buf -bit [20]: for DOLBY_VISION_META - 0, do not fetch DOLBY_VISION_META to aux buf - 1, fetch DOLBY_VISION_META to aux buf -*/ -#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I - /*read only*/ -#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J - /*set before start decoder*/ -#define HEVC_DECODE_MODE HEVC_ASSIST_SCRATCH_J -#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K - -#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 - -#define MAX_INT 0x7FFFFFFF - -#define RPM_BEGIN 0x100 -#define modification_list_cur 0x140 -#define RPM_END 0x180 - -#define RPS_USED_BIT 14 -/* MISC_FLAG0 */ -#define PCM_LOOP_FILTER_DISABLED_FLAG_BIT 0 -#define PCM_ENABLE_FLAG_BIT 1 -#define LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT 2 -#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 3 -#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT 4 -#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 5 -#define DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT 6 -#define SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 7 -#define SLICE_SAO_LUMA_FLAG_BIT 8 -#define SLICE_SAO_CHROMA_FLAG_BIT 9 -#define SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 10 - -union param_u { - struct { - unsigned short data[RPM_END - RPM_BEGIN]; - } l; - struct { - /* from ucode lmem, do not change this struct */ - unsigned short CUR_RPS[0x10]; - unsigned short num_ref_idx_l0_active; - unsigned short num_ref_idx_l1_active; - unsigned short slice_type; - unsigned short slice_temporal_mvp_enable_flag; - unsigned short dependent_slice_segment_flag; - unsigned short slice_segment_address; - unsigned short num_title_rows_minus1; - unsigned short pic_width_in_luma_samples; - unsigned short pic_height_in_luma_samples; - unsigned short log2_min_coding_block_size_minus3; - unsigned short log2_diff_max_min_coding_block_size; - unsigned short log2_max_pic_order_cnt_lsb_minus4; - unsigned short POClsb; - unsigned short collocated_from_l0_flag; - unsigned short collocated_ref_idx; - unsigned short log2_parallel_merge_level; - unsigned short five_minus_max_num_merge_cand; - unsigned short sps_num_reorder_pics_0; - unsigned short modification_flag; - unsigned short tiles_enabled_flag; - unsigned short num_tile_columns_minus1; - unsigned short num_tile_rows_minus1; - unsigned short tile_width[4]; - unsigned short tile_height[4]; - unsigned short misc_flag0; - unsigned short pps_beta_offset_div2; - unsigned short pps_tc_offset_div2; - unsigned short slice_beta_offset_div2; - unsigned short slice_tc_offset_div2; - unsigned short pps_cb_qp_offset; - unsigned short pps_cr_qp_offset; - unsigned short first_slice_segment_in_pic_flag; - unsigned short m_temporalId; - unsigned short m_nalUnitType; - - unsigned short vui_num_units_in_tick_hi; - unsigned short vui_num_units_in_tick_lo; - unsigned short vui_time_scale_hi; - unsigned short vui_time_scale_lo; - unsigned short bit_depth; - unsigned short profile_etc; - unsigned short sei_frame_field_info; - unsigned short video_signal_type; - unsigned short modification_list[0x20]; - unsigned short conformance_window_flag; - unsigned short conf_win_left_offset; - unsigned short conf_win_right_offset; - unsigned short conf_win_top_offset; - unsigned short conf_win_bottom_offset; - unsigned short chroma_format_idc; - unsigned short color_description; - } p; -}; - -#define RPM_BUF_SIZE (0x80*2) -/* non mmu mode lmem size : 0x400, mmu mode : 0x500*/ -#define LMEM_BUF_SIZE (0x500 * 2) - -struct buff_s { - u32 buf_start; - u32 buf_size; - u32 buf_end; -}; - -struct BuffInfo_s { - u32 max_width; - u32 max_height; - unsigned int start_adr; - unsigned int 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 vps; - 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 mmu_vbh; - struct buff_s cm_header; - struct buff_s mpred_above; - struct buff_s mpred_mv; - struct buff_s rpm; - struct buff_s lmem; -}; -#define WORK_BUF_SPEC_NUM 2 -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, - }, - .mmu_vbh = { - .buf_size = 0x5000, /*2*16*2304/4, 4K*/ - }, - .cm_header = {/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ - .buf_size = MMU_COMPRESS_HEADER_SIZE*(16+1), - }, - .mpred_above = { - .buf_size = 0x8000, - }, - .mpred_mv = {/* 1080p, 0x40000 per buffer */ - .buf_size = 0x40000 * MAX_REF_PIC_NUM, - }, - .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 = 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 - 512bytes(total:0x20000), - data 1024bytes(total:0x40000) */ - .buf_size = 0x20000, - }, - .dblk_data = { - .buf_size = 0x40000, - }, - .mmu_vbh = { - .buf_size = 0x5000, /*2*16*2304/4, 4K*/ - }, - .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/ - .buf_size = MMU_COMPRESS_HEADER_SIZE * (16+1), - }, - .mpred_above = { - .buf_size = 0x8000, - }, - .mpred_mv = { - /* .buf_size = 0x100000*16, - //4k2k , 0x100000 per buffer */ - /* 4096x2304 , 0x120000 per buffer */ - .buf_size = 0x120000 * MAX_REF_PIC_NUM, - }, - .rpm = { - .buf_size = RPM_BUF_SIZE, - }, - .lmem = { - .buf_size = 0x500 * 2, - } - } -}; - -unsigned int get_mmu_mode(void) -{ - return mmu_enable; -} - -#ifdef SUPPORT_10BIT -/* Losless compression body buffer size 4K per 64x32 (jt) */ -static int compute_losless_comp_body_size(int width, int height, - int mem_saving_mode) -{ - int width_x64; - int height_x32; - int bsize; - - width_x64 = width + 63; - width_x64 >>= 6; - - height_x32 = height + 31; - height_x32 >>= 5; - if (mem_saving_mode == 1 && mmu_enable) - bsize = 3200 * width_x64 * height_x32; - else if (mem_saving_mode == 1) - bsize = 3072 * width_x64 * height_x32; - else - bsize = 4096 * width_x64 * height_x32; - - return bsize; -} - -/* Losless compression header buffer size 32bytes per 128x64 (jt) */ -static int compute_losless_comp_header_size(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; - - return hsize; -} - -#endif - -static void init_buff_spec(struct hevc_state_s *hevc, - struct BuffInfo_s *buf_spec) -{ - 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->sps.buf_start = - buf_spec->vps.buf_start + buf_spec->vps.buf_size; - buf_spec->pps.buf_start = - buf_spec->sps.buf_start + buf_spec->sps.buf_size; - buf_spec->sao_up.buf_start = - buf_spec->pps.buf_start + buf_spec->pps.buf_size; - buf_spec->swap_buf.buf_start = - buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size; - buf_spec->swap_buf2.buf_start = - buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size; - buf_spec->scalelut.buf_start = - buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.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->mmu_vbh.buf_start = - buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; - buf_spec->cm_header.buf_start = - buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size; - buf_spec->mpred_above.buf_start = - buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; - buf_spec->mpred_mv.buf_start = - buf_spec->mpred_above.buf_start + - buf_spec->mpred_above.buf_size; - if (get_dbg_flag2(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) { - buf_spec->end_adr = - buf_spec->mpred_mv.buf_start + - buf_spec->mpred_mv.buf_size; - } else { - buf_spec->rpm.buf_start = - buf_spec->mpred_mv.buf_start + - buf_spec->mpred_mv.buf_size; - if (get_dbg_flag2(hevc) & H265_DEBUG_UCODE) { - buf_spec->lmem.buf_start = - buf_spec->rpm.buf_start + - buf_spec->rpm.buf_size; - buf_spec->end_adr = - buf_spec->lmem.buf_start + - buf_spec->lmem.buf_size; - } else { - buf_spec->end_adr = - buf_spec->rpm.buf_start + - buf_spec->rpm.buf_size; - } - } - - if (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); - } - if (get_dbg_flag2(hevc)) { - hevc_print(hevc, 0, - "ipp.buf_start :%x\n", - buf_spec->ipp.buf_start); - hevc_print(hevc, 0, - "sao_abv.buf_start :%x\n", - buf_spec->sao_abv.buf_start); - hevc_print(hevc, 0, - "sao_vb.buf_start :%x\n", - buf_spec->sao_vb.buf_start); - hevc_print(hevc, 0, - "short_term_rps.buf_start :%x\n", - buf_spec->short_term_rps.buf_start); - hevc_print(hevc, 0, - "vps.buf_start :%x\n", - buf_spec->vps.buf_start); - hevc_print(hevc, 0, - "sps.buf_start :%x\n", - buf_spec->sps.buf_start); - hevc_print(hevc, 0, - "pps.buf_start :%x\n", - buf_spec->pps.buf_start); - hevc_print(hevc, 0, - "sao_up.buf_start :%x\n", - buf_spec->sao_up.buf_start); - hevc_print(hevc, 0, - "swap_buf.buf_start :%x\n", - buf_spec->swap_buf.buf_start); - hevc_print(hevc, 0, - "swap_buf2.buf_start :%x\n", - buf_spec->swap_buf2.buf_start); - hevc_print(hevc, 0, - "scalelut.buf_start :%x\n", - buf_spec->scalelut.buf_start); - hevc_print(hevc, 0, - "dblk_para.buf_start :%x\n", - buf_spec->dblk_para.buf_start); - hevc_print(hevc, 0, - "dblk_data.buf_start :%x\n", - buf_spec->dblk_data.buf_start); - hevc_print(hevc, 0, - "mpred_above.buf_start :%x\n", - buf_spec->mpred_above.buf_start); - hevc_print(hevc, 0, - "mpred_mv.buf_start :%x\n", - buf_spec->mpred_mv.buf_start); - if ((get_dbg_flag2(hevc) - & - H265_DEBUG_SEND_PARAM_WITH_REG) - == 0) { - hevc_print(hevc, 0, - "rpm.buf_start :%x\n", - buf_spec->rpm.buf_start); - } - } - -} - -enum SliceType { - B_SLICE, - P_SLICE, - I_SLICE -}; - -/*USE_BUF_BLOCK*/ -struct BUF_s { - int index; - /*buffer */ - unsigned long start_adr; - unsigned int size; - - unsigned int free_start_adr; -} /*BUF_t */; - -/* level 6, 6.1 maximum slice number is 800; other is 200 */ -#define MAX_SLICE_NUM 800 -struct PIC_s { - int index; - int BUF_index; - int POC; - int decode_idx; - int slice_type; - int RefNum_L0; - int RefNum_L1; - int num_reorder_pic; - int stream_offset; - unsigned char referenced; - unsigned char output_mark; - unsigned char recon_mark; - unsigned char output_ready; - unsigned char error_mark; - unsigned char used_by_display; - /**/ int slice_idx; - int m_aiRefPOCList0[MAX_SLICE_NUM][16]; - int m_aiRefPOCList1[MAX_SLICE_NUM][16]; - /*buffer */ - unsigned int header_adr; -#ifdef CONFIG_AM_VDEC_DV - unsigned char dv_enhance_exist; -#endif - char *aux_data_buf; - int aux_data_size; - unsigned long cma_alloc_addr; - struct page *alloc_pages; - unsigned int mpred_mv_wr_start_addr; - unsigned int mc_y_adr; - unsigned int mc_u_v_adr; -#ifdef SUPPORT_10BIT - unsigned int comp_body_size; - unsigned int dw_y_adr; - unsigned int dw_u_v_adr; -#endif - unsigned int buf_size; - int mc_canvas_y; - int mc_canvas_u_v; - int width; - int height; - - int y_canvas_index; - int uv_canvas_index; -#ifdef MULTI_INSTANCE_SUPPORT - struct canvas_config_s canvas_config[2]; -#endif -#ifdef LOSLESS_COMPRESS_MODE - unsigned int losless_comp_body_size; -#endif - unsigned char pic_struct; - int vf_ref; - - u32 pts; - u64 pts64; -} /*PIC_t */; - -#define MAX_TILE_COL_NUM 5 -#define MAX_TILE_ROW_NUM 5 -struct tile_s { - int width; - int height; - int start_cu_x; - int start_cu_y; - - unsigned int sao_vb_start_addr; - unsigned int sao_abv_start_addr; -}; - -#define SEI_MASTER_DISPLAY_COLOR_MASK 0x00000001 -#define SEI_CONTENT_LIGHT_LEVEL_MASK 0x00000002 - -#define VF_POOL_SIZE 32 - -#ifdef MULTI_INSTANCE_SUPPORT -#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 - -static void vh265_work(struct work_struct *work); -#endif -struct hevc_state_s { -#ifdef MULTI_INSTANCE_SUPPORT - 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; - /* timeout handle */ - unsigned long int start_process_time; - unsigned last_lcu_idx; - unsigned decode_timeout_count; - unsigned timeout_num; -#ifdef CONFIG_AM_VDEC_DV - unsigned char switch_dvlayer_flag; -#endif - unsigned start_parser_type; -#endif - char *provider_name; - int index; - struct device *cma_dev; - unsigned char m_ins_flag; - unsigned char dolby_enhance_flag; - unsigned long buf_start; - u32 buf_size; - - struct BuffInfo_s work_space_buf_store; - struct BuffInfo_s *work_space_buf; - struct buff_s *mc_buf; - - u32 prefix_aux_size; - u32 suffix_aux_size; - void *aux_addr; - void *rpm_addr; - void *lmem_addr; - dma_addr_t aux_phy_addr; - dma_addr_t rpm_phy_addr; - dma_addr_t lmem_phy_addr; - - unsigned int pic_list_init_flag; - unsigned int use_cma_flag; - - unsigned short *rpm_ptr; - unsigned short *lmem_ptr; - unsigned short *debug_ptr; - int debug_ptr_size; - int pic_w; - int pic_h; - int lcu_x_num; - int lcu_y_num; - int lcu_total; - int lcu_size; - int lcu_size_log2; - int lcu_x_num_pre; - int lcu_y_num_pre; - int first_pic_after_recover; - - int num_tile_col; - int num_tile_row; - int tile_enabled; - int tile_x; - int tile_y; - int tile_y_x; - int tile_start_lcu_x; - int tile_start_lcu_y; - int tile_width_lcu; - int tile_height_lcu; - - int slice_type; - unsigned int slice_addr; - unsigned int slice_segment_addr; - - unsigned char interlace_flag; - unsigned char curr_pic_struct; - - unsigned short sps_num_reorder_pics_0; - unsigned short misc_flag0; - int m_temporalId; - int m_nalUnitType; - int TMVPFlag; - int isNextSliceSegment; - int LDCFlag; - int m_pocRandomAccess; - int plevel; - int MaxNumMergeCand; - - int new_pic; - int new_tile; - int curr_POC; - int iPrevPOC; - int iPrevTid0POC; - int list_no; - int RefNum_L0; - int RefNum_L1; - int ColFromL0Flag; - int LongTerm_Curr; - int LongTerm_Col; - int Col_POC; - int LongTerm_Ref; - - struct PIC_s *cur_pic; - struct PIC_s *col_pic; - int skip_flag; - int decode_idx; - int slice_idx; - unsigned char have_vps; - unsigned char have_sps; - unsigned char have_pps; - unsigned char have_valid_start_slice; - unsigned char wait_buf; - unsigned char error_flag; - unsigned int error_skip_nal_count; - - unsigned char - ignore_bufmgr_error; /* bit 0, for decoding; bit 1, for displaying */ - int PB_skip_mode; - int PB_skip_count_after_decoding; -#ifdef SUPPORT_10BIT - int mem_saving_mode; -#endif -#ifdef LOSLESS_COMPRESS_MODE - unsigned int losless_comp_body_size; -#endif - int pts_mode; - int last_lookup_pts; - int last_pts; - u64 last_lookup_pts_us64; - u64 last_pts_us64; - u32 shift_byte_count_lo; - u32 shift_byte_count_hi; - int pts_mode_switching_count; - int pts_mode_recovery_count; - - int buf_num; - int pic_num; - - /**/ - struct buff_s mc_buf_spec; - union param_u param; - - struct tile_s m_tile[MAX_TILE_ROW_NUM][MAX_TILE_COL_NUM]; - - struct timer_list timer; - struct BUF_s m_BUF[MAX_BUF_NUM]; - u32 used_buf_num; - struct PIC_s *m_PIC[MAX_REF_PIC_NUM]; - - DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE); - struct vframe_s vfpool[VF_POOL_SIZE]; - - u32 stat; - u32 frame_width; - u32 frame_height; - u32 frame_dur; - u32 frame_ar; - u32 bit_depth_luma; - u32 bit_depth_chroma; - u32 video_signal_type; - u32 saved_resolution; - bool get_frame_dur; - u32 error_watchdog_count; - u32 error_skip_nal_wt_cnt; - u32 error_system_watchdog_count; - -#ifdef DEBUG_PTS - unsigned long pts_missed; - unsigned long pts_hit; -#endif - struct dec_sysinfo vh265_amstream_dec_info; - unsigned char init_flag; - unsigned char uninit_list; - u32 start_decoding_time; - - int show_frame_num; - struct semaphore h265_sema; -#ifdef USE_UNINIT_SEMA - struct semaphore h265_uninit_done_sema; -#endif - int fatal_error; - - - u32 sei_present_flag; - void *frame_mmu_map_addr; - dma_addr_t frame_mmu_map_phy_addr; - unsigned int mmu_mc_buf_start; - unsigned int mmu_mc_buf_end; - unsigned int mmu_mc_start_4k_adr; - void *mmu_box; - void *bmmu_box; - - unsigned int last_put_idx_a; - unsigned int last_put_idx_b; - - unsigned int dec_status; - - - /* data for SEI_MASTER_DISPLAY_COLOR */ - unsigned int primaries[3][2]; - unsigned int white_point[2]; - unsigned int luminance[2]; - /* data for SEI_CONTENT_LIGHT_LEVEL */ - unsigned int content_light_level[2]; - - struct PIC_s *pre_top_pic; - struct PIC_s *pre_bot_pic; - -#ifdef MULTI_INSTANCE_SUPPORT - int double_write_mode; - int buf_alloc_width; - int buf_alloc_height; - int dynamic_buf_num_margin; - int start_action; -#endif -} /*hevc_stru_t */; - -#ifdef CONFIG_MULTI_DEC -static int get_double_write_mode(struct hevc_state_s *hevc) -{ - return hevc->double_write_mode; -} - -static int get_buf_alloc_width(struct hevc_state_s *hevc) -{ - return hevc->buf_alloc_width; -} - -static int get_buf_alloc_height(struct hevc_state_s *hevc) -{ - return hevc->buf_alloc_height; -} - -static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc) -{ - return hevc->dynamic_buf_num_margin; -} -#endif - -#ifdef CONFIG_MULTI_DEC -static unsigned char get_idx(struct hevc_state_s *hevc) -{ - return hevc->index; -} -#endif - -#undef pr_info -#define pr_info printk -static int hevc_print(struct hevc_state_s *hevc, - int flag, const char *fmt, ...) -{ -#define HEVC_PRINT_BUF 128 - unsigned char buf[HEVC_PRINT_BUF]; - int len = 0; -#ifdef CONFIG_MULTI_DEC - if (hevc == NULL || - (flag == 0) || - ((debug_mask & - (1 << hevc->index)) - && (debug & flag))) { -#endif - va_list args; - - va_start(args, fmt); - if (hevc) - len = sprintf(buf, "[%d]", hevc->index); - vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - va_end(args); -#ifdef CONFIG_MULTI_DEC - } -#endif - return 0; -} - -static int hevc_print_cont(struct hevc_state_s *hevc, - int flag, const char *fmt, ...) -{ -#define HEVC_PRINT_BUF 128 - unsigned char buf[HEVC_PRINT_BUF]; - int len = 0; -#ifdef CONFIG_MULTI_DEC - if (hevc == NULL || - (flag == 0) || - ((debug_mask & - (1 << hevc->index)) - && (debug & flag))) { -#endif - va_list args; - va_start(args, fmt); - vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - va_end(args); -#ifdef CONFIG_MULTI_DEC - } -#endif - return 0; -} - -static void set_canvas(struct hevc_state_s *hevc, struct PIC_s *pic); - -static void release_aux_data(struct hevc_state_s *hevc, - struct PIC_s *pic); - -static void hevc_init_stru(struct hevc_state_s *hevc, - struct BuffInfo_s *buf_spec_i, - struct buff_s *mc_buf_i) -{ - int i; - - hevc->work_space_buf = buf_spec_i; - hevc->mc_buf = mc_buf_i; - hevc->prefix_aux_size = 0; - hevc->suffix_aux_size = 0; - hevc->aux_addr = NULL; - hevc->rpm_addr = NULL; - hevc->lmem_addr = NULL; - - hevc->curr_POC = INVALID_POC; - - hevc->pic_list_init_flag = 0; - hevc->use_cma_flag = 0; - hevc->decode_idx = 0; - hevc->slice_idx = 0; - hevc->new_pic = 0; - hevc->new_tile = 0; - hevc->iPrevPOC = 0; - hevc->list_no = 0; - /* int m_uiMaxCUWidth = 1<<7; */ - /* int m_uiMaxCUHeight = 1<<7; */ - hevc->m_pocRandomAccess = MAX_INT; - hevc->tile_enabled = 0; - hevc->tile_x = 0; - hevc->tile_y = 0; - hevc->iPrevTid0POC = 0; - hevc->slice_addr = 0; - hevc->slice_segment_addr = 0; - hevc->skip_flag = 0; - hevc->misc_flag0 = 0; - - hevc->cur_pic = NULL; - hevc->col_pic = NULL; - hevc->wait_buf = 0; - hevc->error_flag = 0; - hevc->error_skip_nal_count = 0; - hevc->have_vps = 0; - hevc->have_sps = 0; - hevc->have_pps = 0; - hevc->have_valid_start_slice = 0; - - hevc->pts_mode = PTS_NORMAL; - hevc->last_pts = 0; - hevc->last_lookup_pts = 0; - hevc->last_pts_us64 = 0; - hevc->last_lookup_pts_us64 = 0; - hevc->shift_byte_count_lo = 0; - hevc->shift_byte_count_hi = 0; - hevc->pts_mode_switching_count = 0; - hevc->pts_mode_recovery_count = 0; - - hevc->PB_skip_mode = nal_skip_policy & 0x3; - hevc->PB_skip_count_after_decoding = (nal_skip_policy >> 16) & 0xffff; - if (hevc->PB_skip_mode == 0) - hevc->ignore_bufmgr_error = 0x1; - else - hevc->ignore_bufmgr_error = 0x0; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) - hevc->m_PIC[i] = NULL; - hevc->buf_num = 0; - hevc->pic_num = 0; - hevc->lcu_x_num_pre = 0; - hevc->lcu_y_num_pre = 0; - hevc->first_pic_after_recover = 0; - - hevc->pre_top_pic = NULL; - hevc->pre_bot_pic = NULL; - - hevc->sei_present_flag = 0; -#ifdef MULTI_INSTANCE_SUPPORT - hevc->start_process_time = 0; - hevc->last_lcu_idx = 0; - hevc->decode_timeout_count = 0; - hevc->timeout_num = 0; -#endif -} - -static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic); -static int H265_alloc_mmu(struct hevc_state_s *hevc, - struct PIC_s *new_pic, unsigned short bit_depth, - unsigned int *mmu_index_adr); - -static void get_rpm_param(union param_u *params) -{ - int i; - unsigned int data32; - - for (i = 0; i < 128; i++) { - do { - data32 = READ_VREG(RPM_CMD_REG); - /* hevc_print(hevc, 0, "%x\n", data32); */ - } while ((data32 & 0x10000) == 0); - params->l.data[i] = data32 & 0xffff; - /* hevc_print(hevc, 0, "%x\n", data32); */ - WRITE_VREG(RPM_CMD_REG, 0); - } -} - -static struct PIC_s *get_pic_by_POC(struct hevc_state_s *hevc, int POC) -{ - int i; - struct PIC_s *pic; - struct PIC_s *ret_pic = NULL; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - if (pic->POC == POC) { - if (ret_pic == NULL) - ret_pic = pic; - else { - if (pic->decode_idx > ret_pic->decode_idx) - ret_pic = pic; - } - } - } - return ret_pic; -} - -static struct PIC_s *get_ref_pic_by_POC(struct hevc_state_s *hevc, int POC) -{ - int i; - struct PIC_s *pic; - struct PIC_s *ret_pic = NULL; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - if ((pic->POC == POC) && (pic->referenced)) { - if (ret_pic == NULL) - ret_pic = pic; - else { - if (pic->decode_idx > ret_pic->decode_idx) - ret_pic = pic; - } - } - } - - if (ret_pic == NULL) { - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "Wrong, POC of %d is not in referenced list\n", - POC); - } - ret_pic = get_pic_by_POC(hevc, POC); - } - return ret_pic; -} - -static unsigned int log2i(unsigned int val) -{ - unsigned int ret = -1; - - while (val != 0) { - val >>= 1; - ret++; - } - return ret; -} - -static int init_buf_spec(struct hevc_state_s *hevc); - -static void uninit_mmu_buffers(struct hevc_state_s *hevc) -{ - - if (hevc->mmu_box) - decoder_mmu_box_free(hevc->mmu_box); - hevc->mmu_box = NULL; - - if (hevc->bmmu_box) - decoder_bmmu_box_free(hevc->bmmu_box); - hevc->bmmu_box = NULL; -} -static int init_mmu_buffers(struct hevc_state_s *hevc) -{ - if (mmu_enable) { - hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, - hevc->index, - MAX_REF_PIC_NUM, - 64 * SZ_1M - ); - if (!hevc->mmu_box) { - pr_err("h265 alloc mmu box failed!!\n"); - return -1; - } - } - hevc->bmmu_box = decoder_bmmu_box_alloc_box(DRIVER_NAME, - hevc->index, - BMMU_MAX_BUFFERS, - 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | - CODEC_MM_FLAGS_FOR_VDECODER); - 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; - } - return 0; -} - -static void init_buf_list(struct hevc_state_s *hevc) -{ - int i; - int buf_size; - int mc_buffer_end = hevc->mc_buf->buf_start + hevc->mc_buf->buf_size; - - if (get_dynamic_buf_num_margin(hevc) > 0) - hevc->used_buf_num = hevc->sps_num_reorder_pics_0 - + get_dynamic_buf_num_margin(hevc); - else - hevc->used_buf_num = max_buf_num; - - if (hevc->used_buf_num > MAX_BUF_NUM) - hevc->used_buf_num = MAX_BUF_NUM; - if (buf_alloc_size > 0) { - buf_size = buf_alloc_size; - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "[Buffer Management] init_buf_list:\n"); - } else { - int pic_width = get_buf_alloc_width(hevc) - ? get_buf_alloc_width(hevc) : hevc->pic_w; - int pic_height = - get_buf_alloc_height(hevc) - ? get_buf_alloc_height(hevc) : hevc->pic_h; -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - int losless_comp_header_size = compute_losless_comp_header_size - (pic_width, pic_height); - int losless_comp_body_size = compute_losless_comp_body_size - (pic_width, pic_height, hevc->mem_saving_mode); - int mc_buffer_size = losless_comp_header_size - + losless_comp_body_size; - int mc_buffer_size_h = (mc_buffer_size + 0xffff)>>16; - if (get_double_write_mode(hevc)) { - int pic_width_dw = ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) ? - pic_width / 4 : pic_width; - int pic_height_dw = ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) ? - pic_height / 4 : pic_height; - int lcu_size = hevc->lcu_size; - int pic_width_lcu = (pic_width_dw % lcu_size) - ? pic_width_dw / lcu_size - + 1 : pic_width_dw / lcu_size; - int pic_height_lcu = (pic_height_dw % lcu_size) - ? pic_height_dw / lcu_size - + 1 : pic_height_dw / 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 (mmu_enable) { - if (get_double_write_mode(hevc) == 1) - buf_size += (mc_buffer_size_h << 16); - } else { - if ((get_double_write_mode(hevc) & 0x10) == 0) - buf_size += (mc_buffer_size_h << 16); - } -#else - int lcu_size = hevc->lcu_size; - int pic_width_lcu = - (pic_width % lcu_size) ? pic_width / lcu_size - + 1 : pic_width / lcu_size; - int pic_height_lcu = - (pic_height % lcu_size) ? pic_height / lcu_size - + 1 : pic_height / 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; -#endif - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "init_buf_list num %d (width %d height %d):\n", - hevc->used_buf_num, pic_width, pic_height); - } - } - - hevc_print(hevc, 0, "allocate begin\n"); - //get_cma_alloc_ref();//DEBUG_TMP - for (i = 0; i < hevc->used_buf_num; i++) { - if (((i + 1) * buf_size) > hevc->mc_buf->buf_size) { - if (use_cma) - hevc->use_cma_flag = 1; - else { - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "%s maximum buf size is used\n", - __func__); - } - break; - } - } - - - if (!mmu_enable) { - hevc->m_BUF[i].index = i; - - if (use_cma == 2) - hevc->use_cma_flag = 1; - if (hevc->use_cma_flag) { - if (decoder_bmmu_box_alloc_idx_wait( - hevc->bmmu_box, - i, - buf_size, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - ) < 0) { - /* - not enough mem for buffer. - */ - hevc_print(hevc, 0, - "not enought buffer for [%d],%d\n", - i, buf_size); - hevc->m_BUF[i].start_adr = 0; - if (i <= 8) { - /*if alloced (i+1)>=9 - don't send errors.*/ - hevc->fatal_error |= - DECODER_FATAL_ERROR_NO_MEM; - } - break; - } - hevc->m_BUF[i].start_adr = - decoder_bmmu_box_get_phy_addr( - hevc->bmmu_box, - i); - pr_debug("allocate cma buffer[%d] %ld\n", - i, - hevc->m_BUF[i].start_adr); - } else { - hevc->m_BUF[i].start_adr = - hevc->mc_buf->buf_start + i * buf_size; - if (((hevc->m_BUF[i].start_adr + buf_size) > - mc_buffer_end)) { - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "Max mc buffer or mpred_mv buffer is used\n"); - } - break; - } - } - hevc->m_BUF[i].size = buf_size; - hevc->m_BUF[i].free_start_adr = - hevc->m_BUF[i].start_adr; - - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "Buffer %d: start_adr %p size %x\n", i, - (void *)hevc->m_BUF[i].start_adr, - hevc->m_BUF[i].size); - } - } - } - //put_cma_alloc_ref();//DEBUG_TMP - hevc_print(hevc, 0, "allocate end\n"); - - hevc->buf_num = i; - -} - -static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic, - unsigned int last_disp_addr) -{ - int ret = -1; - int i; - int pic_width = ((re_config_pic_flag == 0) && - get_buf_alloc_width(hevc)) ? - get_buf_alloc_width(hevc) : hevc->pic_w; - int pic_height = ((re_config_pic_flag == 0) && - get_buf_alloc_height(hevc)) ? - get_buf_alloc_height(hevc) : hevc->pic_h; - int lcu_size = hevc->lcu_size; - int pic_width_lcu = (pic_width % lcu_size) ? pic_width / lcu_size + - 1 : pic_width / lcu_size; - int pic_height_lcu = (pic_height % lcu_size) ? pic_height / lcu_size + - 1 : pic_height / lcu_size; - int lcu_total = pic_width_lcu * pic_height_lcu; - int lcu_size_log2 = hevc->lcu_size_log2; - /*int MV_MEM_UNIT=lcu_size_log2== - 6 ? 0x100 : lcu_size_log2==5 ? 0x40 : 0x10;*/ - int MV_MEM_UNIT = lcu_size_log2 == 6 ? 0x200 : lcu_size_log2 == - 5 ? 0x80 : 0x20; - int mpred_mv_end = hevc->work_space_buf->mpred_mv.buf_start + - hevc->work_space_buf->mpred_mv.buf_size; - unsigned int y_adr = 0; - int buf_size = 0; -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - int losless_comp_header_size = - compute_losless_comp_header_size(pic_width, - pic_height); - int losless_comp_body_size = compute_losless_comp_body_size(pic_width, - pic_height, hevc->mem_saving_mode); - 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; - if (get_double_write_mode(hevc)) { - int pic_width_dw = ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) ? - pic_width / 4 : pic_width; - int pic_height_dw = ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) ? - pic_height / 4 : pic_height; - 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; - - 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); - } - if (mc_buffer_size & 0xffff) { /*64k alignment*/ - mc_buffer_size_h += 1; - } - if (mmu_enable) { - if (get_double_write_mode(hevc) == 1) - buf_size += (mc_buffer_size_h << 16); - } else { - if ((get_double_write_mode(hevc) & 0x10) == 0) - buf_size += (mc_buffer_size_h << 16); - } -#else - 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); -#endif - - - if (mmu_enable) { - if ((hevc->work_space_buf->cm_header.buf_start + - ((pic->index + 1) - * MMU_COMPRESS_HEADER_SIZE)) - > (hevc->work_space_buf->cm_header.buf_start + - hevc->work_space_buf->cm_header.buf_size)) { - hevc_print(hevc, 0, - "MMU header_adr allocate fail\n"); - return -1; - } - - pic->header_adr = hevc->work_space_buf->cm_header.buf_start + - (pic->index * MMU_COMPRESS_HEADER_SIZE); - if (last_disp_addr && pic->header_adr == last_disp_addr) { - /*if same as disp add used last one.*/ - pr_info("same as disp %d: %d\n", - pic->index, pic->header_adr); - pic->header_adr = - hevc->work_space_buf->cm_header.buf_start + - (16 * MMU_COMPRESS_HEADER_SIZE); - } - if (get_dbg_flag(hevc)&H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "MMU header_adr %d: %x\n", - pic->index, pic->header_adr); - } - } - - - if ((hevc->work_space_buf->mpred_mv.buf_start + (((pic->index + 1) - * lcu_total) * MV_MEM_UNIT)) - <= mpred_mv_end) { - - if (!mmu_enable) { - for (i = 0; i < hevc->buf_num; i++) { - y_adr = ((hevc->m_BUF[i].free_start_adr - + 0xffff) >> 16) << 16; - /*64k alignment*/ - if ((y_adr+buf_size) <= - (hevc->m_BUF[i].start_adr+ - hevc->m_BUF[i].size)) { - hevc->m_BUF[i].free_start_adr = - y_adr + buf_size; - break; - } - } - } else - i = pic->index; - - if (i < hevc->buf_num) { - pic->POC = INVALID_POC; - /*ensure get_pic_by_POC() - not get the buffer not decoded*/ - pic->BUF_index = i; -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - pic->comp_body_size = losless_comp_body_size; - pic->buf_size = buf_size; - - if (!mmu_enable) - pic->mc_y_adr = y_adr; - else if (get_double_write_mode(hevc)) { - if ((hevc->mc_buf->buf_start - + (i + 1) * buf_size) - < hevc->mc_buf->buf_end) - y_adr = hevc->mc_buf->buf_start - + i * buf_size; - else { - if (decoder_bmmu_box_alloc_idx_wait( - hevc->bmmu_box, - pic->BUF_index, - buf_size, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - ) < 0) { - return -1; - } - pic->cma_alloc_addr = - decoder_bmmu_box_get_phy_addr( - hevc->bmmu_box, - pic->BUF_index); - if (pic->cma_alloc_addr) - y_adr = pic->cma_alloc_addr; - else - return -1; - } - } - pic->mc_canvas_y = pic->index; - pic->mc_canvas_u_v = pic->index; - if (!mmu_enable && get_double_write_mode(hevc) & 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 if (get_double_write_mode(hevc)) { - if (mmu_enable) - pic->dw_y_adr = y_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); - } -#else - pic->buf_size = (mc_buffer_size_u_v_h << 16) * 3; - pic->mc_y_adr = y_adr; - 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; -#endif - pic->mpred_mv_wr_start_addr = - hevc->work_space_buf->mpred_mv.buf_start + - ((pic->index * lcu_total) - * MV_MEM_UNIT); - - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "%s index %d BUF_index %d mc_y_adr %x ", - __func__, pic->index, - pic->BUF_index, pic->mc_y_adr); -#ifdef LOSLESS_COMPRESS_MODE - hevc_print_cont(hevc, 0, - "comp_body_size %x comp_buf_size %x ", - pic->comp_body_size, pic->buf_size); - hevc_print_cont(hevc, 0, - "mpred_mv_wr_start_adr %x\n", - pic->mpred_mv_wr_start_addr); - if (mmu_enable && get_double_write_mode(hevc)) - hevc_print(hevc, 0, - "mmu double write adr %ld\n", - pic->cma_alloc_addr); - -#else - hevc_print(hevc, 0, - ("mc_u_v_adr %x mpred_mv_wr_start_adr %x\n", - pic->mc_u_v_adr, pic->mpred_mv_wr_start_addr); -#endif - } - ret = 0; - } - } - return ret; -} - -/* -*free hevc->m_BUF[..] for all free hevc->m_PIC[..] -* with the different size of hevc->pic_w,hevc->pic_h -*/ -static int recycle_buf(struct hevc_state_s *hevc) -{ - int i, j; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - struct PIC_s *pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - if (pic->width != hevc->pic_w || pic->height != hevc->pic_h) { - if (pic->output_mark == 0 && pic->referenced == 0 - && pic->output_ready == 0) { - if (mmu_enable) { - decoder_mmu_box_free_idx(hevc->mmu_box, - pic->index); - } - pic->BUF_index = -1; - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "%s: %d\n", __func__, - pic->index); - } - } - } - } - - for (i = 0; i < hevc->buf_num; i++) { - if (hevc->m_BUF[i].free_start_adr != - hevc->m_BUF[i].start_adr) { - for (j = 0; j < MAX_REF_PIC_NUM; j++) { - struct PIC_s *pic = hevc->m_PIC[j]; - if (pic == NULL || pic->index == -1) - continue; - if (pic->BUF_index == i) - break; - } - if (j == MAX_REF_PIC_NUM) - hevc->m_BUF[i].free_start_adr = - hevc->m_BUF[i].start_adr; - } - } - return 0; -} - -static void init_pic_list(struct hevc_state_s *hevc) -{ - int i; - struct vframe_s vf; - unsigned long flags; - unsigned long disp_addr = 0; - - if (!get_video0_frame_info(&vf)) { - spin_lock_irqsave(&lock, flags); - if (vf.type & VIDTYPE_SCATTER) { - /*sc only used header.*/ - disp_addr = (VSYNC_RD_MPEG_REG(AFBC_HEAD_BADDR) << 4); - } else if (vf.type & VIDTYPE_COMPRESS) { - /*sc checked body.*/ - disp_addr = (VSYNC_RD_MPEG_REG(AFBC_BODY_BADDR) << 4); - } else { - struct canvas_s cur_canvas; - - canvas_read(vf.canvas0Addr & 0xff, &cur_canvas); - disp_addr = cur_canvas.addr; - } - spin_unlock_irqrestore(&lock, flags); - } - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - struct PIC_s *pic = - vmalloc(sizeof(struct PIC_s)); - if (pic == NULL) { - hevc_print(hevc, 0, - "alloc pic %d fail\n", i); - break; - } - memset(pic, 0, sizeof(struct PIC_s)); - hevc->m_PIC[i] = pic; - pic->index = i; - pic->BUF_index = -1; - if (config_pic(hevc, pic, disp_addr) < 0) { - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "Config_pic %d fail\n", pic->index); - pic->index = -1; - i++; - break; - } - pic->width = hevc->pic_w; - pic->height = hevc->pic_h; - if (get_double_write_mode(hevc)) - set_canvas(hevc, pic); - } - - for (; i < MAX_REF_PIC_NUM; i++) { - struct PIC_s *pic = - vmalloc(sizeof(struct PIC_s)); - if (pic == NULL) { - hevc_print(hevc, 0, - "alloc pic %d fail\n", i); - break; - } - memset(pic, 0, sizeof(struct PIC_s)); - hevc->m_PIC[i] = pic; - pic->index = -1; - pic->BUF_index = -1; - } - -} - -static void uninit_pic_list(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) { - release_aux_data(hevc, pic); - vfree(pic); - hevc->m_PIC[i] = NULL; - } - } -} - -#ifdef LOSLESS_COMPRESS_MODE -static void init_decode_head_hw(struct hevc_state_s *hevc) -{ - - struct BuffInfo_s *buf_spec = hevc->work_space_buf; - unsigned int data32; - - int losless_comp_header_size = - compute_losless_comp_header_size(hevc->pic_w, - hevc->pic_h); - int losless_comp_body_size = compute_losless_comp_body_size(hevc->pic_w, - hevc->pic_h, hevc->mem_saving_mode); - - hevc->losless_comp_body_size = losless_comp_body_size; - - - if (mmu_enable) { - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4)); - WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0); - } else { - if (hevc->mem_saving_mode == 1) - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, - (1 << 3) | ((workaround_enable & 2) ? 1 : 0)); - else - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, - ((workaround_enable & 2) ? 1 : 0)); - 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); - - if (mmu_enable) { - WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start); - WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, - buf_spec->mmu_vbh.buf_start + - buf_spec->mmu_vbh.buf_size/2); - 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); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - } - - if (!hevc->m_ins_flag) - hevc_print(hevc, 0, - "%s: (%d, %d) body_size 0x%x header_size 0x%x\n", - __func__, hevc->pic_w, hevc->pic_h, - losless_comp_body_size, losless_comp_header_size); - -} -#endif -#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464 - -static void init_pic_list_hw(struct hevc_state_s *hevc) -{ - int i; - int cur_pic_num = MAX_REF_PIC_NUM; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, - (0x1 << 1) | (0x1 << 2)); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0); - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - if (hevc->m_PIC[i] == NULL || - hevc->m_PIC[i]->index == -1) { - cur_pic_num = i; - break; - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - if (mmu_enable) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[i]->header_adr>>5); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[i]->mc_y_adr >> 5); - } else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[i]->mc_y_adr | - (hevc->m_PIC[i]->mc_canvas_y << 8) | 0x1); - if (get_double_write_mode(hevc) & 0x10) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - if (mmu_enable) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[i]->header_adr>>5); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[i]->mc_u_v_adr >> 5); - } - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[i]->mc_u_v_adr | - (hevc->m_PIC[i]->mc_canvas_u_v << 8) - | 0x1); - } - } - if (cur_pic_num == 0) - return; - for (; i < MAX_REF_PIC_NUM; i++) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - if (mmu_enable) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->header_adr>>5); - else - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr >> 5); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr >> 5); -#endif - } else { - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_y_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_y<<8) - | 0x1); -#ifndef LOSLESS_COMPRESS_MODE - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - hevc->m_PIC[cur_pic_num-1]->mc_u_v_adr| - (hevc->m_PIC[cur_pic_num-1]->mc_canvas_u_v<<8) - | 0x1); -#endif - } - } - - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); - - /* 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 LOSLESS_COMPRESS_MODE - if ((get_double_write_mode(hevc) & 0x10) == 0) - init_decode_head_hw(hevc); -#endif - -} - - -static void dump_pic_list(struct hevc_state_s *hevc) -{ - int i; - struct PIC_s *pic; - hevc_print(hevc, 0, - "pic_list_init_flag is %d\r\n", hevc->pic_list_init_flag); - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - hevc_print_cont(hevc, 0, - "index %d decode_idx:%d, POC:%d, referenced:%d, ", - pic->index, pic->decode_idx, pic->POC, pic->referenced); - hevc_print_cont(hevc, 0, - "num_reorder_pic:%d, output_mark:%d, w/h %d,%d", - pic->num_reorder_pic, pic->output_mark, - pic->width, pic->height); - hevc_print_cont(hevc, 0, - "output_ready:%d, mv_wr_start %x vf_ref %d\n", - pic->output_ready, pic->mpred_mv_wr_start_addr, - pic->vf_ref); - } -} - -static struct PIC_s *output_pic(struct hevc_state_s *hevc, - unsigned char flush_flag) -{ - int num_pic_not_yet_display = 0; - int i; - struct PIC_s *pic; - struct PIC_s *pic_display = NULL; - - if (i_only_flag & 0x4) { - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || - (pic->index == -1) || (pic->POC == INVALID_POC)) - continue; - if (pic->output_mark) { - if (pic_display) { - if (pic->decode_idx < - pic_display->decode_idx) - pic_display = pic; - - } else - pic_display = pic; - - } - } - if (pic_display) { - pic_display->output_mark = 0; - pic_display->recon_mark = 0; - pic_display->output_ready = 1; - pic_display->referenced = 0; - } - } else { - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || - (pic->index == -1) || (pic->POC == INVALID_POC)) - continue; - if (pic->output_mark) - num_pic_not_yet_display++; - } - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || - (pic->index == -1) || (pic->POC == INVALID_POC)) - continue; - if (pic->output_mark) { - if (pic_display) { - if (pic->POC < pic_display->POC) - pic_display = pic; - else if ((pic->POC == pic_display->POC) - && (pic->decode_idx < - pic_display-> - decode_idx)) - pic_display - = pic; - } else - pic_display = pic; - } - } - if (pic_display) { - if ((num_pic_not_yet_display > - pic_display->num_reorder_pic) - || flush_flag) { - pic_display->output_mark = 0; - pic_display->recon_mark = 0; - pic_display->output_ready = 1; - } else if (num_pic_not_yet_display >= - (MAX_REF_PIC_NUM - 1)) { - pic_display->output_mark = 0; - pic_display->recon_mark = 0; - pic_display->output_ready = 1; - hevc_print(hevc, 0, - "Warning, num_reorder_pic %d is byeond buf num\n", - pic_display->num_reorder_pic); - } else - pic_display = NULL; - } - } - return pic_display; -} - -static int config_mc_buffer(struct hevc_state_s *hevc, struct PIC_s *cur_pic) -{ - int i; - struct PIC_s *pic; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "config_mc_buffer entered .....\n"); - if (cur_pic->slice_type != 2) { /* P and B pic */ - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (0 << 8) | (0 << 1) | 1); - for (i = 0; i < cur_pic->RefNum_L0; i++) { - pic = - get_ref_pic_by_POC(hevc, - cur_pic-> - m_aiRefPOCList0[cur_pic-> - slice_idx][i]); - if (pic) { - if (pic->error_mark) - cur_pic->error_mark = 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 (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, - "refid %x mc_canvas_u_v %x", - i, pic->mc_canvas_u_v); - hevc_print_cont(hevc, 0, - " mc_canvas_y %x\n", - pic->mc_canvas_y); - } - } else { - if (get_dbg_flag(hevc)) { - hevc_print_cont(hevc, 0, - "Error %s, %dth poc (%d)", - __func__, i, - cur_pic->m_aiRefPOCList0[cur_pic-> - slice_idx][i]); - hevc_print_cont(hevc, 0, - " of RPS is not in the pic list0\n"); - } - cur_pic->error_mark = 1; - /* dump_lmem(); */ - } - } - } - if (cur_pic->slice_type == 0) { /* B pic */ - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "config_mc_buffer RefNum_L1\n"); - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (16 << 8) | (0 << 1) | 1); - for (i = 0; i < cur_pic->RefNum_L1; i++) { - pic = - get_ref_pic_by_POC(hevc, - cur_pic-> - m_aiRefPOCList1[cur_pic-> - slice_idx][i]); - if (pic) { - if (pic->error_mark) - cur_pic->error_mark = 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 (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, - "refid %x mc_canvas_u_v %x", - i, pic->mc_canvas_u_v); - hevc_print_cont(hevc, 0, - " mc_canvas_y %x\n", - pic->mc_canvas_y); - } - } else { - if (get_dbg_flag(hevc)) { - hevc_print_cont(hevc, 0, - "Error %s, %dth poc (%d)", - __func__, i, - cur_pic->m_aiRefPOCList1[cur_pic-> - slice_idx][i]); - hevc_print_cont(hevc, 0, - " of RPS is not in the pic list1\n"); - } - cur_pic->error_mark = 1; - /* dump_lmem(); */ - } - } - } - return 0; -} - -static void apply_ref_pic_set(struct hevc_state_s *hevc, int cur_poc, - union param_u *params) -{ - int ii, i; - int poc_tmp; - struct PIC_s *pic; - unsigned char is_referenced; - - /* pr_info("%s cur_poc %d\n", __func__, cur_poc); */ - for (ii = 0; ii < MAX_REF_PIC_NUM; ii++) { - pic = hevc->m_PIC[ii]; - if (pic == NULL || - pic->index == -1) - continue; - - if ((pic->referenced == 0 || pic->POC == cur_poc)) - continue; - is_referenced = 0; - for (i = 0; i < 16; i++) { - int delt; - - if (params->p.CUR_RPS[i] & 0x8000) - break; - delt = - params->p.CUR_RPS[i] & - ((1 << (RPS_USED_BIT - 1)) - 1); - if (params->p.CUR_RPS[i] & (1 << (RPS_USED_BIT - 1))) { - poc_tmp = - cur_poc - ((1 << (RPS_USED_BIT - 1)) - - delt); - } else - poc_tmp = cur_poc + delt; - if (poc_tmp == pic->POC) { - is_referenced = 1; - /* pr_info("i is %d\n", i); */ - break; - } - } - if (is_referenced == 0) { - pic->referenced = 0; - /* pr_info("set poc %d reference to 0\n", pic->POC); */ - } - } - -} - -static void set_ref_pic_list(struct hevc_state_s *hevc, union param_u *params) -{ - struct PIC_s *pic = hevc->cur_pic; - int i, rIdx; - int num_neg = 0; - int num_pos = 0; - int total_num; - int num_ref_idx_l0_active = - (params->p.num_ref_idx_l0_active > - MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : - params->p.num_ref_idx_l0_active; - int num_ref_idx_l1_active = - (params->p.num_ref_idx_l1_active > - MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : - params->p.num_ref_idx_l1_active; - - int RefPicSetStCurr0[16]; - int RefPicSetStCurr1[16]; - - for (i = 0; i < 16; i++) { - RefPicSetStCurr0[i] = 0; - RefPicSetStCurr1[i] = 0; - pic->m_aiRefPOCList0[pic->slice_idx][i] = 0; - pic->m_aiRefPOCList1[pic->slice_idx][i] = 0; - } - for (i = 0; i < 16; i++) { - if (params->p.CUR_RPS[i] & 0x8000) - break; - if ((params->p.CUR_RPS[i] >> RPS_USED_BIT) & 1) { - int delt = - params->p.CUR_RPS[i] & - ((1 << (RPS_USED_BIT - 1)) - 1); - - if ((params->p.CUR_RPS[i] >> (RPS_USED_BIT - 1)) & 1) { - RefPicSetStCurr0[num_neg] = - pic->POC - ((1 << (RPS_USED_BIT - 1)) - - delt); - /* hevc_print(hevc, 0, - "RefPicSetStCurr0 %x %x %x\n", - RefPicSetStCurr0[num_neg], pic->POC, - (0x800-(params[i]&0x7ff))); */ - num_neg++; - } else { - RefPicSetStCurr1[num_pos] = pic->POC + delt; - /* hevc_print(hevc, 0, - "RefPicSetStCurr1 %d\n", - RefPicSetStCurr1[num_pos]); */ - num_pos++; - } - } - } - total_num = num_neg + num_pos; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "%s: curpoc %d slice_type %d, total %d ", - __func__, pic->POC, params->p.slice_type, total_num); - hevc_print_cont(hevc, 0, - "num_neg %d num_list0 %d num_list1 %d\n", - num_neg, num_ref_idx_l0_active, num_ref_idx_l1_active); - } - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "HEVC Stream buf start "); - hevc_print_cont(hevc, 0, - "%x end %x wr %x rd %x lev %x ctl %x intctl %x\n", - READ_VREG(HEVC_STREAM_START_ADDR), - READ_VREG(HEVC_STREAM_END_ADDR), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR), - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_FIFO_CTL), - READ_VREG(HEVC_PARSER_INT_CONTROL)); - } - - if (total_num > 0) { - if (params->p.modification_flag & 0x1) { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, "ref0 POC (modification):"); - for (rIdx = 0; rIdx < num_ref_idx_l0_active; rIdx++) { - int cIdx = params->p.modification_list[rIdx]; - - pic->m_aiRefPOCList0[pic->slice_idx][rIdx] = - cIdx >= - num_neg ? RefPicSetStCurr1[cIdx - - num_neg] : - RefPicSetStCurr0[cIdx]; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, "%d ", - pic->m_aiRefPOCList0[pic-> - slice_idx] - [rIdx]); - } - } - } else { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, "ref0 POC:"); - for (rIdx = 0; rIdx < num_ref_idx_l0_active; rIdx++) { - int cIdx = rIdx % total_num; - - pic->m_aiRefPOCList0[pic->slice_idx][rIdx] = - cIdx >= - num_neg ? RefPicSetStCurr1[cIdx - - num_neg] : - RefPicSetStCurr0[cIdx]; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, "%d ", - pic->m_aiRefPOCList0[pic-> - slice_idx] - [rIdx]); - } - } - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, "\n"); - if (params->p.slice_type == B_SLICE) { - if (params->p.modification_flag & 0x2) { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "ref1 POC (modification):"); - for (rIdx = 0; rIdx < num_ref_idx_l1_active; - rIdx++) { - int cIdx; - - if (params->p.modification_flag & 0x1) { - cIdx = - params->p. - modification_list - [num_ref_idx_l0_active + - rIdx]; - } else { - cIdx = - params->p. - modification_list[rIdx]; - } - pic->m_aiRefPOCList1[pic-> - slice_idx][rIdx] = - cIdx >= - num_pos ? - RefPicSetStCurr0[cIdx - num_pos] - : RefPicSetStCurr1[cIdx]; - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, "%d ", - pic-> - m_aiRefPOCList1[pic-> - slice_idx] - [rIdx]); - } - } - } else { - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, "ref1 POC:"); - for (rIdx = 0; rIdx < num_ref_idx_l1_active; - rIdx++) { - int cIdx = rIdx % total_num; - pic->m_aiRefPOCList1[pic-> - slice_idx][rIdx] = - cIdx >= - num_pos ? - RefPicSetStCurr0[cIdx - - num_pos] - : RefPicSetStCurr1[cIdx]; - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, "%d ", - pic-> - m_aiRefPOCList1[pic-> - slice_idx] - [rIdx]); - } - } - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, "\n"); - } - } - /*set m_PIC */ - pic->slice_type = (params->p.slice_type == I_SLICE) ? 2 : - (params->p.slice_type == P_SLICE) ? 1 : - (params->p.slice_type == B_SLICE) ? 0 : 3; - pic->RefNum_L0 = num_ref_idx_l0_active; - pic->RefNum_L1 = num_ref_idx_l1_active; -} - -static void update_tile_info(struct hevc_state_s *hevc, int pic_width_cu, - int pic_height_cu, int sao_mem_unit, - union param_u *params) -{ - int i, j; - int start_cu_x, start_cu_y; - int sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu; - int sao_abv_size = sao_mem_unit * pic_width_cu; - - hevc->tile_enabled = params->p.tiles_enabled_flag & 1; - if (params->p.tiles_enabled_flag & 1) { - hevc->num_tile_col = params->p.num_tile_columns_minus1 + 1; - hevc->num_tile_row = params->p.num_tile_rows_minus1 + 1; - - if (hevc->num_tile_row > MAX_TILE_ROW_NUM - || hevc->num_tile_row <= 0) { - hevc->num_tile_row = 1; - hevc_print(hevc, 0, - "%s: num_tile_rows_minus1 (%d) error!!\n", - __func__, params->p.num_tile_rows_minus1); - } - if (hevc->num_tile_col > MAX_TILE_COL_NUM - || hevc->num_tile_col <= 0) { - hevc->num_tile_col = 1; - hevc_print(hevc, 0, - "%s: num_tile_columns_minus1 (%d) error!!\n", - __func__, params->p.num_tile_columns_minus1); - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "%s pic_w_cu %d pic_h_cu %d tile_enabled ", - __func__, pic_width_cu, pic_height_cu); - hevc_print_cont(hevc, 0, - "num_tile_col %d num_tile_row %d:\n", - hevc->num_tile_col, hevc->num_tile_row); - } - - if (params->p.tiles_enabled_flag & 2) { /* uniform flag */ - int w = pic_width_cu / hevc->num_tile_col; - int h = pic_height_cu / hevc->num_tile_row; - - start_cu_y = 0; - for (i = 0; i < hevc->num_tile_row; i++) { - start_cu_x = 0; - for (j = 0; j < hevc->num_tile_col; j++) { - if (j == (hevc->num_tile_col - 1)) { - hevc->m_tile[i][j].width = - pic_width_cu - - start_cu_x; - } else - hevc->m_tile[i][j].width = w; - if (i == (hevc->num_tile_row - 1)) { - hevc->m_tile[i][j].height = - pic_height_cu - - start_cu_y; - } else - hevc->m_tile[i][j].height = h; - hevc->m_tile[i][j].start_cu_x - = start_cu_x; - hevc->m_tile[i][j].start_cu_y - = start_cu_y; - hevc->m_tile[i][j].sao_vb_start_addr = - hevc->work_space_buf->sao_vb. - buf_start + j * sao_vb_size; - hevc->m_tile[i][j].sao_abv_start_addr = - hevc->work_space_buf->sao_abv. - buf_start + i * sao_abv_size; - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, - "{y=%d, x=%d w %d h %d ", - i, j, hevc->m_tile[i][j].width, - hevc->m_tile[i][j].height); - hevc_print_cont(hevc, 0, - "start_x %d start_y %d ", - hevc->m_tile[i][j].start_cu_x, - hevc->m_tile[i][j].start_cu_y); - hevc_print_cont(hevc, 0, - "sao_vb_start 0x%x ", - hevc->m_tile[i][j]. - sao_vb_start_addr); - hevc_print_cont(hevc, 0, - "sao_abv_start 0x%x}\n", - hevc->m_tile[i][j]. - sao_abv_start_addr); - } - start_cu_x += hevc->m_tile[i][j].width; - - } - start_cu_y += hevc->m_tile[i][0].height; - } - } else { - start_cu_y = 0; - for (i = 0; i < hevc->num_tile_row; i++) { - start_cu_x = 0; - for (j = 0; j < hevc->num_tile_col; j++) { - if (j == (hevc->num_tile_col - 1)) { - hevc->m_tile[i][j].width = - pic_width_cu - - start_cu_x; - } else { - hevc->m_tile[i][j].width = - params->p.tile_width[j]; - } - if (i == (hevc->num_tile_row - 1)) { - hevc->m_tile[i][j].height = - pic_height_cu - - start_cu_y; - } else { - hevc->m_tile[i][j].height = - params-> - p.tile_height[i]; - } - hevc->m_tile[i][j].start_cu_x - = start_cu_x; - hevc->m_tile[i][j].start_cu_y - = start_cu_y; - hevc->m_tile[i][j].sao_vb_start_addr = - hevc->work_space_buf->sao_vb. - buf_start + j * sao_vb_size; - hevc->m_tile[i][j].sao_abv_start_addr = - hevc->work_space_buf->sao_abv. - buf_start + i * sao_abv_size; - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print_cont(hevc, 0, - "{y=%d, x=%d w %d h %d ", - i, j, hevc->m_tile[i][j].width, - hevc->m_tile[i][j].height); - hevc_print_cont(hevc, 0, - "start_x %d start_y %d ", - hevc->m_tile[i][j].start_cu_x, - hevc->m_tile[i][j].start_cu_y); - hevc_print_cont(hevc, 0, - "sao_vb_start 0x%x ", - hevc->m_tile[i][j]. - sao_vb_start_addr); - hevc_print_cont(hevc, 0, - "sao_abv_start 0x%x}\n", - hevc->m_tile[i][j]. - sao_abv_start_addr); - - } - start_cu_x += hevc->m_tile[i][j].width; - } - start_cu_y += hevc->m_tile[i][0].height; - } - } - } else { - hevc->num_tile_col = 1; - hevc->num_tile_row = 1; - hevc->m_tile[0][0].width = pic_width_cu; - hevc->m_tile[0][0].height = pic_height_cu; - hevc->m_tile[0][0].start_cu_x = 0; - hevc->m_tile[0][0].start_cu_y = 0; - hevc->m_tile[0][0].sao_vb_start_addr = - hevc->work_space_buf->sao_vb.buf_start; - hevc->m_tile[0][0].sao_abv_start_addr = - hevc->work_space_buf->sao_abv.buf_start; - } -} - -static int get_tile_index(struct hevc_state_s *hevc, int cu_adr, - int pic_width_lcu) -{ - int cu_x; - int cu_y; - int tile_x = 0; - int tile_y = 0; - int i; - - if (pic_width_lcu == 0) { - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "%s Error, pic_width_lcu is 0, pic_w %d, pic_h %d\n", - __func__, hevc->pic_w, hevc->pic_h); - } - return -1; - } - cu_x = cu_adr % pic_width_lcu; - cu_y = cu_adr / pic_width_lcu; - if (hevc->tile_enabled) { - for (i = 0; i < hevc->num_tile_col; i++) { - if (cu_x >= hevc->m_tile[0][i].start_cu_x) - tile_x = i; - else - break; - } - for (i = 0; i < hevc->num_tile_row; i++) { - if (cu_y >= hevc->m_tile[i][0].start_cu_y) - tile_y = i; - else - break; - } - } - return (tile_x) | (tile_y << 8); -} - -static void print_scratch_error(int error_num) -{ -#if 0 - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - " ERROR : HEVC_ASSIST_SCRATCH_TEST Error : %d\n", - error_num); - } -#endif -} - -static void hevc_config_work_space_hw(struct hevc_state_s *hevc) -{ - struct BuffInfo_s *buf_spec = hevc->work_space_buf; - - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "%s %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->vps.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); - WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start); - if ((get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) == 0) - WRITE_VREG(HEVC_RPM_BUFFER, (u32)hevc->rpm_phy_addr); - WRITE_VREG(HEVC_SHORT_TERM_RPS, buf_spec->short_term_rps.buf_start); - WRITE_VREG(HEVC_VPS_BUFFER, buf_spec->vps.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); - if (mmu_enable) - WRITE_VREG(H265_MMU_MAP_BUFFER, hevc->frame_mmu_map_phy_addr); - else - WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, - buf_spec->swap_buf.buf_start); - WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start); - WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); - /* 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_dbg_flag(hevc) & H265_DEBUG_UCODE) - WRITE_VREG(LMEM_DUMP_ADR, (u32)hevc->lmem_phy_addr); - -} - -static void hevc_init_decoder_hw(struct hevc_state_s *hevc, - int decode_pic_begin, int decode_pic_num) -{ - unsigned int data32; - int i; - -#if 1 - /* m8baby test1902 */ - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "[test.c] Test Parser Register Read/Write\n"); - data32 = READ_VREG(HEVC_PARSER_VERSION); - if (data32 != 0x00010001) { - print_scratch_error(25); - return; - } - WRITE_VREG(HEVC_PARSER_VERSION, 0x5a5a55aa); - data32 = READ_VREG(HEVC_PARSER_VERSION); - if (data32 != 0x5a5a55aa) { - print_scratch_error(26); - return; - } -#if 0 - /* test Parser Reset */ - /* reset iqit to start mem init again */ - WRITE_VREG(DOS_SW_RESET3, (1 << 14) | - (1 << 3) /* reset_whole parser */ - ); - WRITE_VREG(DOS_SW_RESET3, 0); /* clear reset_whole parser */ - data32 = READ_VREG(HEVC_PARSER_VERSION); - if (data32 != 0x00010001) - hevc_print(hevc, 0, - "Test Parser Fatal Error\n"); -#endif - /* reset iqit to start mem init again */ - WRITE_VREG(DOS_SW_RESET3, (1 << 14) - ); - CLEAR_VREG_MASK(HEVC_CABAC_CONTROL, 1); - CLEAR_VREG_MASK(HEVC_PARSER_CORE_CONTROL, 1); - -#endif - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "[test.c] Enable BitStream Fetch\n"); - ; - if (!hevc->m_ins_flag) { - data32 = READ_VREG(HEVC_STREAM_CONTROL); - data32 = data32 | (1 << 0); /* stream_fetch_enable */ - WRITE_VREG(HEVC_STREAM_CONTROL, data32); - } - data32 = READ_VREG(HEVC_SHIFT_STARTCODE); - if (data32 != 0x00000100) { - print_scratch_error(29); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x00000300) { - print_scratch_error(30); - return; - } - WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678); - WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0); - data32 = READ_VREG(HEVC_SHIFT_STARTCODE); - if (data32 != 0x12345678) { - print_scratch_error(31); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x9abcdef0) { - print_scratch_error(32); - return; - } - WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100); - WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300); - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "[test.c] Enable HEVC Parser Interrupt\n"); - data32 = READ_VREG(HEVC_PARSER_INT_CONTROL); - data32 &= 0x03ffffff; - data32 = data32 | (3 << 29) | (2 << 26) | (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); - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "[test.c] Enable HEVC Parser Shift\n"); - - data32 = READ_VREG(HEVC_SHIFT_STATUS); - data32 = data32 | (1 << 1) | /* emulation_check_on */ - (1 << 0) /* startcode_check_on */ - ; - WRITE_VREG(HEVC_SHIFT_STATUS, data32); - - WRITE_VREG(HEVC_SHIFT_CONTROL, (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_CABAC_CONTROL, (1 << 0) /* cabac_enable */ - ); - /* hevc_parser_core_clk_en */ - WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0) - ); - - WRITE_VREG(HEVC_DEC_STATUS_REG, 0); - - /* Initial IQIT_SCALELUT memory -- just to avoid X in simulation */ - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[test.c] Initial IQIT_SCALELUT memory --"); - hevc_print_cont(hevc, 0, - " just to avoid X in simulation...\n"); - } - WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); /* cfg_p_addr */ - for (i = 0; i < 1024; i++) - WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); - -#ifdef ENABLE_SWAP_TEST - WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100); -#endif - - /*WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);*/ - /*WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0xffffffff);*/ - WRITE_VREG(HEVC_DECODE_SIZE, 0); - /*WRITE_VREG(HEVC_DECODE_COUNT, 0);*/ - /* Send parser_cmd */ - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "[test.c] SEND Parser Command ...\n"); - WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0)); - for (i = 0; i < PARSER_CMD_NUMBER; i++) - WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]); - - WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0); - WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1); - WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2); - - WRITE_VREG(HEVC_PARSER_IF_CONTROL, - /* (1 << 8) | // sao_sw_pred_enable */ - (1 << 5) | /* parser_sao_if_en */ - (1 << 2) | /* parser_mpred_if_en */ - (1 << 0) /* parser_scaler_if_en */ - ); - - /* Changed to Start MPRED in microcode */ - /* - hevc_print(hevc, 0, "[test.c] Start MPRED\n"); - WRITE_VREG(HEVC_MPRED_INT_STATUS, - (1<<31) - ); - */ - - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "[test.c] Reset IPP\n"); - 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 (get_double_write_mode(hevc) & 0x10) - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, - 0x1 << 31 /*/Enable NV21 reference read mode for MC*/ - ); - -} - -static void decoder_hw_reset(void) -{ - int i; - unsigned int data32; - /* reset iqit to start mem init again */ - WRITE_VREG(DOS_SW_RESET3, (1 << 14) - ); - CLEAR_VREG_MASK(HEVC_CABAC_CONTROL, 1); - CLEAR_VREG_MASK(HEVC_PARSER_CORE_CONTROL, 1); - - data32 = READ_VREG(HEVC_STREAM_CONTROL); - data32 = data32 | (1 << 0) /* stream_fetch_enable */ - ; - WRITE_VREG(HEVC_STREAM_CONTROL, data32); - - data32 = READ_VREG(HEVC_SHIFT_STARTCODE); - if (data32 != 0x00000100) { - print_scratch_error(29); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x00000300) { - print_scratch_error(30); - return; - } - WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678); - WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0); - data32 = READ_VREG(HEVC_SHIFT_STARTCODE); - if (data32 != 0x12345678) { - print_scratch_error(31); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x9abcdef0) { - print_scratch_error(32); - return; - } - WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100); - WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300); - - data32 = READ_VREG(HEVC_PARSER_INT_CONTROL); - data32 &= 0x03ffffff; - data32 = data32 | (3 << 29) | (2 << 26) | (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 | (1 << 1) | /* emulation_check_on */ - (1 << 0) /* startcode_check_on */ - ; - WRITE_VREG(HEVC_SHIFT_STATUS, data32); - - WRITE_VREG(HEVC_SHIFT_CONTROL, (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_CABAC_CONTROL, (1 << 0) /* cabac_enable */ - ); - /* hevc_parser_core_clk_en */ - WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0) - ); - - /* Initial IQIT_SCALELUT memory -- just to avoid X in simulation */ - WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); /* cfg_p_addr */ - for (i = 0; i < 1024; i++) - WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 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 << 8) | // sao_sw_pred_enable */ - (1 << 5) | /* parser_sao_if_en */ - (1 << 2) | /* parser_mpred_if_en */ - (1 << 0) /* parser_scaler_if_en */ - ); - - 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 */ - ); -} - -#ifdef CONFIG_HEVC_CLK_FORCED_ON -static void config_hevc_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 | (0x3 << 5) | (0x3 << 2) | (0x3 << 0)); - - /* 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 - -#ifdef MCRCC_ENABLE -static void config_mcrcc_axi_hw(struct hevc_state_s *hevc, int slice_type) -{ - unsigned int rdata32; - unsigned int rdata32_2; - int l0_cnt = 0; - int l1_cnt = 0x7fff; - if (get_double_write_mode(hevc) & 0x10) { - l0_cnt = hevc->cur_pic->RefNum_L0; - l1_cnt = hevc->cur_pic->RefNum_L1; - } - - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); /* reset mcrcc */ - - if (slice_type == 2) { /* I-PIC */ - /* remove reset -- disables clock */ - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0); - return; - } - - if (slice_type == 0) { /* B-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 && l1_cnt > 1) { - 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); - - if (l0_cnt == 1) { - WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32); - } else { - /* 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; -} -#endif - -static void config_title_hw(struct hevc_state_s *hevc, int sao_vb_size, - int sao_mem_unit) -{ - WRITE_VREG(HEVC_sao_mem_unit, sao_mem_unit); - WRITE_VREG(HEVC_SAO_ABV, hevc->work_space_buf->sao_abv.buf_start); - WRITE_VREG(HEVC_sao_vb_size, sao_vb_size); - WRITE_VREG(HEVC_SAO_VB, hevc->work_space_buf->sao_vb.buf_start); -} - -static void config_aux_buf(struct hevc_state_s *hevc) -{ - WRITE_VREG(HEVC_AUX_ADR, hevc->aux_phy_addr); - WRITE_VREG(HEVC_AUX_DATA_SIZE, - ((hevc->prefix_aux_size >> 4) << 16) | - (hevc->suffix_aux_size >> 4) - ); -} - -static void config_mpred_hw(struct hevc_state_s *hevc) -{ - int i; - unsigned int data32; - struct PIC_s *cur_pic = hevc->cur_pic; - struct PIC_s *col_pic = hevc->col_pic; - int AMVP_MAX_NUM_CANDS_MEM = 3; - int AMVP_MAX_NUM_CANDS = 2; - int NUM_CHROMA_MODE = 5; - int DM_CHROMA_IDX = 36; - int above_ptr_ctrl = 0; - int buffer_linear = 1; - int cu_size_log2 = 3; - - int mpred_mv_rd_start_addr; - int mpred_curr_lcu_x; - int mpred_curr_lcu_y; - int mpred_above_buf_start; - int mpred_mv_rd_ptr; - int mpred_mv_rd_ptr_p1; - int mpred_mv_rd_end_addr; - int MV_MEM_UNIT; - int mpred_mv_wr_ptr; - int *ref_poc_L0, *ref_poc_L1; - - int above_en; - int mv_wr_en; - int mv_rd_en; - int col_isIntra; - - if (hevc->slice_type != 2) { - 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 = - hevc->lcu_size_log2 == 6 ? 0x200 : hevc->lcu_size_log2 == - 5 ? 0x80 : 0x20; - mpred_mv_rd_ptr = - mpred_mv_rd_start_addr + (hevc->slice_addr * MV_MEM_UNIT); - - mpred_mv_rd_ptr_p1 = mpred_mv_rd_ptr + MV_MEM_UNIT; - mpred_mv_rd_end_addr = - mpred_mv_rd_start_addr + - ((hevc->lcu_x_num * hevc->lcu_y_num) * MV_MEM_UNIT); - - mpred_above_buf_start = hevc->work_space_buf->mpred_above.buf_start; - - mpred_mv_wr_ptr = - cur_pic->mpred_mv_wr_start_addr + - (hevc->slice_addr * MV_MEM_UNIT); - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "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, mpred_mv_rd_start_addr); - - data32 = ((hevc->lcu_x_num - hevc->tile_width_lcu) * MV_MEM_UNIT); - WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP, data32); - WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP, data32); - - data32 = READ_VREG(HEVC_MPRED_CTRL0); - data32 = (hevc->slice_type | - hevc->new_pic << 2 | - hevc->new_tile << 3 | - hevc->isNextSliceSegment << 4 | - hevc->TMVPFlag << 5 | - hevc->LDCFlag << 6 | - hevc->ColFromL0Flag << 7 | - above_ptr_ctrl << 8 | - above_en << 9 | - mv_wr_en << 10 | - mv_rd_en << 11 | - col_isIntra << 12 | - buffer_linear << 13 | - hevc->LongTerm_Curr << 14 | - hevc->LongTerm_Col << 15 | - hevc->lcu_size_log2 << 16 | - cu_size_log2 << 20 | hevc->plevel << 24); - WRITE_VREG(HEVC_MPRED_CTRL0, data32); - - data32 = READ_VREG(HEVC_MPRED_CTRL1); - data32 = ( -#if 0 - /* no set in m8baby test1902 */ - /* Don't override clk_forced_on , */ - (data32 & (0x1 << 24)) | -#endif - hevc->MaxNumMergeCand | - AMVP_MAX_NUM_CANDS << 4 | - AMVP_MAX_NUM_CANDS_MEM << 8 | - NUM_CHROMA_MODE << 12 | DM_CHROMA_IDX << 16); - WRITE_VREG(HEVC_MPRED_CTRL1, data32); - - data32 = (hevc->pic_w | hevc->pic_h << 16); - WRITE_VREG(HEVC_MPRED_PIC_SIZE, data32); - - data32 = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16); - WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU, data32); - - data32 = (hevc->tile_start_lcu_x | hevc->tile_start_lcu_y << 16); - WRITE_VREG(HEVC_MPRED_TILE_START, data32); - - data32 = (hevc->tile_width_lcu | hevc->tile_height_lcu << 16); - WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU, data32); - - data32 = (hevc->RefNum_L0 | hevc->RefNum_L1 << 8 | 0 - /* col_RefNum_L0<<16| */ - /* col_RefNum_L1<<24 */ - ); - WRITE_VREG(HEVC_MPRED_REF_NUM, data32); - - data32 = (hevc->LongTerm_Ref); - WRITE_VREG(HEVC_MPRED_LT_REF, data32); - - data32 = 0; - for (i = 0; i < hevc->RefNum_L0; i++) - data32 = data32 | (1 << i); - WRITE_VREG(HEVC_MPRED_REF_EN_L0, data32); - - data32 = 0; - for (i = 0; i < hevc->RefNum_L1; i++) - data32 = data32 | (1 << i); - WRITE_VREG(HEVC_MPRED_REF_EN_L1, data32); - - WRITE_VREG(HEVC_MPRED_CUR_POC, hevc->curr_POC); - WRITE_VREG(HEVC_MPRED_COL_POC, hevc->Col_POC); - - /* below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> - Ref_POC_xx_L1 in pair write order!!! */ - ref_poc_L0 = &(cur_pic->m_aiRefPOCList0[cur_pic->slice_idx][0]); - ref_poc_L1 = &(cur_pic->m_aiRefPOCList1[cur_pic->slice_idx][0]); - - WRITE_VREG(HEVC_MPRED_L0_REF00_POC, ref_poc_L0[0]); - WRITE_VREG(HEVC_MPRED_L1_REF00_POC, ref_poc_L1[0]); - - WRITE_VREG(HEVC_MPRED_L0_REF01_POC, ref_poc_L0[1]); - WRITE_VREG(HEVC_MPRED_L1_REF01_POC, ref_poc_L1[1]); - - WRITE_VREG(HEVC_MPRED_L0_REF02_POC, ref_poc_L0[2]); - WRITE_VREG(HEVC_MPRED_L1_REF02_POC, ref_poc_L1[2]); - - WRITE_VREG(HEVC_MPRED_L0_REF03_POC, ref_poc_L0[3]); - WRITE_VREG(HEVC_MPRED_L1_REF03_POC, ref_poc_L1[3]); - - WRITE_VREG(HEVC_MPRED_L0_REF04_POC, ref_poc_L0[4]); - WRITE_VREG(HEVC_MPRED_L1_REF04_POC, ref_poc_L1[4]); - - WRITE_VREG(HEVC_MPRED_L0_REF05_POC, ref_poc_L0[5]); - WRITE_VREG(HEVC_MPRED_L1_REF05_POC, ref_poc_L1[5]); - - WRITE_VREG(HEVC_MPRED_L0_REF06_POC, ref_poc_L0[6]); - WRITE_VREG(HEVC_MPRED_L1_REF06_POC, ref_poc_L1[6]); - - WRITE_VREG(HEVC_MPRED_L0_REF07_POC, ref_poc_L0[7]); - WRITE_VREG(HEVC_MPRED_L1_REF07_POC, ref_poc_L1[7]); - - WRITE_VREG(HEVC_MPRED_L0_REF08_POC, ref_poc_L0[8]); - WRITE_VREG(HEVC_MPRED_L1_REF08_POC, ref_poc_L1[8]); - - WRITE_VREG(HEVC_MPRED_L0_REF09_POC, ref_poc_L0[9]); - WRITE_VREG(HEVC_MPRED_L1_REF09_POC, ref_poc_L1[9]); - - WRITE_VREG(HEVC_MPRED_L0_REF10_POC, ref_poc_L0[10]); - WRITE_VREG(HEVC_MPRED_L1_REF10_POC, ref_poc_L1[10]); - - WRITE_VREG(HEVC_MPRED_L0_REF11_POC, ref_poc_L0[11]); - WRITE_VREG(HEVC_MPRED_L1_REF11_POC, ref_poc_L1[11]); - - WRITE_VREG(HEVC_MPRED_L0_REF12_POC, ref_poc_L0[12]); - WRITE_VREG(HEVC_MPRED_L1_REF12_POC, ref_poc_L1[12]); - - WRITE_VREG(HEVC_MPRED_L0_REF13_POC, ref_poc_L0[13]); - WRITE_VREG(HEVC_MPRED_L1_REF13_POC, ref_poc_L1[13]); - - WRITE_VREG(HEVC_MPRED_L0_REF14_POC, ref_poc_L0[14]); - WRITE_VREG(HEVC_MPRED_L1_REF14_POC, ref_poc_L1[14]); - - WRITE_VREG(HEVC_MPRED_L0_REF15_POC, ref_poc_L0[15]); - WRITE_VREG(HEVC_MPRED_L1_REF15_POC, ref_poc_L1[15]); - - if (hevc->new_pic) { - WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, mpred_above_buf_start); - WRITE_VREG(HEVC_MPRED_MV_WPTR, mpred_mv_wr_ptr); - /* WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr); */ - WRITE_VREG(HEVC_MPRED_MV_RPTR, mpred_mv_rd_start_addr); - } else if (!hevc->isNextSliceSegment) { - /* WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1); */ - WRITE_VREG(HEVC_MPRED_MV_RPTR, mpred_mv_rd_ptr); - } - - WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr); -} - -static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params) -{ - unsigned int data32, data32_2; - int misc_flag0 = hevc->misc_flag0; - int slice_deblocking_filter_disabled_flag = 0; - - int mc_buffer_size_u_v = - hevc->lcu_total * hevc->lcu_size * hevc->lcu_size / 2; - int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16; - struct PIC_s *cur_pic = hevc->cur_pic; - - data32 = READ_VREG(HEVC_SAO_CTRL0); - data32 &= (~0xf); - data32 |= hevc->lcu_size_log2; - WRITE_VREG(HEVC_SAO_CTRL0, data32); - - data32 = (hevc->pic_w | hevc->pic_h << 16); - WRITE_VREG(HEVC_SAO_PIC_SIZE, data32); - - data32 = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16); - WRITE_VREG(HEVC_SAO_PIC_SIZE_LCU, data32); - - if (hevc->new_pic) - WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - if ((get_double_write_mode(hevc) & 0x10) == 0) { - data32 = READ_VREG(HEVC_SAO_CTRL5); - data32 &= (~(0xff << 16)); - if (get_double_write_mode(hevc) != 1) - data32 |= (0xff<<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 (get_double_write_mode(hevc)) - WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr); - - if ((get_double_write_mode(hevc) & 0x10) == 0) - WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32); - - if (mmu_enable) - WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr); -#else - data32 = cur_pic->mc_y_adr; - WRITE_VREG(HEVC_SAO_Y_START_ADDR, data32); -#endif - data32 = (mc_buffer_size_u_v_h << 16) << 1; - WRITE_VREG(HEVC_SAO_Y_LENGTH, data32); - -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - 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; - WRITE_VREG(HEVC_SAO_C_START_ADDR, data32); -#endif - data32 = (mc_buffer_size_u_v_h << 16); - WRITE_VREG(HEVC_SAO_C_LENGTH, data32); - -#ifdef LOSLESS_COMPRESS_MODE -/*SUPPORT_10BIT*/ - 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); - } -#else - /* multi tile to do... */ - data32 = cur_pic->mc_y_adr; - WRITE_VREG(HEVC_SAO_Y_WPTR, data32); - - data32 = cur_pic->mc_u_v_adr; - WRITE_VREG(HEVC_SAO_C_WPTR, data32); -#endif - /* DBLK CONFIG HERE */ - if (hevc->new_pic) { - data32 = (hevc->pic_w | hevc->pic_h << 16); - WRITE_VREG(HEVC_DBLK_CFG2, data32); - - if ((misc_flag0 >> PCM_ENABLE_FLAG_BIT) & 0x1) { - data32 = - ((misc_flag0 >> - PCM_LOOP_FILTER_DISABLED_FLAG_BIT) & - 0x1) << 3; - } else - data32 = 0; - data32 |= - (((params->p.pps_cb_qp_offset & 0x1f) << 4) | - ((params->p.pps_cr_qp_offset - & 0x1f) << - 9)); - data32 |= - (hevc->lcu_size == - 64) ? 0 : ((hevc->lcu_size == 32) ? 1 : 2); - - WRITE_VREG(HEVC_DBLK_CFG1, data32); - } -#if 0 - data32 = READ_VREG(HEVC_SAO_CTRL1); - data32 &= (~0x3000); - data32 |= (mem_map_mode << - 12);/* [13:12] axi_aformat, - 0-Linear, 1-32x32, 2-64x32 */ - WRITE_VREG(HEVC_SAO_CTRL1, data32); - - data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG); - data32 &= (~0x30); - data32 |= (mem_map_mode << - 4); /* [5:4] -- address_format - 00:linear 01:32x32 10:64x32 */ - WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); -#else - /* m8baby test1902 */ - data32 = READ_VREG(HEVC_SAO_CTRL1); - data32 &= (~0x3000); - 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 |= endian; /* Big-Endian per 64-bit */ - data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ - if (get_double_write_mode(hevc) == 0) - data32 |= 0x2; /*disable double write*/ - else if (!mmu_enable && (get_double_write_mode(hevc) & 0x10)) - data32 |= 0x1; /*disable cm*/ - WRITE_VREG(HEVC_SAO_CTRL1, data32); - - if (get_double_write_mode(hevc) & 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); - } - - 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 |= 0xf; /* valid only when double write only */ - /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ - WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); -#endif - data32 = 0; - data32_2 = READ_VREG(HEVC_SAO_CTRL0); - data32_2 &= (~0x300); - /* slice_deblocking_filter_disabled_flag = 0; - ucode has handle it , so read it from ucode directly */ - if (hevc->tile_enabled) { - data32 |= - ((misc_flag0 >> - LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT) & - 0x1) << 0; - data32_2 |= - ((misc_flag0 >> - LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT) & - 0x1) << 8; - } - slice_deblocking_filter_disabled_flag = (misc_flag0 >> - SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & - 0x1; /* ucode has handle it,so read it from ucode directly */ - if ((misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT)) - && (misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT))) { - /* slice_deblocking_filter_disabled_flag = - (misc_flag0>>SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT)&0x1; - //ucode has handle it , so read it from ucode directly */ - data32 |= slice_deblocking_filter_disabled_flag << 2; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(1,%x)", data32); - if (!slice_deblocking_filter_disabled_flag) { - data32 |= (params->p.slice_beta_offset_div2 & 0xf) << 3; - data32 |= (params->p.slice_tc_offset_div2 & 0xf) << 7; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(2,%x)", data32); - } - } else { - data32 |= - ((misc_flag0 >> - PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & - 0x1) << 2; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(3,%x)", data32); - if (((misc_flag0 >> PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) & - 0x1) == 0) { - data32 |= (params->p.pps_beta_offset_div2 & 0xf) << 3; - data32 |= (params->p.pps_tc_offset_div2 & 0xf) << 7; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(4,%x)", data32); - } - } - if ((misc_flag0 & (1 << PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)) - && ((misc_flag0 & (1 << SLICE_SAO_LUMA_FLAG_BIT)) - || (misc_flag0 & (1 << SLICE_SAO_CHROMA_FLAG_BIT)) - || (!slice_deblocking_filter_disabled_flag))) { - data32 |= - ((misc_flag0 >> - SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) - & 0x1) << 1; - data32_2 |= - ((misc_flag0 >> - SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) - & 0x1) << 9; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(5,%x)\n", data32); - } else { - data32 |= - ((misc_flag0 >> - PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) - & 0x1) << 1; - data32_2 |= - ((misc_flag0 >> - PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT) - & 0x1) << 9; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print_cont(hevc, 0, - "(6,%x)\n", data32); - } - WRITE_VREG(HEVC_DBLK_CFG9, data32); - WRITE_VREG(HEVC_SAO_CTRL0, data32_2); -} - -static void clear_used_by_display_flag(struct hevc_state_s *hevc) -{ - struct PIC_s *pic; - int i; - if (get_dbg_flag(hevc) & H265_DEBUG_NOT_USE_LAST_DISPBUF) - return; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic) - pic->used_by_display = 0; - } -} - -static struct PIC_s *get_new_pic(struct hevc_state_s *hevc, - union param_u *rpm_param) -{ - struct PIC_s *new_pic = NULL; - struct PIC_s *pic; - /* recycle un-used pic */ - int i; - int ret; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - if ((pic->used_by_display) && !mmu_enable - && ((READ_VCBUS_REG(AFBC_BODY_BADDR) << 4) != - pic->mc_y_adr)) - pic->used_by_display = 0; - if (pic->output_mark == 0 && pic->referenced == 0 - && pic->output_ready == 0 - && pic->used_by_display == 0) { - if (new_pic) { - if (pic->POC < new_pic->POC) - new_pic = pic; - } else - new_pic = pic; - } - } - - /*try to allocate more pic for new resolution*/ - if (re_config_pic_flag && new_pic == NULL) { - int ii; - - for (ii = 0; ii < MAX_REF_PIC_NUM; ii++) { - if (hevc->m_PIC[ii] == NULL || - hevc->m_PIC[ii]->index == -1) - break; - } - if (ii < MAX_REF_PIC_NUM) { - new_pic = hevc->m_PIC[ii]; - if (new_pic) { - memset(new_pic, 0, sizeof(struct PIC_s)); - new_pic->index = ii; - new_pic->BUF_index = -1; - } - } - } - /**/ - - if (new_pic == NULL) { - /* pr_info("Error: Buffer management, no free buffer\n"); */ - return new_pic; - } - - new_pic->referenced = 1; - if (new_pic->width != hevc->pic_w || - new_pic->height != hevc->pic_h) { - if (re_config_pic_flag) { - /* re config pic for new resolution */ - recycle_buf(hevc); - /* if(new_pic->BUF_index == -1){ */ - if (config_pic(hevc, new_pic, 0) < 0) { - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR_MORE) { - hevc_print(hevc, 0, - "Config_pic %d fail\n", - new_pic->index); - dump_pic_list(hevc); - } - new_pic->index = -1; - new_pic = NULL; - } else - init_pic_list_hw(hevc); - } - if (new_pic) { - new_pic->width = hevc->pic_w; - new_pic->height = hevc->pic_h; - set_canvas(hevc, new_pic); - } - } - if (new_pic) { - new_pic->decode_idx = hevc->decode_idx; - new_pic->slice_idx = 0; - new_pic->referenced = 1; - new_pic->output_mark = 0; - new_pic->recon_mark = 0; - new_pic->error_mark = 0; - /* new_pic->output_ready = 0; */ - new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0; - 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; - if (new_pic->aux_data_buf) - release_aux_data(hevc, new_pic); - } - - if (mmu_enable) { - ret = H265_alloc_mmu(hevc, new_pic, rpm_param->p.bit_depth, - hevc->frame_mmu_map_addr); - /*pr_info("get pic index %x\n",new_pic->index);*/ - if (ret != 0) { - pr_err("can't alloc need mmu1,idx %d ret =%d\n", - new_pic->decode_idx, - ret); - return NULL; - } - - } - - return new_pic; -} - -static int get_display_pic_num(struct hevc_state_s *hevc) -{ - int i; - struct PIC_s *pic; - int num = 0; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || - pic->index == -1) - continue; - - if (pic->output_ready == 1) - num++; - } - return num; -} - -static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic) -{ - struct PIC_s *pic_display; - - if (pic) { - /*PB skip control */ - if (pic->error_mark == 0 && hevc->PB_skip_mode == 1) { - /* start decoding after first I */ - hevc->ignore_bufmgr_error |= 0x1; - } - if (hevc->ignore_bufmgr_error & 1) { - if (hevc->PB_skip_count_after_decoding > 0) - hevc->PB_skip_count_after_decoding--; - else { - /* start displaying */ - hevc->ignore_bufmgr_error |= 0x2; - } - } - /**/ - if (pic->POC != INVALID_POC) { - pic->output_mark = 1; - pic->recon_mark = 1; - } - pic->recon_mark = 1; - } - do { - pic_display = output_pic(hevc, 1); - - if (pic_display) { - pic_display->referenced = 0; - if ((pic_display->error_mark - && ((hevc->ignore_bufmgr_error & 0x2) == 0)) - || (get_dbg_flag(hevc) & - H265_DEBUG_DISPLAY_CUR_FRAME) - || (get_dbg_flag(hevc) & - H265_DEBUG_NO_DISPLAY)) { - pic_display->output_ready = 0; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[BM] Display: POC %d, ", - pic_display->POC); - hevc_print_cont(hevc, 0, - "decoding index %d ==> ", - pic_display->decode_idx); - hevc_print_cont(hevc, 0, - "Debug mode or error, recycle it\n"); - } - } else { - if (i_only_flag & 0x1 - && pic_display->slice_type != 2) - pic_display->output_ready = 0; - else { - prepare_display_buf(hevc, pic_display); - if (get_dbg_flag(hevc) - & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[BM] flush Display: POC %d, ", - pic_display->POC); - hevc_print_cont(hevc, 0, - "decoding index %d\n", - pic_display->decode_idx); - } - } - } - } - } while (pic_display); -} - -static void set_aux_data(struct hevc_state_s *hevc, - struct PIC_s *pic, unsigned char suffix_flag) -{ - int i; - unsigned short *aux_adr; - unsigned size_reg_val = - READ_VREG(HEVC_AUX_DATA_SIZE); - unsigned aux_count = 0; - int aux_size = 0; - if (suffix_flag) { - aux_adr = (unsigned short *) - (hevc->aux_addr + - hevc->prefix_aux_size); - aux_count = - ((size_reg_val & 0xffff) << 4) - >> 1; - aux_size = - hevc->suffix_aux_size; - } else { - aux_adr = - (unsigned short *)hevc->aux_addr; - aux_count = - ((size_reg_val >> 16) << 4) - >> 1; - aux_size = - hevc->prefix_aux_size; - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { - hevc_print(hevc, 0, "%s:old size %d count %d,suf %d\r\n", - __func__, pic->aux_data_size, aux_count, suffix_flag); - } - if (aux_size > 0 && aux_count > 0) { - int heads_size = 0; - int new_size; - char *new_buf; - for (i = 0; i < aux_count; i++) { - unsigned char tag = aux_adr[i] >> 8; - if (tag != 0 && tag != 0xff) - heads_size += 8; - } - new_size = pic->aux_data_size + aux_count + heads_size; - new_buf = krealloc(pic->aux_data_buf, - new_size, - GFP_KERNEL); - if (new_buf) { - unsigned char *p = - new_buf + - pic->aux_data_size; - unsigned char *h = p; - int h_bytes = 8; - int len = 0; - int padding_len = 0; - pic->aux_data_buf = new_buf; - pic->aux_data_size += (aux_count + heads_size); - for (i = 0; i < aux_count; i += 4) { - int ii; - unsigned char tag = aux_adr[i + 3] >> 8; - if (tag != 0 && tag != 0xff) { - if (i > 0) { - 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); - h_bytes += 8; - len = 0; - padding_len = 0; - } - h[4] = tag; - h[5] = 0; - h[6] = 0; - h[7] = 0; - } - for (ii = 0; ii < 4; ii++) { - unsigned short aa = - aux_adr[i + 3 - - ii]; - p[h_bytes + i + ii] = - aa & 0xff; - len++; - if ((aa >> 8) == 0xff) - padding_len++; - } - } - 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 (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); - for (i = 0; i < pic->aux_data_size; i++) { - hevc_print_cont(hevc, 0, - "%02x ", pic->aux_data_buf[i]); - if (((i + 1) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - hevc_print_cont(hevc, 0, "\n"); - } - - } - } - -} - -static void release_aux_data(struct hevc_state_s *hevc, - struct PIC_s *pic) -{ - kfree(pic->aux_data_buf); - pic->aux_data_buf = NULL; - pic->aux_data_size = 0; -} - -static inline void hevc_pre_pic(struct hevc_state_s *hevc, - struct PIC_s *pic) -{ - - /* prev pic */ - /*if (hevc->curr_POC != 0) {*/ - if (hevc->m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR - && hevc->m_nalUnitType != - NAL_UNIT_CODED_SLICE_IDR_N_LP) { - struct PIC_s *pic_display; - - pic = get_pic_by_POC(hevc, hevc->iPrevPOC); - if (pic && (pic->POC != INVALID_POC)) { - /*PB skip control */ - if (pic->error_mark == 0 - && hevc->PB_skip_mode == 1) { - /* start decoding after - first I */ - hevc->ignore_bufmgr_error |= 0x1; - } - if (hevc->ignore_bufmgr_error & 1) { - if (hevc->PB_skip_count_after_decoding > 0) { - hevc->PB_skip_count_after_decoding--; - } else { - /* start displaying */ - hevc->ignore_bufmgr_error |= 0x2; - } - } - pic->output_mark = 1; - pic->recon_mark = 1; - } - do { - pic_display = output_pic(hevc, 0); - - if (pic_display) { - if ((pic_display->error_mark && - ((hevc->ignore_bufmgr_error & - 0x2) == 0)) - || (get_dbg_flag(hevc) & - H265_DEBUG_DISPLAY_CUR_FRAME) - || (get_dbg_flag(hevc) & - H265_DEBUG_NO_DISPLAY)) { - pic_display->output_ready = 0; - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[BM] Display: POC %d, ", - pic_display->POC); - hevc_print_cont(hevc, 0, - "decoding index %d ==> ", - pic_display-> - decode_idx); - hevc_print_cont(hevc, 0, - "Debug or err,recycle it\n"); - } - } else { - if (i_only_flag & 0x1 - && pic_display-> - slice_type != 2) { - pic_display->output_ready = 0; - } else { - prepare_display_buf - (hevc, - pic_display); - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[BM] Display: POC %d, ", - pic_display->POC); - hevc_print_cont(hevc, 0, - "decoding index %d\n", - pic_display-> - decode_idx); - } - } - } - } - } while (pic_display); - } else { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "[BM] current pic is IDR, "); - hevc_print(hevc, 0, - "clear referenced flag of all buffers\n"); - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - dump_pic_list(hevc); - pic = get_pic_by_POC(hevc, hevc->iPrevPOC); - flush_output(hevc, pic); - } - -} - -static void check_pic_decoded_lcu_count(struct hevc_state_s *hevc) -{ - int current_lcu_idx = READ_VREG(HEVC_PARSER_LCU_START)&0xffffff; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "cur lcu idx = %d, (total %d)\n", - current_lcu_idx, hevc->lcu_total); - } - if ((error_handle_policy & 0x20) == 0 && hevc->cur_pic != NULL) { - if (hevc->first_pic_after_recover) { - if (current_lcu_idx != - ((hevc->lcu_x_num_pre*hevc->lcu_y_num_pre) - 1)) - hevc->cur_pic->error_mark = 1; - } else { - if (hevc->lcu_x_num_pre != 0 - && hevc->lcu_y_num_pre != 0 - && current_lcu_idx != 0 - && current_lcu_idx < - ((hevc->lcu_x_num_pre*hevc->lcu_y_num_pre) - 1)) - hevc->cur_pic->error_mark = 1; - } - if (hevc->cur_pic->error_mark) - hevc_print(hevc, 0, - "cur lcu idx = %d, (total %d), set error_mark\n", - current_lcu_idx, - hevc->lcu_x_num_pre*hevc->lcu_y_num_pre); - - } - hevc->lcu_x_num_pre = hevc->lcu_x_num; - hevc->lcu_y_num_pre = hevc->lcu_y_num; -} - -static int hevc_slice_segment_header_process(struct hevc_state_s *hevc, - union param_u *rpm_param, - int decode_pic_begin) -{ -#ifdef CONFIG_AM_VDEC_DV - 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; - - if (hevc->wait_buf == 0) { - hevc->sps_num_reorder_pics_0 = - rpm_param->p.sps_num_reorder_pics_0; - hevc->m_temporalId = rpm_param->p.m_temporalId; - hevc->m_nalUnitType = rpm_param->p.m_nalUnitType; - hevc->interlace_flag = - (rpm_param->p.profile_etc >> 2) & 0x1; - hevc->curr_pic_struct = - (rpm_param->p.sei_frame_field_info >> 3) & 0xf; - - if (interlace_enable == 0) - hevc->interlace_flag = 0; - if (interlace_enable & 0x100) - hevc->interlace_flag = interlace_enable & 0x1; - if (hevc->interlace_flag == 0) - hevc->curr_pic_struct = 0; - /* if(hevc->m_nalUnitType == NAL_UNIT_EOS){ */ - /* - *hevc->m_pocRandomAccess = MAX_INT; - * //add to fix RAP_B_Bossen_1 - */ - /* } */ - hevc->misc_flag0 = rpm_param->p.misc_flag0; - if (rpm_param->p.first_slice_segment_in_pic_flag == 0) { - hevc->slice_segment_addr = - rpm_param->p.slice_segment_address; - if (!rpm_param->p.dependent_slice_segment_flag) - hevc->slice_addr = hevc->slice_segment_addr; - } else { - hevc->slice_segment_addr = 0; - hevc->slice_addr = 0; - } - - hevc->iPrevPOC = hevc->curr_POC; - hevc->slice_type = (rpm_param->p.slice_type == I_SLICE) ? 2 : - (rpm_param->p.slice_type == P_SLICE) ? 1 : - (rpm_param->p.slice_type == B_SLICE) ? 0 : 3; - /* hevc->curr_predFlag_L0=(hevc->slice_type==2) ? 0:1; */ - /* hevc->curr_predFlag_L1=(hevc->slice_type==0) ? 1:0; */ - hevc->TMVPFlag = rpm_param->p.slice_temporal_mvp_enable_flag; - hevc->isNextSliceSegment = - rpm_param->p.dependent_slice_segment_flag ? 1 : 0; - if (hevc->pic_w != rpm_param->p.pic_width_in_luma_samples - || hevc->pic_h != - rpm_param->p.pic_height_in_luma_samples) { - hevc_print(hevc, 0, - "Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n", - hevc->pic_w, hevc->pic_h, - 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; - hevc->frame_height = hevc->pic_h; -#ifdef LOSLESS_COMPRESS_MODE - if (re_config_pic_flag == 0 && - (get_double_write_mode(hevc) & 0x10) == 0) - init_decode_head_hw(hevc); -#endif - } - - if (HEVC_SIZE < hevc->pic_w * hevc->pic_h) { - pr_info("over size : %u x %u.\n", - hevc->pic_w, hevc->pic_h); - if (!hevc->m_ins_flag) - debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC | - H265_DEBUG_DIS_SYS_ERROR_PROC); - hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; - return -1; - } - - /* it will cause divide 0 error */ - if (hevc->pic_w == 0 || hevc->pic_h == 0) { - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "Fatal Error, pic_w = %d, pic_h = %d\n", - hevc->pic_w, hevc->pic_h); - } - return 3; - } - hevc->lcu_size = - 1 << (rpm_param->p.log2_min_coding_block_size_minus3 + - 3 + rpm_param-> - p.log2_diff_max_min_coding_block_size); - if (hevc->lcu_size == 0) { - hevc_print(hevc, 0, - "Error, lcu_size = 0 (%d,%d)\n", - rpm_param->p. - log2_min_coding_block_size_minus3, - rpm_param->p. - log2_diff_max_min_coding_block_size); - return 3; - } - hevc->lcu_size_log2 = log2i(hevc->lcu_size); - lcu_x_num_div = (hevc->pic_w / hevc->lcu_size); - lcu_y_num_div = (hevc->pic_h / hevc->lcu_size); - hevc->lcu_x_num = - ((hevc->pic_w % hevc->lcu_size) == - 0) ? lcu_x_num_div : lcu_x_num_div + 1; - hevc->lcu_y_num = - ((hevc->pic_h % hevc->lcu_size) == - 0) ? lcu_y_num_div : lcu_y_num_div + 1; - hevc->lcu_total = hevc->lcu_x_num * hevc->lcu_y_num; - - if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_IDR_N_LP) { - hevc->curr_POC = 0; - if ((hevc->m_temporalId - 1) == 0) - hevc->iPrevTid0POC = hevc->curr_POC; - } else { - int iMaxPOClsb = - 1 << (rpm_param->p. - log2_max_pic_order_cnt_lsb_minus4 + 4); - int iPrevPOClsb; - int iPrevPOCmsb; - int iPOCmsb; - int iPOClsb = rpm_param->p.POClsb; - - if (iMaxPOClsb == 0) { - hevc_print(hevc, 0, - "error iMaxPOClsb is 0\n"); - return 3; - } - - iPrevPOClsb = hevc->iPrevTid0POC % iMaxPOClsb; - iPrevPOCmsb = hevc->iPrevTid0POC - iPrevPOClsb; - - if ((iPOClsb < iPrevPOClsb) - && ((iPrevPOClsb - iPOClsb) >= - (iMaxPOClsb / 2))) - iPOCmsb = iPrevPOCmsb + iMaxPOClsb; - else if ((iPOClsb > iPrevPOClsb) - && ((iPOClsb - iPrevPOClsb) > - (iMaxPOClsb / 2))) - iPOCmsb = iPrevPOCmsb - iMaxPOClsb; - else - iPOCmsb = iPrevPOCmsb; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "iPrePOC%d iMaxPOClsb%d iPOCmsb%d iPOClsb%d\n", - hevc->iPrevTid0POC, iMaxPOClsb, iPOCmsb, - iPOClsb); - } - if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLANT - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLA_N_LP) { - /* For BLA picture types, POCmsb is set to 0. */ - iPOCmsb = 0; - } - hevc->curr_POC = (iPOCmsb + iPOClsb); - if ((hevc->m_temporalId - 1) == 0) - hevc->iPrevTid0POC = hevc->curr_POC; - else { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "m_temporalID is %d\n", - hevc->m_temporalId); - } - } - } - hevc->RefNum_L0 = - (rpm_param->p.num_ref_idx_l0_active > - MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : rpm_param->p. - num_ref_idx_l0_active; - hevc->RefNum_L1 = - (rpm_param->p.num_ref_idx_l1_active > - MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : rpm_param->p. - num_ref_idx_l1_active; - - /* if(curr_POC==0x10) dump_lmem(); */ - - /* skip RASL pictures after CRA/BLA pictures */ - if (hevc->m_pocRandomAccess == MAX_INT) {/* first picture */ - if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA || - hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLANT - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLA_N_LP) - hevc->m_pocRandomAccess = hevc->curr_POC; - else - hevc->m_pocRandomAccess = -MAX_INT; - } else if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLANT - || hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_BLA_N_LP) - hevc->m_pocRandomAccess = hevc->curr_POC; - else if ((hevc->curr_POC < hevc->m_pocRandomAccess) && - (nal_skip_policy >= 3) && - (hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_RASL_N || - hevc->m_nalUnitType == - NAL_UNIT_CODED_SLICE_TFD)) { /* skip */ - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "RASL picture with POC %d < %d ", - hevc->curr_POC, hevc->m_pocRandomAccess); - hevc_print(hevc, 0, - "RandomAccess point POC), skip it\n"); - } - return 1; - } - - WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) | 0x2); - hevc->skip_flag = 0; - /**/ - /* if((iPrevPOC != curr_POC)){ */ - if (rpm_param->p.slice_segment_address == 0) { - struct PIC_s *pic; - - hevc->new_pic = 1; - check_pic_decoded_lcu_count(hevc); - /**/ if (use_cma == 0) { - if (hevc->pic_list_init_flag == 0) { - /*USE_BUF_BLOCK*/ - init_buf_list(hevc); - /**/ - init_pic_list(hevc); - init_pic_list_hw(hevc); - init_buf_spec(hevc); - hevc->pic_list_init_flag = 3; - } - } - hevc->first_pic_after_recover = 0; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) - dump_pic_list(hevc); - /* prev pic */ - hevc_pre_pic(hevc, pic); - /* - *update referenced of old pictures - *(cur_pic->referenced is 1 and not updated) - */ - apply_ref_pic_set(hevc, hevc->curr_POC, - rpm_param); - if (mmu_enable && hevc->cur_pic != NULL) { - if (!(hevc->cur_pic->error_mark - && ((hevc->ignore_bufmgr_error & 0x1) == 0))) { - long used_4k_num = - (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); - decoder_mmu_box_free_idx_tail(hevc->mmu_box, - hevc->cur_pic->index, used_4k_num); - } - - } -#ifdef CONFIG_AM_VDEC_DV - if (vdec->master) { - struct hevc_state_s *hevc_ba = - (struct hevc_state_s *) - vdec->master->private; - if (hevc_ba->cur_pic != NULL) - hevc_ba->cur_pic->dv_enhance_exist = 1; - } - if (vdec->master == NULL && - vdec->slave == NULL) { - if (hevc->cur_pic != NULL) - set_aux_data(hevc, hevc->cur_pic, 1); - } -#else - if (hevc->cur_pic != NULL) - set_aux_data(hevc, hevc->cur_pic, 1); -#endif - /* new pic */ - hevc->cur_pic = get_new_pic(hevc, rpm_param); - if (hevc->cur_pic == NULL) { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - dump_pic_list(hevc); - hevc->wait_buf = 1; - return -1; - } -#ifdef CONFIG_AM_VDEC_DV - hevc->cur_pic->dv_enhance_exist = 0; - if (vdec->master == NULL && - vdec->slave == NULL) - set_aux_data(hevc, hevc->cur_pic, 0); -#else - set_aux_data(hevc, hevc->cur_pic, 0); -#endif - if (get_dbg_flag(hevc) & H265_DEBUG_DISPLAY_CUR_FRAME) { - hevc->cur_pic->output_ready = 1; - hevc->cur_pic->stream_offset = - READ_VREG(HEVC_SHIFT_BYTE_COUNT); - prepare_display_buf(hevc, hevc->cur_pic); - hevc->wait_buf = 2; - return -1; - } - } else { -#ifdef CONFIG_AM_VDEC_DV - if (vdec->master == NULL && - vdec->slave == NULL) { - if (hevc->cur_pic != NULL) { - set_aux_data(hevc, hevc->cur_pic, 1); - set_aux_data(hevc, hevc->cur_pic, 0); - } - } -#else - if (hevc->cur_pic != NULL) { - set_aux_data(hevc, hevc->cur_pic, 1); - set_aux_data(hevc, hevc->cur_pic, 0); - } -#endif - if (hevc->pic_list_init_flag != 3 - || hevc->cur_pic == NULL) { - /* make it dec from the first slice segment */ - return 3; - } - hevc->cur_pic->slice_idx++; - hevc->new_pic = 0; - } - } else { - if (hevc->wait_buf == 1) { - /* - *if (mmu_enable && hevc->cur_pic != NULL) { - * long used_4k_num = - * (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); - * decoder_mmu_box_free_idx_tail(hevc->mmu_box, - * hevc->cur_pic->index, used_4k_num); - * - * } - */ - hevc->cur_pic = get_new_pic(hevc, rpm_param); - if (hevc->cur_pic == NULL) - return -1; - -#ifdef CONFIG_AM_VDEC_DV - hevc->cur_pic->dv_enhance_exist = 0; - if (vdec->master == NULL && - vdec->slave == NULL) - set_aux_data(hevc, hevc->cur_pic, 0); -#else - set_aux_data(hevc, hevc->cur_pic, 0); -#endif - hevc->wait_buf = 0; - } else if (hevc->wait_buf == - 2) { - if (get_display_pic_num(hevc) > - 1) - return -1; - hevc->wait_buf = 0; - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) - dump_pic_list(hevc); - } - - if (hevc->new_pic) { -#if 1 - /*SUPPORT_10BIT*/ - int sao_mem_unit = - (hevc->lcu_size == 16 ? 9 : - hevc->lcu_size == - 32 ? 14 : 24) << 4; -#else - int sao_mem_unit = ((hevc->lcu_size / 8) * 2 + 4) << 4; -#endif - int pic_height_cu = - (hevc->pic_h + hevc->lcu_size - 1) / hevc->lcu_size; - int pic_width_cu = - (hevc->pic_w + hevc->lcu_size - 1) / hevc->lcu_size; - int sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu; - - /* int sao_abv_size = sao_mem_unit*pic_width_cu; */ - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "==>%s dec idx %d, struct %d interlace %d\n", - __func__, - hevc->decode_idx, - hevc->curr_pic_struct, - hevc->interlace_flag); - } - if (dbg_skip_decode_index != 0 && - hevc->decode_idx == dbg_skip_decode_index) - dbg_skip_flag = 1; - - hevc->decode_idx++; - update_tile_info(hevc, pic_width_cu, pic_height_cu, - sao_mem_unit, rpm_param); - - config_title_hw(hevc, sao_vb_size, sao_mem_unit); - } - - if (hevc->iPrevPOC != hevc->curr_POC) { - hevc->new_tile = 1; - hevc->tile_x = 0; - hevc->tile_y = 0; - hevc->tile_y_x = 0; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "new_tile (new_pic) tile_x=%d, tile_y=%d\n", - hevc->tile_x, hevc->tile_y); - } - } else if (hevc->tile_enabled) { - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "slice_segment_address is %d\n", - rpm_param->p.slice_segment_address); - } - hevc->tile_y_x = - get_tile_index(hevc, rpm_param->p.slice_segment_address, - (hevc->pic_w + - hevc->lcu_size - - 1) / hevc->lcu_size); - if (hevc->tile_y_x != (hevc->tile_x | (hevc->tile_y << 8))) { - hevc->new_tile = 1; - hevc->tile_x = hevc->tile_y_x & 0xff; - hevc->tile_y = (hevc->tile_y_x >> 8) & 0xff; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "new_tile seg adr %d tile_x=%d, tile_y=%d\n", - rpm_param->p.slice_segment_address, - hevc->tile_x, hevc->tile_y); - } - } else - hevc->new_tile = 0; - } else - hevc->new_tile = 0; - - if (hevc->new_tile) { - hevc->tile_start_lcu_x = - hevc->m_tile[hevc->tile_y][hevc->tile_x].start_cu_x; - hevc->tile_start_lcu_y = - hevc->m_tile[hevc->tile_y][hevc->tile_x].start_cu_y; - hevc->tile_width_lcu = - hevc->m_tile[hevc->tile_y][hevc->tile_x].width; - hevc->tile_height_lcu = - hevc->m_tile[hevc->tile_y][hevc->tile_x].height; - } - - set_ref_pic_list(hevc, rpm_param); - - Col_ref = rpm_param->p.collocated_ref_idx; - - hevc->LDCFlag = 0; - if (rpm_param->p.slice_type != I_SLICE) { - hevc->LDCFlag = 1; - for (i = 0; (i < hevc->RefNum_L0) && hevc->LDCFlag; i++) { - if (hevc->cur_pic-> - m_aiRefPOCList0[hevc->cur_pic->slice_idx][i] > - hevc->curr_POC) - hevc->LDCFlag = 0; - } - if (rpm_param->p.slice_type == B_SLICE) { - for (i = 0; (i < hevc->RefNum_L1) - && hevc->LDCFlag; i++) { - if (hevc->cur_pic-> - m_aiRefPOCList1[hevc->cur_pic-> - slice_idx][i] > - hevc->curr_POC) - hevc->LDCFlag = 0; - } - } - } - - hevc->ColFromL0Flag = rpm_param->p.collocated_from_l0_flag; - - hevc->plevel = - rpm_param->p.log2_parallel_merge_level; - hevc->MaxNumMergeCand = 5 - rpm_param->p.five_minus_max_num_merge_cand; - - hevc->LongTerm_Curr = 0; /* to do ... */ - hevc->LongTerm_Col = 0; /* to do ... */ - - hevc->list_no = 0; - if (rpm_param->p.slice_type == B_SLICE) - hevc->list_no = 1 - hevc->ColFromL0Flag; - if (hevc->list_no == 0) { - if (Col_ref < hevc->RefNum_L0) { - hevc->Col_POC = - hevc->cur_pic->m_aiRefPOCList0[hevc->cur_pic-> - slice_idx][Col_ref]; - } else - hevc->Col_POC = INVALID_POC; - } else { - if (Col_ref < hevc->RefNum_L1) { - hevc->Col_POC = - hevc->cur_pic->m_aiRefPOCList1[hevc->cur_pic-> - slice_idx][Col_ref]; - } else - hevc->Col_POC = INVALID_POC; - } - - hevc->LongTerm_Ref = 0; /* to do ... */ - - if (hevc->slice_type != 2) { - /* if(i_only_flag==1){ */ - /* return 0xf; */ - /* } */ - - if (hevc->Col_POC != INVALID_POC) { - hevc->col_pic = get_ref_pic_by_POC(hevc, hevc->Col_POC); - if (hevc->col_pic == NULL) { - hevc->cur_pic->error_mark = 1; - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "WRONG,fail to get the pic Col_POC\n"); - } - } else if (hevc->col_pic->error_mark) { - hevc->cur_pic->error_mark = 1; - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "WRONG, Col_POC error_mark is 1\n"); - } - } - - if (hevc->cur_pic->error_mark - && ((hevc->ignore_bufmgr_error & 0x1) == 0)) { - return 2; - } - } else - hevc->col_pic = hevc->cur_pic; - } /* */ - if (hevc->col_pic == NULL) - hevc->col_pic = hevc->cur_pic; -#ifdef BUFFER_MGR_ONLY - return 0xf; -#else - if ((decode_pic_begin > 0 && hevc->decode_idx <= decode_pic_begin) - || (dbg_skip_flag)) - return 0xf; -#endif - - config_mc_buffer(hevc, hevc->cur_pic); - - if (hevc->cur_pic->error_mark - && ((hevc->ignore_bufmgr_error & 0x1) == 0)) { - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, - "Discard this picture index %d\n", - hevc->cur_pic->index); - return 2; - } -#ifdef MCRCC_ENABLE - config_mcrcc_axi_hw(hevc, hevc->cur_pic->slice_type); -#endif - config_mpred_hw(hevc); - - config_sao_hw(hevc, rpm_param); - - if ((hevc->slice_type != 2) && (i_only_flag & 0x2)) - return 0xf; - - return 0; -} - - - -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; - - picture_size = compute_losless_comp_body_size(new_pic->width, - new_pic->height, !bit_depth_10); - cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12); - - /* - *pr_info("alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n", -* cur_buf_idx, picture_size, cur_mmu_4k_number); -*/ - return decoder_mmu_box_alloc_idx( - hevc->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); -} - - - - - - -/* -************************************************* -* -*h265 buffer management end -* -************************************************** -*/ -static struct hevc_state_s gHevc; - -static void hevc_local_uninit(struct hevc_state_s *hevc) -{ - hevc->rpm_ptr = NULL; - hevc->lmem_ptr = NULL; - - if (hevc->aux_addr) { - dma_unmap_single(amports_get_dma_device(), - hevc->aux_phy_addr, - hevc->prefix_aux_size + hevc->suffix_aux_size, - DMA_FROM_DEVICE); - kfree(hevc->aux_addr); - hevc->aux_addr = NULL; - } - if (hevc->rpm_addr) { - dma_unmap_single(amports_get_dma_device(), - hevc->rpm_phy_addr, RPM_BUF_SIZE, DMA_FROM_DEVICE); - kfree(hevc->rpm_addr); - hevc->rpm_addr = NULL; - } - if (hevc->lmem_addr) { - dma_unmap_single(amports_get_dma_device(), - hevc->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - kfree(hevc->lmem_addr); - hevc->lmem_addr = NULL; - } - - if (mmu_enable && hevc->frame_mmu_map_addr) { - if (hevc->frame_mmu_map_phy_addr) - dma_free_coherent(amports_get_dma_device(), - FRAME_MMU_MAP_SIZE, hevc->frame_mmu_map_addr, - hevc->frame_mmu_map_phy_addr); - - hevc->frame_mmu_map_addr = NULL; - } - - -} - -static int hevc_local_init(struct hevc_state_s *hevc) -{ - int ret = -1; - struct BuffInfo_s *cur_buf_info = NULL; - - memset(&hevc->param, 0, sizeof(union param_u)); - - cur_buf_info = &hevc->work_space_buf_store; -#ifdef SUPPORT_4K2K - memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k2k work space */ - sizeof(struct BuffInfo_s)); -#else - memcpy(cur_buf_info, &amvh265_workbuff_spec[0], /* 1080p work space */ - sizeof(struct BuffInfo_s)); -#endif - cur_buf_info->start_adr = hevc->buf_start; - hevc->mc_buf_spec.buf_end = hevc->buf_start + hevc->buf_size; - init_buff_spec(hevc, cur_buf_info); - - - - hevc->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff) - & (~0xffff); - hevc->mc_buf_spec.buf_size = (hevc->mc_buf_spec.buf_end - - hevc->mc_buf_spec.buf_start); - - hevc_init_stru(hevc, cur_buf_info, &hevc->mc_buf_spec); - - hevc->bit_depth_luma = 8; - hevc->bit_depth_chroma = 8; - hevc->video_signal_type = 0; - bit_depth_luma = hevc->bit_depth_luma; - bit_depth_chroma = hevc->bit_depth_chroma; - video_signal_type = hevc->video_signal_type; - - if ((get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) == 0) { - hevc->rpm_addr = kmalloc(RPM_BUF_SIZE, GFP_KERNEL); - if (hevc->rpm_addr == NULL) { - pr_err("%s: failed to alloc rpm buffer\n", __func__); - return -1; - } - - hevc->rpm_phy_addr = dma_map_single(amports_get_dma_device(), - hevc->rpm_addr, RPM_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hevc->rpm_phy_addr)) { - pr_err("%s: failed to map rpm buffer\n", __func__); - kfree(hevc->rpm_addr); - hevc->rpm_addr = NULL; - return -1; - } - - hevc->rpm_ptr = hevc->rpm_addr; - } - - if (prefix_aux_buf_size > 0 || - suffix_aux_buf_size > 0) { - u32 aux_buf_size; - hevc->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size); - hevc->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size); - aux_buf_size = hevc->prefix_aux_size + hevc->suffix_aux_size; - hevc->aux_addr = kmalloc(aux_buf_size, GFP_KERNEL); - if (hevc->aux_addr == NULL) { - pr_err("%s: failed to alloc rpm buffer\n", __func__); - return -1; - } - - hevc->aux_phy_addr = dma_map_single(amports_get_dma_device(), - hevc->aux_addr, aux_buf_size, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hevc->aux_phy_addr)) { - pr_err("%s: failed to map rpm buffer\n", __func__); - kfree(hevc->aux_addr); - hevc->aux_addr = NULL; - return -1; - } - } - - if (get_dbg_flag(hevc) & H265_DEBUG_UCODE) { - hevc->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); - if (hevc->lmem_addr == NULL) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - return -1; - } - - hevc->lmem_phy_addr = dma_map_single(amports_get_dma_device(), - hevc->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - hevc->lmem_phy_addr)) { - pr_err("%s: failed to map lmem buffer\n", __func__); - kfree(hevc->lmem_addr); - hevc->lmem_addr = NULL; - return -1; - } - - hevc->lmem_ptr = hevc->lmem_addr; - } - - if (mmu_enable) { - hevc->frame_mmu_map_addr = - dma_alloc_coherent(amports_get_dma_device(), - 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 -1; - } - memset(hevc->frame_mmu_map_addr, 0, FRAME_MMU_MAP_SIZE); - } - 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 hevc_state_s *hevc, struct PIC_s *pic) -{ - int canvas_w = ALIGN(pic->width, 64)/4; - int canvas_h = ALIGN(pic->height, 32)/4; - int blkmode = mem_map_mode; - - /*CANVAS_BLKMODE_64X32*/ -#ifdef SUPPORT_10BIT - if (get_double_write_mode(hevc)) { - canvas_w = pic->width; - canvas_h = pic->height; - if ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) { - canvas_w >>= 2; - canvas_h >>= 2; - } - - if (mem_map_mode == 0) - canvas_w = ALIGN(canvas_w, 32); - else - canvas_w = ALIGN(canvas_w, 64); - canvas_h = ALIGN(canvas_h, 32); - - pic->y_canvas_index = 128 + pic->index * 2; - pic->uv_canvas_index = 128 + pic->index * 2 + 1; - - canvas_config_ex(pic->y_canvas_index, - pic->dw_y_adr, canvas_w, canvas_h, - 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); -#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 { - if (!mmu_enable) { - /* to change after 10bit VPU is ready ... */ - pic->y_canvas_index = 128 + pic->index; - pic->uv_canvas_index = 128 + pic->index; - - canvas_config_ex(pic->y_canvas_index, - pic->mc_y_adr, canvas_w, canvas_h, - 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); - } - } -#else - pic->y_canvas_index = 128 + pic->index * 2; - pic->uv_canvas_index = 128 + pic->index * 2 + 1; - - canvas_config_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h, - 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 -} - -static int init_buf_spec(struct hevc_state_s *hevc) -{ - int pic_width = hevc->pic_w; - int pic_height = hevc->pic_h; - - /* hevc_print(hevc, 0, - "%s1: %d %d\n", __func__, hevc->pic_w, hevc->pic_h); */ - hevc_print(hevc, 0, - "%s2 %d %d\n", __func__, pic_width, pic_height); - /* pic_width = hevc->pic_w; */ - /* pic_height = hevc->pic_h; */ - - if (hevc->frame_width == 0 || hevc->frame_height == 0) { - hevc->frame_width = pic_width; - hevc->frame_height = pic_height; - - } - - return 0; -} - -static int parse_sei(struct hevc_state_s *hevc, char *sei_buf, uint32_t size) -{ - char *p = sei_buf; - char *p_sei; - uint16_t header; - uint8_t nal_unit_type; - uint8_t payload_type, payload_size; - int i, j; - - if (size < 2) - return 0; - header = *p++; - header <<= 8; - header += *p++; - nal_unit_type = header >> 9; - if ((nal_unit_type != NAL_UNIT_SEI) - && (nal_unit_type != NAL_UNIT_SEI_SUFFIX)) - return 0; - while (p+2 <= sei_buf+size) { - payload_type = *p++; - payload_size = *p++; - if (p+payload_size <= sei_buf+size) { - switch (payload_type) { - case SEI_MasteringDisplayColorVolume: - hevc_print(hevc, 0, - "sei type: primary display color volume %d, size %d\n", - payload_type, - payload_size); - /* master_display_colour */ - p_sei = p; - for (i = 0; i < 3; i++) { - for (j = 0; j < 2; j++) { - hevc->primaries[i][j] - = (*p_sei<<8) - | *(p_sei+1); - p_sei += 2; - } - } - for (i = 0; i < 2; i++) { - hevc->white_point[i] - = (*p_sei<<8) - | *(p_sei+1); - p_sei += 2; - } - for (i = 0; i < 2; i++) { - hevc->luminance[i] - = (*p_sei<<24) - | (*(p_sei+1)<<16) - | (*(p_sei+2)<<8) - | *(p_sei+3); - p_sei += 4; - } - hevc->sei_present_flag |= - SEI_MASTER_DISPLAY_COLOR_MASK; - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) - hevc_print(hevc, 0, - "\tprimaries[%1d][%1d] = %04x\n", - i, j, - hevc->primaries[i][j]); - hevc_print(hevc, 0, - "\twhite_point = (%04x, %04x)\n", - hevc->white_point[0], - hevc->white_point[1]); - hevc_print(hevc, 0, - "\tmax,min luminance = %08x, %08x\n", - hevc->luminance[0], - hevc->luminance[1]); - break; - case SEI_ContentLightLevel: - hevc_print(hevc, 0, - "sei type: max content light level %d, size %d\n", - payload_type, payload_size); - /* content_light_level */ - p_sei = p; - hevc->content_light_level[0] - = (*p_sei<<8) | *(p_sei+1); - p_sei += 2; - hevc->content_light_level[1] - = (*p_sei<<8) | *(p_sei+1); - p_sei += 2; - hevc->sei_present_flag |= - SEI_CONTENT_LIGHT_LEVEL_MASK; - hevc_print(hevc, 0, - "\tmax cll = %04x, max_pa_cll = %04x\n", - hevc->content_light_level[0], - hevc->content_light_level[1]); - break; - default: - break; - } - } - p += payload_size; - } - return 0; -} - -static void set_frame_info(struct hevc_state_s *hevc, struct vframe_s *vf) -{ - unsigned int ar; - int i, j; - unsigned char index; - char *p; - unsigned size = 0; - unsigned type = 0; - struct vframe_master_display_colour_s *vf_dp - = &vf->prop.master_display_colour; - - if ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) { - vf->width = hevc->frame_width/4; - vf->height = hevc->frame_height/4; - } else { - vf->width = hevc->frame_width; - vf->height = hevc->frame_height; - } - vf->duration = hevc->frame_dur; - vf->duration_pulldown = 0; - vf->flag = 0; - - ar = min_t(u32, hevc->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX); - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); - - /* signal_type */ - if (hevc->video_signal_type & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) - vf->signal_type = hevc->video_signal_type; - else - vf->signal_type = 0; - - /* parser sei */ - index = vf->index & 0xff; - if (index != 0xff && index >= 0 - && index < MAX_REF_PIC_NUM - && hevc->m_PIC[index] - && hevc->m_PIC[index]->aux_data_buf - && hevc->m_PIC[index]->aux_data_size) { - p = hevc->m_PIC[index]->aux_data_buf; - while (p < hevc->m_PIC[index]->aux_data_buf - + hevc->m_PIC[index]->aux_data_size - 8) { - size = *p++; - size = (size << 8) | *p++; - size = (size << 8) | *p++; - size = (size << 8) | *p++; - type = *p++; - type = (type << 8) | *p++; - type = (type << 8) | *p++; - type = (type << 8) | *p++; - if (type == 0x02000000) { - /* hevc_print(hevc, 0, "sei(%d)\n", size); */ - parse_sei(hevc, p, size); - } - p += size; - } - } - - /* master_display_colour */ - if (hevc->sei_present_flag & SEI_MASTER_DISPLAY_COLOR_MASK) { - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) - vf_dp->primaries[i][j] = hevc->primaries[i][j]; - for (i = 0; i < 2; i++) { - vf_dp->white_point[i] = hevc->white_point[i]; - vf_dp->luminance[i] - = hevc->luminance[i]; - } - vf_dp->present_flag = 1; - } else - vf_dp->present_flag = 0; - - /* content_light_level */ - if (hevc->sei_present_flag & SEI_CONTENT_LIGHT_LEVEL_MASK) { - vf_dp->content_light_level.max_content - = hevc->content_light_level[0]; - vf_dp->content_light_level.max_pic_average - = hevc->content_light_level[1]; - vf_dp->content_light_level.present_flag = 1; - } else - vf_dp->content_light_level.present_flag = 0; - return; -} - -static int vh265_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *vdec = op_arg; - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else - struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg; -#endif - - spin_lock_irqsave(&lock, flags); - - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&hevc->newframe_q); - states->buf_avail_num = kfifo_len(&hevc->display_q); - - if (step == 2) - states->buf_avail_num = 0; - spin_unlock_irqrestore(&lock, flags); - return 0; -} - -static struct vframe_s *vh265_vf_peek(void *op_arg) -{ - struct vframe_s *vf; -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *vdec = op_arg; - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else - struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg; -#endif - - if (step == 2) - return NULL; - - if (kfifo_peek(&hevc->display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vh265_vf_get(void *op_arg) -{ - struct vframe_s *vf; -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *vdec = op_arg; - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else - struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg; -#endif - - if (step == 2) - return NULL; - else if (step == 1) - step = 2; - - if (kfifo_get(&hevc->display_q, &vf)) { - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s(type %d index 0x%x)\n", - __func__, vf->type, vf->index); - - hevc->show_frame_num++; - return vf; - } - - return NULL; -} - -static void vh265_vf_put(struct vframe_s *vf, void *op_arg) -{ - unsigned long flags; -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *vdec = op_arg; - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else - struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg; -#endif - unsigned char index_top = vf->index & 0xff; - unsigned char index_bot = (vf->index >> 8) & 0xff; - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s(type %d index 0x%x)\n", - __func__, vf->type, vf->index); - - kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf); - spin_lock_irqsave(&lock, flags); - - if (index_top != 0xff && index_top >= 0 - && index_top < MAX_REF_PIC_NUM - && hevc->m_PIC[index_top]) { - if (hevc->m_PIC[index_top]->vf_ref > 0) { - hevc->m_PIC[index_top]->vf_ref--; - - if (hevc->m_PIC[index_top]->vf_ref == 0) { - hevc->m_PIC[index_top]->output_ready = 0; - if (mmu_enable) - hevc->m_PIC[index_top]-> - used_by_display = 0; - hevc->last_put_idx_a = index_top; - if (hevc->wait_buf != 0) - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - } - } - } - - if (index_bot != 0xff && index_bot >= 0 - && index_bot < MAX_REF_PIC_NUM - && hevc->m_PIC[index_bot]) { - if (hevc->m_PIC[index_bot]->vf_ref > 0) { - hevc->m_PIC[index_bot]->vf_ref--; - - if (hevc->m_PIC[index_bot]->vf_ref == 0) { - clear_used_by_display_flag(hevc); - hevc->m_PIC[index_bot]->output_ready = 0; - hevc->last_put_idx_b = index_bot; - if (hevc->wait_buf != 0) - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - } - } - } - spin_unlock_irqrestore(&lock, flags); -} - -static int vh265_event_cb(int type, void *data, void *op_arg) -{ - unsigned long flags; -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *vdec = op_arg; - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else - struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg; -#endif - if (type & VFRAME_EVENT_RECEIVER_RESET) { -#if 0 - amhevc_stop(); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_light_unreg_provider(&vh265_vf_prov); -#endif - spin_lock_irqsave(&hevc->lock, flags); - vh265_local_init(); - vh265_prot_init(); - spin_unlock_irqrestore(&hevc->lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vh265_vf_prov); -#endif - amhevc_start(); -#endif - } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) { - struct provider_aux_req_s *req = - (struct provider_aux_req_s *)data; - unsigned char index; - spin_lock_irqsave(&lock, flags); - index = req->vf->index & 0xff; - req->aux_buf = NULL; - req->aux_size = 0; - if (req->bot_flag) - index = (req->vf->index >> 8) & 0xff; - if (index != 0xff && index >= 0 - && index < MAX_REF_PIC_NUM - && hevc->m_PIC[index]) { - req->aux_buf = hevc->m_PIC[index]->aux_data_buf; - req->aux_size = hevc->m_PIC[index]->aux_data_size; -#ifdef CONFIG_AM_VDEC_DV - req->dv_enhance_exist = - hevc->m_PIC[index]->dv_enhance_exist; -#else - req->dv_enhance_exist = 0; -#endif - } - spin_unlock_irqrestore(&lock, flags); - - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s(type 0x%x vf index 0x%x)=>size 0x%x\n", - __func__, type, index, req->aux_size); - } - - return 0; -} - -#ifdef HEVC_PIC_STRUCT_SUPPORT -static int process_pending_vframe(struct hevc_state_s *hevc, - struct PIC_s *pair_pic, unsigned char pair_frame_top_flag) -{ - struct vframe_s *vf; - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s: pair_pic index 0x%x %s\n", - __func__, pair_pic->index, - pair_frame_top_flag ? - "top" : "bot"); - - if (kfifo_len(&hevc->pending_q) > 1) { - /* do not pending more than 1 frame */ - if (kfifo_get(&hevc->pending_q, &vf) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s warning(1), vf=>display_q: (index 0x%x)\n", - __func__, vf->index); - kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); - } - - if (kfifo_peek(&hevc->pending_q, &vf)) { - if (pair_pic == NULL || pair_pic->vf_ref <= 0) { - /* - *if pair_pic is recycled (pair_pic->vf_ref <= 0), - *do not use it - */ - if (kfifo_get(&hevc->pending_q, &vf) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s warning(2), vf=>display_q: (index 0x%x)\n", - __func__, vf->index); - if (vf) - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - } else if ((!pair_frame_top_flag) && - (((vf->index >> 8) & 0xff) == 0xff)) { - if (kfifo_get(&hevc->pending_q, &vf) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - if (vf) { - vf->type = VIDTYPE_PROGRESSIVE - | VIDTYPE_VIU_NV21; - vf->index &= 0xff; - vf->index |= (pair_pic->index << 8); - vf->canvas1Addr = spec2canvas(pair_pic); - pair_pic->vf_ref++; - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s vf => display_q: (index 0x%x)\n", - __func__, vf->index); - } - } else if (pair_frame_top_flag && - ((vf->index & 0xff) == 0xff)) { - if (kfifo_get(&hevc->pending_q, &vf) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - if (vf) { - vf->type = VIDTYPE_PROGRESSIVE - | VIDTYPE_VIU_NV21; - vf->index &= 0xff00; - vf->index |= pair_pic->index; - vf->canvas0Addr = spec2canvas(pair_pic); - pair_pic->vf_ref++; - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "%s vf => display_q: (index 0x%x)\n", - __func__, vf->index); - } - } - } - return 0; -} -#endif -static void update_vf_memhandle(struct hevc_state_s *hevc, - struct vframe_s *vf, int index) -{ - if (index < 0) - vf->mem_handle = NULL; - else if (vf->type & VIDTYPE_SCATTER) - vf->mem_handle = - decoder_mmu_box_get_mem_handle( - hevc->mmu_box, index); - else - vf->mem_handle = - decoder_bmmu_box_get_mem_handle( - hevc->bmmu_box, index); - return; -} -static int prepare_display_buf(struct hevc_state_s *hevc, struct PIC_s *pic) -{ - struct vframe_s *vf = NULL; - int stream_offset = pic->stream_offset; - unsigned short slice_type = pic->slice_type; - - if (kfifo_get(&hevc->newframe_q, &vf) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - - if (vf) { - if (hevc->m_ins_flag) { - vf->pts = pic->pts; - vf->pts_us64 = pic->pts64; - } - /* if (pts_lookup_offset(PTS_TYPE_VIDEO, - stream_offset, &vf->pts, 0) != 0) { */ - else if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, stream_offset, &vf->pts, 0, - &vf->pts_us64) != 0) { -#ifdef DEBUG_PTS - hevc->pts_missed++; -#endif - vf->pts = 0; - vf->pts_us64 = 0; - } -#ifdef DEBUG_PTS - else - hevc->pts_hit++; -#endif - if (pts_unstable && (hevc->frame_dur > 0)) - hevc->pts_mode = PTS_NONE_REF_USE_DURATION; - - if ((hevc->pts_mode == PTS_NORMAL) && (vf->pts != 0) - && hevc->get_frame_dur) { - int pts_diff = (int)vf->pts - hevc->last_lookup_pts; - - if (pts_diff < 0) { - hevc->pts_mode_switching_count++; - hevc->pts_mode_recovery_count = 0; - - if (hevc->pts_mode_switching_count >= - PTS_MODE_SWITCHING_THRESHOLD) { - hevc->pts_mode = - PTS_NONE_REF_USE_DURATION; - hevc_print(hevc, 0, - "HEVC: switch to n_d mode.\n"); - } - - } else { - int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD; - - hevc->pts_mode_recovery_count++; - if (hevc->pts_mode_recovery_count > p) { - hevc->pts_mode_switching_count = 0; - hevc->pts_mode_recovery_count = 0; - } - } - } - - if (vf->pts != 0) - hevc->last_lookup_pts = vf->pts; - - if ((hevc->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != 2)) - vf->pts = hevc->last_pts + DUR2PTS(hevc->frame_dur); - hevc->last_pts = vf->pts; - - if (vf->pts_us64 != 0) - hevc->last_lookup_pts_us64 = vf->pts_us64; - - if ((hevc->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != 2)) { - vf->pts_us64 = - hevc->last_pts_us64 + - (DUR2PTS(hevc->frame_dur) * 100 / 9); - } - 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\n", - vf->pts, vf->pts_us64); - } - - /* - *vf->index: - *(1) vf->type is VIDTYPE_PROGRESSIVE - * and vf->canvas0Addr != vf->canvas1Addr, - * vf->index[7:0] is the index of top pic - * vf->index[15:8] is the index of bot pic - *(2) other cases, - * only vf->index[7:0] is used - * vf->index[15:8] == 0xff - */ - vf->index = 0xff00 | pic->index; -#if 1 -/*SUPPORT_10BIT*/ - if (get_double_write_mode(hevc) & 0x10) { - /* double write only */ - vf->compBodyAddr = 0; - vf->compHeadAddr = 0; - } else { - - if (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; - } - - /*head adr*/ - vf->canvas0Addr = vf->canvas1Addr = 0; - } - if (get_double_write_mode(hevc)) { - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; - if (get_double_write_mode(hevc) == 3) - vf->type |= VIDTYPE_COMPRESS; - if (mmu_enable) - vf->type |= VIDTYPE_SCATTER; -#ifdef MULTI_INSTANCE_SUPPORT - if (hevc->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; - if (mmu_enable) - vf->type |= VIDTYPE_SCATTER; - - } - vf->compWidth = pic->width; - vf->compHeight = pic->height; - update_vf_memhandle(hevc, vf, pic->index); - switch (hevc->bit_depth_luma) { - case 9: - vf->bitdepth = BITDEPTH_Y9; - break; - case 10: - vf->bitdepth = BITDEPTH_Y10; - break; - default: - vf->bitdepth = BITDEPTH_Y8; - break; - } - switch (hevc->bit_depth_chroma) { - case 9: - vf->bitdepth |= (BITDEPTH_U9 | BITDEPTH_V9); - break; - case 10: - vf->bitdepth |= (BITDEPTH_U10 | BITDEPTH_V10); - break; - default: - vf->bitdepth |= (BITDEPTH_U8 | BITDEPTH_V8); - break; - } - if (hevc->mem_saving_mode == 1) - vf->bitdepth |= BITDEPTH_SAVING_MODE; -#else - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; - vf->canvas0Addr = vf->canvas1Addr = spec2canvas(pic); -#endif - set_frame_info(hevc, vf); - /* if((vf->width!=pic->width)||(vf->height!=pic->height)) */ - /* hevc_print(hevc, 0, - "aaa: %d/%d, %d/%d\n", - vf->width,vf->height, pic->width, pic->height); */ - if ((get_double_write_mode(hevc) == 2) || - (get_double_write_mode(hevc) == 3)) { - vf->width = pic->width/4; - vf->height = pic->height/4; - } else { - vf->width = pic->width; - vf->height = pic->height; - } - if (force_w_h != 0) { - vf->width = (force_w_h >> 16) & 0xffff; - vf->height = force_w_h & 0xffff; - } - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } - - /* - * !!! to do ... - * need move below code to get_new_pic(), - * hevc->xxx can only be used by current decoded pic - */ - if (hevc->param.p.conformance_window_flag && - (get_dbg_flag(hevc) & - H265_DEBUG_IGNORE_CONFORMANCE_WINDOW) == 0) { - unsigned SubWidthC, SubHeightC; - - switch (hevc->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; - } - vf->width -= SubWidthC * - (hevc->param.p.conf_win_left_offset + - hevc->param.p.conf_win_right_offset); - vf->height -= SubHeightC * - (hevc->param.p.conf_win_top_offset + - hevc->param.p.conf_win_bottom_offset); - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "conformance_window %d, %d, %d, %d, %d => cropped width %d, height %d\n", - hevc->param.p.chroma_format_idc, - hevc->param.p.conf_win_left_offset, - hevc->param.p.conf_win_right_offset, - hevc->param.p.conf_win_top_offset, - hevc->param.p.conf_win_bottom_offset, - vf->width, vf->height); - } - -#ifdef HEVC_PIC_STRUCT_SUPPORT - if (pic->pic_struct == 3 || pic->pic_struct == 4) { - struct vframe_s *vf2; - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "pic_struct = %d index 0x%x\n", - pic->pic_struct, - pic->index); - - if (kfifo_get(&hevc->newframe_q, &vf2) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - pic->vf_ref = 2; - vf->duration = vf->duration>>1; - memcpy(vf2, vf, sizeof(struct vframe_s)); - - if (pic->pic_struct == 3) { - vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; - vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; - } else { - vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; - vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; - } - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf2); - } else if (pic->pic_struct == 5 - || pic->pic_struct == 6) { - struct vframe_s *vf2, *vf3; - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "pic_struct = %d index 0x%x\n", - pic->pic_struct, - pic->index); - - if (kfifo_get(&hevc->newframe_q, &vf2) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - if (kfifo_get(&hevc->newframe_q, &vf3) == 0) { - hevc_print(hevc, 0, - "fatal error, no available buffer slot."); - return -1; - } - pic->vf_ref = 3; - vf->duration = vf->duration/3; - memcpy(vf2, vf, sizeof(struct vframe_s)); - memcpy(vf3, vf, sizeof(struct vframe_s)); - - if (pic->pic_struct == 5) { - vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; - vf2->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; - vf3->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; - } else { - vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; - vf2->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21; - vf3->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21; - } - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf2); - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf3); - - } else if (pic->pic_struct == 9 - || pic->pic_struct == 10) { - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "pic_struct = %d index 0x%x\n", - pic->pic_struct, - pic->index); - - pic->vf_ref = 1; - /* process previous pending vf*/ - process_pending_vframe(hevc, - pic, (pic->pic_struct == 9)); - - /* process current vf */ - kfifo_put(&hevc->pending_q, - (const struct vframe_s *)vf); - vf->height <<= 1; - if (pic->pic_struct == 9) { - vf->type = VIDTYPE_INTERLACE_TOP - | VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; - process_pending_vframe(hevc, - hevc->pre_bot_pic, 0); - } else { - vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; - vf->index = (pic->index << 8) | 0xff; - process_pending_vframe(hevc, - hevc->pre_top_pic, 1); - } - - /**/ - 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) - hevc_print(hevc, 0, - "pic_struct = %d index 0x%x\n", - pic->pic_struct, - pic->index); - pic->vf_ref = 1; - /* process previous pending vf*/ - process_pending_vframe(hevc, pic, - (pic->pic_struct == 11)); - - /* put current into pending q */ - vf->height <<= 1; - if (pic->pic_struct == 11) - vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; - else { - vf->type = VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; - vf->index = (pic->index << 8) | 0xff; - } - kfifo_put(&hevc->pending_q, - (const struct vframe_s *)vf); - - /**/ - if (pic->pic_struct == 11) - hevc->pre_top_pic = pic; - else - hevc->pre_bot_pic = pic; - - } else { - pic->vf_ref = 1; - - if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) - hevc_print(hevc, 0, - "pic_struct = %d index 0x%x\n", - pic->pic_struct, - pic->index); - - switch (pic->pic_struct) { - case 7: - vf->duration <<= 1; - break; - case 8: - vf->duration = vf->duration * 3; - break; - case 1: - vf->height <<= 1; - vf->type = VIDTYPE_INTERLACE_TOP | - VIDTYPE_VIU_NV21 | VIDTYPE_VIU_FIELD; - process_pending_vframe(hevc, pic, 1); - hevc->pre_top_pic = pic; - break; - case 2: - vf->height <<= 1; - vf->type = VIDTYPE_INTERLACE_BOTTOM - | VIDTYPE_VIU_NV21 - | VIDTYPE_VIU_FIELD; - process_pending_vframe(hevc, pic, 0); - hevc->pre_bot_pic = pic; - break; - } - kfifo_put(&hevc->display_q, - (const struct vframe_s *)vf); - } -#else - vf->type_original = vf->type; - pic->vf_ref = 1; - kfifo_put(&hevc->display_q, (const struct vframe_s *)vf); -#endif - - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } - - return 0; -} - -static void process_nal_sei(struct hevc_state_s *hevc, - int payload_type, int payload_size) -{ - unsigned short data; - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) - hevc_print(hevc, 0, - "\tsei message: payload_type = 0x%02x, payload_size = 0x%02x\n", - payload_type, payload_size); - - if (payload_type == 137) { - int i, j; - /* MASTERING_DISPLAY_COLOUR_VOLUME */ - if (payload_size >= 24) { - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) - hevc_print(hevc, 0, - "\tsei MASTERING_DISPLAY_COLOUR_VOLUME available\n"); - for (i = 0; i < 3; i++) { - for (j = 0; j < 2; j++) { - data = - (READ_HREG(HEVC_SHIFTED_DATA) >> 16); - hevc->primaries[i][j] = data; - WRITE_HREG(HEVC_SHIFT_COMMAND, - (1<<7)|16); - if (get_dbg_flag(hevc) & - H265_DEBUG_PRINT_SEI) - hevc_print(hevc, 0, - "\t\tprimaries[%1d][%1d] = %04x\n", - i, j, hevc->primaries[i][j]); - } - } - for (i = 0; i < 2; i++) { - data = (READ_HREG(HEVC_SHIFTED_DATA) >> 16); - hevc->white_point[i] = data; - WRITE_HREG(HEVC_SHIFT_COMMAND, (1<<7)|16); - if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) - hevc_print(hevc, 0, - "\t\twhite_point[%1d] = %04x\n", - i, hevc->white_point[i]); - } - for (i = 0; i < 2; i++) { - data = - (READ_HREG(HEVC_SHIFTED_DATA) >> 16); - hevc->luminance[i] = data << 16; - WRITE_HREG(HEVC_SHIFT_COMMAND, - (1<<7)|16); - data = - (READ_HREG(HEVC_SHIFTED_DATA) >> 16); - hevc->luminance[i] |= data; - WRITE_HREG(HEVC_SHIFT_COMMAND, - (1<<7)|16); - if (get_dbg_flag(hevc) & - H265_DEBUG_PRINT_SEI) - hevc_print(hevc, 0, - "\t\tluminance[%1d] = %08x\n", - i, hevc->luminance[i]); - } - hevc->sei_present_flag |= SEI_MASTER_DISPLAY_COLOR_MASK; - } - payload_size -= 24; - while (payload_size > 0) { - data = (READ_HREG(HEVC_SHIFTED_DATA) >> 24); - payload_size--; - WRITE_HREG(HEVC_SHIFT_COMMAND, (1<<7)|8); - hevc_print(hevc, 0, "\t\tskip byte %02x\n", data); - } - } -} - -static int hevc_recover(struct hevc_state_s *hevc) -{ - int ret = -1; - u32 rem; - u64 shift_byte_count64; - unsigned hevc_shift_byte_count; - unsigned hevc_stream_start_addr; - unsigned hevc_stream_end_addr; - unsigned hevc_stream_rd_ptr; - unsigned hevc_stream_wr_ptr; - unsigned hevc_stream_control; - unsigned hevc_stream_fifo_ctl; - unsigned hevc_stream_buf_size; - mutex_lock(&vh265_mutex); -#if 0 - for (i = 0; i < (hevc->debug_ptr_size / 2); i += 4) { - int ii; - - for (ii = 0; ii < 4; ii++) - hevc_print(hevc, 0, - "%04x ", hevc->debug_ptr[i + 3 - ii]); - if (((i + ii) & 0xf) == 0) - hevc_print(hevc, 0, "\n"); - } -#endif -#define ES_VID_MAN_RD_PTR (1<<0) - if (!hevc->init_flag) { - hevc_print(hevc, 0, "h265 has stopped, recover return!\n"); - mutex_unlock(&vh265_mutex); - return ret; - } - amhevc_stop(); - ret = 0; - /* reset */ - WRITE_MPEG_REG(PARSER_VIDEO_RP, READ_VREG(HEVC_STREAM_RD_PTR)); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - - hevc_stream_start_addr = READ_VREG(HEVC_STREAM_START_ADDR); - hevc_stream_end_addr = READ_VREG(HEVC_STREAM_END_ADDR); - hevc_stream_rd_ptr = READ_VREG(HEVC_STREAM_RD_PTR); - hevc_stream_wr_ptr = READ_VREG(HEVC_STREAM_WR_PTR); - hevc_stream_control = READ_VREG(HEVC_STREAM_CONTROL); - hevc_stream_fifo_ctl = READ_VREG(HEVC_STREAM_FIFO_CTL); - hevc_stream_buf_size = hevc_stream_end_addr - hevc_stream_start_addr; - - /* HEVC streaming buffer will reset and restart - from current hevc_stream_rd_ptr position */ - /* calculate HEVC_SHIFT_BYTE_COUNT value with the new position. */ - hevc_shift_byte_count = READ_VREG(HEVC_SHIFT_BYTE_COUNT); - if ((hevc->shift_byte_count_lo & (1 << 31)) - && ((hevc_shift_byte_count & (1 << 31)) == 0)) - hevc->shift_byte_count_hi++; - - hevc->shift_byte_count_lo = hevc_shift_byte_count; - shift_byte_count64 = ((u64)(hevc->shift_byte_count_hi) << 32) | - hevc->shift_byte_count_lo; - div_u64_rem(shift_byte_count64, hevc_stream_buf_size, &rem); - shift_byte_count64 -= rem; - shift_byte_count64 += hevc_stream_rd_ptr - hevc_stream_start_addr; - - if (rem > (hevc_stream_rd_ptr - hevc_stream_start_addr)) - shift_byte_count64 += hevc_stream_buf_size; - - hevc->shift_byte_count_lo = (u32)shift_byte_count64; - hevc->shift_byte_count_hi = (u32)(shift_byte_count64 >> 32); - - WRITE_VREG(DOS_SW_RESET3, - /* (1<<2)| */ - (1 << 3) | (1 << 4) | (1 << 8) | - (1 << 11) | (1 << 12) | (1 << 14) - | (1 << 15) | (1 << 17) | (1 << 18) | (1 << 19)); - WRITE_VREG(DOS_SW_RESET3, 0); - - WRITE_VREG(HEVC_STREAM_START_ADDR, hevc_stream_start_addr); - WRITE_VREG(HEVC_STREAM_END_ADDR, hevc_stream_end_addr); - WRITE_VREG(HEVC_STREAM_RD_PTR, hevc_stream_rd_ptr); - WRITE_VREG(HEVC_STREAM_WR_PTR, hevc_stream_wr_ptr); - WRITE_VREG(HEVC_STREAM_CONTROL, hevc_stream_control); - WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, hevc->shift_byte_count_lo); - WRITE_VREG(HEVC_STREAM_FIFO_CTL, hevc_stream_fifo_ctl); - - hevc_config_work_space_hw(hevc); - decoder_hw_reset(); - - hevc->have_vps = 0; - hevc->have_sps = 0; - hevc->have_pps = 0; - - hevc->have_valid_start_slice = 0; - - if (get_double_write_mode(hevc) & 0x10) - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, - 0x1 << 31 /*/Enable NV21 reference read mode for MC*/ - ); - - WRITE_VREG(HEVC_WAIT_FLAG, 1); - /* clear mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_CLR_REG, 1); - /* enable mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_MASK, 1); - /* disable PSCALE for hardware sharing */ - WRITE_VREG(HEVC_PSCALE_CTRL, 0); - - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - - if (get_dbg_flag(hevc) & H265_DEBUG_UCODE) - WRITE_VREG(DEBUG_REG1, 0x1); - else - WRITE_VREG(DEBUG_REG1, 0x0); - - if ((error_handle_policy & 1) == 0) { - if ((error_handle_policy & 4) == 0) { - /* ucode auto mode, and do not check vps/sps/pps/idr */ - WRITE_VREG(NAL_SEARCH_CTL, - 0xc); - } else { - WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */ - } - } else { - WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */ - } - - if (get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE) - WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x10000); - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) - | ((parser_sei_enable & 0x7) << 17)); -#ifdef CONFIG_AM_VDEC_DV - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | - ((parser_dolby_vision_enable & 0x1) << 20)); -#endif - config_decode_mode(hevc); - WRITE_VREG(DECODE_STOP_POS, decode_stop_pos); - - /* if (amhevc_loadmc(vh265_mc) < 0) { */ - /* amhevc_disable(); */ - /* return -EBUSY; */ - /* } */ -#if 0 - for (i = 0; i < (hevc->debug_ptr_size / 2); i += 4) { - int ii; - - for (ii = 0; ii < 4; ii++) { - /* hevc->debug_ptr[i+3-ii]=ttt++; */ - hevc_print(hevc, 0, - "%04x ", hevc->debug_ptr[i + 3 - ii]); - } - if (((i + ii) & 0xf) == 0) - hevc_print(hevc, 0, "\n"); - } -#endif - init_pic_list_hw(hevc); - - hevc_print(hevc, 0, "%s HEVC_SHIFT_BYTE_COUNT=%x\n", __func__, - READ_VREG(HEVC_SHIFT_BYTE_COUNT)); - - amhevc_start(); - - /* skip, search next start code */ - WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2)); - hevc->skip_flag = 1; -#ifdef ERROR_HANDLE_DEBUG - if (dbg_nal_skip_count & 0x20000) { - dbg_nal_skip_count &= ~0x20000; - mutex_unlock(&vh265_mutex); - return ret; - } -#endif - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); -#ifdef MULTI_INSTANCE_SUPPORT - if (!hevc->m_ins_flag) -#endif - hevc->first_pic_after_recover = 1; - mutex_unlock(&vh265_mutex); - return ret; -} - -static void dump_aux_buf(struct hevc_state_s *hevc) -{ - int i; - unsigned short *aux_adr = - (unsigned short *) - hevc->aux_addr; - unsigned aux_size = - (READ_VREG(HEVC_AUX_DATA_SIZE) - >> 16) << 4; - - if (hevc->prefix_aux_size > 0) { - hevc_print(hevc, 0, - "prefix aux: (size %d)\n", - aux_size); - for (i = 0; i < - (aux_size >> 1); i++) { - hevc_print_cont(hevc, 0, - "%04x ", - *(aux_adr + i)); - if (((i + 1) & 0xf) - == 0) - hevc_print_cont(hevc, - 0, "\n"); - } - } - if (hevc->suffix_aux_size > 0) { - aux_adr = (unsigned short *) - (hevc->aux_addr + - hevc->prefix_aux_size); - aux_size = - (READ_VREG(HEVC_AUX_DATA_SIZE) & 0xffff) - << 4; - hevc_print(hevc, 0, - "suffix aux: (size %d)\n", - aux_size); - for (i = 0; i < - (aux_size >> 1); i++) { - hevc_print_cont(hevc, 0, - "%04x ", *(aux_adr + i)); - if (((i + 1) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - } -} - -static irqreturn_t vh265_isr_thread_fn(int irq, void *data) -{ - struct hevc_state_s *hevc = (struct hevc_state_s *) data; - unsigned int dec_status = hevc->dec_status; - int i, ret; -#ifdef CONFIG_AM_VDEC_DV - struct vdec_s *vdec = hw_to_vdec(hevc); -#endif - if (hevc->error_flag == 1) { - if ((error_handle_policy & 0x10) == 0) { - if (hevc->cur_pic) { - int current_lcu_idx = - READ_VREG(HEVC_PARSER_LCU_START) - & 0xffffff; - if (current_lcu_idx < - ((hevc->lcu_x_num*hevc->lcu_y_num)-1)) - hevc->cur_pic->error_mark = 1; - - } - } - if ((error_handle_policy & 1) == 0) { - hevc->error_skip_nal_count = 1; - /* manual search nal, skip error_skip_nal_count - of nal and trigger the HEVC_NAL_SEARCH_DONE irq */ - WRITE_VREG(NAL_SEARCH_CTL, - (error_skip_nal_count << 4) | 0x1); - } else { - hevc->error_skip_nal_count = error_skip_nal_count; - WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */ - } - if (get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE) { - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | 0x10000); - } - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) - | ((parser_sei_enable & 0x7) << 17)); -#ifdef CONFIG_AM_VDEC_DV - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | - ((parser_dolby_vision_enable & 0x1) << 20)); -#endif - config_decode_mode(hevc); - /* search new nal */ - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - - /* hevc_print(hevc, 0, - "%s: error handle\n", __func__); */ - hevc->error_flag = 2; - return IRQ_HANDLED; - } else if (hevc->error_flag == 3) { - hevc_print(hevc, 0, "error_flag=3, hevc_recover\n"); - hevc_recover(hevc); - hevc->error_flag = 0; - - if ((error_handle_policy & 0x10) == 0) { - if (hevc->cur_pic) { - int current_lcu_idx = - READ_VREG(HEVC_PARSER_LCU_START) - & 0xffffff; - if (current_lcu_idx < - ((hevc->lcu_x_num*hevc->lcu_y_num)-1)) - hevc->cur_pic->error_mark = 1; - - } - } - if ((error_handle_policy & 1) == 0) { - /* need skip some data when - error_flag of 3 is triggered, */ - /* to avoid hevc_recover() being called - for many times at the same bitstream position */ - hevc->error_skip_nal_count = 1; - /* manual search nal, skip error_skip_nal_count - of nal and trigger the HEVC_NAL_SEARCH_DONE irq */ - WRITE_VREG(NAL_SEARCH_CTL, - (error_skip_nal_count << 4) | 0x1); - } - - if ((error_handle_policy & 0x2) == 0) { - hevc->have_vps = 1; - hevc->have_sps = 1; - hevc->have_pps = 1; - } - return IRQ_HANDLED; - } - - i = READ_VREG(HEVC_SHIFT_BYTE_COUNT); - if ((hevc->shift_byte_count_lo & (1 << 31)) && ((i & (1 << 31)) == 0)) - hevc->shift_byte_count_hi++; - hevc->shift_byte_count_lo = i; - -#ifdef MULTI_INSTANCE_SUPPORT - if ((dec_status == HEVC_DECPIC_DATA_DONE || - dec_status == HEVC_FIND_NEXT_PIC_NAL || - dec_status == HEVC_FIND_NEXT_DVEL_NAL) - && (hevc->m_ins_flag)) { - if (hevc->chunk) { - hevc->cur_pic->pts = hevc->chunk->pts; - hevc->cur_pic->pts64 = hevc->chunk->pts64; - } else if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, - hevc->cur_pic->stream_offset, - &hevc->cur_pic->pts, - 0, - &hevc->cur_pic->pts64) != 0) { -#ifdef DEBUG_PTS - hevc->pts_missed++; -#endif - hevc->cur_pic->pts = 0; - hevc->cur_pic->pts64 = 0; - } - } - - if ((dec_status == HEVC_SEARCH_BUFEMPTY) || - (dec_status == HEVC_DECODE_BUFEMPTY) || - (dec_status == HEVC_NAL_DECODE_DONE) - ) { - if (hevc->m_ins_flag) { -#if 1 - if (!vdec_frame_based(hw_to_vdec(hevc))) { - hevc->dec_result = DEC_RESULT_AGAIN; - amhevc_stop(); - } else - hevc->dec_result = DEC_RESULT_GET_DATA; -#else - if (!vdec_frame_based(hw_to_vdec(hevc))) - hevc->dec_result = DEC_RESULT_AGAIN; - else - hevc->dec_result = DEC_RESULT_DONE; - amhevc_stop(); -#endif - reset_process_time(hevc); - schedule_work(&hevc->work); - } - - return IRQ_HANDLED; - } else if (dec_status == HEVC_DECPIC_DATA_DONE) { - if (hevc->m_ins_flag) { - hevc->dec_result = DEC_RESULT_DONE; - amhevc_stop(); - - reset_process_time(hevc); - schedule_work(&hevc->work); - } - - return IRQ_HANDLED; -#ifdef CONFIG_AM_VDEC_DV - } else if (dec_status == HEVC_FIND_NEXT_PIC_NAL || - dec_status == HEVC_FIND_NEXT_DVEL_NAL) { - if (hevc->m_ins_flag) { - unsigned next_parser_type = - READ_HREG(CUR_NAL_UNIT_TYPE); - if (vdec->slave && - dec_status == HEVC_FIND_NEXT_DVEL_NAL) { - /*cur is base, found enhance*/ - struct hevc_state_s *hevc_el = - (struct hevc_state_s *) - vdec->slave->private; - hevc->switch_dvlayer_flag = 1; - hevc_el->start_parser_type = - next_parser_type; - } else if (vdec->master && - dec_status == HEVC_FIND_NEXT_PIC_NAL) { - /*cur is enhance, found base*/ - struct hevc_state_s *hevc_ba = - (struct hevc_state_s *) - vdec->master->private; - hevc->switch_dvlayer_flag = 1; - hevc_ba->start_parser_type = - next_parser_type; - } else { - hevc->switch_dvlayer_flag = 0; - hevc->start_parser_type = - next_parser_type; - } - hevc->dec_result = DEC_RESULT_DONE; - amhevc_stop(); - reset_process_time(hevc); - if (READ_VREG(HEVC_AUX_DATA_SIZE) != 0) { - dma_sync_single_for_cpu( - amports_get_dma_device(), - hevc->aux_phy_addr, - hevc->prefix_aux_size + hevc->suffix_aux_size, - DMA_FROM_DEVICE); - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR_MORE) - dump_aux_buf(hevc); - if (hevc->cur_pic) - set_aux_data(hevc, hevc->cur_pic, 0); - } - - schedule_work(&hevc->work); - } - - return IRQ_HANDLED; -#endif - } else if (dec_status == HEVC_DECODE_TIMEOUT) { - if (vdec_frame_based(hw_to_vdec(hevc)) || - (READ_VREG(HEVC_STREAM_LEVEL) > 0x200)) { - if ((get_dbg_flag(hevc) - & H265_DEBUG_DIS_LOC_ERROR_PROC)) { - hevc_print(hevc, 0, - "%s decoding error, level 0x%x\n", - __func__, READ_VREG(HEVC_STREAM_LEVEL)); - goto send_again; - } - amhevc_stop(); - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s %s\n", __func__, - (dec_status == HEVC_SEARCH_BUFEMPTY) ? - "HEVC_SEARCH_BUFEMPTY" : - (dec_status == HEVC_DECODE_BUFEMPTY) ? - "HEVC_DECODE_BUFEMPTY" : "HEVC_DECODE_TIMEOUT"); - hevc->dec_result = DEC_RESULT_DONE; - - reset_process_time(hevc); - schedule_work(&hevc->work); - } else { - /* WRITE_VREG(dec_status_REG, H264_ACTION_INIT); */ - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_AGAIN\n", __func__); -send_again: - hevc->dec_result = DEC_RESULT_AGAIN; - reset_process_time(hevc); - schedule_work(&hevc->work); - } - return IRQ_HANDLED; - } - -#endif - - if (dec_status == HEVC_SEI_DAT) { - int payload_type = READ_HREG(CUR_NAL_UNIT_TYPE) & 0xffff; - int payload_size = - (READ_HREG(CUR_NAL_UNIT_TYPE) >> 16) & 0xffff; - process_nal_sei(hevc, payload_type, payload_size); - - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_SEI_DAT_DONE); - } else if (dec_status == HEVC_NAL_SEARCH_DONE) { - int naltype = READ_HREG(CUR_NAL_UNIT_TYPE); - int parse_type = HEVC_DISCARD_NAL; - - hevc->error_watchdog_count = 0; - hevc->error_skip_nal_wt_cnt = 0; - if (slice_parse_begin > 0 && - get_dbg_flag(hevc) & H265_DEBUG_DISCARD_NAL) { - hevc_print(hevc, 0, - "nal type %d, discard %d\n", naltype, - slice_parse_begin); - if (naltype <= NAL_UNIT_CODED_SLICE_CRA) - slice_parse_begin--; - } - if (naltype == NAL_UNIT_EOS) { - struct PIC_s *pic; - hevc_print(hevc, 0, "get NAL_UNIT_EOS, flush output\n"); - pic = get_pic_by_POC(hevc, hevc->curr_POC); - hevc->curr_POC = INVALID_POC; - /* add to fix RAP_B_Bossen_1 */ - hevc->m_pocRandomAccess = MAX_INT; - flush_output(hevc, pic); - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_DISCARD_NAL); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - return IRQ_HANDLED; - } - - if (hevc->error_skip_nal_count > 0) { - hevc_print(hevc, 0, - "nal type %d, discard %d\n", naltype, - hevc->error_skip_nal_count); - hevc->error_skip_nal_count--; - if (hevc->error_skip_nal_count == 0) { - hevc_recover(hevc); - hevc->error_flag = 0; - if ((error_handle_policy & 0x2) == 0) { - hevc->have_vps = 1; - hevc->have_sps = 1; - hevc->have_pps = 1; - } - return IRQ_HANDLED; - } - } else if (naltype == NAL_UNIT_VPS) { - parse_type = HEVC_NAL_UNIT_VPS; - hevc->have_vps = 1; -#ifdef ERROR_HANDLE_DEBUG - if (dbg_nal_skip_flag & 1) - parse_type = HEVC_DISCARD_NAL; -#endif - } else if (hevc->have_vps) { - if (naltype == NAL_UNIT_SPS) { - parse_type = HEVC_NAL_UNIT_SPS; - hevc->have_sps = 1; -#ifdef ERROR_HANDLE_DEBUG - if (dbg_nal_skip_flag & 2) - parse_type = HEVC_DISCARD_NAL; -#endif - } else if (naltype == NAL_UNIT_PPS) { - parse_type = HEVC_NAL_UNIT_PPS; - hevc->have_pps = 1; -#ifdef ERROR_HANDLE_DEBUG - if (dbg_nal_skip_flag & 4) - parse_type = HEVC_DISCARD_NAL; -#endif - } else if (hevc->have_sps && hevc->have_pps) { - int seg = HEVC_NAL_UNIT_CODED_SLICE_SEGMENT; - - if ((naltype == NAL_UNIT_CODED_SLICE_IDR) || - (naltype == - NAL_UNIT_CODED_SLICE_IDR_N_LP) - || (naltype == - NAL_UNIT_CODED_SLICE_CRA) - || (naltype == - NAL_UNIT_CODED_SLICE_BLA) - || (naltype == - NAL_UNIT_CODED_SLICE_BLANT) - || (naltype == - NAL_UNIT_CODED_SLICE_BLA_N_LP) - ) { - if (slice_parse_begin > 0) { - hevc_print(hevc, 0, - "discard %d, for debugging\n", - slice_parse_begin); - slice_parse_begin--; - } else { - parse_type = seg; - } - hevc->have_valid_start_slice = 1; - } else if (naltype <= - NAL_UNIT_CODED_SLICE_CRA - && (hevc->have_valid_start_slice - || (hevc->PB_skip_mode != 3))) { - if (slice_parse_begin > 0) { - hevc_print(hevc, 0, - "discard %d, dd\n", - slice_parse_begin); - slice_parse_begin--; - } else - parse_type = seg; - - } - } - } - if (hevc->have_vps && hevc->have_sps && hevc->have_pps - && hevc->have_valid_start_slice && - hevc->error_flag == 0) { - if ((get_dbg_flag(hevc) & - H265_DEBUG_MAN_SEARCH_NAL) == 0 /*&& - (!hevc->m_ins_flag)*/) { - /* auot parser NAL; do not check - vps/sps/pps/idr */ - WRITE_VREG(NAL_SEARCH_CTL, 0x2); - } - - if (get_dbg_flag(hevc) & - H265_DEBUG_NO_EOS_SEARCH_DONE) { - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | - 0x10000); - } - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) - | ((parser_sei_enable & 0x7) << 17)); -#ifdef CONFIG_AM_VDEC_DV - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | - ((parser_dolby_vision_enable & 0x1) << 20)); -#endif - config_decode_mode(hevc); - } - - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) { - hevc_print(hevc, 0, - "naltype = %d parse_type %d\n %d %d %d %d\n", - naltype, parse_type, hevc->have_vps, - hevc->have_sps, hevc->have_pps, - hevc->have_valid_start_slice); - } - - WRITE_VREG(HEVC_DEC_STATUS_REG, parse_type); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - - } else if (dec_status == HEVC_SLICE_SEGMENT_DONE) { - if (hevc->start_decoding_time > 0) { - u32 process_time = 1000* - (jiffies - hevc->start_decoding_time)/HZ; - if (process_time > max_decoding_time) - max_decoding_time = process_time; - } - - hevc->error_watchdog_count = 0; - if (hevc->pic_list_init_flag == 2) { - hevc->pic_list_init_flag = 3; - hevc_print(hevc, 0, "set pic_list_init_flag to 3\n"); - } else if (hevc->wait_buf == 0) { - u32 vui_time_scale; - u32 vui_num_units_in_tick; - - if (get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) - get_rpm_param(&hevc->param); - else { - dma_sync_single_for_cpu( - amports_get_dma_device(), - hevc->rpm_phy_addr, - RPM_BUF_SIZE, - DMA_FROM_DEVICE); - - for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { - int ii; - - for (ii = 0; ii < 4; ii++) { - hevc->param.l.data[i + ii] = - hevc->rpm_ptr[i + 3 - - ii]; - } - } - } - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) { - hevc_print(hevc, 0, - "rpm_param: (%d)\n", hevc->slice_idx); - hevc->slice_idx++; - for (i = 0; i < (RPM_END - RPM_BEGIN); i++) { - hevc_print_cont(hevc, 0, - "%04x ", hevc->param.l.data[i]); - if (((i + 1) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - - hevc_print(hevc, 0, - "vui_timing_info: %x, %x, %x, %x\n", - hevc->param.p.vui_num_units_in_tick_hi, - hevc->param.p.vui_num_units_in_tick_lo, - hevc->param.p.vui_time_scale_hi, - hevc->param.p.vui_time_scale_lo); - } - if ( -#ifdef CONFIG_AM_VDEC_DV - vdec->master == NULL && - vdec->slave == NULL && -#endif - READ_VREG(HEVC_AUX_DATA_SIZE) != 0 - ) { - dma_sync_single_for_cpu( - amports_get_dma_device(), - hevc->aux_phy_addr, - hevc->prefix_aux_size + hevc->suffix_aux_size, - DMA_FROM_DEVICE); - if (get_dbg_flag(hevc) & - H265_DEBUG_BUFMGR_MORE) - dump_aux_buf(hevc); - } - - vui_time_scale = - (u32)(hevc->param.p.vui_time_scale_hi << 16) | - hevc->param.p.vui_time_scale_lo; - vui_num_units_in_tick = - (u32)(hevc->param. - p.vui_num_units_in_tick_hi << 16) | - hevc->param. - p.vui_num_units_in_tick_lo; - if (hevc->bit_depth_luma != - ((hevc->param.p.bit_depth & 0xf) + 8)) { - hevc_print(hevc, 0, "Bit depth luma = %d\n", - (hevc->param.p.bit_depth & 0xf) + 8); - } - if (hevc->bit_depth_chroma != - (((hevc->param.p.bit_depth >> 4) & 0xf) + 8)) { - hevc_print(hevc, 0, "Bit depth chroma = %d\n", - ((hevc->param.p.bit_depth >> 4) & - 0xf) + 8); - } - hevc->bit_depth_luma = - (hevc->param.p.bit_depth & 0xf) + 8; - hevc->bit_depth_chroma = - ((hevc->param.p.bit_depth >> 4) & 0xf) + 8; - bit_depth_luma = hevc->bit_depth_luma; - bit_depth_chroma = hevc->bit_depth_chroma; -#ifdef SUPPORT_10BIT - if (hevc->bit_depth_luma == 8 && - hevc->bit_depth_chroma == 8 && - enable_mem_saving) - hevc->mem_saving_mode = 1; - else - hevc->mem_saving_mode = 0; -#endif - if ((vui_time_scale != 0) - && (vui_num_units_in_tick != 0)) { - hevc->frame_dur = - div_u64(96000ULL * - vui_num_units_in_tick, - vui_time_scale); - hevc->get_frame_dur = true; - } - - if (hevc->video_signal_type != - ((hevc->param.p.video_signal_type << 16) - | hevc->param.p.color_description)) { - u32 v = hevc->param.p.video_signal_type; - u32 c = hevc->param.p.color_description; -#if 0 - if (v & 0x2000) { - hevc_print(hevc, 0, - "video_signal_type present:\n"); - hevc_print(hevc, 0, " %s %s\n", - video_format_names[(v >> 10) & 7], - ((v >> 9) & 1) ? - "full_range" : "limited"); - if (v & 0x100) { - hevc_print(hevc, 0, - " color_description present:\n"); - hevc_print(hevc, 0, - " color_primarie = %s\n", - color_primaries_names - [v & 0xff]); - hevc_print(hevc, 0, - " transfer_characteristic = %s\n", - transfer_characteristics_names - [(c >> 8) & 0xff]); - hevc_print(hevc, 0, - " matrix_coefficient = %s\n", - matrix_coeffs_names[c & 0xff]); - } - } -#endif - hevc->video_signal_type = (v << 16) | c; - video_signal_type = hevc->video_signal_type; - } - - if (use_cma && - (hevc->param.p.slice_segment_address == 0) - && (hevc->pic_list_init_flag == 0)) { - 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 = hevc->param.p.pic_width_in_luma_samples; - hevc->pic_h = hevc->param.p.pic_height_in_luma_samples; - hevc->lcu_size = 1 << (log + 3 + log_s); - hevc->lcu_size_log2 = log2i(hevc->lcu_size); - if (hevc->pic_w == 0 || hevc->pic_h == 0 - || hevc->lcu_size == 0) { - /* skip search next start code */ - WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) - & (~0x2)); - hevc->skip_flag = 1; - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - - } else { - hevc->sps_num_reorder_pics_0 = - hevc->param.p.sps_num_reorder_pics_0; - hevc->pic_list_init_flag = 1; -#ifdef MULTI_INSTANCE_SUPPORT - if (hevc->m_ins_flag) { - reset_process_time(hevc); - schedule_work(&hevc->work); - } else -#endif - up(&hevc->h265_sema); - hevc_print(hevc, 0, "set pic_list_init_flag 1\n"); - } - return IRQ_HANDLED; - } - -} - ret = - hevc_slice_segment_header_process(hevc, - &hevc->param, decode_pic_begin); - if (ret < 0) - ; - else if (ret == 0) { - if ((hevc->new_pic) && (hevc->cur_pic)) { - hevc->cur_pic->stream_offset = - READ_VREG(HEVC_SHIFT_BYTE_COUNT); - } - - WRITE_VREG(HEVC_DEC_STATUS_REG, - HEVC_CODED_SLICE_SEGMENT_DAT); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - - hevc->start_decoding_time = jiffies; -#if 1 - /*to do..., copy aux data to hevc->cur_pic*/ -#endif -#ifdef MULTI_INSTANCE_SUPPORT - } else if (hevc->m_ins_flag) { - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s, bufmgr ret %d skip, DEC_RESULT_DONE\n", - __func__, ret); - hevc->dec_result = DEC_RESULT_DONE; - amhevc_stop(); - reset_process_time(hevc); - schedule_work(&hevc->work); -#endif - } else { - /* skip, search next start code */ - WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2)); - hevc->skip_flag = 1; - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - /* Interrupt Amrisc to excute */ - WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ); - } - - } - - if (mmu_enable) { - if (hevc->last_put_idx_a >= 0 - && hevc->last_put_idx_a < MAX_REF_PIC_NUM) { - int i = hevc->last_put_idx_a; - struct PIC_s *pic = hevc->m_PIC[i]; - - /*free not used buffers.*/ - if (pic && - pic->output_mark == 0 && pic->referenced == 0 - && pic->output_ready == 0 - && pic->used_by_display == 0 - && (pic->index != -1)) { - decoder_mmu_box_free_idx(hevc->mmu_box, i); - hevc->last_put_idx_a = -1; - /* hevc_print(hevc, 0, "release pic buf %x\n",i);*/ - } - } - if (hevc->last_put_idx_b >= 0 - && hevc->last_put_idx_b < MAX_REF_PIC_NUM) { - int i = hevc->last_put_idx_b; - struct PIC_s *pic = hevc->m_PIC[i]; - - /*free not used buffers.*/ - if (pic && - pic->output_mark == 0 && pic->referenced == 0 - && pic->output_ready == 0 - && pic->used_by_display == 0 - && (pic->index != -1)) { - decoder_mmu_box_free_idx(hevc->mmu_box, i); - hevc->last_put_idx_b = -1; - } - } - } - - return IRQ_HANDLED; -} - -static irqreturn_t vh265_isr(int irq, void *data) -{ - int i, temp; - unsigned int dec_status; - struct hevc_state_s *hevc = (struct hevc_state_s *)data; - - dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - if (hevc->init_flag == 0) - return IRQ_HANDLED; - hevc->dec_status = dec_status; - if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) - hevc_print(hevc, 0, - "265 isr dec status = 0x%x\n", dec_status); - - if (get_dbg_flag(hevc) & H265_DEBUG_UCODE) { - if (READ_HREG(DEBUG_REG1) & 0x10000) { - dma_sync_single_for_cpu( - amports_get_dma_device(), - hevc->lmem_phy_addr, - LMEM_BUF_SIZE, - DMA_FROM_DEVICE); - - hevc_print(hevc, 0, - "LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1)); - - if (mmu_enable) - temp = 0x500; - else - temp = 0x400; - for (i = 0; i < temp; i += 4) { - int ii; - - if ((i & 0xf) == 0) - hevc_print_cont(hevc, 0, "%03x: ", i); - for (ii = 0; ii < 4; ii++) { - hevc_print_cont(hevc, 0, "%04x ", - hevc->lmem_ptr[i + 3 - ii]); - } - if (((i + ii) & 0xf) == 0) - hevc_print_cont(hevc, 0, "\n"); - } - WRITE_HREG(DEBUG_REG1, 0); - } else if (READ_HREG(DEBUG_REG1) != 0) { - hevc_print(hevc, 0, - "dbg%x: %x\n", READ_HREG(DEBUG_REG1), - READ_HREG(DEBUG_REG2)); - WRITE_HREG(DEBUG_REG1, 0); - return IRQ_HANDLED; - } - - } - - if (hevc->pic_list_init_flag == 1) - return IRQ_HANDLED; - - return IRQ_WAKE_THREAD; - -} - -static void vh265_check_timer_func(unsigned long arg) -{ - struct hevc_state_s *hevc = (struct hevc_state_s *)arg; - struct timer_list *timer = &hevc->timer; - unsigned char empty_flag; - unsigned int buf_level; - - enum receviver_start_e state = RECEIVER_INACTIVE; - if (hevc->init_flag == 0) { - if (hevc->stat & STAT_TIMER_ARM) { - timer->expires = jiffies + PUT_INTERVAL; - add_timer(&hevc->timer); - } - return; - } -#ifdef MULTI_INSTANCE_SUPPORT - if (hevc->m_ins_flag && - hw_to_vdec(hevc)->next_status == - VDEC_STATUS_DISCONNECTED) { - hevc->dec_result = DEC_RESULT_DONE; - schedule_work(&hevc->work); - hevc_print(hevc, - 0, "vdec requested to be disconnected\n"); - return; - } - - if (hevc->m_ins_flag) { - if ((input_frame_based(hw_to_vdec(hevc)) || - (READ_VREG(HEVC_STREAM_LEVEL) > 0x200)) && - ((get_dbg_flag(hevc) & - H265_DEBUG_DIS_LOC_ERROR_PROC) == 0) && - (decode_timeout_val > 0) && - (hevc->start_process_time > 0) && - ((1000 * (jiffies - hevc->start_process_time) / HZ) - > decode_timeout_val) - ) { - u32 dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - int current_lcu_idx = - READ_VREG(HEVC_PARSER_LCU_START)&0xffffff; - if (dec_status == HEVC_CODED_SLICE_SEGMENT_DAT) { - if (hevc->last_lcu_idx == current_lcu_idx) { - if (hevc->decode_timeout_count > 0) - hevc->decode_timeout_count--; - if (hevc->decode_timeout_count == 0) - timeout_process(hevc); - } - hevc->last_lcu_idx = current_lcu_idx; - } else - timeout_process(hevc); - } - } else { -#endif - if (hevc->m_ins_flag == 0 && - vf_get_receiver(hevc->provider_name)) { - state = - vf_notify_receiver(hevc->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 (hevc->m_ins_flag == 0 && - (empty_flag == 0) - && (hevc->pic_list_init_flag == 0 - || hevc->pic_list_init_flag - == 3)) { - /* decoder has input */ - if ((get_dbg_flag(hevc) & - H265_DEBUG_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(&hevc->display_q) && - buf_level > 0x200) - ) { - if (hevc->error_flag == 0) { - hevc->error_watchdog_count++; - if (hevc->error_watchdog_count == - error_handle_threshold) { - hevc_print(hevc, 0, - "H265 dec err local reset.\n"); - hevc->error_flag = 1; - hevc->error_watchdog_count = 0; - hevc->error_skip_nal_wt_cnt = 0; - hevc-> - error_system_watchdog_count++; - WRITE_VREG - (HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - } - } else if (hevc->error_flag == 2) { - int th = - error_handle_nal_skip_threshold; - hevc->error_skip_nal_wt_cnt++; - if (hevc->error_skip_nal_wt_cnt - == th) { - hevc->error_flag = 3; - hevc->error_watchdog_count = 0; - hevc-> - error_skip_nal_wt_cnt = 0; - WRITE_VREG - (HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - } - } - } - } - - if ((get_dbg_flag(hevc) - & H265_DEBUG_DIS_SYS_ERROR_PROC) == 0) - /* receiver has no buffer to recycle */ - if ((state == RECEIVER_INACTIVE) && - (kfifo_is_empty(&hevc->display_q)) - ) { /* no buffer to recycle */ - if ((get_dbg_flag(hevc) & - H265_DEBUG_DIS_LOC_ERROR_PROC) != - 0) - hevc->error_system_watchdog_count++; - if (hevc->error_system_watchdog_count == - error_handle_system_threshold) { - /* and it lasts for a while */ - hevc_print(hevc, 0, - "H265 dec fatal error watchdog.\n"); - hevc-> - error_system_watchdog_count = 0; - hevc->fatal_error = - DECODER_FATAL_ERROR_UNKNOWN; - } - } - } else { - hevc->error_watchdog_count = 0; - hevc->error_system_watchdog_count = 0; - } -#ifdef MULTI_INSTANCE_SUPPORT - } -#endif - if (decode_stop_pos != decode_stop_pos_pre) { - WRITE_VREG(DECODE_STOP_POS, decode_stop_pos); - decode_stop_pos_pre = decode_stop_pos; - } - - if (get_dbg_flag(hevc) & H265_DEBUG_DUMP_PIC_LIST) { - dump_pic_list(hevc); - debug &= ~H265_DEBUG_DUMP_PIC_LIST; - } - if (get_dbg_flag(hevc) & H265_DEBUG_TRIG_SLICE_SEGMENT_PROC) { - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, 0x1); - debug &= ~H265_DEBUG_TRIG_SLICE_SEGMENT_PROC; - } - if (get_dbg_flag(hevc) & H265_DEBUG_HW_RESET) { - hevc->error_skip_nal_count = error_skip_nal_count; - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - - debug &= ~H265_DEBUG_HW_RESET; - } - if (get_dbg_flag(hevc) & H265_DEBUG_ERROR_TRIG) { - WRITE_VREG(DECODE_STOP_POS, 1); - debug &= ~H265_DEBUG_ERROR_TRIG; - } -#ifdef ERROR_HANDLE_DEBUG - if ((dbg_nal_skip_count > 0) && ((dbg_nal_skip_count & 0x10000) != 0)) { - hevc->error_skip_nal_count = dbg_nal_skip_count & 0xffff; - dbg_nal_skip_count &= ~0x10000; - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - } -#endif - - if (radr != 0) { - if (rval != 0) { - WRITE_VREG(radr, rval); - hevc_print(hevc, 0, - "WRITE_VREG(%x,%x)\n", radr, rval); - } else - hevc_print(hevc, 0, - "READ_VREG(%x)=%x\n", radr, READ_VREG(radr)); - rval = 0; - radr = 0; - } - if (dbg_cmd != 0) { - if (dbg_cmd == 1) { - u32 disp_laddr; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB && - get_double_write_mode(hevc) == 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; - } - hevc_print(hevc, 0, - "current displayed buffer address %x\r\n", - disp_laddr); - } - dbg_cmd = 0; - } - /*don't changed at start.*/ - if (hevc->m_ins_flag == 0 && - hevc->get_frame_dur && hevc->show_frame_num > 60 && - hevc->frame_dur > 0 && hevc->saved_resolution != - hevc->frame_width * hevc->frame_height * - (96000 / hevc->frame_dur)) { - int fps = 96000 / hevc->frame_dur; - - if (hevc_source_changed(VFORMAT_HEVC, - hevc->frame_width, hevc->frame_height, fps) > 0) - hevc->saved_resolution = hevc->frame_width * - hevc->frame_height * fps; - } - - - timer->expires = jiffies + PUT_INTERVAL; - add_timer(timer); -} - -static int h265_task_handle(void *data) -{ - int ret = 0; - struct hevc_state_s *hevc = (struct hevc_state_s *)data; - - set_user_nice(current, -10); - while (1) { - if (use_cma == 0) { - hevc_print(hevc, 0, - "ERROR: use_cma can not be changed dynamically\n"); - } - ret = down_interruptible(&hevc->h265_sema); - if ((hevc->init_flag != 0) && (hevc->pic_list_init_flag == 1)) { - /*USE_BUF_BLOCK*/ - init_buf_list(hevc); - /**/ - init_pic_list(hevc); - init_pic_list_hw(hevc); - init_buf_spec(hevc); - hevc->pic_list_init_flag = 2; - hevc_print(hevc, 0, "set pic_list_init_flag to 2\n"); - - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, 0x1); - - } - - if (hevc->uninit_list) { - /*USE_BUF_BLOCK*/ - uninit_pic_list(hevc); - hevc_print(hevc, 0, "uninit list\n"); - hevc->uninit_list = 0; -#ifdef USE_UNINIT_SEMA - up(&hevc->h265_uninit_done_sema); -#endif - } - - } - - return 0; - -} - -void vh265_free_cmabuf(void) -{ - struct hevc_state_s *hevc = &gHevc; - - mutex_lock(&vh265_mutex); - - if (hevc->init_flag) { - mutex_unlock(&vh265_mutex); - return; - } - - mutex_unlock(&vh265_mutex); -} - -#ifdef MULTI_INSTANCE_SUPPORT -int vh265_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -#else -int vh265_dec_status(struct vdec_status *vstatus) -#endif -{ - struct hevc_state_s *hevc = &gHevc; - - vstatus->width = hevc->frame_width; - vstatus->height = hevc->frame_height; - if (hevc->frame_dur != 0) - vstatus->fps = 96000 / hevc->frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = 0; - vstatus->status = hevc->stat | hevc->fatal_error; - return 0; -} - -#if 0 -static void H265_DECODE_INIT(void) -{ - /* enable hevc clocks */ - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); - /* *************************************************************** */ - /* Power ON HEVC */ - /* *************************************************************** */ - /* Powerup HEVC */ - WRITE_VREG(P_AO_RTI_GEN_PWR_SLEEP0, - READ_VREG(P_AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6))); - WRITE_VREG(DOS_MEM_PD_HEVC, 0x0); - WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2)); - WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2))); - /* remove isolations */ - WRITE_VREG(AO_RTI_GEN_PWR_ISO0, - READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10))); - -} -#endif - -static void config_decode_mode(struct hevc_state_s *hevc) -{ -#ifdef CONFIG_AM_VDEC_DV - struct vdec_s *vdec = hw_to_vdec(hevc); -#endif - if (!hevc->m_ins_flag) - WRITE_VREG(HEVC_DECODE_MODE, - DECODE_MODE_SINGLE); - else if (vdec_frame_based(hw_to_vdec(hevc))) - WRITE_VREG(HEVC_DECODE_MODE, - DECODE_MODE_MULTI_FRAMEBASE); -#ifdef CONFIG_AM_VDEC_DV - else if (vdec->slave) - WRITE_VREG(HEVC_DECODE_MODE, - (hevc->start_parser_type << 8) - | DECODE_MODE_MULTI_DVBAL); - else if (vdec->master) - WRITE_VREG(HEVC_DECODE_MODE, - (hevc->start_parser_type << 8) - | DECODE_MODE_MULTI_DVENL); -#endif - else - WRITE_VREG(HEVC_DECODE_MODE, - DECODE_MODE_MULTI_STREAMBASE); -} - -static void vh265_prot_init(struct hevc_state_s *hevc) -{ - /* H265_DECODE_INIT(); */ - - hevc_config_work_space_hw(hevc); - - hevc_init_decoder_hw(hevc, 0, 0xffffffff); - - WRITE_VREG(HEVC_WAIT_FLAG, 1); - - /* WRITE_VREG(P_HEVC_MPSR, 1); */ - - /* clear mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_MASK, 1); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(HEVC_PSCALE_CTRL, 0); - - if (get_dbg_flag(hevc) & H265_DEBUG_UCODE) - WRITE_VREG(DEBUG_REG1, 0x1); - else - WRITE_VREG(DEBUG_REG1, 0x0); - - if ((get_dbg_flag(hevc) & - (H265_DEBUG_MAN_SKIP_NAL | - H265_DEBUG_MAN_SEARCH_NAL))/* || - hevc->m_ins_flag*/) { - WRITE_VREG(NAL_SEARCH_CTL, 0x1); /* manual parser NAL */ - } else { - /* check vps/sps/pps/i-slice in ucode */ - unsigned ctl_val = 0x8; -#ifdef MULTI_INSTANCE_SUPPORT - if (hevc->m_ins_flag && - hevc->init_flag) { - /* do not check vps/sps/pps/i-slice in ucode - from the 2nd picture*/ - ctl_val = 0x2; - } else -#endif - if (hevc->PB_skip_mode == 0) - ctl_val = 0x4; /* check vps/sps/pps only in ucode */ - else if (hevc->PB_skip_mode == 3) - ctl_val = 0x0; /* check vps/sps/pps/idr in ucode */ - WRITE_VREG(NAL_SEARCH_CTL, ctl_val); - } - if (get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE) - WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x10000); - - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) - | ((parser_sei_enable & 0x7) << 17)); -#ifdef CONFIG_AM_VDEC_DV - WRITE_VREG(NAL_SEARCH_CTL, - READ_VREG(NAL_SEARCH_CTL) | - ((parser_dolby_vision_enable & 0x1) << 20)); -#endif - WRITE_VREG(DECODE_STOP_POS, decode_stop_pos); - - config_decode_mode(hevc); - config_aux_buf(hevc); -} - -static int vh265_local_init(struct hevc_state_s *hevc) -{ - int i; - int ret = -1; - -#ifdef DEBUG_PTS - hevc->pts_missed = 0; - hevc->pts_hit = 0; -#endif - - hevc->last_put_idx_a = -1; - hevc->last_put_idx_b = -1; - hevc->saved_resolution = 0; - hevc->get_frame_dur = false; - hevc->frame_width = hevc->vh265_amstream_dec_info.width; - hevc->frame_height = hevc->vh265_amstream_dec_info.height; - if (HEVC_SIZE < hevc->frame_width * hevc->frame_height) { - pr_info("over size : %u x %u.\n", - hevc->frame_width, hevc->frame_height); - hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW; - return ret; - } - hevc->frame_dur = - (hevc->vh265_amstream_dec_info.rate == - 0) ? 3600 : hevc->vh265_amstream_dec_info.rate; - if (hevc->frame_width && hevc->frame_height) - hevc->frame_ar = hevc->frame_height * 0x100 / hevc->frame_width; - hevc->error_watchdog_count = 0; - hevc->sei_present_flag = 0; - pts_unstable = ((unsigned long)hevc->vh265_amstream_dec_info.param - & 0x40) >> 6; - hevc_print(hevc, 0, - "h265:pts_unstable=%d\n", pts_unstable); -/* -*TODO:FOR VERSION -*/ - hevc_print(hevc, 0, - "h265: ver (%d,%d) decinfo: %dx%d rate=%d\n", h265_version, - 0, hevc->frame_width, hevc->frame_height, hevc->frame_dur); - - if (hevc->frame_dur == 0) - hevc->frame_dur = 96000 / 24; - - INIT_KFIFO(hevc->display_q); - INIT_KFIFO(hevc->newframe_q); - - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &hevc->vfpool[i]; - - hevc->vfpool[i].index = -1; - kfifo_put(&hevc->newframe_q, vf); - } - - - ret = hevc_local_init(hevc); - - return ret; -} -#ifdef MULTI_INSTANCE_SUPPORT -static s32 vh265_init(struct vdec_s *vdec) -{ - struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; -#else -static s32 vh265_init(struct hevc_state_s *hevc) -{ - -#endif - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - init_timer(&hevc->timer); - - hevc->stat |= STAT_TIMER_INIT; - if (vh265_local_init(hevc) < 0) { - vfree(buf); - return -EBUSY; - } - -#ifdef MULTI_INSTANCE_SUPPORT - if (hevc->m_ins_flag) { - hevc->timer.data = (ulong) hevc; - hevc->timer.function = vh265_check_timer_func; - hevc->timer.expires = jiffies + PUT_INTERVAL; - - /*add_timer(&hevc->timer); - - hevc->stat |= STAT_TIMER_ARM;*/ - - INIT_WORK(&hevc->work, vh265_work); - vfree(buf); - return 0; - } -#endif - amhevc_enable(); - - if (mmu_enable && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { - size = get_firmware_data(VIDEO_DEC_HEVC_MMU, buf); - hevc_print(hevc, 0, "vh265 mmu ucode loaded!\n"); - } else - size = get_firmware_data(VIDEO_DEC_HEVC, buf); - - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return -1; - } - - if (amhevc_loadmc_ex(VFORMAT_HEVC, NULL, buf) < 0) { - amhevc_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - hevc->stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vh265_prot_init(hevc); - - if (vdec_request_threaded_irq(VDEC_IRQ_1, vh265_isr, - vh265_isr_thread_fn, - IRQF_ONESHOT,/*run thread on this irq disabled*/ - "vh265-irq", (void *)hevc)) { - hevc_print(hevc, 0, "vh265 irq register error.\n"); - amhevc_disable(); - return -ENOENT; - } - - hevc->stat |= STAT_ISR_REG; - hevc->provider_name = PROVIDER_NAME; - -#ifdef MULTI_INSTANCE_SUPPORT - 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); - vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)hevc->frame_dur)); -#else - vf_provider_init(&vh265_vf_prov, PROVIDER_NAME, &vh265_vf_provider, - hevc); - vf_reg_provider(&vh265_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)hevc->frame_dur)); -#endif - hevc->stat |= STAT_VF_HOOK; - - hevc->timer.data = (ulong) hevc; - hevc->timer.function = vh265_check_timer_func; - hevc->timer.expires = jiffies + PUT_INTERVAL; - - add_timer(&hevc->timer); - - hevc->stat |= STAT_TIMER_ARM; - - if (use_cma) { - if (h265_task == NULL) { - sema_init(&hevc->h265_sema, 1); -#ifdef USE_UNINIT_SEMA - sema_init( - &hevc->h265_uninit_done_sema, 0); -#endif - h265_task = - kthread_run(h265_task_handle, hevc, - "kthread_h265"); - } - } - /* hevc->stat |= STAT_KTHREAD; */ - - if (get_dbg_flag(hevc) & H265_DEBUG_FORCE_CLK) { - hevc_print(hevc, 0, "%s force clk\n", __func__); - WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, - READ_VREG(HEVC_IQIT_CLK_RST_CTRL) | - ((1 << 2) | (1 << 1))); - WRITE_VREG(HEVC_DBLK_CFG0, - READ_VREG(HEVC_DBLK_CFG0) | ((1 << 2) | - (1 << 1) | 0x3fff0000));/* 2,29:16 */ - WRITE_VREG(HEVC_SAO_CTRL1, READ_VREG(HEVC_SAO_CTRL1) | - (1 << 2)); /* 2 */ - WRITE_VREG(HEVC_MPRED_CTRL1, READ_VREG(HEVC_MPRED_CTRL1) | - (1 << 24)); /* 24 */ - WRITE_VREG(HEVC_STREAM_CONTROL, - READ_VREG(HEVC_STREAM_CONTROL) | - (1 << 15)); /* 15 */ - WRITE_VREG(HEVC_CABAC_CONTROL, READ_VREG(HEVC_CABAC_CONTROL) | - (1 << 13)); /* 13 */ - WRITE_VREG(HEVC_PARSER_CORE_CONTROL, - READ_VREG(HEVC_PARSER_CORE_CONTROL) | - (1 << 15)); /* 15 */ - WRITE_VREG(HEVC_PARSER_INT_CONTROL, - READ_VREG(HEVC_PARSER_INT_CONTROL) | - (1 << 15)); /* 15 */ - WRITE_VREG(HEVC_PARSER_IF_CONTROL, - READ_VREG(HEVC_PARSER_IF_CONTROL) | ((1 << 6) | - (1 << 3) | (1 << 1))); /* 6, 3, 1 */ - WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, - READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG) | - 0xffffffff); /* 31:0 */ - WRITE_VREG(HEVCD_MCRCC_CTL1, READ_VREG(HEVCD_MCRCC_CTL1) | - (1 << 3)); /* 3 */ - } - - amhevc_start(); - - hevc->stat |= STAT_VDEC_RUN; -#ifndef MULTI_INSTANCE_SUPPORT - set_vdec_func(&vh265_dec_status); -#endif - hevc->init_flag = 1; - if (mmu_enable) - error_handle_threshold = 300; - else - error_handle_threshold = 30; - /* pr_info("%d, vh265_init, RP=0x%x\n", - __LINE__, READ_VREG(HEVC_STREAM_RD_PTR)); */ - - return 0; -} - -static int vh265_stop(struct hevc_state_s *hevc) -{ - - hevc->init_flag = 0; - - if (get_dbg_flag(hevc) & - H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP) { - int wait_timeout_count = 0; - - while (READ_VREG(HEVC_DEC_STATUS_REG) == - HEVC_CODED_SLICE_SEGMENT_DAT && - wait_timeout_count < 10){ - wait_timeout_count++; - msleep(20); - } - } - if (hevc->stat & STAT_VDEC_RUN) { - amhevc_stop(); - hevc->stat &= ~STAT_VDEC_RUN; - } - - if (hevc->stat & STAT_ISR_REG) { - WRITE_VREG(HEVC_ASSIST_MBOX1_MASK, 0); - vdec_free_irq(VDEC_IRQ_1, (void *)hevc); - hevc->stat &= ~STAT_ISR_REG; - } - - hevc->stat &= ~STAT_TIMER_INIT; - if (hevc->stat & STAT_TIMER_ARM) { - del_timer_sync(&hevc->timer); - hevc->stat &= ~STAT_TIMER_ARM; - } - - if (hevc->stat & STAT_VF_HOOK) { - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vh265_vf_prov); - hevc->stat &= ~STAT_VF_HOOK; - } - - hevc_local_uninit(hevc); - - if (use_cma) { -#ifdef USE_UNINIT_SEMA - int ret; -#endif - hevc->uninit_list = 1; - up(&hevc->h265_sema); -#ifdef USE_UNINIT_SEMA - ret = down_interruptible( - &hevc->h265_uninit_done_sema); -#else - while (hevc->uninit_list) /* wait uninit complete */ - msleep(20); -#endif - - } - uninit_mmu_buffers(hevc); - amhevc_disable(); - - return 0; -} - -#ifdef MULTI_INSTANCE_SUPPORT -static void reset_process_time(struct hevc_state_s *hevc) -{ - if (hevc->start_process_time) { - unsigned process_time = - 1000 * (jiffies - hevc->start_process_time) / HZ; - hevc->start_process_time = 0; - if (process_time > max_process_time[hevc->index]) - max_process_time[hevc->index] = process_time; - } -} - -static void start_process_time(struct hevc_state_s *hevc) -{ - hevc->start_process_time = jiffies; - hevc->decode_timeout_count = 2; - hevc->last_lcu_idx = 0; -} - -static void timeout_process(struct hevc_state_s *hevc) -{ - hevc->timeout_num++; - amhevc_stop(); - hevc_print(hevc, - 0, "%s decoder timeout\n", __func__); - - hevc->dec_result = DEC_RESULT_DONE; - reset_process_time(hevc); - schedule_work(&hevc->work); -} - -static unsigned char is_new_pic_available(struct hevc_state_s *hevc) -{ - struct PIC_s *new_pic = NULL; - struct PIC_s *pic; - /* recycle un-used pic */ - int i; - /*return 1 if pic_list is not initialized yet*/ - if (hevc->pic_list_init_flag != 3) - return 1; - - for (i = 0; i < MAX_REF_PIC_NUM; i++) { - pic = hevc->m_PIC[i]; - if (pic == NULL || pic->index == -1) - continue; - if ((pic->used_by_display) - && ((READ_VCBUS_REG(AFBC_BODY_BADDR) << 4) != - pic->mc_y_adr)) - pic->used_by_display = 0; - if (pic->output_mark == 0 && pic->referenced == 0 - && pic->output_ready == 0 - && pic->used_by_display == 0) { - if (new_pic) { - if (pic->POC < new_pic->POC) - new_pic = pic; - } else - new_pic = pic; - } - } - return (new_pic != NULL) ? 1 : 0; -} - -static int vmh265_stop(struct hevc_state_s *hevc) -{ - hevc->init_flag = 0; - - if (hevc->stat & STAT_TIMER_ARM) { - del_timer_sync(&hevc->timer); - hevc->stat &= ~STAT_TIMER_ARM; - } - - if (hevc->stat & STAT_VF_HOOK) { - vf_notify_receiver(hevc->provider_name, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vh265_vf_prov); - hevc->stat &= ~STAT_VF_HOOK; - } - - hevc_local_uninit(hevc); - - if (use_cma) { -#ifdef USE_UNINIT_SEMA - int ret; -#endif - hevc->uninit_list = 1; - reset_process_time(hevc); - schedule_work(&hevc->work); -#ifdef USE_UNINIT_SEMA - ret = down_interruptible( - &hevc->h265_uninit_done_sema); -#else - while (hevc->uninit_list) /* wait uninit complete */ - msleep(20); -#endif - } - cancel_work_sync(&hevc->work); - uninit_mmu_buffers(hevc); - return 0; -} - -static unsigned int start_decode_buf_level; /* = 0x80000;*/ - -static unsigned char get_data_check_sum - (struct hevc_state_s *hevc, int size) -{ - int jj; - int sum = 0; - u8 *data = ((u8 *)hevc->chunk->block->start_virt) + - hevc->chunk->offset; - for (jj = 0; jj < size; jj++) - sum += data[jj]; - return sum; -} - -static void vh265_work(struct work_struct *work) -{ - struct hevc_state_s *hevc = container_of(work, - struct hevc_state_s, work); - struct vdec_s *vdec = hw_to_vdec(hevc); - /* finished decoding one frame or error, - * notify vdec core to switch context - */ - if ((hevc->init_flag != 0) && (hevc->pic_list_init_flag == 1)) { - /*USE_BUF_BLOCK*/ - init_buf_list(hevc); - /**/ - init_pic_list(hevc); - init_pic_list_hw(hevc); - init_buf_spec(hevc); - hevc->pic_list_init_flag = 2; - hevc_print(hevc, 0, - "set pic_list_init_flag to 2\n"); - - start_process_time(hevc); - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, 0x1); - return; - } - - if (hevc->uninit_list) { - /*USE_BUF_BLOCK*/ - uninit_pic_list(hevc); - hevc_print(hevc, 0, "uninit list\n"); - hevc->uninit_list = 0; -#ifdef USE_UNINIT_SEMA - up(&hevc->h265_uninit_done_sema); -#endif - return; - } - - if ((hevc->dec_result == DEC_RESULT_GET_DATA) || - (hevc->dec_result == DEC_RESULT_GET_DATA_RETRY)) { - if (hevc->dec_result == DEC_RESULT_GET_DATA) { - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_GET_DATA %x %x %x mpc %x\n", - __func__, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR), - READ_VREG(HEVC_MPC_E)); - vdec_vframe_dirty(vdec, hevc->chunk); - vdec_clean_input(vdec); - } - - /*if (is_new_pic_available(hevc)) {*/ - if (run_ready(vdec)) { - int r; - r = vdec_prepare_input(vdec, &hevc->chunk); - if (r < 0) { - hevc->dec_result = DEC_RESULT_GET_DATA_RETRY; - - hevc_print(hevc, - PRINT_FLAG_VDEC_DETAIL, - "amvdec_vh265: Insufficient data\n"); - - schedule_work(&hevc->work); - return; - } - hevc->dec_result = DEC_RESULT_NONE; - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s: chunk size 0x%x sum 0x%x mpc %x\n", - __func__, r, - (get_dbg_flag(hevc) & PRINT_FLAG_VDEC_STATUS) ? - get_data_check_sum(hevc, r) : 0, - READ_VREG(HEVC_MPC_E)); - if ((get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) && - input_frame_based(vdec)) { - int jj; - u8 *data = - ((u8 *)hevc->chunk->block->start_virt) + - hevc->chunk->offset; - for (jj = 0; jj < r; jj++) { - if ((jj & 0xf) == 0) - hevc_print(hevc, - PRINT_FRAMEBASE_DATA, - "%06x:", jj); - hevc_print_cont(hevc, - PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - hevc_print_cont(hevc, - PRINT_FRAMEBASE_DATA, - "\n"); - } - } - - WRITE_VREG(HEVC_DECODE_SIZE, r); - - vdec_enable_input(vdec); - - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s: mpc %x\n", - __func__, READ_VREG(HEVC_MPC_E)); - - start_process_time(hevc); - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - } else{ - hevc->dec_result = DEC_RESULT_GET_DATA_RETRY; - - /*hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, - "amvdec_vh265: Insufficient data\n"); - */ - - schedule_work(&hevc->work); - } - return; - } else if (hevc->dec_result == DEC_RESULT_DONE) { - /* if (!hevc->ctx_valid) - hevc->ctx_valid = 1; */ - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s dec_result %d %x %x %x\n", - __func__, - hevc->dec_result, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); -#ifdef CONFIG_AM_VDEC_DV -#if 1 - if (vdec->slave) { - if (dv_debug & 0x1) - vdec_set_flag(vdec->slave, 0); - else - vdec_set_flag(vdec->slave, - VDEC_FLAG_INPUT_KEEP_CONTEXT); - } -#else - if (vdec->slave) { - if (no_interleaved_el_slice) - vdec_set_flag(vdec->slave, - VDEC_FLAG_INPUT_KEEP_CONTEXT); - /* this will move real HW pointer for input */ - else - vdec_set_flag(vdec->slave, 0); - /* this will not move real HW pointer - and SL layer decoding - will start from same stream position - as current BL decoder */ - } -#endif -#endif - vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk); - } else { - hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, - "%s dec_result %d %x %x %x\n", - __func__, - hevc->dec_result, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); - } - - if (hevc->stat & STAT_TIMER_ARM) { - del_timer_sync(&hevc->timer); - hevc->stat &= ~STAT_TIMER_ARM; - } - /* mark itself has all HW resource released and input released */ - vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_CONNECTED); - -#ifdef CONFIG_AM_VDEC_DV - if (hevc->switch_dvlayer_flag) { - if (vdec->slave) - vdec_set_next_sched(vdec, vdec->slave); - else if (vdec->master) - vdec_set_next_sched(vdec, vdec->master); - } else if (vdec->slave || vdec->master) - vdec_set_next_sched(vdec, vdec); -#endif - - if (hevc->vdec_cb) - hevc->vdec_cb(hw_to_vdec(hevc), hevc->vdec_cb_arg); -} - -static int vh265_hw_ctx_restore(struct hevc_state_s *hevc) -{ - /* new to do ... */ - vh265_prot_init(hevc); - return 0; -} - -static bool run_ready(struct vdec_s *vdec) -{ - struct hevc_state_s *hevc = - (struct hevc_state_s *)vdec->private; - - /*hevc_print(hevc, - PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); - */ - if ((!vdec_frame_based(vdec)) && (start_decode_buf_level > 0)) { - u32 rp, wp; - u32 level; - - rp = READ_MPEG_REG(PARSER_VIDEO_RP); - wp = READ_MPEG_REG(PARSER_VIDEO_WP); - - if (wp < rp) - level = vdec->input.size + wp - rp; - else - level = wp - rp; - - if (level < start_decode_buf_level) { - hevc_print(hevc, 0, - "level %d not run_ready\n", level); - return false; - } - } else if (vdec_frame_based(vdec)) { - if (!vdec_input_next_input_chunk(&vdec->input)) - return false; - } - - return is_new_pic_available(hevc); -} - -static void reset_dec_hw(struct vdec_s *vdec) -{ - if (input_frame_based(vdec)) - WRITE_VREG(HEVC_STREAM_CONTROL, 0); - - /* - * 2: assist - * 3: parser - * 4: parser_state - * 8: dblk - * 11:mcpu - * 12:ccpu - * 13:ddr - * 14:iqit - * 15:ipp - * 17:qdct - * 18:mpred - * 19:sao - * 24:hevc_afifo - */ - 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)); - WRITE_VREG(DOS_SW_RESET3, 0); -} - -static void run(struct vdec_s *vdec, - void (*callback)(struct vdec_s *, void *), void *arg) -{ - struct hevc_state_s *hevc = - (struct hevc_state_s *)vdec->private; - int r; - - hevc->vdec_cb_arg = arg; - hevc->vdec_cb = callback; - - reset_dec_hw(vdec); - - r = vdec_prepare_input(vdec, &hevc->chunk); - if (r < 0) { - hevc->dec_result = DEC_RESULT_AGAIN; - - hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, - "ammvdec_vh265: Insufficient data\n"); - - schedule_work(&hevc->work); - return; - } - - hevc->dec_result = DEC_RESULT_NONE; - - hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, - "%s: size 0x%x sum 0x%x (%x %x %x)\n", - __func__, r, - (vdec_frame_based(vdec) && - (get_dbg_flag(hevc) & PRINT_FLAG_VDEC_STATUS)) ? - get_data_check_sum(hevc, r) : 0, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); - if ((get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) && - input_frame_based(vdec)) { - int jj; - u8 *data = ((u8 *)hevc->chunk->block->start_virt) + - hevc->chunk->offset; - for (jj = 0; jj < r; jj++) { - if ((jj & 0xf) == 0) - hevc_print(hevc, PRINT_FRAMEBASE_DATA, - "%06x:", jj); - hevc_print_cont(hevc, PRINT_FRAMEBASE_DATA, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - hevc_print_cont(hevc, PRINT_FRAMEBASE_DATA, - "\n"); - } - } - if (hevc->init_flag == 0) { - if (amhevc_vdec_loadmc_ex(vdec, "vh265_mc") < 0) { - amhevc_disable(); - hevc_print(hevc, 0, - "%s: Error amvdec_loadmc fail\n", __func__); - return; - } - } - if (vh265_hw_ctx_restore(hevc) < 0) { - schedule_work(&hevc->work); - return; - } - - vdec_enable_input(vdec); - - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - - if (vdec_frame_based(vdec)) - WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); - - WRITE_VREG(HEVC_DECODE_SIZE, r); - /*WRITE_VREG(HEVC_DECODE_COUNT, hevc->decode_idx);*/ - hevc->init_flag = 1; - - if (hevc->pic_list_init_flag == 3) - init_pic_list_hw(hevc); - - start_process_time(hevc); - add_timer(&hevc->timer); - hevc->stat |= STAT_TIMER_ARM; - amhevc_start(); - -} - -static void reset(struct vdec_s *vdec) -{ - - struct hevc_state_s *hevc = - (struct hevc_state_s *)vdec->private; - - hevc_print(hevc, - PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); - -} - -static irqreturn_t vh265_irq_cb(struct vdec_s *vdec) -{ - struct hevc_state_s *hevc = - (struct hevc_state_s *)vdec->private; - - return vh265_isr(0, hevc); -} - -static irqreturn_t vh265_threaded_irq_cb(struct vdec_s *vdec) -{ - struct hevc_state_s *hevc = - (struct hevc_state_s *)vdec->private; - - return vh265_isr_thread_fn(0, hevc); -} -#endif - -static int amvdec_h265_probe(struct platform_device *pdev) -{ -#ifdef MULTI_INSTANCE_SUPPORT - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; -#else - struct vdec_dev_reg_s *pdata = - (struct vdec_dev_reg_s *)pdev->dev.platform_data; -#endif - struct hevc_state_s *hevc = &gHevc; - - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, "%s\r\n", __func__); - mutex_lock(&vh265_mutex); - - if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) && - (parser_sei_enable & 0x100) == 0) - parser_sei_enable = 1; - hevc->m_ins_flag = 0; - hevc->init_flag = 0; - hevc->uninit_list = 0; - hevc->fatal_error = 0; - hevc->show_frame_num = 0; - if (pdata == NULL) { - hevc_print(hevc, 0, - "\namvdec_h265 memory resource undefined.\n"); - mutex_unlock(&vh265_mutex); - return -EFAULT; - } -#ifndef CONFIG_MULTI_DEC - if (get_cpu_type() < MESON_CPU_MAJOR_ID_GXL - || double_write_mode == 0x10) - mmu_enable = 0; - else - mmu_enable = 1; -#endif - if (init_mmu_buffers(hevc)) { - hevc_print(hevc, 0, - "\n 265 mmu init failed!\n"); - mutex_unlock(&vh265_mutex); - return -EFAULT; - } - hevc->buf_start = pdata->mem_start; - hevc->buf_size = pdata->mem_end - pdata->mem_start + 1; - /* - hevc->mc_buf_spec.buf_end = pdata->mem_end + 1; - for (i = 0; i < WORK_BUF_SPEC_NUM; i++) - amvh265_workbuff_spec[i].start_adr = pdata->mem_start; - */ - - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "===H.265 decoder mem resource 0x%lx -- 0x%lx\n", - pdata->mem_start, pdata->mem_end + 1); - } - - if (pdata->sys_info) - hevc->vh265_amstream_dec_info = *pdata->sys_info; - else { - hevc->vh265_amstream_dec_info.width = 0; - hevc->vh265_amstream_dec_info.height = 0; - hevc->vh265_amstream_dec_info.rate = 30; - } -#ifndef MULTI_INSTANCE_SUPPORT - if (pdata->flag & DEC_FLAG_HEVC_WORKAROUND) { - workaround_enable |= 3; - hevc_print(hevc, 0, - "amvdec_h265 HEVC_WORKAROUND flag set.\n"); - } else - workaround_enable &= ~3; -#endif - hevc->cma_dev = pdata->cma_dev; -#ifdef MULTI_INSTANCE_SUPPORT - pdata->private = hevc; - pdata->dec_status = vh265_dec_status; - if (vh265_init(pdata) < 0) { -#else - if (vh265_init(hevc) < 0) { -#endif - hevc_print(hevc, 0, - "\namvdec_h265 init failed.\n"); - hevc_local_uninit(hevc); - uninit_mmu_buffers(hevc); - mutex_unlock(&vh265_mutex); - return -ENODEV; - } - /*set the max clk for smooth playing...*/ - hevc_source_changed(VFORMAT_HEVC, - 3840, 2160, 60); - mutex_unlock(&vh265_mutex); - - return 0; -} - -static int amvdec_h265_remove(struct platform_device *pdev) -{ - struct hevc_state_s *hevc = &gHevc; - - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, "%s\r\n", __func__); - - mutex_lock(&vh265_mutex); - - vh265_stop(hevc); - - hevc_source_changed(VFORMAT_HEVC, 0, 0, 0); - - -#ifdef DEBUG_PTS - hevc_print(hevc, 0, - "pts missed %ld, pts hit %ld, duration %d\n", - hevc->pts_missed, hevc->pts_hit, hevc->frame_dur); -#endif - - mutex_unlock(&vh265_mutex); - - return 0; -} -/****************************************/ - -static struct platform_driver amvdec_h265_driver = { - .probe = amvdec_h265_probe, - .remove = amvdec_h265_remove, -#ifdef CONFIG_PM - .suspend = amhevc_suspend, - .resume = amhevc_resume, -#endif - .driver = { - .name = DRIVER_NAME, - } -}; - -#ifdef MULTI_INSTANCE_SUPPORT -static int ammvdec_h265_probe(struct platform_device *pdev) -{ - - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct hevc_state_s *hevc = NULL; -#ifdef CONFIG_MULTI_DEC - int config_val; -#endif - 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); - if (hevc == NULL) { - pr_info("\nammvdec_h265 device data allocation failed\n"); - return -ENOMEM; - } - pdata->private = hevc; - pdata->dec_status = vh265_dec_status; - /* pdata->set_trickmode = set_trickmode; */ - pdata->run_ready = run_ready; - pdata->run = run; - pdata->reset = reset; - pdata->irq_handler = vh265_irq_cb; - pdata->threaded_irq_handler = vh265_threaded_irq_cb; - - pdata->id = pdev->id; - hevc->index = pdev->id; - - if (pdata->use_vfm_path) - snprintf(pdata->vf_provider_name, - VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); -#ifdef CONFIG_AM_VDEC_DV - else if (vdec_dual(pdata)) { - 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; - } -#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, - &vh265_vf_provider, pdata); - - hevc->provider_name = pdata->vf_provider_name; - platform_set_drvdata(pdev, pdata); - - hevc->platform_dev = pdev; - if (init_mmu_buffers(hevc) < 0) { - hevc_print(hevc, 0, - "\n 265 mmu init failed!\n"); - mutex_unlock(&vh265_mutex); - devm_kfree(&pdev->dev, (void *)hevc); - return -EFAULT; - } -#if 0 - hevc->buf_start = pdata->mem_start; - hevc->buf_size = pdata->mem_end - pdata->mem_start + 1; -#else - - if (decoder_bmmu_box_alloc_idx_wait( - hevc->bmmu_box, - BMMU_WORKSPACE_ID, - work_buf_size, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR) < 0) { - hevc_print(hevc, 0, - "workbuf alloc failed, request buf size 0x%lx\n", - work_buf_size); - uninit_mmu_buffers(hevc); - devm_kfree(&pdev->dev, (void *)hevc); - return -ENOMEM; - } - hevc->buf_start = decoder_bmmu_box_get_phy_addr( - hevc->bmmu_box, - BMMU_WORKSPACE_ID); - hevc->buf_size = work_buf_size; -#endif - if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) && - (parser_sei_enable & 0x100) == 0) - parser_sei_enable = 1; - hevc->m_ins_flag = 1; - hevc->init_flag = 0; - hevc->uninit_list = 0; - hevc->fatal_error = 0; - hevc->show_frame_num = 0; - if (pdata == NULL) { - hevc_print(hevc, 0, - "\namvdec_h265 memory resource undefined.\n"); - uninit_mmu_buffers(hevc); - devm_kfree(&pdev->dev, (void *)hevc); - return -EFAULT; - } - /* - hevc->mc_buf_spec.buf_end = pdata->mem_end + 1; - for (i = 0; i < WORK_BUF_SPEC_NUM; i++) - amvh265_workbuff_spec[i].start_adr = pdata->mem_start; - */ - if (get_dbg_flag(hevc)) { - hevc_print(hevc, 0, - "===H.265 decoder mem resource 0x%lx -- 0x%lx\n", - hevc->buf_start, hevc->buf_start + hevc->buf_size); - } - - if (((get_dbg_flag(hevc) & IGNORE_PARAM_FROM_CONFIG) == 0) && - pdata->config && pdata->config_len) { -#ifdef CONFIG_MULTI_DEC - /*use ptr config for doubel_write_mode, etc*/ - hevc_print(hevc, 0, "pdata->config=%s\n", pdata->config); - if (get_config_int(pdata->config, "hevc_buf_width", - &config_val) == 0) - hevc->buf_alloc_width = config_val; - else - hevc->buf_alloc_width = buf_alloc_width; - - if (get_config_int(pdata->config, "hevc_buf_height", - &config_val) == 0) - hevc->buf_alloc_height = config_val; - else - hevc->buf_alloc_height = buf_alloc_height; - - if (get_config_int(pdata->config, "hevc_buf_margin", - &config_val) == 0) - hevc->dynamic_buf_num_margin = config_val; - else - hevc->dynamic_buf_num_margin = dynamic_buf_num_margin; - - if (get_config_int(pdata->config, "hevc_double_write_mode", - &config_val) == 0) - hevc->double_write_mode = config_val; - else - hevc->double_write_mode = double_write_mode; -#endif - } else { - hevc->vh265_amstream_dec_info.width = 0; - hevc->vh265_amstream_dec_info.height = 0; - hevc->vh265_amstream_dec_info.rate = 30; - hevc->buf_alloc_width = buf_alloc_width; - hevc->buf_alloc_height = buf_alloc_height; - hevc->dynamic_buf_num_margin = dynamic_buf_num_margin; - hevc->double_write_mode = double_write_mode; - } - hevc_print(hevc, 0, - "buf_alloc_width=%d\n", - hevc->buf_alloc_width); - hevc_print(hevc, 0, - "buf_alloc_height=%d\n", - hevc->buf_alloc_height); - hevc_print(hevc, 0, - "dynamic_buf_num_margin=%d\n", - hevc->dynamic_buf_num_margin); - hevc_print(hevc, 0, - "double_write_mode=%d\n", - hevc->double_write_mode); - - hevc->cma_dev = pdata->cma_dev; - - if (vh265_init(pdata) < 0) { - hevc_print(hevc, 0, - "\namvdec_h265 init failed.\n"); - hevc_local_uninit(hevc); - uninit_mmu_buffers(hevc); - devm_kfree(&pdev->dev, (void *)hevc); - return -ENODEV; - } - - /*set the max clk for smooth playing...*/ - hevc_source_changed(VFORMAT_HEVC, - 3840, 2160, 60); - - return 0; -} - -static int ammvdec_h265_remove(struct platform_device *pdev) -{ - struct hevc_state_s *hevc = - (struct hevc_state_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - - if (get_dbg_flag(hevc)) - hevc_print(hevc, 0, "%s\r\n", __func__); - - vmh265_stop(hevc); - - /* vdec_source_changed(VFORMAT_H264, 0, 0, 0); */ - - vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED); - - return 0; -} - -static struct platform_driver ammvdec_h265_driver = { - .probe = ammvdec_h265_probe, - .remove = ammvdec_h265_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif - .driver = { - .name = MULTI_DRIVER_NAME, - } -}; -#endif - -static struct codec_profile_t amvdec_h265_profile = { - .name = "hevc", - .profile = "" -}; - -static int __init amvdec_h265_driver_init_module(void) -{ - pr_debug("amvdec_h265 module init\n"); - error_handle_policy = 0; - -#ifdef ERROR_HANDLE_DEBUG - dbg_nal_skip_flag = 0; - dbg_nal_skip_count = 0; -#endif - decode_stop_pos = 0; - decode_stop_pos_pre = 0; - decode_pic_begin = 0; - slice_parse_begin = 0; - step = 0; - buf_alloc_size = 0; - -#ifdef MULTI_INSTANCE_SUPPORT - if (platform_driver_register(&ammvdec_h265_driver)) - pr_err("failed to register ammvdec_h265 driver\n"); - -#endif - if (platform_driver_register(&amvdec_h265_driver)) { - pr_err("failed to register amvdec_h265 driver\n"); - return -ENODEV; - } -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ - if (!has_hevc_vdec()) { - /* not support hevc */ - amvdec_h265_profile.name = "hevc_unsupport"; - } else if (is_meson_m8m2_cpu()) { - /* m8m2 support 4k */ - amvdec_h265_profile.profile = "4k"; - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - amvdec_h265_profile.profile = - "4k, 9bit, 10bit, dwrite, compressed"; - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_MG9TV) - amvdec_h265_profile.profile = "4k"; -#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); - - return 0; -} - -static void __exit amvdec_h265_driver_remove_module(void) -{ - pr_debug("amvdec_h265 module remove.\n"); - -#ifdef MULTI_INSTANCE_SUPPORT - platform_driver_unregister(&ammvdec_h265_driver); -#endif - platform_driver_unregister(&amvdec_h265_driver); -} - -/****************************************/ -/* -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_h265 stat\n"); -*/ -module_param(use_cma, uint, 0664); -MODULE_PARM_DESC(use_cma, "\n amvdec_h265 use_cma\n"); - -module_param(bit_depth_luma, uint, 0664); -MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_h265 bit_depth_luma\n"); - -module_param(bit_depth_chroma, uint, 0664); -MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_h265 bit_depth_chroma\n"); - -module_param(video_signal_type, uint, 0664); -MODULE_PARM_DESC(video_signal_type, "\n amvdec_h265 video_signal_type\n"); - -#ifdef ERROR_HANDLE_DEBUG -module_param(dbg_nal_skip_flag, uint, 0664); -MODULE_PARM_DESC(dbg_nal_skip_flag, "\n amvdec_h265 dbg_nal_skip_flag\n"); - -module_param(dbg_nal_skip_count, uint, 0664); -MODULE_PARM_DESC(dbg_nal_skip_count, "\n amvdec_h265 dbg_nal_skip_count\n"); -#endif - -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, "\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_h265 step\n"); - -module_param(decode_stop_pos, uint, 0664); -MODULE_PARM_DESC(decode_stop_pos, "\n amvdec_h265 decode_stop_pos\n"); - -module_param(decode_pic_begin, uint, 0664); -MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_h265 decode_pic_begin\n"); - -module_param(slice_parse_begin, uint, 0664); -MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_h265 slice_parse_begin\n"); - -module_param(nal_skip_policy, uint, 0664); -MODULE_PARM_DESC(nal_skip_policy, "\n amvdec_h265 nal_skip_policy\n"); - -module_param(i_only_flag, uint, 0664); -MODULE_PARM_DESC(i_only_flag, "\n amvdec_h265 i_only_flag\n"); - -module_param(error_handle_policy, uint, 0664); -MODULE_PARM_DESC(error_handle_policy, "\n amvdec_h265 error_handle_policy\n"); - -module_param(error_handle_threshold, uint, 0664); -MODULE_PARM_DESC(error_handle_threshold, - "\n amvdec_h265 error_handle_threshold\n"); - -module_param(error_handle_nal_skip_threshold, uint, 0664); -MODULE_PARM_DESC(error_handle_nal_skip_threshold, - "\n amvdec_h265 error_handle_nal_skip_threshold\n"); - -module_param(error_handle_system_threshold, uint, 0664); -MODULE_PARM_DESC(error_handle_system_threshold, - "\n amvdec_h265 error_handle_system_threshold\n"); - -module_param(error_skip_nal_count, uint, 0664); -MODULE_PARM_DESC(error_skip_nal_count, - "\n amvdec_h265 error_skip_nal_count\n"); - -module_param(debug, uint, 0664); -MODULE_PARM_DESC(debug, "\n amvdec_h265 debug\n"); - -module_param(debug_mask, uint, 0664); -MODULE_PARM_DESC(debug_mask, "\n amvdec_h265 debug mask\n"); - -module_param(buffer_mode, uint, 0664); -MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n"); - -module_param(double_write_mode, uint, 0664); -MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\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(dynamic_buf_num_margin, uint, 0664); -MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n"); - -module_param(max_buf_num, uint, 0664); -MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n"); - -module_param(buf_alloc_size, uint, 0664); -MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n"); - -module_param(re_config_pic_flag, uint, 0664); -MODULE_PARM_DESC(re_config_pic_flag, "\n re_config_pic_flag\n"); - -module_param(buffer_mode_dbg, uint, 0664); -MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n"); - -module_param(mem_map_mode, uint, 0664); -MODULE_PARM_DESC(mem_map_mode, "\n mem_map_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(prefix_aux_buf_size, uint, 0664); -MODULE_PARM_DESC(prefix_aux_buf_size, "\n prefix_aux_buf_size\n"); - -module_param(suffix_aux_buf_size, uint, 0664); -MODULE_PARM_DESC(suffix_aux_buf_size, "\n suffix_aux_buf_size\n"); - -module_param(interlace_enable, uint, 0664); -MODULE_PARM_DESC(interlace_enable, "\n interlace_enable\n"); -module_param(pts_unstable, uint, 0664); -MODULE_PARM_DESC(pts_unstable, "\n amvdec_h265 pts_unstable\n"); -module_param(parser_sei_enable, uint, 0664); -MODULE_PARM_DESC(parser_sei_enable, "\n parser_sei_enable\n"); - -#ifdef CONFIG_AM_VDEC_DV -module_param(parser_dolby_vision_enable, uint, 0664); -MODULE_PARM_DESC(parser_dolby_vision_enable, - "\n parser_dolby_vision_enable\n"); -#endif - -#ifdef MULTI_INSTANCE_SUPPORT -module_param(start_decode_buf_level, uint, 0664); -MODULE_PARM_DESC(start_decode_buf_level, - "\n h265 start_decode_buf_level\n"); - -module_param(decode_timeout_val, uint, 0664); -MODULE_PARM_DESC(decode_timeout_val, - "\n h265 decode_timeout_val\n"); - -module_param_array(decode_frame_count, uint, - &max_decode_instance_num, 0664); - -module_param_array(max_process_time, uint, - &max_decode_instance_num, 0664); - -module_param_array(max_get_frame_interval, - uint, &max_decode_instance_num, 0664); - -#endif -#ifdef CONFIG_AM_VDEC_DV -module_param(dv_toggle_prov_name, uint, 0664); -MODULE_PARM_DESC(dv_toggle_prov_name, "\n dv_toggle_prov_name\n"); - -module_param(dv_debug, uint, 0664); -MODULE_PARM_DESC(dv_debug, "\n dv_debug\n"); -#endif - -module_init(amvdec_h265_driver_init_module); -module_exit(amvdec_h265_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC h265 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/h265/vh265.h b/drivers/frame_provider/decoder/h265/vh265.h deleted file mode 100644 index 8b10541..0000000 --- a/drivers/frame_provider/decoder/h265/vh265.h +++ b/dev/null @@ -1,27 +0,0 @@ -/* - * drivers/amlogic/amports/vh265.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 VH265_H -#define VH265_H - -extern u32 get_blackout_policy(void); - -extern s32 vh265_init(void); - -extern s32 vh265_release(void); - -#endif /* VMPEG4_H */ diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg.c deleted file mode 100644 index db27382..0000000 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c +++ b/dev/null @@ -1,912 +0,0 @@ -/* - * drivers/amlogic/amports/vmjpeg.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/kfifo.h> -#include <linux/platform_device.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/media/utils/vdec_reg.h> -#include "../../../stream_input/amports/amports_priv.h" -#include <linux/amlogic/media/registers/register.h> - -#ifdef CONFIG_AM_VDEC_MJPEG_LOG -#define AMLOG -#define LOG_LEVEL_VAR amlog_level_vmjpeg -#define LOG_MASK_VAR amlog_mask_vmjpeg -#define LOG_LEVEL_ERROR 0 -#define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_DESC "0:ERROR, 1:INFO" -#endif -#include <linux/amlogic/media/utils/amlog.h> -MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); - -#include "../utils/amvdec.h" - -#define DRIVER_NAME "amvdec_mjpeg" -#define MODULE_NAME "amvdec_mjpeg" - -/* protocol register usage - AV_SCRATCH_0 - AV_SCRATCH_1 : initial display buffer fifo - AV_SCRATCH_2 - AV_SCRATCH_3 : decoder settings - AV_SCRATCH_4 - AV_SCRATCH_7 : display buffer spec - AV_SCRATCH_8 - AV_SCRATCH_9 : amrisc/host display buffer management - AV_SCRATCH_a : time stamp -*/ - -#define MREG_DECODE_PARAM AV_SCRATCH_2 /* bit 0-3: pico_addr_mode */ -/* bit 15-4: reference height */ -#define MREG_TO_AMRISC AV_SCRATCH_8 -#define MREG_FROM_AMRISC AV_SCRATCH_9 -#define MREG_FRAME_OFFSET AV_SCRATCH_A - -#define PICINFO_BUF_IDX_MASK 0x0007 -#define PICINFO_AVI1 0x0080 -#define PICINFO_INTERLACE 0x0020 -#define PICINFO_INTERLACE_AVI1_BOT 0x0010 -#define PICINFO_INTERLACE_FIRST 0x0010 - -#define VF_POOL_SIZE 16 -#define DECODE_BUFFER_NUM_MAX 4 -#define PUT_INTERVAL (HZ/100) - -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/ -/* #define NV21 */ -#endif -static DEFINE_MUTEX(vmjpeg_mutex); - -static struct dec_sysinfo vmjpeg_amstream_dec_info; - -static struct vframe_s *vmjpeg_vf_peek(void *); -static struct vframe_s *vmjpeg_vf_get(void *); -static void vmjpeg_vf_put(struct vframe_s *, void *); -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_prot_init(void); -static void vmjpeg_local_init(void); - -static const char vmjpeg_dec_id[] = "vmjpeg-dev"; - -#define PROVIDER_NAME "decoder.mjpeg" -static const struct vframe_operations_s vmjpeg_vf_provider = { - .peek = vmjpeg_vf_peek, - .get = vmjpeg_vf_get, - .put = vmjpeg_vf_put, - .event_cb = vmjpeg_event_cb, - .vf_states = vmjpeg_vf_states, -}; - -static struct vframe_provider_s vmjpeg_vf_prov; - -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[DECODE_BUFFER_NUM_MAX]; - -static u32 frame_width, frame_height, frame_dur; -static u32 saved_resolution; -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start; -static u32 buf_size; -static DEFINE_SPINLOCK(lock); - -static inline u32 index2canvas0(u32 index) -{ - const u32 canvas_tab[4] = { -#ifdef NV21 - 0x010100, 0x030302, 0x050504, 0x070706 -#else - 0x020100, 0x050403, 0x080706, 0x0b0a09 -#endif - }; - - return canvas_tab[index]; -} - -static inline u32 index2canvas1(u32 index) -{ - const u32 canvas_tab[4] = { -#ifdef NV21 - 0x0d0d0c, 0x0f0f0e, 0x171716, 0x191918 -#else - 0x0e0d0c, 0x181716, 0x222120, 0x252423 -#endif - }; - - return canvas_tab[index]; -} - -static void set_frame_info(struct vframe_s *vf) -{ - vf->width = frame_width; - vf->height = frame_height; - vf->duration = frame_dur; - vf->ratio_control = 0; - vf->duration_pulldown = 0; - vf->flag = 0; -} - -static irqreturn_t vmjpeg_isr(int irq, void *dev_id) -{ - u32 reg, offset, pts, pts_valid = 0; - struct vframe_s *vf = NULL; - u64 pts_us64; - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - reg = READ_VREG(MREG_FROM_AMRISC); - - if (reg & PICINFO_BUF_IDX_MASK) { - offset = READ_VREG(MREG_FRAME_OFFSET); - - if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, offset, &pts, 0, &pts_us64) == 0) - pts_valid = 1; - - if ((reg & PICINFO_INTERLACE) == 0) { - u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; - - if (index >= DECODE_BUFFER_NUM_MAX) { - pr_err("fatal error, invalid buffer index."); - return IRQ_HANDLED; - } - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info( - "fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - set_frame_info(vf); - vf->signal_type = 0; - vf->index = index; -#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 = - index2canvas0(index); - vf->pts = (pts_valid) ? pts : 0; - vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - vf->orientation = 0; - vf->type_original = vf->type; - vfbuf_use[index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - } else { - u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3; - - if (index >= DECODE_BUFFER_NUM_MAX) { - pr_info("fatal error, invalid buffer index."); - return IRQ_HANDLED; - } - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - set_frame_info(vf); - vf->signal_type = 0; - vf->index = index; -#if 0 - if (reg & PICINFO_AVI1) { - /* AVI1 format */ - if (reg & PICINFO_INTERLACE_AVI1_BOT) { - vf->type = - VIDTYPE_INTERLACE_BOTTOM | - VIDTYPE_INTERLACE_FIRST; - } else - vf->type = VIDTYPE_INTERLACE_TOP; - } else { - if (reg & PICINFO_INTERLACE_FIRST) { - vf->type = - VIDTYPE_INTERLACE_TOP | - VIDTYPE_INTERLACE_FIRST; - } else - vf->type = VIDTYPE_INTERLACE_BOTTOM; - } - - vf->type |= VIDTYPE_VIU_FIELD; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->duration >>= 1; - vf->canvas0Addr = vf->canvas1Addr = - index2canvas0(index); - vf->orientation = 0; - if ((vf->type & VIDTYPE_INTERLACE_FIRST) && - (pts_valid)) - vf->pts = pts; - else - vf->pts = 0; - - vfbuf_use[index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); -#else - /* send whole frame by weaving top & bottom field */ -#ifdef NV21 - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_NV21; -#else - vf->type = VIDTYPE_PROGRESSIVE; -#endif - vf->canvas0Addr = index2canvas0(index); - vf->canvas1Addr = index2canvas1(index); - vf->orientation = 0; - if (pts_valid) { - vf->pts = pts; - vf->pts_us64 = pts_us64; - } else { - vf->pts = 0; - vf->pts_us64 = 0; - } - vf->type_original = vf->type; - vfbuf_use[index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); -#endif - } - - WRITE_VREG(MREG_FROM_AMRISC, 0); - } - - return IRQ_HANDLED; -} - -static struct vframe_s *vmjpeg_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vmjpeg_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; -} - -static void vmjpeg_vf_put(struct vframe_s *vf, void *op_arg) -{ - kfifo_put(&recycle_q, (const struct vframe_s *)vf); -} - -static int vmjpeg_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(&vmjpeg_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vmjpeg_local_init(); - vmjpeg_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vmjpeg_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -static int vmjpeg_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 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; - if (kfifo_get(&recycle_q, &vf)) { - if ((vf->index >= 0) - && (vf->index < DECODE_BUFFER_NUM_MAX) - && (--vfbuf_use[vf->index] == 0)) { - WRITE_VREG(MREG_TO_AMRISC, vf->index + 1); - vf->index = DECODE_BUFFER_NUM_MAX; - } - - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } - } - 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_MJPEG, - frame_width, frame_height, fps); - } - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; - vstatus->height = frame_height; - if (0 != frame_dur) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = 96000; - vstatus->error_count = 0; - vstatus->status = stat; - - return 0; -} - -/****************************************/ -static void vmjpeg_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - - 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; - } - - if (is_vpp_postblend()) { - struct canvas_s cur_canvas; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < 4; i++) { - if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) { -#ifdef NV21 - canvas_config(index2canvas0(i) & 0xff, - buf_start + 4 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 8) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(index2canvas1(i) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_size / 2, canvas_width, - canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 8) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size + decbuf_uv_size / 2, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); -#else - canvas_config(index2canvas0(i) & 0xff, - buf_start + 4 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 8) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 16) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(index2canvas1(i) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_size / 2, canvas_width, - canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 8) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size + decbuf_uv_size / 2, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 16) & 0xff, - buf_start + 4 * decbuf_size + - decbuf_y_size + decbuf_uv_size + - decbuf_uv_size / 2, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); -#endif - } else { -#ifdef NV21 - canvas_config(index2canvas0(i) & 0xff, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 8) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(index2canvas1(i) & 0xff, - buf_start + i * decbuf_size + - decbuf_size / 2, canvas_width, - canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 8) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size / 2, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); -#else - canvas_config(index2canvas0(i) & 0xff, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 8) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas0(i) >> 16) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(index2canvas1(i) & 0xff, - buf_start + i * decbuf_size + - decbuf_size / 2, canvas_width, - canvas_height, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 8) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size / 2, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config((index2canvas1(i) >> 16) & 0xff, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size + - decbuf_uv_size / 2, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); -#endif - } - } -} - -static void init_scaler(void) -{ - /* 4 point triangle */ - const unsigned filt_coef[] = { - 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, - 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, - 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, - 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, - 0x18382808, 0x18382808, 0x17372909, 0x17372909, - 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, - 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, - 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, - 0x10303010 - }; - int i; - - /* pscale enable, PSCALE cbus bmem enable */ - WRITE_VREG(PSCALE_CTRL, 0xc000); - - /* write filter coefs */ - WRITE_VREG(PSCALE_BMEM_ADDR, 0); - for (i = 0; i < 33; i++) { - WRITE_VREG(PSCALE_BMEM_DAT, 0); - WRITE_VREG(PSCALE_BMEM_DAT, filt_coef[i]); - } - - /* Y horizontal initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 37 * 2); - /* [35]: buf repeat pix0, - * [34:29] => buf receive num, - * [28:16] => buf blk x, - * [15:0] => buf phase - */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* C horizontal initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 41 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* Y vertical initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 39 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* C vertical initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 43 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* Y horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 36 * 2 + 1); - /* [19:0] => Y horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - /* C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 40 * 2 + 1); - /* [19:0] => C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - - /* Y vertical phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 38 * 2 + 1); - /* [19:0] => Y vertical phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - /* C vertical phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 42 * 2 + 1); - /* [19:0] => C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - - /* reset pscaler */ -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/ - WRITE_VREG(DOS_SW_RESET0, (1 << 10)); - WRITE_VREG(DOS_SW_RESET0, 0); -#else - WRITE_MPEG_REG(RESET2_REGISTER, RESET_PSCALE); -#endif - READ_MPEG_REG(RESET2_REGISTER); - READ_MPEG_REG(RESET2_REGISTER); - READ_MPEG_REG(RESET2_REGISTER); - - WRITE_VREG(PSCALE_RST, 0x7); - WRITE_VREG(PSCALE_RST, 0x0); -} - -static void vmjpeg_prot_init(void) -{ -#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_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC); -#endif - - vmjpeg_canvas_init(); - - WRITE_VREG(AV_SCRATCH_0, 12); - WRITE_VREG(AV_SCRATCH_1, 0x031a); -#ifdef NV21 - WRITE_VREG(AV_SCRATCH_4, 0x010100); - WRITE_VREG(AV_SCRATCH_5, 0x030302); - WRITE_VREG(AV_SCRATCH_6, 0x050504); - WRITE_VREG(AV_SCRATCH_7, 0x070706); -#else - WRITE_VREG(AV_SCRATCH_4, 0x020100); - WRITE_VREG(AV_SCRATCH_5, 0x050403); - WRITE_VREG(AV_SCRATCH_6, 0x080706); - WRITE_VREG(AV_SCRATCH_7, 0x0b0a09); -#endif - init_scaler(); - - /* clear buffer IN/OUT registers */ - WRITE_VREG(MREG_TO_AMRISC, 0); - WRITE_VREG(MREG_FROM_AMRISC, 0); - - WRITE_VREG(MCPU_INTR_MSK, 0xffff); - WRITE_VREG(MREG_DECODE_PARAM, (frame_height << 4) | 0x8000); - - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - /* set interrupt mapping for vld */ - WRITE_VREG(ASSIST_AMR1_INT8, 8); -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/ -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#else - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif -#endif -} - -static void vmjpeg_local_init(void) -{ - int i; - - frame_width = vmjpeg_amstream_dec_info.width; - frame_height = vmjpeg_amstream_dec_info.height; - frame_dur = vmjpeg_amstream_dec_info.rate; - saved_resolution = 0; - amlog_level(LOG_LEVEL_INFO, "mjpegdec: w(%d), h(%d), dur(%d)\n", - frame_width, frame_height, frame_dur); - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; 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 = DECODE_BUFFER_NUM_MAX; - kfifo_put(&newframe_q, vf); - } -} - -static s32 vmjpeg_init(void) -{ - int ret = -1,size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - amvdec_enable(); - - vmjpeg_local_init(); - - size = get_firmware_data(VIDEO_DEC_MJPEG, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_MJPEG, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vmjpeg_prot_init(); - - ret = vdec_request_irq(VDEC_IRQ_1, vmjpeg_isr, - "vmjpeg-irq", (void *)vmjpeg_dec_id); - - if (ret) { - amvdec_disable(); - - amlog_level(LOG_LEVEL_ERROR, "vmjpeg irq register error.\n"); - return -ENOENT; - } - - stat |= STAT_ISR_REG; - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vmjpeg_vf_prov, PROVIDER_NAME, &vmjpeg_vf_provider, - NULL); - vf_reg_provider(&vmjpeg_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vmjpeg_vf_prov, PROVIDER_NAME, &vmjpeg_vf_provider, - NULL); - vf_reg_provider(&vmjpeg_vf_prov); -#endif - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vmjpeg_amstream_dec_info.rate)); - - 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; - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int amvdec_mjpeg_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - mutex_lock(&vmjpeg_mutex); - - amlog_level(LOG_LEVEL_INFO, "amvdec_mjpeg probe start.\n"); - - if (pdata == NULL) { - amlog_level(LOG_LEVEL_ERROR, - "amvdec_mjpeg memory resource undefined.\n"); - mutex_unlock(&vmjpeg_mutex); - - return -EFAULT; - } - - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - - if (pdata->sys_info) - vmjpeg_amstream_dec_info = *pdata->sys_info; - - pdata->dec_status = vmjpeg_dec_status; - - if (vmjpeg_init() < 0) { - amlog_level(LOG_LEVEL_ERROR, "amvdec_mjpeg init failed.\n"); - mutex_unlock(&vmjpeg_mutex); - - return -ENODEV; - } - - mutex_unlock(&vmjpeg_mutex); - - amlog_level(LOG_LEVEL_INFO, "amvdec_mjpeg probe end.\n"); - - return 0; -} - -static int amvdec_mjpeg_remove(struct platform_device *pdev) -{ - mutex_lock(&vmjpeg_mutex); - - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vmjpeg_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) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vmjpeg_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - amvdec_disable(); - - mutex_unlock(&vmjpeg_mutex); - - amlog_level(LOG_LEVEL_INFO, "amvdec_mjpeg remove.\n"); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_mjpeg_profile = { - .name = "mjpeg", - .profile = "" -}; - -static int __init amvdec_mjpeg_driver_init_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mjpeg module init\n"); - - if (platform_driver_register(&amvdec_mjpeg_driver)) { - amlog_level(LOG_LEVEL_ERROR, - "failed to register amvdec_mjpeg driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_mjpeg_profile); - return 0; -} - -static void __exit amvdec_mjpeg_driver_remove_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mjpeg module remove.\n"); - - platform_driver_unregister(&amvdec_mjpeg_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_mjpeg stat\n"); - -module_init(amvdec_mjpeg_driver_init_module); -module_exit(amvdec_mjpeg_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC MJMPEG Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c deleted file mode 100644 index 850e0b6..0000000 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/dev/null @@ -1,723 +0,0 @@ -/* - * drivers/amlogic/amports/vmjpeg.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/kfifo.h> -#include <linux/platform_device.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/media/utils/vdec_reg.h> -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" - -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#include "../utils/vdec_input.h" -#include "../utils/vdec.h" -#include "../utils/amvdec.h" - -#define MEM_NAME "codec_mmjpeg" - -#define DRIVER_NAME "ammvdec_mjpeg" -#define MODULE_NAME "ammvdec_mjpeg" - -/* protocol register usage - AV_SCRATCH_4 : decode buffer spec - AV_SCRATCH_5 : decode buffer index -*/ - -#define MREG_DECODE_PARAM AV_SCRATCH_2 /* bit 0-3: pico_addr_mode */ -/* bit 15-4: reference height */ -#define MREG_TO_AMRISC AV_SCRATCH_8 -#define MREG_FROM_AMRISC AV_SCRATCH_9 -#define MREG_FRAME_OFFSET AV_SCRATCH_A - -#define PICINFO_BUF_IDX_MASK 0x0007 -#define PICINFO_AVI1 0x0080 -#define PICINFO_INTERLACE 0x0020 -#define PICINFO_INTERLACE_AVI1_BOT 0x0010 -#define PICINFO_INTERLACE_FIRST 0x0010 - -#define VF_POOL_SIZE 16 -#define DECODE_BUFFER_NUM_MAX 4 - -static struct vframe_s *vmjpeg_vf_peek(void *); -static struct vframe_s *vmjpeg_vf_get(void *); -static void vmjpeg_vf_put(struct vframe_s *, void *); -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 const char vmjpeg_dec_id[] = "vmmjpeg-dev"; - -#define PROVIDER_NAME "vdec.mjpeg" -static const struct vframe_operations_s vf_provider_ops = { - .peek = vmjpeg_vf_peek, - .get = vmjpeg_vf_get, - .put = vmjpeg_vf_put, - .event_cb = vmjpeg_event_cb, - .vf_states = vmjpeg_vf_states, -}; - -#define DEC_RESULT_NONE 0 -#define DEC_RESULT_DONE 1 -#define DEC_RESULT_AGAIN 2 - -struct buffer_spec_s { - unsigned int y_addr; - unsigned int u_addr; - unsigned int v_addr; - - int y_canvas_index; - int u_canvas_index; - int v_canvas_index; - - struct canvas_config_s canvas_config[3]; - unsigned long cma_alloc_addr; - int cma_alloc_count; - unsigned int buf_adr; -}; - -#define spec2canvas(x) \ - (((x)->v_canvas_index << 16) | \ - ((x)->u_canvas_index << 8) | \ - ((x)->y_canvas_index << 0)) - -struct vdec_mjpeg_hw_s { - spinlock_t lock; - struct mutex vmjpeg_mutex; - - 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); - - struct vframe_s vfpool[VF_POOL_SIZE]; - struct buffer_spec_s buffer_spec[DECODE_BUFFER_NUM_MAX]; - s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; - - u32 frame_width; - u32 frame_height; - u32 frame_dur; - u32 saved_resolution; - - u32 stat; - u32 dec_result; - unsigned long buf_start; - u32 buf_size; - - struct dec_sysinfo vmjpeg_amstream_dec_info; - - struct vframe_chunk_s *chunk; - struct work_struct work; - void (*vdec_cb)(struct vdec_s *, void *); - void *vdec_cb_arg; -}; - -static void set_frame_info(struct vdec_mjpeg_hw_s *hw, struct vframe_s *vf) -{ - vf->width = hw->frame_width; - vf->height = hw->frame_height; - vf->duration = hw->frame_dur; - vf->ratio_control = 0; - vf->duration_pulldown = 0; - vf->flag = 0; - - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->plane_num = 3; - - vf->canvas0_config[0] = hw->buffer_spec[vf->index].canvas_config[0]; - vf->canvas0_config[1] = hw->buffer_spec[vf->index].canvas_config[1]; - vf->canvas0_config[2] = hw->buffer_spec[vf->index].canvas_config[2]; - - vf->canvas1_config[0] = hw->buffer_spec[vf->index].canvas_config[0]; - vf->canvas1_config[1] = hw->buffer_spec[vf->index].canvas_config[1]; - vf->canvas1_config[2] = hw->buffer_spec[vf->index].canvas_config[2]; -} - -static irqreturn_t vmjpeg_isr(struct vdec_s *vdec) -{ - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)(vdec->private); - u32 reg; - struct vframe_s *vf = NULL; - u32 index; - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - if (!hw) - return IRQ_HANDLED; - - reg = READ_VREG(MREG_FROM_AMRISC); - index = READ_VREG(AV_SCRATCH_5); - - if (index >= DECODE_BUFFER_NUM_MAX) { - pr_err("fatal error, invalid buffer index."); - return IRQ_HANDLED; - } - - if (kfifo_get(&hw->newframe_q, &vf) == 0) { - pr_info( - "fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - vf->index = index; - set_frame_info(hw, vf); - - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - /* vf->pts = (pts_valid) ? pts : 0; */ - /* vf->pts_us64 = (pts_valid) ? pts_us64 : 0; */ - vf->pts = hw->chunk->pts; - vf->pts_us64 = hw->chunk->pts64; - vf->orientation = 0; - hw->vfbuf_use[index]++; - - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - hw->dec_result = DEC_RESULT_DONE; - - schedule_work(&hw->work); - - return IRQ_HANDLED; -} - -static struct vframe_s *vmjpeg_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_s *vdec = op_arg; - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - - if (!hw) - return NULL; - - if (kfifo_peek(&hw->display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vmjpeg_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_s *vdec = op_arg; - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - - if (!hw) - return NULL; - - if (kfifo_get(&hw->display_q, &vf)) - return vf; - - return NULL; -} - -static void vmjpeg_vf_put(struct vframe_s *vf, void *op_arg) -{ - struct vdec_s *vdec = op_arg; - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - - hw->vfbuf_use[vf->index]--; - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); -} - -static int vmjpeg_event_cb(int type, void *data, void *private_data) -{ - return 0; -} - -static int vmjpeg_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - struct vdec_s *vdec = op_arg; - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_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); - states->buf_recycle_num = 0; - - spin_unlock_irqrestore(&hw->lock, flags); - - return 0; -} - -static int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private; - vstatus->width = hw->frame_width; - vstatus->height = hw->frame_height; - if (0 != hw->frame_dur) - vstatus->fps = 96000 / hw->frame_dur; - else - vstatus->fps = 96000; - vstatus->error_count = 0; - vstatus->status = hw->stat; - - return 0; -} - -/****************************************/ -static void vmjpeg_canvas_init(struct vdec_s *vdec) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - struct vdec_mjpeg_hw_s *hw = - (struct vdec_mjpeg_hw_s *)vdec->private; - ulong addr; - - canvas_width = 1920; - canvas_height = 1088; - decbuf_y_size = 0x200000; - decbuf_uv_size = 0x80000; - decbuf_size = 0x300000; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - int canvas; - - canvas = vdec->get_canvas(i, 3); - if (hw->buffer_spec[i].cma_alloc_count == 0) { - hw->buffer_spec[i].cma_alloc_count = - PAGE_ALIGN(decbuf_size) / PAGE_SIZE; - hw->buffer_spec[i].cma_alloc_addr = - codec_mm_alloc_for_dma(MEM_NAME, - hw->buffer_spec[i].cma_alloc_count, - 16, CODEC_MM_FLAGS_FOR_VDECODER); - } - - if (!hw->buffer_spec[i].cma_alloc_addr) { - pr_err("CMA alloc failed, request buf size 0x%lx\n", - hw->buffer_spec[i].cma_alloc_count * PAGE_SIZE); - hw->buffer_spec[i].cma_alloc_count = 0; - break; - } - - 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 += decbuf_y_size; - hw->buffer_spec[i].u_addr = addr; - addr += decbuf_uv_size; - hw->buffer_spec[i].v_addr = addr; - - 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); - - canvas_config(hw->buffer_spec[i].y_canvas_index, - hw->buffer_spec[i].y_addr, - canvas_width, - canvas_height, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - hw->buffer_spec[i].canvas_config[0].phy_addr = - hw->buffer_spec[i].y_addr; - hw->buffer_spec[i].canvas_config[0].width = - canvas_width; - hw->buffer_spec[i].canvas_config[0].height = - canvas_height; - hw->buffer_spec[i].canvas_config[0].block_mode = - CANVAS_BLKMODE_LINEAR; - - canvas_config(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); - hw->buffer_spec[i].canvas_config[1].phy_addr = - hw->buffer_spec[i].u_addr; - hw->buffer_spec[i].canvas_config[1].width = - canvas_width / 2; - hw->buffer_spec[i].canvas_config[1].height = - canvas_height / 2; - hw->buffer_spec[i].canvas_config[1].block_mode = - CANVAS_BLKMODE_LINEAR; - - canvas_config(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); - hw->buffer_spec[i].canvas_config[2].phy_addr = - hw->buffer_spec[i].v_addr; - hw->buffer_spec[i].canvas_config[2].width = - canvas_width / 2; - hw->buffer_spec[i].canvas_config[2].height = - canvas_height / 2; - hw->buffer_spec[i].canvas_config[2].block_mode = - CANVAS_BLKMODE_LINEAR; - } -} - -static void init_scaler(void) -{ - /* 4 point triangle */ - const unsigned filt_coef[] = { - 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, - 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, - 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, - 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, - 0x18382808, 0x18382808, 0x17372909, 0x17372909, - 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, - 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, - 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, - 0x10303010 - }; - int i; - - /* pscale enable, PSCALE cbus bmem enable */ - WRITE_VREG(PSCALE_CTRL, 0xc000); - - /* write filter coefs */ - WRITE_VREG(PSCALE_BMEM_ADDR, 0); - for (i = 0; i < 33; i++) { - WRITE_VREG(PSCALE_BMEM_DAT, 0); - WRITE_VREG(PSCALE_BMEM_DAT, filt_coef[i]); - } - - /* Y horizontal initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 37 * 2); - /* [35]: buf repeat pix0, - * [34:29] => buf receive num, - * [28:16] => buf blk x, - * [15:0] => buf phase - */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* C horizontal initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 41 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* Y vertical initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 39 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* C vertical initial info */ - WRITE_VREG(PSCALE_BMEM_ADDR, 43 * 2); - WRITE_VREG(PSCALE_BMEM_DAT, 0x0008); - WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000); - - /* Y horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 36 * 2 + 1); - /* [19:0] => Y horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - /* C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 40 * 2 + 1); - /* [19:0] => C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - - /* Y vertical phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 38 * 2 + 1); - /* [19:0] => Y vertical phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - /* C vertical phase step */ - WRITE_VREG(PSCALE_BMEM_ADDR, 42 * 2 + 1); - /* [19:0] => C horizontal phase step */ - WRITE_VREG(PSCALE_BMEM_DAT, 0x10000); - - /* reset pscaler */ -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/ - WRITE_VREG(DOS_SW_RESET0, (1 << 10)); - WRITE_VREG(DOS_SW_RESET0, 0); -#else - WRITE_MPEG_REG(RESET2_REGISTER, RESET_PSCALE); -#endif - READ_MPEG_REG(RESET2_REGISTER); - READ_MPEG_REG(RESET2_REGISTER); - READ_MPEG_REG(RESET2_REGISTER); - - WRITE_VREG(PSCALE_RST, 0x7); - WRITE_VREG(PSCALE_RST, 0x0); -} - -static void vmjpeg_hw_ctx_restore(struct vdec_s *vdec, int index) -{ - struct vdec_mjpeg_hw_s *hw = - (struct vdec_mjpeg_hw_s *)vdec->private; - - WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6)); - WRITE_VREG(DOS_SW_RESET0, 0); - - vmjpeg_canvas_init(vdec); - - /* find next decode buffer index */ - WRITE_VREG(AV_SCRATCH_4, spec2canvas(&hw->buffer_spec[index])); - WRITE_VREG(AV_SCRATCH_5, index); - - init_scaler(); - - /* clear buffer IN/OUT registers */ - WRITE_VREG(MREG_TO_AMRISC, 0); - WRITE_VREG(MREG_FROM_AMRISC, 0); - - WRITE_VREG(MCPU_INTR_MSK, 0xffff); - WRITE_VREG(MREG_DECODE_PARAM, (hw->frame_height << 4) | 0x8000); - - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - /* set interrupt mapping for vld */ - WRITE_VREG(ASSIST_AMR1_INT8, 8); -#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/ - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif -} - -static s32 vmjpeg_init(struct vdec_s *vdec) -{ - int i; - struct vdec_mjpeg_hw_s *hw = - (struct vdec_mjpeg_hw_s *)vdec->private; - - hw->frame_width = hw->vmjpeg_amstream_dec_info.width; - hw->frame_height = hw->vmjpeg_amstream_dec_info.height; - hw->frame_dur = hw->vmjpeg_amstream_dec_info.rate; - hw->saved_resolution = 0; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - hw->vfbuf_use[i] = 0; - - 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[i]; - hw->vfpool[i].index = -1; - kfifo_put(&hw->newframe_q, vf); - } - - INIT_WORK(&hw->work, vmjpeg_work); - - return 0; -} - -static bool run_ready(struct vdec_s *vdec) -{ - return true; -} - -static void run(struct vdec_s *vdec, - void (*callback)(struct vdec_s *, void *), void *arg) -{ - struct vdec_mjpeg_hw_s *hw = - (struct vdec_mjpeg_hw_s *)vdec->private; - int i,ret = -1,size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; - - hw->vdec_cb_arg = arg; - hw->vdec_cb = callback; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - if (hw->vfbuf_use[i] == 0) - break; - } - - if (i == DECODE_BUFFER_NUM_MAX) { - hw->dec_result = DEC_RESULT_AGAIN; - schedule_work(&hw->work); - return; - } - - ret = vdec_prepare_input(vdec, &hw->chunk); - if (ret < 0) { - hw->dec_result = DEC_RESULT_AGAIN; - schedule_work(&hw->work); - return; - } - - hw->dec_result = DEC_RESULT_NONE; - - size = get_firmware_data(VIDEO_DEC_MJPEG_MULTI, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return; - } - - if (amvdec_vdec_loadmc_buf_ex(vdec, buf, size) < 0) { - pr_err("%s: Error amvdec_loadmc fail\n", __func__); - vfree(buf); - return; - } - - vfree(buf); - - vmjpeg_hw_ctx_restore(vdec, i); - - vdec_enable_input(vdec); - - amvdec_start(); -} - -static void vmjpeg_work(struct work_struct *work) -{ - struct vdec_mjpeg_hw_s *hw = container_of(work, - struct vdec_mjpeg_hw_s, work); - - if (hw->dec_result == DEC_RESULT_DONE) - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - - /* mark itself has all HW resource released and input released */ - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_CONNECTED); - - if (hw->vdec_cb) - hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg); -} - -static int amvdec_mjpeg_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct vdec_mjpeg_hw_s *hw = NULL; - - if (pdata == NULL) { - pr_info("amvdec_mjpeg memory resource undefined.\n"); - return -EFAULT; - } - - hw = (struct vdec_mjpeg_hw_s *)devm_kzalloc(&pdev->dev, - sizeof(struct vdec_mjpeg_hw_s), GFP_KERNEL); - if (hw == NULL) { - pr_info("\nammvdec_mjpeg device data allocation failed\n"); - return -ENOMEM; - } - - pdata->private = hw; - pdata->dec_status = vmjpeg_dec_status; - - pdata->run = run; - pdata->run_ready = run_ready; - pdata->irq_handler = vmjpeg_isr; - - pdata->id = pdev->id; - - if (pdata->use_vfm_path) - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - else - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - PROVIDER_NAME ".%02x", pdev->id & 0xff); - - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vf_provider_ops, pdata); - - platform_set_drvdata(pdev, pdata); - - hw->platform_dev = pdev; - hw->buf_start = pdata->mem_start; - hw->buf_size = pdata->mem_end - pdata->mem_start + 1; - - if (pdata->sys_info) - hw->vmjpeg_amstream_dec_info = *pdata->sys_info; - - if (vmjpeg_init(pdata) < 0) { - pr_info("amvdec_mjpeg init failed.\n"); - return -ENODEV; - } - - return 0; -} - -static int amvdec_mjpeg_remove(struct platform_device *pdev) -{ - struct vdec_mjpeg_hw_s *hw = - (struct vdec_mjpeg_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - int i; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - if (hw->buffer_spec[i].cma_alloc_addr) { - pr_info("codec_mm release buffer_spec[%d], 0x%lx\n", i, - hw->buffer_spec[i].cma_alloc_addr); - codec_mm_free_for_dma(MEM_NAME, - hw->buffer_spec[i].cma_alloc_addr); - hw->buffer_spec[i].cma_alloc_count = 0; - } - } - - cancel_work_sync(&hw->work); - - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_mjpeg_profile = { - .name = "mmjpeg", - .profile = "" -}; - -static int __init amvdec_mjpeg_driver_init_module(void) -{ - if (platform_driver_register(&amvdec_mjpeg_driver)) { - pr_err("failed to register amvdec_mjpeg driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_mjpeg_profile); - return 0; -} - -static void __exit amvdec_mjpeg_driver_remove_module(void) -{ - platform_driver_unregister(&amvdec_mjpeg_driver); -} - -/****************************************/ - -module_init(amvdec_mjpeg_driver_init_module); -module_exit(amvdec_mjpeg_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC MJMPEG Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c deleted file mode 100644 index 1d15e11..0000000 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/dev/null @@ -1,1110 +0,0 @@ -/* - * drivers/amlogic/amports/vmpeg12.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/kfifo.h> -#include <linux/platform_device.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/module.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/cpu_version.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include <linux/dma-mapping.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "vmpeg12.h" -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" - -#ifdef CONFIG_AM_VDEC_MPEG12_LOG -#define AMLOG -#define LOG_LEVEL_VAR amlog_level_vmpeg -#define LOG_MASK_VAR amlog_mask_vmpeg -#define LOG_LEVEL_ERROR 0 -#define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_DESC "0:ERROR, 1:INFO" -#endif -#include <linux/amlogic/media/utils/amlog.h> -MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); - -#include "../utils/amvdec.h" -#include "../utils/vdec.h" - -#define DRIVER_NAME "amvdec_mpeg12" -#define MODULE_NAME "amvdec_mpeg12" - -/* protocol registers */ -#define MREG_SEQ_INFO AV_SCRATCH_4 -#define MREG_PIC_INFO AV_SCRATCH_5 -#define MREG_PIC_WIDTH AV_SCRATCH_6 -#define MREG_PIC_HEIGHT AV_SCRATCH_7 -#define MREG_BUFFERIN AV_SCRATCH_8 -#define MREG_BUFFEROUT AV_SCRATCH_9 - -#define MREG_CMD AV_SCRATCH_A -#define MREG_CO_MV_START AV_SCRATCH_B -#define MREG_ERROR_COUNT AV_SCRATCH_C -#define MREG_FRAME_OFFSET AV_SCRATCH_D -#define MREG_WAIT_BUFFER AV_SCRATCH_E -#define MREG_FATAL_ERROR AV_SCRATCH_F - -#define PICINFO_ERROR 0x80000000 -#define PICINFO_TYPE_MASK 0x00030000 -#define PICINFO_TYPE_I 0x00000000 -#define PICINFO_TYPE_P 0x00010000 -#define PICINFO_TYPE_B 0x00020000 - -#define PICINFO_PROG 0x8000 -#define PICINFO_RPT_FIRST 0x4000 -#define PICINFO_TOP_FIRST 0x2000 -#define PICINFO_FRAME 0x1000 - -#define SEQINFO_EXT_AVAILABLE 0x80000000 -#define SEQINFO_PROG 0x00010000 - -#define VF_POOL_SIZE 32 -#define DECODE_BUFFER_NUM_MAX 8 -#define PUT_INTERVAL (HZ/100) - -#define INCPTR(p) ptr_atomic_wrap_inc(&p) - -#define DEC_CONTROL_FLAG_FORCE_2500_720_576_INTERLACE 0x0002 -#define DEC_CONTROL_FLAG_FORCE_3000_704_480_INTERLACE 0x0004 -#define DEC_CONTROL_FLAG_FORCE_2500_704_576_INTERLACE 0x0008 -#define DEC_CONTROL_FLAG_FORCE_2500_544_576_INTERLACE 0x0010 -#define DEC_CONTROL_FLAG_FORCE_2500_480_576_INTERLACE 0x0020 -#define DEC_CONTROL_INTERNAL_MASK 0x0fff -#define DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE 0x1000 - -#define INTERLACE_SEQ_ALWAYS - -#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define NV21 -#endif -#define CCBUF_SIZE (5*1024) - -enum { - FRAME_REPEAT_TOP, - FRAME_REPEAT_BOT, - FRAME_REPEAT_NONE -}; - -static struct vframe_s *vmpeg_vf_peek(void *); -static struct vframe_s *vmpeg_vf_get(void *); -static void vmpeg_vf_put(struct vframe_s *, void *); -static int vmpeg_vf_states(struct vframe_states *states, void *); -static int vmpeg_event_cb(int type, void *data, void *private_data); - -static void vmpeg12_prot_init(void); -static void vmpeg12_local_init(void); - -static const char vmpeg12_dec_id[] = "vmpeg12-dev"; -#define PROVIDER_NAME "decoder.mpeg12" -static const struct vframe_operations_s vmpeg_vf_provider = { - .peek = vmpeg_vf_peek, - .get = vmpeg_vf_get, - .put = vmpeg_vf_put, - .event_cb = vmpeg_event_cb, - .vf_states = vmpeg_vf_states, -}; - -static struct vframe_provider_s vmpeg_vf_prov; - -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 const u32 frame_rate_tab[16] = { - 96000 / 30, 96000 / 24, 96000 / 24, 96000 / 25, - 96000 / 30, 96000 / 30, 96000 / 50, 96000 / 60, - 96000 / 60, - /* > 8 reserved, use 24 */ - 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24, - 96000 / 24, 96000 / 24, 96000 / 24 -}; - -static struct vframe_s vfpool[VF_POOL_SIZE]; -static struct vframe_s vfpool2[VF_POOL_SIZE]; -static int cur_pool_idx; -static s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; -static u32 dec_control; -static u32 frame_width, frame_height, frame_dur, frame_prog; -static u32 saved_resolution; -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start; -static u32 buf_size, ccbuf_phyAddress; -static void *ccbuf_phyAddress_virt; -static int ccbuf_phyAddress_is_remaped_nocache; - -static DEFINE_SPINLOCK(lock); - -static u32 frame_rpt_state; - -static struct dec_sysinfo vmpeg12_amstream_dec_info; - -/* for error handling */ -static s32 frame_force_skip_flag; -static s32 error_frame_skip_level; -static s32 wait_buffer_counter; -static u32 first_i_frame_ready; - -static inline int pool_index(struct vframe_s *vf) -{ - if ((vf >= &vfpool[0]) && (vf <= &vfpool[VF_POOL_SIZE - 1])) - return 0; - else if ((vf >= &vfpool2[0]) && (vf <= &vfpool2[VF_POOL_SIZE - 1])) - return 1; - else - return -1; -} - -static inline u32 index2canvas(u32 index) -{ - const u32 canvas_tab[8] = { -#ifdef NV21 - 0x010100, 0x030302, 0x050504, 0x070706, - 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e -#else - 0x020100, 0x050403, 0x080706, 0x0b0a09, - 0x0e0d0c, 0x11100f, 0x141312, 0x171615 -#endif - }; - - return canvas_tab[index]; -} - -static void set_frame_info(struct vframe_s *vf) -{ - unsigned ar_bits; - u32 temp; - -#ifdef CONFIG_AM_VDEC_MPEG12_LOG - bool first = (frame_width == 0) && (frame_height == 0); -#endif - temp = READ_VREG(MREG_PIC_WIDTH); - if (temp > 1920) - vf->width = frame_width = 1920; - else - vf->width = frame_width = temp; - - temp = READ_VREG(MREG_PIC_HEIGHT); - if (temp > 1088) - vf->height = frame_height = 1088; - else - vf->height = frame_height = temp; - - vf->flag = 0; - - if (frame_dur > 0) - vf->duration = frame_dur; - else { - vf->duration = frame_dur = - frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf]; - } - - ar_bits = READ_VREG(MREG_SEQ_INFO) & 0xf; - - if (ar_bits == 0x2) - vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT; - - else if (ar_bits == 0x3) - vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT; - - else if (ar_bits == 0x4) - vf->ratio_control = 0x74 << DISP_RATIO_ASPECT_RATIO_BIT; - - else - vf->ratio_control = 0; - - amlog_level_if(first, LOG_LEVEL_INFO, - "mpeg2dec: w(%d), h(%d), dur(%d), dur-ES(%d)\n", - frame_width, frame_height, frame_dur, - frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf]); -} - -static bool error_skip(u32 info, struct vframe_s *vf) -{ - if (error_frame_skip_level) { - /* skip error frame */ - if ((info & PICINFO_ERROR) || (frame_force_skip_flag)) { - if ((info & PICINFO_ERROR) == 0) { - if ((info & PICINFO_TYPE_MASK) == - PICINFO_TYPE_I) - frame_force_skip_flag = 0; - } else { - if (error_frame_skip_level >= 2) - frame_force_skip_flag = 1; - } - if ((info & PICINFO_ERROR) || (frame_force_skip_flag)) - return true; - } - } - - return false; -} - -static irqreturn_t vmpeg12_isr(int irq, void *dev_id) -{ - u32 reg, info, seqinfo, offset, pts, pts_valid = 0; - struct vframe_s *vf; - u64 pts_us64 = 0; - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - reg = READ_VREG(MREG_BUFFEROUT); - - if ((reg >> 16) == 0xfe) { - if (!ccbuf_phyAddress_is_remaped_nocache && - ccbuf_phyAddress && - ccbuf_phyAddress_virt) { - codec_mm_dma_flush( - ccbuf_phyAddress_virt, - CCBUF_SIZE, - DMA_FROM_DEVICE); - } - wakeup_userdata_poll( - reg & 0xffff, - (unsigned long)ccbuf_phyAddress_virt, - CCBUF_SIZE, 0); - WRITE_VREG(MREG_BUFFEROUT, 0); - } else if (reg) { - info = READ_VREG(MREG_PIC_INFO); - offset = READ_VREG(MREG_FRAME_OFFSET); - - if ((first_i_frame_ready == 0) && - ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) && - ((info & PICINFO_ERROR) == 0)) - first_i_frame_ready = 1; - - if ((pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, offset, &pts, 0, &pts_us64) == 0) - && (((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) - || ((info & PICINFO_TYPE_MASK) == - PICINFO_TYPE_P))) - pts_valid = 1; - - /*if (frame_prog == 0) */ - { - frame_prog = info & PICINFO_PROG; - } - - if ((dec_control & - DEC_CONTROL_FLAG_FORCE_2500_720_576_INTERLACE) - && (frame_width == 720 || frame_width == 480) - && (frame_height == 576) - && (frame_dur == 3840)) - frame_prog = 0; - else if ((dec_control & - DEC_CONTROL_FLAG_FORCE_3000_704_480_INTERLACE) - && (frame_width == 704) && (frame_height == 480) - && (frame_dur == 3200)) - frame_prog = 0; - else if ((dec_control & - DEC_CONTROL_FLAG_FORCE_2500_704_576_INTERLACE) - && (frame_width == 704) && (frame_height == 576) - && (frame_dur == 3840)) - frame_prog = 0; - else if ((dec_control & - DEC_CONTROL_FLAG_FORCE_2500_544_576_INTERLACE) - && (frame_width == 544) && (frame_height == 576) - && (frame_dur == 3840)) - frame_prog = 0; - else if ((dec_control & - DEC_CONTROL_FLAG_FORCE_2500_480_576_INTERLACE) - && (frame_width == 480) && (frame_height == 576) - && (frame_dur == 3840)) - frame_prog = 0; - else if (dec_control & DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE) - frame_prog = 0; - if (frame_prog & PICINFO_PROG) { - u32 index = ((reg & 0xf) - 1) & 7; - - seqinfo = READ_VREG(MREG_SEQ_INFO); - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - set_frame_info(vf); - vf->signal_type = 0; - vf->index = index; -#ifdef NV21 - vf->type = - VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; -#else - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; -#endif - if ((seqinfo & SEQINFO_EXT_AVAILABLE) - && (seqinfo & SEQINFO_PROG)) { - if (info & PICINFO_RPT_FIRST) { - if (info & PICINFO_TOP_FIRST) { - vf->duration = - vf->duration * 3; - /* repeat three times */ - } else { - vf->duration = - vf->duration * 2; - /* repeat two times */ - } - } - vf->duration_pulldown = 0; - /* no pull down */ - - } else { - vf->duration_pulldown = - (info & PICINFO_RPT_FIRST) ? - vf->duration >> 1 : 0; - } - - vf->duration += vf->duration_pulldown; - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(index); - vf->orientation = 0; - vf->pts = (pts_valid) ? pts : 0; - vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - vf->type_original = vf->type; - - vfbuf_use[index] = 1; - - if ((error_skip(info, vf)) || - ((first_i_frame_ready == 0) - && ((PICINFO_TYPE_MASK & info) != - PICINFO_TYPE_I))) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - } else { - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - - } else { - u32 index = ((reg & 0xf) - 1) & 7; - int first_field_type = (info & PICINFO_TOP_FIRST) ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM; - -#ifdef INTERLACE_SEQ_ALWAYS - /* once an interlaced sequence exist, - always force interlaced type */ - /* to make DI easy. */ - dec_control |= DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE; -#endif - - if (info & PICINFO_FRAME) { - frame_rpt_state = - (info & PICINFO_TOP_FIRST) ? - FRAME_REPEAT_TOP : FRAME_REPEAT_BOT; - } else { - if (frame_rpt_state == FRAME_REPEAT_TOP) { - first_field_type = - VIDTYPE_INTERLACE_TOP; - } else if (frame_rpt_state == - FRAME_REPEAT_BOT) { - first_field_type = - VIDTYPE_INTERLACE_BOTTOM; - } - frame_rpt_state = FRAME_REPEAT_NONE; - } - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - vfbuf_use[index] = 2; - - set_frame_info(vf); - vf->signal_type = 0; - vf->index = index; - vf->type = - (first_field_type == VIDTYPE_INTERLACE_TOP) ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->duration >>= 1; - vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? - vf->duration >> 1 : 0; - vf->duration += vf->duration_pulldown; - vf->orientation = 0; - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(index); - vf->pts = (pts_valid) ? pts : 0; - vf->pts_us64 = (pts_valid) ? pts_us64 : 0; - vf->type_original = vf->type; - - if ((error_skip(info, vf)) || - ((first_i_frame_ready == 0) - && ((PICINFO_TYPE_MASK & info) != - PICINFO_TYPE_I))) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - } else { - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - set_frame_info(vf); - vf->signal_type = 0; - vf->index = index; - vf->type = (first_field_type == - VIDTYPE_INTERLACE_TOP) ? - VIDTYPE_INTERLACE_BOTTOM : - VIDTYPE_INTERLACE_TOP; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->duration >>= 1; - vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ? - vf->duration >> 1 : 0; - vf->duration += vf->duration_pulldown; - vf->orientation = 0; - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(index); - vf->pts = 0; - vf->pts_us64 = 0; - vf->type_original = vf->type; - - if ((error_skip(info, vf)) || - ((first_i_frame_ready == 0) - && ((PICINFO_TYPE_MASK & info) != - PICINFO_TYPE_I))) { - kfifo_put(&recycle_q, - (const struct vframe_s *)vf); - } else { - kfifo_put(&display_q, - (const struct vframe_s *)vf); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - } - - WRITE_VREG(MREG_BUFFEROUT, 0); - } - - return IRQ_HANDLED; -} - -static struct vframe_s *vmpeg_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vmpeg_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; -} - -static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg) -{ - if (pool_index(vf) == cur_pool_idx) - kfifo_put(&recycle_q, (const struct vframe_s *)vf); -} - -static int vmpeg_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(&vmpeg_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vmpeg12_local_init(); - vmpeg12_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vmpeg_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -static int vmpeg_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - spin_lock_irqsave(&lock, flags); - - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&newframe_q); - states->buf_avail_num = kfifo_len(&display_q); - states->buf_recycle_num = kfifo_len(&recycle_q); - - spin_unlock_irqrestore(&lock, flags); - - return 0; -} - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER -static void vmpeg12_ppmgr_reset(void) -{ - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - - vmpeg12_local_init(); - - pr_info("vmpeg12dec: vf_ppmgr_reset\n"); -} -#endif - -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)) { - 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(MREG_FATAL_ERROR) == 1) - fatal_reset = 1; - - if ((READ_VREG(MREG_WAIT_BUFFER) != 0) && - (kfifo_is_empty(&recycle_q)) && - (kfifo_is_empty(&display_q)) && (state == RECEIVER_INACTIVE)) { - if (++wait_buffer_counter > 4) - fatal_reset = 1; - - } else - wait_buffer_counter = 0; - - if (fatal_reset && (kfifo_is_empty(&display_q))) { - pr_info("$$$$decoder is waiting for buffer or fatal reset.\n"); - - amvdec_stop(); - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vmpeg12_ppmgr_reset(); -#else - vf_light_unreg_provider(&vmpeg_vf_prov); - vmpeg12_local_init(); - vf_reg_provider(&vmpeg_vf_prov); -#endif - vmpeg12_prot_init(); - amvdec_start(); - } - - while (!kfifo_is_empty(&recycle_q) && (READ_VREG(MREG_BUFFERIN) == 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(MREG_BUFFERIN, vf->index + 1); - vf->index = DECODE_BUFFER_NUM_MAX; - } - - if (pool_index(vf) == cur_pool_idx) { - kfifo_put(&newframe_q, - (const struct vframe_s *)vf); - } - } - } - - 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_MPEG12, - frame_width, frame_height, fps); - } - - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vmpeg12_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = frame_width; - vstatus->height = frame_height; - if (frame_dur != 0) - vstatus->fps = 96000 / frame_dur; - else - vstatus->fps = 96000; - vstatus->error_count = READ_VREG(AV_SCRATCH_C); - vstatus->status = stat; - - return 0; -} - -/****************************************/ -static void vmpeg12_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - - 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; - } - - if (is_vpp_postblend()) { - struct canvas_s cur_canvas; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < 8; i++) { - if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) { -#ifdef NV21 - canvas_config(2 * i + 0, - buf_start + 8 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - buf_start + 8 * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(3 * i + 0, - buf_start + 8 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - buf_start + 8 * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - buf_start + 8 * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -#endif - } else { -#ifdef NV21 - canvas_config(2 * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(3 * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -#endif - } - } - - WRITE_VREG(MREG_CO_MV_START, - buf_start + 9 * decbuf_size + CCBUF_SIZE); - if (!ccbuf_phyAddress) { - ccbuf_phyAddress = (u32)(buf_start + 9 * decbuf_size); - ccbuf_phyAddress_virt = codec_mm_phys_to_virt(ccbuf_phyAddress); - if (!ccbuf_phyAddress_virt) { - ccbuf_phyAddress_virt = ioremap_nocache( - ccbuf_phyAddress, - CCBUF_SIZE); - ccbuf_phyAddress_is_remaped_nocache = 1; - } - } - -} - -static void vmpeg12_prot_init(void) -{ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - int save_reg = READ_VREG(POWER_CTL_VLD); - - WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); - WRITE_VREG(DOS_SW_RESET0, 0); - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - - 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); - - WRITE_VREG(MDEC_SW_RESET, (1 << 7)); - WRITE_VREG(MDEC_SW_RESET, 0); - } - - WRITE_VREG(POWER_CTL_VLD, save_reg); - - } else - WRITE_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC); - - vmpeg12_canvas_init(); - -#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); - WRITE_VREG(AV_SCRATCH_4, 0x090908); - WRITE_VREG(AV_SCRATCH_5, 0x0b0b0a); - WRITE_VREG(AV_SCRATCH_6, 0x0d0d0c); - WRITE_VREG(AV_SCRATCH_7, 0x0f0f0e); -#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); - WRITE_VREG(AV_SCRATCH_4, 0x0e0d0c); - WRITE_VREG(AV_SCRATCH_5, 0x11100f); - WRITE_VREG(AV_SCRATCH_6, 0x141312); - WRITE_VREG(AV_SCRATCH_7, 0x171615); -#endif - - /* set to mpeg1 default */ - WRITE_VREG(MPEG1_2_REG, 0); - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - /* for Mpeg1 default value */ - WRITE_VREG(PIC_HEAD_INFO, 0x380); - /* disable mpeg4 */ - WRITE_VREG(M4_CONTROL_REG, 0); - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - /* clear buffer IN/OUT registers */ - WRITE_VREG(MREG_BUFFERIN, 0); - WRITE_VREG(MREG_BUFFEROUT, 0); - /* set reference width and height */ - if ((frame_width != 0) && (frame_height != 0)) - WRITE_VREG(MREG_CMD, (frame_width << 16) | frame_height); - else - WRITE_VREG(MREG_CMD, 0); - /* clear error count */ - WRITE_VREG(MREG_ERROR_COUNT, 0); - WRITE_VREG(MREG_FATAL_ERROR, 0); - /* clear wait buffer status */ - WRITE_VREG(MREG_WAIT_BUFFER, 0); -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif -} - -static void vmpeg12_local_init(void) -{ - int i; - - INIT_KFIFO(display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - - cur_pool_idx ^= 1; - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf; - if (cur_pool_idx == 0) { - vf = &vfpool[i]; - vfpool[i].index = DECODE_BUFFER_NUM_MAX; - } else { - vf = &vfpool2[i]; - vfpool2[i].index = DECODE_BUFFER_NUM_MAX; - } - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - vfbuf_use[i] = 0; - - - frame_width = frame_height = frame_dur = frame_prog = 0; - frame_force_skip_flag = 0; - wait_buffer_counter = 0; - first_i_frame_ready = 0; - saved_resolution = 0; - dec_control &= DEC_CONTROL_INTERNAL_MASK; -} - -static s32 vmpeg12_init(void) -{ - int ret = -1, size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - vmpeg12_local_init(); - - amvdec_enable(); - - size = get_firmware_data(VIDEO_DEC_MPEG12, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_MPEG12, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vmpeg12_prot_init(); - - ret = vdec_request_irq(VDEC_IRQ_1, vmpeg12_isr, - "vmpeg12-irq", (void *)vmpeg12_dec_id); - - if (ret) { - amvdec_disable(); - amlog_level(LOG_LEVEL_ERROR, "vmpeg12 irq register error.\n"); - return -ENOENT; - } - - stat |= STAT_ISR_REG; -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, - NULL); - vf_reg_provider(&vmpeg_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, - NULL); - vf_reg_provider(&vmpeg_vf_prov); -#endif - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vmpeg12_amstream_dec_info.rate)); - - 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; - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int amvdec_mpeg12_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 probe start.\n"); - - if (pdata == NULL) { - amlog_level(LOG_LEVEL_ERROR, - "amvdec_mpeg12 platform data undefined.\n"); - return -EFAULT; - } - - if (pdata->sys_info) - vmpeg12_amstream_dec_info = *pdata->sys_info; - - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - - pdata->dec_status = vmpeg12_dec_status; - - if (vmpeg12_init() < 0) { - amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg12 init failed.\n"); - - return -ENODEV; - } - - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 probe end.\n"); - - return 0; -} - -static int amvdec_mpeg12_remove(struct platform_device *pdev) -{ - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vmpeg12_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) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vmpeg_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - amvdec_disable(); - if (ccbuf_phyAddress_is_remaped_nocache) - iounmap(ccbuf_phyAddress_virt); - - ccbuf_phyAddress_virt = NULL; - ccbuf_phyAddress = 0; - ccbuf_phyAddress_is_remaped_nocache = 0; - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 remove.\n"); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_mpeg12_profile = { - .name = "mpeg12", - .profile = "" -}; - -static int __init amvdec_mpeg12_driver_init_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 module init\n"); - - if (platform_driver_register(&amvdec_mpeg12_driver)) { - amlog_level(LOG_LEVEL_ERROR, - "failed to register amvdec_mpeg12 driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_mpeg12_profile); - return 0; -} - -static void __exit amvdec_mpeg12_driver_remove_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 module remove.\n"); - - platform_driver_unregister(&amvdec_mpeg12_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_mpeg12 stat\n"); -module_param(dec_control, uint, 0664); -MODULE_PARM_DESC(dec_control, "\n amvmpeg12 decoder control\n"); -module_param(error_frame_skip_level, uint, 0664); -MODULE_PARM_DESC(error_frame_skip_level, - "\n amvdec_mpeg12 error_frame_skip_level\n"); - -module_init(amvdec_mpeg12_driver_init_module); -module_exit(amvdec_mpeg12_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC MPEG1/2 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12.h b/drivers/frame_provider/decoder/mpeg12/vmpeg12.h deleted file mode 100644 index 2038c06..0000000 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12.h +++ b/dev/null @@ -1,26 +0,0 @@ -/* - * drivers/amlogic/amports/vmpeg12.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 VMPEG12_H -#define VMPEG12_H - -/* /#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -/* TODO: move to register headers */ -#define VPP_VD1_POSTBLEND (1 << 10) -/* /#endif */ - -#endif /* VMPEG12_H */ diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c deleted file mode 100644 index 1f1541a..0000000 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c +++ b/dev/null @@ -1,1127 +0,0 @@ -/* - * drivers/amlogic/amports/vmpeg4.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/kfifo.h> -#include <linux/platform_device.h> -#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> -#include "../../../stream_input/amports/amports_priv.h" - - -/* #define CONFIG_AM_VDEC_MPEG4_LOG */ -#ifdef CONFIG_AM_VDEC_MPEG4_LOG -#define AMLOG -#define LOG_LEVEL_VAR amlog_level_vmpeg4 -#define LOG_MASK_VAR amlog_mask_vmpeg4 -#define LOG_LEVEL_ERROR 0 -#define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_DESC "0:ERROR, 1:INFO" -#define LOG_MASK_PTS 0x01 -#define LOG_MASK_DESC "0x01:DEBUG_PTS" -#endif - -#include <linux/amlogic/media/utils/amlog.h> - -MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC); - -#include "../utils/amvdec.h" -#include "../utils/vdec.h" - -#define DRIVER_NAME "amvdec_mpeg4" -#define MODULE_NAME "amvdec_mpeg4" - -#define DEBUG_PTS - -/* /#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define NV21 -/* /#endif */ - -#define I_PICTURE 0 -#define P_PICTURE 1 -#define B_PICTURE 2 - -#define ORI_BUFFER_START_ADDR 0x01000000 - -#define INTERLACE_FLAG 0x80 -#define TOP_FIELD_FIRST_FLAG 0x40 - -/* protocol registers */ -#define MP4_PIC_RATIO AV_SCRATCH_5 -#define MP4_RATE AV_SCRATCH_3 -#define MP4_ERR_COUNT AV_SCRATCH_6 -#define MP4_PIC_WH AV_SCRATCH_7 -#define MREG_BUFFERIN AV_SCRATCH_8 -#define MREG_BUFFEROUT AV_SCRATCH_9 -#define MP4_NOT_CODED_CNT AV_SCRATCH_A -#define MP4_VOP_TIME_INC AV_SCRATCH_B -#define MP4_OFFSET_REG AV_SCRATCH_C -#define MP4_SYS_RATE AV_SCRATCH_E -#define MEM_OFFSET_REG AV_SCRATCH_F - -#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 32 -#define DECODE_BUFFER_NUM_MAX 8 -#define PUT_INTERVAL (HZ/100) - -#define RATE_DETECT_COUNT 5 -#define DURATION_UNIT 96000 -#define PTS_UNIT 90000 - -#define DUR2PTS(x) ((x) - ((x) >> 4)) - -static struct vframe_s *vmpeg_vf_peek(void *); -static struct vframe_s *vmpeg_vf_get(void *); -static void vmpeg_vf_put(struct vframe_s *, void *); -static int vmpeg_vf_states(struct vframe_states *states, void *); -static int vmpeg_event_cb(int type, void *data, void *private_data); - -static void vmpeg4_prot_init(void); -static void vmpeg4_local_init(void); - -static const char vmpeg4_dec_id[] = "vmpeg4-dev"; - -#define PROVIDER_NAME "decoder.mpeg4" - -/* -int query_video_status(int type, int *value); -*/ -static const struct vframe_operations_s vmpeg_vf_provider = { - .peek = vmpeg_vf_peek, - .get = vmpeg_vf_get, - .put = vmpeg_vf_put, - .event_cb = vmpeg_event_cb, - .vf_states = vmpeg_vf_states, -}; - -static struct vframe_provider_s vmpeg_vf_prov; - -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[DECODE_BUFFER_NUM_MAX]; -static u32 frame_width, frame_height, frame_dur, frame_prog; -static u32 saved_resolution; -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start; -static u32 buf_size, buf_offset; -static u32 vmpeg4_ratio; -static u64 vmpeg4_ratio64; -static u32 rate_detect; -static u32 vmpeg4_rotation; - -static u32 total_frame; -static u32 last_vop_time_inc, last_duration; -static u32 last_anch_pts, vop_time_inc_since_last_anch, - frame_num_since_last_anch; -static u64 last_anch_pts_us64; - -#ifdef CONFIG_AM_VDEC_MPEG4_LOG -u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; -#endif - -static DEFINE_SPINLOCK(lock); - -static struct dec_sysinfo vmpeg4_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[8] = { -#ifdef NV21 - 0x010100, 0x030302, 0x050504, 0x070706, - 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e -#else - 0x020100, 0x050403, 0x080706, 0x0b0a09, - 0x0e0d0c, 0x11100f, 0x141312, 0x171615 -#endif - }; - - return canvas_tab[index]; -} - -static void set_aspect_ratio(struct vframe_s *vf, unsigned pixel_ratio) -{ - int ar = 0; - unsigned int num = 0; - unsigned int den = 0; - - if (vmpeg4_ratio64 != 0) { - num = vmpeg4_ratio64 >> 32; - den = vmpeg4_ratio64 & 0xffffffff; - } else { - num = vmpeg4_ratio >> 16; - den = vmpeg4_ratio & 0xffff; - - } - if ((num == 0) || (den == 0)) { - num = 1; - den = 1; - } - - if (vmpeg4_ratio == 0) { - vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT); - /* always stretch to 16:9 */ - } else if (pixel_ratio > 0x0f) { - num = (pixel_ratio >> 8) * - vmpeg4_amstream_dec_info.width * num; - ar = div_u64((pixel_ratio & 0xff) * - vmpeg4_amstream_dec_info.height * den * 0x100ULL + - (num >> 1), num); - } else { - switch (aspect_ratio_table[pixel_ratio]) { - case 0: - num = vmpeg4_amstream_dec_info.width * num; - ar = (vmpeg4_amstream_dec_info.height * den * 0x100 + - (num >> 1)) / num; - break; - case 1: - num = vf->width * num; - ar = (vf->height * den * 0x100 + (num >> 1)) / num; - break; - case 2: - num = (vf->width * 12) * num; - ar = (vf->height * den * 0x100 * 11 + - ((num) >> 1)) / num; - break; - case 3: - num = (vf->width * 10) * num; - ar = (vf->height * den * 0x100 * 11 + (num >> 1)) / - num; - break; - case 4: - num = (vf->width * 16) * num; - ar = (vf->height * den * 0x100 * 11 + (num >> 1)) / - num; - break; - case 5: - num = (vf->width * 40) * num; - ar = (vf->height * den * 0x100 * 33 + (num >> 1)) / - num; - break; - default: - num = vf->width * num; - ar = (vf->height * den * 0x100 + (num >> 1)) / num; - break; - } - } - - ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX); - - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); -} - -static irqreturn_t vmpeg4_isr(int irq, void *dev_id) -{ - u32 reg; - struct vframe_s *vf = NULL; - u32 picture_type; - u32 buffer_index; - u32 pts, pts_valid = 0, offset = 0; - u64 pts_us64 = 0; - u32 rate, vop_time_inc, repeat_cnt, duration = 3200; - - reg = READ_VREG(MREG_BUFFEROUT); - - if (reg) { - buffer_index = reg & 0x7; - picture_type = (reg >> 3) & 7; - rate = READ_VREG(MP4_RATE); - repeat_cnt = READ_VREG(MP4_NOT_CODED_CNT); - vop_time_inc = READ_VREG(MP4_VOP_TIME_INC); - - if (buffer_index >= DECODE_BUFFER_NUM_MAX) { - pr_err("fatal error, invalid buffer index."); - return IRQ_HANDLED; - } - - if (vmpeg4_amstream_dec_info.width == 0) { - vmpeg4_amstream_dec_info.width = - READ_VREG(MP4_PIC_WH) >> 16; - } -#if 0 - else { - pr_info("info width = %d, ucode width = %d\n", - vmpeg4_amstream_dec_info.width, - READ_VREG(MP4_PIC_WH) >> 16); - } -#endif - - if (vmpeg4_amstream_dec_info.height == 0) { - vmpeg4_amstream_dec_info.height = - READ_VREG(MP4_PIC_WH) & 0xffff; - } -#if 0 - else { - pr_info("info height = %d, ucode height = %d\n", - vmpeg4_amstream_dec_info.height, - READ_VREG(MP4_PIC_WH) & 0xffff); - } -#endif - if (vmpeg4_amstream_dec_info.rate == 0 - || vmpeg4_amstream_dec_info.rate > 96000) { - /* if ((rate >> 16) != 0) { */ - if ((rate & 0xffff) != 0 && (rate >> 16) != 0) { - vmpeg4_amstream_dec_info.rate = - (rate >> 16) * DURATION_UNIT / - (rate & 0xffff); - duration = vmpeg4_amstream_dec_info.rate; - } else if (rate_detect < RATE_DETECT_COUNT) { - if (vop_time_inc < last_vop_time_inc) { - duration = - vop_time_inc + rate - - last_vop_time_inc; - } else { - duration = - vop_time_inc - last_vop_time_inc; - } - - if (duration == last_duration) { - rate_detect++; - if (rate_detect >= RATE_DETECT_COUNT) { - vmpeg4_amstream_dec_info.rate = - duration * DURATION_UNIT / - rate; - duration = - vmpeg4_amstream_dec_info.rate; - } - } else - rate_detect = 0; - - last_duration = duration; - } - } else { - duration = vmpeg4_amstream_dec_info.rate; -#if 0 - pr_info("info rate = %d, ucode rate = 0x%x:0x%x\n", - vmpeg4_amstream_dec_info.rate, - READ_VREG(MP4_RATE), vop_time_inc); -#endif - } - - if ((I_PICTURE == picture_type) || - (P_PICTURE == picture_type)) { - offset = READ_VREG(MP4_OFFSET_REG); - /*2500-->3000,because some mpeg4 - video may checkout failed; - may have av sync problem.can changed small later. - 263 may need small? - */ - if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, offset, &pts, 3000, - &pts_us64) == 0) { - pts_valid = 1; - last_anch_pts = pts; - last_anch_pts_us64 = pts_us64; -#ifdef CONFIG_AM_VDEC_MPEG4_LOG - pts_hit++; -#endif - } else { -#ifdef CONFIG_AM_VDEC_MPEG4_LOG - pts_missed++; -#endif - } -#ifdef CONFIG_AM_VDEC_MPEG4_LOG - amlog_mask(LOG_MASK_PTS, - "I offset 0x%x, pts_valid %d pts=0x%x\n", - offset, pts_valid, pts); -#endif - } - - if (pts_valid) { - last_anch_pts = pts; - last_anch_pts_us64 = pts_us64; - frame_num_since_last_anch = 0; - vop_time_inc_since_last_anch = 0; - } else { - pts = last_anch_pts; - pts_us64 = last_anch_pts_us64; - - if ((rate != 0) && ((rate >> 16) == 0) - && vmpeg4_amstream_dec_info.rate == 0) { - /* variable PTS rate */ - /*bug on variable pts calc, - do as dixed vop first if we - have rate setting before. - */ - if (vop_time_inc > last_vop_time_inc) { - vop_time_inc_since_last_anch += - vop_time_inc - last_vop_time_inc; - } else { - vop_time_inc_since_last_anch += - vop_time_inc + rate - - last_vop_time_inc; - } - - pts += vop_time_inc_since_last_anch * - PTS_UNIT / rate; - pts_us64 += (vop_time_inc_since_last_anch * - PTS_UNIT / rate) * 100 / 9; - - if (vop_time_inc_since_last_anch > (1 << 14)) { - /* avoid overflow */ - last_anch_pts = pts; - last_anch_pts_us64 = pts_us64; - vop_time_inc_since_last_anch = 0; - } - } else { - /* fixed VOP rate */ - frame_num_since_last_anch++; - pts += DUR2PTS(frame_num_since_last_anch * - vmpeg4_amstream_dec_info.rate); - pts_us64 += DUR2PTS(frame_num_since_last_anch * - vmpeg4_amstream_dec_info.rate) * - 100 / 9; - - if (frame_num_since_last_anch > (1 << 15)) { - /* avoid overflow */ - last_anch_pts = pts; - last_anch_pts_us64 = pts_us64; - frame_num_since_last_anch = 0; - } - } - } - - if (reg & INTERLACE_FLAG) { /* interlace */ - if (kfifo_get(&newframe_q, &vf) == 0) { - printk - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vmpeg4_amstream_dec_info.width; - vf->height = vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = vmpeg4_rotation; - vf->pts = pts; - vf->pts_us64 = pts_us64; - vf->duration = duration >> 1; - vf->duration_pulldown = 0; - vf->type = (reg & TOP_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->type_original = vf->type; - - set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO)); - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - if (kfifo_get(&newframe_q, &vf) == 0) { - printk( - "fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vmpeg4_amstream_dec_info.width; - vf->height = vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = vmpeg4_rotation; - - vf->pts = 0; - vf->pts_us64 = 0; - vf->duration = duration >> 1; - - vf->duration_pulldown = 0; - vf->type = (reg & TOP_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->type_original = vf->type; - - set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO)); - - vfbuf_use[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); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - } else { /* progressive */ - if (kfifo_get(&newframe_q, &vf) == 0) { - printk - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vmpeg4_amstream_dec_info.width; - vf->height = vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = vmpeg4_rotation; - vf->pts = pts; - vf->pts_us64 = pts_us64; - vf->duration = duration; - vf->duration_pulldown = repeat_cnt * duration; -#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->type_original = vf->type; - - set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO)); - - amlog_mask(LOG_MASK_PTS, - "[%s:%d] [prog] dur=0x%x rate=%d picture_type=%d\n", - __func__, __LINE__, vf->duration, - vmpeg4_amstream_dec_info.rate, picture_type); - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - - total_frame += repeat_cnt + 1; - - WRITE_VREG(MREG_BUFFEROUT, 0); - - last_vop_time_inc = vop_time_inc; - } - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - return IRQ_HANDLED; -} - -static struct vframe_s *vmpeg_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vmpeg_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; -} - -static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg) -{ - kfifo_put(&recycle_q, (const struct vframe_s *)vf); -} - -static int vmpeg_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(&vmpeg_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vmpeg4_local_init(); - vmpeg4_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vmpeg_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -static int vmpeg_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 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; - if (kfifo_get(&recycle_q, &vf)) { - if ((vf->index >= 0) - && (vf->index < DECODE_BUFFER_NUM_MAX) - && (--vfbuf_use[vf->index] == 0)) { - WRITE_VREG(MREG_BUFFERIN, ~(1 << vf->index)); - vf->index = DECODE_BUFFER_NUM_MAX; - } - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } - } - 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_MPEG4, - frame_width, frame_height, fps); - } - if (READ_VREG(AV_SCRATCH_L)) { - unsigned long flags; - pr_info("mpeg4 fatal error happened,need reset !!\n"); - amvdec_stop(); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_light_unreg_provider(&vmpeg_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vmpeg4_local_init(); - vmpeg4_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vmpeg_vf_prov); -#endif - amvdec_start(); - } - - - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vmpeg4_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = vmpeg4_amstream_dec_info.width; - vstatus->height = vmpeg4_amstream_dec_info.height; - if (0 != vmpeg4_amstream_dec_info.rate) - vstatus->fps = DURATION_UNIT / vmpeg4_amstream_dec_info.rate; - else - vstatus->fps = DURATION_UNIT; - vstatus->error_count = READ_VREG(MP4_ERR_COUNT); - vstatus->status = stat; - - return 0; -} - -/****************************************/ -static void vmpeg4_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - u32 buff_off = 0; - - if (buf_size <= 0x00400000) { - /* SD only */ - canvas_width = 768; - canvas_height = 576; - decbuf_y_size = 0x80000; - decbuf_uv_size = 0x20000; - decbuf_size = 0x100000; - } else { - int w = vmpeg4_amstream_dec_info.width; - int h = vmpeg4_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 { - 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; - } - } - - if (is_vpp_postblend()) { - struct canvas_s cur_canvas; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < 8; i++) { - u32 one_buf_start = buf_start + buff_off; - if (((one_buf_start + 7) >> 3) == disp_addr) { - /*last disp buffer, to next..*/ - buff_off += decbuf_size; - one_buf_start = buf_start + buff_off; - pr_info("one_buf_start %d,=== %x disp_addr %x", - i, one_buf_start, disp_addr); - } - if (buff_off < 0x02000000 && - buff_off + decbuf_size > 0x01b00000){ - /*0x01b00000 is references buffer. - to next 32M;*/ - buff_off = 32 * SZ_1M;/*next 32M*/ - one_buf_start = buf_start + buff_off; - } - if (buff_off + decbuf_size > buf_size) { - pr_err("ERROR::too small buffer for buf%d %d x%d ,size =%d\n", - i, - canvas_width, - canvas_height, - buf_size); - } - pr_debug("alloced buffer %d at %x,%d\n", - i, one_buf_start, decbuf_size); -#ifdef NV21 - canvas_config(2 * i + 0, - one_buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - one_buf_start + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(3 * i + 0, - one_buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - one_buf_start + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - one_buf_start + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -#endif - buff_off = buff_off + decbuf_size; - } -} - -static void vmpeg4_prot_init(void) -{ -#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_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC); -#endif - - vmpeg4_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); - WRITE_VREG(AV_SCRATCH_G, 0x090908); - WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a); - WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c); - WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e); -#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); - WRITE_VREG(AV_SCRATCH_G, 0x0e0d0c); - WRITE_VREG(AV_SCRATCH_H, 0x11100f); - WRITE_VREG(AV_SCRATCH_I, 0x141312); - WRITE_VREG(AV_SCRATCH_J, 0x171615); -#endif - WRITE_VREG(AV_SCRATCH_L, 0);/*clearfatal error flag*/ - - /* notify ucode the buffer offset */ - WRITE_VREG(AV_SCRATCH_F, buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(MREG_BUFFERIN, 0); - WRITE_VREG(MREG_BUFFEROUT, 0); - - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - - /* clear repeat count */ - WRITE_VREG(MP4_NOT_CODED_CNT, 0); - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#if 1/* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - printk("mpeg4 meson8 prot init\n"); - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); -#endif - - WRITE_VREG(MP4_PIC_WH, (vmpeg4_amstream_dec_info. - width << 16) | vmpeg4_amstream_dec_info.height); - WRITE_VREG(MP4_SYS_RATE, vmpeg4_amstream_dec_info.rate); -} - -static void vmpeg4_local_init(void) -{ - int i; - - vmpeg4_ratio = vmpeg4_amstream_dec_info.ratio; - - vmpeg4_ratio64 = vmpeg4_amstream_dec_info.ratio64; - - vmpeg4_rotation = - (((unsigned long) vmpeg4_amstream_dec_info.param) - >> 16) & 0xffff; - - frame_width = frame_height = frame_dur = frame_prog = 0; - - total_frame = 0; - saved_resolution = 0; - last_anch_pts = 0; - - last_anch_pts_us64 = 0; - - last_vop_time_inc = last_duration = 0; - - vop_time_inc_since_last_anch = 0; - - frame_num_since_last_anch = 0; - -#ifdef CONFIG_AM_VDEC_MPEG4_LOG - pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0; -#endif - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; 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 = DECODE_BUFFER_NUM_MAX; - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } -} - -static s32 vmpeg4_init(void) -{ - int trickmode_fffb = 0; - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - query_video_status(0, &trickmode_fffb); - - amlog_level(LOG_LEVEL_INFO, "vmpeg4_init\n"); - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - amvdec_enable(); - - vmpeg4_local_init(); - - if (vmpeg4_amstream_dec_info.format == VIDEO_DEC_FORMAT_MPEG4_3) { - size = get_firmware_data(VIDEO_DEC_MPEG4_3, buf); - - amlog_level(LOG_LEVEL_INFO, "load VIDEO_DEC_FORMAT_MPEG4_3\n"); - } else if (vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_4) { - size = get_firmware_data(VIDEO_DEC_MPEG4_4, buf); - - amlog_level(LOG_LEVEL_INFO, "load VIDEO_DEC_FORMAT_MPEG4_4\n"); - } else if (vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_5) { - size = get_firmware_data(VIDEO_DEC_MPEG4_5, buf); - - amlog_level(LOG_LEVEL_INFO, "load VIDEO_DEC_FORMAT_MPEG4_5\n"); - } else if (vmpeg4_amstream_dec_info.format == VIDEO_DEC_FORMAT_H263) { - size = get_firmware_data(VIDEO_DEC_H263, buf); - - amlog_level(LOG_LEVEL_INFO, "load VIDEO_DEC_FORMAT_H263\n"); - } else - amlog_level(LOG_LEVEL_ERROR, "not supported MPEG4 format\n"); - - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_MPEG4, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vmpeg4_prot_init(); - - if (vdec_request_irq(VDEC_IRQ_1, vmpeg4_isr, - "vmpeg4-irq", (void *)vmpeg4_dec_id)) { - amvdec_disable(); - - amlog_level(LOG_LEVEL_ERROR, "vmpeg4 irq register error.\n"); - return -ENOENT; - } - - stat |= STAT_ISR_REG; -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, - NULL); - vf_reg_provider(&vmpeg_vf_prov); - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, - NULL); - vf_reg_provider(&vmpeg_vf_prov); -#endif - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vmpeg4_amstream_dec_info.rate)); - - 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; - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int amvdec_mpeg4_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - if (pdata == NULL) { - amlog_level(LOG_LEVEL_ERROR, - "amvdec_mpeg4 memory resource undefined.\n"); - return -EFAULT; - } - - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - buf_offset = buf_start - ORI_BUFFER_START_ADDR; - - if (pdata->sys_info) - vmpeg4_amstream_dec_info = *pdata->sys_info; - - pdata->dec_status = vmpeg4_dec_status; - - if (vmpeg4_init() < 0) { - amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg4 init failed.\n"); - - return -ENODEV; - } - - return 0; -} - -static int amvdec_mpeg4_remove(struct platform_device *pdev) -{ - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vmpeg4_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) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vmpeg_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - amvdec_disable(); - - amlog_mask(LOG_MASK_PTS, - "pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit, - pts_missed, pts_i_hit, pts_i_missed); - amlog_mask(LOG_MASK_PTS, "total frame %d, rate %d\n", total_frame, - vmpeg4_amstream_dec_info.rate); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_mpeg4_profile = { - .name = "mpeg4", - .profile = "" -}; - -static int __init amvdec_mpeg4_driver_init_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg4 module init\n"); - - if (platform_driver_register(&amvdec_mpeg4_driver)) { - amlog_level(LOG_LEVEL_ERROR, - "failed to register amvdec_mpeg4 driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_mpeg4_profile); - return 0; -} - -static void __exit amvdec_mpeg4_driver_remove_module(void) -{ - amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg4 module remove.\n"); - - platform_driver_unregister(&amvdec_mpeg4_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_mpeg4 stat\n"); - -module_init(amvdec_mpeg4_driver_init_module); -module_exit(amvdec_mpeg4_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC MPEG4 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4.h b/drivers/frame_provider/decoder/mpeg4/vmpeg4.h deleted file mode 100644 index 21ff478..0000000 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4.h +++ b/dev/null @@ -1,26 +0,0 @@ -/* - * drivers/amlogic/amports/vmpeg4.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 VMPEG4_H -#define VMPEG4_H - -/* /#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -/* TODO: move to register headers */ -#define VPP_VD1_POSTBLEND (1 << 10) -/* /#endif */ - -#endif /* VMPEG4_H */ diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c deleted file mode 100644 index 5c4b242..0000000 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/dev/null @@ -1,1304 +0,0 @@ -/* - * drivers/amlogic/amports/vmpeg4.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/kfifo.h> -#include <linux/platform_device.h> -#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/codec_mm/codec_mm.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "vmpeg4.h" -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" - -#include "../utils/amvdec.h" -#include "../utils/vdec_input.h" -#include "../utils/vdec.h" - -#define DRIVER_NAME "ammvdec_mpeg4" -#define MODULE_NAME "ammvdec_mpeg4" - -#define MEM_NAME "codec_mpeg4" - -#define DEBUG_PTS - -#define NV21 -#define I_PICTURE 0 -#define P_PICTURE 1 -#define B_PICTURE 2 - -#define ORI_BUFFER_START_ADDR 0x01000000 -#define DEFAULT_MEM_SIZE (32*SZ_1M) - -#define INTERLACE_FLAG 0x80 -#define TOP_FIELD_FIRST_FLAG 0x40 - -/* protocol registers */ -#define MREG_REF0 AV_SCRATCH_1 -#define MREG_REF1 AV_SCRATCH_2 -#define MP4_PIC_RATIO AV_SCRATCH_5 -#define MP4_RATE AV_SCRATCH_3 -#define MP4_ERR_COUNT AV_SCRATCH_6 -#define MP4_PIC_WH AV_SCRATCH_7 -#define MREG_INPUT AV_SCRATCH_8 -#define MREG_BUFFEROUT AV_SCRATCH_9 -#define MP4_NOT_CODED_CNT AV_SCRATCH_A -#define MP4_VOP_TIME_INC AV_SCRATCH_B -#define MP4_OFFSET_REG AV_SCRATCH_C -#define MP4_SYS_RATE AV_SCRATCH_E -#define MEM_OFFSET_REG AV_SCRATCH_F - -#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 DECODE_BUFFER_NUM_MAX 4 -#define PUT_INTERVAL (HZ/100) - -#define CTX_LMEM_SWAP_OFFSET 0 -#define CTX_QUANT_MATRIX_OFFSET 0x800 -/* dcac buffer must align at 4k boundary */ -#define CTX_DCAC_BUF_OFFSET 0x1000 -#define CTX_DECBUF_OFFSET (0x0c0000 + 0x1000) - -#define RATE_DETECT_COUNT 5 -#define DURATION_UNIT 96000 -#define PTS_UNIT 90000 - -#define DUR2PTS(x) ((x) - ((x) >> 4)) - -#define DEC_RESULT_NONE 0 -#define DEC_RESULT_DONE 1 -#define DEC_RESULT_AGAIN 2 -#define DEC_RESULT_ERROR 3 - -static struct vframe_s *vmpeg_vf_peek(void *); -static struct vframe_s *vmpeg_vf_get(void *); -static void vmpeg_vf_put(struct vframe_s *, void *); -static int vmpeg_vf_states(struct vframe_states *states, void *); -static int vmpeg_event_cb(int type, void *data, void *private_data); - -struct vdec_mpeg4_hw_s { - spinlock_t lock; - struct platform_device *platform_dev; - struct device *cma_dev; - - DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); - DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); - struct vframe_s vfpool[VF_POOL_SIZE]; - - s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; - u32 frame_width; - u32 frame_height; - u32 frame_dur; - u32 frame_prog; - - u32 ctx_valid; - u32 reg_vcop_ctrl_reg; - u32 reg_pic_head_info; - u32 reg_mpeg1_2_reg; - u32 reg_slice_qp; - u32 reg_mp4_pic_wh; - u32 reg_mp4_rate; - u32 reg_mb_info; - u32 reg_dc_ac_ctrl; - u32 reg_iqidct_control; - u32 reg_resync_marker_length; - u32 reg_rv_ai_mb_count; - - struct vframe_chunk_s *chunk; - u32 stat; - u32 buf_start; - u32 buf_size; - unsigned long cma_alloc_addr; - int cma_alloc_count; - u32 vmpeg4_ratio; - u64 vmpeg4_ratio64; - u32 rate_detect; - u32 vmpeg4_rotation; - u32 total_frame; - u32 last_vop_time_inc; - u32 last_duration; - u32 last_anch_pts; - u32 vop_time_inc_since_last_anch; - u32 frame_num_since_last_anch; - u64 last_anch_pts_us64; - - u32 pts_hit; - u32 pts_missed; - u32 pts_i_hit; - u32 pts_i_missed; - - u32 buffer_info[DECODE_BUFFER_NUM_MAX]; - u32 pts[DECODE_BUFFER_NUM_MAX]; - u64 pts64[DECODE_BUFFER_NUM_MAX]; - bool pts_valid[DECODE_BUFFER_NUM_MAX]; - u32 canvas_spec[DECODE_BUFFER_NUM_MAX]; -#ifdef NV21 - struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2]; -#else - struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][3]; -#endif - struct dec_sysinfo vmpeg4_amstream_dec_info; - - s32 refs[2]; - int dec_result; - struct work_struct work; - - void (*vdec_cb)(struct vdec_s *, void *); - void *vdec_cb_arg; - -}; -static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); -static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); - -#define PROVIDER_NAME "vdec.mpeg4" - -/* -int query_video_status(int type, int *value); -*/ -static const struct vframe_operations_s vf_provider_ops = { - .peek = vmpeg_vf_peek, - .get = vmpeg_vf_get, - .put = vmpeg_vf_put, - .event_cb = vmpeg_event_cb, - .vf_states = vmpeg_vf_states, -}; - -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 int find_buffer(struct vdec_mpeg4_hw_s *hw) -{ - int i; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - if (hw->vfbuf_use[i] == 0) - return i; - } - - return -1; -} - -static int spec_to_index(struct vdec_mpeg4_hw_s *hw, u32 spec) -{ - int i; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { - if (hw->canvas_spec[i] == spec) - return i; - } - - return -1; -} - -static void set_frame_info(struct vdec_mpeg4_hw_s *hw, struct vframe_s *vf, - int buffer_index) -{ - int ar = 0; - unsigned int num = 0; - unsigned int den = 0; - unsigned pixel_ratio = READ_VREG(MP4_PIC_RATIO); - - if (hw->vmpeg4_ratio64 != 0) { - num = hw->vmpeg4_ratio64>>32; - den = hw->vmpeg4_ratio64 & 0xffffffff; - } else { - num = hw->vmpeg4_ratio>>16; - den = hw->vmpeg4_ratio & 0xffff; - - } - if ((num == 0) || (den == 0)) { - num = 1; - den = 1; - } - - if (hw->vmpeg4_ratio == 0) { - vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT); - /* always stretch to 16:9 */ - } else if (pixel_ratio > 0x0f) { - num = (pixel_ratio >> 8) * - hw->vmpeg4_amstream_dec_info.width * num; - ar = div_u64((pixel_ratio & 0xff) * - hw->vmpeg4_amstream_dec_info.height * den * 0x100ULL + - (num >> 1), num); - } else { - switch (aspect_ratio_table[pixel_ratio]) { - case 0: - num = hw->vmpeg4_amstream_dec_info.width * num; - ar = (hw->vmpeg4_amstream_dec_info.height * den * - 0x100 + (num >> 1)) / num; - break; - case 1: - num = vf->width * num; - ar = (vf->height * den * 0x100 + (num >> 1)) / num; - break; - case 2: - num = (vf->width * 12) * num; - ar = (vf->height * den * 0x100 * 11 + - ((num) >> 1)) / num; - break; - case 3: - num = (vf->width * 10) * num; - ar = (vf->height * den * 0x100 * 11 + (num >> 1)) / - num; - break; - case 4: - num = (vf->width * 16) * num; - ar = (vf->height * den * 0x100 * 11 + (num >> 1)) / - num; - break; - case 5: - num = (vf->width * 40) * num; - ar = (vf->height * den * 0x100 * 33 + (num >> 1)) / - num; - break; - default: - num = vf->width * num; - ar = (vf->height * den * 0x100 + (num >> 1)) / num; - break; - } - } - - ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX); - - vf->signal_type = 0; - vf->type_original = vf->type; - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); - vf->canvas0Addr = vf->canvas1Addr = -1; -#ifdef NV21 - vf->plane_num = 2; -#else - vf->plane_num = 3; -#endif - vf->canvas0_config[0] = hw->canvas_config[buffer_index][0]; - vf->canvas0_config[1] = hw->canvas_config[buffer_index][1]; -#ifndef NV21 - vf->canvas0_config[2] = hw->canvas_config[buffer_index][2]; -#endif - vf->canvas1_config[0] = hw->canvas_config[buffer_index][0]; - vf->canvas1_config[1] = hw->canvas_config[buffer_index][1]; -#ifndef NV21 - vf->canvas1_config[2] = hw->canvas_config[buffer_index][2]; -#endif -} - -static inline void vmpeg4_save_hw_context(struct vdec_mpeg4_hw_s *hw) -{ - hw->reg_mpeg1_2_reg = READ_VREG(MPEG1_2_REG); - hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); - hw->reg_pic_head_info = READ_VREG(PIC_HEAD_INFO); - hw->reg_slice_qp = READ_VREG(SLICE_QP); - hw->reg_mp4_pic_wh = READ_VREG(MP4_PIC_WH); - hw->reg_mp4_rate = READ_VREG(MP4_RATE); - hw->reg_mb_info = READ_VREG(MB_INFO); - hw->reg_dc_ac_ctrl = READ_VREG(DC_AC_CTRL); - hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL); - hw->reg_resync_marker_length = READ_VREG(RESYNC_MARKER_LENGTH); - hw->reg_rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); -} - -static irqreturn_t vmpeg4_isr(struct vdec_s *vdec) -{ - u32 reg; - struct vframe_s *vf = NULL; - u32 picture_type; - int index; - u32 pts, offset = 0; - bool pts_valid = false; - u64 pts_us64 = 0; - u32 time_increment_resolution, fixed_vop_rate, vop_time_inc; - u32 repeat_cnt, duration = 3200; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)(vdec->private); - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - reg = READ_VREG(MREG_BUFFEROUT); - - time_increment_resolution = READ_VREG(MP4_RATE); - fixed_vop_rate = time_increment_resolution >> 16; - time_increment_resolution &= 0xffff; - - if (hw->vmpeg4_amstream_dec_info.rate == 0) { - if ((fixed_vop_rate != 0) && (time_increment_resolution != 0)) { - /* fixed VOP rate */ - hw->vmpeg4_amstream_dec_info.rate = fixed_vop_rate * - DURATION_UNIT / - time_increment_resolution; - } - } - - if (reg == 2) { - /* timeout when decoding next frame */ - - /* for frame based case, insufficient result may happen - * at the begining when only VOL head is available save - * HW context also, such as for the QTable from VCOP register - */ - if (input_frame_based(vdec)) - vmpeg4_save_hw_context(hw); - - hw->dec_result = DEC_RESULT_AGAIN; - - schedule_work(&hw->work); - - return IRQ_HANDLED; - } else { - picture_type = (reg >> 3) & 7; - repeat_cnt = READ_VREG(MP4_NOT_CODED_CNT); - vop_time_inc = READ_VREG(MP4_VOP_TIME_INC); - - index = spec_to_index(hw, READ_VREG(REC_CANVAS_ADDR)); - - if (index < 0) { - pr_err("invalid buffer index."); - hw->dec_result = DEC_RESULT_ERROR; - - schedule_work(&hw->work); - - return IRQ_HANDLED; - } - - hw->dec_result = DEC_RESULT_DONE; - - pr_debug("amvdec_mpeg4: offset = 0x%x\n", - READ_VREG(MP4_OFFSET_REG)); - - if (hw->vmpeg4_amstream_dec_info.width == 0) { - hw->vmpeg4_amstream_dec_info.width = - READ_VREG(MP4_PIC_WH) >> 16; - } -#if 0 - else { - pr_info("info width = %d, ucode width = %d\n", - hw->vmpeg4_amstream_dec_info.width, - READ_VREG(MP4_PIC_WH) >> 16); - } -#endif - - if (hw->vmpeg4_amstream_dec_info.height == 0) { - hw->vmpeg4_amstream_dec_info.height = - READ_VREG(MP4_PIC_WH) & 0xffff; - } -#if 0 - else { - pr_info("info height = %d, ucode height = %d\n", - hw->vmpeg4_amstream_dec_info.height, - READ_VREG(MP4_PIC_WH) & 0xffff); - } -#endif - if (hw->vmpeg4_amstream_dec_info.rate == 0) { - if (vop_time_inc < hw->last_vop_time_inc) { - duration = vop_time_inc + - time_increment_resolution - - hw->last_vop_time_inc; - } else { - duration = vop_time_inc - - hw->last_vop_time_inc; - } - - if (duration == hw->last_duration) { - hw->rate_detect++; - if (hw->rate_detect >= RATE_DETECT_COUNT) { - hw->vmpeg4_amstream_dec_info.rate = - duration * DURATION_UNIT / - time_increment_resolution; - duration = - hw->vmpeg4_amstream_dec_info.rate; - } - } else { - hw->rate_detect = 0; - hw->last_duration = duration; - } - } else { - duration = hw->vmpeg4_amstream_dec_info.rate; -#if 0 - pr_info("info rate = %d, ucode rate = 0x%x:0x%x\n", - hw->vmpeg4_amstream_dec_info.rate, - READ_VREG(MP4_RATE), vop_time_inc); -#endif - } - - if ((I_PICTURE == picture_type) || - (P_PICTURE == picture_type)) { - offset = READ_VREG(MP4_OFFSET_REG); - if (hw->chunk) { - hw->pts_valid[index] = hw->chunk->pts_valid; - hw->pts[index] = hw->chunk->pts; - hw->pts64[index] = hw->chunk->pts64; - } else { - if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, offset, &pts, 3000, - &pts_us64) == 0) { - hw->pts_valid[index] = true; - hw->pts[index] = pts; - hw->pts64[index] = pts_us64; - hw->pts_hit++; - } else { - hw->pts_valid[index] = false; - hw->pts_missed++; - } - } - pr_debug("I/P offset 0x%x, pts_valid %d pts=0x%x\n", - offset, hw->pts_valid[index], - hw->pts[index]); - } else { - hw->pts_valid[index] = false; - hw->pts[index] = 0; - hw->pts64[index] = 0; - } - - hw->buffer_info[index] = reg; - hw->vfbuf_use[index] = 0; - - pr_debug("amvdec_mpeg4: decoded buffer %d, frame_type %s\n", - index, - (picture_type == I_PICTURE) ? "I" : - (picture_type == P_PICTURE) ? "P" : "B"); - - /* Buffer management - * todo: add sequence-end flush - */ - if ((picture_type == I_PICTURE) || - (picture_type == P_PICTURE)) { - hw->vfbuf_use[index]++; - - if (hw->refs[1] == -1) { - hw->refs[1] = index; - index = -1; - } else if (hw->refs[0] == -1) { - hw->refs[0] = hw->refs[1]; - hw->refs[1] = index; - index = hw->refs[0]; - } else { - hw->vfbuf_use[hw->refs[0]]--; - hw->refs[0] = hw->refs[1]; - hw->refs[1] = index; - index = hw->refs[0]; - } - } else { - /* if this is a B frame, then drop (depending on if - * there are two reference frames) or display - * immediately - */ - if (hw->refs[1] == -1) - index = -1; - } - - vmpeg4_save_hw_context(hw); - - if (index < 0) { - schedule_work(&hw->work); - return IRQ_HANDLED; - } - - reg = hw->buffer_info[index]; - pts_valid = hw->pts_valid[index]; - pts = hw->pts[index]; - pts_us64 = hw->pts64[index]; - - pr_debug("queued buffer %d, pts = 0x%x, pts_valid=%d\n", - index, pts, pts_valid); - - if (pts_valid) { - hw->last_anch_pts = pts; - hw->last_anch_pts_us64 = pts_us64; - hw->frame_num_since_last_anch = 0; - hw->vop_time_inc_since_last_anch = 0; - } else { - pts = hw->last_anch_pts; - pts_us64 = hw->last_anch_pts_us64; - - if ((time_increment_resolution != 0) && - (fixed_vop_rate == 0) && - (hw->vmpeg4_amstream_dec_info.rate == 0)) { - /* variable PTS rate */ - /*bug on variable pts calc, - do as dixed vop first if we - have rate setting before. - */ - if (vop_time_inc > hw->last_vop_time_inc) { - duration = vop_time_inc - - hw->last_vop_time_inc; - } else { - duration = vop_time_inc + - time_increment_resolution - - hw->last_vop_time_inc; - } - - hw->vop_time_inc_since_last_anch += duration; - - pts += hw->vop_time_inc_since_last_anch * - PTS_UNIT / time_increment_resolution; - pts_us64 += (hw->vop_time_inc_since_last_anch * - PTS_UNIT / time_increment_resolution) * - 100 / 9; - - if (hw->vop_time_inc_since_last_anch > - (1 << 14)) { - /* avoid overflow */ - hw->last_anch_pts = pts; - hw->last_anch_pts_us64 = pts_us64; - hw->vop_time_inc_since_last_anch = 0; - } - } else { - /* fixed VOP rate */ - hw->frame_num_since_last_anch++; - pts += DUR2PTS(hw->frame_num_since_last_anch * - hw->vmpeg4_amstream_dec_info.rate); - pts_us64 += DUR2PTS( - hw->frame_num_since_last_anch * - hw->vmpeg4_amstream_dec_info.rate) * - 100 / 9; - - if (hw->frame_num_since_last_anch > (1 << 15)) { - /* avoid overflow */ - hw->last_anch_pts = pts; - hw->last_anch_pts_us64 = pts_us64; - hw->frame_num_since_last_anch = 0; - } - } - } - - if (reg & INTERLACE_FLAG) { /* interlace */ - if (kfifo_get(&hw->newframe_q, &vf) == 0) { - pr_err - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - vf->index = index; - vf->width = hw->vmpeg4_amstream_dec_info.width; - vf->height = hw->vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = hw->vmpeg4_rotation; - vf->pts = pts; - vf->pts_us64 = pts_us64; - vf->duration = duration >> 1; - vf->duration_pulldown = 0; - vf->type = (reg & TOP_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_TOP : - VIDTYPE_INTERLACE_BOTTOM; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - set_frame_info(hw, vf, index); - - hw->vfbuf_use[index]++; - - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - if (kfifo_get(&hw->newframe_q, &vf) == 0) { - pr_err("fatal error, no available buffer slot."); - hw->dec_result = DEC_RESULT_ERROR; - schedule_work(&hw->work); - return IRQ_HANDLED; - } - - vf->index = index; - vf->width = hw->vmpeg4_amstream_dec_info.width; - vf->height = hw->vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = hw->vmpeg4_rotation; - - vf->pts = 0; - vf->pts_us64 = 0; - vf->duration = duration >> 1; - - vf->duration_pulldown = 0; - vf->type = (reg & TOP_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - set_frame_info(hw, vf, index); - - hw->vfbuf_use[index]++; - - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - } else { /* progressive */ - if (kfifo_get(&hw->newframe_q, &vf) == 0) { - pr_err("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - - vf->index = index; - vf->width = hw->vmpeg4_amstream_dec_info.width; - vf->height = hw->vmpeg4_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - vf->orientation = hw->vmpeg4_rotation; - vf->pts = pts; - vf->pts_us64 = pts_us64; - vf->duration = duration; - vf->duration_pulldown = repeat_cnt * duration; -#ifdef NV21 - vf->type = - VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | - VIDTYPE_VIU_NV21; -#else - vf->type = - VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; -#endif - set_frame_info(hw, vf, index); - - - hw->vfbuf_use[index]++; - - kfifo_put(&hw->display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(vdec->vf_provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - - hw->total_frame += repeat_cnt + 1; - hw->last_vop_time_inc = vop_time_inc; - - schedule_work(&hw->work); - } - - return IRQ_HANDLED; -} - -static void vmpeg4_work(struct work_struct *work) -{ - struct vdec_mpeg4_hw_s *hw = - container_of(work, struct vdec_mpeg4_hw_s, work); - - /* finished decoding one frame or error, - * notify vdec core to switch context - */ - amvdec_stop(); - - if ((hw->dec_result == DEC_RESULT_DONE) || - ((hw->chunk) && - (input_frame_based(&(hw_to_vdec(hw))->input)))) { - if (!hw->ctx_valid) - hw->ctx_valid = 1; - - vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); - } - - /* mark itself has all HW resource released and input released */ - vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_CONNECTED); - - if (hw->vdec_cb) - hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg); -} - -static struct vframe_s *vmpeg_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_s *vdec = op_arg; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - if (!hw) - return NULL; - - if (kfifo_peek(&hw->display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vmpeg_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct vdec_s *vdec = op_arg; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - if (kfifo_get(&hw->display_q, &vf)) - return vf; - - return NULL; -} - -static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg) -{ - struct vdec_s *vdec = op_arg; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - hw->vfbuf_use[vf->index]--; - - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); -} - -static int vmpeg_event_cb(int type, void *data, void *private_data) -{ - return 0; -} - -static int vmpeg_vf_states(struct vframe_states *states, void *op_arg) -{ - unsigned long flags; - struct vdec_s *vdec = op_arg; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_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); - states->buf_recycle_num = 0; - - spin_unlock_irqrestore(&hw->lock, flags); - - return 0; -} - - -static int dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - vstatus->width = hw->vmpeg4_amstream_dec_info.width; - vstatus->height = hw->vmpeg4_amstream_dec_info.height; - if (0 != hw->vmpeg4_amstream_dec_info.rate) - vstatus->fps = DURATION_UNIT / - hw->vmpeg4_amstream_dec_info.rate; - else - vstatus->fps = DURATION_UNIT; - vstatus->error_count = READ_VREG(MP4_ERR_COUNT); - vstatus->status = hw->stat; - - return 0; -} - -/****************************************/ -static int vmpeg4_canvas_init(struct vdec_mpeg4_hw_s *hw) -{ - int i; - u32 decbuf_size, decbuf_y_size; - struct vdec_s *vdec = hw_to_vdec(hw); - u32 decbuf_start; - - int w = hw->vmpeg4_amstream_dec_info.width; - int h = hw->vmpeg4_amstream_dec_info.height; - - if (w == 0) - w = 1920; - if (h == 0) - h = 1088; - - w = ALIGN(w, 64); - h = ALIGN(h, 64); - decbuf_y_size = ALIGN(w * h, SZ_64K); - decbuf_size = ALIGN(w * h * 3/2, SZ_64K); - - decbuf_start = hw->buf_start + CTX_DECBUF_OFFSET; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { -#ifdef NV21 - unsigned int canvas = vdec->get_canvas(i, 2); -#else - unsigned int canvas = vdec->get_canvas(i, 3); -#endif - - hw->canvas_spec[i] = canvas; - -#ifdef NV21 - hw->canvas_config[i][0].phy_addr = decbuf_start + - i * decbuf_size; - hw->canvas_config[i][0].width = w; - hw->canvas_config[i][0].height = h; - hw->canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32; - - canvas_config_config(canvas_y(canvas), - &hw->canvas_config[i][0]); - - hw->canvas_config[i][1].phy_addr = decbuf_start + - i * decbuf_size + decbuf_y_size; - hw->canvas_config[i][1].width = w; - hw->canvas_config[i][1].height = h / 2; - hw->canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32; - - canvas_config_config(canvas_u(canvas), - &hw->canvas_config[i][1]); -#else - hw->canvas_config[i][0].phy_addr = decbuf_start + - i * decbuf_size; - hw->canvas_config[i][0].width = w; - hw->canvas_config[i][0].height = h; - hw->canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32; - - canvas_config_config(canvas_y(canvas), - &hw->canvas_config[i][0]); - - hw->canvas_config[i][1].phy_addr = decbuf_start + - i * decbuf_size + decbuf_y_size; - hw->canvas_config[i][1].width = w / 2; - hw->canvas_config[i][1].height = h / 2; - hw->canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32; - - canvas_config_config(canvas_u(canvas), - &hw->canvas_config[i][1]); - - hw->canvas_config[i][2].phy_addr = decbuf_start + - i * decbuf_size + decbuf_y_size + - decbuf_uv_size; - hw->canvas_config[i][2].width = w / 2; - hw->canvas_config[i][2].height = h / 2; - hw->canvas_config[i][2].block_mode = CANVAS_BLKMODE_32X32; - - canvas_config_config(canvas_v(canvas), - &hw->canvas_config[i][2]); -#endif - } - - return 0; -} - -static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw) -{ - int index; - - - index = find_buffer(hw); - if (index < 0) - return -1; - - - if (vmpeg4_canvas_init(hw) < 0) - return -1; - - /* prepare REF0 & REF1 - * points to the past two IP buffers - * prepare REC_CANVAS_ADDR and ANC2_CANVAS_ADDR - * points to the output buffer - */ - if (hw->refs[0] == -1) { - WRITE_VREG(MREG_REF0, (hw->refs[1] == -1) ? 0xffffffff : - hw->canvas_spec[hw->refs[1]]); - } else { - 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]]); - - 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]]); - WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]); - WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]); - - pr_debug("vmpeg4_hw_ctx_restore ref0=0x%x, ref1=0x%x, rec=0x%x, ctx_valid=%d\n", - READ_VREG(MREG_REF0), - READ_VREG(MREG_REF1), - READ_VREG(REC_CANVAS_ADDR), - hw->ctx_valid); - - /* notify ucode the buffer start address */ - WRITE_VREG(MEM_OFFSET_REG, hw->buf_start); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(MREG_BUFFEROUT, 0); - - /* clear mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(ASSIST_MBOX1_MASK, 1); - - /* clear repeat count */ - WRITE_VREG(MP4_NOT_CODED_CNT, 0); - -#ifdef NV21 - SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); -#endif - -#if 1/* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); -#endif - - WRITE_VREG(MP4_PIC_WH, (hw->ctx_valid) ? - hw->reg_mp4_pic_wh : - ((hw->vmpeg4_amstream_dec_info.width << 16) | - hw->vmpeg4_amstream_dec_info.height)); - WRITE_VREG(MP4_SYS_RATE, hw->vmpeg4_amstream_dec_info.rate); - - if (hw->ctx_valid) { - WRITE_VREG(DC_AC_CTRL, hw->reg_dc_ac_ctrl); - WRITE_VREG(IQIDCT_CONTROL, hw->reg_iqidct_control); - WRITE_VREG(RESYNC_MARKER_LENGTH, hw->reg_resync_marker_length); - WRITE_VREG(RV_AI_MB_COUNT, hw->reg_rv_ai_mb_count); - } - WRITE_VREG(MPEG1_2_REG, (hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 1); - WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg); - WRITE_VREG(PIC_HEAD_INFO, hw->reg_pic_head_info); - WRITE_VREG(SLICE_QP, hw->reg_slice_qp); - WRITE_VREG(MB_INFO, hw->reg_mb_info); - - if (hw->chunk) { - /* frame based input */ - WRITE_VREG(MREG_INPUT, (hw->chunk->offset & 7) | (1<<7) | - (hw->ctx_valid<<6)); - } else { - /* stream based input */ - WRITE_VREG(MREG_INPUT, (hw->ctx_valid<<6)); - } - - return 0; -} - -static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw) -{ - int i; - - hw->vmpeg4_ratio = hw->vmpeg4_amstream_dec_info.ratio; - - hw->vmpeg4_ratio64 = hw->vmpeg4_amstream_dec_info.ratio64; - - hw->vmpeg4_rotation = - (((unsigned long) hw->vmpeg4_amstream_dec_info.param) - >> 16) & 0xffff; - - hw->frame_width = hw->frame_height = hw->frame_dur = hw->frame_prog = 0; - - hw->total_frame = 0; - - hw->last_anch_pts = 0; - - hw->last_anch_pts_us64 = 0; - - hw->last_vop_time_inc = hw->last_duration = 0; - - hw->vop_time_inc_since_last_anch = 0; - - hw->frame_num_since_last_anch = 0; - - hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0; - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - hw->vfbuf_use[i] = 0; - - 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[i]; - hw->vfpool[i].index = DECODE_BUFFER_NUM_MAX; - kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - } - - INIT_WORK(&hw->work, vmpeg4_work); -} - -static s32 vmpeg4_init(struct vdec_mpeg4_hw_s *hw) -{ - int trickmode_fffb = 0; - - query_video_status(0, &trickmode_fffb); - - pr_info("vmpeg4_init\n"); - - amvdec_enable(); - - vmpeg4_local_init(hw); - - return 0; -} - -static bool run_ready(struct vdec_s *vdec) -{ - int index; - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - index = find_buffer(hw); - - return index >= 0; -} - -static void run(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *), - void *arg) -{ - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - int save_reg = READ_VREG(POWER_CTL_VLD); - int ret = -1,size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; - - /* reset everything except DOS_TOP[1] and APB_CBUS[0] */ - WRITE_VREG(DOS_SW_RESET0, 0xfffffff0); - WRITE_VREG(DOS_SW_RESET0, 0); - WRITE_VREG(POWER_CTL_VLD, save_reg); - - hw->vdec_cb_arg = arg; - hw->vdec_cb = callback; - - ret = vdec_prepare_input(vdec, &hw->chunk); - if (ret < 0) { - pr_debug("amvdec_mpeg4: Input not ready\n"); - hw->dec_result = DEC_RESULT_AGAIN; - schedule_work(&hw->work); - vfree(buf); - return; - } - - vdec_enable_input(vdec); - - if (hw->chunk) - pr_debug("input chunk offset %d, size %d\n", - hw->chunk->offset, hw->chunk->size); - - hw->dec_result = DEC_RESULT_NONE; - - if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_3) { - size = get_firmware_data(VIDEO_DEC_MPEG4_3, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_3\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_4) { - size = get_firmware_data(VIDEO_DEC_MPEG4_4, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_4\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_MPEG4_5) { - size = get_firmware_data(VIDEO_DEC_MPEG4_5, buf); - - pr_info("load VIDEO_DEC_FORMAT_MPEG4_5\n"); - } else if (hw->vmpeg4_amstream_dec_info.format == - VIDEO_DEC_FORMAT_H263) { - size = get_firmware_data(VIDEO_DEC_H263, buf); - - pr_info("load VIDEO_DEC_FORMAT_H263\n"); - } - - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return; - } - - if (amvdec_vdec_loadmc_buf_ex(vdec, buf, size) < 0) { - hw->dec_result = DEC_RESULT_ERROR; - schedule_work(&hw->work); - vfree(buf); - return; - } - - vfree(buf); - - if (vmpeg4_hw_ctx_restore(hw) < 0) { - hw->dec_result = DEC_RESULT_ERROR; - pr_err("amvdec_mpeg4: error HW context restore\n"); - schedule_work(&hw->work); - return; - } - - /* wmb before ISR is handled */ - wmb(); - - amvdec_start(); -} - -static void reset(struct vdec_s *vdec) -{ - struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private; - - pr_info("amvdec_mpeg4: reset.\n"); - - vmpeg4_local_init(hw); - - hw->ctx_valid = false; -} - -static int amvdec_mpeg4_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct vdec_mpeg4_hw_s *hw = NULL; - - pr_info("amvdec_mpeg4[%d] probe start.\n", pdev->id); - - if (pdata == NULL) { - pr_err("ammvdec_mpeg4 memory resource undefined.\n"); - return -EFAULT; - } - - hw = (struct vdec_mpeg4_hw_s *)devm_kzalloc(&pdev->dev, - sizeof(struct vdec_mpeg4_hw_s), GFP_KERNEL); - if (hw == NULL) { - pr_info("\namvdec_mpeg4 decoder driver alloc failed\n"); - return -ENOMEM; - } - - pdata->private = hw; - pdata->dec_status = dec_status; - /* pdata->set_trickmode = set_trickmode; */ - pdata->run_ready = run_ready; - pdata->run = run; - pdata->reset = reset; - pdata->irq_handler = vmpeg4_isr; - - pdata->id = pdev->id; - - if (pdata->use_vfm_path) - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - else - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - PROVIDER_NAME ".%02x", pdev->id & 0xff); - - vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, - &vf_provider_ops, pdata); - - platform_set_drvdata(pdev, pdata); - - hw->platform_dev = pdev; - hw->cma_dev = pdata->cma_dev; - - hw->cma_alloc_count = PAGE_ALIGN(DEFAULT_MEM_SIZE) / PAGE_SIZE; - hw->cma_alloc_addr = codec_mm_alloc_for_dma(MEM_NAME, - hw->cma_alloc_count, - 4, CODEC_MM_FLAGS_FOR_VDECODER); - - if (!hw->cma_alloc_addr) { - pr_err("codec_mm alloc failed, request buf size 0x%lx\n", - hw->cma_alloc_count * PAGE_SIZE); - hw->cma_alloc_count = 0; - return -ENOMEM; - } - hw->buf_start = hw->cma_alloc_addr; - hw->buf_size = DEFAULT_MEM_SIZE; - - if (pdata->sys_info) - hw->vmpeg4_amstream_dec_info = *pdata->sys_info; - - if (vmpeg4_init(hw) < 0) { - pr_err("amvdec_mpeg4 init failed.\n"); - - return -ENODEV; - } - - return 0; -} - -static int amvdec_mpeg4_remove(struct platform_device *pdev) -{ - struct vdec_mpeg4_hw_s *hw = - (struct vdec_mpeg4_hw_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - - - amvdec_disable(); - - if (hw->cma_alloc_addr) { - pr_info("codec_mm release buffer 0x%lx\n", hw->cma_alloc_addr); - codec_mm_free_for_dma(MEM_NAME, hw->cma_alloc_addr); - hw->cma_alloc_count = 0; - } - - pr_info("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_info("total frame %d, rate %d\n", hw->total_frame, - hw->vmpeg4_amstream_dec_info.rate); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_mpeg4_profile = { - .name = "mmpeg4", - .profile = "" -}; - -static int __init amvdec_mmpeg4_driver_init_module(void) -{ - pr_info("amvdec_mmpeg4 module init\n"); - - if (platform_driver_register(&amvdec_mpeg4_driver)) { - pr_err("failed to register amvdec_mpeg4 driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_mpeg4_profile); - return 0; -} - -static void __exit amvdec_mmpeg4_driver_remove_module(void) -{ - pr_info("amvdec_mmpeg4 module remove.\n"); - - platform_driver_unregister(&amvdec_mpeg4_driver); -} - -/****************************************/ - -module_init(amvdec_mmpeg4_driver_init_module); -module_exit(amvdec_mmpeg4_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC MPEG4 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); - diff --git a/drivers/frame_provider/decoder/real/vreal.c b/drivers/frame_provider/decoder/real/vreal.c deleted file mode 100644 index d47fa99..0000000 --- a/drivers/frame_provider/decoder/real/vreal.c +++ b/dev/null @@ -1,1022 +0,0 @@ -/* - * 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/parser/streambuf.h" -#include "../../../stream_input/parser/streambuf_reg.h" -#include "../../../stream_input/parser/rmparser.h" - -#include "vreal.h" -#include <linux/amlogic/media/registers/register.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) - -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 void 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 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 unsigned long buf_start; -static u32 buf_size, 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 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 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 (0 == pictype) { /* 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; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - 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_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 >= 0) && (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); - } - } - - 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); - } - - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -int vreal_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = vreal_amstream_dec_info.width; - vstatus->height = vreal_amstream_dec_info.height; - if (0 != vreal_amstream_dec_info.rate) - vstatus->fps = 96000 / vreal_amstream_dec_info.rate; - else - vstatus->fps = 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; -} - -/****************************************/ -static void vreal_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - u32 buff_off = 0; - 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 - /* canvas_width = 1920; - canvas_height = 1088; - decbuf_y_size = 0x200000; - decbuf_uv_size = 0x80000; - decbuf_size = 0x300000;*/ - } - - if (is_vpp_postblend()) { - struct canvas_s cur_canvas; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < 4; i++) { - u32 one_buf_start = buf_start + buff_off; - if (((one_buf_start + 7) >> 3) == disp_addr) { - /*last disp buffer, to next..*/ - buff_off += decbuf_size; - one_buf_start = buf_start + buff_off; - pr_info("one_buf_start %d,=== %x disp_addr %x", - i, one_buf_start, disp_addr); - } - if (buff_off < 0x01000000 && - buff_off + decbuf_size > 0x0f00000){ - /*0x01b00000 is references buffer. - to next 16M;*/ - buff_off = 16 * SZ_1M;/*next 16M*/ - one_buf_start = buf_start + buff_off; - } - if (buff_off + decbuf_size > buf_size) { - pr_err("ERROR::too small buffer for buf%d %d x%d ,size =%d\n", - i, - canvas_width, - canvas_height, - buf_size); - } - pr_info("alloced buffer %d at %x,%d\n", - i, one_buf_start, decbuf_size); - #ifdef NV21 - canvas_config(2 * i + 0, - one_buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - one_buf_start + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - #else - canvas_config(3 * i + 0, - one_buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - one_buf_start + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - one_buf_start + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - #endif - buff_off = buff_off + decbuf_size; - } -} - -static void vreal_prot_init(void) -{ -#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_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC); -#endif - - 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_MPEG_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 -} - -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); - } - - 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); - - return; -} - -s32 vreal_init(struct vdec_s *vdec) -{ - int ret = -1,size = -1; - 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(); - - pr_info("rm parser init failed\n"); - return ret; - } - - if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_8) { - load_block_data((void *)pic_sz_tbl, 12); - - /* TODO: need to load the table into lmem */ - WRITE_VREG(LMEM_DMA_ADR, (unsigned)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); - - 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); - - pr_info("load VIDEO_DEC_FORMAT_REAL_9\n"); - } else - pr_info("unsurpported real format\n"); - - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_REAL, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vreal_prot_init(); - - if (vdec_request_irq(VDEC_IRQ_1, vreal_isr, - "vreal-irq", (void *)vreal_dec_id)) { - 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 - - 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; -} - -/*TODO encoder*/ -/* extern void AbortEncodeWithVdec2(int abort); */ - -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; - } - - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - buf_offset = buf_start - RM_DEF_BUFFER_ADDR; - - if (pdata->sys_info) - vreal_amstream_dec_info = *pdata->sys_info; - /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)&&(HAS_HDEC)) */ - /* if(IS_MESON_M8_CPU){ */ - if (has_hdec()) { - /* disable vdec2 dblk when miracast. */ - int count = 0; - if (get_vdec2_usage() != USAGE_NONE) - /*TODO encoder */ - /* AbortEncodeWithVdec2(1); */ - while ((get_vdec2_usage() != USAGE_NONE) - && (count < 10)) { - msleep(50); - count++; - } - - if (get_vdec2_usage() != USAGE_NONE) { - pr_info("\namvdec_real_probe --- stop vdec2 fail.\n"); - return -EBUSY; - } - } - /* } */ - /* #endif */ - - pdata->dec_status = vreal_dec_status; - - if (vreal_init(pdata) < 0) { - pr_info("amvdec_real init failed.\n"); - /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)&&(HAS_HDEC) */ - /* if(IS_MESON_M8_CPU) */ - if (has_hdec()) { - /*TODO encoder */ - /* AbortEncodeWithVdec2(0); */ - } - /* #endif */ - return -ENODEV; - } - - return 0; -} - -static int amvdec_real_remove(struct platform_device *pdev) -{ - 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) { - 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 (MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8)&&(HAS_HDEC) */ - /* if(IS_MESON_M8_CPU) */ - if (has_hdec()) { - /*TODO encoder */ - /* AbortEncodeWithVdec2(0); */ - } - /* #endif */ - pr_info("frame duration %d, frames %d\n", frame_dur, frame_count); - return 0; -} - -/****************************************/ - -static struct platform_driver amvdec_real_driver = { - .probe = amvdec_real_probe, - .remove = amvdec_real_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif - .driver = { - .name = DRIVER_NAME, - } -}; - -static struct codec_profile_t amvdec_real_profile = { - .name = "real", - .profile = "rmvb,1080p+" -}; - -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); - 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_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_real stat\n"); - -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/real/vreal.h b/drivers/frame_provider/decoder/real/vreal.h deleted file mode 100644 index 8c0d51a..0000000 --- a/drivers/frame_provider/decoder/real/vreal.h +++ b/dev/null @@ -1,26 +0,0 @@ -/* - * drivers/amlogic/amports/vreal.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 VREAL_H -#define VREAL_H - -#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 deleted file mode 100644 index b7e6184..0000000 --- a/drivers/frame_provider/decoder/utils/Makefile +++ b/dev/null @@ -1,4 +0,0 @@ -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 diff --git a/drivers/frame_provider/decoder/utils/amvdec.c b/drivers/frame_provider/decoder/utils/amvdec.c deleted file mode 100644 index a5e1462..0000000 --- a/drivers/frame_provider/decoder/utils/amvdec.c +++ b/dev/null @@ -1,998 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/amvdec.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/types.h> -#include <linux/errno.h> -#include <linux/platform_device.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/vmalloc.h> -#include "vdec.h" - -#ifdef CONFIG_PM -#include <linux/pm.h> -#endif - -#ifdef CONFIG_WAKELOCK -#include <linux/wakelock.h> -#endif -#include "../../../stream_input/amports/amports_priv.h" - -/* #include <mach/am_regs.h> */ -/* #include <mach/power_gate.h> */ -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "amvdec.h" -#include <linux/amlogic/media/utils/amports_config.h> -#include "../../../common/firmware/firmware.h" - -#define MC_SIZE (4096 * 16) - -#ifdef CONFIG_WAKELOCK -static struct wake_lock amvdec_lock; -struct timer_list amvdevtimer; -#define WAKE_CHECK_INTERVAL (100*HZ/100) -#endif -#define AMVDEC_USE_STATIC_MEMORY -static void *mc_addr; -static dma_addr_t mc_addr_map; - -#ifdef CONFIG_WAKELOCK -static int video_running; -static int video_stated_changed = 1; -#endif - -static void amvdec_pg_enable(bool enable) -{ - ulong timeout; - - if (enable) { - AMVDEC_CLK_GATE_ON(MDEC_CLK_PIC_DC); - AMVDEC_CLK_GATE_ON(MDEC_CLK_DBLK); - AMVDEC_CLK_GATE_ON(MC_CLK); - AMVDEC_CLK_GATE_ON(IQIDCT_CLK); - /* AMVDEC_CLK_GATE_ON(VLD_CLK); */ - AMVDEC_CLK_GATE_ON(AMRISC); - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) - WRITE_VREG(GCLK_EN, 0x3ff); - /* #endif */ - CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); - } else { - - AMVDEC_CLK_GATE_OFF(AMRISC); - timeout = jiffies + HZ / 10; - - while (READ_VREG(MDEC_PIC_DC_STATUS) != 0) { - if (time_after(jiffies, timeout)) { - WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 1, 0, 1); - WRITE_VREG_BITS(MDEC_PIC_DC_CTRL, 0, 0, 1); - READ_VREG(MDEC_PIC_DC_STATUS); - READ_VREG(MDEC_PIC_DC_STATUS); - READ_VREG(MDEC_PIC_DC_STATUS); - break; - } - } - - AMVDEC_CLK_GATE_OFF(MDEC_CLK_PIC_DC); - timeout = jiffies + HZ / 10; - - while (READ_VREG(DBLK_STATUS) & 1) { - if (time_after(jiffies, timeout)) { - WRITE_VREG(DBLK_CTRL, 3); - WRITE_VREG(DBLK_CTRL, 0); - READ_VREG(DBLK_STATUS); - READ_VREG(DBLK_STATUS); - READ_VREG(DBLK_STATUS); - break; - } - } - AMVDEC_CLK_GATE_OFF(MDEC_CLK_DBLK); - timeout = jiffies + HZ / 10; - - while (READ_VREG(MC_STATUS0) & 1) { - if (time_after(jiffies, timeout)) { - SET_VREG_MASK(MC_CTRL1, 0x9); - CLEAR_VREG_MASK(MC_CTRL1, 0x9); - READ_VREG(MC_STATUS0); - READ_VREG(MC_STATUS0); - READ_VREG(MC_STATUS0); - break; - } - } - AMVDEC_CLK_GATE_OFF(MC_CLK); - timeout = jiffies + HZ / 10; - while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - AMVDEC_CLK_GATE_OFF(IQIDCT_CLK); - /* AMVDEC_CLK_GATE_OFF(VLD_CLK); */ - } -} - -static void amvdec2_pg_enable(bool enable) -{ - if (has_vdec2()) { - ulong timeout; - - if (!vdec_on(VDEC_2)) - return; - if (enable) { - /* WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); */ - } else { - timeout = jiffies + HZ / 10; - - while (READ_VREG(VDEC2_MDEC_PIC_DC_STATUS) != 0) { - if (time_after(jiffies, timeout)) { - WRITE_VREG_BITS(VDEC2_MDEC_PIC_DC_CTRL, - 1, 0, 1); - WRITE_VREG_BITS(VDEC2_MDEC_PIC_DC_CTRL, - 0, 0, 1); - READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); - READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); - READ_VREG(VDEC2_MDEC_PIC_DC_STATUS); - break; - } - } - - timeout = jiffies + HZ / 10; - - while (READ_VREG(VDEC2_DBLK_STATUS) & 1) { - if (time_after(jiffies, timeout)) { - WRITE_VREG(VDEC2_DBLK_CTRL, 3); - WRITE_VREG(VDEC2_DBLK_CTRL, 0); - READ_VREG(VDEC2_DBLK_STATUS); - READ_VREG(VDEC2_DBLK_STATUS); - READ_VREG(VDEC2_DBLK_STATUS); - break; - } - } - - timeout = jiffies + HZ / 10; - - while (READ_VREG(VDEC2_DCAC_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - } - } -} - -static void amhevc_pg_enable(bool enable) -{ - if (has_hevc_vdec()) { - ulong timeout; - - if (!vdec_on(VDEC_HEVC)) - return; - if (enable) { - /* WRITE_VREG(VDEC2_GCLK_EN, 0x3ff); */ - } else { - timeout = jiffies + HZ / 10; - - while (READ_VREG(HEVC_MDEC_PIC_DC_STATUS) != 0) { - if (time_after(jiffies, timeout)) { - WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, - 1, 0, 1); - WRITE_VREG_BITS(HEVC_MDEC_PIC_DC_CTRL, - 0, 0, 1); - READ_VREG(HEVC_MDEC_PIC_DC_STATUS); - READ_VREG(HEVC_MDEC_PIC_DC_STATUS); - READ_VREG(HEVC_MDEC_PIC_DC_STATUS); - break; - } - } - - timeout = jiffies + HZ / 10; - - while (READ_VREG(HEVC_DBLK_STATUS) & 1) { - if (time_after(jiffies, timeout)) { - WRITE_VREG(HEVC_DBLK_CTRL, 3); - WRITE_VREG(HEVC_DBLK_CTRL, 0); - READ_VREG(HEVC_DBLK_STATUS); - READ_VREG(HEVC_DBLK_STATUS); - READ_VREG(HEVC_DBLK_STATUS); - break; - } - } - - timeout = jiffies + HZ / 10; - - while (READ_VREG(HEVC_DCAC_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - } - } -} - -#ifdef CONFIG_WAKELOCK -int amvdec_wake_lock(void) -{ - wake_lock(&amvdec_lock); - return 0; -} - -int amvdec_wake_unlock(void) -{ - wake_unlock(&amvdec_lock); - return 0; -} -#else -#define amvdec_wake_lock() -#define amvdec_wake_unlock() -#endif - -static s32 am_vdec_loadmc_ex(struct vdec_s *vdec, - const char *name, s32(*load)(const u32 *)) -{ - int err; - - if (!vdec->mc_loaded) { - int loaded; - loaded = get_decoder_firmware_data(vdec->format, - name, (u8 *)(vdec->mc), (4096 * 4 * 4)); - if (loaded <= 0) - return -1; - - vdec->mc_loaded = true; - } - - err = (*load)(vdec->mc); - if (err < 0) { - pr_err("loading firmware %s to vdec ram failed!\n", name); - return err; - } - pr_debug("loading firmware %s to vdec ram ok!\n", name); - return err; -} - -static s32 am_vdec_loadmc_buf_ex(struct vdec_s *vdec, - char *buf, int size, s32(*load)(const u32 *)) -{ - int err; - - if (!vdec->mc_loaded) { - memcpy((u8 *)(vdec->mc), buf, size); - vdec->mc_loaded = true; - } - - err = (*load)(vdec->mc); - if (err < 0) { - pr_err("loading firmware to vdec ram failed!\n"); - return err; - } - pr_debug("loading firmware to vdec ram ok!\n"); - return err; -} - -static s32 am_loadmc_ex(enum vformat_e type, - const char *name, char *def, s32(*load)(const u32 *)) -{ - char *mc_addr = vmalloc(4096 * 16); - char *pmc_addr = def; - int err; - - if (!def && mc_addr) { - int loaded; - - loaded = get_decoder_firmware_data(type, - name, mc_addr, (4096 * 16)); - if (loaded > 0) - pmc_addr = mc_addr; - } - if (!pmc_addr) { - vfree(mc_addr); - return -1; - } - err = (*load)((u32 *) pmc_addr); - if (err < 0) { - pr_err("loading firmware %s to vdec ram failed!\n", name); - return err; - } - vfree(mc_addr); - pr_debug("loading firmware %s to vdec ram ok!\n", name); - return err; -} - -static s32 amvdec_loadmc(const u32 *p) -{ - ulong timeout; - s32 ret = 0; - -#ifdef AMVDEC_USE_STATIC_MEMORY - if (mc_addr == NULL) { -#else - { -#endif - mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); - } - - if (!mc_addr) - return -ENOMEM; - - memcpy(mc_addr, p, MC_SIZE); - - mc_addr_map = dma_map_single(get_vdec_device(), - mc_addr, MC_SIZE, DMA_TO_DEVICE); - - WRITE_VREG(MPSR, 0); - WRITE_VREG(CPSR, 0); - - /* Read CBUS register for timing */ - timeout = READ_VREG(MPSR); - timeout = READ_VREG(MPSR); - - timeout = jiffies + HZ; - - WRITE_VREG(IMEM_DMA_ADR, mc_addr_map); - WRITE_VREG(IMEM_DMA_COUNT, 0x1000); - WRITE_VREG(IMEM_DMA_CTRL, (0x8000 | (7 << 16))); - - while (READ_VREG(IMEM_DMA_CTRL) & 0x8000) { - if (time_before(jiffies, timeout)) - schedule(); - else { - pr_err("vdec load mc error\n"); - ret = -EBUSY; - break; - } - } - - dma_unmap_single(get_vdec_device(), - mc_addr_map, MC_SIZE, DMA_TO_DEVICE); - -#ifndef AMVDEC_USE_STATIC_MEMORY - kfree(mc_addr); - mc_addr = NULL; -#endif - - return ret; -} - -s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def) -{ - return am_loadmc_ex(type, name, def, &amvdec_loadmc); -} -EXPORT_SYMBOL(amvdec_loadmc_ex); -s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name) -{ - return am_vdec_loadmc_ex(vdec, name, &amvdec_loadmc); -} -EXPORT_SYMBOL(amvdec_vdec_loadmc_ex); - -s32 amvdec_vdec_loadmc_buf_ex(struct vdec_s *vdec, char *buf, int size) -{ - return am_vdec_loadmc_buf_ex(vdec, buf, size, &amvdec_loadmc); -} -EXPORT_SYMBOL(amvdec_vdec_loadmc_buf_ex); - -static s32 amvdec2_loadmc(const u32 *p) -{ - if (has_vdec2()) { - ulong timeout; - s32 ret = 0; - -#ifdef AMVDEC_USE_STATIC_MEMORY - if (mc_addr == NULL) { -#else - { -#endif - mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); - } - - if (!mc_addr) - return -ENOMEM; - - memcpy(mc_addr, p, MC_SIZE); - - mc_addr_map = dma_map_single(get_vdec_device(), - mc_addr, MC_SIZE, DMA_TO_DEVICE); - - WRITE_VREG(VDEC2_MPSR, 0); - WRITE_VREG(VDEC2_CPSR, 0); - - /* Read CBUS register for timing */ - timeout = READ_VREG(VDEC2_MPSR); - timeout = READ_VREG(VDEC2_MPSR); - - timeout = jiffies + HZ; - - WRITE_VREG(VDEC2_IMEM_DMA_ADR, mc_addr_map); - WRITE_VREG(VDEC2_IMEM_DMA_COUNT, 0x1000); - WRITE_VREG(VDEC2_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); - - while (READ_VREG(VDEC2_IMEM_DMA_CTRL) & 0x8000) { - if (time_before(jiffies, timeout)) - schedule(); - else { - pr_err("vdec2 load mc error\n"); - ret = -EBUSY; - break; - } - } - - dma_unmap_single(get_vdec_device(), - mc_addr_map, MC_SIZE, DMA_TO_DEVICE); - -#ifndef AMVDEC_USE_STATIC_MEMORY - kfree(mc_addr); - mc_addr = NULL; -#endif - - return ret; - } else - return 0; -} - -s32 amvdec2_loadmc_ex(enum vformat_e type, const char *name, char *def) -{ - if (has_vdec2()) - return am_loadmc_ex(type, name, def, &amvdec2_loadmc); - else - return 0; -} -EXPORT_SYMBOL(amvdec2_loadmc_ex); - -s32 amhcodec_loadmc(const u32 *p) -{ -#ifdef AMVDEC_USE_STATIC_MEMORY - if (mc_addr == NULL) { -#else - { -#endif - mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); - } - - if (!mc_addr) - return -ENOMEM; - - memcpy(mc_addr, p, MC_SIZE); - - mc_addr_map = dma_map_single(get_vdec_device(), - mc_addr, MC_SIZE, DMA_TO_DEVICE); - - WRITE_VREG(HCODEC_IMEM_DMA_ADR, mc_addr_map); - WRITE_VREG(HCODEC_IMEM_DMA_COUNT, 0x100); - WRITE_VREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); - - while (READ_VREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) - udelay(1000); - - dma_unmap_single(get_vdec_device(), - mc_addr_map, MC_SIZE, DMA_TO_DEVICE); - -#ifndef AMVDEC_USE_STATIC_MEMORY - kfree(mc_addr); -#endif - - return 0; -} -EXPORT_SYMBOL(amhcodec_loadmc); - -s32 amhcodec_loadmc_ex(enum vformat_e type, const char *name, char *def) -{ - return am_loadmc_ex(type, name, def, &amhcodec_loadmc); -} -EXPORT_SYMBOL(amhcodec_loadmc_ex); - -static s32 amhevc_loadmc(const u32 *p) -{ - ulong timeout; - s32 ret = 0; - - if (has_hevc_vdec()) { -#ifdef AMVDEC_USE_STATIC_MEMORY - if (mc_addr == NULL) { -#else - { -#endif - mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); - } - - if (!mc_addr) - return -ENOMEM; - - memcpy(mc_addr, p, MC_SIZE); - - mc_addr_map = - dma_map_single(get_vdec_device(), - mc_addr, MC_SIZE, DMA_TO_DEVICE); - - WRITE_VREG(HEVC_MPSR, 0); - WRITE_VREG(HEVC_CPSR, 0); - - /* Read CBUS register for timing */ - timeout = READ_VREG(HEVC_MPSR); - timeout = READ_VREG(HEVC_MPSR); - - timeout = jiffies + HZ; - - WRITE_VREG(HEVC_IMEM_DMA_ADR, mc_addr_map); - WRITE_VREG(HEVC_IMEM_DMA_COUNT, 0x1000); - 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("vdec2 load mc error\n"); - ret = -EBUSY; - break; - } - } - - dma_unmap_single(get_vdec_device(), - mc_addr_map, MC_SIZE, DMA_TO_DEVICE); - -#ifndef AMVDEC_USE_STATIC_MEMORY - kfree(mc_addr); - mc_addr = NULL; -#endif - } - - return ret; -} - -s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def) -{ - if (has_hevc_vdec()) - return am_loadmc_ex(type, name, def, &amhevc_loadmc); - else - return 0; -} -EXPORT_SYMBOL(amhevc_loadmc_ex); -s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name) -{ - if (has_hevc_vdec()) - return am_vdec_loadmc_ex(vdec, name, &amhevc_loadmc); - else - return 0; -} -EXPORT_SYMBOL(amhevc_vdec_loadmc_ex); - -void amvdec_start(void) -{ -#ifdef CONFIG_WAKELOCK - amvdec_wake_lock(); -#endif - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - - WRITE_VREG(DOS_SW_RESET0, (1 << 12) | (1 << 11)); - WRITE_VREG(DOS_SW_RESET0, 0); - - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - } else { - /* #else */ - /* additional cbus dummy register reading for timing control */ - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - - WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); - - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - } - /* #endif */ - - WRITE_VREG(MPSR, 0x0001); -} -EXPORT_SYMBOL(amvdec_start); - -void amvdec2_start(void) -{ - if (has_vdec2()) { -#ifdef CONFIG_WAKELOCK - amvdec_wake_lock(); -#endif - - READ_VREG(DOS_SW_RESET2); - READ_VREG(DOS_SW_RESET2); - READ_VREG(DOS_SW_RESET2); - - WRITE_VREG(DOS_SW_RESET2, (1 << 12) | (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(VDEC2_MPSR, 0x0001); - } -} -EXPORT_SYMBOL(amvdec2_start); - -void amhcodec_start(void) -{ - WRITE_VREG(HCODEC_MPSR, 0x0001); -} -EXPORT_SYMBOL(amhcodec_start); - -void amhevc_start(void) -{ - - if (has_hevc_vdec()) { -#ifdef CONFIG_WAKELOCK - amvdec_wake_lock(); -#endif - - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - - WRITE_VREG(DOS_SW_RESET3, (1 << 12) | (1 << 11)); - WRITE_VREG(DOS_SW_RESET3, 0); - - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - - WRITE_VREG(HEVC_MPSR, 0x0001); - } -} -EXPORT_SYMBOL(amhevc_start); - -void amvdec_stop(void) -{ - ulong timeout = jiffies + HZ; - - WRITE_VREG(MPSR, 0); - WRITE_VREG(CPSR, 0); - - while (READ_VREG(IMEM_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - - WRITE_VREG(DOS_SW_RESET0, (1 << 12) | (1 << 11)); - WRITE_VREG(DOS_SW_RESET0, 0); - - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - READ_VREG(DOS_SW_RESET0); - } else { - /* #else */ - WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); - - /* additional cbus dummy register reading for timing control */ - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - } - /* #endif */ - -#ifdef CONFIG_WAKELOCK - amvdec_wake_unlock(); -#endif -} -EXPORT_SYMBOL(amvdec_stop); - -void amvdec2_stop(void) -{ - if (has_vdec2()) { - ulong timeout = jiffies + HZ; - - WRITE_VREG(VDEC2_MPSR, 0); - WRITE_VREG(VDEC2_CPSR, 0); - - while (READ_VREG(VDEC2_IMEM_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - - READ_VREG(DOS_SW_RESET2); - READ_VREG(DOS_SW_RESET2); - READ_VREG(DOS_SW_RESET2); - -#ifdef CONFIG_WAKELOCK - amvdec_wake_unlock(); -#endif - } -} -EXPORT_SYMBOL(amvdec2_stop); - -void amhcodec_stop(void) -{ - WRITE_VREG(HCODEC_MPSR, 0); -} -EXPORT_SYMBOL(amhcodec_stop); - -void amhevc_stop(void) -{ - if (has_hevc_vdec()) { - ulong timeout = jiffies + HZ; - - WRITE_VREG(HEVC_MPSR, 0); - WRITE_VREG(HEVC_CPSR, 0); - - while (READ_VREG(HEVC_IMEM_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - READ_VREG(DOS_SW_RESET3); - -#ifdef CONFIG_WAKELOCK - amvdec_wake_unlock(); -#endif - } -} -EXPORT_SYMBOL(amhevc_stop); - -void amvdec_enable(void) -{ - amvdec_pg_enable(true); -} -EXPORT_SYMBOL(amvdec_enable); - -void amvdec_disable(void) -{ - amvdec_pg_enable(false); -} -EXPORT_SYMBOL(amvdec_disable); - -void amvdec2_enable(void) -{ - if (has_vdec2()) - amvdec2_pg_enable(true); -} -EXPORT_SYMBOL(amvdec2_enable); - -void amvdec2_disable(void) -{ - if (has_vdec2()) - amvdec2_pg_enable(false); -} -EXPORT_SYMBOL(amvdec2_disable); - -void amhevc_enable(void) -{ - if (has_hevc_vdec()) - amhevc_pg_enable(true); -} -EXPORT_SYMBOL(amhevc_enable); - -void amhevc_disable(void) -{ - if (has_hevc_vdec()) - amhevc_pg_enable(false); -} -EXPORT_SYMBOL(amhevc_disable); - -#ifdef CONFIG_PM -int amvdec_suspend(struct platform_device *dev, pm_message_t event) -{ - amvdec_pg_enable(false); - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ - if (has_vdec2()) - amvdec2_pg_enable(false); - /* #endif */ - - if (has_hevc_vdec()) - amhevc_pg_enable(false); - - return 0; -} -EXPORT_SYMBOL(amvdec_suspend); - -int amvdec_resume(struct platform_device *dev) -{ - amvdec_pg_enable(true); - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ - if (has_vdec2()) - amvdec2_pg_enable(true); - /* #endif */ - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if (has_hevc_vdec()) - amhevc_pg_enable(true); - /* #endif */ - - return 0; -} -EXPORT_SYMBOL(amvdec_resume); - -int amhevc_suspend(struct platform_device *dev, pm_message_t event) -{ - if (has_hevc_vdec()) - amhevc_pg_enable(false); - return 0; -} -EXPORT_SYMBOL(amhevc_suspend); - -int amhevc_resume(struct platform_device *dev) -{ - if (has_hevc_vdec()) - amhevc_pg_enable(true); - return 0; -} -EXPORT_SYMBOL(amhevc_resume); - - -#endif - -#ifdef CONFIG_WAKELOCK - -static int vdec_is_paused(void) -{ - static unsigned long old_wp = -1, old_rp = -1, old_level = -1; - unsigned long wp, rp, level; - static int paused_time; - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if (has_hevc_vdec()) { - if ((vdec_on(VDEC_HEVC)) - && (READ_VREG(HEVC_STREAM_CONTROL) & 1)) { - wp = READ_VREG(HEVC_STREAM_WR_PTR); - rp = READ_VREG(HEVC_STREAM_RD_PTR); - level = READ_VREG(HEVC_STREAM_LEVEL); - } else { - wp = READ_VREG(VLD_MEM_VIFIFO_WP); - rp = READ_VREG(VLD_MEM_VIFIFO_RP); - level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); - } - } else - /* #endif */ - { - wp = READ_VREG(VLD_MEM_VIFIFO_WP); - rp = READ_VREG(VLD_MEM_VIFIFO_RP); - level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); - } - /*have data,but output buffer is full */ - if ((rp == old_rp && level > 1024) || - (rp == old_rp && wp == old_wp && level == level)) { - /*no write && not read */ - paused_time++; - } else { - paused_time = 0; - } - old_wp = wp; old_rp = rp; old_level = level; - if (paused_time > 10) - return 1; - return 0; -} - -int amvdev_pause(void) -{ - video_running = 0; - video_stated_changed = 1; - return 0; -} -EXPORT_SYMBOL(amvdev_pause); - -int amvdev_resume(void) -{ - video_running = 1; - video_stated_changed = 1; - return 0; -} -EXPORT_SYMBOL(amvdev_resume); - -static void vdec_paused_check_timer(unsigned long arg) -{ - if (video_stated_changed) { - if (!video_running) { - if (vdec_is_paused()) { - pr_info("vdec paused and release wakelock now\n"); - amvdec_wake_unlock(); - video_stated_changed = 0; - } - } else { - amvdec_wake_lock(); - video_stated_changed = 0; - } - } - mod_timer(&amvdevtimer, jiffies + WAKE_CHECK_INTERVAL); -} -#else -int amvdev_pause(void) -{ - return 0; -} - -int amvdev_resume(void) -{ - return 0; -} -#endif - -int amvdec_init(void) -{ -#ifdef CONFIG_WAKELOCK - /* - *wake_lock_init(&amvdec_lock, WAKE_LOCK_IDLE, "amvdec_lock"); - *tmp mark for compile, no "WAKE_LOCK_IDLE" definition in kernel 3.8 - */ - wake_lock_init(&amvdec_lock, /*WAKE_LOCK_IDLE */ WAKE_LOCK_SUSPEND, - "amvdec_lock"); - - init_timer(&amvdevtimer); - - amvdevtimer.data = (ulong) &amvdevtimer; - amvdevtimer.function = vdec_paused_check_timer; -#endif - return 0; -} -EXPORT_SYMBOL(amvdec_init); - -void amvdec_exit(void) -{ -#ifdef CONFIG_WAKELOCK - del_timer_sync(&amvdevtimer); -#endif -} -EXPORT_SYMBOL(amvdec_exit); - -#if 0 -int __init amvdec_init(void) -{ -#ifdef CONFIG_WAKELOCK - /* - *wake_lock_init(&amvdec_lock, WAKE_LOCK_IDLE, "amvdec_lock"); - *tmp mark for compile, no "WAKE_LOCK_IDLE" definition in kernel 3.8 - */ - wake_lock_init(&amvdec_lock, /*WAKE_LOCK_IDLE */ WAKE_LOCK_SUSPEND, - "amvdec_lock"); - - init_timer(&amvdevtimer); - - amvdevtimer.data = (ulong) &amvdevtimer; - amvdevtimer.function = vdec_paused_check_timer; -#endif - return 0; -} - -static void __exit amvdec_exit(void) -{ -#ifdef CONFIG_WAKELOCK - del_timer_sync(&amvdevtimer); -#endif -} - -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>"); diff --git a/drivers/frame_provider/decoder/utils/amvdec.h b/drivers/frame_provider/decoder/utils/amvdec.h deleted file mode 100644 index c6f11d7..0000000 --- a/drivers/frame_provider/decoder/utils/amvdec.h +++ b/dev/null @@ -1,86 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/amvdec.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 AMVDEC_H -#define AMVDEC_H -#include <linux/amlogic/media/utils/amports_config.h> -#include <linux/amlogic/media/utils/vformat.h> -#include "vdec.h" - -#define UCODE_ALIGN 8 -#define UCODE_ALIGN_MASK 7UL - -struct amvdec_dec_reg_s { - unsigned long mem_start; - unsigned long mem_end; - struct device *cma_dev; - struct dec_sysinfo *dec_sysinfo; -}; /*amvdec_dec_reg_t */ - -extern void amvdec_start(void); -extern void amvdec_stop(void); -extern void amvdec_enable(void); -extern void amvdec_disable(void); -s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def); -s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name); - -extern void amvdec2_start(void); -extern void amvdec2_stop(void); -extern void amvdec2_enable(void); -extern void amvdec2_disable(void); -s32 amvdec2_loadmc_ex(enum vformat_e type, const char *name, char *def); - -extern void amhevc_start(void); -extern void amhevc_stop(void); -extern void amhevc_enable(void); -extern void amhevc_disable(void); -s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def); -s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name); -s32 amvdec_vdec_loadmc_buf_ex(struct vdec_s *vdec, char *buf, int size); - -extern void amhcodec_start(void); -extern void amhcodec_stop(void); -s32 amhcodec_loadmc(const u32 *p); -s32 amhcodec_loadmc_ex(enum vformat_e type, const char *name, char *def); - -extern int amvdev_pause(void); -extern int amvdev_resume(void); - -#ifdef CONFIG_PM -extern int amvdec_suspend(struct platform_device *dev, pm_message_t event); -extern int amvdec_resume(struct platform_device *dec); -extern int amhevc_suspend(struct platform_device *dev, pm_message_t event); -extern int amhevc_resume(struct platform_device *dec); - -#endif - -int amvdec_init(void); -void amvdec_exit(void); - -#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define AMVDEC_CLK_GATE_ON(a) -#define AMVDEC_CLK_GATE_OFF(a) -#else -#define AMVDEC_CLK_GATE_ON(a) CLK_GATE_ON(a) -#define AMVDEC_CLK_GATE_OFF(a) CLK_GATE_OFF(a) -#endif - -/* TODO: move to register headers */ -#define RESET_VCPU (1<<7) -#define RESET_CCPU (1<<8) - -#endif /* AMVDEC_H */ diff --git a/drivers/frame_provider/decoder/utils/config_parser.c b/drivers/frame_provider/decoder/utils/config_parser.c deleted file mode 100644 index b9c64f7..0000000 --- a/drivers/frame_provider/decoder/utils/config_parser.c +++ b/dev/null @@ -1,62 +0,0 @@ -/* - * drivers/amlogic/amports/config_parser.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 "config_parser.h" -/* -sample config: -configs: width:1920;height:1080; -need:width -ok: return 0; -*val = value; -*/ -int get_config_int(const char *configs, const char *need, int *val) -{ - const char *str; - int ret; - int lval = 0; - *val = 0; - - if (!configs || !need) - return -1; - str = strstr(configs, need); - if (str != NULL) { - if (str > configs && str[-1] != ';') { - /* - if not the first config val. - make sure before is ';' - to recognize: - ;crop_width:100 - ;width:100 - */ - return -2; - } - str += strlen(need); - if (str[0] != ':' || str[1] == '\0') - return -3; - ret = sscanf(str, ":%d", &lval); - if (ret == 1) { - *val = lval; - return 0; - } - } - - return -4; -} diff --git a/drivers/frame_provider/decoder/utils/config_parser.h b/drivers/frame_provider/decoder/utils/config_parser.h deleted file mode 100644 index e10210a..0000000 --- a/drivers/frame_provider/decoder/utils/config_parser.h +++ b/dev/null @@ -1,21 +0,0 @@ -/* - * drivers/amlogic/amports/config_parser.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. - * -*/ -#ifndef CONFIG_PARSER_HHH_ -#define CONFIG_PARSER_HHH_ -int get_config_int(const char *configs, const char *need, int *val); - -#endif/*CONFIG_PARSER_HHH_*/ diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c deleted file mode 100644 index 7a858d5..0000000 --- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c +++ b/dev/null @@ -1,425 +0,0 @@ -/* - * drivers/amlogic/amports/decoder/decoder_bmmu_box.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/slab.h> -#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h> -#include <linux/platform_device.h> - -#include <linux/amlogic/media/video_sink/video_keeper.h> -#include "decoder_bmmu_box.h" -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -struct decoder_bmmu_box { - int max_mm_num; - const char *name; - int channel_id; - struct mutex mutex; - struct list_head list; - int total_size; - int change_size_on_need_smaller; - int align2n; /*can overwite on idx alloc */ - int mem_flags; /*can overwite on idx alloc */ - struct codec_mm_s *mm_list[1]; -}; - -struct decoder_bmmu_box_mgr { - int num; - struct mutex mutex; - struct list_head box_list; -}; -static struct decoder_bmmu_box_mgr global_blk_mgr; -static struct decoder_bmmu_box_mgr *get_decoder_bmmu_box_mgr(void) -{ - return &global_blk_mgr; -} - -static int decoder_bmmu_box_mgr_add_box(struct decoder_bmmu_box *box) -{ - struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr(); - mutex_lock(&mgr->mutex); - list_add_tail(&box->list, &mgr->box_list); - mutex_unlock(&mgr->mutex); - return 0; -} - -static int decoder_bmmu_box_mgr_del_box(struct decoder_bmmu_box *box) -{ - struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr(); - mutex_lock(&mgr->mutex); - list_del(&box->list); - mutex_unlock(&mgr->mutex); - return 0; -} - -void *decoder_bmmu_box_alloc_box(const char *name, - int channel_id, int max_num, - int aligned, int mem_flags) -/*min_size_M:wait alloc this size*/ -{ - struct decoder_bmmu_box *box; - int size; - size = sizeof(struct decoder_bmmu_box) + sizeof(struct codec_mm_s *) * - max_num; - box = kmalloc(size, GFP_KERNEL); - if (!box) { - pr_err("can't alloc decoder buffers box!!!\n"); - return NULL; - } - memset(box, 0, size); - box->max_mm_num = max_num; - box->name = name; - box->channel_id = channel_id; - box->align2n = aligned; - box->mem_flags = mem_flags; - mutex_init(&box->mutex); - INIT_LIST_HEAD(&box->list); - decoder_bmmu_box_mgr_add_box(box); - return (void *)box; -} -EXPORT_SYMBOL(decoder_bmmu_box_alloc_box); - -int decoder_bmmu_box_alloc_idx(void *handle, int idx, int size, int aligned_2n, - int mem_flags) -/*align& flags if -1 user box default.*/ -{ - struct decoder_bmmu_box *box = handle; - struct codec_mm_s *mm; - int align = aligned_2n; - int memflags = mem_flags; - - if (!box || idx < 0 || idx >= box->max_mm_num) { - pr_err("can't alloc mmu box(%p),idx:%d\n", - box, idx); - return -1; - } - if (align == -1) - align = box->align2n; - if (memflags == -1) - memflags = box->mem_flags; - - mutex_lock(&box->mutex); - mm = box->mm_list[idx]; - if (mm) { - int invalid = 0; - if (mm->page_count * PAGE_SIZE < size) { - /*size is small. */ - invalid = 1; - } else if (box->change_size_on_need_smaller && - (mm->buffer_size > (size << 1))) { - /*size is too large. */ - invalid = 2; - } else if (mm->phy_addr & ((1 << align) - 1)) { - /*addr is not align */ - invalid = 4; - } - if (invalid) { - box->total_size -= mm->buffer_size; - codec_mm_release(mm, box->name); - box->mm_list[idx] = NULL; - mm = NULL; - } - } - if (!mm) { - mm = codec_mm_alloc(box->name, size, align, memflags); - if (mm) { - box->mm_list[idx] = mm; - box->total_size += mm->buffer_size; - } - } - mutex_unlock(&box->mutex); - return mm ? 0 : -ENOMEM; -} - -int decoder_bmmu_box_free_idx(void *handle, int idx) -{ - struct decoder_bmmu_box *box = handle; - struct codec_mm_s *mm; - if (!box || idx < 0 || idx >= box->max_mm_num) { - pr_err("can't free idx of box(%p),idx:%d in (%d-%d)\n", - box, idx, 0, - box->max_mm_num - 1); - return -1; - } - mutex_lock(&box->mutex); - mm = box->mm_list[idx]; - if (mm) { - box->total_size -= mm->buffer_size; - codec_mm_release(mm, box->name); - box->mm_list[idx] = NULL; - mm = NULL; - } - mutex_unlock(&box->mutex); - return 0; -} -EXPORT_SYMBOL(decoder_bmmu_box_free_idx); - -int decoder_bmmu_box_free(void *handle) -{ - struct decoder_bmmu_box *box = handle; - struct codec_mm_s *mm; - int i; - if (!box) { - pr_err("can't free box of NULL box!\n"); - return -1; - } - mutex_lock(&box->mutex); - for (i = 0; i < box->max_mm_num; i++) { - mm = box->mm_list[i]; - if (mm) { - codec_mm_release(mm, box->name); - box->mm_list[i] = NULL; - } - } - mutex_unlock(&box->mutex); - decoder_bmmu_box_mgr_del_box(box); - kfree(box); - return 0; -} -EXPORT_SYMBOL(decoder_bmmu_box_free); - -void *decoder_bmmu_box_get_mem_handle(void *box_handle, int idx) -{ - struct decoder_bmmu_box *box = box_handle; - if (!box || idx < 0 || idx >= box->max_mm_num) - return NULL; - return box->mm_list[idx]; -} -EXPORT_SYMBOL(decoder_bmmu_box_get_mem_handle); - -int decoder_bmmu_box_get_mem_size(void *box_handle, int idx) -{ - struct decoder_bmmu_box *box = box_handle; - int size = 0; - if (!box || idx < 0 || idx >= box->max_mm_num) - return 0; - mutex_lock(&box->mutex); - if (box->mm_list[idx] != NULL) - size = box->mm_list[idx]->buffer_size; - mutex_unlock(&box->mutex); - return size; -} - - -unsigned long decoder_bmmu_box_get_phy_addr(void *box_handle, int idx) -{ - struct decoder_bmmu_box *box = box_handle; - struct codec_mm_s *mm; - if (!box || idx < 0 || idx >= box->max_mm_num) - return 0; - mm = box->mm_list[idx]; - if (!mm) - return 0; - return mm->phy_addr; -} -EXPORT_SYMBOL(decoder_bmmu_box_get_phy_addr); - -void *decoder_bmmu_box_get_virt_addr(void *box_handle, int idx) -{ - struct decoder_bmmu_box *box = box_handle; - struct codec_mm_s *mm; - if (!box || idx < 0 || idx >= box->max_mm_num) - return NULL; - mm = box->mm_list[idx]; - if (!mm) - return 0; - return codec_mm_phys_to_virt(mm->phy_addr); -} - -/*flags: &0x1 for wait,*/ -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) { - pr_err("CMA force free keep,for size = %d\n", size); - /*need free others? - */ - try_free_keep_video(1); - } - - return codec_mm_enough_for_size(size, - flags & BMMU_ALLOC_FLAGS_WAIT); -} - -int decoder_bmmu_box_alloc_idx_wait( - void *handle, int idx, - int size, int aligned_2n, - int mem_flags, - int wait_flags) -{ - int have_space; - int ret = -1; - if (decoder_bmmu_box_get_mem_size(handle, idx) >= size) - return 0;/*have alloced memery before.*/ - have_space = decoder_bmmu_box_check_and_wait_size( - size, - wait_flags); - if (have_space) { - ret = decoder_bmmu_box_alloc_idx(handle, - idx, size, aligned_2n, mem_flags); - } else { - ret = -ENOMEM; - } - return ret; -} -EXPORT_SYMBOL(decoder_bmmu_box_alloc_idx_wait); - -static int decoder_bmmu_box_dump(struct decoder_bmmu_box *box, void *buf, - int size) -{ - char *pbuf = buf; - char sbuf[512]; - int tsize = 0; - int s; - int i; - if (!pbuf) - pbuf = sbuf; - -#define BUFPRINT(args...) \ - do {\ - s = sprintf(pbuf, args);\ - tsize += s;\ - pbuf += s; \ - } while (0) - - for (i = 0; i < box->max_mm_num; i++) { - struct codec_mm_s *mm = box->mm_list[i]; - if (buf && (size - tsize) < 128) - break; - if (mm) { - BUFPRINT("code mem[%d]:%p, addr=%p, size=%d,from=%d\n", - i, - (void *)mm, - (void *)mm->phy_addr, - mm->buffer_size, - mm->from_flags); - } - } -#undef BUFPRINT - if (!buf) - pr_info("%s", sbuf); - - return tsize; -} - -static int decoder_bmmu_box_dump_all(void *buf, int size) -{ - struct decoder_bmmu_box_mgr *mgr = get_decoder_bmmu_box_mgr(); - char *pbuf = buf; - char sbuf[512]; - int tsize = 0; - int s; - int i; - struct list_head *head, *list; - if (!pbuf) - pbuf = sbuf; - -#define BUFPRINT(args...) \ - do {\ - s = sprintf(pbuf, args);\ - tsize += s;\ - pbuf += s; \ - } while (0) - - mutex_lock(&mgr->mutex); - head = &mgr->box_list; - list = head->next; - i = 0; - while (list != head) { - struct decoder_bmmu_box *box; - box = list_entry(list, struct decoder_bmmu_box, list); - BUFPRINT("box[%d]: %s, player_id:%d, max_num:%d, size:%d\n", - i, box->name, - box->channel_id, - box->max_mm_num, - box->total_size); - if (buf) { - tsize += decoder_bmmu_box_dump(box, pbuf, size - tsize); - if (tsize > 0) - pbuf += tsize; - } else { - pr_info("%s", sbuf); - pbuf = sbuf; - tsize += decoder_bmmu_box_dump(box, NULL, 0); - } - list = list->next; - i++; - } - mutex_unlock(&mgr->mutex); - -#undef BUFPRINT - if (!buf) - pr_info("%s", sbuf); - return tsize; -} - -static ssize_t box_dump_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - ssize_t ret = 0; - ret = decoder_bmmu_box_dump_all(buf, PAGE_SIZE); - return ret; -} - -static struct class_attribute decoder_bmmu_box_class_attrs[] = { - __ATTR_RO(box_dump), - __ATTR_NULL -}; - -static struct class decoder_bmmu_box_class = { - .name = "decoder_bmmu_box", - .class_attrs = decoder_bmmu_box_class_attrs, - }; - -int decoder_bmmu_box_init(void) -{ - int r; - memset(&global_blk_mgr, 0, sizeof(global_blk_mgr)); - INIT_LIST_HEAD(&global_blk_mgr.box_list); - mutex_init(&global_blk_mgr.mutex); - r = class_register(&decoder_bmmu_box_class); - return r; -} -EXPORT_SYMBOL(decoder_bmmu_box_init); - -void decoder_bmmu_box_exit(void) -{ - class_unregister(&decoder_bmmu_box_class); - pr_info("dec bmmu box exit.\n"); -} - -#if 0 -static int __init decoder_bmmu_box_init(void) -{ - int r; - memset(&global_blk_mgr, 0, sizeof(global_blk_mgr)); - INIT_LIST_HEAD(&global_blk_mgr.box_list); - mutex_init(&global_blk_mgr.mutex); - r = class_register(&decoder_bmmu_box_class); - return r; -} - -module_init(decoder_bmmu_box_init); -#endif diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h deleted file mode 100644 index 99aa89b..0000000 --- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h +++ b/dev/null @@ -1,63 +0,0 @@ -/* - * drivers/amlogic/amports/decoder/decoder_bmmu_box.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 DECODER_BLOCK_BUFFER_BOX -#define DECODER_BLOCK_BUFFER_BOX - -void *decoder_bmmu_box_alloc_box(const char *name, - int channel_id, - int max_num, - int aligned, - int mem_flags); - -int decoder_bmmu_box_alloc_idx( - void *handle, int idx, int size, - int aligned_2n, int mem_flags); - -int decoder_bmmu_box_free_idx(void *handle, int idx); -int decoder_bmmu_box_free(void *handle); -void *decoder_bmmu_box_get_mem_handle( - void *box_handle, int idx); - -unsigned long decoder_bmmu_box_get_phy_addr( - void *box_handle, int idx); - -void *decoder_bmmu_box_get_virt_addr( - void *box_handle, int idx); - -/*flags: &0x1 for wait,*/ -int decoder_bmmu_box_check_and_wait_size( - int size, int flags); - -#define BMMU_ALLOC_FLAGS_WAIT (1 << 0) -#define BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER (1 << 1) -#define BMMU_ALLOC_FLAGS_WAITCLEAR \ - (BMMU_ALLOC_FLAGS_WAIT |\ - BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER) - -int decoder_bmmu_box_alloc_idx_wait( - void *handle, int idx, - int size, int aligned_2n, - int mem_flags, - int wait_flags); - -int decoder_bmmu_box_init(void); -void decoder_bmmu_box_exit(void); - -#endif /* - */ - diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c b/drivers/frame_provider/decoder/utils/decoder_mmu_box.c deleted file mode 100644 index 26440fe..0000000 --- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c +++ b/dev/null @@ -1,383 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/decoder_mmu_box.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/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/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; - struct mutex mutex; - struct list_head list; - struct codec_mm_scatter *sc_list[1]; -}; -#define MAX_KEEP_FRAME 4 -#define START_KEEP_ID 0x9 -#define MAX_KEEP_ID (INT_MAX - 1) -struct decoder_mmu_box_mgr { - int num; - struct mutex mutex; - struct codec_mm_scatter *keep_sc[MAX_KEEP_FRAME]; - int keep_id[MAX_KEEP_FRAME]; - int next_id;/*id for keep & free.*/ - struct list_head box_list; -}; -static struct decoder_mmu_box_mgr global_mgr; -static struct decoder_mmu_box_mgr *get_decoder_mmu_box_mgr(void) -{ - return &global_mgr; -} - -static int decoder_mmu_box_mgr_add_box(struct decoder_mmu_box *box) -{ - struct decoder_mmu_box_mgr *mgr = get_decoder_mmu_box_mgr(); - - mutex_lock(&mgr->mutex); - list_add_tail(&box->list, &mgr->box_list); - mutex_unlock(&mgr->mutex); - return 0; -} - -static int decoder_mmu_box_mgr_del_box(struct decoder_mmu_box *box) -{ - struct decoder_mmu_box_mgr *mgr = get_decoder_mmu_box_mgr(); - - mutex_lock(&mgr->mutex); - list_del(&box->list); - mutex_unlock(&mgr->mutex); - return 0; -} - - - -void *decoder_mmu_box_alloc_box(const char *name, - int channel_id, - int max_num, - int min_size_M) -/*min_size_M:wait alloc this size*/ -{ - struct decoder_mmu_box *box; - int size; - - size = sizeof(struct decoder_mmu_box) + - sizeof(struct codec_mm_scatter *) * - max_num; - box = kmalloc(size, GFP_KERNEL); - if (!box) { - pr_err("can't alloc decoder buffers box!!!\n"); - return NULL; - } - memset(box, 0, size); - box->max_sc_num = max_num; - box->name = name; - box->channel_id = channel_id; - mutex_init(&box->mutex); - INIT_LIST_HEAD(&box->list); - decoder_mmu_box_mgr_add_box(box); - codec_mm_scatter_mgt_delay_free_swith(1, 2000, - min_size_M); - return (void *)box; -} -EXPORT_SYMBOL(decoder_mmu_box_alloc_box); - -int decoder_mmu_box_alloc_idx( - void *handle, int idx, int num_pages, - unsigned int *mmu_index_adr) -{ - struct decoder_mmu_box *box = handle; - struct codec_mm_scatter *sc; - int ret; - int i; - - if (!box || idx < 0 || idx >= box->max_sc_num) { - pr_err("can't alloc mmu box(%p),idx:%d\n", - box, idx); - return -1; - } - mutex_lock(&box->mutex); - sc = box->sc_list[idx]; - if (sc) { - if (sc->page_max_cnt >= num_pages) - ret = codec_mm_scatter_alloc_want_pages(sc, - num_pages); - else { - codec_mm_scatter_dec_owner_user(sc, 0); - box->sc_list[idx] = NULL; - sc = NULL; - } - - } - if (!sc) { - sc = codec_mm_scatter_alloc(num_pages + 64, num_pages); - if (!sc) { - mutex_unlock(&box->mutex); - pr_err("alloc mmu failed, need pages=%d\n", - num_pages); - return -1; - } - box->sc_list[idx] = sc; - } - - for (i = 0; i < num_pages; i++) - mmu_index_adr[i] = PAGE_INDEX(sc->pages_list[i]); - mmu_index_adr[num_pages] = 0; - - mutex_unlock(&box->mutex); - - return 0; -} -EXPORT_SYMBOL(decoder_mmu_box_alloc_idx); - -int decoder_mmu_box_free_idx_tail( - void *handle, int idx, - int start_release_index) -{ - struct decoder_mmu_box *box = handle; - struct codec_mm_scatter *sc; - - if (!box || idx < 0 || idx >= box->max_sc_num) { - pr_err("can't free tail mmu box(%p),idx:%d in (%d-%d)\n", - box, idx, 0, - box->max_sc_num - 1); - return -1; - } - mutex_lock(&box->mutex); - sc = box->sc_list[idx]; - if (sc && start_release_index < sc->page_cnt) - codec_mm_scatter_free_tail_pages_fast(sc, - start_release_index); - mutex_unlock(&box->mutex); - return 0; -} -EXPORT_SYMBOL(decoder_mmu_box_free_idx_tail); - -int decoder_mmu_box_free_idx(void *handle, int idx) -{ - struct decoder_mmu_box *box = handle; - struct codec_mm_scatter *sc; - - if (!box || idx < 0 || idx >= box->max_sc_num) { - pr_err("can't free idx of box(%p),idx:%d in (%d-%d)\n", - box, idx, 0, - box->max_sc_num - 1); - 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; - } mutex_unlock(&box->mutex); - return 0; -} -EXPORT_SYMBOL(decoder_mmu_box_free_idx); - -int decoder_mmu_box_free(void *handle) -{ - struct decoder_mmu_box *box = handle; - struct codec_mm_scatter *sc; - int i; - - if (!box) { - 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, 200); - box->sc_list[i] = NULL; - } - } - mutex_unlock(&box->mutex); - decoder_mmu_box_mgr_del_box(box); - kfree(box); - codec_mm_scatter_mgt_delay_free_swith(0, 2000, 0); - return 0; -} -EXPORT_SYMBOL(decoder_mmu_box_free); - -void *decoder_mmu_box_get_mem_handle(void *box_handle, int idx) -{ - struct decoder_mmu_box *box = box_handle; - - if (!box || idx < 0 || idx >= box->max_sc_num) - return NULL; - return box->sc_list[idx]; -} -EXPORT_SYMBOL(decoder_mmu_box_get_mem_handle); - -static int decoder_mmu_box_dump(struct decoder_mmu_box *box, - void *buf, int size) -{ - char *pbuf = buf; - char sbuf[512]; - int tsize = 0; - int s; - int i; - - if (!pbuf) - pbuf = sbuf; - - #define BUFPRINT(args...) \ - do {\ - s = sprintf(pbuf, args);\ - tsize += s;\ - pbuf += s; \ - } while (0) - - for (i = 0; i < box->max_sc_num; i++) { - struct codec_mm_scatter *sc = box->sc_list[i]; - - if (sc) { - BUFPRINT("sc mem[%d]:%p, size=%d\n", - i, sc, - sc->page_cnt << PAGE_SHIFT); - } - } -#undef BUFPRINT - if (!buf) - pr_info("%s", sbuf); - - return tsize; -} - -static int decoder_mmu_box_dump_all(void *buf, int size) -{ - struct decoder_mmu_box_mgr *mgr = get_decoder_mmu_box_mgr(); - char *pbuf = buf; - char sbuf[512]; - int tsize = 0; - int s; - int i; - struct list_head *head, *list; - - if (!pbuf) - pbuf = sbuf; - - #define BUFPRINT(args...) \ - do {\ - s = sprintf(pbuf, args);\ - tsize += s;\ - pbuf += s; \ - } while (0) - - mutex_lock(&mgr->mutex); - head = &mgr->box_list; - list = head->next; - i = 0; - while (list != head) { - struct decoder_mmu_box *box; - - box = list_entry(list, struct decoder_mmu_box, - list); - BUFPRINT("box[%d]: %s, player_id:%d, max_num:%d\n", - i, - box->name, - box->channel_id, - box->max_sc_num); - if (buf) { - tsize += decoder_mmu_box_dump(box, pbuf, size - tsize); - if (tsize > 0) - pbuf += tsize; - } else { - pr_info("%s", sbuf); - pbuf = sbuf; - tsize += decoder_mmu_box_dump(box, NULL, 0); - } - list = list->next; - i++; - } - mutex_unlock(&mgr->mutex); - - -#undef BUFPRINT - if (!buf) - pr_info("%s", sbuf); - return tsize; -} - - - -static ssize_t -box_dump_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - ssize_t ret = 0; - - ret = decoder_mmu_box_dump_all(buf, PAGE_SIZE); - return ret; -} - - - -static struct class_attribute decoder_mmu_box_class_attrs[] = { - __ATTR_RO(box_dump), - __ATTR_NULL -}; - -static struct class decoder_mmu_box_class = { - .name = "decoder_mmu_box", - .class_attrs = decoder_mmu_box_class_attrs, -}; - -int decoder_mmu_box_init(void) -{ - int r; - - memset(&global_mgr, 0, sizeof(global_mgr)); - INIT_LIST_HEAD(&global_mgr.box_list); - mutex_init(&global_mgr.mutex); - global_mgr.next_id = START_KEEP_ID; - r = class_register(&decoder_mmu_box_class); - return r; -} -EXPORT_SYMBOL(decoder_mmu_box_init); - -void decoder_mmu_box_exit(void) -{ - class_unregister(&decoder_mmu_box_class); - pr_info("dec mmu box exit.\n"); -} - -#if 0 -static int __init decoder_mmu_box_init(void) -{ - int r; - - memset(&global_mgr, 0, sizeof(global_mgr)); - INIT_LIST_HEAD(&global_mgr.box_list); - mutex_init(&global_mgr.mutex); - global_mgr.next_id = START_KEEP_ID; - r = class_register(&decoder_mmu_box_class); - return r; -} - -module_init(decoder_mmu_box_init); -#endif diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h b/drivers/frame_provider/decoder/utils/decoder_mmu_box.h deleted file mode 100644 index 387dd24..0000000 --- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h +++ b/dev/null @@ -1,45 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/decoder_mmu_box.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 DECODER_BUFFER_BOX -#define DECODER_BUFFER_BOX - -void *decoder_mmu_box_alloc_box(const char *name, - int channel_id, - int max_num, - int min_size_M); - -int decoder_mmu_box_alloc_idx( - void *handle, int idx, int num_pages, - unsigned int *mmu_index_adr); - -int decoder_mmu_box_free_idx_tail(void *handle, int idx, - int start_release_index); - -int decoder_mmu_box_free_idx(void *handle, int idx); - -int decoder_mmu_box_free(void *handle); - -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); -int decoder_mmu_box_init(void); -void decoder_mmu_box_exit(void); - -#endif diff --git a/drivers/frame_provider/decoder/utils/utils.c b/drivers/frame_provider/decoder/utils/utils.c deleted file mode 100644 index 33ab765..0000000 --- a/drivers/frame_provider/decoder/utils/utils.c +++ b/dev/null @@ -1,66 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/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/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <linux/platform_device.h> -#include <linux/uaccess.h> -#include <linux/semaphore.h> -#include <linux/sched/rt.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/slab.h> - -#include "vdec.h" -#include "vdec_input.h" -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "amvdec.h" -#include "decoder_mmu_box.h" -#include "decoder_bmmu_box.h" - -static int __init decoder_common_init(void) -{ - /*vdec init.*/ - vdec_module_init(); - - /*amvdec init.*/ - amvdec_init(); - - /*mmu box init.*/ - decoder_mmu_box_init();/*exit?*/ - decoder_bmmu_box_init(); - - return 0; -} - -static void __exit decoder_common_exit(void) -{ - /*vdec exit.*/ - vdec_module_exit(); - - /*amvdec exit.*/ - amvdec_exit(); - - decoder_mmu_box_exit(); - decoder_bmmu_box_exit(); -} - -module_init(decoder_common_init); -module_exit(decoder_common_exit); diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c deleted file mode 100644 index 7c54882..0000000 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/dev/null @@ -1,2907 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec.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/spinlock.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <linux/platform_device.h> -#include <linux/uaccess.h> -#include <linux/semaphore.h> -#include <linux/sched/rt.h> -#include <linux/interrupt.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/iomap.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/video_sink/ionvideo_ext.h> -#include <linux/amlogic/media/vfm/vfm_ext.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "vdec.h" -#ifdef CONFIG_MULTI_DEC -#include "vdec_profile.h" -#endif -#include <linux/of.h> -#include <linux/of_fdt.h> -#include <linux/libfdt_env.h> -#include <linux/of_reserved_mem.h> -#include <linux/dma-contiguous.h> -#include <linux/cma.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/utils/amports_config.h> -#include "../utils/amvdec.h" -#include "vdec_input.h" - -#include "../../../common/media_clock/clk/clk.h" -#include <linux/reset.h> -#include <linux/amlogic/media/old_cpu_version.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> -#include <linux/amlogic/media/video_sink/video_keeper.h> - -static DEFINE_MUTEX(vdec_mutex); - -#define MC_SIZE (4096 * 4) -#define CMA_ALLOC_SIZE SZ_64M -#define MEM_NAME "vdec_prealloc" -static int inited_vcodec_num; -static int poweron_clock_level; -static int keep_vdec_mem; -static unsigned int debug_trace_num = 16 * 20; -static int step_mode; -static unsigned int clk_config; - -static struct page *vdec_cma_page; -int vdec_mem_alloced_from_codec, delay_release; -static unsigned long reserved_mem_start, reserved_mem_end; -static int hevc_max_reset_count; -static DEFINE_SPINLOCK(vdec_spin_lock); - -#define HEVC_TEST_LIMIT 100 -#define GXBB_REV_A_MINOR 0xA - -struct am_reg { - char *name; - int offset; -}; - -struct vdec_isr_context_s { - int index; - int irq; - irq_handler_t dev_isr; - irq_handler_t dev_threaded_isr; - void *dev_id; -}; - -struct vdec_core_s { - struct list_head connected_vdec_list; - spinlock_t lock; - - atomic_t vdec_nr; - struct vdec_s *vfm_vdec; - struct vdec_s *active_vdec; - struct platform_device *vdec_core_platform_device; - struct device *cma_dev; - unsigned long mem_start; - unsigned long mem_end; - - struct semaphore sem; - struct task_struct *thread; - - struct vdec_isr_context_s isr_context[VDEC_IRQ_MAX]; - int power_ref_count[VDEC_MAX]; -}; - -static struct vdec_core_s *vdec_core; - -unsigned long vdec_core_lock(struct vdec_core_s *core) -{ - unsigned long flags; - - spin_lock_irqsave(&core->lock, flags); - - return flags; -} - -void vdec_core_unlock(struct vdec_core_s *core, unsigned long flags) -{ - spin_unlock_irqrestore(&core->lock, flags); -} - -static int get_canvas(unsigned int index, unsigned int base) -{ - int start; - int canvas_index = index * base; - - 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) { - return start; - } else if (base == 2) { - return ((start + 1) << 16) | ((start + 1) << 8) | start; - } else if (base == 3) { - return ((start + 2) << 16) | ((start + 1) << 8) | start; - } else if (base == 4) { - return (((start + 3) << 24) | (start + 2) << 16) | - ((start + 1) << 8) | start; - } - - return -1; -} - - -int vdec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - if (vdec->dec_status) - return vdec->dec_status(vdec, vstatus); - - return -1; -} -EXPORT_SYMBOL(vdec_status); - -int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) -{ - int r; - - if (vdec->set_trickmode) { - r = vdec->set_trickmode(vdec, trickmode); - - if ((r == 0) && (vdec->slave) && (vdec->slave->set_trickmode)) - r = vdec->slave->set_trickmode(vdec->slave, - trickmode); - } - - return -1; -} -EXPORT_SYMBOL(vdec_set_trickmode); - -/* -* clk_config: - *0:default - *1:no gp0_pll; - *2:always used gp0_pll; - *>=10:fixed n M clk; - *== 100 , 100M clks; -*/ -unsigned int get_vdec_clk_config_settings(void) -{ - return clk_config; -} -void update_vdec_clk_config_settings(unsigned int config) -{ - clk_config = config; -} -EXPORT_SYMBOL(update_vdec_clk_config_settings); - -static bool hevc_workaround_needed(void) -{ - return (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) && - (get_meson_cpu_version(MESON_CPU_VERSION_LVL_MINOR) - == GXBB_REV_A_MINOR); -} - -struct device *get_codec_cma_device(void) -{ - return vdec_core->cma_dev; -} - -static unsigned int get_mmu_mode(void) -{ - return 1;//DEBUG_TMP -} - -#ifdef CONFIG_MULTI_DEC -static const char * const vdec_device_name[] = { - "amvdec_mpeg12", "ammvdec_mpeg12", - "amvdec_mpeg4", "ammvdec_mpeg4", - "amvdec_h264", "ammvdec_h264", - "amvdec_mjpeg", "ammvdec_mjpeg", - "amvdec_real", "ammvdec_real", - "amjpegdec", "ammjpegdec", - "amvdec_vc1", "ammvdec_vc1", - "amvdec_avs", "ammvdec_avs", - "amvdec_yuv", "ammvdec_yuv", - "amvdec_h264mvc", "ammvdec_h264mvc", - "amvdec_h264_4k2k", "ammvdec_h264_4k2k", - "amvdec_h265", "ammvdec_h265", - "amvenc_avc", "amvenc_avc", - "jpegenc", "jpegenc", - "amvdec_vp9", "ammvdec_vp9" -}; - -static int vdec_default_buf_size[] = { - 32, 32, /*"amvdec_mpeg12",*/ - 32, 0, /*"amvdec_mpeg4",*/ - 48, 0, /*"amvdec_h264",*/ - 32, 32, /*"amvdec_mjpeg",*/ - 32, 32, /*"amvdec_real",*/ - 32, 32, /*"amjpegdec",*/ - 32, 32, /*"amvdec_vc1",*/ - 32, 32, /*"amvdec_avs",*/ - 32, 32, /*"amvdec_yuv",*/ - 64, 64, /*"amvdec_h264mvc",*/ - 64, 64, /*"amvdec_h264_4k2k", else alloc on decoder*/ - 48, 48, /*"amvdec_h265", else alloc on decoder*/ - 0, 0, /* avs encoder */ - 0, 0, /* jpg encoder */ -#ifdef VP9_10B_MMU - 24, 24, /*"amvdec_vp9", else alloc on decoder*/ -#else - 32, 32, -#endif - 0 -}; - -#else - -static const char * const vdec_device_name[] = { - "amvdec_mpeg12", - "amvdec_mpeg4", - "amvdec_h264", - "amvdec_mjpeg", - "amvdec_real", - "amjpegdec", - "amvdec_vc1", - "amvdec_avs", - "amvdec_yuv", - "amvdec_h264mvc", - "amvdec_h264_4k2k", - "amvdec_h265", - "amvenc_avc", - "jpegenc", - "amvdec_vp9" -}; - -static int vdec_default_buf_size[] = { - 32, /*"amvdec_mpeg12",*/ - 32, /*"amvdec_mpeg4",*/ - 48, /*"amvdec_h264",*/ - 32, /*"amvdec_mjpeg",*/ - 32, /*"amvdec_real",*/ - 32, /*"amjpegdec",*/ - 32, /*"amvdec_vc1",*/ - 32, /*"amvdec_avs",*/ - 32, /*"amvdec_yuv",*/ - 64, /*"amvdec_h264mvc",*/ - 64, /*"amvdec_h264_4k2k", else alloc on decoder*/ - 48, /*"amvdec_h265", else alloc on decoder*/ - 0, /* avs encoder */ - 0, /* jpg encoder */ -#ifdef VP9_10B_MMU - 24, /*"amvdec_vp9", else alloc on decoder*/ -#else - 32, -#endif -}; -#endif - -int vdec_set_decinfo(struct vdec_s *vdec, struct dec_sysinfo *p) -{ - if (copy_from_user((void *)&vdec->sys_info_store, (void *)p, - sizeof(struct dec_sysinfo))) - return -EFAULT; - - return 0; -} -EXPORT_SYMBOL(vdec_set_decinfo); - -/* construct vdec strcture */ -struct vdec_s *vdec_create(struct stream_port_s *port, - struct vdec_s *master) -{ - struct vdec_s *vdec; - int type = VDEC_TYPE_SINGLE; - - if (port->type & PORT_TYPE_DECODER_SCHED) - type = (port->type & PORT_TYPE_FRAME) ? - VDEC_TYPE_FRAME_BLOCK : - VDEC_TYPE_STREAM_PARSER; - - vdec = vzalloc(sizeof(struct vdec_s)); - - /* TBD */ - if (vdec) { - vdec->magic = 0x43454456; - vdec->id = 0; - vdec->type = type; - vdec->port = port; - vdec->sys_info = &vdec->sys_info_store; - - INIT_LIST_HEAD(&vdec->list); - - vdec_input_init(&vdec->input, vdec); - - atomic_inc(&vdec_core->vdec_nr); - - if (master) { - vdec->master = master; - master->slave = vdec; - master->sched = 1; - } - } - - pr_info("vdec_create instance %p, total %d\n", vdec, - atomic_read(&vdec_core->vdec_nr)); - - return vdec; -} -EXPORT_SYMBOL(vdec_create); - -int vdec_set_format(struct vdec_s *vdec, int format) -{ - vdec->format = format; - - if (vdec->slave) - vdec->slave->format = format; - - return 0; -} -EXPORT_SYMBOL(vdec_set_format); - -int vdec_set_pts(struct vdec_s *vdec, u32 pts) -{ - vdec->pts = pts; - vdec->pts_valid = true; - return 0; -} -EXPORT_SYMBOL(vdec_set_pts); - -int vdec_set_pts64(struct vdec_s *vdec, u64 pts64) -{ - vdec->pts64 = pts64; - vdec->pts_valid = true; - return 0; -} -EXPORT_SYMBOL(vdec_set_pts64); - -void vdec_set_status(struct vdec_s *vdec, int status) -{ - vdec->status = status; -} -EXPORT_SYMBOL(vdec_set_status); - -void vdec_set_next_status(struct vdec_s *vdec, int status) -{ - vdec->next_status = status; -} -EXPORT_SYMBOL(vdec_set_next_status); - -int vdec_set_video_path(struct vdec_s *vdec, int video_path) -{ - vdec->frame_base_video_path = video_path; - return 0; -} -EXPORT_SYMBOL(vdec_set_video_path); - -/* add frame data to input chain */ -int vdec_write_vframe(struct vdec_s *vdec, const char *buf, size_t count) -{ - return vdec_input_add_frame(&vdec->input, buf, count); -} -EXPORT_SYMBOL(vdec_write_vframe); - -/* -*get next frame from input chain -*/ -/* -*THE VLD_FIFO is 512 bytes and Video buffer level - * empty interrupt is set to 0x80 bytes threshold - */ -#define VLD_PADDING_SIZE 1024 -#define HEVC_PADDING_SIZE (1024*16) -#define FIFO_ALIGN 8 -int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p) -{ - struct vdec_input_s *input = (vdec->master) ? - &vdec->master->input : &vdec->input; - struct vframe_chunk_s *chunk = NULL; - struct vframe_block_list_s *block = NULL; - int dummy; - - /* full reset to HW input */ - if (input->target == VDEC_INPUT_TARGET_VLD) { - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0); - - /* reset VLD fifo for all vdec */ - WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3)); - WRITE_VREG(DOS_SW_RESET0, 0); - - dummy = READ_MPEG_REG(RESET0_REGISTER); - WRITE_VREG(POWER_CTL_VLD, 1 << 4); - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { -#if 0 - /*move to driver*/ - if (input_frame_based(input)) - WRITE_VREG(HEVC_STREAM_CONTROL, 0); - - /* - * 2: assist - * 3: parser - * 4: parser_state - * 8: dblk - * 11:mcpu - * 12:ccpu - * 13:ddr - * 14:iqit - * 15:ipp - * 17:qdct - * 18:mpred - * 19:sao - * 24:hevc_afifo - */ - 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)); - WRITE_VREG(DOS_SW_RESET3, 0); -#endif - } - - /* - *setup HW decoder input buffer (VLD context) - * based on input->type and input->target - */ - if (input_frame_based(input)) { - chunk = vdec_input_next_chunk(&vdec->input); - - if (chunk == NULL) { - *p = NULL; - return -1; - } - - block = chunk->block; - - if (input->target == VDEC_INPUT_TARGET_VLD) { - WRITE_VREG(VLD_MEM_VIFIFO_START_PTR, block->start); - WRITE_VREG(VLD_MEM_VIFIFO_END_PTR, block->start + - block->size - 8); - WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR, - round_down(block->start + chunk->offset, - FIFO_ALIGN)); - - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1); - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0); - - /* set to manual mode */ - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2); - WRITE_VREG(VLD_MEM_VIFIFO_RP, - round_down(block->start + chunk->offset, - FIFO_ALIGN)); - dummy = chunk->offset + chunk->size + - VLD_PADDING_SIZE; - if (dummy >= block->size) - dummy -= block->size; - WRITE_VREG(VLD_MEM_VIFIFO_WP, - round_down(block->start + dummy, FIFO_ALIGN)); - - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 3); - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2); - - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, - (0x11 << 16) | (1<<10) | (7<<3)); - - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - 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 + - chunk->offset); - dummy = chunk->offset + chunk->size + - HEVC_PADDING_SIZE; - if (dummy >= block->size) - dummy -= block->size; - WRITE_VREG(HEVC_STREAM_WR_PTR, - round_down(block->start + dummy, FIFO_ALIGN)); - - /* set endian */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, 7 << 4); - } - - *p = chunk; - return chunk->size; - - } else { - u32 rp = 0, wp = 0, fifo_len = 0; - int size; - /* stream based */ - if (input->swap_valid) { - if (input->target == VDEC_INPUT_TARGET_VLD) { - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0); - - /* restore read side */ - WRITE_VREG(VLD_MEM_SWAP_ADDR, - page_to_phys(input->swap_page)); - WRITE_VREG(VLD_MEM_SWAP_CTL, 1); - - while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7)) - ; - WRITE_VREG(VLD_MEM_SWAP_CTL, 0); - - /* restore wrap count */ - WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, - input->stream_cookie); - - rp = READ_VREG(VLD_MEM_VIFIFO_RP); - fifo_len = READ_VREG(VLD_MEM_VIFIFO_LEVEL); - - /* enable */ - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, - (0x11 << 16) | (1<<10)); - - /* update write side */ - WRITE_VREG(VLD_MEM_VIFIFO_WP, - READ_MPEG_REG(PARSER_VIDEO_WP)); - - wp = READ_VREG(VLD_MEM_VIFIFO_WP); - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); - - /* restore read side */ - WRITE_VREG(HEVC_STREAM_SWAP_ADDR, - page_to_phys(input->swap_page)); - WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 1); - - while (READ_VREG(HEVC_STREAM_SWAP_CTRL) - & (1<<7)) - ; - WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0); - - /* restore stream offset */ - WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, - input->stream_cookie); - - rp = READ_VREG(HEVC_STREAM_RD_PTR); - fifo_len = (READ_VREG(HEVC_STREAM_FIFO_CTL) - >> 16) & 0x7f; - - - /* enable */ - - /* update write side */ - WRITE_VREG(HEVC_STREAM_WR_PTR, - READ_MPEG_REG(PARSER_VIDEO_WP)); - - wp = READ_VREG(HEVC_STREAM_WR_PTR); - } - - } else { - if (input->target == VDEC_INPUT_TARGET_VLD) { - WRITE_VREG(VLD_MEM_VIFIFO_START_PTR, - input->start); - WRITE_VREG(VLD_MEM_VIFIFO_END_PTR, - input->start + input->size - 8); - WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR, - input->start); - - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1); - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0); - - /* set to manual mode */ - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2); - WRITE_VREG(VLD_MEM_VIFIFO_RP, input->start); - WRITE_VREG(VLD_MEM_VIFIFO_WP, - READ_MPEG_REG(PARSER_VIDEO_WP)); - - rp = READ_VREG(VLD_MEM_VIFIFO_RP); - - /* enable */ - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, - (0x11 << 16) | (1<<10)); - - wp = READ_VREG(VLD_MEM_VIFIFO_WP); - - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - WRITE_VREG(HEVC_STREAM_START_ADDR, - input->start); - WRITE_VREG(HEVC_STREAM_END_ADDR, - input->start + input->size); - WRITE_VREG(HEVC_STREAM_RD_PTR, - input->start); - WRITE_VREG(HEVC_STREAM_WR_PTR, - READ_MPEG_REG(PARSER_VIDEO_WP)); - - rp = READ_VREG(HEVC_STREAM_RD_PTR); - wp = READ_VREG(HEVC_STREAM_WR_PTR); - fifo_len = (READ_VREG(HEVC_STREAM_FIFO_CTL) - >> 16) & 0x7f; - - /* enable */ - } - } - *p = NULL; - if (wp >= rp) - size = wp - rp + fifo_len; - else - size = wp + input->size - rp + fifo_len; - if (size < 0) { - pr_info("%s error: input->size %x wp %x rp %x fifo_len %x => size %x\r\n", - __func__, input->size, wp, rp, fifo_len, size); - size = 0; - } - return size; - } -} -EXPORT_SYMBOL(vdec_prepare_input); - -void vdec_enable_input(struct vdec_s *vdec) -{ - struct vdec_input_s *input = &vdec->input; - - if (vdec->status != VDEC_STATUS_ACTIVE) - return; - - if (input->target == VDEC_INPUT_TARGET_VLD) - SET_VREG_MASK(VLD_MEM_VIFIFO_CONTROL, (1<<2) | (1<<1)); - else if (input->target == VDEC_INPUT_TARGET_HEVC) { - SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); - if (vdec_stream_based(vdec)) - CLEAR_VREG_MASK(HEVC_STREAM_CONTROL, 7 << 4); - else - SET_VREG_MASK(HEVC_STREAM_CONTROL, 7 << 4); - SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, (1<<29)); - } -} -EXPORT_SYMBOL(vdec_enable_input); - -void vdec_set_flag(struct vdec_s *vdec, u32 flag) -{ - vdec->flag = flag; -} - -void vdec_set_next_sched(struct vdec_s *vdec, struct vdec_s *next_vdec) -{ - if (vdec && next_vdec) { - vdec->sched = 0; - next_vdec->sched = 1; - } -} -void vdec_vframe_dirty(struct vdec_s *vdec, struct vframe_chunk_s *chunk) -{ - if (chunk) - chunk->flag |= VFRAME_CHUNK_FLAG_CONSUMED; - - if (vdec_stream_based(vdec)) { - if (vdec->slave && - ((vdec->slave->flag & - VDEC_FLAG_INPUT_KEEP_CONTEXT) == 0)) { - vdec->input.swap_needed = false; - } else - vdec->input.swap_needed = true; - - if (vdec->input.target == VDEC_INPUT_TARGET_VLD) { - WRITE_MPEG_REG(PARSER_VIDEO_RP, - READ_VREG(VLD_MEM_VIFIFO_RP)); - WRITE_VREG(VLD_MEM_VIFIFO_WP, - READ_MPEG_REG(PARSER_VIDEO_WP)); - } else if (vdec->input.target == VDEC_INPUT_TARGET_HEVC) { - WRITE_MPEG_REG(PARSER_VIDEO_RP, - READ_VREG(HEVC_STREAM_RD_PTR)); - WRITE_VREG(HEVC_STREAM_WR_PTR, - READ_MPEG_REG(PARSER_VIDEO_WP)); - } - } -} -EXPORT_SYMBOL(vdec_vframe_dirty); - -void vdec_save_input_context(struct vdec_s *vdec) -{ - struct vdec_input_s *input = (vdec->master) ? - &vdec->master->input : &vdec->input; - -#ifdef CONFIG_MULTI_DEC - vdec_profile(vdec, VDEC_PROFILE_EVENT_SAVE_INPUT); -#endif - - if (input->target == VDEC_INPUT_TARGET_VLD) - WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1<<15); - - if (input_stream_based(input) && (input->swap_needed)) { - if (input->target == VDEC_INPUT_TARGET_VLD) { - WRITE_VREG(VLD_MEM_SWAP_ADDR, - page_to_phys(input->swap_page)); - WRITE_VREG(VLD_MEM_SWAP_CTL, 3); - while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7)) - ; - WRITE_VREG(VLD_MEM_SWAP_CTL, 0); - vdec->input.stream_cookie = - READ_VREG(VLD_MEM_VIFIFO_WRAP_COUNT); - } else if (input->target == VDEC_INPUT_TARGET_HEVC) { - WRITE_VREG(HEVC_STREAM_SWAP_ADDR, - page_to_phys(input->swap_page)); - WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 3); - - while (READ_VREG(HEVC_STREAM_SWAP_CTRL) & (1<<7)) - ; - WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0); - - vdec->input.stream_cookie = - READ_VREG(HEVC_SHIFT_BYTE_COUNT); - } - - input->swap_valid = true; - - if (input->target == VDEC_INPUT_TARGET_VLD) - WRITE_MPEG_REG(PARSER_VIDEO_RP, - READ_VREG(VLD_MEM_VIFIFO_RP)); - else - WRITE_MPEG_REG(PARSER_VIDEO_RP, - READ_VREG(HEVC_STREAM_RD_PTR)); - } -} -EXPORT_SYMBOL(vdec_save_input_context); - -void vdec_clean_input(struct vdec_s *vdec) -{ - struct vdec_input_s *input = &vdec->input; - - while (!list_empty(&input->vframe_chunk_list)) { - struct vframe_chunk_s *chunk = - vdec_input_next_chunk(input); - if (chunk->flag & VFRAME_CHUNK_FLAG_CONSUMED) - vdec_input_release_chunk(input, chunk); - else - break; - } - vdec_save_input_context(vdec); -} -EXPORT_SYMBOL(vdec_clean_input); - -const char *vdec_status_str(struct vdec_s *vdec) -{ - switch (vdec->status) { - case VDEC_STATUS_UNINITIALIZED: - return "VDEC_STATUS_UNINITIALIZED"; - case VDEC_STATUS_DISCONNECTED: - return "VDEC_STATUS_DISCONNECTED"; - case VDEC_STATUS_CONNECTED: - return "VDEC_STATUS_CONNECTED"; - case VDEC_STATUS_ACTIVE: - return "VDEC_STATUS_ACTIVE"; - default: - return "invalid status"; - } -} - -const char *vdec_type_str(struct vdec_s *vdec) -{ - switch (vdec->type) { - case VDEC_TYPE_SINGLE: - return "VDEC_TYPE_SINGLE"; - case VDEC_TYPE_STREAM_PARSER: - return "VDEC_TYPE_STREAM_PARSER"; - case VDEC_TYPE_FRAME_BLOCK: - return "VDEC_TYPE_FRAME_BLOCK"; - case VDEC_TYPE_FRAME_CIRCULAR: - return "VDEC_TYPE_FRAME_CIRCULAR"; - default: - return "VDEC_TYPE_INVALID"; - } -} - -const char *vdec_device_name_str(struct vdec_s *vdec) -{ - return vdec_device_name[vdec->format * 2 + 1]; -} - -void walk_vdec_core_list(char *s) -{ - struct vdec_s *vdec; - struct vdec_core_s *core = vdec_core; - unsigned long flags; - - pr_info("%s --->\n", s); - - flags = vdec_core_lock(vdec_core); - - if (list_empty(&core->connected_vdec_list)) { - pr_info("connected vdec list empty\n"); - } else { - list_for_each_entry(vdec, &core->connected_vdec_list, list) { - pr_info("\tvdec (%p), status = %s\n", vdec, - vdec_status_str(vdec)); - } - } - - vdec_core_unlock(vdec_core, flags); -} -EXPORT_SYMBOL(walk_vdec_core_list); - -/* insert vdec to vdec_core for scheduling */ -int vdec_connect(struct vdec_s *vdec) -{ - unsigned long flags; - - if (vdec->status != VDEC_STATUS_DISCONNECTED) - return 0; - - vdec_set_status(vdec, VDEC_STATUS_CONNECTED); - vdec_set_next_status(vdec, VDEC_STATUS_CONNECTED); - - init_completion(&vdec->inactive_done); - - if (vdec->slave) { - vdec_set_status(vdec->slave, VDEC_STATUS_CONNECTED); - vdec_set_next_status(vdec->slave, VDEC_STATUS_CONNECTED); - - init_completion(&vdec->slave->inactive_done); - } - - flags = vdec_core_lock(vdec_core); - - list_add_tail(&vdec->list, &vdec_core->connected_vdec_list); - - if (vdec->slave) { - list_add_tail(&vdec->slave->list, - &vdec_core->connected_vdec_list); - } - - vdec_core_unlock(vdec_core, flags); - - up(&vdec_core->sem); - - return 0; -} -EXPORT_SYMBOL(vdec_connect); - -/* remove vdec from vdec_core scheduling */ -int vdec_disconnect(struct vdec_s *vdec) -{ -#ifdef CONFIG_MULTI_DEC - vdec_profile(vdec, VDEC_PROFILE_EVENT_DISCONNECT); -#endif - - if ((vdec->status != VDEC_STATUS_CONNECTED) && - (vdec->status != VDEC_STATUS_ACTIVE)) { - return 0; - } - - /* - *when a vdec is under the management of scheduler - * the status change will only be from vdec_core_thread - */ - vdec_set_next_status(vdec, VDEC_STATUS_DISCONNECTED); - - if (vdec->slave) - vdec_set_next_status(vdec->slave, VDEC_STATUS_DISCONNECTED); - else if (vdec->master) - vdec_set_next_status(vdec->master, VDEC_STATUS_DISCONNECTED); - - up(&vdec_core->sem); - - wait_for_completion(&vdec->inactive_done); - - if (vdec->slave) - wait_for_completion(&vdec->slave->inactive_done); - else if (vdec->master) - wait_for_completion(&vdec->master->inactive_done); - - return 0; -} -EXPORT_SYMBOL(vdec_disconnect); - -/* release vdec structure */ -int vdec_destroy(struct vdec_s *vdec) -{ - if (!vdec->master) - vdec_input_release(&vdec->input); - -#ifdef CONFIG_MULTI_DEC - vdec_profile_flush(vdec); -#endif - - vfree(vdec); - - atomic_dec(&vdec_core->vdec_nr); - - return 0; -} -EXPORT_SYMBOL(vdec_destroy); - -/* - * Only support time sliced decoding for frame based input, - * so legacy decoder can exist with time sliced decoder. - */ -static const char *get_dev_name(bool use_legacy_vdec, int format) -{ -#ifdef CONFIG_MULTI_DEC - if (use_legacy_vdec) - return vdec_device_name[format * 2]; - else - return vdec_device_name[format * 2 + 1]; -#else - return vdec_device_name[format]; -#endif -} - -void vdec_free_cmabuf(void) -{ - mutex_lock(&vdec_mutex); - - if (inited_vcodec_num > 0) { - mutex_unlock(&vdec_mutex); - return; - } - - if (vdec_mem_alloced_from_codec && vdec_core->mem_start) { - codec_mm_free_for_dma(MEM_NAME, vdec_core->mem_start); - vdec_cma_page = NULL; - vdec_core->mem_start = reserved_mem_start; - vdec_core->mem_end = reserved_mem_end; - pr_info("force free vdec memory\n"); - } - - mutex_unlock(&vdec_mutex); -} - -/* -*register vdec_device - * create output, vfm or create ionvideo output - */ -s32 vdec_init(struct vdec_s *vdec, int is_4k) -{ - int r = 0; - struct vdec_s *p = vdec; - int retry_num = 0; - int more_buffers = 0; - const char *dev_name; - - if (is_4k && vdec->format < VFORMAT_H264) { - /* - *old decoder don't support 4k - * but size is bigger; - * clear 4k flag, and used more buffers; - */ - more_buffers = 1; - is_4k = 0; - } - - dev_name = get_dev_name(vdec_single(vdec), vdec->format); - - if (dev_name == NULL) - return -ENODEV; - - pr_info("vdec_init, dev_name:%s, vdec_type=%s\n", - dev_name, vdec_type_str(vdec)); - - /* - *todo: VFM patch control should be configurable, - * for now all stream based input uses default VFM path. - */ - if (vdec_stream_based(vdec) && !vdec_dual(vdec)) { - if (vdec_core->vfm_vdec == NULL) { - pr_info("vdec_init set vfm decoder %p\n", vdec); - vdec_core->vfm_vdec = vdec; - } else { - pr_info("vdec_init vfm path busy.\n"); - return -EBUSY; - } - } - - if (vdec_single(vdec) && - ((vdec->format == VFORMAT_H264_4K2K) || - (vdec->format == VFORMAT_HEVC && is_4k))) { - try_free_keep_video(0); - } - - /* - *when blackout_policy was set, vdec would not free cma buffer, if - * current vformat require larger buffer size than current - * buf size, reallocated it - */ - if (vdec_single(vdec) && - ((vdec_core->mem_start != vdec_core->mem_end && - vdec_core->mem_end - vdec_core->mem_start + 1 < - vdec_default_buf_size[vdec->format] * SZ_1M))) { -#ifdef CONFIG_MULTI_DEC - pr_info("current vdec size %ld, vformat %d need size %d\n", - vdec_core->mem_end - vdec_core->mem_start, - vdec->format, - vdec_default_buf_size[vdec->format * 2] * SZ_1M); -#else - pr_info("current vdec size %ld, vformat %d need size %d\n", - vdec_core->mem_end - vdec_core->mem_start, - vdec->format, - vdec_default_buf_size[vdec->format] * SZ_1M); -#endif - try_free_keep_video(0); - vdec_free_cmabuf(); - } - - mutex_lock(&vdec_mutex); - inited_vcodec_num++; - mutex_unlock(&vdec_mutex); - - vdec_input_set_type(&vdec->input, vdec->type, - (vdec->format == VFORMAT_HEVC || - vdec->format == VFORMAT_VP9) ? - VDEC_INPUT_TARGET_HEVC : - VDEC_INPUT_TARGET_VLD); - - p->cma_dev = vdec_core->cma_dev; - p->get_canvas = get_canvas; - /* todo */ - if (!vdec_dual(vdec)) - p->use_vfm_path = vdec_stream_based(vdec); - - if (vdec_single(vdec)) { - pr_info("vdec_dev_reg.mem[0x%lx -- 0x%lx]\n", - vdec_core->mem_start, - vdec_core->mem_end); - p->mem_start = vdec_core->mem_start; - p->mem_end = vdec_core->mem_end; - } - - /* allocate base memory for decoder instance */ - while ((p->mem_start == p->mem_end) && (vdec_single(vdec))) { - int alloc_size; - -#ifdef CONFIG_MULTI_DEC - alloc_size = - vdec_default_buf_size[vdec->format * 2 + 1] - * SZ_1M; -#else - alloc_size = vdec_default_buf_size[vdec->format] * SZ_1M; -#endif - if (alloc_size == 0) - break;/*alloc end*/ - if (is_4k) { - /*used 264 4k's setting for 265.*/ -#ifdef CONFIG_MULTI_DEC - int m4k_size = - vdec_default_buf_size[VFORMAT_H264_4K2K * 2] * - SZ_1M; -#else - int m4k_size = - vdec_default_buf_size[VFORMAT_H264_4K2K] * - SZ_1M; -#endif - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) - m4k_size = 32 * SZ_1M; - if ((m4k_size > 0) && (m4k_size < 200 * SZ_1M)) - alloc_size = m4k_size; - -#ifdef VP9_10B_MMU - if ((vdec->format == VFORMAT_VP9) && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { -#ifdef CONFIG_MULTI_DEC - if (p->use_vfm_path) - alloc_size = - vdec_default_buf_size[VFORMAT_VP9 * 2] - * SZ_1M; - else - alloc_size = - vdec_default_buf_size[VFORMAT_VP9 - * 2 + 1] * SZ_1M; - -#else - alloc_size = - vdec_default_buf_size[VFORMAT_VP9] * SZ_1M; -#endif - } -#endif - } else if (more_buffers) { - alloc_size = alloc_size + 16 * SZ_1M; - } - - if ((vdec->format == VFORMAT_HEVC) - && get_mmu_mode() - && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { -#ifdef CONFIG_MULTI_DEC - if (p->use_vfm_path) - alloc_size = 33 * SZ_1M; - else - alloc_size = 33 * SZ_1M; -#else - alloc_size = 33 * SZ_1M; -#endif - } - - if ((vdec->format == VFORMAT_H264) - && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - && codec_mm_get_total_size() <= 80 * SZ_1M) { -#ifdef CONFIG_MULTI_DEC - if (p->use_vfm_path) - alloc_size = 32 * SZ_1M; - else - alloc_size = 32 * SZ_1M; -#else - alloc_size = 32 * SZ_1M; -#endif - } - - - p->mem_start = codec_mm_alloc_for_dma(MEM_NAME, - alloc_size / PAGE_SIZE, 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_CPU | - CODEC_MM_FLAGS_FOR_VDECODER); - if (!p->mem_start) { - if (retry_num < 1) { - pr_err("vdec base CMA allocation failed,try again\\n"); - retry_num++; - try_free_keep_video(0); - continue;/*retry alloc*/ - } - pr_err("vdec base CMA allocation failed.\n"); - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - - return -ENOMEM; - } - - p->mem_end = p->mem_start + alloc_size - 1; - pr_info("vdec base memory alloced [%p -- %p]\n", - (void *)p->mem_start, - (void *)p->mem_end); - - break;/*alloc end*/ - } - - if (vdec_single(vdec)) { - vdec_core->mem_start = p->mem_start; - vdec_core->mem_end = p->mem_end; - vdec_mem_alloced_from_codec = 1; - } - -/*alloc end:*/ - /* vdec_dev_reg.flag = 0; */ - - p->dev = - platform_device_register_data( - &vdec_core->vdec_core_platform_device->dev, - dev_name, - PLATFORM_DEVID_AUTO, - &p, sizeof(struct vdec_s *)); - - if (IS_ERR(p->dev)) { - r = PTR_ERR(p->dev); - pr_err("vdec: Decoder device %s register failed (%d)\n", - dev_name, r); - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - - goto error; - } - - if ((p->type == VDEC_TYPE_FRAME_BLOCK) && (p->run == NULL)) { - r = -ENODEV; - pr_err("vdec: Decoder device not handled (%s)\n", dev_name); - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - - goto error; - } - - if (p->use_vfm_path) { - vdec->vf_receiver_inst = -1; - } else if (!vdec_dual(vdec)) { - /* create IONVIDEO instance and connect decoder's - * vf_provider interface to it - */ - if (p->type != VDEC_TYPE_FRAME_BLOCK) { - r = -ENODEV; - pr_err("vdec: Incorrect decoder type\n"); - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - - goto error; - } - if (p->frame_base_video_path == FRAME_BASE_PATH_IONVIDEO) { -#if 1 - //r = ionvideo_alloc_map(&vdec->vf_receiver_name, - //&vdec->vf_receiver_inst);//DEBUG_TMP -#else - /* - * temporarily just use decoder instance ID as iondriver ID - * to solve OMX iondriver instance number check time sequence - * only the limitation is we can NOT mix different video - * decoders since same ID will be used for different decoder - * formats. - */ - vdec->vf_receiver_inst = p->dev->id; - r = ionvideo_assign_map(&vdec->vf_receiver_name, - &vdec->vf_receiver_inst); -#endif - if (r < 0) { - pr_err("IonVideo 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, - "%s-%s", vdec->vf_provider_name, - vdec->vf_receiver_name); - - } else if (p->frame_base_video_path == - FRAME_BASE_PATH_AMLVIDEO_AMVIDEO) { - snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s", vdec->vf_provider_name, - "amlvideo.0 amvideo"); - snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, - "%s-%s", vdec->vf_provider_name, - "amlvideo.0 amvideo"); - } else if (p->frame_base_video_path == - FRAME_BASE_PATH_AMLVIDEO1_AMVIDEO2) { - snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE, - "%s %s", vdec->vf_provider_name, - "ppmgr amlvideo.1 amvide2"); - snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE, - "%s-%s", vdec->vf_provider_name, - "ppmgr amlvideo.1 amvide2"); - } - - if (vfm_map_add(vdec->vfm_map_id, - vdec->vfm_map_chain) < 0) { - r = -ENOMEM; - pr_err("Decoder pipeline map creation failed %s.\n", - vdec->vfm_map_id); - vdec->vfm_map_id[0] = 0; - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); - - goto error; - } - - pr_info("vfm map %s created\n", vdec->vfm_map_id); - - /* - *assume IONVIDEO driver already have a few vframe_receiver - * registered. - * 1. Call iondriver function to allocate a IONVIDEO path and - * provide receiver's name and receiver op. - * 2. Get decoder driver's provider name from driver instance - * 3. vfm_map_add(name, "<decoder provider name> - * <iondriver receiver name>"), e.g. - * vfm_map_add("vdec_ion_map_0", "mpeg4_0 iondriver_1"); - * 4. vf_reg_provider and vf_reg_receiver - * Note: the decoder provider's op uses vdec as op_arg - * the iondriver receiver's op uses iondev device as - * op_arg - */ - - } - - if (!vdec_single(vdec)) { - vf_reg_provider(&p->vframe_provider); - - vf_notify_receiver(p->vf_provider_name, - VFRAME_EVENT_PROVIDER_START, - vdec); - } - - pr_info("vdec_init, vf_provider_name = %s\n", p->vf_provider_name); - - /* vdec is now ready to be active */ - vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED); - - return 0; - -error: - return r; -} -EXPORT_SYMBOL(vdec_init); - -void vdec_release(struct vdec_s *vdec) -{ - vdec_disconnect(vdec); - - if (vdec->vframe_provider.name) - vf_unreg_provider(&vdec->vframe_provider); - - if (vdec_core->vfm_vdec == vdec) - vdec_core->vfm_vdec = NULL; - - if (vdec->vf_receiver_inst >= 0) { - if (vdec->vfm_map_id[0]) { - vfm_map_remove(vdec->vfm_map_id); - vdec->vfm_map_id[0] = 0; - } - - /* - *vf_receiver_inst should be > 0 since 0 is - * for either un-initialized vdec or a ionvideo - * instance reserved for legacy path. - */ - //ionvideo_release_map(vdec->vf_receiver_inst);//DEBUG_TMP - } - - platform_device_unregister(vdec->dev); - - if (!vdec->use_vfm_path) { - if (vdec->mem_start) { - codec_mm_free_for_dma(MEM_NAME, vdec->mem_start); - vdec->mem_start = 0; - vdec->mem_end = 0; - } - } else if (delay_release-- <= 0 && - !keep_vdec_mem && - vdec_mem_alloced_from_codec && - vdec_core->mem_start && - get_blackout_policy()) { - codec_mm_free_for_dma(MEM_NAME, vdec_core->mem_start); - vdec_cma_page = NULL; - vdec_core->mem_start = reserved_mem_start; - vdec_core->mem_end = reserved_mem_end; - } - - vdec_destroy(vdec); - - mutex_lock(&vdec_mutex); - inited_vcodec_num--; - mutex_unlock(&vdec_mutex); -} -EXPORT_SYMBOL(vdec_release); - -int vdec_reset(struct vdec_s *vdec) -{ - vdec_disconnect(vdec); - - 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->reset) { - vdec->reset(vdec); - if (vdec->slave) - vdec->slave->reset(vdec->slave); - } - - vdec_input_release(&vdec->input); - - 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_connect(vdec); - - return 0; -} -EXPORT_SYMBOL(vdec_reset); - -static struct vdec_s *active_vdec(struct vdec_core_s *core) -{ - struct vdec_s *vdec; - struct list_head *p; - - list_for_each(p, &core->connected_vdec_list) { - vdec = list_entry(p, struct vdec_s, list); - if (vdec->status == VDEC_STATUS_ACTIVE) - return vdec; - } - - return NULL; -} - -/* -*Decoder callback - * Each decoder instance uses this callback to notify status change, e.g. when - * decoder finished using HW resource. - * a sample callback from decoder's driver is following: - * - * if (hw->vdec_cb) { - * vdec_set_next_status(vdec, VDEC_STATUS_CONNECTED); - * hw->vdec_cb(vdec, hw->vdec_cb_arg); - * } - */ -static void vdec_callback(struct vdec_s *vdec, void *data) -{ - struct vdec_core_s *core = (struct vdec_core_s *)data; - -#ifdef CONFIG_MULTI_DEC - vdec_profile(vdec, VDEC_PROFILE_EVENT_CB); -#endif - - up(&core->sem); -} - -static irqreturn_t vdec_isr(int irq, void *dev_id) -{ - struct vdec_isr_context_s *c = - (struct vdec_isr_context_s *)dev_id; - struct vdec_s *vdec = vdec_core->active_vdec; - - if (c->dev_isr) - return c->dev_isr(irq, c->dev_id); - - if (c != &vdec_core->isr_context[VDEC_IRQ_1]) { -#if 0 - pr_warn("vdec interrupt w/o a valid receiver\n"); -#endif - return IRQ_HANDLED; - } - - if (!vdec) { -#if 0 - pr_warn("vdec interrupt w/o an active instance running. core = %p\n", - core); -#endif - return IRQ_HANDLED; - } - - if (!vdec->irq_handler) { -#if 0 - pr_warn("vdec instance has no irq handle.\n"); -#endif - return IRQ_HANDLED; - } - - return vdec->irq_handler(vdec); -} - -static irqreturn_t vdec_thread_isr(int irq, void *dev_id) -{ - struct vdec_isr_context_s *c = - (struct vdec_isr_context_s *)dev_id; - struct vdec_s *vdec = vdec_core->active_vdec; - - if (c->dev_threaded_isr) - return c->dev_threaded_isr(irq, c->dev_id); - - if (!vdec) - return IRQ_HANDLED; - - if (!vdec->threaded_irq_handler) - return IRQ_HANDLED; - - return vdec->threaded_irq_handler(vdec); -} - -static inline bool vdec_ready_to_run(struct vdec_s *vdec) -{ - bool r; - - if (vdec->status != VDEC_STATUS_CONNECTED) - return false; - - if (!vdec->run_ready) - return false; - - if ((vdec->slave || vdec->master) && - (vdec->sched == 0)) - return false; - - if (step_mode) { - if ((step_mode & 0xff) != vdec->id) - return false; - } - - step_mode &= ~0xff; - -#ifdef CONFIG_MULTI_DEC - vdec_profile(vdec, VDEC_PROFILE_EVENT_CHK_RUN_READY); -#endif - - r = vdec->run_ready(vdec); - -#ifdef CONFIG_MULTI_DEC - if (r) - vdec_profile(vdec, VDEC_PROFILE_EVENT_RUN_READY); -#endif - - return r; -} - -/* 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) - * VDEC_STATUS_ACTIVE(the decoder owns HW resources and is running). - * Removing a decoder from active list is only performed within core thread. - * Adding a decoder into active list is performed from user thread. - */ -static int vdec_core_thread(void *data) -{ - unsigned long flags; - struct vdec_core_s *core = (struct vdec_core_s *)data; - - struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1}; - - sched_setscheduler(current, SCHED_FIFO, ¶m); - - allow_signal(SIGTERM); - - while (down_interruptible(&core->sem) == 0) { - struct vdec_s *vdec, *tmp; - LIST_HEAD(disconnecting_list); - - if (kthread_should_stop()) - break; - - /* clean up previous active vdec's input */ - if ((core->active_vdec) && - (core->active_vdec->status == VDEC_STATUS_CONNECTED)) { - struct vdec_input_s *input = &core->active_vdec->input; - - while (!list_empty(&input->vframe_chunk_list)) { - struct vframe_chunk_s *chunk = - vdec_input_next_chunk(input); - if (chunk->flag & VFRAME_CHUNK_FLAG_CONSUMED) - vdec_input_release_chunk(input, chunk); - else - break; - } - - vdec_save_input_context(core->active_vdec); - } - - /* - *todo: - * this is the case when the decoder is in active mode and - * the system side wants to stop it. Currently we rely on - * the decoder instance to go back to VDEC_STATUS_CONNECTED - * from VDEC_STATUS_ACTIVE by its own. However, if for some - * reason the decoder can not exist by itself (dead decoding - * or whatever), then we may have to add another vdec API - * to kill the vdec and release its HW resource and make it - * become inactive again. - * if ((core->active_vdec) && - * (core->active_vdec->status == VDEC_STATUS_DISCONNECTED)) { - * } - */ - - flags = vdec_core_lock(core); - - /* check disconnected decoders */ - list_for_each_entry_safe(vdec, tmp, - &core->connected_vdec_list, list) { - if ((vdec->status == VDEC_STATUS_CONNECTED) && - (vdec->next_status == VDEC_STATUS_DISCONNECTED)) { - if (core->active_vdec == vdec) - core->active_vdec = NULL; - list_move(&vdec->list, &disconnecting_list); - } - } - - /* activate next decoder instance if there is none */ - vdec = active_vdec(core); - - if (!vdec) { - /* - *round-robin decoder scheduling - * start from the decoder after previous active - * decoder instance, if not, then start from beginning - */ - if (core->active_vdec) - vdec = list_entry( - core->active_vdec->list.next, - struct vdec_s, list); - else - vdec = list_entry( - core->connected_vdec_list.next, - struct vdec_s, list); - - list_for_each_entry_from(vdec, - &core->connected_vdec_list, list) { - if (vdec_ready_to_run(vdec)) - break; - } - - if ((&vdec->list == &core->connected_vdec_list) && - (core->active_vdec)) { - /* search from beginning */ - list_for_each_entry(vdec, - &core->connected_vdec_list, list) { - if (vdec_ready_to_run(vdec)) - break; - - if (vdec == core->active_vdec) { - vdec = NULL; - break; - } - } - } - - if (&vdec->list == &core->connected_vdec_list) - vdec = NULL; - - core->active_vdec = NULL; - } - - vdec_core_unlock(core, flags); - - /* start the vdec instance */ - if ((vdec) && (vdec->status != VDEC_STATUS_ACTIVE)) { - vdec_set_status(vdec, VDEC_STATUS_ACTIVE); - - /* activatate the decoder instance to run */ - core->active_vdec = vdec; -#ifdef CONFIG_MULTI_DEC - vdec_profile(vdec, VDEC_PROFILE_EVENT_RUN); -#endif - vdec->run(vdec, vdec_callback, core); - } - - /* remove disconnected decoder from active list */ - list_for_each_entry_safe(vdec, tmp, &disconnecting_list, list) { - list_del(&vdec->list); - vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED); - complete(&vdec->inactive_done); - } - - if (!core->active_vdec) { - msleep(20); - up(&core->sem); - } - } - - return 0; -} - -#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ -static bool test_hevc(u32 decomp_addr, u32 us_delay) -{ - int i; - - /* SW_RESET IPP */ - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 1); - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0); - - /* initialize all canvas table */ - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0); - for (i = 0; i < 32; i++) - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - 0x1 | (i << 8) | decomp_addr); - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1); - 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); - - /* Initialize mcrcc */ - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); - WRITE_VREG(HEVCD_MCRCC_CTL2, 0x0); - WRITE_VREG(HEVCD_MCRCC_CTL3, 0x0); - WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); - - /* Decomp initialize */ - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x0); - WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0); - - /* Frame level initialization */ - WRITE_VREG(HEVCD_IPP_TOP_FRMCONFIG, 0x100 | (0x100 << 16)); - WRITE_VREG(HEVCD_IPP_TOP_TILECONFIG3, 0x0); - WRITE_VREG(HEVCD_IPP_TOP_LCUCONFIG, 0x1 << 5); - WRITE_VREG(HEVCD_IPP_BITDEPTH_CONFIG, 0x2 | (0x2 << 2)); - - WRITE_VREG(HEVCD_IPP_CONFIG, 0x0); - WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, 0x0); - - /* Enable SWIMP mode */ - WRITE_VREG(HEVCD_IPP_SWMPREDIF_CONFIG, 0x1); - - /* Enable frame */ - WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x2); - WRITE_VREG(HEVCD_IPP_TOP_FRMCTL, 0x1); - - /* Send SW-command CTB info */ - WRITE_VREG(HEVCD_IPP_SWMPREDIF_CTBINFO, 0x1 << 31); - - /* Send PU_command */ - WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO0, (0x4 << 9) | (0x4 << 16)); - WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO1, 0x1 << 3); - WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO2, 0x0); - WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO3, 0x0); - - udelay(us_delay); - - WRITE_VREG(HEVCD_IPP_DBG_SEL, 0x2 << 4); - - return (READ_VREG(HEVCD_IPP_DBG_DATA) & 3) == 1; -} - -void vdec_poweron(enum vdec_type_e core) -{ - void *decomp_addr = NULL; - dma_addr_t decomp_dma_addr; - u32 decomp_addr_aligned = 0; - int hevc_loop = 0; - - if (core >= VDEC_MAX) - return; - - mutex_lock(&vdec_mutex); - - vdec_core->power_ref_count[core]++; - if (vdec_core->power_ref_count[core] > 1) { - mutex_unlock(&vdec_mutex); - return; - } - - if (vdec_on(core)) { - mutex_unlock(&vdec_mutex); - return; - } - - if (hevc_workaround_needed() && - (core == VDEC_HEVC)) { - decomp_addr = codec_mm_dma_alloc_coherent(MEM_NAME, - SZ_64K + SZ_4K, &decomp_dma_addr, GFP_KERNEL, 0); - - if (decomp_addr) { - decomp_addr_aligned = ALIGN(decomp_dma_addr, SZ_64K); - memset((u8 *)decomp_addr + - (decomp_addr_aligned - decomp_dma_addr), - 0xff, SZ_4K); - } else - pr_err("vdec: alloc HEVC gxbb decomp buffer failed.\n"); - } - - if (core == VDEC_1) { - /* vdec1 power on */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~0xc); - /* wait 10uS */ - udelay(10); - /* vdec1 soft reset */ - WRITE_VREG(DOS_SW_RESET0, 0xfffffffc); - WRITE_VREG(DOS_SW_RESET0, 0); - /* enable vdec1 clock */ - /* - *add power on vdec clock level setting,only for m8 chip, - * m8baby and m8m2 can dynamic adjust vdec clock, - * power on with default clock level - */ - vdec_clock_hi_enable(); - /* power up vdec memories */ - WRITE_VREG(DOS_MEM_PD_VDEC, 0); - /* remove vdec1 isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~0xC0); - /* reset DOS top registers */ - WRITE_VREG(DOS_VDEC_MCRCC_STALL_CTRL, 0); - if (get_cpu_type() >= - MESON_CPU_MAJOR_ID_GXBB) { - /* - *enable VDEC_1 DMC request - */ - unsigned long flags; - - spin_lock_irqsave(&vdec_spin_lock, flags); - codec_dmcbus_write(DMC_REQ_CTRL, - codec_dmcbus_read(DMC_REQ_CTRL) | (1 << 13)); - spin_unlock_irqrestore(&vdec_spin_lock, flags); - } - } else if (core == VDEC_2) { - if (has_vdec2()) { - /* vdec2 power on */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & - ~0x30); - /* wait 10uS */ - udelay(10); - /* vdec2 soft reset */ - WRITE_VREG(DOS_SW_RESET2, 0xffffffff); - WRITE_VREG(DOS_SW_RESET2, 0); - /* enable vdec1 clock */ - vdec2_clock_hi_enable(); - /* power up vdec memories */ - WRITE_VREG(DOS_MEM_PD_VDEC2, 0); - /* remove vdec2 isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) & - ~0x300); - /* reset DOS top registers */ - WRITE_VREG(DOS_VDEC2_MCRCC_STALL_CTRL, 0); - } - } else if (core == VDEC_HCODEC) { - if (has_hdec()) { - /* hcodec power on */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & - ~0x3); - /* wait 10uS */ - udelay(10); - /* hcodec soft reset */ - WRITE_VREG(DOS_SW_RESET1, 0xffffffff); - WRITE_VREG(DOS_SW_RESET1, 0); - /* enable hcodec clock */ - hcodec_clock_enable(); - /* power up hcodec memories */ - WRITE_VREG(DOS_MEM_PD_HCODEC, 0); - /* remove hcodec isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) & - ~0x30); - } - } else if (core == VDEC_HEVC) { - if (has_hevc_vdec()) { - bool hevc_fixed = false; - - while (!hevc_fixed) { - /* hevc power on */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & - ~0xc0); - /* wait 10uS */ - udelay(10); - /* hevc soft reset */ - WRITE_VREG(DOS_SW_RESET3, 0xffffffff); - WRITE_VREG(DOS_SW_RESET3, 0); - /* enable hevc clock */ - hevc_clock_hi_enable(); - /* power up hevc memories */ - WRITE_VREG(DOS_MEM_PD_HEVC, 0); - /* remove hevc isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) & - ~0xc00); - - if (!hevc_workaround_needed()) - break; - - if (decomp_addr) - hevc_fixed = test_hevc( - decomp_addr_aligned, 20); - - if (!hevc_fixed) { - hevc_loop++; - - mutex_unlock(&vdec_mutex); - - if (hevc_loop >= HEVC_TEST_LIMIT) { - pr_warn("hevc power sequence over limit\n"); - pr_warn("=====================================================\n"); - pr_warn(" This chip is identified to have HW failure.\n"); - pr_warn(" Please contact sqa-platform to replace the platform.\n"); - pr_warn("=====================================================\n"); - - panic("Force panic for chip detection !!!\n"); - - break; - } - - vdec_poweroff(VDEC_HEVC); - - mdelay(10); - - mutex_lock(&vdec_mutex); - } - } - - if (hevc_loop > hevc_max_reset_count) - hevc_max_reset_count = hevc_loop; - - WRITE_VREG(DOS_SW_RESET3, 0xffffffff); - udelay(10); - WRITE_VREG(DOS_SW_RESET3, 0); - } - } - - if (decomp_addr) - codec_mm_dma_free_coherent(MEM_NAME, - SZ_64K + SZ_4K, decomp_addr, decomp_dma_addr, 0); - - mutex_unlock(&vdec_mutex); -} -EXPORT_SYMBOL(vdec_poweron); - -void vdec_poweroff(enum vdec_type_e core) -{ - if (core >= VDEC_MAX) - return; - - mutex_lock(&vdec_mutex); - - vdec_core->power_ref_count[core]--; - if (vdec_core->power_ref_count[core] > 0) { - mutex_unlock(&vdec_mutex); - return; - } - - if (core == VDEC_1) { - if (get_cpu_type() >= - MESON_CPU_MAJOR_ID_GXBB) { - /* disable VDEC_1 DMC REQ*/ - unsigned long flags; - - spin_lock_irqsave(&vdec_spin_lock, flags); - codec_dmcbus_write(DMC_REQ_CTRL, - codec_dmcbus_read(DMC_REQ_CTRL) & (~(1 << 13))); - spin_unlock_irqrestore(&vdec_spin_lock, flags); - udelay(10); - } - /* enable vdec1 isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | 0xc0); - /* power off vdec1 memories */ - WRITE_VREG(DOS_MEM_PD_VDEC, 0xffffffffUL); - /* disable vdec1 clock */ - vdec_clock_off(); - /* vdec1 power off */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 0xc); - } else if (core == VDEC_2) { - if (has_vdec2()) { - /* enable vdec2 isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | - 0x300); - /* power off vdec2 memories */ - WRITE_VREG(DOS_MEM_PD_VDEC2, 0xffffffffUL); - /* disable vdec2 clock */ - vdec2_clock_off(); - /* vdec2 power off */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | - 0x30); - } - } else if (core == VDEC_HCODEC) { - if (has_hdec()) { - /* enable hcodec isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | - 0x30); - /* power off hcodec memories */ - WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL); - /* disable hcodec clock */ - hcodec_clock_off(); - /* hcodec power off */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 3); - } - } else if (core == VDEC_HEVC) { - if (has_hevc_vdec()) { - /* enable hevc isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | - 0xc00); - /* power off hevc memories */ - WRITE_VREG(DOS_MEM_PD_HEVC, 0xffffffffUL); - /* disable hevc clock */ - hevc_clock_off(); - /* hevc power off */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | - 0xc0); - } - } - mutex_unlock(&vdec_mutex); -} -EXPORT_SYMBOL(vdec_poweroff); - -bool vdec_on(enum vdec_type_e core) -{ - bool ret = false; - - if (core == VDEC_1) { - if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & 0xc) == 0) && - (READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x100)) - ret = true; - } else if (core == VDEC_2) { - if (has_vdec2()) { - if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & 0x30) == 0) && - (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0x100)) - ret = true; - } - } else if (core == VDEC_HCODEC) { - if (has_hdec()) { - if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & 0x3) == 0) && - (READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x1000000)) - ret = true; - } - } else if (core == VDEC_HEVC) { - if (has_hevc_vdec()) { - if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & 0xc0) == 0) && - (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0x1000000)) - ret = true; - } - } - - return ret; -} -EXPORT_SYMBOL(vdec_on); - -#elif 0 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ -void vdec_poweron(enum vdec_type_e core) -{ - ulong flags; - - spin_lock_irqsave(&lock, flags); - - if (core == VDEC_1) { - /* vdec1 soft reset */ - WRITE_VREG(DOS_SW_RESET0, 0xfffffffc); - WRITE_VREG(DOS_SW_RESET0, 0); - /* enable vdec1 clock */ - vdec_clock_enable(); - /* reset DOS top registers */ - WRITE_VREG(DOS_VDEC_MCRCC_STALL_CTRL, 0); - } else if (core == VDEC_2) { - /* vdec2 soft reset */ - WRITE_VREG(DOS_SW_RESET2, 0xffffffff); - WRITE_VREG(DOS_SW_RESET2, 0); - /* enable vdec2 clock */ - vdec2_clock_enable(); - /* reset DOS top registers */ - WRITE_VREG(DOS_VDEC2_MCRCC_STALL_CTRL, 0); - } else if (core == VDEC_HCODEC) { - /* hcodec soft reset */ - WRITE_VREG(DOS_SW_RESET1, 0xffffffff); - WRITE_VREG(DOS_SW_RESET1, 0); - /* enable hcodec clock */ - hcodec_clock_enable(); - } - - spin_unlock_irqrestore(&lock, flags); -} - -void vdec_poweroff(enum vdec_type_e core) -{ - ulong flags; - - spin_lock_irqsave(&lock, flags); - - if (core == VDEC_1) { - /* disable vdec1 clock */ - vdec_clock_off(); - } else if (core == VDEC_2) { - /* disable vdec2 clock */ - vdec2_clock_off(); - } else if (core == VDEC_HCODEC) { - /* disable hcodec clock */ - hcodec_clock_off(); - } - - spin_unlock_irqrestore(&lock, flags); -} - -bool vdec_on(enum vdec_type_e core) -{ - bool ret = false; - - if (core == VDEC_1) { - if (READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x100) - ret = true; - } else if (core == VDEC_2) { - if (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0x100) - ret = true; - } else if (core == VDEC_HCODEC) { - if (READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x1000000) - ret = true; - } - - return ret; -} -#endif - -int vdec_source_changed(int format, int width, int height, int fps) -{ - /* todo: add level routines for clock adjustment per chips */ - int ret = -1; - static int on_setting; - - if (on_setting > 0) - return ret;/*on changing clk,ignore this change*/ - - if (vdec_source_get(VDEC_1) == width * height * fps) - return ret; - - - on_setting = 1; - ret = vdec_source_changed_for_clk_set(format, width, height, fps); - pr_info("vdec1 video changed to %d x %d %d fps clk->%dMHZ\n", - width, height, fps, vdec_clk_get(VDEC_1)); - on_setting = 0; - return ret; - -} -EXPORT_SYMBOL(vdec_source_changed); - -int vdec2_source_changed(int format, int width, int height, int fps) -{ - int ret = -1; - static int on_setting; - - if (has_vdec2()) { - /* todo: add level routines for clock adjustment per chips */ - if (on_setting != 0) - return ret;/*on changing clk,ignore this change*/ - - if (vdec_source_get(VDEC_2) == width * height * fps) - return ret; - - on_setting = 1; - ret = vdec_source_changed_for_clk_set(format, - width, height, fps); - pr_info("vdec2 video changed to %d x %d %d fps clk->%dMHZ\n", - width, height, fps, vdec_clk_get(VDEC_2)); - on_setting = 0; - return ret; - } - return 0; -} -EXPORT_SYMBOL(vdec2_source_changed); - -int hevc_source_changed(int format, int width, int height, int fps) -{ - /* todo: add level routines for clock adjustment per chips */ - int ret = -1; - static int on_setting; - - if (on_setting != 0) - return ret;/*on changing clk,ignore this change*/ - - if (vdec_source_get(VDEC_HEVC) == width * height * fps) - return ret; - - on_setting = 1; - ret = vdec_source_changed_for_clk_set(format, width, height, fps); - pr_info("hevc video changed to %d x %d %d fps clk->%dMHZ\n", - width, height, fps, vdec_clk_get(VDEC_HEVC)); - on_setting = 0; - - return ret; -} -EXPORT_SYMBOL(hevc_source_changed); - -static enum vdec2_usage_e vdec2_usage = USAGE_NONE; -void set_vdec2_usage(enum vdec2_usage_e usage) -{ - if (has_vdec2()) { - mutex_lock(&vdec_mutex); - vdec2_usage = usage; - mutex_unlock(&vdec_mutex); - } -} -EXPORT_SYMBOL(set_vdec2_usage); - -enum vdec2_usage_e get_vdec2_usage(void) -{ - if (has_vdec2()) - return vdec2_usage; - else - return 0; -} -EXPORT_SYMBOL(get_vdec2_usage); - -static struct am_reg am_risc[] = { - {"MSP", 0x300}, - {"MPSR", 0x301}, - {"MCPU_INT_BASE", 0x302}, - {"MCPU_INTR_GRP", 0x303}, - {"MCPU_INTR_MSK", 0x304}, - {"MCPU_INTR_REQ", 0x305}, - {"MPC-P", 0x306}, - {"MPC-D", 0x307}, - {"MPC_E", 0x308}, - {"MPC_W", 0x309}, - {"CSP", 0x320}, - {"CPSR", 0x321}, - {"CCPU_INT_BASE", 0x322}, - {"CCPU_INTR_GRP", 0x323}, - {"CCPU_INTR_MSK", 0x324}, - {"CCPU_INTR_REQ", 0x325}, - {"CPC-P", 0x326}, - {"CPC-D", 0x327}, - {"CPC_E", 0x328}, - {"CPC_W", 0x329}, - {"AV_SCRATCH_0", 0x09c0}, - {"AV_SCRATCH_1", 0x09c1}, - {"AV_SCRATCH_2", 0x09c2}, - {"AV_SCRATCH_3", 0x09c3}, - {"AV_SCRATCH_4", 0x09c4}, - {"AV_SCRATCH_5", 0x09c5}, - {"AV_SCRATCH_6", 0x09c6}, - {"AV_SCRATCH_7", 0x09c7}, - {"AV_SCRATCH_8", 0x09c8}, - {"AV_SCRATCH_9", 0x09c9}, - {"AV_SCRATCH_A", 0x09ca}, - {"AV_SCRATCH_B", 0x09cb}, - {"AV_SCRATCH_C", 0x09cc}, - {"AV_SCRATCH_D", 0x09cd}, - {"AV_SCRATCH_E", 0x09ce}, - {"AV_SCRATCH_F", 0x09cf}, - {"AV_SCRATCH_G", 0x09d0}, - {"AV_SCRATCH_H", 0x09d1}, - {"AV_SCRATCH_I", 0x09d2}, - {"AV_SCRATCH_J", 0x09d3}, - {"AV_SCRATCH_K", 0x09d4}, - {"AV_SCRATCH_L", 0x09d5}, - {"AV_SCRATCH_M", 0x09d6}, - {"AV_SCRATCH_N", 0x09d7}, -}; - -static ssize_t amrisc_regs_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; - struct am_reg *regs = am_risc; - int rsize = sizeof(am_risc) / sizeof(struct am_reg); - int i; - unsigned val; - ssize_t ret; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - mutex_lock(&vdec_mutex); - if (!vdec_on(VDEC_1)) { - mutex_unlock(&vdec_mutex); - pbuf += sprintf(pbuf, "amrisc is power off\n"); - ret = pbuf - buf; - return ret; - } - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 1); - */ - amports_switch_gate("vdec", 1); - } - pbuf += sprintf(pbuf, "amrisc registers show:\n"); - for (i = 0; i < rsize; i++) { - val = READ_VREG(regs[i].offset); - pbuf += sprintf(pbuf, "%s(%#x)\t:%#x(%d)\n", - regs[i].name, regs[i].offset, val, val); - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) - mutex_unlock(&vdec_mutex); - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 0); - */ - amports_switch_gate("vdec", 0); - } - ret = pbuf - buf; - return ret; -} - -static ssize_t dump_trace_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - int i; - char *pbuf = buf; - ssize_t ret; - u16 *trace_buf = kmalloc(debug_trace_num * 2, GFP_KERNEL); - - if (!trace_buf) { - pbuf += sprintf(pbuf, "No Memory bug\n"); - ret = pbuf - buf; - return ret; - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - mutex_lock(&vdec_mutex); - if (!vdec_on(VDEC_1)) { - mutex_unlock(&vdec_mutex); - kfree(trace_buf); - pbuf += sprintf(pbuf, "amrisc is power off\n"); - ret = pbuf - buf; - return ret; - } - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 1); - */ - amports_switch_gate("vdec", 1); - } - pr_info("dump trace steps:%d start\n", debug_trace_num); - i = 0; - while (i <= debug_trace_num - 16) { - trace_buf[i] = READ_VREG(MPC_E); - trace_buf[i + 1] = READ_VREG(MPC_E); - trace_buf[i + 2] = READ_VREG(MPC_E); - trace_buf[i + 3] = READ_VREG(MPC_E); - trace_buf[i + 4] = READ_VREG(MPC_E); - trace_buf[i + 5] = READ_VREG(MPC_E); - trace_buf[i + 6] = READ_VREG(MPC_E); - trace_buf[i + 7] = READ_VREG(MPC_E); - trace_buf[i + 8] = READ_VREG(MPC_E); - trace_buf[i + 9] = READ_VREG(MPC_E); - trace_buf[i + 10] = READ_VREG(MPC_E); - trace_buf[i + 11] = READ_VREG(MPC_E); - trace_buf[i + 12] = READ_VREG(MPC_E); - trace_buf[i + 13] = READ_VREG(MPC_E); - trace_buf[i + 14] = READ_VREG(MPC_E); - trace_buf[i + 15] = READ_VREG(MPC_E); - i += 16; - }; - pr_info("dump trace steps:%d finished\n", debug_trace_num); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) - mutex_unlock(&vdec_mutex); - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 0); - */ - amports_switch_gate("vdec", 0); - } - for (i = 0; i < debug_trace_num; i++) { - if (i % 4 == 0) { - if (i % 16 == 0) - pbuf += sprintf(pbuf, "\n"); - else if (i % 8 == 0) - pbuf += sprintf(pbuf, " "); - else /* 4 */ - pbuf += sprintf(pbuf, " "); - } - pbuf += sprintf(pbuf, "%04x:", trace_buf[i]); - } - while (i < debug_trace_num) - ; - kfree(trace_buf); - pbuf += sprintf(pbuf, "\n"); - ret = pbuf - buf; - return ret; -} - -static ssize_t clock_level_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; - size_t ret; - - pbuf += sprintf(pbuf, "%dMHZ\n", vdec_clk_get(VDEC_1)); - - if (has_vdec2()) - pbuf += sprintf(pbuf, "%dMHZ\n", vdec_clk_get(VDEC_2)); - - if (has_hevc_vdec()) - pbuf += sprintf(pbuf, "%dMHZ\n", vdec_clk_get(VDEC_HEVC)); - - ret = pbuf - buf; - return ret; -} - -static ssize_t store_poweron_clock_level(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size) -{ - unsigned val; - ssize_t ret; - - /*ret = sscanf(buf, "%d", &val);*/ - ret = kstrtoint(buf, 0, &val); - - if (ret != 0) - return -EINVAL; - poweron_clock_level = val; - return size; -} - -static ssize_t show_poweron_clock_level(struct class *class, - struct class_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", poweron_clock_level); -} - -/* -*if keep_vdec_mem == 1 -*always don't release -*vdec 64 memory for fast play. -*/ -static ssize_t store_keep_vdec_mem(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size) -{ - unsigned val; - ssize_t ret; - - /*ret = sscanf(buf, "%d", &val);*/ - ret = kstrtoint(buf, 0, &val); - if (ret != 0) - return -EINVAL; - keep_vdec_mem = val; - return size; -} - -static ssize_t show_keep_vdec_mem(struct class *class, - struct class_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", keep_vdec_mem); -} - - -/*irq num as same as .dts*/ -/* -* interrupts = <0 3 1 -* 0 23 1 -* 0 32 1 -* 0 43 1 -* 0 44 1 -* 0 45 1>; -* interrupt-names = "vsync", -* "demux", -* "parser", -* "mailbox_0", -* "mailbox_1", -* "mailbox_2"; -*/ -s32 vdec_request_threaded_irq(enum vdec_irq_num num, - irq_handler_t handler, - irq_handler_t thread_fn, - unsigned long irqflags, - const char *devname, void *dev) -{ - s32 res_irq; - s32 ret = 0; - - if (num >= VDEC_IRQ_MAX) { - pr_err("[%s] request irq error, irq num too big!", __func__); - return -EINVAL; - } - - if (vdec_core->isr_context[num].irq < 0) { - res_irq = platform_get_irq( - vdec_core->vdec_core_platform_device, num); - if (res_irq < 0) { - pr_err("[%s] get irq error!", __func__); - return -EINVAL; - } - - vdec_core->isr_context[num].irq = res_irq; - 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, - (thread_fn) ? IRQF_ONESHOT : irqflags, - devname, - &vdec_core->isr_context[num]); - - if (ret) { - vdec_core->isr_context[num].irq = -1; - vdec_core->isr_context[num].dev_isr = NULL; - vdec_core->isr_context[num].dev_threaded_isr = NULL; - vdec_core->isr_context[num].dev_id = NULL; - - pr_err("vdec irq register error for %s.\n", devname); - return -EIO; - } - } else { - 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; - } - - return ret; -} -EXPORT_SYMBOL(vdec_request_threaded_irq); - -s32 vdec_request_irq(enum vdec_irq_num num, irq_handler_t handler, - const char *devname, void *dev) -{ - pr_info("vdec_request_irq %p, %s\n", handler, devname); - - return vdec_request_threaded_irq(num, - handler, - NULL,/*no thread_fn*/ - IRQF_SHARED, - devname, - dev); -} -EXPORT_SYMBOL(vdec_request_irq); - -void vdec_free_irq(enum vdec_irq_num num, void *dev) -{ - if (num >= VDEC_IRQ_MAX) { - pr_err("[%s] request irq error, irq num too big!", __func__); - return; - } - - synchronize_irq(vdec_core->isr_context[num].irq); - - /* - *assume amrisc is stopped already and there is no mailbox interrupt - * when we reset pointers here. - */ - vdec_core->isr_context[num].dev_isr = NULL; - vdec_core->isr_context[num].dev_threaded_isr = NULL; - vdec_core->isr_context[num].dev_id = NULL; -} -EXPORT_SYMBOL(vdec_free_irq); - -static int dump_mode; -static ssize_t dump_risc_mem_store(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size)/*set*/ -{ - unsigned val; - ssize_t ret; - char dump_mode_str[4] = "PRL"; - - /*ret = sscanf(buf, "%d", &val);*/ - ret = kstrtoint(buf, 0, &val); - - if (ret != 0) - return -EINVAL; - dump_mode = val & 0x3; - pr_info("set dump mode to %d,%c_mem\n", - dump_mode, dump_mode_str[dump_mode]); - return size; -} -static u32 read_amrisc_reg(int reg) -{ - WRITE_VREG(0x31b, reg); - return READ_VREG(0x31c); -} - -static void dump_pmem(void) -{ - int i; - - WRITE_VREG(0x301, 0x8000); - WRITE_VREG(0x31d, 0); - pr_info("start dump amrisc pmem of risc\n"); - for (i = 0; i < 0xfff; i++) { - /*same as .o format*/ - pr_info("%08x // 0x%04x:\n", read_amrisc_reg(i), i); - } -} - -static void dump_lmem(void) -{ - int i; - - WRITE_VREG(0x301, 0x8000); - WRITE_VREG(0x31d, 2); - pr_info("start dump amrisc lmem\n"); - for (i = 0; i < 0x3ff; i++) { - /*same as */ - pr_info("[%04x] = 0x%08x:\n", i, read_amrisc_reg(i)); - } -} - -static ssize_t dump_risc_mem_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; - int ret; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - mutex_lock(&vdec_mutex); - if (!vdec_on(VDEC_1)) { - mutex_unlock(&vdec_mutex); - pbuf += sprintf(pbuf, "amrisc is power off\n"); - ret = pbuf - buf; - return ret; - } - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 1); - */ - amports_switch_gate("vdec", 1); - } - /*start do**/ - switch (dump_mode) { - case 0: - dump_pmem(); - break; - case 2: - dump_lmem(); - break; - default: - break; - } - - /*done*/ - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) - mutex_unlock(&vdec_mutex); - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /*TODO:M6 define */ - /* - * switch_mod_gate_by_type(MOD_VDEC, 0); - */ - amports_switch_gate("vdec", 0); - } - return sprintf(buf, "done\n"); -} - -static ssize_t core_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - struct vdec_core_s *core = vdec_core; - char *pbuf = buf; - - if (list_empty(&core->connected_vdec_list)) - pbuf += sprintf(pbuf, "connected vdec list empty\n"); - else { - struct vdec_s *vdec; - - list_for_each_entry(vdec, &core->connected_vdec_list, list) { - pbuf += sprintf(pbuf, - "\tvdec (%p (%s)), status = %s,\ttype = %s\n", - vdec, vdec_device_name[vdec->format * 2], - vdec_status_str(vdec), - vdec_type_str(vdec)); - } - } - - return pbuf - buf; -} - -static struct class_attribute vdec_class_attrs[] = { - __ATTR_RO(amrisc_regs), - __ATTR_RO(dump_trace), - __ATTR_RO(clock_level), - __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_NULL -}; - -static struct class vdec_class = { - .name = "vdec", - .class_attrs = vdec_class_attrs, - }; - - -/* -*pre alloced enough memory for decoder -*fast start. -*/ -void pre_alloc_vdec_memory(void) -{ - if (!keep_vdec_mem || vdec_core->mem_start) - return; - - vdec_core->mem_start = codec_mm_alloc_for_dma(MEM_NAME, - CMA_ALLOC_SIZE / PAGE_SIZE, 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | - CODEC_MM_FLAGS_FOR_VDECODER); - if (!vdec_core->mem_start) - return; - pr_debug("vdec base memory alloced %p\n", - (void *)vdec_core->mem_start); - - vdec_core->mem_end = vdec_core->mem_start + CMA_ALLOC_SIZE - 1; - vdec_mem_alloced_from_codec = 1; - delay_release = 3; -} -EXPORT_SYMBOL(pre_alloc_vdec_memory); - -struct device *get_vdec_device(void) -{ - return &vdec_core->vdec_core_platform_device->dev; -} -EXPORT_SYMBOL(get_vdec_device); - -static int vdec_probe(struct platform_device *pdev) -{ - s32 i, r; - - vdec_core = (struct vdec_core_s *)devm_kzalloc(&pdev->dev, - sizeof(struct vdec_core_s), GFP_KERNEL); - if (vdec_core == NULL) { - pr_err("vdec core allocation failed.\n"); - return -ENOMEM; - } - - atomic_set(&vdec_core->vdec_nr, 0); - sema_init(&vdec_core->sem, 1); - - r = class_register(&vdec_class); - if (r) { - pr_info("vdec class create fail.\n"); - return r; - } - - vdec_core->vdec_core_platform_device = pdev; - - platform_set_drvdata(pdev, vdec_core); - - for (i = 0; i < VDEC_IRQ_MAX; i++) { - vdec_core->isr_context[i].index = i; - vdec_core->isr_context[i].irq = -1; - } - - r = vdec_request_threaded_irq(VDEC_IRQ_1, NULL, NULL, - IRQF_ONESHOT, "vdec-1", NULL); - if (r < 0) { - pr_err("vdec interrupt request failed\n"); - return r; - } - - r = of_reserved_mem_device_init(&pdev->dev); - if (r == 0) - pr_info("vdec_probe done\n"); - - vdec_core->cma_dev = &pdev->dev; - - if (get_cpu_type() < MESON_CPU_MAJOR_ID_M8) { - /* default to 250MHz */ - vdec_clock_hi_enable(); - } - - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) { - /* set vdec dmc request to urgent */ - WRITE_DMCREG(DMC_AM5_CHAN_CTRL, 0x3f203cf); - } - if (codec_mm_get_reserved_size() >= 48 * SZ_1M - && codec_mm_get_reserved_size() <= 96 * SZ_1M) { -#ifdef CONFIG_MULTI_DEC - vdec_default_buf_size[VFORMAT_H264_4K2K * 2] = - codec_mm_get_reserved_size() / SZ_1M; -#else - vdec_default_buf_size[VFORMAT_H264_4K2K] = - codec_mm_get_reserved_size() / SZ_1M; -#endif - - /*all reserved size for prealloc*/ - } - pre_alloc_vdec_memory(); - - INIT_LIST_HEAD(&vdec_core->connected_vdec_list); - spin_lock_init(&vdec_core->lock); - - vdec_core->thread = kthread_run(vdec_core_thread, vdec_core, - "vdec-core"); - - return 0; -} - -static int vdec_remove(struct platform_device *pdev) -{ - int i; - - for (i = 0; i < VDEC_IRQ_MAX; i++) { - if (vdec_core->isr_context[i].irq >= 0) { - free_irq(vdec_core->isr_context[i].irq, - &vdec_core->isr_context[i]); - vdec_core->isr_context[i].irq = -1; - vdec_core->isr_context[i].dev_isr = NULL; - vdec_core->isr_context[i].dev_threaded_isr = NULL; - vdec_core->isr_context[i].dev_id = NULL; - } - } - - kthread_stop(vdec_core->thread); - - class_unregister(&vdec_class); - - return 0; -} - -static const struct of_device_id amlogic_vdec_dt_match[] = { - { - .compatible = "amlogic, vdec", - }, - {}, -}; - -static struct platform_driver vdec_driver = { - .probe = vdec_probe, - .remove = vdec_remove, - .driver = { - .name = "vdec", - .of_match_table = amlogic_vdec_dt_match, - } -}; - -int vdec_module_init(void) -{ - if (platform_driver_register(&vdec_driver)) { - pr_info("failed to register vdec module\n"); - return -ENODEV; - } - - return 0; -} -EXPORT_SYMBOL(vdec_module_init); - -void vdec_module_exit(void) -{ - platform_driver_unregister(&vdec_driver); -} -EXPORT_SYMBOL(vdec_module_exit); - -#if 0 -static int __init vdec_module_init(void) -{ - if (platform_driver_register(&vdec_driver)) { - pr_info("failed to register vdec module\n"); - return -ENODEV; - } - - return 0; -} - -static void __exit vdec_module_exit(void) -{ - platform_driver_unregister(&vdec_driver); -} -#endif - -static int vdec_mem_device_init(struct reserved_mem *rmem, struct device *dev) -{ - unsigned long start, end; - - start = rmem->base; - end = rmem->base + rmem->size - 1; - pr_info("init vdec memsource %lx->%lx\n", start, end); - - vdec_core->mem_start = start; - vdec_core->mem_end = end; - vdec_core->cma_dev = dev; - - return 0; -} - -static const struct reserved_mem_ops rmem_vdec_ops = { - .device_init = vdec_mem_device_init, -}; - -static int __init vdec_mem_setup(struct reserved_mem *rmem) -{ - rmem->ops = &rmem_vdec_ops; - pr_info("vdec: reserved mem setup\n"); - - return 0; -} - -RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup); - -module_param(debug_trace_num, uint, 0664); -module_param(hevc_max_reset_count, int, 0664); -module_param(clk_config, uint, 0664); -module_param(step_mode, int, 0664); -/* -*module_init(vdec_module_init); -*module_exit(vdec_module_exit); -*/ -MODULE_DESCRIPTION("AMLOGIC vdec driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h deleted file mode 100644 index cb63f8d..0000000 --- a/drivers/frame_provider/decoder/utils/vdec.h +++ b/dev/null @@ -1,306 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec.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_H -#define VDEC_H -#include <linux/amlogic/media/utils/amports_config.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/completion.h> -#include <linux/irqreturn.h> - -#include <linux/amlogic/media/utils/amstream.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 "vdec_input.h" - -s32 vdec_dev_register(void); -s32 vdec_dev_unregister(void); - -int vdec_source_changed(int format, int width, int height, int fps); -int vdec2_source_changed(int format, int width, int height, int fps); -int hevc_source_changed(int format, int width, int height, int fps); -struct device *get_vdec_device(void); -int vdec_module_init(void); -void vdec_module_exit(void); - -#define DEC_FLAG_HEVC_WORKAROUND 0x01 - -enum vdec_type_e { - VDEC_1 = 0, - VDEC_HCODEC, - VDEC_2, - VDEC_HEVC, - VDEC_MAX -}; - -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); - -/*irq num as same as .dts*/ - -/* -* interrupts = <0 3 1 -* 0 23 1 -* 0 32 1 -* 0 43 1 -* 0 44 1 -* 0 45 1>; -* interrupt-names = "vsync", -* "demux", -* "parser", -* "mailbox_0", -* "mailbox_1", -* "mailbox_2"; -*/ -enum vdec_irq_num { - VSYNC_IRQ = 0, - DEMUX_IRQ, - PARSER_IRQ, - VDEC_IRQ_0, - VDEC_IRQ_1, - VDEC_IRQ_2, - VDEC_IRQ_MAX, -}; -extern s32 vdec_request_threaded_irq(enum vdec_irq_num num, - irq_handler_t handler, - irq_handler_t thread_fn, - unsigned long irqflags, - const char *devname, void *dev); -extern s32 vdec_request_irq(enum vdec_irq_num num, irq_handler_t handler, - const char *devname, void *dev); -extern void vdec_free_irq(enum vdec_irq_num num, void *dev); - -enum vdec2_usage_e { - USAGE_NONE, - USAGE_DEC_4K2K, - USAGE_ENCODE, -}; - -extern void set_vdec2_usage(enum vdec2_usage_e usage); -extern enum vdec2_usage_e get_vdec2_usage(void); - -extern void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); -unsigned int get_vdec_clk_config_settings(void); -void update_vdec_clk_config_settings(unsigned int config); -//unsigned int get_mmu_mode(void);//DEBUG_TMP - -struct vdec_s; -enum vformat_t; - -/* stream based with single instance decoder driver */ -#define VDEC_TYPE_SINGLE 0 - -/* stream based with multi-instance decoder with HW resouce sharing */ -#define VDEC_TYPE_STREAM_PARSER 1 - -/* frame based with multi-instance decoder, input block list based */ -#define VDEC_TYPE_FRAME_BLOCK 2 - -/* frame based with multi-instance decoder, single circular input block */ -#define VDEC_TYPE_FRAME_CIRCULAR 3 - -/* decoder status: uninitialized */ -#define VDEC_STATUS_UNINITIALIZED 0 - -/* decoder status: before the decoder can start consuming data */ -#define VDEC_STATUS_DISCONNECTED 1 - -/* decoder status: decoder should become disconnected once it's not active */ -#define VDEC_STATUS_CONNECTED 2 - -/* decoder status: decoder owns HW resource and is running */ -#define VDEC_STATUS_ACTIVE 3 - -#define VDEC_PROVIDER_NAME_SIZE 16 -#define VDEC_RECEIVER_NAME_SIZE 16 -#define VDEC_MAP_NAME_SIZE 40 - -#define VDEC_FLAG_INPUT_KEEP_CONTEXT 0x01 - -struct vdec_s { - u32 magic; - struct list_head list; - int id; - - struct vdec_s *master; - struct vdec_s *slave; - struct stream_port_s *port; - int status; - int next_status; - int type; - int port_flag; - int format; - u32 pts; - u64 pts64; - bool pts_valid; - int flag; - int sched; - - struct completion inactive_done; - - /* config (temp) */ - unsigned long mem_start; - unsigned long mem_end; - - struct device *cma_dev; - struct platform_device *dev; - struct dec_sysinfo sys_info_store; - struct dec_sysinfo *sys_info; - - /* input */ - struct vdec_input_s input; - - /* mc cache */ - u32 mc[4096 * 4]; - bool mc_loaded; - - /* frame provider/receiver interface */ - char vf_provider_name[VDEC_PROVIDER_NAME_SIZE]; - struct vframe_provider_s vframe_provider; - char *vf_receiver_name; - char vfm_map_id[VDEC_MAP_NAME_SIZE]; - char vfm_map_chain[VDEC_MAP_NAME_SIZE]; - int vf_receiver_inst; - enum FRAME_BASE_VIDEO_PATH frame_base_video_path; - bool use_vfm_path; - char config[PAGE_SIZE]; - int config_len; - - /* canvas */ - int (*get_canvas)(unsigned int index, unsigned int base); - - int (*dec_status)(struct vdec_s *vdec, struct vdec_status *vstatus); - int (*set_trickmode)(struct vdec_s *vdec, unsigned long trickmode); - - bool (*run_ready)(struct vdec_s *vdec); - void (*run)(struct vdec_s *vdec, - void (*callback)(struct vdec_s *, void *), void *); - void (*reset)(struct vdec_s *vdec); - irqreturn_t (*irq_handler)(struct vdec_s *); - irqreturn_t (*threaded_irq_handler)(struct vdec_s *); - - /* private */ - void *private; /* decoder per instance specific data */ -}; - -/* 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 hw_to_vdec(hw) ((struct vdec_s *) \ - (platform_get_drvdata(hw->platform_dev))) - -#define canvas_y(canvas) ((canvas) & 0xff) -#define canvas_u(canvas) (((canvas) >> 8) & 0xff) -#define canvas_v(canvas) (((canvas) >> 16) & 0xff) -#define canvas_y2(canvas) (((canvas) >> 16) & 0xff) -#define canvas_u2(canvas) (((canvas) >> 24) & 0xff) - -#define vdec_frame_based(vdec) \ - (((vdec)->type == VDEC_TYPE_FRAME_BLOCK) || \ - ((vdec)->type == VDEC_TYPE_FRAME_CIRCULAR)) -#define vdec_stream_based(vdec) \ - (((vdec)->type == VDEC_TYPE_STREAM_PARSER) || \ - ((vdec)->type == VDEC_TYPE_SINGLE)) -#define vdec_single(vdec) \ - ((vdec)->type == VDEC_TYPE_SINGLE) -#define vdec_dual(vdec) \ - ((vdec)->port->type & PORT_TYPE_DUALDEC) - -/* construct vdec strcture */ -extern struct vdec_s *vdec_create(struct stream_port_s *port, - struct vdec_s *master); - -/* set video format */ -extern int vdec_set_format(struct vdec_s *vdec, int format); - -/* set PTS */ -extern int vdec_set_pts(struct vdec_s *vdec, u32 pts); - -extern int vdec_set_pts64(struct vdec_s *vdec, u64 pts64); - -/* set vfm map when use frame base decoder */ -extern int vdec_set_video_path(struct vdec_s *vdec, int video_path); - -/* add frame data to input chain */ -extern int vdec_write_vframe(struct vdec_s *vdec, const char *buf, - size_t count); - -/* mark the vframe_chunk as consumed */ -extern void vdec_vframe_dirty(struct vdec_s *vdec, - struct vframe_chunk_s *chunk); - -/* prepare decoder input */ -extern int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p); - -/* clean decoder input */ -extern void vdec_clean_input(struct vdec_s *vdec); - -/* enable decoder input */ -extern void vdec_enable_input(struct vdec_s *vdec); - -/* allocate input chain - * register vdec_device - * create output, vfm or create ionvideo output - * insert vdec to vdec_manager for scheduling - */ -extern int vdec_connect(struct vdec_s *vdec); - -/* remove vdec from vdec_manager scheduling - * release input chain - * disconnect video output from ionvideo - */ -extern int vdec_disconnect(struct vdec_s *vdec); - -/* release vdec structure */ -extern int vdec_destroy(struct vdec_s *vdec); - -/* reset vdec */ -extern int vdec_reset(struct vdec_s *vdec); - -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); - -extern void vdec_release(struct vdec_s *vdec); - -extern int vdec_status(struct vdec_s *vdec, struct vdec_status *vstatus); - -extern int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode); - -extern void vdec_set_flag(struct vdec_s *vdec, u32 flag); - -extern void vdec_set_next_sched(struct vdec_s *vdec, struct vdec_s *next_vdec); - -extern const char *vdec_status_str(struct vdec_s *vdec); - -extern const char *vdec_type_str(struct vdec_s *vdec); - -extern const char *vdec_device_name_str(struct vdec_s *vdec); - -#endif /* VDEC_H */ diff --git a/drivers/frame_provider/decoder/utils/vdec_input.c b/drivers/frame_provider/decoder/utils/vdec_input.c deleted file mode 100644 index d6acac1..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_input.c +++ b/dev/null @@ -1,544 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec_input.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/uaccess.h> -#include <linux/list.h> -#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" - -#define VFRAME_BLOCK_SIZE (4*SZ_1M) -#define VFRAME_BLOCK_PAGESIZE (PAGE_ALIGN(VFRAME_BLOCK_SIZE)/PAGE_SIZE) -#define VFRAME_BLOCK_PAGEALIGN 4 -#define VFRAME_BLOCK_MAX_LEVEL (8*SZ_1M) -#define VFRAME_BLOCK_HOLE (SZ_64K) - -#define FRAME_PADDING_SIZE 1024U -#define MEM_NAME "VFRAME_INPUT" - -static int vframe_chunk_fill(struct vdec_input_s *input, - struct vframe_chunk_s *chunk, const char *buf, - size_t count, struct vframe_block_list_s *block) -{ - u8 *p = (u8 *)block->start_virt + block->wp; - - if (block->type == VDEC_TYPE_FRAME_BLOCK) { - if (copy_from_user(p, buf, count)) - return -EFAULT; - - p += count; - - memset(p, 0, FRAME_PADDING_SIZE); - - dma_sync_single_for_device(get_vdec_device(), - block->start + block->wp, - count + FRAME_PADDING_SIZE, DMA_TO_DEVICE); - - } else if (block->type == VDEC_TYPE_FRAME_CIRCULAR) { - size_t len = min((size_t)(block->size - block->wp), count); - u32 wp; - - if (copy_from_user(p, buf, len)) - return -EFAULT; - - dma_sync_single_for_device(get_vdec_device(), - block->start + block->wp, - len, DMA_TO_DEVICE); - - p += len; - - if (count > len) { - p = (u8 *)block->start_virt; - if (copy_from_user(p, buf, count - len)) - return -EFAULT; - - dma_sync_single_for_device(get_vdec_device(), - block->start, - count-len, DMA_TO_DEVICE); - - p += count - len; - } - - wp = block->wp + count; - if (wp >= block->size) - wp -= block->size; - - len = min(block->size - wp, FRAME_PADDING_SIZE); - - memset(p, 0, len); - - dma_sync_single_for_device(get_vdec_device(), - block->start + wp, - len, DMA_TO_DEVICE); - - if (len < FRAME_PADDING_SIZE) { - p = (u8 *)block->start_virt; - - memset(p, 0, count - len); - - dma_sync_single_for_device(get_vdec_device(), - block->start, - count - len, DMA_TO_DEVICE); - } - } - - return 0; -} - -static inline u32 vframe_block_space(struct vframe_block_list_s *block) -{ - if (block->type == VDEC_TYPE_FRAME_BLOCK) { - return block->size - block->wp; - } else { - return (block->rp >= block->wp) ? - (block->rp - block->wp) : - (block->rp - block->wp + block->size); - } -} - -static void vframe_block_add_chunk(struct vframe_block_list_s *block, - struct vframe_chunk_s *chunk) -{ - block->wp += chunk->size + FRAME_PADDING_SIZE; - if (block->wp >= block->size) - block->wp -= block->size; - block->chunk_count++; - chunk->block = block; - block->input->wr_block = block; - chunk->sequence = block->input->sequence; - block->input->sequence++; -} - -static void vframe_block_free_storage(struct vframe_block_list_s *block) -{ - if (block->addr) { - dma_unmap_single( - get_vdec_device(), - block->start, - VFRAME_BLOCK_PAGESIZE, - DMA_TO_DEVICE); - - codec_mm_free_for_dma(MEM_NAME, block->addr); - - block->addr = 0; - block->start_virt = NULL; - block->start = 0; - } - - block->size = 0; -} - -static int vframe_block_init_alloc_storage(struct vdec_input_s *input, - struct vframe_block_list_s *block) -{ - block->magic = 0x4b434c42; - block->input = input; - block->type = input->type; - - /* - * todo: for different type use different size - */ - block->addr = codec_mm_alloc_for_dma( - MEM_NAME, - VFRAME_BLOCK_PAGESIZE, - VFRAME_BLOCK_PAGEALIGN, - CODEC_MM_FLAGS_DMA_CPU | CODEC_MM_FLAGS_FOR_VDECODER); - - if (!block->addr) { - pr_err("Input block allocation failed\n"); - return -ENOMEM; - } - - block->start_virt = (void *)codec_mm_phys_to_virt(block->addr); - block->start = dma_map_single( - get_vdec_device(), - block->start_virt, - VFRAME_BLOCK_PAGESIZE, - DMA_TO_DEVICE); - block->size = VFRAME_BLOCK_PAGESIZE * PAGE_SIZE; - - return 0; -} - -void vdec_input_init(struct vdec_input_s *input, struct vdec_s *vdec) -{ - INIT_LIST_HEAD(&input->vframe_block_list); - INIT_LIST_HEAD(&input->vframe_chunk_list); - spin_lock_init(&input->lock); - - input->vdec = vdec; -} -EXPORT_SYMBOL(vdec_input_init); - -int vdec_input_set_buffer(struct vdec_input_s *input, u32 start, u32 size) -{ - if (input_frame_based(input)) - return -EINVAL; - - input->start = start; - input->size = size; - input->swap_page = alloc_page(GFP_KERNEL); - - if (input->swap_page == NULL) - return -ENOMEM; - - return 0; -} -EXPORT_SYMBOL(vdec_input_set_buffer); - -void vdec_input_set_type(struct vdec_input_s *input, int type, int target) -{ - input->type = type; - input->target = target; -} -EXPORT_SYMBOL(vdec_input_set_type); - -int vdec_input_get_status(struct vdec_input_s *input, - struct vdec_input_status_s *status) -{ - unsigned long flags; - - if (input->vdec == NULL) - return -EINVAL; - - flags = vdec_input_lock(input); - - if (list_empty(&input->vframe_block_list)) { - status->size = VFRAME_BLOCK_SIZE; - status->data_len = 0; - status->free_len = VFRAME_BLOCK_SIZE; - status->read_pointer = 0; - } else { - int r = VFRAME_BLOCK_MAX_LEVEL - vdec_input_level(input) - - VFRAME_BLOCK_HOLE; - status->size = input->size; - status->data_len = vdec_input_level(input); - status->free_len = (r > 0) ? r : 0; - status->read_pointer = input->total_rd_count; - } - - vdec_input_unlock(input, flags); - - return 0; -} -EXPORT_SYMBOL(vdec_input_get_status); - -static void vdec_input_add_block(struct vdec_input_s *input, - struct vframe_block_list_s *block) -{ - unsigned long flags; - - flags = vdec_input_lock(input); - - list_add_tail(&block->list, &input->vframe_block_list); - input->size += block->size; - - vdec_input_unlock(input, flags); -} - -static void vdec_input_remove_block(struct vdec_input_s *input, - struct vframe_block_list_s *block) -{ - unsigned long flags; - - flags = vdec_input_lock(input); - - list_del(&block->list); - input->size -= block->size; - - vdec_input_unlock(input, flags); - - vframe_block_free_storage(block); - - kfree(block); - - pr_info("block %p removed\n", block); -} - -int vdec_input_level(struct vdec_input_s *input) -{ - return input->total_wr_count - input->total_rd_count; -} -EXPORT_SYMBOL(vdec_input_level); - -int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, - size_t count) -{ - unsigned long flags; - struct vframe_chunk_s *chunk; - struct vdec_s *vdec = input->vdec; - struct vframe_block_list_s *block = input->wr_block; - -#if 0 - if (add_count == 0) { - add_count++; - memcpy(sps, buf, 30); - return 30; - } else if (add_count == 1) { - add_count++; - memcpy(pps, buf, 8); - return 8; - } - add_count++; -#endif - -#if 0 - pr_info("vdec_input_add_frame add %p, count=%d\n", buf, (int)count); - - if (count >= 8) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); - } - if (count >= 16) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[8], buf[9], buf[10], buf[11], - buf[12], buf[13], buf[14], buf[15]); - } - if (count >= 24) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[16], buf[17], buf[18], buf[19], - buf[20], buf[21], buf[22], buf[23]); - } - if (count >= 32) { - pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[24], buf[25], buf[26], buf[27], - buf[28], buf[29], buf[30], buf[31]); - } -#endif - if (input_stream_based(input)) - return -EINVAL; - - /* prepare block to write */ - if ((!block) || (block && - (vframe_block_space(block) < (count + FRAME_PADDING_SIZE)))) { - /* switch to another block for the added chunk */ - struct vframe_block_list_s *new_block; - -#if 0 - pr_info("Adding new block, total level = %d, total_wr_count=%d, total_rd_count=%d\n", - vdec_input_level(input), - (int)input->total_wr_count, - (int)input->total_rd_count); -#endif - - if ((!list_empty(&input->vframe_block_list)) && - (block->type == VDEC_TYPE_FRAME_CIRCULAR)) - return -EAGAIN; - /* - *todo: add input limit check for - * VDEC_TYPE_FRAME_BLOCK - */ - if (vdec_input_level(input) > - VFRAME_BLOCK_MAX_LEVEL) { - pr_info("vdec_input %p reaching max size\n", - input); - return -EAGAIN; - } - - /* - *check next block of current wr_block, it should be an empty - * block to use - */ - if ((block) && (!list_is_last( - &block->list, &input->vframe_block_list))) { - block = list_next_entry(block, list); - - if (vframe_block_space(block) != VFRAME_BLOCK_SIZE) - /* should never happen */ - pr_err("next writing block not empty.\n"); - } else { - /* add a new block into input list */ - new_block = kzalloc(sizeof(struct vframe_block_list_s), - GFP_KERNEL); - if (new_block == NULL) { - pr_err("vframe_block structure allocation failed\n"); - return -EAGAIN; - } - - if (vframe_block_init_alloc_storage(input, - new_block) != 0) { - kfree(new_block); - pr_err("vframe_block storage allocation failed\n"); - return -EAGAIN; - } - - INIT_LIST_HEAD(&new_block->list); - - vdec_input_add_block(input, new_block); - - /* pr_info("added new block %p\n", new_block); */ - - block = new_block; - } - } - - chunk = kzalloc(sizeof(struct vframe_chunk_s), GFP_KERNEL); - - if (!chunk) { - pr_err("vframe_chunk structure allocation failed\n"); - return -ENOMEM; - } - - chunk->magic = 0x4b554843; - if (vdec->pts_valid) { - chunk->pts = vdec->pts; - chunk->pts64 = vdec->pts64; - } - chunk->pts_valid = vdec->pts_valid; - vdec->pts_valid = false; - chunk->offset = block->wp; - chunk->size = count; - - INIT_LIST_HEAD(&chunk->list); - - if (vframe_chunk_fill(input, chunk, buf, count, block)) { - pr_err("vframe_chunk_fill failed\n"); - kfree(chunk); - return -EFAULT; - } - - flags = vdec_input_lock(input); - - vframe_block_add_chunk(block, chunk); - - list_add_tail(&chunk->list, &input->vframe_chunk_list); - - vdec_input_unlock(input, flags); - - input->total_wr_count += count; - -#if 0 - if (add_count == 2) - input->total_wr_count += 38; -#endif - - return count; -} -EXPORT_SYMBOL(vdec_input_add_frame); - -struct vframe_chunk_s *vdec_input_next_chunk(struct vdec_input_s *input) -{ - if (list_empty(&input->vframe_chunk_list)) - return NULL; - - return list_first_entry(&input->vframe_chunk_list, - struct vframe_chunk_s, list); -} -EXPORT_SYMBOL(vdec_input_next_chunk); - -struct vframe_chunk_s *vdec_input_next_input_chunk( - struct vdec_input_s *input) -{ - struct vframe_chunk_s *chunk = NULL; - struct list_head *p; - - list_for_each(p, &input->vframe_chunk_list) { - struct vframe_chunk_s *c = list_entry( - p, struct vframe_chunk_s, list); - if ((c->flag & VFRAME_CHUNK_FLAG_CONSUMED) == 0) { - chunk = c; - break; - } - } - - return chunk; -} -EXPORT_SYMBOL(vdec_input_next_input_chunk); - -void vdec_input_release_chunk(struct vdec_input_s *input, - struct vframe_chunk_s *chunk) -{ - unsigned long flags; - struct vframe_block_list_s *block = chunk->block; - - flags = vdec_input_lock(input); - - list_del(&chunk->list); - - block->rp += chunk->size; - if (block->rp >= block->size) - block->rp -= block->size; - block->chunk_count--; - input->total_rd_count += chunk->size; - - if (block->chunk_count == 0) { - /* reuse the block */ - block->wp = 0; - block->rp = 0; - - if ((input->wr_block == block) && - (!list_is_last(&block->list, - &input->vframe_block_list))) - input->wr_block = list_next_entry(block, list); - - list_move_tail(&block->list, &input->vframe_block_list); - } - - vdec_input_unlock(input, flags); - - kfree(chunk); -} -EXPORT_SYMBOL(vdec_input_release_chunk); - -unsigned long vdec_input_lock(struct vdec_input_s *input) -{ - unsigned long flags; - - spin_lock_irqsave(&input->lock, flags); - - return flags; -} -EXPORT_SYMBOL(vdec_input_lock); - -void vdec_input_unlock(struct vdec_input_s *input, unsigned long flags) -{ - spin_unlock_irqrestore(&input->lock, flags); -} -EXPORT_SYMBOL(vdec_input_unlock); - -void vdec_input_release(struct vdec_input_s *input) -{ - struct list_head *p, *tmp; - - /* release chunk data */ - list_for_each_safe(p, tmp, &input->vframe_chunk_list) { - struct vframe_chunk_s *chunk = list_entry( - p, struct vframe_chunk_s, list); - vdec_input_release_chunk(input, chunk); - } - - /* release input blocks */ - list_for_each_safe(p, tmp, &input->vframe_block_list) { - struct vframe_block_list_s *block = list_entry( - p, struct vframe_block_list_s, list); - vdec_input_remove_block(input, block); - } - - /* release swap page */ - if (input->swap_page) { - __free_page(input->swap_page); - input->swap_page = NULL; - input->swap_valid = false; - } -} -EXPORT_SYMBOL(vdec_input_release); - diff --git a/drivers/frame_provider/decoder/utils/vdec_input.h b/drivers/frame_provider/decoder/utils/vdec_input.h deleted file mode 100644 index b029b89..0000000 --- a/drivers/frame_provider/decoder/utils/vdec_input.h +++ b/dev/null @@ -1,131 +0,0 @@ -/* - * drivers/amlogic/media/frame_provider/decoder/utils/vdec_input.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_INPUT_H -#define VDEC_INPUT_H - -struct vdec_s; -struct vdec_input_s; - -struct vframe_block_list_s { - u32 magic; - struct list_head list; - ulong start; - void *start_virt; - ulong addr; - int type; - u32 size; - u32 wp; - u32 rp; - int chunk_count; - struct vdec_input_s *input; -}; - -#define VFRAME_CHUNK_FLAG_CONSUMED 0x0001 - -struct vframe_chunk_s { - u32 magic; - struct list_head list; - int flag; - u32 offset; - u32 size; - u32 pts; - u64 pts64; - bool pts_valid; - u64 sequence; - struct vframe_block_list_s *block; -}; - -#define VDEC_INPUT_TARGET_VLD 0 -#define VDEC_INPUT_TARGET_HEVC 1 - -struct vdec_input_s { - struct list_head vframe_block_list; - struct list_head vframe_chunk_list; - struct vframe_block_list_s *wr_block; - spinlock_t lock; - int type; - int target; - struct vdec_s *vdec; - bool swap_valid; - bool swap_needed; - struct page *swap_page; - int total_wr_count; - int total_rd_count; - u64 sequence; - unsigned start; - unsigned size; - int stream_cookie; /* wrap count for vld_mem and*/ - /*HEVC_SHIFT_BYTE_COUNT for hevc */ -}; - -struct vdec_input_status_s { - int size; - int data_len; - int free_len; - int read_pointer; -}; - -#define input_frame_based(input) \ - (((input)->type == VDEC_TYPE_FRAME_BLOCK) || \ - ((input)->type == VDEC_TYPE_FRAME_CIRCULAR)) -#define input_stream_based(input) \ - (((input)->type == VDEC_TYPE_STREAM_PARSER) || \ - ((input)->type == VDEC_TYPE_SINGLE)) - -/* Initialize vdec_input structure */ -extern void vdec_input_init(struct vdec_input_s *input, struct vdec_s *vdec); - -/* Get available input data size */ -extern int vdec_input_level(struct vdec_input_s *input); - -/* Set input type and target */ -extern void vdec_input_set_type(struct vdec_input_s *input, int type, - int target); - -/* Set stream buffer information for stream based input */ -extern int vdec_input_set_buffer(struct vdec_input_s *input, u32 start, - u32 size); - -/* Add enqueue video data into decoder's input */ -extern int vdec_input_add_frame(struct vdec_input_s *input, const char *buf, - size_t count); - -/* Peek next frame data from decoder's input */ -extern struct vframe_chunk_s *vdec_input_next_chunk( - struct vdec_input_s *input); - -/* Peek next frame data from decoder's input, not marked as consumed */ -extern struct vframe_chunk_s *vdec_input_next_input_chunk( - struct vdec_input_s *input); - -/* Consume next frame data from decoder's input */ -extern void vdec_input_release_chunk(struct vdec_input_s *input, - struct vframe_chunk_s *chunk); - -/* Get decoder input buffer status */ -extern int vdec_input_get_status(struct vdec_input_s *input, - struct vdec_input_status_s *status); - -extern unsigned long vdec_input_lock(struct vdec_input_s *input); - -extern void vdec_input_unlock(struct vdec_input_s *input, unsigned long lock); - -/* release all resource for decoder's input */ -extern void vdec_input_release(struct vdec_input_s *input); - -#endif /* VDEC_INPUT_H */ diff --git a/drivers/frame_provider/decoder/vc1/vvc1.c b/drivers/frame_provider/decoder/vc1/vvc1.c deleted file mode 100644 index 3495d92..0000000 --- a/drivers/frame_provider/decoder/vc1/vvc1.c +++ b/dev/null @@ -1,1170 +0,0 @@ -/* - * drivers/amlogic/amports/vvc1.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/module.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/kfifo.h> -#include <linux/platform_device.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/canvas/canvas.h> -#include <linux/amlogic/media/canvas/canvas_mgr.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/vdec_reg.h> -#include "../utils/amvdec.h" -#include "../utils/vdec.h" -#include <linux/amlogic/media/registers/register.h> -#include "../../../stream_input/amports/amports_priv.h" - -#define DRIVER_NAME "amvdec_vc1" -#define MODULE_NAME "amvdec_vc1" - -#define DEBUG_PTS -#if 1 /* //MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -#define NV21 -#endif - -#define I_PICTURE 0 -#define P_PICTURE 1 -#define B_PICTURE 2 - -#define ORI_BUFFER_START_ADDR 0x01000000 - -#define INTERLACE_FLAG 0x80 -#define BOTTOM_FIELD_FIRST_FLAG 0x40 - -/* protocol registers */ -#define VC1_PIC_RATIO AV_SCRATCH_0 -#define VC1_ERROR_COUNT AV_SCRATCH_6 -#define VC1_SOS_COUNT AV_SCRATCH_7 -#define VC1_BUFFERIN AV_SCRATCH_8 -#define VC1_BUFFEROUT AV_SCRATCH_9 -#define VC1_REPEAT_COUNT AV_SCRATCH_A -#define VC1_TIME_STAMP AV_SCRATCH_B -#define VC1_OFFSET_REG AV_SCRATCH_C -#define MEM_OFFSET_REG AV_SCRATCH_F - -#define VF_POOL_SIZE 32 -#define DECODE_BUFFER_NUM_MAX 8 -#define PUT_INTERVAL (HZ/100) - -#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -/* TODO: move to register headers */ -#define VPP_VD1_POSTBLEND (1 << 10) -#define MEM_FIFO_CNT_BIT 16 -#define MEM_LEVEL_CNT_BIT 18 -#endif - -static struct vframe_s *vvc1_vf_peek(void *); -static struct vframe_s *vvc1_vf_get(void *); -static void vvc1_vf_put(struct vframe_s *, void *); -static int vvc1_vf_states(struct vframe_states *states, void *); -static int vvc1_event_cb(int type, void *data, void *private_data); - -static void vvc1_prot_init(void); -static void vvc1_local_init(void); - -static const char vvc1_dec_id[] = "vvc1-dev"; - -#define PROVIDER_NAME "decoder.vc1" -static const struct vframe_operations_s vvc1_vf_provider = { - .peek = vvc1_vf_peek, - .get = vvc1_vf_get, - .put = vvc1_vf_put, - .event_cb = vvc1_event_cb, - .vf_states = vvc1_vf_states, -}; - -static struct vframe_provider_s vvc1_vf_prov; - -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 struct vframe_s vfpool2[VF_POOL_SIZE]; -static int cur_pool_idx; - -static s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; -static struct timer_list recycle_timer; -static u32 stat; -static unsigned long buf_start; -static u32 buf_size, buf_offset; -static u32 avi_flag; -static u32 vvc1_ratio; -static u32 vvc1_format; - -static u32 intra_output; -static u32 frame_width, frame_height, frame_dur; -static u32 saved_resolution; -static u32 pts_by_offset = 1; -static u32 total_frame; -static u32 next_pts; -static u64 next_pts_us64; - -#ifdef DEBUG_PTS -static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; -#endif -static DEFINE_SPINLOCK(lock); - -static struct dec_sysinfo vvc1_amstream_dec_info; - -struct frm_s { - int state; - u32 start_pts; - int num; - u32 end_pts; - u32 rate; - u32 trymax; -}; - -static struct frm_s frm; - -enum { - RATE_MEASURE_START_PTS = 0, - RATE_MEASURE_END_PTS, - RATE_MEASURE_DONE -}; -#define RATE_MEASURE_NUM 8 -#define RATE_CORRECTION_THRESHOLD 5 -#define RATE_24_FPS 3755 /* 23.97 */ -#define RATE_30_FPS 3003 /* 29.97 */ -#define DUR2PTS(x) ((x)*90/96) -#define PTS2DUR(x) ((x)*96/90) - -static inline int pool_index(struct vframe_s *vf) -{ - if ((vf >= &vfpool[0]) && (vf <= &vfpool[VF_POOL_SIZE - 1])) - return 0; - else if ((vf >= &vfpool2[0]) && (vf <= &vfpool2[VF_POOL_SIZE - 1])) - return 1; - else - return -1; -} - -static inline bool close_to(int a, int b, int m) -{ - return abs(a - b) < m; -} - -static inline u32 index2canvas(u32 index) -{ - const u32 canvas_tab[DECODE_BUFFER_NUM_MAX] = { -#if 1 /* ALWASY.MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - 0x010100, 0x030302, 0x050504, 0x070706, - 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e -#else - 0x020100, 0x050403, 0x080706, 0x0b0a09 -#endif - }; - - return canvas_tab[index]; -} - -static void set_aspect_ratio(struct vframe_s *vf, unsigned pixel_ratio) -{ - int ar = 0; - - if (vvc1_ratio == 0) { - /* always stretch to 16:9 */ - vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT); - } else if (pixel_ratio > 0x0f) { - ar = (vvc1_amstream_dec_info.height * (pixel_ratio & 0xff) * - vvc1_ratio) / (vvc1_amstream_dec_info.width * - (pixel_ratio >> 8)); - } else { - switch (pixel_ratio) { - case 0: - ar = (vvc1_amstream_dec_info.height * vvc1_ratio) / - vvc1_amstream_dec_info.width; - break; - case 1: - ar = (vf->height * vvc1_ratio) / vf->width; - break; - case 2: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 12); - break; - case 3: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 10); - break; - case 4: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 16); - break; - case 5: - ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 40); - break; - case 6: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 24); - break; - case 7: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 20); - break; - case 8: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 32); - break; - case 9: - ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 80); - break; - case 10: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 18); - break; - case 11: - ar = (vf->height * 11 * vvc1_ratio) / (vf->width * 15); - break; - case 12: - ar = (vf->height * 33 * vvc1_ratio) / (vf->width * 64); - break; - case 13: - ar = (vf->height * 99 * vvc1_ratio) / - (vf->width * 160); - break; - default: - ar = (vf->height * vvc1_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;*/ -} - -static irqreturn_t vvc1_isr(int irq, void *dev_id) -{ - u32 reg; - struct vframe_s *vf = NULL; - u32 repeat_count; - u32 picture_type; - u32 buffer_index; - unsigned int pts, pts_valid = 0, offset; - u32 v_width, v_height; - u64 pts_us64 = 0; - - reg = READ_VREG(VC1_BUFFEROUT); - - if (reg) { - v_width = READ_VREG(AV_SCRATCH_J); - v_height = READ_VREG(AV_SCRATCH_K); - - if (v_width && v_width <= 4096 - && (v_width != vvc1_amstream_dec_info.width)) { - pr_info("frame width changed %d to %d\n", - vvc1_amstream_dec_info.width, v_width); - vvc1_amstream_dec_info.width = v_width; - frame_width = v_width; - } - if (v_height && v_height <= 4096 - && (v_height != vvc1_amstream_dec_info.height)) { - pr_info("frame height changed %d to %d\n", - vvc1_amstream_dec_info.height, v_height); - vvc1_amstream_dec_info.height = v_height; - frame_height = v_height; - } - - if (pts_by_offset) { - offset = READ_VREG(VC1_OFFSET_REG); - if (pts_lookup_offset_us64( - PTS_TYPE_VIDEO, - offset, &pts, 0, &pts_us64) == 0) { - pts_valid = 1; -#ifdef DEBUG_PTS - pts_hit++; -#endif - } else { -#ifdef DEBUG_PTS - pts_missed++; -#endif - } - } - - repeat_count = READ_VREG(VC1_REPEAT_COUNT); - buffer_index = reg & 0x7; - picture_type = (reg >> 3) & 7; - - if (buffer_index >= DECODE_BUFFER_NUM_MAX) { - pr_info("fatal error, invalid buffer index."); - return IRQ_HANDLED; - } - - if ((intra_output == 0) && (picture_type != 0)) { - WRITE_VREG(VC1_BUFFERIN, ~(1 << buffer_index)); - WRITE_VREG(VC1_BUFFEROUT, 0); - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - return IRQ_HANDLED; - } - - intra_output = 1; - -#ifdef DEBUG_PTS - if (picture_type == I_PICTURE) { - /* pr_info("I offset 0x%x, - pts_valid %d\n", offset, pts_valid); */ - if (!pts_valid) - pts_i_missed++; - else - pts_i_hit++; - } -#endif - - if ((pts_valid) && (frm.state != RATE_MEASURE_DONE)) { - if (frm.state == RATE_MEASURE_START_PTS) { - frm.start_pts = pts; - frm.state = RATE_MEASURE_END_PTS; - frm.trymax = RATE_MEASURE_NUM; - } else if (frm.state == RATE_MEASURE_END_PTS) { - if (frm.num >= frm.trymax) { - frm.end_pts = pts; - frm.rate = (frm.end_pts - - frm.start_pts) / frm.num; - pr_info("frate before=%d,%d,num=%d\n", - frm.rate, - DUR2PTS(vvc1_amstream_dec_info.rate), - frm.num); - /* check if measured rate is same as - * settings from upper layer - * and correct it if necessary */ - if ((close_to(frm.rate, RATE_30_FPS, - RATE_CORRECTION_THRESHOLD) && - close_to( - DUR2PTS( - vvc1_amstream_dec_info.rate), - RATE_24_FPS, - RATE_CORRECTION_THRESHOLD)) - || - (close_to( - frm.rate, RATE_24_FPS, - RATE_CORRECTION_THRESHOLD) - && - close_to(DUR2PTS( - vvc1_amstream_dec_info.rate), - RATE_30_FPS, - RATE_CORRECTION_THRESHOLD))) { - pr_info( - "vvc1: frate from %d to %d\n", - vvc1_amstream_dec_info.rate, - PTS2DUR(frm.rate)); - - vvc1_amstream_dec_info.rate = - PTS2DUR(frm.rate); - frm.state = RATE_MEASURE_DONE; - } else if (close_to(frm.rate, - DUR2PTS( - vvc1_amstream_dec_info.rate), - RATE_CORRECTION_THRESHOLD)) - frm.state = RATE_MEASURE_DONE; - else { /*maybe still have problem, - try next double frames.... */ - frm.state = RATE_MEASURE_DONE; - frm.start_pts = pts; - frm.state = - RATE_MEASURE_END_PTS; - /*60 fps*60 S */ - frm.num = 0; - } - } - } - } - - if (frm.state != RATE_MEASURE_DONE) - frm.num += (repeat_count > 1) ? repeat_count : 1; - if (0 == vvc1_amstream_dec_info.rate) - vvc1_amstream_dec_info.rate = PTS2DUR(frm.rate); - - if (reg & INTERLACE_FLAG) { /* interlace */ - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vvc1_amstream_dec_info.width; - vf->height = vvc1_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - - if (pts_valid) { - vf->pts = pts; - vf->pts_us64 = pts_us64; - if ((repeat_count > 1) && avi_flag) { - vf->duration = - vvc1_amstream_dec_info.rate * - repeat_count >> 1; - next_pts = pts + - (vvc1_amstream_dec_info.rate * - repeat_count >> 1) * 15 / 16; - next_pts_us64 = pts_us64 + - ((vvc1_amstream_dec_info.rate * - repeat_count >> 1) * 15 / 16) * - 100 / 9; - } else { - vf->duration = - vvc1_amstream_dec_info.rate >> 1; - next_pts = 0; - next_pts_us64 = 0; - } - } else { - vf->pts = next_pts; - vf->pts_us64 = next_pts_us64; - if ((repeat_count > 1) && avi_flag) { - vf->duration = - vvc1_amstream_dec_info.rate * - repeat_count >> 1; - if (next_pts != 0) { - next_pts += ((vf->duration) - - ((vf->duration) >> 4)); - } - if (next_pts_us64 != 0) { - next_pts_us64 += - ((vf->duration) - - ((vf->duration) >> 4)) * - 100 / 9; - } - } else { - vf->duration = - vvc1_amstream_dec_info.rate >> 1; - next_pts = 0; - next_pts_us64 = 0; - } - } - - vf->duration_pulldown = 0; - vf->type = (reg & BOTTOM_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->orientation = 0; - vf->type_original = vf->type; - set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO)); - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver( - PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vvc1_amstream_dec_info.width; - vf->height = vvc1_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - - vf->pts = next_pts; - vf->pts_us64 = next_pts_us64; - if ((repeat_count > 1) && avi_flag) { - vf->duration = - vvc1_amstream_dec_info.rate * - repeat_count >> 1; - if (next_pts != 0) { - next_pts += - ((vf->duration) - - ((vf->duration) >> 4)); - } - if (next_pts_us64 != 0) { - next_pts_us64 += ((vf->duration) - - ((vf->duration) >> 4)) * 100 / 9; - } - } else { - vf->duration = - vvc1_amstream_dec_info.rate >> 1; - next_pts = 0; - next_pts_us64 = 0; - } - - vf->duration_pulldown = 0; - vf->type = (reg & BOTTOM_FIELD_FIRST_FLAG) ? - VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; -#ifdef NV21 - vf->type |= VIDTYPE_VIU_NV21; -#endif - vf->canvas0Addr = vf->canvas1Addr = - index2canvas(buffer_index); - vf->orientation = 0; - vf->type_original = vf->type; - set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO)); - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver( - PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } else { /* progressive */ - if (kfifo_get(&newframe_q, &vf) == 0) { - pr_info - ("fatal error, no available buffer slot."); - return IRQ_HANDLED; - } - vf->signal_type = 0; - vf->index = buffer_index; - vf->width = vvc1_amstream_dec_info.width; - vf->height = vvc1_amstream_dec_info.height; - vf->bufWidth = 1920; - vf->flag = 0; - - if (pts_valid) { - vf->pts = pts; - vf->pts_us64 = pts_us64; - if ((repeat_count > 1) && avi_flag) { - vf->duration = - vvc1_amstream_dec_info.rate * - repeat_count; - next_pts = - pts + - (vvc1_amstream_dec_info.rate * - repeat_count) * 15 / 16; - next_pts_us64 = pts_us64 + - ((vvc1_amstream_dec_info.rate * - repeat_count) * 15 / 16) * - 100 / 9; - } else { - vf->duration = - vvc1_amstream_dec_info.rate; - next_pts = 0; - next_pts_us64 = 0; - } - } else { - vf->pts = next_pts; - vf->pts_us64 = next_pts_us64; - if ((repeat_count > 1) && avi_flag) { - vf->duration = - vvc1_amstream_dec_info.rate * - repeat_count; - if (next_pts != 0) { - next_pts += ((vf->duration) - - ((vf->duration) >> 4)); - } - if (next_pts_us64 != 0) { - next_pts_us64 += - ((vf->duration) - - ((vf->duration) >> 4)) * - 100 / 9; - } - } else { - vf->duration = - vvc1_amstream_dec_info.rate; - next_pts = 0; - next_pts_us64 = 0; - } - } - - 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; - set_aspect_ratio(vf, READ_VREG(VC1_PIC_RATIO)); - - vfbuf_use[buffer_index]++; - - kfifo_put(&display_q, (const struct vframe_s *)vf); - - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); - } - frame_dur = vvc1_amstream_dec_info.rate; - total_frame++; - - /* pr_info("PicType = %d, PTS = 0x%x, repeat - count %d\n", picture_type, vf->pts, repeat_count); */ - WRITE_VREG(VC1_BUFFEROUT, 0); - } - - WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); - - return IRQ_HANDLED; -} - -static struct vframe_s *vvc1_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_peek(&display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vvc1_vf_get(void *op_arg) -{ - struct vframe_s *vf; - - if (kfifo_get(&display_q, &vf)) - return vf; - - return NULL; -} - -static void vvc1_vf_put(struct vframe_s *vf, void *op_arg) -{ - if (pool_index(vf) == cur_pool_idx) - kfifo_put(&recycle_q, (const struct vframe_s *)vf); -} - -static int vvc1_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 int vvc1_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(&vvc1_vf_prov); -#endif - spin_lock_irqsave(&lock, flags); - vvc1_local_init(); - vvc1_prot_init(); - spin_unlock_irqrestore(&lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vvc1_vf_prov); -#endif - amvdec_start(); - } - return 0; -} - -int vvc1_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - vstatus->width = vvc1_amstream_dec_info.width; - vstatus->height = vvc1_amstream_dec_info.height; - if (0 != vvc1_amstream_dec_info.rate) - vstatus->fps = 96000 / vvc1_amstream_dec_info.rate; - else - vstatus->fps = 96000; - vstatus->error_count = READ_VREG(AV_SCRATCH_4); - vstatus->status = stat; - - return 0; -} - -/****************************************/ -static void vvc1_canvas_init(void) -{ - int i; - u32 canvas_width, canvas_height; - u32 decbuf_size, decbuf_y_size, decbuf_uv_size; - u32 disp_addr = 0xffffffff; - - 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; - } - - if (is_vpp_postblend()) { - struct canvas_s cur_canvas; - - canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), - &cur_canvas); - disp_addr = (cur_canvas.addr + 7) >> 3; - } - - for (i = 0; i < 8; i++) { - if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) { -#ifdef NV21 - canvas_config(2 * i + 0, - buf_start + 8 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - buf_start + 8 * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(3 * i + 0, - buf_start + 8 * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - buf_start + 8 * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - buf_start + 8 * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -#endif - } else { -#ifdef NV21 - canvas_config(2 * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(2 * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); -#else - canvas_config(3 * i + 0, - buf_start + i * decbuf_size, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 1, - buf_start + i * decbuf_size + - decbuf_y_size, canvas_width / 2, - canvas_height / 2, CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_32X32); - canvas_config(3 * i + 2, - buf_start + i * decbuf_size + - decbuf_y_size + decbuf_uv_size, - canvas_width / 2, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); -#endif - } - } -} - -static void vvc1_prot_init(void) -{ -#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_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - READ_MPEG_REG(RESET0_REGISTER); - WRITE_MPEG_REG(RESET0_REGISTER, - RESET_IQIDCT | RESET_MC | RESET_VLD_PART); - - WRITE_MPEG_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); -#endif - - 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); - - vvc1_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); - WRITE_VREG(AV_SCRATCH_G, 0x090908); - WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a); - WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c); - WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e); -#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); - WRITE_VREG(AV_SCRATCH_G, 0x090908); - WRITE_VREG(AV_SCRATCH_H, 0x0b0b0a); - WRITE_VREG(AV_SCRATCH_I, 0x0d0d0c); - WRITE_VREG(AV_SCRATCH_J, 0x0f0f0e); -#endif - - /* notify ucode the buffer offset */ - WRITE_VREG(AV_SCRATCH_F, buf_offset); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(PSCALE_CTRL, 0); - - WRITE_VREG(VC1_SOS_COUNT, 0); - WRITE_VREG(VC1_BUFFERIN, 0); - WRITE_VREG(VC1_BUFFEROUT, 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 -} - -static void vvc1_local_init(void) -{ - int i; - - /* vvc1_ratio = vvc1_amstream_dec_info.ratio; */ - vvc1_ratio = 0x100; - - avi_flag = (unsigned long) vvc1_amstream_dec_info.param; - - total_frame = 0; - - next_pts = 0; - - next_pts_us64 = 0; - saved_resolution = 0; - frame_width = frame_height = frame_dur = 0; -#ifdef DEBUG_PTS - pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0; -#endif - - memset(&frm, 0, sizeof(frm)); - - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) - vfbuf_use[i] = 0; - - INIT_KFIFO(display_q); - INIT_KFIFO(recycle_q); - INIT_KFIFO(newframe_q); - cur_pool_idx ^= 1; - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf; - if (cur_pool_idx == 0) { - vf = &vfpool[i]; - vfpool[i].index = DECODE_BUFFER_NUM_MAX; - } else { - vf = &vfpool2[i]; - vfpool2[i].index = DECODE_BUFFER_NUM_MAX; - } - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } -} - -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER -static void vvc1_ppmgr_reset(void) -{ - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); - - vvc1_local_init(); - - /* vf_notify_receiver(PROVIDER_NAME, - * VFRAME_EVENT_PROVIDER_START,NULL); */ - - pr_info("vvc1dec: vf_ppmgr_reset\n"); -} -#endif - -static void vvc1_put_timer_func(unsigned long arg) -{ - struct timer_list *timer = (struct timer_list *)arg; - -#if 1 - if (READ_VREG(VC1_SOS_COUNT) > 10) { - amvdec_stop(); -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vvc1_ppmgr_reset(); -#else - vf_light_unreg_provider(&vvc1_vf_prov); - vvc1_local_init(); - vf_reg_provider(&vvc1_vf_prov); -#endif - vvc1_prot_init(); - amvdec_start(); - } -#endif - - while (!kfifo_is_empty(&recycle_q) && (READ_VREG(VC1_BUFFERIN) == 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(VC1_BUFFERIN, ~(1 << vf->index)); - vf->index = DECODE_BUFFER_NUM_MAX; - } - if (pool_index(vf) == cur_pool_idx) - kfifo_put(&newframe_q, (const struct vframe_s *)vf); - } - } - 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_VC1, - frame_width, frame_height, fps); - } - timer->expires = jiffies + PUT_INTERVAL; - - add_timer(timer); -} - -static s32 vvc1_init(void) -{ - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - pr_info("vvc1_init, format %d\n", vvc1_amstream_dec_info.format); - init_timer(&recycle_timer); - - stat |= STAT_TIMER_INIT; - - intra_output = 0; - amvdec_enable(); - - vvc1_local_init(); - - if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WMV3) { - pr_info("WMV3 dec format\n"); - vvc1_format = VIDEO_DEC_FORMAT_WMV3; - WRITE_VREG(AV_SCRATCH_4, 0); - } else if (vvc1_amstream_dec_info.format == VIDEO_DEC_FORMAT_WVC1) { - pr_info("WVC1 dec format\n"); - vvc1_format = VIDEO_DEC_FORMAT_WVC1; - WRITE_VREG(AV_SCRATCH_4, 1); - } else - pr_info("not supported VC1 format\n"); - - size = get_firmware_data(VIDEO_DEC_VC1, buf); - if (size < 0) { - pr_err("get firmware fail."); - vfree(buf); - return -1; - } - - if (amvdec_loadmc_ex(VFORMAT_VC1, NULL, buf) < 0) { - amvdec_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vvc1_prot_init(); - - if (vdec_request_irq(VDEC_IRQ_1, vvc1_isr, - "vvc1-irq", (void *)vvc1_dec_id)) { - amvdec_disable(); - - pr_info("vvc1 irq register error.\n"); - return -ENOENT; - } - - stat |= STAT_ISR_REG; -#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_provider_init(&vvc1_vf_prov, - PROVIDER_NAME, &vvc1_vf_provider, NULL); - vf_reg_provider(&vvc1_vf_prov); - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_START, NULL); -#else - vf_provider_init(&vvc1_vf_prov, - PROVIDER_NAME, &vvc1_vf_provider, NULL); - vf_reg_provider(&vvc1_vf_prov); -#endif - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)vvc1_amstream_dec_info.rate)); - - 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; - - amvdec_start(); - - stat |= STAT_VDEC_RUN; - - return 0; -} - -static int amvdec_vc1_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - if (pdata == NULL) { - pr_info("amvdec_vc1 memory resource undefined.\n"); - return -EFAULT; - } - - buf_start = pdata->mem_start; - buf_size = pdata->mem_end - pdata->mem_start + 1; - buf_offset = buf_start - ORI_BUFFER_START_ADDR; - - if (pdata->sys_info) - vvc1_amstream_dec_info = *pdata->sys_info; - - pdata->dec_status = vvc1_dec_status; - - if (vvc1_init() < 0) { - pr_info("amvdec_vc1 init failed.\n"); - - return -ENODEV; - } - - return 0; -} - -static int amvdec_vc1_remove(struct platform_device *pdev) -{ - if (stat & STAT_VDEC_RUN) { - amvdec_stop(); - stat &= ~STAT_VDEC_RUN; - } - - if (stat & STAT_ISR_REG) { - vdec_free_irq(VDEC_IRQ_1, (void *)vvc1_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) { - vf_notify_receiver(PROVIDER_NAME, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vvc1_vf_prov); - stat &= ~STAT_VF_HOOK; - } - - amvdec_disable(); - -#ifdef DEBUG_PTS - pr_info("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit, - pts_missed, pts_i_hit, pts_i_missed); - pr_info("total frame %d, avi_flag %d, rate %d\n", - total_frame, avi_flag, - vvc1_amstream_dec_info.rate); -#endif - - return 0; -} - -/****************************************/ - -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, - } -}; - -#if defined(CONFIG_ARCH_MESON) /*meson1 only support progressive */ -static struct codec_profile_t amvdec_vc1_profile = { - .name = "vc1", - .profile = "progressive, wmv3" -}; -#else -static struct codec_profile_t amvdec_vc1_profile = { - .name = "vc1", - .profile = "progressive, interlace, wmv3" -}; -#endif - -static int __init amvdec_vc1_driver_init_module(void) -{ - pr_debug("amvdec_vc1 module init\n"); - - if (platform_driver_register(&amvdec_vc1_driver)) { - pr_err("failed to register amvdec_vc1 driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvdec_vc1_profile); - return 0; -} - -static void __exit amvdec_vc1_driver_remove_module(void) -{ - pr_debug("amvdec_vc1 module remove.\n"); - - platform_driver_unregister(&amvdec_vc1_driver); -} - -/****************************************/ - -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_vc1 stat\n"); - -module_init(amvdec_vc1_driver_init_module); -module_exit(amvdec_vc1_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC VC1 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c deleted file mode 100644 index 0e819e7..0000000 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/dev/null @@ -1,6922 +0,0 @@ - /* - * drivers/amlogic/amports/vvp9.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/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 "../../../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" - -#include <linux/amlogic/media/video_sink/video.h> - -#define MIX_STREAM_SUPPORT -#define SUPPORT_4K2K - -#include "vvp9.h" -#define VP9D_MPP_REFINFO_TBL_ACCCONFIG 0x3442 -#define VP9D_MPP_REFINFO_DATA 0x3443 -#define VP9D_MPP_REF_SCALE_ENBL 0x3441 -#define HEVC_MPRED_CTRL4 0x324c -#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_SAO_MMU_STATUS 0x3639 - - -#define VP9_10B_DEC_IDLE 0 -#define VP9_10B_DEC_FRAME_HEADER 1 -#define VP9_10B_DEC_SLICE_SEGMENT 2 -#define VP9_10B_DECODE_SLICE 5 -#define VP9_10B_DISCARD_NAL 6 -#define VP9_DUMP_LMEM 7 -#define HEVC_DECPIC_DATA_DONE 0xa -#define HEVC_DECPIC_DATA_ERROR 0xb -#define HEVC_NAL_DECODE_DONE 0xe -#define HEVC_DECODE_BUFEMPTY 0x20 -#define HEVC_DECODE_TIMEOUT 0x21 -#define HEVC_SEARCH_BUFEMPTY 0x22 -#define VP9_HEAD_PARSER_DONE 0xf0 -#define VP9_HEAD_SEARCH_DONE 0xf1 -#define VP9_EOS 0xf2 -#define HEVC_ACTION_DONE 0xff - -#define MAX_BUF_NUM 24 -#define MAX_REF_ACTIVE 16 -#define VF_POOL_SIZE 32 - -#undef pr_info -#define pr_info printk - -#define DECODE_MODE_SINGLE 0 -#define DECODE_MODE_MULTI_STREAMBASE 1 -#define DECODE_MODE_MULTI_FRAMEBASE 2 - -/*--------------------------------------------------- - 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 - -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 -}; -/*#define HEVC_PIC_STRUCT_SUPPORT*/ -/* to remove, fix build error */ - -/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/ - -#define MULTI_INSTANCE_SUPPORT -#define SUPPORT_10BIT -/* #define ERROR_HANDLE_DEBUG */ -#if 0 /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESON8B*/ -#undef SUPPORT_4K2K -#else -#define SUPPORT_4K2K -#endif - -#ifndef STAT_KTHREAD -#define STAT_KTHREAD 0x40 -#endif - -#ifdef MULTI_INSTANCE_SUPPORT -#define MAX_DECODE_INSTANCE_NUM 5 -#define MULTI_DRIVER_NAME "ammvdec_vp9" -#endif - -#define DRIVER_NAME "amvdec_vp9" -#define MODULE_NAME "amvdec_vp9" - -#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 VP9Decoder_s; -static int vvp9_vf_states(struct vframe_states *states, void *); -static struct vframe_s *vvp9_vf_peek(void *); -static struct vframe_s *vvp9_vf_get(void *); -static void vvp9_vf_put(struct vframe_s *, void *); -static int vvp9_event_cb(int type, void *data, void *private_data); - -static int vvp9_stop(struct VP9Decoder_s *pbi); -static s32 vvp9_init(struct VP9Decoder_s *pbi); -static void vvp9_prot_init(struct VP9Decoder_s *pbi); -static int vvp9_local_init(struct VP9Decoder_s *pbi); -static void vvp9_put_timer_func(unsigned long arg); -#ifdef VP9_10B_MMU -static int vp9_alloc_mmu( - 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"; - -#define PROVIDER_NAME "decoder.vp9" -#define MULTI_INSTANCE_PROVIDER_NAME "vdec.vp9" - -static const struct vframe_operations_s vvp9_vf_provider = { - .peek = vvp9_vf_peek, - .get = vvp9_vf_get, - .put = vvp9_vf_put, - .event_cb = vvp9_event_cb, - .vf_states = vvp9_vf_states, -}; - -static struct vframe_provider_s vvp9_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; - - -#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 FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4) - -static inline int div_r32(int64_t m, int n) -{ -/* -return (int)(m/n) -*/ -#ifndef CONFIG_ARM64 - do_div(m, n); - return (int)m; -#else - return (int)(m/n); -#endif -} - -/*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 */; - - - /* #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*/ -#define MCRCC_ENABLE - -#ifdef VP9_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 - -#define VP9_LPF_LVL_UPDATE -/*#define DBG_LF_PRINT*/ - -#ifdef VP9_10B_NV21 -#else -#define LOSLESS_COMPRESS_MODE -#endif - -#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_UCODE 0x04 -#define VP9_DEBUG_REG 0x08 -#define VP9_DEBUG_MERGE 0x10 -#define VP9_DEBUG_BASIC 0x40 -#define VP9_DEBUG_SEND_PARAM_WITH_REG 0x100 -#define VP9_DEBUG_NO_DISPLAY 0x200 -#define VP9_DEBUG_DBG_LF_PRINT 0x400 -#define VP9_DEBUG_OUT_PTS 0x800 -#define VP9_DEBUG_VF_REF 0x1000 -#define VP9_DEBUG_DIS_LOC_ERROR_PROC 0x10000 -#define VP9_DEBUG_DIS_SYS_ERROR_PROC 0x20000 -#define VP9_DEBUG_DUMP_PIC_LIST 0x40000 -#define VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000 -#define VP9_DEBUG_HW_RESET 0x100000 -#define VP9_DEBUG_LOAD_UCODE_FROM_FILE 0x200000 -#define VP9_DEBUG_ERROR_TRIG 0x400000 -#define VP9_DEBUG_NOWAIT_DECODE_DONE_WHEN_STOP 0x4000000 -#ifdef MULTI_INSTANCE_SUPPORT -#define PRINT_FLAG_ERROR 0 -#define PRINT_FLAG_UCODE_EVT 0x10000000 -#define PRINT_FLAG_VDEC_STATUS 0x20000000 -#define PRINT_FLAG_VDEC_DETAIL 0x40000000 -#define PRINT_FLAG_VDEC_DATA 0x80000000 -#endif - -static u32 debug; - -#define DEBUG_REG -#ifdef DEBUG_REG -void WRITE_VREG_DBG2(unsigned adr, unsigned val) -{ - if (debug & VP9_DEBUG_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 - -/************************************************** - -VP9 buffer management start - -***************************************************/ -#ifdef VP9_10B_MMU -#define MMU_COMPRESS_HEADER_SIZE 0x48000 -#endif - -#define INVALID_IDX -1 /* Invalid buffer index.*/ - -#define RPM_BEGIN 0x200 -#define RPM_END 0x280 - -union param_u { - struct { - unsigned short data[RPM_END - RPM_BEGIN]; - } l; - struct { - /* from ucode lmem, do not change this struct */ - unsigned short profile; - unsigned short show_existing_frame; - unsigned short frame_to_show_idx; - unsigned short frame_type; /*1 bit*/ - unsigned short show_frame; /*1 bit*/ - unsigned short error_resilient_mode; /*1 bit*/ - unsigned short intra_only; /*1 bit*/ - unsigned short display_size_present; /*1 bit*/ - unsigned short reset_frame_context; - unsigned short refresh_frame_flags; - unsigned short width; - unsigned short height; - unsigned short display_width; - unsigned short display_height; - /* - bit[11:8] - ref_frame_info_0 (ref(3-bits), ref_frame_sign_bias(1-bit)) - bit[7:4] - ref_frame_info_1 (ref(3-bits), ref_frame_sign_bias(1-bit)) - bit[3:0] - ref_frame_info_2 (ref(3-bits), ref_frame_sign_bias(1-bit)) - */ - unsigned short ref_info; - /* - bit[2]: same_frame_size0 - bit[1]: same_frame_size1 - bit[0]: same_frame_size2 - */ - unsigned short same_frame_size; - - unsigned short mode_ref_delta_enabled; - unsigned short ref_deltas[4]; - unsigned short mode_deltas[2]; - unsigned short filter_level; - unsigned short sharpness_level; - unsigned short bit_depth; - unsigned short seg_quant_info[8]; - unsigned short seg_enabled; - unsigned short seg_abs_delta; - /* bit 15: feature enabled; bit 8, sign; bit[5:0], data */ - unsigned short seg_lf_info[8]; - } p; -}; - - -struct vpx_codec_frame_buffer_s { - uint8_t *data; /**< Pointer to the data buffer */ - size_t size; /**< Size of data in bytes */ - void *priv; /**< Frame's private data */ -}; - -enum vpx_color_space_t { - VPX_CS_UNKNOWN = 0, /**< Unknown */ - VPX_CS_BT_601 = 1, /**< BT.601 */ - VPX_CS_BT_709 = 2, /**< BT.709 */ - VPX_CS_SMPTE_170 = 3, /**< SMPTE.170 */ - VPX_CS_SMPTE_240 = 4, /**< SMPTE.240 */ - VPX_CS_BT_2020 = 5, /**< BT.2020 */ - VPX_CS_RESERVED = 6, /**< Reserved */ - VPX_CS_SRGB = 7 /**< sRGB */ -}; /**< alias for enum vpx_color_space */ - -enum vpx_bit_depth_t { - VPX_BITS_8 = 8, /**< 8 bits */ - VPX_BITS_10 = 10, /**< 10 bits */ - VPX_BITS_12 = 12, /**< 12 bits */ -}; - -#define MAX_SLICE_NUM 1024 -struct PIC_BUFFER_CONFIG_s { - int index; - int BUF_index; - int comp_body_size; - int buf_size; - int vf_ref; - int y_canvas_index; - int uv_canvas_index; -#ifdef MULTI_INSTANCE_SUPPORT - struct canvas_config_s canvas_config[2]; -#endif - int decode_idx; - int slice_type; - int num_reorder_pic; - int stream_offset; - uint8_t used_by_display; - uint8_t referenced; - uint8_t output_mark; - uint8_t recon_mark; - uint8_t output_ready; - uint8_t error_mark; - /**/ - int slice_idx; - /*buffer*/ -#ifdef VP9_10B_MMU - unsigned long header_adr; -#endif - unsigned long mpred_mv_wr_start_addr; - unsigned long mc_y_adr; - unsigned long mc_u_v_adr; - unsigned int dw_y_adr; - unsigned int dw_u_v_adr; - int mc_canvas_y; - int mc_canvas_u_v; - - int lcu_total; - /**/ - int y_width; - int y_height; - int y_crop_width; - int y_crop_height; - int y_stride; - - int uv_width; - int uv_height; - int uv_crop_width; - int uv_crop_height; - int uv_stride; - - int alpha_width; - int alpha_height; - int alpha_stride; - - uint8_t *y_buffer; - uint8_t *u_buffer; - uint8_t *v_buffer; - uint8_t *alpha_buffer; - - uint8_t *buffer_alloc; - int buffer_alloc_sz; - int border; - int frame_size; - int subsampling_x; - int subsampling_y; - unsigned int bit_depth; - enum vpx_color_space_t color_space; - - int corrupted; - int flags; - unsigned long cma_alloc_addr; -} PIC_BUFFER_CONFIG; - -enum BITSTREAM_PROFILE { - PROFILE_0, - PROFILE_1, - PROFILE_2, - PROFILE_3, - MAX_PROFILES -}; - -enum FRAME_TYPE { - KEY_FRAME = 0, - INTER_FRAME = 1, - FRAME_TYPES, -}; - -enum REFERENCE_MODE { - SINGLE_REFERENCE = 0, - COMPOUND_REFERENCE = 1, - REFERENCE_MODE_SELECT = 2, - REFERENCE_MODES = 3, -}; - -#define NONE -1 -#define INTRA_FRAME 0 -#define LAST_FRAME 1 -#define GOLDEN_FRAME 2 -#define ALTREF_FRAME 3 -#define MAX_REF_FRAMES 4 - -#define REFS_PER_FRAME 3 - -#define REF_FRAMES_LOG2 3 -#define REF_FRAMES (1 << REF_FRAMES_LOG2) - -/*4 scratch frames for the new frames to support a maximum of 4 cores decoding -in parallel, 3 for scaled references on the encoder. -TODO(hkuang): Add ondemand frame buffers instead of hardcoding the number -// of framebuffers. -TODO(jkoleszar): These 3 extra references could probably come from the -normal reference pool.*/ -#define FRAME_BUFFERS (REF_FRAMES + 7) - -#define FRAME_CONTEXTS_LOG2 2 -#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) -#define MAX_BMMU_BUFFER_NUM (FRAME_BUFFERS + 1) -#define WORK_SPACE_BUF_ID (FRAME_BUFFERS) - -struct RefCntBuffer_s { - int ref_count; - /*MV_REF *mvs;*/ - int mi_rows; - int mi_cols; - struct vpx_codec_frame_buffer_s raw_frame_buffer; - struct PIC_BUFFER_CONFIG_s buf; - -/*The Following variables will only be used in frame parallel decode. - -frame_worker_owner indicates which FrameWorker owns this buffer. NULL means -that no FrameWorker owns, or is decoding, this buffer. -VP9Worker *frame_worker_owner; - -row and col indicate which position frame has been decoded to in real -pixel unit. They are reset to -1 when decoding begins and set to INT_MAX -when the frame is fully decoded.*/ - int row; - int col; -} RefCntBuffer; - -struct RefBuffer_s { -/*TODO(dkovalev): idx is not really required and should be removed, now it -is used in vp9_onyxd_if.c*/ - int idx; - struct PIC_BUFFER_CONFIG_s *buf; - /*struct scale_factors sf;*/ -} RefBuffer; - -struct InternalFrameBuffer_s { - uint8_t *data; - size_t size; - int in_use; -} InternalFrameBuffer; - -struct InternalFrameBufferList_s { - int num_internal_frame_buffers; - struct InternalFrameBuffer_s *int_fb; -} InternalFrameBufferList; - -struct BufferPool_s { -/*Protect BufferPool from being accessed by several FrameWorkers at -the same time during frame parallel decode. -TODO(hkuang): Try to use atomic variable instead of locking the whole pool. - -Private data associated with the frame buffer callbacks. -void *cb_priv; - -vpx_get_frame_buffer_cb_fn_t get_fb_cb; -vpx_release_frame_buffer_cb_fn_t release_fb_cb;*/ - - struct RefCntBuffer_s frame_bufs[FRAME_BUFFERS]; - -/*Frame buffers allocated internally by the codec.*/ - struct InternalFrameBufferList_s int_frame_buffers; - unsigned long flags; - spinlock_t lock; - -} BufferPool; - -static void lock_buffer_pool(struct BufferPool_s *pool) -{ - spin_lock_irqsave(&pool->lock, pool->flags); -} -static void unlock_buffer_pool(struct BufferPool_s *pool) -{ - spin_unlock_irqrestore(&pool->lock, pool->flags); -} - -struct VP9_Common_s { - enum vpx_color_space_t color_space; - int width; - int height; - int display_width; - int display_height; - int last_width; - int last_height; - - int subsampling_x; - int subsampling_y; - - int use_highbitdepth;/*Marks if we need to use 16bit frame buffers.*/ - - struct PIC_BUFFER_CONFIG_s *frame_to_show; - struct RefCntBuffer_s *prev_frame; - - /*TODO(hkuang): Combine this with cur_buf in macroblockd.*/ - struct RefCntBuffer_s *cur_frame; - - int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */ - - /*Prepare ref_frame_map for the next frame. - Only used in frame parallel decode.*/ - int next_ref_frame_map[REF_FRAMES]; - - /* TODO(jkoleszar): could expand active_ref_idx to 4, - with 0 as intra, and roll new_fb_idx into it.*/ - - /*Each frame can reference REFS_PER_FRAME buffers*/ - struct RefBuffer_s frame_refs[REFS_PER_FRAME]; - - int prev_fb_idx; - int new_fb_idx; - - /*last frame's frame type for motion search*/ - enum FRAME_TYPE last_frame_type; - enum FRAME_TYPE frame_type; - - int show_frame; - int last_show_frame; - int show_existing_frame; - - /*Flag signaling that the frame is encoded using only INTRA modes.*/ - uint8_t intra_only; - uint8_t last_intra_only; - - int allow_high_precision_mv; - - /*Flag signaling that the frame context should be reset to default - values. 0 or 1 implies don't reset, 2 reset just the context - specified in the frame header, 3 reset all contexts.*/ - int reset_frame_context; - - /*MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in - MODE_INFO (8-pixel) units.*/ - int MBs; - int mb_rows, mi_rows; - int mb_cols, mi_cols; - int mi_stride; - - /*Whether to use previous frame's motion vectors for prediction.*/ - int use_prev_frame_mvs; - - int refresh_frame_context; /* Two state 0 = NO, 1 = YES */ - - int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */ - - /*struct loopfilter lf;*/ - /*struct segmentation seg;*/ - - /*TODO(hkuang):Remove this as it is the same as frame_parallel_decode*/ - /* in pbi.*/ - int frame_parallel_decode; /* frame-based threading.*/ - - /*Context probabilities for reference frame prediction*/ - /*MV_REFERENCE_FRAME comp_fixed_ref;*/ - /*MV_REFERENCE_FRAME comp_var_ref[2];*/ - enum REFERENCE_MODE reference_mode; - - /*FRAME_CONTEXT *fc; */ /* this frame entropy */ - /*FRAME_CONTEXT *frame_contexts; */ /*FRAME_CONTEXTS*/ - /*unsigned int frame_context_idx; *//* Context to use/update */ - /*FRAME_COUNTS counts;*/ - - unsigned int current_video_frame; - enum BITSTREAM_PROFILE profile; - - enum vpx_bit_depth_t bit_depth; - - int error_resilient_mode; - int frame_parallel_decoding_mode; - - int byte_alignment; - int skip_loop_filter; - - /*External BufferPool passed from outside.*/ - struct BufferPool_s *buffer_pool; - - int above_context_alloc_cols; - -} VP9_COMMON; - -static void set_canvas(struct PIC_BUFFER_CONFIG_s *pic_config); -static int prepare_display_buf(struct VP9Decoder_s *pbi, - struct PIC_BUFFER_CONFIG_s *pic_config); -static int get_free_fb(struct VP9_Common_s *cm) -{ - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - int i; - - lock_buffer_pool(cm->buffer_pool); - for (i = 0; i < FRAME_BUFFERS; ++i) { - if (debug & VP9_DEBUG_BUFMGR_MORE) - pr_info("%s:%d, ref_count %d vf_ref %d used_by_d %d index %d\r\n", - __func__, i, frame_bufs[i].ref_count, - frame_bufs[i].buf.vf_ref, - frame_bufs[i].buf.used_by_display, - frame_bufs[i].buf.index); - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.used_by_display == 0) && - (frame_bufs[i].buf.index != -1) - ) - break; - } - if (i != FRAME_BUFFERS) { - frame_bufs[i].ref_count = 1; - /*pr_info("[MMU DEBUG 1] set ref_count[%d] : %d\r\n", - i, frame_bufs[i].ref_count);*/ - } else { - /* Reset i to be INVALID_IDX to indicate - no free buffer found*/ - i = INVALID_IDX; - } - - unlock_buffer_pool(cm->buffer_pool); - return i; -} - -static unsigned char is_buffer_empty(struct VP9_Common_s *cm) -{ - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - int i; - - for (i = 0; i < FRAME_BUFFERS; ++i) - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.used_by_display == 0) && - (frame_bufs[i].buf.index != -1) - ) - break; - if (i != FRAME_BUFFERS) - return 0; - - return 1; -} - -static struct PIC_BUFFER_CONFIG_s *get_frame_new_buffer(struct VP9_Common_s *cm) -{ - return &cm->buffer_pool->frame_bufs[cm->new_fb_idx].buf; -} - -static void ref_cnt_fb(struct RefCntBuffer_s *bufs, int *idx, int new_idx) -{ - const int ref_index = *idx; - - if (ref_index >= 0 && bufs[ref_index].ref_count > 0) { - bufs[ref_index].ref_count--; - /*pr_info("[MMU DEBUG 2] dec ref_count[%d] : %d\r\n", - ref_index, bufs[ref_index].ref_count);*/ - } - - *idx = new_idx; - - bufs[new_idx].ref_count++; - /*pr_info("[MMU DEBUG 3] inc ref_count[%d] : %d\r\n", - new_idx, bufs[new_idx].ref_count);*/ -} - -int vp9_release_frame_buffer(struct vpx_codec_frame_buffer_s *fb) -{ - struct InternalFrameBuffer_s *const int_fb = - (struct InternalFrameBuffer_s *)fb->priv; - if (int_fb) - int_fb->in_use = 0; - return 0; -} - -static int compute_losless_comp_body_size(int width, int height, - uint8_t is_bit_depth_10); - -static void setup_display_size(struct VP9_Common_s *cm, union param_u *params, - int print_header_info) -{ - cm->display_width = cm->width; - cm->display_height = cm->height; - if (params->p.display_size_present) { - if (print_header_info) - pr_info(" * 1-bit display_size_present read : 1\n"); - cm->display_width = params->p.display_width; - cm->display_height = params->p.display_height; - /*vp9_read_frame_size(rb, &cm->display_width, - &cm->display_height);*/ - } else { - if (print_header_info) - pr_info(" * 1-bit display_size_present read : 0\n"); - } -} - -static void resize_context_buffers(struct VP9_Common_s *cm, int width, - int height) -{ - if (cm->width != width || cm->height != height) { - /* to do ..*/ - cm->width = width; - cm->height = height; - pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width, - cm->height, width, height); - } - /* - if (cm->cur_frame->mvs == NULL || - cm->mi_rows > cm->cur_frame->mi_rows || - cm->mi_cols > cm->cur_frame->mi_cols) { - resize_mv_buffer(cm); - } - */ -} - -static int valid_ref_frame_size(int ref_width, int ref_height, - int this_width, int this_height) { - return 2 * this_width >= ref_width && - 2 * this_height >= ref_height && - this_width <= 16 * ref_width && - this_height <= 16 * ref_height; -} - -/* -static int valid_ref_frame_img_fmt(enum vpx_bit_depth_t ref_bit_depth, - int ref_xss, int ref_yss, - enum vpx_bit_depth_t this_bit_depth, - int this_xss, int this_yss) { - return ref_bit_depth == this_bit_depth && ref_xss == this_xss && - ref_yss == this_yss; -} -*/ - - -static int setup_frame_size( - struct VP9Decoder_s *pbi, - struct VP9_Common_s *cm, union param_u *params, - unsigned int *mmu_index_adr, - int print_header_info) { - int width, height; - struct BufferPool_s * const pool = cm->buffer_pool; - struct PIC_BUFFER_CONFIG_s *ybf; - int ret = 0; - - width = params->p.width; - height = params->p.height; - /*vp9_read_frame_size(rb, &width, &height);*/ - if (print_header_info) - pr_info(" * 16-bits w read : %d (width : %d)\n", width, height); - if (print_header_info) - pr_info - (" * 16-bits h read : %d (height : %d)\n", width, height); - - WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width); - -#ifdef VP9_10B_MMU - /* if(cm->prev_fb_idx >= 0) release_unused_4k(cm->prev_fb_idx);*/ - /* cm->prev_fb_idx = cm->new_fb_idx;*/ - /*pr_info - ("[DEBUG DEBUG]Before alloc_mmu, prev_fb_idx : %d, new_fb_idx : %d\r\n", - cm->prev_fb_idx, cm->new_fb_idx);*/ - ret = vp9_alloc_mmu(pbi, - cm->new_fb_idx, - params->p.width, - params->p.height, - params->p.bit_depth, - mmu_index_adr); - if (ret != 0) { - pr_err("can't alloc need mmu1,idx %d ret =%d\n", - cm->new_fb_idx, - ret); - return ret; - } -#endif - - resize_context_buffers(cm, width, height); - setup_display_size(cm, params, print_header_info); -#if 0 - lock_buffer_pool(pool); - if (vp9_realloc_frame_buffer( - get_frame_new_buffer(cm), cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_DEC_BORDER_IN_PIXELS, - cm->byte_alignment, - &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, - pool->get_fb_cb, pool->cb_priv)) { - unlock_buffer_pool(pool); - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - } - unlock_buffer_pool(pool); -#else - /* porting */ - ybf = get_frame_new_buffer(cm); - ybf->y_crop_width = width; - ybf->y_crop_height = height; - ybf->bit_depth = params->p.bit_depth; -#endif - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y; - pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = - (unsigned int)cm->bit_depth; - pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space; - return ret; -} - -static int setup_frame_size_with_refs( - struct VP9Decoder_s *pbi, - struct VP9_Common_s *cm, - union param_u *params, - unsigned int *mmu_index_adr, - int print_header_info) { - - int width, height; - int found = 0, i; - int has_valid_ref_frame = 0; - struct PIC_BUFFER_CONFIG_s *ybf; - struct BufferPool_s * const pool = cm->buffer_pool; - int ret = 0; - - for (i = 0; i < REFS_PER_FRAME; ++i) { - if ((params->p.same_frame_size >> - (REFS_PER_FRAME - i - 1)) & 0x1) { - struct PIC_BUFFER_CONFIG_s *const buf = - cm->frame_refs[i].buf; - /*if (print_header_info) - pr_info - ("1-bit same_frame_size[%d] read : 1\n", i);*/ - width = buf->y_crop_width; - height = buf->y_crop_height; - /*if (print_header_info) - pr_info - (" - same_frame_size width : %d\n", width);*/ - /*if (print_header_info) - pr_info - (" - same_frame_size height : %d\n", height);*/ - found = 1; - break; - } else { - /*if (print_header_info) - pr_info - ("1-bit same_frame_size[%d] read : 0\n", i);*/ - } - } - - if (!found) { - /*vp9_read_frame_size(rb, &width, &height);*/ - width = params->p.width; - height = params->p.height; - /*if (print_header_info) - pr_info - (" * 16-bits w read : %d (width : %d)\n", - width, height); - if (print_header_info) - pr_info - (" * 16-bits h read : %d (height : %d)\n", - width, height);*/ - } - - if (width <= 0 || height <= 0) { - pr_err("Error: Invalid frame size\r\n"); - return -1; - } - - params->p.width = width; - params->p.height = height; - - WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width); -#ifdef VP9_10B_MMU - /*if(cm->prev_fb_idx >= 0) release_unused_4k(cm->prev_fb_idx); - cm->prev_fb_idx = cm->new_fb_idx;*/ -/* pr_info - ("[DEBUG DEBUG]Before alloc_mmu, prev_fb_idx : %d, new_fb_idx : %d\r\n", - cm->prev_fb_idx, cm->new_fb_idx);*/ - ret = vp9_alloc_mmu(pbi, cm->new_fb_idx, - params->p.width, params->p.height, - params->p.bit_depth, mmu_index_adr); - if (ret != 0) { - pr_err("can't alloc need mmu,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.*/ - for (i = 0; i < REFS_PER_FRAME; ++i) { - struct RefBuffer_s * const ref_frame = &cm->frame_refs[i]; - has_valid_ref_frame |= - valid_ref_frame_size(ref_frame->buf->y_crop_width, - ref_frame->buf->y_crop_height, - width, height); - } - if (!has_valid_ref_frame) { - pr_err("Error: Referenced frame has invalid size\r\n"); - return -1; - } -#if 0 - for (i = 0; i < REFS_PER_FRAME; ++i) { - struct RefBuffer_s * const ref_frame = - &cm->frame_refs[i]; - if (!valid_ref_frame_img_fmt( - ref_frame->buf->bit_depth, - ref_frame->buf->subsampling_x, - ref_frame->buf->subsampling_y, - cm->bit_depth, - cm->subsampling_x, - cm->subsampling_y)) - pr_err - ("Referenced frame incompatible color fmt\r\n"); - return -1; - } -#endif - resize_context_buffers(cm, width, height); - setup_display_size(cm, params, print_header_info); - -#if 0 - lock_buffer_pool(pool); - if (vp9_realloc_frame_buffer( - get_frame_new_buffer(cm), cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_DEC_BORDER_IN_PIXELS, - cm->byte_alignment, - &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, - pool->get_fb_cb, - pool->cb_priv)) { - unlock_buffer_pool(pool); - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - } - unlock_buffer_pool(pool); -#else - /* porting */ - ybf = get_frame_new_buffer(cm); - ybf->y_crop_width = width; - ybf->y_crop_height = height; - ybf->bit_depth = params->p.bit_depth; -#endif - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y; - pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = - (unsigned int)cm->bit_depth; - pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space; - return ret; -} - -uint8_t print_header_info = 0; - -struct buff_s { - u32 buf_start; - u32 buf_size; - u32 buf_end; -} buff_t; - -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 vps; - 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 seg_map; -#ifdef VP9_10B_MMU - struct buff_s mmu_vbh; - struct buff_s cm_header; -#endif - struct buff_s mpred_above; - struct buff_s mpred_mv; - struct buff_s rpm; - struct buff_s lmem; -} BuffInfo_t; - -#ifdef MULTI_INSTANCE_SUPPORT -#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 - -static void vp9_work(struct work_struct *work); -#endif - -struct VP9Decoder_s { -#ifdef MULTI_INSTANCE_SUPPORT - unsigned char index; - - 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; - - struct BuffInfo_s work_space_buf_store; - unsigned long buf_start; - u32 buf_size; - u32 cma_alloc_count; - unsigned long cma_alloc_addr; -#endif - unsigned char m_ins_flag; - char *provider_name; - union param_u param; - int frame_count; - int pic_count; - u32 stat; - struct timer_list timer; - u32 frame_dur; - u32 frame_ar; - int fatal_error; - uint8_t init_flag; - uint8_t process_busy; - int show_frame_num; - struct buff_s mc_buf_spec; - struct dec_sysinfo vvp9_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; - - void *prob_buffer_addr; - void *count_buffer_addr; - dma_addr_t prob_buffer_phy_addr; - dma_addr_t count_buffer_phy_addr; - -#if 1 - /*VP9_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]; - 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]; - int buf_num; - int pic_num; - int lcu_size_log2; - unsigned int losless_comp_body_size; - - u32 video_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; - - /**/ - struct VP9_Common_s common; - struct RefCntBuffer_s *cur_buf; - int refresh_frame_flags; - uint8_t need_resync; - uint8_t hold_ref_buf; - uint8_t ready_for_new_data; - struct BufferPool_s vp9_buffer_pool; - - struct BuffInfo_s *work_space_buf; - struct buff_s *mc_buf; - - unsigned int frame_width; - unsigned int frame_height; - - unsigned short *rpm_ptr; - int init_pic_w; - int init_pic_h; - int lcu_total; - int lcu_size; - - int slice_type; - - int skip_flag; - int decode_idx; - int slice_idx; - uint8_t has_keyframe; - uint8_t wait_buf; - uint8_t error_flag; - - /* bit 0, for decoding; bit 1, for displaying */ - uint8_t ignore_bufmgr_error; - int PB_skip_mode; - int PB_skip_count_after_decoding; - /*hw*/ - - u32 pre_stream_offset; - - unsigned int dec_status; - u32 last_put_idx; - int new_frame_displayed; - void *mmu_box; - void *bmmu_box; -} VP9Decoder; - -static int vp9_print(struct VP9Decoder_s *pbi, - int flag, const char *fmt, ...) -{ -#define HEVC_PRINT_BUF 128 - unsigned char buf[HEVC_PRINT_BUF]; - int len = 0; - if (pbi == NULL || - (flag == 0) || - (debug & flag)) { - va_list args; - va_start(args, fmt); - if (pbi) - len = sprintf(buf, "[%d]", pbi->index); - vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args); - pr_info("%s", buf); - va_end(args); - } - return 0; -} - -#ifdef MULTI_INSTANCE_SUPPORT -static int vp9_print_cont(struct VP9Decoder_s *pbi, - int flag, const char *fmt, ...) -{ - unsigned char buf[HEVC_PRINT_BUF]; - int len = 0; - if (pbi == 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; -} -#endif - -#ifdef VP9_10B_MMU -int vp9_alloc_mmu( - struct VP9Decoder_s *pbi, - 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 == VPX_BITS_10); - int picture_size; - int cur_mmu_4k_number; - - picture_size = compute_losless_comp_body_size(pic_width, pic_height, - bit_depth_10); - cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12); - return decoder_mmu_box_alloc_idx( - pbi->mmu_box, - cur_buf_idx, - cur_mmu_4k_number, - mmu_index_adr); -} -#endif -static void decrease_ref_count(int idx, struct RefCntBuffer_s *const frame_bufs, - struct BufferPool_s *const pool) -{ - if (idx >= 0) { - --frame_bufs[idx].ref_count; - /*pr_info("[MMU DEBUG 7] dec ref_count[%d] : %d\r\n", idx, - frame_bufs[idx].ref_count);*/ - /*A worker may only get a free framebuffer index when - calling get_free_fb. But the private buffer is not set up - until finish decoding header. So any error happens during - decoding header, the frame_bufs will not have valid priv - buffer.*/ - - if (frame_bufs[idx].ref_count == 0 && - frame_bufs[idx].raw_frame_buffer.priv) - vp9_release_frame_buffer - (&frame_bufs[idx].raw_frame_buffer); - } -} - -static void generate_next_ref_frames(struct VP9Decoder_s *pbi) -{ - struct VP9_Common_s *const cm = &pbi->common; - struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; - struct BufferPool_s *const pool = cm->buffer_pool; - int mask, ref_index = 0; - - /* Generate next_ref_frame_map.*/ - lock_buffer_pool(pool); - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - if (mask & 1) { - cm->next_ref_frame_map[ref_index] = cm->new_fb_idx; - ++frame_bufs[cm->new_fb_idx].ref_count; - /*pr_info("[MMU DEBUG 4] inc ref_count[%d] : %d\r\n", - cm->new_fb_idx, frame_bufs[cm->new_fb_idx].ref_count);*/ - } else - cm->next_ref_frame_map[ref_index] = - cm->ref_frame_map[ref_index]; - /* Current thread holds the reference frame.*/ - if (cm->ref_frame_map[ref_index] >= 0) { - ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count; - /*pr_info - ("[MMU DEBUG 5] inc ref_count[%d] : %d\r\n", - cm->ref_frame_map[ref_index], - frame_bufs[cm->ref_frame_map[ref_index]].ref_count);*/ - } - ++ref_index; - } - - for (; ref_index < REF_FRAMES; ++ref_index) { - cm->next_ref_frame_map[ref_index] = - cm->ref_frame_map[ref_index]; - /* Current thread holds the reference frame.*/ - if (cm->ref_frame_map[ref_index] >= 0) { - ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count; - /*pr_info("[MMU DEBUG 6] inc ref_count[%d] : %d\r\n", - cm->ref_frame_map[ref_index], - frame_bufs[cm->ref_frame_map[ref_index]].ref_count);*/ - } - } - unlock_buffer_pool(pool); - return; -} - -static void refresh_ref_frames(struct VP9Decoder_s *pbi) - -{ - struct VP9_Common_s *const cm = &pbi->common; - struct BufferPool_s *pool = cm->buffer_pool; - struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; - int mask, ref_index = 0; - - lock_buffer_pool(pool); - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - const int old_idx = cm->ref_frame_map[ref_index]; - /*Current thread releases the holding of reference frame.*/ - decrease_ref_count(old_idx, frame_bufs, pool); - - /*Release the reference frame in reference map.*/ - if ((mask & 1) && old_idx >= 0) - decrease_ref_count(old_idx, frame_bufs, pool); - cm->ref_frame_map[ref_index] = - cm->next_ref_frame_map[ref_index]; - ++ref_index; - } - - /*Current thread releases the holding of reference frame.*/ - for (; ref_index < REF_FRAMES && !cm->show_existing_frame; - ++ref_index) { - const int old_idx = cm->ref_frame_map[ref_index]; - decrease_ref_count(old_idx, frame_bufs, pool); - cm->ref_frame_map[ref_index] = - cm->next_ref_frame_map[ref_index]; - } - unlock_buffer_pool(pool); - return; -} -int vp9_bufmgr_process(struct VP9Decoder_s *pbi, union param_u *params) -{ - struct VP9_Common_s *const cm = &pbi->common; - struct BufferPool_s *pool = cm->buffer_pool; - struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; - int i; - int ret; - - pbi->ready_for_new_data = 0; - - if (pbi->has_keyframe == 0 && - params->p.frame_type != KEY_FRAME){ - on_no_keyframe_skiped++; - return -2; - } - pbi->has_keyframe = 1; - on_no_keyframe_skiped = 0; -#ifdef VP9_10B_MMU - if (cm->prev_fb_idx >= 0) { - long used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16); - decoder_mmu_box_free_idx_tail(pbi->mmu_box, - cm->prev_fb_idx, used_4k_num); - } -#endif - if (cm->new_fb_idx >= 0 - && frame_bufs[cm->new_fb_idx].ref_count == 0){ - vp9_release_frame_buffer - (&frame_bufs[cm->new_fb_idx].raw_frame_buffer); - } - /*pr_info("Before get_free_fb, prev_fb_idx : %d, new_fb_idx : %d\r\n", - cm->prev_fb_idx, cm->new_fb_idx);*/ - cm->new_fb_idx = get_free_fb(cm); - cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; - /*if (debug & VP9_DEBUG_BUFMGR) - pr_info("[VP9 DEBUG]%s(get_free_fb): %d\r\n", __func__, - cm->new_fb_idx);*/ - if (cm->new_fb_idx == INVALID_IDX) { - pr_info("get_free_fb error\r\n"); - return -1; - } - pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; -#ifdef VP9_10B_MMU - /* moved to after picture size ready - alloc_mmu(cm, params->p.width, params->p.height, - params->p.bit_depth, pbi->frame_mmu_map_addr);*/ - cm->prev_fb_idx = cm->new_fb_idx; -#endif - /*read_uncompressed_header()*/ - cm->last_frame_type = cm->frame_type; - cm->last_intra_only = cm->intra_only; - cm->profile = params->p.profile; - if (cm->profile >= MAX_PROFILES) { - pr_err("Error: Unsupported profile %d\r\n", cm->profile); - return -1; - } - cm->show_existing_frame = params->p.show_existing_frame; - if (cm->show_existing_frame) { - /* Show an existing frame directly.*/ - int frame_to_show_idx = params->p.frame_to_show_idx; - int frame_to_show; - if (frame_to_show_idx >= REF_FRAMES) { - pr_info("frame_to_show_idx %d exceed max index\r\n", - frame_to_show_idx); - return -1; - } - - frame_to_show = cm->ref_frame_map[frame_to_show_idx]; - /*pr_info("frame_to_show %d\r\n", frame_to_show);*/ - lock_buffer_pool(pool); - if (frame_to_show < 0 || - frame_bufs[frame_to_show].ref_count < 1) { - unlock_buffer_pool(pool); - pr_err - ("Error:Buffer %d does not contain a decoded frame", - frame_to_show); - return -1; - } - - ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show); - unlock_buffer_pool(pool); - pbi->refresh_frame_flags = 0; - /*cm->lf.filter_level = 0;*/ - cm->show_frame = 1; - - /* - if (pbi->frame_parallel_decode) { - for (i = 0; i < REF_FRAMES; ++i) - cm->next_ref_frame_map[i] = - cm->ref_frame_map[i]; - } - */ - /* do not decode, search next start code */ - return 1; - } - cm->frame_type = params->p.frame_type; - cm->show_frame = params->p.show_frame; - cm->error_resilient_mode = params->p.error_resilient_mode; - - - if (cm->frame_type == KEY_FRAME) { - pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1; - - for (i = 0; i < REFS_PER_FRAME; ++i) { - cm->frame_refs[i].idx = INVALID_IDX; - cm->frame_refs[i].buf = NULL; - } - - ret = setup_frame_size(pbi, - cm, params, pbi->frame_mmu_map_addr, - print_header_info); - if (ret) - return -1; - if (pbi->need_resync) { - memset(&cm->ref_frame_map, -1, - sizeof(cm->ref_frame_map)); - pbi->need_resync = 0; - } - } else { - cm->intra_only = cm->show_frame ? 0 : params->p.intra_only; - /*if (print_header_info) { - if (cm->show_frame) - pr_info - ("intra_only set to 0 because of show_frame\n"); - else - pr_info - ("1-bit intra_only read: %d\n", cm->intra_only); - }*/ - - - cm->reset_frame_context = cm->error_resilient_mode ? - 0 : params->p.reset_frame_context; - if (print_header_info) { - if (cm->error_resilient_mode) - pr_info - ("reset to 0 error_resilient_mode\n"); - else - pr_info - (" * 2-bits reset_frame_context read : %d\n", - cm->reset_frame_context); - } - - if (cm->intra_only) { - if (cm->profile > PROFILE_0) { - /*read_bitdepth_colorspace_sampling(cm, - rb, print_header_info);*/ - } else { - /*NOTE: The intra-only frame header - does not include the specification - of either the color format or color sub-sampling - in profile 0. VP9 specifies that the default - color format should be YUV 4:2:0 in this - case (normative).*/ - cm->color_space = VPX_CS_BT_601; - cm->subsampling_y = cm->subsampling_x = 1; - cm->bit_depth = VPX_BITS_8; - cm->use_highbitdepth = 0; - } - - pbi->refresh_frame_flags = - params->p.refresh_frame_flags; - /*if (print_header_info) - pr_info("*%d-bits refresh_frame read:0x%x\n", - REF_FRAMES, pbi->refresh_frame_flags);*/ - ret = setup_frame_size(pbi, - cm, - params, - pbi->frame_mmu_map_addr, - print_header_info); - if (ret) { - return -1; - } - if (pbi->need_resync) { - memset(&cm->ref_frame_map, -1, - sizeof(cm->ref_frame_map)); - pbi->need_resync = 0; - } - } else if (pbi->need_resync != 1) { /* Skip if need resync */ - pbi->refresh_frame_flags = - params->p.refresh_frame_flags; - if (print_header_info) - pr_info - ("*%d-bits refresh_frame read:0x%x\n", - REF_FRAMES, pbi->refresh_frame_flags); - for (i = 0; i < REFS_PER_FRAME; ++i) { - const int ref = - (params->p.ref_info >> - (((REFS_PER_FRAME-i-1)*4)+1)) - & 0x7; - const int idx = - cm->ref_frame_map[ref]; - struct RefBuffer_s * const ref_frame = - &cm->frame_refs[i]; - if (print_header_info) - pr_info - ("*%d-bits ref[%d]read:%d\n", - REF_FRAMES_LOG2, i, ref); - ref_frame->idx = idx; - ref_frame->buf = &frame_bufs[idx].buf; - cm->ref_frame_sign_bias[LAST_FRAME + i] - = (params->p.ref_info >> - ((REFS_PER_FRAME-i-1)*4)) & 0x1; - if (print_header_info) - pr_info - ("1bit ref_frame_sign_bias"); - /*pr_info - ("%dread: %d\n", - LAST_FRAME+i, - cm->ref_frame_sign_bias - [LAST_FRAME + i]);*/ - /*pr_info - ("[VP9 DEBUG]%s(get ref):%d\r\n", - __func__, ref_frame->idx);*/ - - } - - ret = setup_frame_size_with_refs( - pbi, - cm, - params, - pbi->frame_mmu_map_addr, - print_header_info); - if (ret) { - return -1; - } - for (i = 0; i < REFS_PER_FRAME; ++i) { - /*struct RefBuffer_s *const ref_buf = - &cm->frame_refs[i];*/ - /* to do: - vp9_setup_scale_factors_for_frame*/ - } - } - } - - get_frame_new_buffer(cm)->bit_depth = cm->bit_depth; - get_frame_new_buffer(cm)->color_space = cm->color_space; - get_frame_new_buffer(cm)->slice_type = cm->frame_type; - - if (pbi->need_resync) - pr_err - ("Error: Keyframe/intra-only frame required to reset\r\n"); - generate_next_ref_frames(pbi); - pbi->hold_ref_buf = 1; - -#if 0 - if (frame_is_intra_only(cm) || cm->error_resilient_mode) - vp9_setup_past_independence(cm); - setup_loopfilter(&cm->lf, rb, print_header_info); - setup_quantization(cm, &pbi->mb, rb, print_header_info); - setup_segmentation(&cm->seg, rb, print_header_info); - setup_segmentation_dequant(cm, print_header_info); - - setup_tile_info(cm, rb, print_header_info); - sz = vp9_rb_read_literal(rb, 16); - if (print_header_info) - pr_info(" * 16-bits size read : %d (0x%x)\n", sz, sz); - - if (sz == 0) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid header size"); -#endif - /*end read_uncompressed_header()*/ - cm->use_prev_frame_mvs = !cm->error_resilient_mode && - cm->width == cm->last_width && - cm->height == cm->last_height && - !cm->last_intra_only && - cm->last_show_frame && - (cm->last_frame_type != KEY_FRAME); - - /*pr_info - ("set use_prev_frame_mvs to %d (last_width %d last_height %d", - cm->use_prev_frame_mvs, cm->last_width, cm->last_height); - pr_info - (" last_intra_only %d last_show_frame %d last_frame_type %d)\n", - cm->last_intra_only, cm->last_show_frame, cm->last_frame_type);*/ - return 0; -} - - -void swap_frame_buffers(struct VP9Decoder_s *pbi) -{ - int ref_index = 0; - struct VP9_Common_s *const cm = &pbi->common; - struct BufferPool_s *const pool = cm->buffer_pool; - struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs; - refresh_ref_frames(pbi); - pbi->hold_ref_buf = 0; - cm->frame_to_show = get_frame_new_buffer(cm); - - /*if (!pbi->frame_parallel_decode || !cm->show_frame) {*/ - lock_buffer_pool(pool); - --frame_bufs[cm->new_fb_idx].ref_count; - /*pr_info("[MMU DEBUG 8] dec ref_count[%d] : %d\r\n", cm->new_fb_idx, - frame_bufs[cm->new_fb_idx].ref_count);*/ - unlock_buffer_pool(pool); - /*}*/ - - /*Invalidate these references until the next frame starts.*/ - for (ref_index = 0; ref_index < 3; ref_index++) - cm->frame_refs[ref_index].idx = -1; -} - -#if 0 -static void check_resync(vpx_codec_alg_priv_t *const ctx, - const struct VP9Decoder_s *const pbi) -{ - /* Clear resync flag if worker got a key frame or intra only frame.*/ - if (ctx->need_resync == 1 && pbi->need_resync == 0 && - (pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME)) - ctx->need_resync = 0; -} -#endif - -int vp9_get_raw_frame(struct VP9Decoder_s *pbi, struct PIC_BUFFER_CONFIG_s *sd) -{ - struct VP9_Common_s *const cm = &pbi->common; - int ret = -1; - - if (pbi->ready_for_new_data == 1) - return ret; - - pbi->ready_for_new_data = 1; - - /* no raw frame to show!!! */ - if (!cm->show_frame) - return ret; - - pbi->ready_for_new_data = 1; - - *sd = *cm->frame_to_show; - ret = 0; - - return ret; -} - -int vp9_bufmgr_init(struct VP9Decoder_s *pbi, struct BuffInfo_s *buf_spec_i, - struct buff_s *mc_buf_i) { - struct VP9_Common_s *cm = &pbi->common; - - /*memset(pbi, 0, sizeof(struct VP9Decoder));*/ - pbi->frame_count = 0; - pbi->pic_count = 0; - pbi->pre_stream_offset = 0; - cm->buffer_pool = &pbi->vp9_buffer_pool; - spin_lock_init(&cm->buffer_pool->lock); - cm->prev_fb_idx = INVALID_IDX; - cm->new_fb_idx = INVALID_IDX; - pr_info - ("After vp9_bufmgr_init, prev_fb_idx : %d, new_fb_idx : %d\r\n", - cm->prev_fb_idx, cm->new_fb_idx); - pbi->need_resync = 1; - /* Initialize the references to not point to any frame buffers.*/ - memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); - memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map)); - cm->current_video_frame = 0; - pbi->ready_for_new_data = 1; - - /* private init */ - pbi->work_space_buf = buf_spec_i; - pbi->mc_buf = mc_buf_i; - pbi->rpm_addr = NULL; - pbi->lmem_addr = NULL; - - pbi->use_cma_flag = 0; - pbi->decode_idx = 0; - pbi->slice_idx = 0; - /*int m_uiMaxCUWidth = 1<<7;*/ - /*int m_uiMaxCUHeight = 1<<7;*/ - pbi->has_keyframe = 0; - pbi->skip_flag = 0; - pbi->wait_buf = 0; - pbi->error_flag = 0; - - pbi->pts_mode = PTS_NORMAL; - pbi->last_pts = 0; - pbi->last_lookup_pts = 0; - pbi->last_pts_us64 = 0; - pbi->last_lookup_pts_us64 = 0; - pbi->shift_byte_count = 0; - pbi->shift_byte_count_lo = 0; - pbi->shift_byte_count_hi = 0; - pbi->pts_mode_switching_count = 0; - pbi->pts_mode_recovery_count = 0; - - pbi->buf_num = 0; - pbi->pic_num = 0; - - return 0; -} - - -int vp9_bufmgr_postproc(struct VP9Decoder_s *pbi) -{ - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s sd; - swap_frame_buffers(pbi); - if (!cm->show_existing_frame) { - cm->last_show_frame = cm->show_frame; - cm->prev_frame = cm->cur_frame; -#if 0 - if (cm->seg.enabled && !pbi->frame_parallel_decode) - vp9_swap_current_and_last_seg_map(cm); -#endif - } - cm->last_width = cm->width; - cm->last_height = cm->height; - if (cm->show_frame) - cm->current_video_frame++; - - if (vp9_get_raw_frame(pbi, &sd) == 0) { - /*pr_info("Display frame index %d\r\n", sd.index);*/ - sd.stream_offset = pbi->pre_stream_offset; - prepare_display_buf(pbi, &sd); - pbi->pre_stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT); - } /*else - pr_info - ("Not display this frame,ready_for_new_data%d show_frame%d\r\n", - pbi->ready_for_new_data, cm->show_frame);*/ - return 0; -} - -struct VP9Decoder_s vp9_decoder; -union param_u vp9_param; - -/************************************************** - -VP9 buffer management end - -***************************************************/ - - -#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 -/* 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 - 0x10, double write only -*/ -static u32 double_write_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 vp9_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; -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 */ -static u32 dbg_nal_skip_count; -#endif -/*for debug*/ -static u32 decode_stop_pos; -static u32 decode_stop_pos_pre; -static u32 decode_pic_begin; -static uint slice_parse_begin; -static u32 step; -#ifdef MIX_STREAM_SUPPORT -#ifdef SUPPORT_4K2K -static u32 buf_alloc_width = 4096; -static u32 buf_alloc_height = 2304; -#else -static u32 buf_alloc_width = 1920; -static u32 buf_alloc_height = 1088; -#endif -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; -/* -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; - -/* -use_cma: 1, use both reserver memory and cma for buffers -2, only use cma for buffers -*/ -static u32 use_cma = 2; - -static u32 max_decoding_time; -/* -error handling -*/ -/*error_handle_policy: -bit 0: 0, auto skip error_skip_nal_count nals before error recovery; -1, skip error_skip_nal_count nals before error recovery; -bit 1 (valid only when bit0 == 1): -1, wait vps/sps/pps after error recovery; -bit 2 (valid only when bit0 == 0): -0, auto search after error recovery (vp9_recover() called); -1, manual search after error recovery -(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2)) - -bit 4: 0, set error_mark after reset/recover - 1, do not set error_mark after reset/recover -bit 5: 0, check total lcu for every picture - 1, do not check total lcu - -*/ - -static u32 error_handle_policy; -/*static u32 parser_sei_enable = 1;*/ - -static u32 max_buf_num = 12; - - -static DEFINE_MUTEX(vvp9_mutex); -#ifndef MULTI_INSTANCE_SUPPORT -static struct device *cma_dev; -#endif - -#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0 -#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1 -#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2 -#define VP9_ADAPT_PROB_REG HEVC_ASSIST_SCRATCH_3 -#define VP9_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_4 -#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5 -#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6 -#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7 -#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 HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E -#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F -#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F -#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L -#ifdef MULTI_INSTANCE_SUPPORT -#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M -#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N -#else -#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M -#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N -#endif -#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 -#define DECODE_MODE HEVC_ASSIST_SCRATCH_J -#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K - -#ifdef MULTI_INSTANCE_SUPPORT -#define RPM_BUF_SIZE (0x400 * 2) -#else -#define RPM_BUF_SIZE (0x80*2) -#endif -#define LMEM_BUF_SIZE (0x400 * 2) - -#define WORK_BUF_SPEC_NUM 2 -static struct BuffInfo_s amvvp9_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 = { - /* 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, - }, -#ifdef VP9_10B_MMU - .mmu_vbh = { - .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/ - }, - .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*/ - }, - .mpred_mv = {/* 1080p, 0x40000 per buffer */ - .buf_size = 0x40000 * FRAME_BUFFERS, - }, - .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, - }, -#ifdef VP9_10B_MMU - .mmu_vbh = { - .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/ - }, - .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*/ - }, - .mpred_mv = { - /* .buf_size = 0x100000*16, - //4k2k , 0x100000 per buffer */ - /* 4096x2304 , 0x120000 per buffer */ - .buf_size = 0x120000 * FRAME_BUFFERS, - }, - .rpm = { - .buf_size = RPM_BUF_SIZE, - }, - .lmem = { - .buf_size = 0x400 * 2, - } - } -}; - - -/*Losless compression body buffer size 4K per 64x32 (jt)*/ -int compute_losless_comp_body_size(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 VP9_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 - if (debug & VP9_DEBUG_BUFMGR_MORE) - pr_info("%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(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; - if (debug & VP9_DEBUG_BUFMGR_MORE) - pr_info("%s(%d,%d)=>%d\n", - __func__, width, height, - hsize); - - return hsize; -} - -static void init_buff_spec(struct VP9Decoder_s *pbi, - struct BuffInfo_s *buf_spec) -{ - void *mem_start_virt; - 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->sps.buf_start = - buf_spec->vps.buf_start + buf_spec->vps.buf_size; - buf_spec->pps.buf_start = - buf_spec->sps.buf_start + buf_spec->sps.buf_size; - buf_spec->sao_up.buf_start = - buf_spec->pps.buf_start + buf_spec->pps.buf_size; - buf_spec->swap_buf.buf_start = - buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size; - buf_spec->swap_buf2.buf_start = - buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size; - buf_spec->scalelut.buf_start = - buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.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->seg_map.buf_start = - buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size; -#ifdef VP9_10B_MMU - buf_spec->mmu_vbh.buf_start = - buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size; - buf_spec->cm_header.buf_start = - buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size; - buf_spec->mpred_above.buf_start = - buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size; -#else - buf_spec->mpred_above.buf_start = - buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size; -#endif - buf_spec->mpred_mv.buf_start = - buf_spec->mpred_above.buf_start + - buf_spec->mpred_above.buf_size; - if (debug & VP9_DEBUG_SEND_PARAM_WITH_REG) { - buf_spec->end_adr = - buf_spec->mpred_mv.buf_start + - buf_spec->mpred_mv.buf_size; - } else { - buf_spec->rpm.buf_start = - buf_spec->mpred_mv.buf_start + - buf_spec->mpred_mv.buf_size; - if (debug & VP9_DEBUG_UCODE) { - buf_spec->lmem.buf_start = - buf_spec->rpm.buf_start + - buf_spec->rpm.buf_size; - buf_spec->end_adr = - buf_spec->lmem.buf_start + - buf_spec->lmem.buf_size; - } else { - buf_spec->end_adr = - buf_spec->rpm.buf_start + - buf_spec->rpm.buf_size; - } - } - 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("vps.buf_start :%x\n", - buf_spec->vps.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("seg_map.buf_start :%x\n", - buf_spec->seg_map.buf_start); -#ifdef VP9_10B_MMU - pr_info("mmu_vbh.buf_start :%x\n", - buf_spec->mmu_vbh.buf_start); - pr_info("cm_header.buf_start :%x\n", - buf_spec->cm_header.buf_start); -#endif - pr_info("mpred_above.buf_start :%x\n", - buf_spec->mpred_above.buf_start); - pr_info("mpred_mv.buf_start :%x\n", - buf_spec->mpred_mv.buf_start); - if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) { - pr_info("rpm.buf_start :%x\n", - buf_spec->rpm.buf_start); - } - } - -} - -/*==================================================== -======================================================================== -vp9_prob define -========================================================================*/ -#define VP9_PARTITION_START 0 -#define VP9_PARTITION_SIZE_STEP (3 * 4) -#define VP9_PARTITION_ONE_SIZE (4 * VP9_PARTITION_SIZE_STEP) -#define VP9_PARTITION_KEY_START 0 -#define VP9_PARTITION_P_START VP9_PARTITION_ONE_SIZE -#define VP9_PARTITION_SIZE (2 * VP9_PARTITION_ONE_SIZE) -#define VP9_SKIP_START (VP9_PARTITION_START + VP9_PARTITION_SIZE) -#define VP9_SKIP_SIZE 4 /* only use 3*/ -#define VP9_TX_MODE_START (VP9_SKIP_START+VP9_SKIP_SIZE) -#define VP9_TX_MODE_8_0_OFFSET 0 -#define VP9_TX_MODE_8_1_OFFSET 1 -#define VP9_TX_MODE_16_0_OFFSET 2 -#define VP9_TX_MODE_16_1_OFFSET 4 -#define VP9_TX_MODE_32_0_OFFSET 6 -#define VP9_TX_MODE_32_1_OFFSET 9 -#define VP9_TX_MODE_SIZE 12 -#define VP9_COEF_START (VP9_TX_MODE_START+VP9_TX_MODE_SIZE) -#define VP9_COEF_BAND_0_OFFSET 0 -#define VP9_COEF_BAND_1_OFFSET (VP9_COEF_BAND_0_OFFSET + 3 * 3 + 1) -#define VP9_COEF_BAND_2_OFFSET (VP9_COEF_BAND_1_OFFSET + 6 * 3) -#define VP9_COEF_BAND_3_OFFSET (VP9_COEF_BAND_2_OFFSET + 6 * 3) -#define VP9_COEF_BAND_4_OFFSET (VP9_COEF_BAND_3_OFFSET + 6 * 3) -#define VP9_COEF_BAND_5_OFFSET (VP9_COEF_BAND_4_OFFSET + 6 * 3) -#define VP9_COEF_SIZE_ONE_SET 100 /* ((3 +5*6)*3 + 1 padding)*/ -#define VP9_COEF_4X4_START (VP9_COEF_START + 0 * VP9_COEF_SIZE_ONE_SET) -#define VP9_COEF_8X8_START (VP9_COEF_START + 4 * VP9_COEF_SIZE_ONE_SET) -#define VP9_COEF_16X16_START (VP9_COEF_START + 8 * VP9_COEF_SIZE_ONE_SET) -#define VP9_COEF_32X32_START (VP9_COEF_START + 12 * VP9_COEF_SIZE_ONE_SET) -#define VP9_COEF_SIZE_PLANE (2 * VP9_COEF_SIZE_ONE_SET) -#define VP9_COEF_SIZE (4 * 2 * 2 * VP9_COEF_SIZE_ONE_SET) -#define VP9_INTER_MODE_START (VP9_COEF_START+VP9_COEF_SIZE) -#define VP9_INTER_MODE_SIZE 24 /* only use 21 ( #*7)*/ -#define VP9_INTERP_START (VP9_INTER_MODE_START+VP9_INTER_MODE_SIZE) -#define VP9_INTERP_SIZE 8 -#define VP9_INTRA_INTER_START (VP9_INTERP_START+VP9_INTERP_SIZE) -#define VP9_INTRA_INTER_SIZE 4 -#define VP9_INTERP_INTRA_INTER_START VP9_INTERP_START -#define VP9_INTERP_INTRA_INTER_SIZE (VP9_INTERP_SIZE + VP9_INTRA_INTER_SIZE) -#define VP9_COMP_INTER_START \ - (VP9_INTERP_INTRA_INTER_START+VP9_INTERP_INTRA_INTER_SIZE) -#define VP9_COMP_INTER_SIZE 5 -#define VP9_COMP_REF_START (VP9_COMP_INTER_START+VP9_COMP_INTER_SIZE) -#define VP9_COMP_REF_SIZE 5 -#define VP9_SINGLE_REF_START (VP9_COMP_REF_START+VP9_COMP_REF_SIZE) -#define VP9_SINGLE_REF_SIZE 10 -#define VP9_REF_MODE_START VP9_COMP_INTER_START -#define VP9_REF_MODE_SIZE \ - (VP9_COMP_INTER_SIZE+VP9_COMP_REF_SIZE+VP9_SINGLE_REF_SIZE) -#define VP9_IF_Y_MODE_START (VP9_REF_MODE_START+VP9_REF_MODE_SIZE) -#define VP9_IF_Y_MODE_SIZE 36 -#define VP9_IF_UV_MODE_START (VP9_IF_Y_MODE_START+VP9_IF_Y_MODE_SIZE) -#define VP9_IF_UV_MODE_SIZE 92 /* only use 90*/ -#define VP9_MV_JOINTS_START (VP9_IF_UV_MODE_START+VP9_IF_UV_MODE_SIZE) -#define VP9_MV_JOINTS_SIZE 3 -#define VP9_MV_SIGN_0_START (VP9_MV_JOINTS_START+VP9_MV_JOINTS_SIZE) -#define VP9_MV_SIGN_0_SIZE 1 -#define VP9_MV_CLASSES_0_START (VP9_MV_SIGN_0_START+VP9_MV_SIGN_0_SIZE) -#define VP9_MV_CLASSES_0_SIZE 10 -#define VP9_MV_CLASS0_0_START (VP9_MV_CLASSES_0_START+VP9_MV_CLASSES_0_SIZE) -#define VP9_MV_CLASS0_0_SIZE 1 -#define VP9_MV_BITS_0_START (VP9_MV_CLASS0_0_START+VP9_MV_CLASS0_0_SIZE) -#define VP9_MV_BITS_0_SIZE 10 -#define VP9_MV_SIGN_1_START (VP9_MV_BITS_0_START+VP9_MV_BITS_0_SIZE) -#define VP9_MV_SIGN_1_SIZE 1 -#define VP9_MV_CLASSES_1_START \ - (VP9_MV_SIGN_1_START+VP9_MV_SIGN_1_SIZE) -#define VP9_MV_CLASSES_1_SIZE 10 -#define VP9_MV_CLASS0_1_START \ - (VP9_MV_CLASSES_1_START+VP9_MV_CLASSES_1_SIZE) -#define VP9_MV_CLASS0_1_SIZE 1 -#define VP9_MV_BITS_1_START \ - (VP9_MV_CLASS0_1_START+VP9_MV_CLASS0_1_SIZE) -#define VP9_MV_BITS_1_SIZE 10 -#define VP9_MV_CLASS0_FP_0_START \ - (VP9_MV_BITS_1_START+VP9_MV_BITS_1_SIZE) -#define VP9_MV_CLASS0_FP_0_SIZE 9 -#define VP9_MV_CLASS0_FP_1_START \ - (VP9_MV_CLASS0_FP_0_START+VP9_MV_CLASS0_FP_0_SIZE) -#define VP9_MV_CLASS0_FP_1_SIZE 9 -#define VP9_MV_CLASS0_HP_0_START \ - (VP9_MV_CLASS0_FP_1_START+VP9_MV_CLASS0_FP_1_SIZE) -#define VP9_MV_CLASS0_HP_0_SIZE 2 -#define VP9_MV_CLASS0_HP_1_START \ - (VP9_MV_CLASS0_HP_0_START+VP9_MV_CLASS0_HP_0_SIZE) -#define VP9_MV_CLASS0_HP_1_SIZE 2 -#define VP9_MV_START VP9_MV_JOINTS_START -#define VP9_MV_SIZE 72 /*only use 69*/ - -#define VP9_TOTAL_SIZE (VP9_MV_START + VP9_MV_SIZE) - - -/*======================================================================== - vp9_count_mem define -========================================================================*/ -#define VP9_COEF_COUNT_START 0 -#define VP9_COEF_COUNT_BAND_0_OFFSET 0 -#define VP9_COEF_COUNT_BAND_1_OFFSET \ - (VP9_COEF_COUNT_BAND_0_OFFSET + 3*5) -#define VP9_COEF_COUNT_BAND_2_OFFSET \ - (VP9_COEF_COUNT_BAND_1_OFFSET + 6*5) -#define VP9_COEF_COUNT_BAND_3_OFFSET \ - (VP9_COEF_COUNT_BAND_2_OFFSET + 6*5) -#define VP9_COEF_COUNT_BAND_4_OFFSET \ - (VP9_COEF_COUNT_BAND_3_OFFSET + 6*5) -#define VP9_COEF_COUNT_BAND_5_OFFSET \ - (VP9_COEF_COUNT_BAND_4_OFFSET + 6*5) -#define VP9_COEF_COUNT_SIZE_ONE_SET 165 /* ((3 +5*6)*5 */ -#define VP9_COEF_COUNT_4X4_START \ - (VP9_COEF_COUNT_START + 0*VP9_COEF_COUNT_SIZE_ONE_SET) -#define VP9_COEF_COUNT_8X8_START \ - (VP9_COEF_COUNT_START + 4*VP9_COEF_COUNT_SIZE_ONE_SET) -#define VP9_COEF_COUNT_16X16_START \ - (VP9_COEF_COUNT_START + 8*VP9_COEF_COUNT_SIZE_ONE_SET) -#define VP9_COEF_COUNT_32X32_START \ - (VP9_COEF_COUNT_START + 12*VP9_COEF_COUNT_SIZE_ONE_SET) -#define VP9_COEF_COUNT_SIZE_PLANE (2 * VP9_COEF_COUNT_SIZE_ONE_SET) -#define VP9_COEF_COUNT_SIZE (4 * 2 * 2 * VP9_COEF_COUNT_SIZE_ONE_SET) - -#define VP9_INTRA_INTER_COUNT_START \ - (VP9_COEF_COUNT_START+VP9_COEF_COUNT_SIZE) -#define VP9_INTRA_INTER_COUNT_SIZE (4*2) -#define VP9_COMP_INTER_COUNT_START \ - (VP9_INTRA_INTER_COUNT_START+VP9_INTRA_INTER_COUNT_SIZE) -#define VP9_COMP_INTER_COUNT_SIZE (5*2) -#define VP9_COMP_REF_COUNT_START \ - (VP9_COMP_INTER_COUNT_START+VP9_COMP_INTER_COUNT_SIZE) -#define VP9_COMP_REF_COUNT_SIZE (5*2) -#define VP9_SINGLE_REF_COUNT_START \ - (VP9_COMP_REF_COUNT_START+VP9_COMP_REF_COUNT_SIZE) -#define VP9_SINGLE_REF_COUNT_SIZE (10*2) -#define VP9_TX_MODE_COUNT_START \ - (VP9_SINGLE_REF_COUNT_START+VP9_SINGLE_REF_COUNT_SIZE) -#define VP9_TX_MODE_COUNT_SIZE (12*2) -#define VP9_SKIP_COUNT_START \ - (VP9_TX_MODE_COUNT_START+VP9_TX_MODE_COUNT_SIZE) -#define VP9_SKIP_COUNT_SIZE (3*2) -#define VP9_MV_SIGN_0_COUNT_START \ - (VP9_SKIP_COUNT_START+VP9_SKIP_COUNT_SIZE) -#define VP9_MV_SIGN_0_COUNT_SIZE (1*2) -#define VP9_MV_SIGN_1_COUNT_START \ - (VP9_MV_SIGN_0_COUNT_START+VP9_MV_SIGN_0_COUNT_SIZE) -#define VP9_MV_SIGN_1_COUNT_SIZE (1*2) -#define VP9_MV_BITS_0_COUNT_START \ - (VP9_MV_SIGN_1_COUNT_START+VP9_MV_SIGN_1_COUNT_SIZE) -#define VP9_MV_BITS_0_COUNT_SIZE (10*2) -#define VP9_MV_BITS_1_COUNT_START \ - (VP9_MV_BITS_0_COUNT_START+VP9_MV_BITS_0_COUNT_SIZE) -#define VP9_MV_BITS_1_COUNT_SIZE (10*2) -#define VP9_MV_CLASS0_HP_0_COUNT_START \ - (VP9_MV_BITS_1_COUNT_START+VP9_MV_BITS_1_COUNT_SIZE) -#define VP9_MV_CLASS0_HP_0_COUNT_SIZE (2*2) -#define VP9_MV_CLASS0_HP_1_COUNT_START \ - (VP9_MV_CLASS0_HP_0_COUNT_START+VP9_MV_CLASS0_HP_0_COUNT_SIZE) -#define VP9_MV_CLASS0_HP_1_COUNT_SIZE (2*2) -/* Start merge_tree*/ -#define VP9_INTER_MODE_COUNT_START \ - (VP9_MV_CLASS0_HP_1_COUNT_START+VP9_MV_CLASS0_HP_1_COUNT_SIZE) -#define VP9_INTER_MODE_COUNT_SIZE (7*4) -#define VP9_IF_Y_MODE_COUNT_START \ - (VP9_INTER_MODE_COUNT_START+VP9_INTER_MODE_COUNT_SIZE) -#define VP9_IF_Y_MODE_COUNT_SIZE (10*4) -#define VP9_IF_UV_MODE_COUNT_START \ - (VP9_IF_Y_MODE_COUNT_START+VP9_IF_Y_MODE_COUNT_SIZE) -#define VP9_IF_UV_MODE_COUNT_SIZE (10*10) -#define VP9_PARTITION_P_COUNT_START \ - (VP9_IF_UV_MODE_COUNT_START+VP9_IF_UV_MODE_COUNT_SIZE) -#define VP9_PARTITION_P_COUNT_SIZE (4*4*4) -#define VP9_INTERP_COUNT_START \ - (VP9_PARTITION_P_COUNT_START+VP9_PARTITION_P_COUNT_SIZE) -#define VP9_INTERP_COUNT_SIZE (4*3) -#define VP9_MV_JOINTS_COUNT_START \ - (VP9_INTERP_COUNT_START+VP9_INTERP_COUNT_SIZE) -#define VP9_MV_JOINTS_COUNT_SIZE (1 * 4) -#define VP9_MV_CLASSES_0_COUNT_START \ - (VP9_MV_JOINTS_COUNT_START+VP9_MV_JOINTS_COUNT_SIZE) -#define VP9_MV_CLASSES_0_COUNT_SIZE (1*11) -#define VP9_MV_CLASS0_0_COUNT_START \ - (VP9_MV_CLASSES_0_COUNT_START+VP9_MV_CLASSES_0_COUNT_SIZE) -#define VP9_MV_CLASS0_0_COUNT_SIZE (1*2) -#define VP9_MV_CLASSES_1_COUNT_START \ - (VP9_MV_CLASS0_0_COUNT_START+VP9_MV_CLASS0_0_COUNT_SIZE) -#define VP9_MV_CLASSES_1_COUNT_SIZE (1*11) -#define VP9_MV_CLASS0_1_COUNT_START \ - (VP9_MV_CLASSES_1_COUNT_START+VP9_MV_CLASSES_1_COUNT_SIZE) -#define VP9_MV_CLASS0_1_COUNT_SIZE (1*2) -#define VP9_MV_CLASS0_FP_0_COUNT_START \ - (VP9_MV_CLASS0_1_COUNT_START+VP9_MV_CLASS0_1_COUNT_SIZE) -#define VP9_MV_CLASS0_FP_0_COUNT_SIZE (3*4) -#define VP9_MV_CLASS0_FP_1_COUNT_START \ - (VP9_MV_CLASS0_FP_0_COUNT_START+VP9_MV_CLASS0_FP_0_COUNT_SIZE) -#define VP9_MV_CLASS0_FP_1_COUNT_SIZE (3*4) - - -#define DC_PRED 0 /* Average of above and left pixels*/ -#define V_PRED 1 /* Vertical*/ -#define H_PRED 2 /* Horizontal*/ -#define D45_PRED 3 /*Directional 45 deg = round(arctan(1/1) * 180/pi)*/ -#define D135_PRED 4 /* Directional 135 deg = 180 - 45*/ -#define D117_PRED 5 /* Directional 117 deg = 180 - 63*/ -#define D153_PRED 6 /* Directional 153 deg = 180 - 27*/ -#define D207_PRED 7 /* Directional 207 deg = 180 + 27*/ -#define D63_PRED 8 /*Directional 63 deg = round(arctan(2/1) * 180/pi)*/ -#define TM_PRED 9 /*True-motion*/ - -int clip_prob(int p) -{ - return (p > 255) ? 255 : (p < 1) ? 1 : p; -} - -#define ROUND_POWER_OF_TWO(value, n) \ - (((value) + (1 << ((n) - 1))) >> (n)) - -#define MODE_MV_COUNT_SAT 20 -static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = { - 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, - 70, 76, 83, 89, 96, 102, 108, 115, 121, 128 -}; - -void vp9_tree_merge_probs(unsigned int *prev_prob, unsigned int *cur_prob, - int coef_node_start, int tree_left, int tree_right, int tree_i, - int node) { - - int prob_32, prob_res, prob_shift; - int pre_prob, new_prob; - int den, m_count, get_prob, factor; - prob_32 = prev_prob[coef_node_start / 4 * 2]; - prob_res = coef_node_start & 3; - prob_shift = prob_res * 8; - pre_prob = (prob_32 >> prob_shift) & 0xff; - - den = tree_left + tree_right; - - if (den == 0) - new_prob = pre_prob; - else { - m_count = (den < MODE_MV_COUNT_SAT) ? - den : MODE_MV_COUNT_SAT; - get_prob = clip_prob( - div_r32(((int64_t)tree_left * 256 + (den >> 1)), - den)); - /*weighted_prob*/ - factor = count_to_update_factor[m_count]; - new_prob = ROUND_POWER_OF_TWO(pre_prob * (256 - factor) - + get_prob * factor, 8); - } - cur_prob[coef_node_start / 4 * 2] = (cur_prob[coef_node_start / 4 * 2] - & (~(0xff << prob_shift))) | (new_prob << prob_shift); - - /*pr_info(" - [%d][%d] 0x%02X --> 0x%02X (0x%X 0x%X) (%X)\n", - tree_i, node, pre_prob, new_prob, tree_left, tree_right, - cur_prob[coef_node_start/4*2]);*/ -} - - -/*void adapt_coef_probs(void)*/ -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) -{ - /* 80 * 64bits = 0xF00 ( use 0x1000 4K bytes) - unsigned int prev_prob[496*2]; - unsigned int cur_prob[496*2]; - 0x300 * 128bits = 0x3000 (32K Bytes) - unsigned int count[0x300*4];*/ - - int tx_size, coef_tx_size_start, coef_count_tx_size_start; - int plane, coef_plane_start, coef_count_plane_start; - int type, coef_type_start, coef_count_type_start; - int band, coef_band_start, coef_count_band_start; - int cxt_num; - int cxt, coef_cxt_start, coef_count_cxt_start; - int node, coef_node_start, coef_count_node_start; - - int tree_i, tree_left, tree_right; - int mvd_i; - - int count_sat = 24; - /*int update_factor = 112;*/ /*If COEF_MAX_UPDATE_FACTOR_AFTER_KEY, - use 128*/ - /* If COEF_MAX_UPDATE_FACTOR_AFTER_KEY, use 128*/ - /*int update_factor = (pic_count == 1) ? 128 : 112;*/ - int update_factor = cur_kf ? 112 : - prev_kf ? 128 : 112; - - int prob_32; - int prob_res; - int prob_shift; - int pre_prob; - - int num, den; - int get_prob; - int m_count; - int factor; - - int new_prob; - - if (debug & VP9_DEBUG_MERGE) - pr_info - ("\n ##adapt_coef_probs (pre_fc : %d ,prev_kf : %d,cur_kf : %d)##\n\n", - pre_fc, prev_kf, cur_kf); - - /*adapt_coef_probs*/ - for (tx_size = 0; tx_size < 4; tx_size++) { - coef_tx_size_start = VP9_COEF_START - + tx_size * 4 * VP9_COEF_SIZE_ONE_SET; - coef_count_tx_size_start = VP9_COEF_COUNT_START - + tx_size * 4 * VP9_COEF_COUNT_SIZE_ONE_SET; - coef_plane_start = coef_tx_size_start; - coef_count_plane_start = coef_count_tx_size_start; - for (plane = 0; plane < 2; plane++) { - coef_type_start = coef_plane_start; - coef_count_type_start = coef_count_plane_start; - for (type = 0; type < 2; type++) { - coef_band_start = coef_type_start; - coef_count_band_start = coef_count_type_start; - for (band = 0; band < 6; band++) { - if (band == 0) - cxt_num = 3; - else - cxt_num = 6; - coef_cxt_start = coef_band_start; - coef_count_cxt_start = - coef_count_band_start; - for (cxt = 0; cxt < cxt_num; cxt++) { - const int n0 = - count[coef_count_cxt_start]; - const int n1 = - count[coef_count_cxt_start + 1]; - const int n2 = - count[coef_count_cxt_start + 2]; - const int neob = - count[coef_count_cxt_start + 3]; - const int nneob = - count[coef_count_cxt_start + 4]; - const unsigned int - branch_ct[3][2] = { - { neob, nneob }, - { n0, n1 + n2 }, - { n1, n2 } - }; - coef_node_start = - coef_cxt_start; - for - (node = 0; node < 3; node++) { - prob_32 = - prev_prob[ - coef_node_start - / 4 * 2]; - prob_res = - coef_node_start & 3; - prob_shift = - prob_res * 8; - pre_prob = - (prob_32 >> prob_shift) - & 0xff; - - /*get_binary_prob*/ - num = - branch_ct[node][0]; - den = - branch_ct[node][0] + - branch_ct[node][1]; - m_count = (den < - count_sat) - ? den : count_sat; - - get_prob = - (den == 0) ? 128u : - clip_prob( - div_r32(((int64_t) - num * 256 - + (den >> 1)), - den)); - - factor = - update_factor * m_count - / count_sat; - new_prob = - ROUND_POWER_OF_TWO - (pre_prob * - (256 - factor) + - get_prob * factor, 8); - - cur_prob[coef_node_start - / 4 * 2] = - (cur_prob - [coef_node_start - / 4 * 2] & (~(0xff << - prob_shift))) | - (new_prob << - prob_shift); - - coef_node_start += 1; - } - - coef_cxt_start = - coef_cxt_start + 3; - coef_count_cxt_start = - coef_count_cxt_start - + 5; - } - if (band == 0) { - coef_band_start += 10; - coef_count_band_start += 15; - } else { - coef_band_start += 18; - coef_count_band_start += 30; - } - } - coef_type_start += VP9_COEF_SIZE_ONE_SET; - coef_count_type_start += - VP9_COEF_COUNT_SIZE_ONE_SET; - } - coef_plane_start += 2 * VP9_COEF_SIZE_ONE_SET; - coef_count_plane_start += - 2 * VP9_COEF_COUNT_SIZE_ONE_SET; - } - } - -if (cur_kf == 0) { - /*mode_mv_merge_probs - merge_intra_inter_prob*/ - for (coef_count_node_start = VP9_INTRA_INTER_COUNT_START; - coef_count_node_start < (VP9_MV_CLASS0_HP_1_COUNT_START + - VP9_MV_CLASS0_HP_1_COUNT_SIZE); coef_count_node_start += 2) { - - if (coef_count_node_start == - VP9_INTRA_INTER_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_intra_inter_prob\n"); - coef_node_start = VP9_INTRA_INTER_START; - } else if (coef_count_node_start == - VP9_COMP_INTER_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_comp_inter_prob\n"); - coef_node_start = VP9_COMP_INTER_START; - } - /* - else if (coef_count_node_start == - VP9_COMP_REF_COUNT_START) { - pr_info(" # merge_comp_inter_prob\n"); - coef_node_start = VP9_COMP_REF_START; - } - else if (coef_count_node_start == - VP9_SINGLE_REF_COUNT_START) { - pr_info(" # merge_comp_inter_prob\n"); - coef_node_start = VP9_SINGLE_REF_START; - } - */ - else if (coef_count_node_start == - VP9_TX_MODE_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_tx_mode_probs\n"); - coef_node_start = VP9_TX_MODE_START; - } else if (coef_count_node_start == - VP9_SKIP_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_skip_probs\n"); - coef_node_start = VP9_SKIP_START; - } else if (coef_count_node_start == - VP9_MV_SIGN_0_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_sign_0\n"); - coef_node_start = VP9_MV_SIGN_0_START; - } else if (coef_count_node_start == - VP9_MV_SIGN_1_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_sign_1\n"); - coef_node_start = VP9_MV_SIGN_1_START; - } else if (coef_count_node_start == - VP9_MV_BITS_0_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_bits_0\n"); - coef_node_start = VP9_MV_BITS_0_START; - } else if (coef_count_node_start == - VP9_MV_BITS_1_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_bits_1\n"); - coef_node_start = VP9_MV_BITS_1_START; - } else if (coef_count_node_start == - VP9_MV_CLASS0_HP_0_COUNT_START) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_class0_hp\n"); - coef_node_start = VP9_MV_CLASS0_HP_0_START; - } - - - den = count[coef_count_node_start] + - count[coef_count_node_start + 1]; - - prob_32 = prev_prob[coef_node_start / 4 * 2]; - prob_res = coef_node_start & 3; - prob_shift = prob_res * 8; - pre_prob = (prob_32 >> prob_shift) & 0xff; - - if (den == 0) - new_prob = pre_prob; - else { - m_count = (den < MODE_MV_COUNT_SAT) ? - den : MODE_MV_COUNT_SAT; - get_prob = - clip_prob( - div_r32(((int64_t)count[coef_count_node_start] - * 256 + (den >> 1)), - den)); - /*weighted_prob*/ - factor = count_to_update_factor[m_count]; - new_prob = - ROUND_POWER_OF_TWO(pre_prob * (256 - factor) - + get_prob * factor, 8); - } - cur_prob[coef_node_start / 4 * 2] = - (cur_prob[coef_node_start / 4 * 2] & - (~(0xff << prob_shift))) - | (new_prob << prob_shift); - - coef_node_start = coef_node_start + 1; - } - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_inter_mode_tree\n"); - coef_node_start = VP9_INTER_MODE_START; - coef_count_node_start = VP9_INTER_MODE_COUNT_START; - for (tree_i = 0; tree_i < 7; tree_i++) { - for (node = 0; node < 3; node++) { - switch (node) { - case 2: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 3]; - break; - case 1: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] - + count[coef_count_node_start + 3]; - break; - default: - tree_left = - count[coef_count_node_start + 2]; - tree_right = - count[coef_count_node_start + 0] - + count[coef_count_node_start + 1] - + count[coef_count_node_start + 3]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, tree_left, tree_right, - tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 4; - } - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_intra_mode_tree\n"); - coef_node_start = VP9_IF_Y_MODE_START; - coef_count_node_start = VP9_IF_Y_MODE_COUNT_START; - for (tree_i = 0; tree_i < 14; tree_i++) { - for (node = 0; node < 9; node++) { - switch (node) { - case 8: - tree_left = - count[coef_count_node_start+D153_PRED]; - tree_right = - count[coef_count_node_start+D207_PRED]; - break; - case 7: - tree_left = - count[coef_count_node_start+D63_PRED]; - tree_right = - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED]; - break; - case 6: - tree_left = - count[coef_count_node_start + D45_PRED]; - tree_right = - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED] + - count[coef_count_node_start+D63_PRED]; - break; - case 5: - tree_left = - count[coef_count_node_start+D135_PRED]; - tree_right = - count[coef_count_node_start+D117_PRED]; - break; - case 4: - tree_left = - count[coef_count_node_start+H_PRED]; - tree_right = - count[coef_count_node_start+D117_PRED] + - count[coef_count_node_start+D135_PRED]; - break; - case 3: - tree_left = - count[coef_count_node_start+H_PRED] + - count[coef_count_node_start+D117_PRED] + - count[coef_count_node_start+D135_PRED]; - tree_right = - count[coef_count_node_start+D45_PRED] + - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED] + - count[coef_count_node_start+D63_PRED]; - break; - case 2: - tree_left = - count[coef_count_node_start+V_PRED]; - tree_right = - count[coef_count_node_start+H_PRED] + - count[coef_count_node_start+D117_PRED] + - count[coef_count_node_start+D135_PRED] + - count[coef_count_node_start+D45_PRED] + - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED] + - count[coef_count_node_start+D63_PRED]; - break; - case 1: - tree_left = - count[coef_count_node_start+TM_PRED]; - tree_right = - count[coef_count_node_start+V_PRED] + - count[coef_count_node_start+H_PRED] + - count[coef_count_node_start+D117_PRED] + - count[coef_count_node_start+D135_PRED] + - count[coef_count_node_start+D45_PRED] + - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED] + - count[coef_count_node_start+D63_PRED]; - break; - default: - tree_left = - count[coef_count_node_start+DC_PRED]; - tree_right = - count[coef_count_node_start+TM_PRED] + - count[coef_count_node_start+V_PRED] + - count[coef_count_node_start+H_PRED] + - count[coef_count_node_start+D117_PRED] + - count[coef_count_node_start+D135_PRED] + - count[coef_count_node_start+D45_PRED] + - count[coef_count_node_start+D207_PRED] + - count[coef_count_node_start+D153_PRED] + - count[coef_count_node_start+D63_PRED]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, tree_left, tree_right, - tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 10; - } - - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_partition_tree\n"); - coef_node_start = VP9_PARTITION_P_START; - coef_count_node_start = VP9_PARTITION_P_COUNT_START; - for (tree_i = 0; tree_i < 16; tree_i++) { - for (node = 0; node < 3; node++) { - switch (node) { - case 2: - tree_left = - count[coef_count_node_start + 2]; - tree_right = - count[coef_count_node_start + 3]; - break; - case 1: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3]; - break; - default: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] + - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, - tree_left, tree_right, tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 4; - } - - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_switchable_interp_tree\n"); - coef_node_start = VP9_INTERP_START; - coef_count_node_start = VP9_INTERP_COUNT_START; - for (tree_i = 0; tree_i < 4; tree_i++) { - for (node = 0; node < 2; node++) { - switch (node) { - case 1: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 2]; - break; - default: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] + - count[coef_count_node_start + 2]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, - tree_left, tree_right, tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 3; - } - - if (debug & VP9_DEBUG_MERGE) - pr_info("# merge_vp9_mv_joint_tree\n"); - coef_node_start = VP9_MV_JOINTS_START; - coef_count_node_start = VP9_MV_JOINTS_COUNT_START; - for (tree_i = 0; tree_i < 1; tree_i++) { - for (node = 0; node < 3; node++) { - switch (node) { - case 2: - tree_left = - count[coef_count_node_start + 2]; - tree_right = - count[coef_count_node_start + 3]; - break; - case 1: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3]; - break; - default: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] + - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3]; - break; - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, - tree_left, tree_right, tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 4; - } - - for (mvd_i = 0; mvd_i < 2; mvd_i++) { - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_mv_class_tree [%d] -\n", mvd_i); - coef_node_start = - mvd_i ? VP9_MV_CLASSES_1_START : VP9_MV_CLASSES_0_START; - coef_count_node_start = - mvd_i ? VP9_MV_CLASSES_1_COUNT_START - : VP9_MV_CLASSES_0_COUNT_START; - tree_i = 0; - for (node = 0; node < 10; node++) { - switch (node) { - case 9: - tree_left = - count[coef_count_node_start + 9]; - tree_right = - count[coef_count_node_start + 10]; - break; - case 8: - tree_left = - count[coef_count_node_start + 7]; - tree_right = - count[coef_count_node_start + 8]; - break; - case 7: - tree_left = - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8]; - tree_right = - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - case 6: - tree_left = - count[coef_count_node_start + 6]; - tree_right = - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8] + - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - case 5: - tree_left = - count[coef_count_node_start + 4]; - tree_right = - count[coef_count_node_start + 5]; - break; - case 4: - tree_left = - count[coef_count_node_start + 4] + - count[coef_count_node_start + 5]; - tree_right = - count[coef_count_node_start + 6] + - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8] + - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - case 3: - tree_left = - count[coef_count_node_start + 2]; - tree_right = - count[coef_count_node_start + 3]; - break; - case 2: - tree_left = - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3]; - tree_right = - count[coef_count_node_start + 4] + - count[coef_count_node_start + 5] + - count[coef_count_node_start + 6] + - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8] + - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - case 1: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3] + - count[coef_count_node_start + 4] + - count[coef_count_node_start + 5] + - count[coef_count_node_start + 6] + - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8] + - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - default: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] + - count[coef_count_node_start + 2] + - count[coef_count_node_start + 3] + - count[coef_count_node_start + 4] + - count[coef_count_node_start + 5] + - count[coef_count_node_start + 6] + - count[coef_count_node_start + 7] + - count[coef_count_node_start + 8] + - count[coef_count_node_start + 9] + - count[coef_count_node_start + 10]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, tree_left, tree_right, - tree_i, node); - - coef_node_start = coef_node_start + 1; - } - - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_mv_class0_tree [%d] -\n", mvd_i); - coef_node_start = - mvd_i ? VP9_MV_CLASS0_1_START : VP9_MV_CLASS0_0_START; - coef_count_node_start = - mvd_i ? VP9_MV_CLASS0_1_COUNT_START : - VP9_MV_CLASS0_0_COUNT_START; - tree_i = 0; - node = 0; - tree_left = count[coef_count_node_start + 0]; - tree_right = count[coef_count_node_start + 1]; - - vp9_tree_merge_probs(prev_prob, cur_prob, coef_node_start, - tree_left, tree_right, tree_i, node); - if (debug & VP9_DEBUG_MERGE) - pr_info(" # merge_vp9_mv_fp_tree_class0_fp [%d] -\n", - mvd_i); - coef_node_start = - mvd_i ? VP9_MV_CLASS0_FP_1_START : - VP9_MV_CLASS0_FP_0_START; - coef_count_node_start = - mvd_i ? VP9_MV_CLASS0_FP_1_COUNT_START : - VP9_MV_CLASS0_FP_0_COUNT_START; - for (tree_i = 0; tree_i < 3; tree_i++) { - for (node = 0; node < 3; node++) { - switch (node) { - case 2: - tree_left = - count[coef_count_node_start + 2]; - tree_right = - count[coef_count_node_start + 3]; - break; - case 1: - tree_left = - count[coef_count_node_start + 1]; - tree_right = - count[coef_count_node_start + 2] - + count[coef_count_node_start + 3]; - break; - default: - tree_left = - count[coef_count_node_start + 0]; - tree_right = - count[coef_count_node_start + 1] - + count[coef_count_node_start + 2] - + count[coef_count_node_start + 3]; - break; - - } - - vp9_tree_merge_probs(prev_prob, cur_prob, - coef_node_start, tree_left, tree_right, - tree_i, node); - - coef_node_start = coef_node_start + 1; - } - coef_count_node_start = coef_count_node_start + 4; - } - - } /* for mvd_i (mvd_y or mvd_x)*/ -} - -} - - -static void uninit_mmu_buffers(struct VP9Decoder_s *pbi) -{ - - decoder_mmu_box_free(pbi->mmu_box); - pbi->mmu_box = NULL; - - if (pbi->bmmu_box) - decoder_bmmu_box_free(pbi->bmmu_box); - pbi->bmmu_box = NULL; -} - -#ifndef VP9_10B_MMU -static void init_buf_list(struct VP9Decoder_s *pbi) -{ - int i; - int buf_size; -#ifndef VP9_10B_MMU - int mc_buffer_end = pbi->mc_buf->buf_start + pbi->mc_buf->buf_size; -#endif - pbi->used_buf_num = max_buf_num; - - if (pbi->used_buf_num > MAX_BUF_NUM) - pbi->used_buf_num = MAX_BUF_NUM; - if (buf_alloc_size > 0) { - buf_size = buf_alloc_size; - if (debug) - pr_info("[Buffer Management] init_buf_list:\n"); - } else { - int pic_width = pbi->init_pic_w; - int pic_height = pbi->init_pic_h; - - /*SUPPORT_10BIT*/ - int losless_comp_header_size = compute_losless_comp_header_size - (pic_width, pic_height); - int losless_comp_body_size = compute_losless_comp_body_size - (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; - if (double_write_mode) { - int pic_width_dw = (double_write_mode == 2) ? - pic_width / 2 : pic_width; - int pic_height_dw = (double_write_mode == 2) ? - pic_height / 2 : pic_height; - 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 ((double_write_mode & 0x10) == 0) - buf_size += (mc_buffer_size_h << 16); - if (debug) { - pr_info - ("init_buf_list num %d (width %d height %d):\n", - pbi->used_buf_num, pic_width, pic_height); - } - } - - for (i = 0; i < pbi->used_buf_num; i++) { - if (((i + 1) * buf_size) > pbi->mc_buf->buf_size) { - if (use_cma) - pbi->use_cma_flag = 1; - else { - if (debug) { - pr_info("%s maximum buf size is used\n", - __func__); - } - break; - } - } -#ifndef VP9_10B_MMU - pbi->m_BUF[i].alloc_flag = 0; - pbi->m_BUF[i].index = i; - - if (use_cma == 2) - pbi->use_cma_flag = 1; - if (pbi->use_cma_flag) { - if (!decoder_bmmu_box_alloc_idx_wait( - pbi->bmmu_box, - i, - buf_size, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR)) { - pbi->m_BUF[i].alloc_addr = - decoder_bmmu_box_get_phy_addr( - pbi->bmmu_box, - i); - pbi->m_BUF[i].cma_page_count = - PAGE_ALIGN(buf_size) / PAGE_SIZE; - pr_info("CMA malloc ok %d\n", i); - } else { - pbi->m_BUF[i].cma_page_count = 0; - pr_info("CMA malloc failed %d\n", i); - if (i <= 5) { - pbi->fatal_error |= - DECODER_FATAL_ERROR_NO_MEM; - } - break; - } - pbi->m_BUF[i].start_adr = pbi->m_BUF[i].alloc_addr; - } else { - pbi->m_BUF[i].cma_page_count = 0; - pbi->m_BUF[i].alloc_addr = 0; - pbi->m_BUF[i].start_adr = - pbi->mc_buf->buf_start + i * buf_size; - } - pbi->m_BUF[i].size = buf_size; - pbi->m_BUF[i].free_start_adr = pbi->m_BUF[i].start_adr; - - if (((pbi->m_BUF[i].start_adr + buf_size) > mc_buffer_end) - && (pbi->m_BUF[i].alloc_addr == 0)) { - if (debug) { - pr_info - ("Max mc buffer or mpred_mv buffer is used\n"); - } - break; - } - - if (debug) { - pr_info("Buffer %d: start_adr %p size %x\n", i, - (void *)pbi->m_BUF[i].start_adr, - pbi->m_BUF[i].size); - } -#endif - } - pbi->buf_num = i; -} -#endif -static int config_pic(struct VP9Decoder_s *pbi, - struct PIC_BUFFER_CONFIG_s *pic_config, - unsigned long last_disp_addr) -{ - int ret = -1; - int i; - int pic_width = pbi->init_pic_w; - int pic_height = pbi->init_pic_h; - int MV_MEM_UNIT = 0x240; - 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; - - u32 mpred_mv_end = pbi->work_space_buf->mpred_mv.buf_start + - pbi->work_space_buf->mpred_mv.buf_size; - u32 y_adr = 0; - int buf_size = 0; - - int losless_comp_header_size = - compute_losless_comp_header_size(pic_width , - pic_height); - int losless_comp_body_size = compute_losless_comp_body_size(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; - if (double_write_mode) { - int pic_width_dw = (double_write_mode == 2) ? - pic_width / 2 : pic_width; - int pic_height_dw = (double_write_mode == 2) ? - pic_height / 2 : pic_height; - 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 VP9_10B_MMU - if ((double_write_mode & 0x10) == 0) - buf_size += (mc_buffer_size_h << 16); -#endif - -#ifdef VP9_10B_MMU - if ((pbi->work_space_buf->cm_header.buf_start + - ((pic_config->index + 2) - * MMU_COMPRESS_HEADER_SIZE)) - > (pbi->work_space_buf->cm_header.buf_start + - pbi->work_space_buf->cm_header.buf_size)) { - pr_info("MMU header_adr allocate fail\n"); - return -1; - } - - pic_config->header_adr = pbi->work_space_buf->cm_header.buf_start - + (pic_config->index * MMU_COMPRESS_HEADER_SIZE); - if (last_disp_addr && pic_config->header_adr == last_disp_addr) { - /*if same as disp add used last one.*/ - pr_info("same as disp %d: %ld\n", - pic_config->index, pic_config->header_adr); - pic_config->header_adr = - pbi->work_space_buf->cm_header.buf_start + - (FRAME_BUFFERS * MMU_COMPRESS_HEADER_SIZE); - } - if (debug & VP9_DEBUG_BUFMGR) { - pr_info("MMU header_adr %d: %ld\n", - pic_config->index, pic_config->header_adr); - } -#endif - - i = pic_config->index; - if ((pbi->work_space_buf->mpred_mv.buf_start + - (((i + 1) * lcu_total) * MV_MEM_UNIT)) - <= mpred_mv_end -#ifdef VP9_10B_MMU -#endif - ) { - if (debug) { - pr_err("start %x .size=%d\n", - pbi->mc_buf_spec.buf_start + i * buf_size, - buf_size); - } - -#ifndef VP9_10B_MMU - for (i = 0; i < pbi->buf_num; i++) { - y_adr = ((pbi->m_BUF[i].free_start_adr - + 0xffff) >> 16) << 16; - /*64k alignment*/ - if ((y_adr+buf_size) <= (pbi->m_BUF[i].start_adr+ - pbi->m_BUF[i].size)) { - pbi->m_BUF[i].free_start_adr = - y_adr + buf_size; - break; - } - } - if (i < pbi->buf_num) -#else - if ((pbi->mc_buf->buf_start + (i + 1) * buf_size) < - pbi->mc_buf->buf_end) - y_adr = pbi->mc_buf->buf_start + i * buf_size; - else { - if (!decoder_bmmu_box_alloc_idx_wait( - pbi->bmmu_box, - i, - buf_size, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - )) { - pic_config->cma_alloc_addr = - decoder_bmmu_box_get_phy_addr( - pbi->bmmu_box, - i); - } else { - pr_err("alloc cma buffer failed %d\n", i); - } - if (pic_config->cma_alloc_addr) - y_adr = pic_config->cma_alloc_addr; - else - return -1; - } -#endif - { - /*ensure get_pic_by_POC() - not get the buffer not decoded*/ - pic_config->BUF_index = i; - pic_config->lcu_total = lcu_total; - - pic_config->comp_body_size = losless_comp_body_size; - pic_config->buf_size = buf_size; -#ifndef VP9_10B_MMU - pic_config->mc_y_adr = y_adr; -#endif - pic_config->mc_canvas_y = pic_config->index; - pic_config->mc_canvas_u_v = pic_config->index; -#ifndef VP9_10B_MMU - if (double_write_mode & 0x10) { - pic_config->mc_u_v_adr = y_adr + - ((mc_buffer_size_u_v_h << 16) << 1); - - pic_config->mc_canvas_y = - (pic_config->index << 1); - pic_config->mc_canvas_u_v = - (pic_config->index << 1) + 1; - - pic_config->dw_y_adr = y_adr; - pic_config->dw_u_v_adr = pic_config->mc_u_v_adr; - } else -#endif - if (double_write_mode) { - pic_config->dw_y_adr = y_adr -#ifndef VP9_10B_MMU - + (mc_buffer_size_h << 16) -#endif - ; - pic_config->dw_u_v_adr = pic_config->dw_y_adr + - ((mc_buffer_size_u_v_h << 16) << 1); - } - - pic_config->mpred_mv_wr_start_addr = - pbi->work_space_buf->mpred_mv.buf_start + - ((pic_config->index * lcu_total) - * MV_MEM_UNIT); - - if (debug) { - pr_info - ("%s index %d BUF_index %d mc_y_adr %lx ", - __func__, pic_config->index, - pic_config->BUF_index, - pic_config->mc_y_adr); - pr_info - ("comp_body_size %x comp_buf_size %x ", - pic_config->comp_body_size, - pic_config->buf_size); - pr_info - ("mpred_mv_wr_start_adr %ld\n", - pic_config->mpred_mv_wr_start_addr); - pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n", - pic_config->dw_y_adr, - pic_config->dw_u_v_adr); - } - ret = 0; - } - } - return ret; -} - -static void init_pic_list(struct VP9Decoder_s *pbi) -{ - int i; - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *pic_config; - struct vframe_s vf; - unsigned long disp_addr = 0; - - if (!get_video0_frame_info(&vf)) { - if (vf.type & VIDTYPE_SCATTER) { - /*sc only used header.*/ - disp_addr = vf.compHeadAddr; - } else if (vf.type & VIDTYPE_COMPRESS) { - /*sc checked body.*/ - disp_addr = vf.compBodyAddr; - } else { - struct canvas_s cur_canvas; - canvas_read(vf.canvas0Addr & 0xff, &cur_canvas); - disp_addr = cur_canvas.addr; - } - } - - for (i = 0; i < FRAME_BUFFERS; i++) { - pic_config = &cm->buffer_pool->frame_bufs[i].buf; - pic_config->index = i; - pic_config->BUF_index = -1; - if (config_pic(pbi, pic_config, disp_addr) < 0) { - if (debug) - pr_info("Config_pic %d fail\n", - pic_config->index); - pic_config->index = -1; - break; - } - pic_config->y_crop_width = pbi->init_pic_w; - pic_config->y_crop_height = pbi->init_pic_h; - /*set_canvas(pic_config);*/ - } - for (; i < FRAME_BUFFERS; i++) { - pic_config = &cm->buffer_pool->frame_bufs[i].buf; - pic_config->index = -1; - pic_config->BUF_index = -1; - } - -} - - -static void init_pic_list_hw(struct VP9Decoder_s *pbi) -{ - int i; - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *pic_config; - /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/ - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, - (0x1 << 1) | (0x1 << 2)); - - - for (i = 0; i < FRAME_BUFFERS; i++) { - pic_config = &cm->buffer_pool->frame_bufs[i].buf; - if (pic_config->index < 0) - break; - -#ifdef VP9_10B_MMU - /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - pic_config->header_adr - | (pic_config->mc_canvas_y << 8)|0x1);*/ - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic_config->header_adr >> 5); -#else - /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - pic_config->mc_y_adr - | (pic_config->mc_canvas_y << 8) | 0x1);*/ - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic_config->mc_y_adr >> 5); -#endif -#ifndef LOSLESS_COMPRESS_MODE - /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, - pic_config->mc_u_v_adr - | (pic_config->mc_canvas_u_v << 8)| 0x1);*/ - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic_config->mc_u_v_adr >> 5); -#endif - } - WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1); - - /*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); -} - - -static void dump_pic_list(struct VP9Decoder_s *pbi) -{ - return; -} - -static int config_pic_size(struct VP9Decoder_s *pbi, unsigned short bit_depth) -{ -#ifdef LOSLESS_COMPRESS_MODE - unsigned int data32; -#endif - int losless_comp_header_size, losless_comp_body_size; - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf; - frame_width = cur_pic_config->y_crop_width; - frame_height = cur_pic_config->y_crop_height; - cur_pic_config->bit_depth = bit_depth; - losless_comp_header_size = - compute_losless_comp_header_size(cur_pic_config->y_crop_width, - cur_pic_config->y_crop_height); - losless_comp_body_size = - compute_losless_comp_body_size(cur_pic_config->y_crop_width, - cur_pic_config->y_crop_height, (bit_depth == VPX_BITS_10)); - cur_pic_config->comp_body_size = losless_comp_body_size; -#ifdef LOSLESS_COMPRESS_MODE - data32 = READ_VREG(HEVC_SAO_CTRL5); - if (bit_depth == VPX_BITS_10) - data32 &= ~(1 << 9); - else - data32 |= (1 << 9); - - WRITE_VREG(HEVC_SAO_CTRL5, data32); - -#ifdef VP9_10B_MMU - /*bit[4] : paged_mem_mode*/ - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4)); -#else - /*bit[3] smem mdoe*/ - if (bit_depth == VPX_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 - return 0; -} - -static int config_mc_buffer(struct VP9Decoder_s *pbi, unsigned short bit_depth) -{ - int i; - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf; - uint8_t scale_enable = 0; - - if (debug&VP9_DEBUG_BUFMGR) - pr_info("config_mc_buffer entered .....\n"); - - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (0 << 8) | (0 << 1) | 1); - for (i = 0; i < REFS_PER_FRAME; ++i) { - struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf; - - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, - (pic_config->mc_canvas_u_v << 16) - | (pic_config->mc_canvas_u_v << 8) - | pic_config->mc_canvas_y); - if (debug & VP9_DEBUG_BUFMGR_MORE) - pr_info("refid %x mc_canvas_u_v %x mc_canvas_y %x\n", - i, pic_config->mc_canvas_u_v, - pic_config->mc_canvas_y); - } - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, - (16 << 8) | (0 << 1) | 1); - for (i = 0; i < REFS_PER_FRAME; ++i) { - struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf; - - WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, - (pic_config->mc_canvas_u_v << 16) - | (pic_config->mc_canvas_u_v << 8) - | pic_config->mc_canvas_y); - } - - /*auto_inc start index:0 field:0*/ - WRITE_VREG(VP9D_MPP_REFINFO_TBL_ACCCONFIG, 0x1 << 2); - /*index 0:last 1:golden 2:altref*/ - for (i = 0; i < REFS_PER_FRAME; i++) { - int ref_pic_body_size; - struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf; - - WRITE_VREG(VP9D_MPP_REFINFO_DATA, pic_config->y_crop_width); - WRITE_VREG(VP9D_MPP_REFINFO_DATA, pic_config->y_crop_height); - - if (pic_config->y_crop_width != cur_pic_config->y_crop_width || - pic_config->y_crop_height != cur_pic_config->y_crop_height) { - scale_enable |= (1 << i); - } - ref_pic_body_size = - compute_losless_comp_body_size(pic_config->y_crop_width, - pic_config->y_crop_height, (bit_depth == VPX_BITS_10)); - WRITE_VREG(VP9D_MPP_REFINFO_DATA, - (pic_config->y_crop_width << 14) - / cur_pic_config->y_crop_width); - WRITE_VREG(VP9D_MPP_REFINFO_DATA, - (pic_config->y_crop_height << 14) - / cur_pic_config->y_crop_height); -#ifdef VP9_10B_MMU - WRITE_VREG(VP9D_MPP_REFINFO_DATA, 0); -#else - WRITE_VREG(VP9D_MPP_REFINFO_DATA, ref_pic_body_size >> 5); -#endif - } - WRITE_VREG(VP9D_MPP_REF_SCALE_ENBL, scale_enable); - return 0; -} - -static void clear_mpred_hw(struct VP9Decoder_s *pbi) -{ - unsigned int data32; - data32 = READ_VREG(HEVC_MPRED_CTRL4); - data32 &= (~(1 << 6)); - WRITE_VREG(HEVC_MPRED_CTRL4, data32); -} - -static void config_mpred_hw(struct VP9Decoder_s *pbi) -{ - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf; - struct PIC_BUFFER_CONFIG_s *last_frame_pic_config = - &cm->prev_frame->buf; - - unsigned int data32; - int mpred_curr_lcu_x; - int mpred_curr_lcu_y; - int mpred_mv_rd_end_addr; - int MV_MEM_UNIT = 0x240; - - - mpred_mv_rd_end_addr = last_frame_pic_config->mpred_mv_wr_start_addr - + (last_frame_pic_config->lcu_total * MV_MEM_UNIT); - - data32 = READ_VREG(HEVC_MPRED_CURR_LCU); - mpred_curr_lcu_x = data32 & 0xffff; - mpred_curr_lcu_y = (data32 >> 16) & 0xffff; - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("cur pic_config index %d col pic_config index %d\n", - cur_pic_config->index, last_frame_pic_config->index); - WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412); - WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, - pbi->work_space_buf->mpred_above.buf_start); - - data32 = READ_VREG(HEVC_MPRED_CTRL4); - - data32 &= (~(1 << 6)); - data32 |= (cm->use_prev_frame_mvs << 6); - WRITE_VREG(HEVC_MPRED_CTRL4, data32); - - WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR, - cur_pic_config->mpred_mv_wr_start_addr); - WRITE_VREG(HEVC_MPRED_MV_WPTR, cur_pic_config->mpred_mv_wr_start_addr); - - WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, - last_frame_pic_config->mpred_mv_wr_start_addr); - WRITE_VREG(HEVC_MPRED_MV_RPTR, - last_frame_pic_config->mpred_mv_wr_start_addr); - /*data32 = ((pbi->lcu_x_num - pbi->tile_width_lcu)*MV_MEM_UNIT);*/ - /*WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);*/ - /*WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);*/ - WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr); - -} - -static void config_sao_hw(struct VP9Decoder_s *pbi, union param_u *params) -{ - struct VP9_Common_s *cm = &pbi->common; - struct PIC_BUFFER_CONFIG_s *pic_config = &cm->cur_frame->buf; - - unsigned int data32; - int lcu_size = 64; - int mc_buffer_size_u_v = - pic_config->lcu_total * lcu_size*lcu_size/2; - int mc_buffer_size_u_v_h = - (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/ - -#ifndef VP9_10B_MMU - if ((double_write_mode & 0x10) == 0) - WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic_config->mc_y_adr); -#endif - if (double_write_mode) { - 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 { - WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff); - WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff); - } -#ifdef VP9_10B_MMU - WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->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, pic_config->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 VP9_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*/ - 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); - - 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*/ - WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); -#endif -#else - data32 = READ_VREG(HEVC_SAO_CTRL1); - data32 &= (~0x3000); - 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 |= endian; /* Big-Endian per 64-bit */ - data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/ - if (double_write_mode == 0) - data32 |= 0x2; /*disable double write*/ -#ifndef VP9_10B_MMU - else - if (double_write_mode & 0x10) - data32 |= 0x1; /*disable cm*/ -#endif - WRITE_VREG(HEVC_SAO_CTRL1, data32); - - if (double_write_mode & 0x10) { - /* [23:22] dw_v1_ctrl - [21:20] dw_v0_ctrl - [19:18] dw_h1_ctrl - [17:16] dw_h0_ctrl - */ - data32 = READ_VREG(HEVC_SAO_CTRL5); - /*set them all 0 for H265_NV21 (no down-scale)*/ - data32 &= ~(0xff << 16); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - } else { - data32 = READ_VREG(HEVC_SAO_CTRL5); - data32 &= (~(0xff << 16)); - if (double_write_mode != 1) - data32 |= (0xff<<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 |= (mem_map_mode << - 4); - data32 &= (~0xF); - data32 |= 0xf; /* valid only when double write only */ - /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */ - WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32); -#endif -} - -static void vp9_config_work_space_hw(struct VP9Decoder_s *pbi) -{ - struct BuffInfo_s *buf_spec = pbi->work_space_buf; -#ifdef LOSLESS_COMPRESS_MODE - int losless_comp_header_size = - compute_losless_comp_header_size(pbi->init_pic_w, - pbi->init_pic_h); - int losless_comp_body_size = - compute_losless_comp_body_size(pbi->init_pic_w, - pbi->init_pic_h, buf_alloc_depth == 10); -#endif -#ifdef VP9_10B_MMU - unsigned int data32; -#endif - if (debug) - pr_info("%s %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->vps.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); - WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start); - if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) - WRITE_VREG(HEVC_RPM_BUFFER, (u32)pbi->rpm_phy_addr); - WRITE_VREG(HEVC_SHORT_TERM_RPS, buf_spec->short_term_rps.buf_start); - /*WRITE_VREG(HEVC_VPS_BUFFER, buf_spec->vps.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); - WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start); - WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start); - WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start); - - /* 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); - -#ifdef LOSLESS_COMPRESS_MODE -#ifdef VP9_10B_MMU - /*bit[4] : paged_mem_mode*/ - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4)); - WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0); -#else - /*if(cur_pic_config->bit_depth == VPX_BITS_10) - WRITE_VREG(P_HEVCD_MPP_DECOMP_CTL1, (0<<3));*/ - /*bit[3] smem mdoe*/ - /*else WRITE_VREG(P_HEVCD_MPP_DECOMP_CTL1, (1<<3));*/ - /*bit[3] smem mdoe*/ - WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5)); -#endif - /*WRITE_VREG(P_HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));*/ - /*WRITE_VREG(P_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 VP9_10B_MMU - WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start); - WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start - + buf_spec->mmu_vbh.buf_size/2); - /*data32 = READ_VREG(P_HEVC_SAO_CTRL9);*/ - /*data32 |= 0x1;*/ - /*WRITE_VREG(P_HEVC_SAO_CTRL9, data32);*/ - - /* use HEVC_CM_HEADER_START_ADDR */ - data32 = READ_VREG(HEVC_SAO_CTRL5); - data32 |= (1<<10); - WRITE_VREG(HEVC_SAO_CTRL5, data32); - -#endif - - WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start); - - if (debug & VP9_DEBUG_UCODE) - 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); -#ifdef VP9_10B_MMU - WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr); -#endif - -} - - -#ifdef VP9_LPF_LVL_UPDATE -/* - * Defines, declarations, sub-functions for vp9 de-block loop - filter Thr/Lvl table update - * - struct segmentation is for loop filter only (removed something) - * - function "vp9_loop_filter_init" and "vp9_loop_filter_frame_init" will - be instantiated in C_Entry - * - vp9_loop_filter_init run once before decoding start - * - vp9_loop_filter_frame_init run before every frame decoding start - * - set video format to VP9 is in vp9_loop_filter_init - */ -#define MAX_LOOP_FILTER 63 -#define MAX_REF_LF_DELTAS 4 -#define MAX_MODE_LF_DELTAS 2 -/*#define INTRA_FRAME 0*/ -/*#define LAST_FRAME 1*/ -/*#define MAX_REF_FRAMES 4*/ -#define SEGMENT_DELTADATA 0 -#define SEGMENT_ABSDATA 1 -#define MAX_SEGMENTS 8 -/*.#define SEG_TREE_PROBS (MAX_SEGMENTS-1)*/ -/*no use for loop filter, if this struct for common use, pls add it back*/ -/*#define PREDICTION_PROBS 3*/ -/* no use for loop filter, if this struct for common use, pls add it back*/ - -enum SEG_LVL_FEATURES { - SEG_LVL_ALT_Q = 0, /*Use alternate Quantizer ....*/ - SEG_LVL_ALT_LF = 1, /*Use alternate loop filter value...*/ - SEG_LVL_REF_FRAME = 2, /*Optional Segment reference frame*/ - SEG_LVL_SKIP = 3, /*Optional Segment (0,0) + skip mode*/ - SEG_LVL_MAX = 4 /*Number of features supported*/ -}; - -struct segmentation { - uint8_t enabled; - uint8_t update_map; - uint8_t update_data; - uint8_t abs_delta; - uint8_t temporal_update; - - /*no use for loop filter, if this struct - for common use, pls add it back*/ - /*vp9_prob tree_probs[SEG_TREE_PROBS]; */ - /* no use for loop filter, if this struct - for common use, pls add it back*/ - /*vp9_prob pred_probs[PREDICTION_PROBS];*/ - - int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX]; - unsigned int feature_mask[MAX_SEGMENTS]; -}; - -struct loop_filter_thresh { - uint8_t mblim; - uint8_t lim; - uint8_t hev_thr; -}; - -struct loop_filter_info_n { - struct loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1]; - uint8_t lvl[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS]; -}; - -struct loopfilter { - int filter_level; - - int sharpness_level; - int last_sharpness_level; - - uint8_t mode_ref_delta_enabled; - uint8_t mode_ref_delta_update; - - /*0 = Intra, Last, GF, ARF*/ - signed char ref_deltas[MAX_REF_LF_DELTAS]; - signed char last_ref_deltas[MAX_REF_LF_DELTAS]; - - /*0 = ZERO_MV, MV*/ - signed char mode_deltas[MAX_MODE_LF_DELTAS]; - signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; -}; - -static int vp9_clamp(int value, int low, int high) -{ - return value < low ? low : (value > high ? high : value); -} - -int segfeature_active(struct segmentation *seg, - int segment_id, - enum SEG_LVL_FEATURES feature_id) { - return seg->enabled && - (seg->feature_mask[segment_id] & (1 << feature_id)); -} - -int get_segdata(struct segmentation *seg, int segment_id, - enum SEG_LVL_FEATURES feature_id) { - return seg->feature_data[segment_id][feature_id]; -} - -static void vp9_update_sharpness(struct loop_filter_info_n *lfi, - int sharpness_lvl) -{ - int lvl; - /*For each possible value for the loop filter fill out limits*/ - for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) { - /*Set loop filter parameters that control sharpness.*/ - int block_inside_limit = lvl >> ((sharpness_lvl > 0) + - (sharpness_lvl > 4)); - - if (sharpness_lvl > 0) { - if (block_inside_limit > (9 - sharpness_lvl)) - block_inside_limit = (9 - sharpness_lvl); - } - - if (block_inside_limit < 1) - block_inside_limit = 1; - - lfi->lfthr[lvl].lim = (uint8_t)block_inside_limit; - lfi->lfthr[lvl].mblim = (uint8_t)(2 * (lvl + 2) + - block_inside_limit); - } -} - -int default_filt_lvl; -struct loop_filter_info_n *lfi; -struct loopfilter *lf; -struct segmentation *seg_4lf; - -/*instantiate this function once when decode is started*/ -void vp9_loop_filter_init(void) -{ - int i; - if (!lfi) - lfi = kmalloc(sizeof(struct loop_filter_info_n), GFP_KERNEL); - if (!lf) - lf = kmalloc(sizeof(struct loopfilter), GFP_KERNEL); - if (!seg_4lf) - seg_4lf = kmalloc(sizeof(struct segmentation), GFP_KERNEL); - if (lfi == NULL || lf == NULL || seg_4lf == NULL) { - pr_err("[test.c] vp9_loop_filter init malloc error!!!\n"); - return; - } - memset(lfi, 0, sizeof(struct loop_filter_info_n)); - memset(lf, 0, sizeof(struct loopfilter)); - memset(seg_4lf, 0, sizeof(struct segmentation)); - lf->sharpness_level = 0; /*init to 0 */ - /*init limits for given sharpness*/ - vp9_update_sharpness(lfi, lf->sharpness_level); - lf->last_sharpness_level = lf->sharpness_level; - /*init hev threshold const vectors (actually no use) - for (i = 0; i <= MAX_LOOP_FILTER; i++) - lfi->lfthr[i].hev_thr = (uint8_t)(i >> 4);*/ - - /*Write to register*/ - for (i = 0; i < 32; i++) { - unsigned int thr; - thr = ((lfi->lfthr[i * 2 + 1].lim & 0x3f)<<8) | - (lfi->lfthr[i * 2 + 1].mblim & 0xff); - thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8) | - (lfi->lfthr[i * 2].mblim & 0xff); - WRITE_VREG(HEVC_DBLK_CFG9, thr); - } - - /*video format is VP9*/ - WRITE_VREG(HEVC_DBLK_CFGB, 0x40400001); -} - /* perform this function per frame*/ -void vp9_loop_filter_frame_init(struct segmentation *seg, - struct loop_filter_info_n *lfi, struct loopfilter *lf, - int default_filt_lvl) { - int i; - int seg_id; - /*n_shift is the multiplier for lf_deltas - the multiplier is 1 for when filter_lvl is between 0 and 31; - 2 when filter_lvl is between 32 and 63*/ - const int scale = 1 << (default_filt_lvl >> 5); - - /*update limits if sharpness has changed*/ - if (lf->last_sharpness_level != lf->sharpness_level) { - vp9_update_sharpness(lfi, lf->sharpness_level); - lf->last_sharpness_level = lf->sharpness_level; - - /*Write to register*/ - for (i = 0; i < 32; i++) { - unsigned int thr; - thr = ((lfi->lfthr[i * 2 + 1].lim & 0x3f) << 8) - | (lfi->lfthr[i * 2 + 1].mblim & 0xff); - thr = (thr << 16) | ((lfi->lfthr[i * 2].lim & 0x3f) << 8) - | (lfi->lfthr[i * 2].mblim & 0xff); - WRITE_VREG(HEVC_DBLK_CFG9, thr); - } - } - - for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) {/*MAX_SEGMENTS = 8*/ - int lvl_seg = default_filt_lvl; - if (segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) { - const int data = get_segdata(seg, seg_id, - SEG_LVL_ALT_LF); - lvl_seg = vp9_clamp(seg->abs_delta == SEGMENT_ABSDATA ? - data : default_filt_lvl + data, - 0, MAX_LOOP_FILTER); -#ifdef DBG_LF_PRINT - pr_info("segfeature_active!!!seg_id=%d,lvl_seg=%d\n", seg_id, lvl_seg); -#endif - } - - if (!lf->mode_ref_delta_enabled) { - /*we could get rid of this if we assume that deltas are set to - zero when not in use; encoder always uses deltas*/ - memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id])); - } else { - int ref, mode; - const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] - * scale; -#ifdef DBG_LF_PRINT - pr_info("LF_PRINT:vp9_loop_filter_frame_init,seg_id=%d\n", seg_id); - pr_info("ref_deltas[INTRA_FRAME]=%d\n", lf->ref_deltas[INTRA_FRAME]); -#endif - lfi->lvl[seg_id][INTRA_FRAME][0] = - vp9_clamp(intra_lvl, 0, MAX_LOOP_FILTER); - - for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) { - /* LAST_FRAME = 1, MAX_REF_FRAMES = 4*/ - for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { - /*MAX_MODE_LF_DELTAS = 2*/ - const int inter_lvl = - lvl_seg + lf->ref_deltas[ref] * scale - + lf->mode_deltas[mode] * scale; -#ifdef DBG_LF_PRINT -#endif - lfi->lvl[seg_id][ref][mode] = - vp9_clamp(inter_lvl, 0, - MAX_LOOP_FILTER); - } - } - } - } - -#ifdef DBG_LF_PRINT - /*print out thr/lvl table per frame*/ - for (i = 0; i <= MAX_LOOP_FILTER; i++) { - pr_info("LF_PRINT:(%d)thr=%d,blim=%d,lim=%d\n", - i, lfi->lfthr[i].hev_thr, lfi->lfthr[i].mblim, - lfi->lfthr[i].lim); - } - for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { - pr_info("LF_PRINT:lvl(seg_id=%d)(mode=0,%d,%d,%d,%d)\n", - seg_id, lfi->lvl[seg_id][0][0], - lfi->lvl[seg_id][1][0], lfi->lvl[seg_id][2][0], - lfi->lvl[seg_id][3][0]); - pr_info("i(mode=1,%d,%d,%d,%d)\n", lfi->lvl[seg_id][0][1], - lfi->lvl[seg_id][1][1], lfi->lvl[seg_id][2][1], - lfi->lvl[seg_id][3][1]); - } -#endif - - /*Write to register */ - for (i = 0; i < 16; i++) { - unsigned int level; - level = ((lfi->lvl[i >> 1][3][i & 1] & 0x3f) << 24) | - ((lfi->lvl[i >> 1][2][i & 1] & 0x3f) << 16) | - ((lfi->lvl[i >> 1][1][i & 1] & 0x3f) << 8) | - (lfi->lvl[i >> 1][0][i & 1] & 0x3f); - if (!default_filt_lvl) - level = 0; - WRITE_VREG(HEVC_DBLK_CFGA, level); - } -} -/* VP9_LPF_LVL_UPDATE */ -#endif - -static void vp9_init_decoder_hw(struct VP9Decoder_s *pbi) -{ - unsigned int data32; - int i; - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("[test.c] Enable HEVC Parser Interrupt\n"); - 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); - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("[test.c] Enable HEVC Parser Shift\n"); - - 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, - (0 << 14) | /*disable_start_code_protect*/ - (1 << 10) | /*length_zero_startcode_en for VP9*/ - (1 << 9) | /*length_valid_startcode_en for VP9*/ - (3 << 6) | /*sft_valid_wr_position*/ - (2 << 4) | /*emulate_code_length_sub_1*/ - (3 << 1) | /*start_code_length_sub_1 - VP9 use 0x00000001 as startcode (4 Bytes)*/ - (1 << 0) /*stream_shift_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 (debug & VP9_DEBUG_BUFMGR) - pr_info("Initial IQIT_SCALELUT memory\n"); - WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/ - for (i = 0; i < 1024; i++) - WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); - - -#ifdef ENABLE_SWAP_TEST - WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100); -#else - WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0); -#endif -#ifdef MULTI_INSTANCE_SUPPORT - if (pbi->platform_dev && vdec_frame_based(hw_to_vdec(pbi))) - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); - else - WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); - WRITE_VREG(HEVC_DECODE_SIZE, 0); - WRITE_VREG(HEVC_DECODE_COUNT, 0); -#else - WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); - WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0); - WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0x7fffffff); /*to remove*/ -#endif - /*Send parser_cmd*/ - if (debug) - pr_info("[test.c] SEND Parser Command ...\n"); - WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0)); - for (i = 0; i < PARSER_CMD_NUMBER; i++) - WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]); - WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0); - WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1); - WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2); - - - WRITE_VREG(HEVC_PARSER_IF_CONTROL, - /* (1 << 8) |*/ /*sao_sw_pred_enable*/ - (1 << 5) | /*parser_sao_if_en*/ - (1 << 2) | /*parser_mpred_if_en*/ - (1 << 0) /*parser_scaler_if_en*/ - ); - /*Changed to Start MPRED in microcode*/ - /* - pr_info("[test.c] Start MPRED\n"); - WRITE_VREG(HEVC_MPRED_INT_STATUS, - (1<<31) - ); - */ - if (debug) - pr_info("[test.c] Reset IPP\n"); - 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*/ - ); -#ifdef VP9_10B_NV21 - /*Enable NV21 reference read mode for MC*/ - WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31); -#endif - - /*Initialize mcrcc and decomp perf counters - mcrcc_perfcount_reset(); - decomp_perfcount_reset();*/ - return; -} - - -#ifdef CONFIG_HEVC_CLK_FORCED_ON -static void config_vp9_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 - - -#ifdef MCRCC_ENABLE -static void config_mcrcc_axi_hw(struct VP9Decoder_s *pbi) -{ - unsigned int rdata32; - unsigned short is_inter; - /*pr_info("Entered config_mcrcc_axi_hw...\n");*/ - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2);/* reset mcrcc*/ - is_inter = ((pbi->common.frame_type != KEY_FRAME) && - (!pbi->common.intra_only)) ? 1 : 0; - if (!is_inter) { /* I-PIC*/ - /*remove reset -- disables clock*/ - WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0); - return; - } - -#if 0 - pr_info("before call mcrcc_get_hitrate\r\n"); - mcrcc_get_hitrate(); - decomp_get_hitrate(); - decomp_get_comprate(); -#endif - - 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; -} -#endif - - -static struct VP9Decoder_s gHevc; - -static void vp9_local_uninit(struct VP9Decoder_s *pbi) -{ - pbi->rpm_ptr = NULL; - pbi->lmem_ptr = NULL; - if (pbi->rpm_addr) { - dma_unmap_single(amports_get_dma_device(), - pbi->rpm_phy_addr, RPM_BUF_SIZE, - DMA_FROM_DEVICE); - kfree(pbi->rpm_addr); - pbi->rpm_addr = NULL; - } - if (pbi->lmem_addr) { - if (pbi->lmem_phy_addr) - dma_free_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, pbi->lmem_addr, - pbi->lmem_phy_addr); - - pbi->lmem_addr = NULL; - } - 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; - } -#ifdef VP9_10B_MMU - if (pbi->frame_mmu_map_addr) { - if (pbi->frame_mmu_map_phy_addr) - dma_free_coherent(amports_get_dma_device(), - FRAME_MMU_MAP_SIZE, pbi->frame_mmu_map_addr, - pbi->frame_mmu_map_phy_addr); - - pbi->frame_mmu_map_addr = NULL; - } -#endif - -#ifdef VP9_LPF_LVL_UPDATE - kfree(lfi); - lfi = NULL; - kfree(lf); - lf = NULL; - kfree(seg_4lf); - seg_4lf = NULL; -#endif -} - -static int vp9_local_init(struct VP9Decoder_s *pbi) -{ - int ret = -1; - /*int losless_comp_header_size, losless_comp_body_size;*/ - - struct BuffInfo_s *cur_buf_info = NULL; - memset(&pbi->param, 0, sizeof(union param_u)); - memset(&pbi->common, 0, sizeof(struct VP9_Common_s)); -#ifdef MULTI_INSTANCE_SUPPORT - cur_buf_info = &pbi->work_space_buf_store; -#ifdef SUPPORT_4K2K - memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k2k work space */ - sizeof(struct BuffInfo_s)); -#else - memcpy(cur_buf_info, &amvvp9_workbuff_spec[0], /* 1080p work space */ - sizeof(struct BuffInfo_s)); -#endif - cur_buf_info->start_adr = pbi->buf_start; - pbi->mc_buf_spec.buf_end = pbi->buf_start + pbi->buf_size; -#else -/*! MULTI_INSTANCE_SUPPORT*/ -#ifdef SUPPORT_4K2K - cur_buf_info = &amvvp9_workbuff_spec[1]; /* 4k2k work space */ -#else - cur_buf_info = &amvvp9_workbuff_spec[0]; /* 1080p work space */ -#endif -#endif - - init_buff_spec(pbi, cur_buf_info); - pbi->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff) - & (~0xffff); - pbi->mc_buf_spec.buf_size = (pbi->mc_buf_spec.buf_end - - pbi->mc_buf_spec.buf_start); - if (debug) { - pr_err("pbi->mc_buf_spec.buf_start %x-%x\n", - pbi->mc_buf_spec.buf_start, - pbi->mc_buf_spec.buf_start + - pbi->mc_buf_spec.buf_size); - } - vp9_bufmgr_init(pbi, cur_buf_info, &pbi->mc_buf_spec); - - pbi->init_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 = buf_alloc_height ? buf_alloc_height : - (pbi->vvp9_amstream_dec_info.height ? - pbi->vvp9_amstream_dec_info.height : - pbi->work_space_buf->max_height); -#ifndef VP9_10B_MMU - init_buf_list(pbi); -#endif - init_pic_list(pbi); - - pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param) - & 0x40) >> 6; - - pbi->video_signal_type = 0; - video_signal_type = pbi->video_signal_type; - - if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) { - pbi->rpm_addr = kmalloc(RPM_BUF_SIZE, GFP_KERNEL); - if (pbi->rpm_addr == NULL) { - pr_err("%s: failed to alloc rpm buffer\n", __func__); - return -1; - } - - pbi->rpm_phy_addr = dma_map_single(amports_get_dma_device(), - pbi->rpm_addr, RPM_BUF_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - pbi->rpm_phy_addr)) { - pr_err("%s: failed to map rpm buffer\n", __func__); - kfree(pbi->rpm_addr); - pbi->rpm_addr = NULL; - return -1; - } - - pbi->rpm_ptr = pbi->rpm_addr; - } - - if (debug & VP9_DEBUG_UCODE) { - pbi->lmem_addr = dma_alloc_coherent(amports_get_dma_device(), - LMEM_BUF_SIZE, - &pbi->lmem_phy_addr, GFP_KERNEL); - if (pbi->lmem_addr == NULL) { - pr_err("%s: failed to alloc lmem buffer\n", __func__); - return -1; - } -/* - pbi->lmem_phy_addr = dma_map_single(amports_get_dma_device(), - pbi->lmem_addr, LMEM_BUF_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - pbi->lmem_phy_addr)) { - pr_err("%s: failed to map lmem buffer\n", __func__); - kfree(pbi->lmem_addr); - pbi->lmem_addr = NULL; - return -1; - } -*/ - pbi->lmem_ptr = pbi->lmem_addr; - } - 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->prob_buffer_phy_addr = dma_map_single(amports_get_dma_device(), - pbi->prob_buffer_addr, PROB_BUF_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - pbi->prob_buffer_phy_addr)) { - pr_err("%s: failed to map prob_buffer\n", __func__); - kfree(pbi->prob_buffer_addr); - pbi->prob_buffer_addr = NULL; - return -1; - } -*/ - 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->count_buffer_phy_addr = dma_map_single(amports_get_dma_device(), - pbi->count_buffer_addr, COUNT_BUF_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - pbi->count_buffer_phy_addr)) { - pr_err("%s: failed to map count_buffer\n", __func__); - kfree(pbi->count_buffer_addr); - pbi->count_buffer_addr = NULL; - return -1; - } -*/ -#ifdef VP9_10B_MMU - pbi->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(), - FRAME_MMU_MAP_SIZE, - &pbi->frame_mmu_map_phy_addr, GFP_KERNEL); - if (pbi->frame_mmu_map_addr == NULL) { - pr_err("%s: failed to alloc count_buffer\n", __func__); - return -1; - } - memset(pbi->frame_mmu_map_addr, 0, COUNT_BUF_SIZE); -/* pbi->frame_mmu_map_phy_addr = dma_map_single(amports_get_dma_device(), - pbi->frame_mmu_map_addr, FRAME_MMU_MAP_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(amports_get_dma_device(), - pbi->frame_mmu_map_phy_addr)) { - pr_err("%s: failed to map count_buffer\n", __func__); - kfree(pbi->frame_mmu_map_addr); - pbi->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 PIC_BUFFER_CONFIG_s *pic_config) -{ - int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4; - int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4; - int blkmode = mem_map_mode; - /*CANVAS_BLKMODE_64X32*/ - if (double_write_mode) { - canvas_w = pic_config->y_crop_width; - canvas_h = pic_config->y_crop_height; - if (double_write_mode == 2) { - canvas_w >>= 2; - canvas_h >>= 2; - } - - if (mem_map_mode == 0) - canvas_w = ALIGN(canvas_w, 32); - else - canvas_w = ALIGN(canvas_w, 64); - canvas_h = ALIGN(canvas_h, 32); - - pic_config->y_canvas_index = 128 + pic_config->index * 2; - pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1; - - canvas_config_ex(pic_config->y_canvas_index, - pic_config->dw_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, 0x7); - canvas_config_ex(pic_config->uv_canvas_index, - pic_config->dw_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, 0x7); -#ifdef MULTI_INSTANCE_SUPPORT - pic_config->canvas_config[0].phy_addr = - pic_config->dw_y_adr; - pic_config->canvas_config[0].width = - canvas_w; - pic_config->canvas_config[0].height = - canvas_h; - pic_config->canvas_config[0].block_mode = - blkmode; - pic_config->canvas_config[0].endian = 7; - - pic_config->canvas_config[1].phy_addr = - pic_config->dw_u_v_adr; - pic_config->canvas_config[1].width = - canvas_w; - pic_config->canvas_config[1].height = - canvas_h; - pic_config->canvas_config[1].block_mode = - blkmode; - pic_config->canvas_config[1].endian = 7; -#endif - } else { - #ifndef VP9_10B_MMU - pic_config->y_canvas_index = 128 + pic_config->index; - pic_config->uv_canvas_index = 128 + pic_config->index; - - canvas_config_ex(pic_config->y_canvas_index, - pic_config->mc_y_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, 0x7); - canvas_config_ex(pic_config->uv_canvas_index, - pic_config->mc_u_v_adr, canvas_w, canvas_h, - CANVAS_ADDR_NOWRAP, blkmode, 0x7); - #endif - } - -} - - -static void set_frame_info(struct VP9Decoder_s *pbi, struct vframe_s *vf) -{ - unsigned int ar; - - vf->duration = pbi->frame_dur; - vf->duration_pulldown = 0; - vf->flag = 0; - - ar = min_t(u32, pbi->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX); - vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); - - return; -} - -static int vvp9_vf_states(struct vframe_states *states, void *op_arg) -{ - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg; - - states->vf_pool_size = VF_POOL_SIZE; - states->buf_free_num = kfifo_len(&pbi->newframe_q); - states->buf_avail_num = kfifo_len(&pbi->display_q); - - if (step == 2) - states->buf_avail_num = 0; - return 0; -} - -static struct vframe_s *vvp9_vf_peek(void *op_arg) -{ - struct vframe_s *vf; - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg; - if (step == 2) - return NULL; - - if (kfifo_peek(&pbi->display_q, &vf)) - return vf; - - return NULL; -} - -static struct vframe_s *vvp9_vf_get(void *op_arg) -{ - struct vframe_s *vf; - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg; - if (step == 2) - return NULL; - else if (step == 1) - step = 2; - - if (kfifo_get(&pbi->display_q, &vf)) { - uint8_t index = vf->index & 0xff; - if (index >= 0 && index < FRAME_BUFFERS) - return vf; - } - return NULL; -} - -static void vvp9_vf_put(struct vframe_s *vf, void *op_arg) -{ - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg; - uint8_t index = vf->index & 0xff; - - kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf); - - if (index >= 0 - && index < FRAME_BUFFERS) { - struct VP9_Common_s *cm = &pbi->common; - struct BufferPool_s *pool = cm->buffer_pool; - lock_buffer_pool(pool); - if (pool->frame_bufs[index].buf.vf_ref > 0) - pool->frame_bufs[index].buf.vf_ref--; - - if (pbi->wait_buf) - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - pbi->last_put_idx = index; - pbi->new_frame_displayed++; - unlock_buffer_pool(pool); - } - -} - -static int vvp9_event_cb(int type, void *data, void *private_data) -{ - if (type & VFRAME_EVENT_RECEIVER_RESET) { -#if 0 - unsigned long flags; - amhevc_stop(); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_light_unreg_provider(&vvp9_vf_prov); -#endif - spin_lock_irqsave(&pbi->lock, flags); - vvp9_local_init(); - vvp9_prot_init(); - spin_unlock_irqrestore(&pbi->lock, flags); -#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER - vf_reg_provider(&vvp9_vf_prov); -#endif - amhevc_start(); -#endif - } - - return 0; -} - -void inc_vf_ref(struct VP9Decoder_s *pbi, int index) -{ - struct VP9_Common_s *cm = &pbi->common; - cm->buffer_pool->frame_bufs[index].buf.vf_ref++; - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("%s index = %d new vf_ref = %d\r\n", - __func__, index, - cm->buffer_pool->frame_bufs[index].buf.vf_ref); -} - - -static int prepare_display_buf(struct VP9Decoder_s *pbi, - struct PIC_BUFFER_CONFIG_s *pic_config) -{ - struct vframe_s *vf = NULL; - int stream_offset = pic_config->stream_offset; - unsigned short slice_type = pic_config->slice_type; - - if (debug & VP9_DEBUG_BUFMGR) - pr_info("%s index = %d\r\n", __func__, pic_config->index); - if (kfifo_get(&pbi->newframe_q, &vf) == 0) { - pr_info("fatal error, no available buffer slot."); - return -1; - } - - if (double_write_mode) { - set_canvas(pic_config); - } - if (vf) { - /* 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, 0, - &vf->pts_us64) != 0) { -#ifdef DEBUG_PTS - pbi->pts_missed++; -#endif - vf->pts = 0; - vf->pts_us64 = 0; - } -#ifdef DEBUG_PTS - else - pbi->pts_hit++; -#endif - if (pts_unstable) - pbi->pts_mode = PTS_NONE_REF_USE_DURATION; - - if ((pbi->pts_mode == PTS_NORMAL) && (vf->pts != 0) - && pbi->get_frame_dur) { - int pts_diff = (int)vf->pts - pbi->last_lookup_pts; - - if (pts_diff < 0) { - pbi->pts_mode_switching_count++; - pbi->pts_mode_recovery_count = 0; - - if (pbi->pts_mode_switching_count >= - PTS_MODE_SWITCHING_THRESHOLD) { - pbi->pts_mode = - PTS_NONE_REF_USE_DURATION; - pr_info - ("HEVC: switch to n_d mode.\n"); - } - - } else { - int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD; - pbi->pts_mode_recovery_count++; - if (pbi->pts_mode_recovery_count > p) { - pbi->pts_mode_switching_count = 0; - pbi->pts_mode_recovery_count = 0; - } - } - } - - if (vf->pts != 0) - pbi->last_lookup_pts = vf->pts; - - if ((pbi->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != KEY_FRAME)) - vf->pts = pbi->last_pts + DUR2PTS(pbi->frame_dur); - pbi->last_pts = vf->pts; - - if (vf->pts_us64 != 0) - pbi->last_lookup_pts_us64 = vf->pts_us64; - - if ((pbi->pts_mode == PTS_NONE_REF_USE_DURATION) - && (slice_type != KEY_FRAME)) { - vf->pts_us64 = - pbi->last_pts_us64 + - (DUR2PTS(pbi->frame_dur) * 100 / 9); - } - pbi->last_pts_us64 = vf->pts_us64; - if ((debug & VP9_DEBUG_OUT_PTS) != 0) { - pr_info - ("VP9 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n", - vf->pts, vf->pts_us64); - } - - vf->index = 0xff00 | pic_config->index; -#if 1 -/*SUPPORT_10BIT*/ - if (double_write_mode & 0x10) { - /* double write only */ - vf->compBodyAddr = 0; - vf->compHeadAddr = 0; - } else { -#ifdef VP9_10B_MMU - vf->compBodyAddr = 0; - vf->compHeadAddr = pic_config->header_adr; -#else - vf->compBodyAddr = pic_config->mc_y_adr; /*body adr*/ - vf->compHeadAddr = pic_config->mc_y_adr + - pic_config->comp_body_size; - /*head adr*/ -#endif - } - if (double_write_mode) { - vf->type = VIDTYPE_PROGRESSIVE | - VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; -#ifdef MULTI_INSTANCE_SUPPORT - if (pbi->m_ins_flag) { - vf->canvas0Addr = vf->canvas1Addr = -1; - vf->plane_num = 2; - vf->canvas0_config[0] = - pic_config->canvas_config[0]; - vf->canvas0_config[1] = - pic_config->canvas_config[1]; - - vf->canvas1_config[0] = - pic_config->canvas_config[0]; - vf->canvas1_config[1] = - pic_config->canvas_config[1]; - - } else -#endif - vf->canvas0Addr = vf->canvas1Addr = - spec2canvas(pic_config); - } else { - vf->canvas0Addr = vf->canvas1Addr = 0; - vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD; -#ifdef VP9_10B_MMU - vf->type |= VIDTYPE_SCATTER; -#endif - switch (pic_config->bit_depth) { - case VPX_BITS_8: - vf->bitdepth = BITDEPTH_Y8 | - BITDEPTH_U8 | BITDEPTH_V8; - break; - case VPX_BITS_10: - case VPX_BITS_12: - vf->bitdepth = BITDEPTH_Y10 | - BITDEPTH_U10 | BITDEPTH_V10; - break; - default: - vf->bitdepth = BITDEPTH_Y10 | - BITDEPTH_U10 | BITDEPTH_V10; - break; - } - if (pic_config->bit_depth == VPX_BITS_8) - vf->bitdepth |= BITDEPTH_SAVING_MODE; - } -#else - vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; - vf->type |= VIDTYPE_VIU_NV21; - vf->canvas0Addr = vf->canvas1Addr = spec2canvas(pic_config); -#endif - set_frame_info(pbi, vf); - /* 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); */ - if (double_write_mode == 2) { - vf->width = pic_config->y_crop_width/4; - vf->height = pic_config->y_crop_height/4; - } else { - vf->width = pic_config->y_crop_width; - vf->height = pic_config->y_crop_height; - } - if (force_w_h != 0) { - vf->width = (force_w_h >> 16) & 0xffff; - vf->height = force_w_h & 0xffff; - } - vf->compWidth = pic_config->y_crop_width; - vf->compHeight = pic_config->y_crop_height; - if (force_fps & 0x100) { - u32 rate = force_fps & 0xff; - if (rate) - vf->duration = 96000/rate; - else - vf->duration = 0; - } - if (vf->type & VIDTYPE_SCATTER) { - vf->mem_handle = decoder_mmu_box_get_mem_handle( - pbi->mmu_box, - pic_config->index); - } else { - vf->mem_handle = decoder_bmmu_box_get_mem_handle( - pbi->bmmu_box, - pic_config->index); - } - inc_vf_ref(pbi, pic_config->index); - kfifo_put(&pbi->display_q, (const struct vframe_s *)vf); - vf_notify_receiver(pbi->provider_name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - } - - return 0; -} - -static void get_rpm_param(union param_u *params) -{ - int i; - unsigned int data32; - if (debug & VP9_DEBUG_BUFMGR) - pr_info("enter %s\r\n", __func__); - for (i = 0; i < 128; 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 & VP9_DEBUG_BUFMGR) - pr_info("leave %s\r\n", __func__); -} -static void debug_buffer_mgr_more(struct VP9Decoder_s *pbi) -{ - int i; - if (!(debug & VP9_DEBUG_BUFMGR_MORE)) - return; - pr_info("vp9_param: (%d)\n", pbi->slice_idx); - for (i = 0; i < (RPM_END-RPM_BEGIN); i++) { - pr_info("%04x ", vp9_param.l.data[i]); - if (((i + 1) & 0xf) == 0) - pr_info("\n"); - } - pr_info("=============param==========\r\n"); - pr_info("profile %x\r\n", vp9_param.p.profile); - pr_info("show_existing_frame %x\r\n", - vp9_param.p.show_existing_frame); - pr_info("frame_to_show_idx %x\r\n", - vp9_param.p.frame_to_show_idx); - pr_info("frame_type %x\r\n", vp9_param.p.frame_type); - pr_info("show_frame %x\r\n", vp9_param.p.show_frame); - pr_info("e.r.r.o.r_resilient_mode %x\r\n", - vp9_param.p.error_resilient_mode); - pr_info("intra_only %x\r\n", vp9_param.p.intra_only); - pr_info("display_size_present %x\r\n", - vp9_param.p.display_size_present); - pr_info("reset_frame_context %x\r\n", - vp9_param.p.reset_frame_context); - pr_info("refresh_frame_flags %x\r\n", - vp9_param.p.refresh_frame_flags); - pr_info("bit_depth %x\r\n", vp9_param.p.bit_depth); - pr_info("width %x\r\n", vp9_param.p.width); - pr_info("height %x\r\n", vp9_param.p.height); - pr_info("display_width %x\r\n", vp9_param.p.display_width); - pr_info("display_height %x\r\n", vp9_param.p.display_height); - pr_info("ref_info %x\r\n", vp9_param.p.ref_info); - pr_info("same_frame_size %x\r\n", vp9_param.p.same_frame_size); - if (!(debug & VP9_DEBUG_DBG_LF_PRINT)) - return; - pr_info("mode_ref_delta_enabled: 0x%x\r\n", - vp9_param.p.mode_ref_delta_enabled); - pr_info("sharpness_level: 0x%x\r\n", - vp9_param.p.sharpness_level); - pr_info("ref_deltas: 0x%x, 0x%x, 0x%x, 0x%x\r\n", - vp9_param.p.ref_deltas[0], vp9_param.p.ref_deltas[1], - vp9_param.p.ref_deltas[2], vp9_param.p.ref_deltas[3]); - pr_info("mode_deltas: 0x%x, 0x%x\r\n", vp9_param.p.mode_deltas[0], - vp9_param.p.mode_deltas[1]); - pr_info("filter_level: 0x%x\r\n", vp9_param.p.filter_level); - pr_info("seg_enabled: 0x%x\r\n", vp9_param.p.seg_enabled); - pr_info("seg_abs_delta: 0x%x\r\n", vp9_param.p.seg_abs_delta); - pr_info("seg_lf_feature_enabled: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", - (vp9_param.p.seg_lf_info[0]>>15 & 1), - (vp9_param.p.seg_lf_info[1]>>15 & 1), - (vp9_param.p.seg_lf_info[2]>>15 & 1), - (vp9_param.p.seg_lf_info[3]>>15 & 1), - (vp9_param.p.seg_lf_info[4]>>15 & 1), - (vp9_param.p.seg_lf_info[5]>>15 & 1), - (vp9_param.p.seg_lf_info[6]>>15 & 1), - (vp9_param.p.seg_lf_info[7]>>15 & 1)); - pr_info("seg_lf_feature_data: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", - (vp9_param.p.seg_lf_info[0] & 0x13f), - (vp9_param.p.seg_lf_info[1] & 0x13f), - (vp9_param.p.seg_lf_info[2] & 0x13f), - (vp9_param.p.seg_lf_info[3] & 0x13f), - (vp9_param.p.seg_lf_info[4] & 0x13f), - (vp9_param.p.seg_lf_info[5] & 0x13f), - (vp9_param.p.seg_lf_info[6] & 0x13f), - (vp9_param.p.seg_lf_info[7] & 0x13f)); - -} - -static irqreturn_t vvp9_isr_thread_fn(int irq, void *data) -{ - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data; - unsigned int dec_status = pbi->dec_status; - struct VP9_Common_s *const cm = &pbi->common; - int i, ret; - - /*if (pbi->wait_buf) - pr_info("set wait_buf to 0\r\n"); - */ - pbi->wait_buf = 0; - - if (dec_status == VP9_EOS) { - pr_info("VP9_EOS, flush buffer\r\n"); - - vp9_bufmgr_postproc(pbi); - - pr_info("send VP9_10B_DISCARD_NAL\r\n"); - WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL); - pbi->process_busy = 0; - return IRQ_HANDLED; - } - - if (dec_status != VP9_HEAD_PARSER_DONE) { - pbi->process_busy = 0; - return IRQ_HANDLED; - } - if (pbi->frame_count > 0) - vp9_bufmgr_postproc(pbi); - - if (debug & VP9_DEBUG_SEND_PARAM_WITH_REG) { - get_rpm_param(&vp9_param); - } else { - dma_sync_single_for_cpu( - amports_get_dma_device(), - pbi->rpm_phy_addr, - RPM_BUF_SIZE, - DMA_FROM_DEVICE); - - for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) { - int ii; - for (ii = 0; ii < 4; ii++) - vp9_param.l.data[i + ii] = - pbi->rpm_ptr[i + 3 - ii]; - } - } - debug_buffer_mgr_more(pbi); - - bit_depth_luma = vp9_param.p.bit_depth; - bit_depth_chroma = vp9_param.p.bit_depth; - - ret = vp9_bufmgr_process(pbi, &vp9_param); - pbi->slice_idx++; - if (ret < 0) { - pr_info("vp9_bufmgr_process=> %d, VP9_10B_DISCARD_NAL\r\n", - ret); - WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL); - pbi->process_busy = 0; - return IRQ_HANDLED; - } else if (ret == 0) { - pbi->frame_count++; - /*pr_info("Decode Frame Data %d\n", pbi->frame_count);*/ - config_pic_size(pbi, vp9_param.p.bit_depth); - if ((pbi->common.frame_type != KEY_FRAME) - && (!pbi->common.intra_only)) { - config_mc_buffer(pbi, vp9_param.p.bit_depth); - config_mpred_hw(pbi); - } else { - clear_mpred_hw(pbi); - } -#ifdef MCRCC_ENABLE - config_mcrcc_axi_hw(pbi); -#endif - config_sao_hw(pbi, &vp9_param); - -#ifdef VP9_LPF_LVL_UPDATE - /* - * Get loop filter related picture level parameters from Parser - */ - lf->mode_ref_delta_enabled = vp9_param.p.mode_ref_delta_enabled; - lf->sharpness_level = vp9_param.p.sharpness_level; - for (i = 0; i < 4; i++) - lf->ref_deltas[i] = vp9_param.p.ref_deltas[i]; - for (i = 0; i < 2; i++) - lf->mode_deltas[i] = vp9_param.p.mode_deltas[i]; - default_filt_lvl = vp9_param.p.filter_level; - seg_4lf->enabled = vp9_param.p.seg_enabled; - seg_4lf->abs_delta = vp9_param.p.seg_abs_delta; - for (i = 0; i < MAX_SEGMENTS; i++) - seg_4lf->feature_mask[i] = (vp9_param.p.seg_lf_info[i] & - 0x8000) ? (1 << SEG_LVL_ALT_LF) : 0; - - for (i = 0; i < MAX_SEGMENTS; i++) - seg_4lf->feature_data[i][SEG_LVL_ALT_LF] - = (vp9_param.p.seg_lf_info[i] - & 0x100) ? -(vp9_param.p.seg_lf_info[i] - & 0x3f) : (vp9_param.p.seg_lf_info[i] & 0x3f); - /* - * Update loop filter Thr/Lvl table for every frame - */ - /*pr_info - ("vp9_loop_filter (run before every frame decoding start)\n");*/ - vp9_loop_filter_frame_init(seg_4lf, lfi, lf, default_filt_lvl); -#endif - /*pr_info("HEVC_DEC_STATUS_REG <= VP9_10B_DECODE_SLICE\n");*/ - - WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DECODE_SLICE); - } else { - pr_info("Skip search next start code\n"); - cm->prev_fb_idx = INVALID_IDX; - /*skip, search next start code*/ - WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DECODE_SLICE); - } - pbi->process_busy = 0; -#ifdef VP9_10B_MMU - if (pbi->last_put_idx >= 0 && pbi->last_put_idx < FRAME_BUFFERS) { - struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs; - int i = pbi->last_put_idx; - /*free not used buffers.*/ - if ((frame_bufs[i].ref_count == 0) && - (frame_bufs[i].buf.vf_ref == 0) && - (frame_bufs[i].buf.used_by_display == 0) && - (frame_bufs[i].buf.index != -1)) { - decoder_mmu_box_free_idx(pbi->mmu_box, i); - } - pbi->last_put_idx = -1; - } -#endif - return IRQ_HANDLED; -} - -static irqreturn_t vvp9_isr(int irq, void *data) -{ - int i; - 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; - dec_status = READ_VREG(HEVC_DEC_STATUS_REG); - adapt_prob_status = READ_VREG(VP9_ADAPT_PROB_REG); - if (pbi->init_flag == 0) - return IRQ_HANDLED; - if (pbi->process_busy)/*on process.*/ - return IRQ_HANDLED; - pbi->dec_status = dec_status; - pbi->process_busy = 1; - if (debug & VP9_DEBUG_BUFMGR) - pr_info("vp9 isr dec status = %d\n", dec_status); - - if (debug & VP9_DEBUG_UCODE) { - if (READ_HREG(DEBUG_REG1) & 0x10000) { - dma_sync_single_for_cpu( - amports_get_dma_device(), - pbi->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 ", - pbi->lmem_ptr[i + 3 - ii]); - } - if (((i + ii) & 0xf) == 0) - pr_info("\n"); - } - WRITE_HREG(DEBUG_REG1, 0); - } else if (READ_HREG(DEBUG_REG1) != 0) { - pr_info("dbg%x: %x\n", READ_HREG(DEBUG_REG1), - READ_HREG(DEBUG_REG2)); - WRITE_HREG(DEBUG_REG1, 0); - pbi->process_busy = 0; - return IRQ_HANDLED; - } - - } - - if (pbi->error_flag == 1) { - pbi->error_flag = 2; - pbi->process_busy = 0; - return IRQ_HANDLED; - } else if (pbi->error_flag == 3) { - pbi->process_busy = 0; - return IRQ_HANDLED; - } - - if (is_buffer_empty(cm)) { - /* - if (pbi->wait_buf == 0) - pr_info("set wait_buf to 1\r\n"); - */ - pbi->wait_buf = 1; - pbi->process_busy = 0; - return IRQ_HANDLED; - } - if ((adapt_prob_status & 0xff) == 0xfd) { - /*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; - - 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); - WRITE_VREG(VP9_ADAPT_PROB_REG, 0); - pbi->pic_count += 1; - - /*return IRQ_HANDLED;*/ - } -#ifdef MULTI_INSTANCE_SUPPORT -#if 0 - if ((dec_status == HEVC_DECPIC_DATA_DONE) && (pbi->m_ins_flag)) { - if (pbi->chunk) { - pbi->cur_pic->pts = pbi->chunk->pts; - pbi->cur_pic->pts64 = pbi->chunk->pts64; - } else if (pts_lookup_offset_us64 - (PTS_TYPE_VIDEO, - pbi->cur_pic->stream_offset, - &pbi->cur_pic->pts, - 0, - &pbi->cur_pic->pts64) != 0) { -#ifdef DEBUG_PTS - pbi->pts_missed++; -#endif - pbi->cur_pic->pts = 0; - pbi->cur_pic->pts64 = 0; - } - } -#endif - if (dec_status == HEVC_NAL_DECODE_DONE) { - if (pbi->m_ins_flag) { -#if 0 - if (!vdec_frame_based(hw_to_vdec(hevc))) { - pbi->dec_result = DEC_RESULT_AGAIN; - if ((debug & - ONLY_RESET_AT_START) == 0) - amhevc_stop(); - } else - pbi->dec_result = DEC_RESULT_GET_DATA; -#else - if (!vdec_frame_based(hw_to_vdec(pbi))) - pbi->dec_result = DEC_RESULT_AGAIN; - else - pbi->dec_result = DEC_RESULT_DONE; - amhevc_stop(); -#endif - schedule_work(&pbi->work); - } - pbi->process_busy = 0; - return IRQ_HANDLED; - } else if (dec_status == HEVC_DECPIC_DATA_DONE) { - if (pbi->m_ins_flag) { - pbi->dec_result = DEC_RESULT_DONE; - amhevc_stop(); - schedule_work(&pbi->work); - } - - pbi->process_busy = 0; - return IRQ_HANDLED; - } else if ( - (dec_status == HEVC_SEARCH_BUFEMPTY) || - (dec_status == HEVC_DECODE_BUFEMPTY) || - (dec_status == HEVC_DECODE_TIMEOUT)) { - if (vdec_frame_based(hw_to_vdec(pbi)) || - (READ_VREG(HEVC_STREAM_LEVEL) > 0x200)) { - if (debug & VP9_DEBUG_DIS_LOC_ERROR_PROC) { - vp9_print(pbi, PRINT_FLAG_ERROR, - "%s decoding error, level 0x%x\n", - __func__, READ_VREG(HEVC_STREAM_LEVEL)); - goto send_again; - } - amhevc_stop(); - vp9_print(pbi, PRINT_FLAG_UCODE_EVT, - "%s %s\n", __func__, - (dec_status == HEVC_SEARCH_BUFEMPTY) ? - "HEVC_SEARCH_BUFEMPTY" : - (dec_status == HEVC_DECODE_BUFEMPTY) ? - "HEVC_DECODE_BUFEMPTY" : "HEVC_DECODE_TIMEOUT"); - pbi->dec_result = DEC_RESULT_DONE; - - schedule_work(&pbi->work); - } else { - /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */ - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s DEC_RESULT_AGAIN\n", __func__); -send_again: - pbi->dec_result = DEC_RESULT_AGAIN; - schedule_work(&pbi->work); - } - pbi->process_busy = 0; - return IRQ_HANDLED; - } -#endif - - return IRQ_WAKE_THREAD; -} - -static void vvp9_put_timer_func(unsigned long arg) -{ - 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) { - pbi->dec_result = DEC_RESULT_DONE; - schedule_work(&pbi->work); - pr_info( - "vdec requested to be disconnected\n"); - return; - } - } - if (pbi->init_flag == 0) { - if (pbi->stat & STAT_TIMER_ARM) { - timer->expires = jiffies + PUT_INTERVAL; - add_timer(&pbi->timer); - } - return; - } - if (pbi->m_ins_flag == 0) { - if (vf_get_receiver(pbi->provider_name)) { - state = - vf_notify_receiver(pbi->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 & VP9_DEBUG_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(&pbi->display_q) && - buf_level > 0x200) - ) { - WRITE_VREG - (HEVC_ASSIST_MBOX1_IRQ_REG, - 0x1); - } - } - - if ((debug & VP9_DEBUG_DIS_SYS_ERROR_PROC) == 0) { - /* receiver has no buffer to recycle */ - /*if ((state == RECEIVER_INACTIVE) && - (kfifo_is_empty(&pbi->display_q))) { - pr_info("vp9 something error,need reset\n"); - }*/ - } - } - } - - if (decode_stop_pos != decode_stop_pos_pre) { - WRITE_VREG(DECODE_STOP_POS, decode_stop_pos); - decode_stop_pos_pre = decode_stop_pos; - } - - if (debug & VP9_DEBUG_DUMP_PIC_LIST) { - dump_pic_list(pbi); - debug &= ~VP9_DEBUG_DUMP_PIC_LIST; - } - if (debug & VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC) { - WRITE_VREG(HEVC_ASSIST_MBOX1_IRQ_REG, 0x1); - debug &= ~VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC; - } - /*if (debug & VP9_DEBUG_HW_RESET) { - }*/ - if (debug & VP9_DEBUG_ERROR_TRIG) { - WRITE_VREG(DECODE_STOP_POS, 1); - debug &= ~VP9_DEBUG_ERROR_TRIG; - } - - 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_type() >= MESON_CPU_MAJOR_ID_GXBB && - double_write_mode == 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 (pbi->get_frame_dur && pbi->show_frame_num > 60 && - pbi->frame_dur > 0 && pbi->saved_resolution != - frame_width * frame_height * - (96000 / pbi->frame_dur)) { - int fps = 96000 / pbi->frame_dur; - if (hevc_source_changed(VFORMAT_VP9, - frame_width, frame_height, fps) > 0) - pbi->saved_resolution = frame_width * - frame_height * fps; - } - - timer->expires = jiffies + PUT_INTERVAL; - add_timer(timer); -} - - -int vvp9_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) -{ - struct VP9Decoder_s *pbi = &gHevc; - vstatus->width = frame_width; - vstatus->height = frame_height; - if (pbi->frame_dur != 0) - vstatus->fps = 96000 / pbi->frame_dur; - else - vstatus->fps = -1; - vstatus->error_count = 0; - vstatus->status = pbi->stat | pbi->fatal_error; - return 0; -} - -#if 0 -static void VP9_DECODE_INIT(void) -{ - /* enable vp9 clocks */ - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); - /* *************************************************************** */ - /* Power ON HEVC */ - /* *************************************************************** */ - /* Powerup HEVC */ - WRITE_VREG(AO_RTI_GEN_PWR_SLEEP0, - READ_VREG(AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6))); - WRITE_VREG(DOS_MEM_PD_HEVC, 0x0); - WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2)); - WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2))); - /* remove isolations */ - WRITE_VREG(AO_RTI_GEN_PWR_ISO0, - READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10))); - -} -#endif - -static void vvp9_prot_init(struct VP9Decoder_s *pbi) -{ - unsigned int data32; - /* VP9_DECODE_INIT(); */ - vp9_config_work_space_hw(pbi); - init_pic_list_hw(pbi); - - vp9_init_decoder_hw(pbi); - -#ifdef VP9_LPF_LVL_UPDATE - vp9_loop_filter_init(); -#endif - -#if 1 - if (debug & VP9_DEBUG_BUFMGR) - pr_info("[test.c] Enable BitStream Fetch\n"); - data32 = READ_VREG(HEVC_STREAM_CONTROL); - data32 = data32 | - (1 << 0)/*stream_fetch_enable*/ - ; - WRITE_VREG(HEVC_STREAM_CONTROL, data32); -#if 0 - data32 = READ_VREG(HEVC_SHIFT_STARTCODE); - if (data32 != 0x00000100) { - pr_info("vp9 prot init error %d\n", __LINE__); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x00000300) { - pr_info("vp9 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("vp9 prot init error %d\n", __LINE__); - return; - } - data32 = READ_VREG(HEVC_SHIFT_EMULATECODE); - if (data32 != 0x9abcdef0) { - pr_info("vp9 prot init error %d\n", __LINE__); - return; - } -#endif - WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x000000001); - WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300); -#endif - - - - WRITE_VREG(HEVC_WAIT_FLAG, 1); - - /* WRITE_VREG(HEVC_MPSR, 1); */ - - /* clear mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_CLR_REG, 1); - - /* enable mailbox interrupt */ - WRITE_VREG(HEVC_ASSIST_MBOX1_MASK, 1); - - /* disable PSCALE for hardware sharing */ - WRITE_VREG(HEVC_PSCALE_CTRL, 0); - - if (debug & VP9_DEBUG_UCODE) - WRITE_VREG(DEBUG_REG1, 0x1); - else - WRITE_VREG(DEBUG_REG1, 0x0); - /*check vps/sps/pps/i-slice in ucode*/ - WRITE_VREG(NAL_SEARCH_CTL, 0x8); - - WRITE_VREG(DECODE_STOP_POS, decode_stop_pos); - -} - -static int vvp9_local_init(struct VP9Decoder_s *pbi) -{ - int i; - int ret; - int width, height; -#ifdef DEBUG_PTS - pbi->pts_missed = 0; - pbi->pts_hit = 0; -#endif - pbi->new_frame_displayed = 0; - pbi->last_put_idx = -1; - pbi->saved_resolution = 0; - pbi->get_frame_dur = false; - on_no_keyframe_skiped = 0; - width = pbi->vvp9_amstream_dec_info.width; - height = pbi->vvp9_amstream_dec_info.height; - pbi->frame_dur = - (pbi->vvp9_amstream_dec_info.rate == - 0) ? 3600 : pbi->vvp9_amstream_dec_info.rate; - if (width && height) - pbi->frame_ar = height * 0x100 / width; -/* -TODO:FOR VERSION -*/ - pr_info("vp9: ver (%d,%d) decinfo: %dx%d rate=%d\n", vp9_version, - 0, width, height, pbi->frame_dur); - - if (pbi->frame_dur == 0) - pbi->frame_dur = 96000 / 24; - - INIT_KFIFO(pbi->display_q); - INIT_KFIFO(pbi->newframe_q); - - - for (i = 0; i < VF_POOL_SIZE; i++) { - const struct vframe_s *vf = &pbi->vfpool[i]; - pbi->vfpool[i].index = -1; - kfifo_put(&pbi->newframe_q, vf); - } - - - ret = vp9_local_init(pbi); - - return ret; -} - -static s32 vvp9_init(struct VP9Decoder_s *pbi) -{ - int size = -1; - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return -ENOMEM; - - init_timer(&pbi->timer); - - pbi->stat |= STAT_TIMER_INIT; - if (vvp9_local_init(pbi) < 0) { - vfree(buf); - return -EBUSY; - } - -#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); - - pbi->stat |= STAT_TIMER_ARM; - - INIT_WORK(&pbi->work, vp9_work); - - vfree(buf); - return 0; - } -#endif - - amhevc_enable(); - - size = get_firmware_data(VIDEO_DEC_VP9_MMU, buf); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return -1; - } - - if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, buf) < 0) { - amhevc_disable(); - vfree(buf); - return -EBUSY; - } - - vfree(buf); - - pbi->stat |= STAT_MC_LOAD; - - /* enable AMRISC side protocol */ - vvp9_prot_init(pbi); - - if (vdec_request_threaded_irq(VDEC_IRQ_1, - vvp9_isr, - vvp9_isr_thread_fn, - IRQF_ONESHOT,/*run thread on this irq disabled*/ - "vvp9-irq", (void *)pbi)) { - pr_info("vvp9 irq register error.\n"); - amhevc_disable(); - return -ENOENT; - } - - pbi->stat |= STAT_ISR_REG; - - pbi->provider_name = PROVIDER_NAME; - 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); - - vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, - (void *)((unsigned long)pbi->frame_dur)); - - 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_TIMER_ARM; - - /* pbi->stat |= STAT_KTHREAD; */ - - amhevc_start(); - - pbi->stat |= STAT_VDEC_RUN; - - pbi->init_flag = 1; - pbi->process_busy = 0; - pr_info("%d, vvp9_init, RP=0x%x\n", - __LINE__, READ_VREG(HEVC_STREAM_RD_PTR)); - return 0; -} - -static int vvp9_stop(struct VP9Decoder_s *pbi) -{ - - pbi->init_flag = 0; - /* - if ((debug & VP9_DEBUG_NOWAIT_DECODE_DONE_WHEN_STOP) == 0) { - int wait_timeout_count = 0; - while ((READ_VREG(HEVC_DEC_STATUS_REG) == - VP9_10B_DECODE_SLICE && - wait_timeout_count < 10) || - pbi->process_busy){ - wait_timeout_count++; - msleep(20); - } - } - */ - if (pbi->stat & STAT_VDEC_RUN) { - amhevc_stop(); - pbi->stat &= ~STAT_VDEC_RUN; - } - - if (pbi->stat & STAT_ISR_REG) { - WRITE_VREG(HEVC_ASSIST_MBOX1_MASK, 0); - vdec_free_irq(VDEC_IRQ_1, (void *)pbi); - pbi->stat &= ~STAT_ISR_REG; - } - - if (pbi->stat & STAT_TIMER_ARM) { - del_timer_sync(&pbi->timer); - pbi->stat &= ~STAT_TIMER_ARM; - } - - if (pbi->stat & STAT_VF_HOOK) { - vf_notify_receiver(pbi->provider_name, - VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); - - vf_unreg_provider(&vvp9_vf_prov); - pbi->stat &= ~STAT_VF_HOOK; - } - vp9_local_uninit(pbi); - -#ifdef MULTI_INSTANCE_SUPPORT - if (pbi->m_ins_flag) { - cancel_work_sync(&pbi->work); - } else { - amhevc_disable(); - } -#else - amhevc_disable(); -#endif - uninit_mmu_buffers(pbi); - - return 0; -} - -static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi) -{ -#ifdef VP9_10B_MMU - pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, - 0, FRAME_BUFFERS, - 48 * SZ_1M - ); - if (!pbi->mmu_box) { - pr_err("vp9 alloc mmu box failed!!\n"); - return -1; - } -#endif - pbi->bmmu_box = decoder_bmmu_box_alloc_box( - DRIVER_NAME, - pbi->index, - MAX_BMMU_BUFFER_NUM, - 4 + PAGE_SHIFT, - CODEC_MM_FLAGS_CMA_CLEAR | - CODEC_MM_FLAGS_FOR_VDECODER); - if (!pbi->bmmu_box) { - pr_err("vp9 alloc bmmu box failed!!\n"); - return -1; - } - return 0; -} -static int amvdec_vp9_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - struct BUF_s BUF[MAX_BUF_NUM]; - struct VP9Decoder_s *pbi = &gHevc; - pr_info("%s\n", __func__); - mutex_lock(&vvp9_mutex); - - memcpy(&BUF[0], &pbi->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); - memset(pbi, 0, sizeof(VP9Decoder)); - memcpy(&pbi->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); - - pbi->init_flag = 0; - pbi->fatal_error = 0; - pbi->show_frame_num = 0; - if (pdata == NULL) { - pr_info("\namvdec_vp9 memory resource undefined.\n"); - mutex_unlock(&vvp9_mutex); - return -EFAULT; - } - pbi->m_ins_flag = 0; -#ifdef MULTI_INSTANCE_SUPPORT - pbi->buf_start = pdata->mem_start; - pbi->buf_size = pdata->mem_end - pdata->mem_start + 1; -#else - pbi->mc_buf_spec.buf_end = pdata->mem_end + 1; - for (i = 0; i < WORK_BUF_SPEC_NUM; i++) - amvvp9_workbuff_spec[i].start_adr = pdata->mem_start; -#endif - if (amvdec_vp9_mmu_init(pbi) < 0) { - pr_err("vp9 alloc bmmu box failed!!\n"); - return -1; - } - if (debug) { - pr_info("===VP9 decoder mem resource 0x%lx -- 0x%lx\n", - pdata->mem_start, pdata->mem_end + 1); - } - - 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; - } -#ifdef MULTI_INSTANCE_SUPPORT - pbi->cma_dev = pdata->cma_dev; -#else - cma_dev = pdata->cma_dev; -#endif - pdata->dec_status = vvp9_dec_status; - - if (vvp9_init(pbi) < 0) { - pr_info("\namvdec_vp9 init failed.\n"); - vp9_local_uninit(pbi); - mutex_unlock(&vvp9_mutex); - return -ENODEV; - } - /*set the max clk for smooth playing...*/ - hevc_source_changed(VFORMAT_VP9, - 4096, 2048, 60); - mutex_unlock(&vvp9_mutex); - - return 0; -} - -static int amvdec_vp9_remove(struct platform_device *pdev) -{ - struct VP9Decoder_s *pbi = &gHevc; - if (debug) - pr_info("amvdec_vp9_remove\n"); - - mutex_lock(&vvp9_mutex); - - vvp9_stop(pbi); - - - hevc_source_changed(VFORMAT_VP9, 0, 0, 0); - - -#ifdef DEBUG_PTS - pr_info("pts missed %ld, pts hit %ld, duration %d\n", - pbi->pts_missed, pbi->pts_hit, pbi->frame_dur); -#endif - - mutex_unlock(&vvp9_mutex); - - return 0; -} - -/****************************************/ - -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, - } -}; - -static struct codec_profile_t amvdec_vp9_profile = { - .name = "vp9", - .profile = "" -}; - -#ifdef MULTI_INSTANCE_SUPPORT -static unsigned int start_decode_buf_level = 0x8000; -#ifdef VP9_10B_MMU -static u32 work_buf_size = 24 * 1024 * 1024; -#else -static u32 work_buf_size = 32 * 1024 * 1024; -#endif - -static unsigned char decoder_id_used[MAX_DECODE_INSTANCE_NUM]; -static unsigned int get_free_decoder_id(struct vdec_s *vdec) -{ - /*stream base decoder always has id of 0*/ - int i; - if (vdec_frame_based(vdec)) { - for (i = 1; i < decoder_id_used[i]; i++) { - if (!decoder_id_used[i]) { - decoder_id_used[i] = 1; - return i; - } - } - } - return 0; -} - -static unsigned char get_data_check_sum - (struct VP9Decoder_s *pbi, int size) -{ - int jj; - int sum = 0; - u8 *data = ((u8 *)pbi->chunk->block->start_virt) + - pbi->chunk->offset; - for (jj = 0; jj < size; jj++) - sum += data[jj]; - return sum; -} - -static void dump_data(struct VP9Decoder_s *pbi, int size) -{ - int jj; - u8 *data = ((u8 *)pbi->chunk->block->start_virt) + - pbi->chunk->offset; - for (jj = 0; jj < size; jj++) { - if ((jj & 0xf) == 0) - vp9_print(pbi, - 0, - "%06x:", jj); - vp9_print_cont(pbi, - 0, - "%02x ", data[jj]); - if (((jj + 1) & 0xf) == 0) - vp9_print(pbi, - 0, - "\n"); - } - vp9_print(pbi, - 0, - "\n"); -} - -static void vp9_work(struct work_struct *work) -{ - struct VP9Decoder_s *pbi = container_of(work, - struct VP9Decoder_s, work); - struct VP9_Common_s *const cm = &pbi->common; - struct vdec_s *vdec = hw_to_vdec(pbi); - /* finished decoding one frame or error, - * notify vdec core to switch context - */ - - if ((pbi->dec_result == DEC_RESULT_GET_DATA) || - (pbi->dec_result == DEC_RESULT_GET_DATA_RETRY)) { - if (pbi->dec_result == DEC_RESULT_GET_DATA) { - vp9_print(pbi, 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, pbi->chunk); - vdec_clean_input(vdec); - } - - if (!is_buffer_empty(cm)) { - int r; - r = vdec_prepare_input(vdec, &pbi->chunk); - if (r < 0) { - pbi->dec_result = DEC_RESULT_GET_DATA_RETRY; - - vp9_print(pbi, - PRINT_FLAG_VDEC_DETAIL, - "amvdec_vh265: Insufficient data\n"); - - schedule_work(&pbi->work); - return; - } - pbi->dec_result = DEC_RESULT_NONE; - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s: chunk size 0x%x sum 0x%x\n", - __func__, r, - (debug & PRINT_FLAG_VDEC_STATUS) ? - get_data_check_sum(pbi, r) : 0 - ); - - if (debug & PRINT_FLAG_VDEC_DATA) - dump_data(pbi, pbi->chunk->size); - WRITE_VREG(HEVC_DECODE_SIZE, r); - - vdec_enable_input(vdec); - - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - } else{ - pbi->dec_result = DEC_RESULT_GET_DATA_RETRY; - - vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, - "amvdec_vh265: Insufficient data\n"); - - schedule_work(&pbi->work); - } - return; - } else if (pbi->dec_result == DEC_RESULT_DONE) { - /* if (!pbi->ctx_valid) - pbi->ctx_valid = 1; */ - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s dec_result %d %x %x %x\n", - __func__, - pbi->dec_result, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); - vdec_vframe_dirty(hw_to_vdec(pbi), pbi->chunk); - } else { - vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, - "%s dec_result %d %x %x %x\n", - __func__, - pbi->dec_result, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); - } - - /* mark itself has all HW resource released and input released */ - vdec_set_status(hw_to_vdec(pbi), VDEC_STATUS_CONNECTED); - - if (pbi->vdec_cb) - pbi->vdec_cb(hw_to_vdec(pbi), pbi->vdec_cb_arg); -} - -static int vp9_hw_ctx_restore(struct VP9Decoder_s *pbi) -{ - /* new to do ... */ - vvp9_prot_init(pbi); - return 0; -} - -static bool run_ready(struct vdec_s *vdec) -{ - struct VP9Decoder_s *pbi = - (struct VP9Decoder_s *)vdec->private; - struct VP9_Common_s *const cm = &pbi->common; - - vp9_print(pbi, - PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); - - if ((!vdec_frame_based(vdec)) && (start_decode_buf_level > 0)) { - u32 rp, wp; - u32 level; - - rp = READ_MPEG_REG(PARSER_VIDEO_RP); - wp = READ_MPEG_REG(PARSER_VIDEO_WP); - - if (wp < rp) - level = vdec->input.size + wp - rp; - else - level = wp - rp; - - if (level < start_decode_buf_level) { - vp9_print(pbi, 0, - "level %d not run_ready\n", level); - return false; - } - } else if (vdec_frame_based(vdec)) { - if (!vdec_input_next_input_chunk(&vdec->input)) - return false; - } - - return !is_buffer_empty(cm); -} - -static void reset_dec_hw(struct vdec_s *vdec) -{ - if (input_frame_based(vdec)) - WRITE_VREG(HEVC_STREAM_CONTROL, 0); - - /* - * 2: assist - * 3: parser - * 4: parser_state - * 8: dblk - * 11:mcpu - * 12:ccpu - * 13:ddr - * 14:iqit - * 15:ipp - * 17:qdct - * 18:mpred - * 19:sao - * 24:hevc_afifo - */ - 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)); - WRITE_VREG(DOS_SW_RESET3, 0); -} - -static void run(struct vdec_s *vdec, - void (*callback)(struct vdec_s *, void *), void *arg) -{ - struct VP9Decoder_s *pbi = - (struct VP9Decoder_s *)vdec->private; - int r, size = -1; - - char *buf = vmalloc(0x1000 * 16); - if (IS_ERR_OR_NULL(buf)) - return; - - pbi->vdec_cb_arg = arg; - pbi->vdec_cb = callback; - /* pbi->chunk = vdec_prepare_input(vdec); */ - reset_dec_hw(vdec); - - r = vdec_prepare_input(vdec, &pbi->chunk); - if (r < 0) { - pbi->dec_result = DEC_RESULT_AGAIN; - - vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, - "ammvdec_vh265: Insufficient data\n"); - - schedule_work(&pbi->work); - return; - } - pbi->dec_result = DEC_RESULT_NONE; - - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s: size 0x%x sum 0x%x (%x %x %x)\n", - __func__, r, - (vdec_frame_based(vdec) && - (debug & PRINT_FLAG_VDEC_STATUS)) ? - get_data_check_sum(pbi, r) : 0, - READ_VREG(HEVC_STREAM_LEVEL), - READ_VREG(HEVC_STREAM_WR_PTR), - READ_VREG(HEVC_STREAM_RD_PTR)); - - size = get_firmware_data(VIDEO_DEC_VP9_MMU, buf); - if (size < 0) { - pr_err("get firmware fail.\n"); - vfree(buf); - return; - } - - if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, buf) < 0) { - amhevc_disable(); - vfree(buf); - return; - } - - vfree(buf); - - if (vp9_hw_ctx_restore(pbi) < 0) { - schedule_work(&pbi->work); - return; - } - - vdec_enable_input(vdec); - - WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE); - - if (vdec_frame_based(vdec)) { - if (debug & PRINT_FLAG_VDEC_DATA) - dump_data(pbi, pbi->chunk->size); - - WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0); - } - WRITE_VREG(HEVC_DECODE_SIZE, r); - WRITE_VREG(HEVC_DECODE_COUNT, pbi->slice_idx); - pbi->init_flag = 1; - - vp9_print(pbi, PRINT_FLAG_VDEC_STATUS, - "%s: start hevc (%x %x %x)\n", - __func__, - READ_VREG(HEVC_DEC_STATUS_REG), - READ_VREG(HEVC_MPC_E), - READ_VREG(HEVC_MPSR)); - - amhevc_start(); - -} - -static void reset(struct vdec_s *vdec) -{ - - struct VP9Decoder_s *pbi = - (struct VP9Decoder_s *)vdec->private; - - vp9_print(pbi, - PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__); - -} - -static irqreturn_t vp9_irq_cb(struct vdec_s *vdec) -{ - struct VP9Decoder_s *pbi = - (struct VP9Decoder_s *)vdec->private; - return vvp9_isr(0, pbi); -} - -static irqreturn_t vp9_threaded_irq_cb(struct vdec_s *vdec) -{ - struct VP9Decoder_s *pbi = - (struct VP9Decoder_s *)vdec->private; - return vvp9_isr_thread_fn(0, pbi); -} - - -static int ammvdec_vp9_probe(struct platform_device *pdev) -{ - struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; - - struct BUF_s BUF[MAX_BUF_NUM]; - struct VP9Decoder_s *pbi = NULL; - pr_info("%s\n", __func__); - if (pdata == NULL) { - pr_info("\nammvdec_vp9 memory resource undefined.\n"); - return -EFAULT; - } - pbi = (struct VP9Decoder_s *)devm_kzalloc(&pdev->dev, - sizeof(struct VP9Decoder_s), GFP_KERNEL); - if (pbi == NULL) { - pr_info("\nammvdec_vp9 device data allocation failed\n"); - return -ENOMEM; - } - pdata->private = pbi; - pdata->dec_status = vvp9_dec_status; - /* pdata->set_trickmode = set_trickmode; */ - pdata->run_ready = run_ready; - pdata->run = run; - pdata->reset = reset; - pdata->irq_handler = vp9_irq_cb; - pdata->threaded_irq_handler = vp9_threaded_irq_cb; - - pdata->id = pdev->id; - - - memcpy(&BUF[0], &pbi->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); - memset(pbi, 0, sizeof(VP9Decoder)); - memcpy(&pbi->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM); - - pbi->index = get_free_decoder_id(pdata); - - if (pdata->use_vfm_path) - snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, - VFM_DEC_PROVIDER_NAME); - 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, - &vvp9_vf_provider, pbi); - - pbi->provider_name = pdata->vf_provider_name; - platform_set_drvdata(pdev, pdata); - - pbi->platform_dev = pdev; -#if 0 - pbi->buf_start = pdata->mem_start; - pbi->buf_size = pdata->mem_end - pdata->mem_start + 1; -#else - if (amvdec_vp9_mmu_init(pbi) < 0) { - pr_err("vp9 alloc bmmu box failed!!\n"); - devm_kfree(&pdev->dev, (void *)pbi); - return -1; - } - - pbi->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE; - if (!decoder_bmmu_box_alloc_idx_wait( - pbi->bmmu_box, - WORK_SPACE_BUF_ID, - pbi->cma_alloc_count * PAGE_SIZE, - -1, - -1, - BMMU_ALLOC_FLAGS_WAITCLEAR - )) { - pbi->cma_alloc_addr = decoder_bmmu_box_get_phy_addr( - pbi->bmmu_box, - WORK_SPACE_BUF_ID); - } else { - vp9_print(pbi, 0, - "codec_mm alloc failed, request buf size 0x%lx\n", - pbi->cma_alloc_count * PAGE_SIZE); - pbi->cma_alloc_count = 0; - uninit_mmu_buffers(pbi); - devm_kfree(&pdev->dev, (void *)pbi); - return -ENOMEM; - } - pbi->buf_start = pbi->cma_alloc_addr; - pbi->buf_size = work_buf_size; -#endif - pbi->m_ins_flag = 1; - - pbi->init_flag = 0; - pbi->fatal_error = 0; - pbi->show_frame_num = 0; - if (pdata == NULL) { - pr_info("\namvdec_vp9 memory resource undefined.\n"); - uninit_mmu_buffers(pbi); - devm_kfree(&pdev->dev, (void *)pbi); - return -EFAULT; - } - - if (debug) { - pr_info("===VP9 decoder mem resource 0x%lx -- 0x%lx\n", - pbi->buf_start, - pbi->buf_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->cma_dev = pdata->cma_dev; - - if (vvp9_init(pbi) < 0) { - pr_info("\namvdec_vp9 init failed.\n"); - vp9_local_uninit(pbi); - uninit_mmu_buffers(pbi); - devm_kfree(&pdev->dev, (void *)pbi); - return -ENODEV; - } - return 0; -} - -static int ammvdec_vp9_remove(struct platform_device *pdev) -{ - struct VP9Decoder_s *pbi = (struct VP9Decoder_s *) - (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); - if (debug) - pr_info("amvdec_vp9_remove\n"); - - vvp9_stop(pbi); - - vdec_set_status(hw_to_vdec(pbi), VDEC_STATUS_DISCONNECTED); - - -#ifdef DEBUG_PTS - pr_info("pts missed %ld, pts hit %ld, duration %d\n", - pbi->pts_missed, pbi->pts_hit, pbi->frame_dur); -#endif - devm_kfree(&pdev->dev, (void *)pbi); - return 0; -} - -static struct platform_driver ammvdec_vp9_driver = { - .probe = ammvdec_vp9_probe, - .remove = ammvdec_vp9_remove, -#ifdef CONFIG_PM - .suspend = amvdec_suspend, - .resume = amvdec_resume, -#endif - .driver = { - .name = MULTI_DRIVER_NAME, - } -}; -#endif - -static int __init amvdec_vp9_driver_init_module(void) -{ - pr_debug("amvdec_vp9 module init\n"); - error_handle_policy = 0; - -#ifdef ERROR_HANDLE_DEBUG - dbg_nal_skip_flag = 0; - dbg_nal_skip_count = 0; -#endif - decode_stop_pos = 0; - decode_stop_pos_pre = 0; - decode_pic_begin = 0; - slice_parse_begin = 0; - step = 0; - buf_alloc_size = 0; -#ifdef MULTI_INSTANCE_SUPPORT - if (platform_driver_register(&ammvdec_vp9_driver)) - pr_err("failed to register ammvdec_vp9 driver\n"); - -#endif - if (platform_driver_register(&amvdec_vp9_driver)) { - pr_err("failed to register amvdec_vp9 driver\n"); - return -ENODEV; - } - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - amvdec_vp9_profile.profile = - "4k, 10bit, dwrite, compressed"; - } else { - amvdec_vp9_profile.name = "vp9_unsupport"; - } - - vcodec_profile_register(&amvdec_vp9_profile); - - return 0; -} - -static void __exit amvdec_vp9_driver_remove_module(void) -{ - pr_debug("amvdec_vp9 module remove.\n"); -#ifdef MULTI_INSTANCE_SUPPORT - platform_driver_unregister(&ammvdec_vp9_driver); -#endif - platform_driver_unregister(&amvdec_vp9_driver); -} - -/****************************************/ -/* -module_param(stat, uint, 0664); -MODULE_PARM_DESC(stat, "\n amvdec_vp9 stat\n"); -*/ -module_param(use_cma, uint, 0664); -MODULE_PARM_DESC(use_cma, "\n amvdec_vp9 use_cma\n"); - -module_param(bit_depth_luma, uint, 0664); -MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_vp9 bit_depth_luma\n"); - -module_param(bit_depth_chroma, uint, 0664); -MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_vp9 bit_depth_chroma\n"); - -module_param(frame_width, uint, 0664); -MODULE_PARM_DESC(frame_width, "\n amvdec_vp9 frame_width\n"); - -module_param(frame_height, uint, 0664); -MODULE_PARM_DESC(frame_height, "\n amvdec_vp9 frame_height\n"); - -module_param(debug, uint, 0664); -MODULE_PARM_DESC(debug, "\n amvdec_vp9 debug\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_vp9 step\n"); - -module_param(decode_stop_pos, uint, 0664); -MODULE_PARM_DESC(decode_stop_pos, "\n amvdec_vp9 decode_stop_pos\n"); - -module_param(decode_pic_begin, uint, 0664); -MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_vp9 decode_pic_begin\n"); - -module_param(slice_parse_begin, uint, 0664); -MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_vp9 slice_parse_begin\n"); - -module_param(i_only_flag, uint, 0664); -MODULE_PARM_DESC(i_only_flag, "\n amvdec_vp9 i_only_flag\n"); - -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"); - -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"); -/**/ - -module_param(mem_map_mode, uint, 0664); -MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n"); - -#ifdef SUPPORT_10BIT -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"); -#endif - -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"); - -#ifdef MULTI_INSTANCE_SUPPORT -module_param(start_decode_buf_level, uint, 0664); -MODULE_PARM_DESC(start_decode_buf_level, - "\n ammvdec_h264 start_decode_buf_level\n"); -#endif - -module_init(amvdec_vp9_driver_init_module); -module_exit(amvdec_vp9_driver_remove_module); - -MODULE_DESCRIPTION("AMLOGIC vp9 Video Decoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>"); diff --git a/drivers/frame_provider/decoder/vp9/vvp9.h b/drivers/frame_provider/decoder/vp9/vvp9.h deleted file mode 100644 index 4cf3254..0000000 --- a/drivers/frame_provider/decoder/vp9/vvp9.h +++ b/dev/null @@ -1,25 +0,0 @@ -/* - * drivers/amlogic/amports/vvp9.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 VVP9_H -#define VVP9_H -#ifndef CONFIG_MULTI_DEC -#define VP9_10B_MMU -#endif -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_sink/Makefile b/drivers/frame_sink/Makefile deleted file mode 100644 index 2b9754a..0000000 --- a/drivers/frame_sink/Makefile +++ b/dev/null @@ -1 +0,0 @@ -obj-y += encoder/ diff --git a/drivers/frame_sink/encoder/Makefile b/drivers/frame_sink/encoder/Makefile deleted file mode 100644 index 9afecec..0000000 --- a/drivers/frame_sink/encoder/Makefile +++ b/dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_AMLOGIC_MEDIA_VENC_H264) += h264/ -obj-$(CONFIG_AMLOGIC_MEDIA_VENC_H265) += h265/ diff --git a/drivers/frame_sink/encoder/h264/Makefile b/drivers/frame_sink/encoder/h264/Makefile deleted file mode 100644 index c12d7c3..0000000 --- a/drivers/frame_sink/encoder/h264/Makefile +++ b/dev/null @@ -1 +0,0 @@ -obj-m += encoder.o diff --git a/drivers/frame_sink/encoder/h264/encoder.c b/drivers/frame_sink/encoder/h264/encoder.c deleted file mode 100644 index 9badd53..0000000 --- a/drivers/frame_sink/encoder/h264/encoder.c +++ b/dev/null @@ -1,4237 +0,0 @@ -/* - * drivers/amlogic/amports/encoder.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/sched.h> -#include <linux/slab.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/ctype.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/canvas/canvas_mgr.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../../frame_provider/decoder/utils/vdec.h" -#include <linux/delay.h> -#include <linux/poll.h> -#include <linux/of.h> -#include <linux/of_fdt.h> -#include <linux/dma-contiguous.h> -#include <linux/kthread.h> -#include <linux/sched/rt.h> -#include <linux/amlogic/media/utils/amports_config.h> -#include "encoder.h" -#include "../../../frame_provider/decoder/utils/amvdec.h" -#include <linux/amlogic/media/utils/amlog.h> -#include "../../../stream_input/amports/amports_priv.h" -#include <linux/of_reserved_mem.h> -#ifdef CONFIG_AM_JPEG_ENCODER -#include "jpegenc.h" -#endif - -#define ENCODE_NAME "encoder" -#define AMVENC_CANVAS_INDEX 0xE4 -#define AMVENC_CANVAS_MAX_INDEX 0xEF - -#define MIN_SIZE amvenc_buffspec[0].min_buffsize -#define DUMP_INFO_BYTES_PER_MB 80 - -#define ADJUSTED_QP_FLAG 64 - -static s32 avc_device_major; -static struct device *amvenc_avc_dev; -#define DRIVER_NAME "amvenc_avc" -#define CLASS_NAME "amvenc_avc" -#define DEVICE_NAME "amvenc_avc" - -static struct encode_manager_s encode_manager; - -#define MULTI_SLICE_MC -#define H264_ENC_CBR -/* #define MORE_MODULE_PARAM */ - -#define ENC_CANVAS_OFFSET AMVENC_CANVAS_INDEX - -#define UCODE_MODE_FULL 0 - -/* #define ENABLE_IGNORE_FUNCTION */ - -static u32 ie_me_mb_type; -static u32 ie_me_mode; -static u32 ie_pippeline_block = 3; -static u32 ie_cur_ref_sel; -/* static u32 avc_endian = 6; */ -static u32 clock_level = 5; - -static u32 encode_print_level = LOG_DEBUG; -static u32 no_timeout; -static int nr_mode = -1; -static u32 qp_table_debug; - -static u32 me_mv_merge_ctl = - (0x1 << 31) | /* [31] me_merge_mv_en_16 */ - (0x1 << 30) | /* [30] me_merge_small_mv_en_16 */ - (0x1 << 29) | /* [29] me_merge_flex_en_16 */ - (0x1 << 28) | /* [28] me_merge_sad_en_16 */ - (0x1 << 27) | /* [27] me_merge_mv_en_8 */ - (0x1 << 26) | /* [26] me_merge_small_mv_en_8 */ - (0x1 << 25) | /* [25] me_merge_flex_en_8 */ - (0x1 << 24) | /* [24] me_merge_sad_en_8 */ - /* [23:18] me_merge_mv_diff_16 - MV diff <= n pixel can be merged */ - (0x12 << 18) | - /* [17:12] me_merge_mv_diff_8 - MV diff <= n pixel can be merged */ - (0x2b << 12) | - /* [11:0] me_merge_min_sad - SAD >= 0x180 can be merged with other MV */ - (0x80 << 0); - /* ( 0x4 << 18) | - // [23:18] me_merge_mv_diff_16 - MV diff <= n pixel can be merged */ - /* ( 0x3f << 12) | - // [17:12] me_merge_mv_diff_8 - MV diff <= n pixel can be merged */ - /* ( 0xc0 << 0); - // [11:0] me_merge_min_sad - SAD >= 0x180 can be merged with other MV */ - -static u32 me_mv_weight_01 = (0x40 << 24) | (0x30 << 16) | (0x20 << 8) | 0x30; -static u32 me_mv_weight_23 = (0x40 << 8) | 0x30; -static u32 me_sad_range_inc = 0x03030303; -static u32 me_step0_close_mv = 0x003ffc21; -static u32 me_f_skip_sad; -static u32 me_f_skip_weight; -static u32 me_sad_enough_01;/* 0x00018010; */ -static u32 me_sad_enough_23;/* 0x00000020; */ - -/* [31:0] NUM_ROWS_PER_SLICE_P */ -/* [15:0] NUM_ROWS_PER_SLICE_I */ -static u32 fixed_slice_cfg; - -/* y tnr */ -static unsigned int y_tnr_mc_en = 1; -static unsigned int y_tnr_txt_mode; -static unsigned int y_tnr_mot_sad_margin = 1; -static unsigned int y_tnr_mot_cortxt_rate = 1; -static unsigned int y_tnr_mot_distxt_ofst = 5; -static unsigned int y_tnr_mot_distxt_rate = 4; -static unsigned int y_tnr_mot_dismot_ofst = 4; -static unsigned int y_tnr_mot_frcsad_lock = 8; -static unsigned int y_tnr_mot2alp_frc_gain = 10; -static unsigned int y_tnr_mot2alp_nrm_gain = 216; -static unsigned int y_tnr_mot2alp_dis_gain = 128; -static unsigned int y_tnr_mot2alp_dis_ofst = 32; -static unsigned int y_tnr_alpha_min = 32; -static unsigned int y_tnr_alpha_max = 63; -static unsigned int y_tnr_deghost_os; -/* c tnr */ -static unsigned int c_tnr_mc_en = 1; -static unsigned int c_tnr_txt_mode; -static unsigned int c_tnr_mot_sad_margin = 1; -static unsigned int c_tnr_mot_cortxt_rate = 1; -static unsigned int c_tnr_mot_distxt_ofst = 5; -static unsigned int c_tnr_mot_distxt_rate = 4; -static unsigned int c_tnr_mot_dismot_ofst = 4; -static unsigned int c_tnr_mot_frcsad_lock = 8; -static unsigned int c_tnr_mot2alp_frc_gain = 10; -static unsigned int c_tnr_mot2alp_nrm_gain = 216; -static unsigned int c_tnr_mot2alp_dis_gain = 128; -static unsigned int c_tnr_mot2alp_dis_ofst = 32; -static unsigned int c_tnr_alpha_min = 32; -static unsigned int c_tnr_alpha_max = 63; -static unsigned int c_tnr_deghost_os; -/* y snr */ -static unsigned int y_snr_err_norm = 1; -static unsigned int y_snr_gau_bld_core = 1; -static int y_snr_gau_bld_ofst = -1; -static unsigned int y_snr_gau_bld_rate = 48; -static unsigned int y_snr_gau_alp0_min; -static unsigned int y_snr_gau_alp0_max = 63; -static unsigned int y_bld_beta2alp_rate = 16; -static unsigned int y_bld_beta_min; -static unsigned int y_bld_beta_max = 63; -/* c snr */ -static unsigned int c_snr_err_norm = 1; -static unsigned int c_snr_gau_bld_core = 1; -static int c_snr_gau_bld_ofst = -1; -static unsigned int c_snr_gau_bld_rate = 48; -static unsigned int c_snr_gau_alp0_min; -static unsigned int c_snr_gau_alp0_max = 63; -static unsigned int c_bld_beta2alp_rate = 16; -static unsigned int c_bld_beta_min; -static unsigned int c_bld_beta_max = 63; - -static DEFINE_SPINLOCK(lock); - -#define ADV_MV_LARGE_16x8 1 -#define ADV_MV_LARGE_8x16 1 -#define ADV_MV_LARGE_16x16 1 - -/* me weight offset should not very small, it used by v1 me module. */ -/* the min real sad for me is 16 by hardware. */ -#define ME_WEIGHT_OFFSET 0x520 -#define I4MB_WEIGHT_OFFSET 0x655 -#define I16MB_WEIGHT_OFFSET 0x560 - -#define ADV_MV_16x16_WEIGHT 0x080 -#define ADV_MV_16_8_WEIGHT 0x0e0 -#define ADV_MV_8x8_WEIGHT 0x240 -#define ADV_MV_4x4x4_WEIGHT 0x3000 - -#define IE_SAD_SHIFT_I16 0x001 -#define IE_SAD_SHIFT_I4 0x001 -#define ME_SAD_SHIFT_INTER 0x001 - -#define STEP_2_SKIP_SAD 0 -#define STEP_1_SKIP_SAD 0 -#define STEP_0_SKIP_SAD 0 -#define STEP_2_SKIP_WEIGHT 0 -#define STEP_1_SKIP_WEIGHT 0 -#define STEP_0_SKIP_WEIGHT 0 - -#define ME_SAD_RANGE_0 0x1 /* 0x0 */ -#define ME_SAD_RANGE_1 0x0 -#define ME_SAD_RANGE_2 0x0 -#define ME_SAD_RANGE_3 0x0 - -/* use 0 for v3, 0x18 for v2 */ -#define ME_MV_PRE_WEIGHT_0 0x18 -/* use 0 for v3, 0x18 for v2 */ -#define ME_MV_PRE_WEIGHT_1 0x18 -#define ME_MV_PRE_WEIGHT_2 0x0 -#define ME_MV_PRE_WEIGHT_3 0x0 - -/* use 0 for v3, 0x18 for v2 */ -#define ME_MV_STEP_WEIGHT_0 0x18 -/* use 0 for v3, 0x18 for v2 */ -#define ME_MV_STEP_WEIGHT_1 0x18 -#define ME_MV_STEP_WEIGHT_2 0x0 -#define ME_MV_STEP_WEIGHT_3 0x0 - -#define ME_SAD_ENOUGH_0_DATA 0x00 -#define ME_SAD_ENOUGH_1_DATA 0x04 -#define ME_SAD_ENOUGH_2_DATA 0x11 -#define ADV_MV_8x8_ENOUGH_DATA 0x20 - -/* V4_COLOR_BLOCK_FIX */ -#define V3_FORCE_SKIP_SAD_0 0x10 -/* 4 Blocks */ -#define V3_FORCE_SKIP_SAD_1 0x60 -/* 16 Blocks + V3_SKIP_WEIGHT_2 */ -#define V3_FORCE_SKIP_SAD_2 0x250 -/* almost disable it -- use t_lac_coeff_2 output to F_ZERO is better */ -#define V3_ME_F_ZERO_SAD (ME_WEIGHT_OFFSET + 0x10) - -#define V3_IE_F_ZERO_SAD_I16 (I16MB_WEIGHT_OFFSET + 0x10) -#define V3_IE_F_ZERO_SAD_I4 (I4MB_WEIGHT_OFFSET + 0x20) - -#define V3_SKIP_WEIGHT_0 0x10 -/* 4 Blocks 8 seperate search sad can be very low */ -#define V3_SKIP_WEIGHT_1 0x8 /* (4 * ME_MV_STEP_WEIGHT_1 + 0x100) */ -#define V3_SKIP_WEIGHT_2 0x3 - -#define V3_LEVEL_1_F_SKIP_MAX_SAD 0x0 -#define V3_LEVEL_1_SKIP_MAX_SAD 0x6 - -#define I4_ipred_weight_most 0x18 -#define I4_ipred_weight_else 0x28 - -#define C_ipred_weight_V 0x04 -#define C_ipred_weight_H 0x08 -#define C_ipred_weight_DC 0x0c - -#define I16_ipred_weight_V 0x04 -#define I16_ipred_weight_H 0x08 -#define I16_ipred_weight_DC 0x0c - -/* 0x00 same as disable */ -#define v3_left_small_max_ie_sad 0x00 -#define v3_left_small_max_me_sad 0x40 - -#define v5_use_small_diff_cnt 0 -#define v5_simple_mb_inter_all_en 1 -#define v5_simple_mb_inter_8x8_en 1 -#define v5_simple_mb_inter_16_8_en 1 -#define v5_simple_mb_inter_16x16_en 1 -#define v5_simple_mb_intra_en 1 -#define v5_simple_mb_C_en 0 -#define v5_simple_mb_Y_en 1 -#define v5_small_diff_Y 0x10 -#define v5_small_diff_C 0x18 -/* shift 8-bits, 2, 1, 0, -1, -2, -3, -4 */ -#define v5_simple_dq_setting 0x43210fed -#define v5_simple_me_weight_setting 0 - -#ifdef H264_ENC_CBR -#define CBR_TABLE_SIZE 0x800 -#define CBR_SHORT_SHIFT 12 /* same as disable */ -#define CBR_LONG_MB_NUM 2 -#define START_TABLE_ID 8 -#define CBR_LONG_THRESH 4 -#endif - -static u32 v3_mv_sad[64] = { - /* For step0 */ - 0x00000004, - 0x00010008, - 0x00020010, - 0x00030018, - 0x00040020, - 0x00050028, - 0x00060038, - 0x00070048, - 0x00080058, - 0x00090068, - 0x000a0080, - 0x000b0098, - 0x000c00b0, - 0x000d00c8, - 0x000e00e8, - 0x000f0110, - /* For step1 */ - 0x00100002, - 0x00110004, - 0x00120008, - 0x0013000c, - 0x00140010, - 0x00150014, - 0x0016001c, - 0x00170024, - 0x0018002c, - 0x00190034, - 0x001a0044, - 0x001b0054, - 0x001c0064, - 0x001d0074, - 0x001e0094, - 0x001f00b4, - /* For step2 */ - 0x00200006, - 0x0021000c, - 0x0022000c, - 0x00230018, - 0x00240018, - 0x00250018, - 0x00260018, - 0x00270030, - 0x00280030, - 0x00290030, - 0x002a0030, - 0x002b0030, - 0x002c0030, - 0x002d0030, - 0x002e0030, - 0x002f0050, - /* For step2 4x4-8x8 */ - 0x00300001, - 0x00310002, - 0x00320002, - 0x00330004, - 0x00340004, - 0x00350004, - 0x00360004, - 0x00370006, - 0x00380006, - 0x00390006, - 0x003a0006, - 0x003b0006, - 0x003c0006, - 0x003d0006, - 0x003e0006, - 0x003f0006 -}; - -static struct BuffInfo_s amvenc_buffspec[] = { - { - .lev_id = 0, - .max_width = 1920, - .max_height = 1088, - .min_buffsize = 0x1400000, - .dct = { - .buf_start = 0, - .buf_size = 0x800000, /* 1920x1088x4 */ - }, - .dec0_y = { - .buf_start = 0x800000, - .buf_size = 0x300000, - }, - .dec1_y = { - .buf_start = 0xb00000, - .buf_size = 0x300000, - }, - .assit = { - .buf_start = 0xe10000, - .buf_size = 0xc0000, - }, - .bitstream = { - .buf_start = 0xf00000, - .buf_size = 0x100000, - }, - .scale_buff = { - .buf_start = 0x1000000, - .buf_size = 0x300000, - }, - .dump_info = { - .buf_start = 0x1300000, - .buf_size = 0xa0000, /* (1920x1088/256)x80 */ - }, - .cbr_info = { - .buf_start = 0x13b0000, - .buf_size = 0x2000, - } - } -}; - -enum ucode_type_e { - UCODE_GX, - UCODE_GXTV, - UCODE_GXL, - UCODE_TXL, - UCODE_MAX -}; - -const char *ucode_name[] = { - "h264_enc_mc_gx", - "h264_enc_mc_gxtv", - "gx_h264_enc", - "h264_enc_mc_txl", -}; - -static void dma_flush(u32 buf_start, u32 buf_size); -static void cache_flush(u32 buf_start , u32 buf_size); - -static const char *select_ucode(u32 ucode_index) -{ - enum ucode_type_e ucode = UCODE_GX; - switch (ucode_index) { - case UCODE_MODE_FULL: - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) - ucode = UCODE_TXL; - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - ucode = UCODE_GXL; - else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) - ucode = UCODE_GXTV; - else /* if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) */ - ucode = UCODE_GX; - break; - break; - default: - break; - } - return (const char *)ucode_name[ucode]; -} - -static void hcodec_prog_qtbl(struct encode_wq_s *wq) -{ - WRITE_HREG(HCODEC_Q_QUANT_CONTROL, - (0 << 23) | /* quant_table_addr */ - (1 << 22)); /* quant_table_addr_update */ - - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[0]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[1]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[2]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[3]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[4]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[5]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[6]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i4[7]); - - WRITE_HREG(HCODEC_Q_QUANT_CONTROL, - (8 << 23) | /* quant_table_addr */ - (1 << 22)); /* quant_table_addr_update */ - - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[0]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[1]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[2]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[3]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[4]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[5]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[6]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_i16[7]); - - WRITE_HREG(HCODEC_Q_QUANT_CONTROL, - (16 << 23) | /* quant_table_addr */ - (1 << 22)); /* quant_table_addr_update */ - - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[0]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[1]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[2]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[3]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[4]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[5]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[6]); - WRITE_HREG(HCODEC_QUANT_TABLE_DATA, - wq->quant_tbl_me[7]); - return; -} - -static void InitEncodeWeight(void) -{ - me_mv_merge_ctl = - (0x1 << 31) | /* [31] me_merge_mv_en_16 */ - (0x1 << 30) | /* [30] me_merge_small_mv_en_16 */ - (0x1 << 29) | /* [29] me_merge_flex_en_16 */ - (0x1 << 28) | /* [28] me_merge_sad_en_16 */ - (0x1 << 27) | /* [27] me_merge_mv_en_8 */ - (0x1 << 26) | /* [26] me_merge_small_mv_en_8 */ - (0x1 << 25) | /* [25] me_merge_flex_en_8 */ - (0x1 << 24) | /* [24] me_merge_sad_en_8 */ - (0x12 << 18) | - /* [23:18] me_merge_mv_diff_16 - MV diff - <= n pixel can be merged */ - (0x2b << 12) | - /* [17:12] me_merge_mv_diff_8 - MV diff - <= n pixel can be merged */ - (0x80 << 0); - /* [11:0] me_merge_min_sad - SAD - >= 0x180 can be merged with other MV */ - - me_mv_weight_01 = (ME_MV_STEP_WEIGHT_1 << 24) | - (ME_MV_PRE_WEIGHT_1 << 16) | - (ME_MV_STEP_WEIGHT_0 << 8) | - (ME_MV_PRE_WEIGHT_0 << 0); - - me_mv_weight_23 = (ME_MV_STEP_WEIGHT_3 << 24) | - (ME_MV_PRE_WEIGHT_3 << 16) | - (ME_MV_STEP_WEIGHT_2 << 8) | - (ME_MV_PRE_WEIGHT_2 << 0); - - me_sad_range_inc = (ME_SAD_RANGE_3 << 24) | - (ME_SAD_RANGE_2 << 16) | - (ME_SAD_RANGE_1 << 8) | - (ME_SAD_RANGE_0 << 0); - - me_step0_close_mv = (0x100 << 10) | - /* me_step0_big_sad -- two MV sad - diff bigger will use use 1 */ - (2 << 5) | /* me_step0_close_mv_y */ - (2 << 0); /* me_step0_close_mv_x */ - - me_f_skip_sad = (0x00 << 24) | /* force_skip_sad_3 */ - (STEP_2_SKIP_SAD << 16) | /* force_skip_sad_2 */ - (STEP_1_SKIP_SAD << 8) | /* force_skip_sad_1 */ - (STEP_0_SKIP_SAD << 0); /* force_skip_sad_0 */ - - me_f_skip_weight = (0x00 << 24) | /* force_skip_weight_3 */ - /* force_skip_weight_2 */ - (STEP_2_SKIP_WEIGHT << 16) | - /* force_skip_weight_1 */ - (STEP_1_SKIP_WEIGHT << 8) | - /* force_skip_weight_0 */ - (STEP_0_SKIP_WEIGHT << 0); - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - me_f_skip_sad = 0; - me_f_skip_weight = 0; - me_mv_weight_01 = 0; - me_mv_weight_23 = 0; - } - - me_sad_enough_01 = (ME_SAD_ENOUGH_1_DATA << 12) | - /* me_sad_enough_1 */ - (ME_SAD_ENOUGH_0_DATA << 0) | - /* me_sad_enough_0 */ - (0 << 12) | /* me_sad_enough_1 */ - (0 << 0); /* me_sad_enough_0 */ - - me_sad_enough_23 = (ADV_MV_8x8_ENOUGH_DATA << 12) | - /* adv_mv_8x8_enough */ - (ME_SAD_ENOUGH_2_DATA << 0) | - /* me_sad_enough_2 */ - (0 << 12) | /* me_sad_enough_3 */ - (0 << 0); /* me_sad_enough_2 */ -} - -/*output stream buffer setting*/ -static void avc_init_output_buffer(struct encode_wq_s *wq) -{ - WRITE_HREG(HCODEC_VLC_VB_MEM_CTL, - ((1 << 31) | (0x3f << 24) | - (0x20 << 16) | (2 << 0))); - WRITE_HREG(HCODEC_VLC_VB_START_PTR, - wq->mem.BitstreamStart); - WRITE_HREG(HCODEC_VLC_VB_WR_PTR, - wq->mem.BitstreamStart); - WRITE_HREG(HCODEC_VLC_VB_SW_RD_PTR, - wq->mem.BitstreamStart); - WRITE_HREG(HCODEC_VLC_VB_END_PTR, - wq->mem.BitstreamEnd); - WRITE_HREG(HCODEC_VLC_VB_CONTROL, 1); - WRITE_HREG(HCODEC_VLC_VB_CONTROL, - ((0 << 14) | (7 << 3) | - (1 << 1) | (0 << 0))); -} - -/*input dct buffer setting*/ -static void avc_init_input_buffer(struct encode_wq_s *wq) -{ - WRITE_HREG(HCODEC_QDCT_MB_START_PTR, - wq->mem.dct_buff_start_addr); - WRITE_HREG(HCODEC_QDCT_MB_END_PTR, - wq->mem.dct_buff_end_addr); - WRITE_HREG(HCODEC_QDCT_MB_WR_PTR, - wq->mem.dct_buff_start_addr); - WRITE_HREG(HCODEC_QDCT_MB_RD_PTR, - wq->mem.dct_buff_start_addr); - WRITE_HREG(HCODEC_QDCT_MB_BUFF, 0); -} - -/*input reference buffer setting*/ -static void avc_init_reference_buffer(s32 canvas) -{ - WRITE_HREG(HCODEC_ANC0_CANVAS_ADDR, canvas); - WRITE_HREG(HCODEC_VLC_HCMD_CONFIG, 0); -} - -static void avc_init_assit_buffer(struct encode_wq_s *wq) -{ - WRITE_HREG(MEM_OFFSET_REG, wq->mem.assit_buffer_offset); -} - -/*deblock buffer setting, same as INI_CANVAS*/ -static void avc_init_dblk_buffer(s32 canvas) -{ - WRITE_HREG(HCODEC_REC_CANVAS_ADDR, canvas); - WRITE_HREG(HCODEC_DBKR_CANVAS_ADDR, canvas); - WRITE_HREG(HCODEC_DBKW_CANVAS_ADDR, canvas); -} - -static void avc_init_encoder(struct encode_wq_s *wq, bool idr) -{ - WRITE_HREG(HCODEC_VLC_TOTAL_BYTES, 0); - WRITE_HREG(HCODEC_VLC_CONFIG, 0x07); - WRITE_HREG(HCODEC_VLC_INT_CONTROL, 0); - - WRITE_HREG(HCODEC_ASSIST_AMR1_INT0, 0x15); - WRITE_HREG(HCODEC_ASSIST_AMR1_INT1, 0x8); - WRITE_HREG(HCODEC_ASSIST_AMR1_INT3, 0x14); - - WRITE_HREG(IDR_PIC_ID, wq->pic.idr_pic_id); - WRITE_HREG(FRAME_NUMBER, - (idr == true) ? 0 : wq->pic.frame_number); - WRITE_HREG(PIC_ORDER_CNT_LSB, - (idr == true) ? 0 : wq->pic.pic_order_cnt_lsb); - - WRITE_HREG(LOG2_MAX_PIC_ORDER_CNT_LSB, - wq->pic.log2_max_pic_order_cnt_lsb); - WRITE_HREG(LOG2_MAX_FRAME_NUM, - wq->pic.log2_max_frame_num); - WRITE_HREG(ANC0_BUFFER_ID, 0); - WRITE_HREG(QPPICTURE, wq->pic.init_qppicture); -} - -static void avc_canvas_init(struct encode_wq_s *wq) -{ - u32 canvas_width, canvas_height; - u32 start_addr = wq->mem.buf_start; - - canvas_width = ((wq->pic.encoder_width + 31) >> 5) << 5; - canvas_height = ((wq->pic.encoder_height + 15) >> 4) << 4; - - canvas_config(ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec0_y.buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - canvas_config(1 + ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec0_uv.buf_start, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - /*here the third plane use the same address as the second plane*/ - canvas_config(2 + ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec0_uv.buf_start, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - - canvas_config(3 + ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec1_y.buf_start, - canvas_width, canvas_height, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - canvas_config(4 + ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec1_uv.buf_start, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - /*here the third plane use the same address as the second plane*/ - canvas_config(5 + ENC_CANVAS_OFFSET, - start_addr + wq->mem.bufspec.dec1_uv.buf_start, - canvas_width, canvas_height / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); -} - -static void avc_buffspec_init(struct encode_wq_s *wq) -{ - u32 canvas_width, canvas_height; - u32 start_addr = wq->mem.buf_start; - u32 mb_w = (wq->pic.encoder_width + 15) >> 4; - u32 mb_h = (wq->pic.encoder_height + 15) >> 4; - u32 mbs = mb_w * mb_h; - - canvas_width = ((wq->pic.encoder_width + 31) >> 5) << 5; - canvas_height = ((wq->pic.encoder_height + 15) >> 4) << 4; - - wq->mem.dct_buff_start_addr = start_addr + - wq->mem.bufspec.dct.buf_start; - wq->mem.dct_buff_end_addr = - wq->mem.dct_buff_start_addr + - wq->mem.bufspec.dct.buf_size - 1; - enc_pr(LOG_INFO, "dct_buff_start_addr is 0x%x, wq:%p.\n", - wq->mem.dct_buff_start_addr, (void *)wq); - - wq->mem.bufspec.dec0_uv.buf_start = - wq->mem.bufspec.dec0_y.buf_start + - canvas_width * canvas_height; - wq->mem.bufspec.dec0_uv.buf_size = canvas_width * canvas_height / 2; - wq->mem.bufspec.dec1_uv.buf_start = - wq->mem.bufspec.dec1_y.buf_start + - canvas_width * canvas_height; - wq->mem.bufspec.dec1_uv.buf_size = canvas_width * canvas_height / 2; - wq->mem.assit_buffer_offset = start_addr + - wq->mem.bufspec.assit.buf_start; - enc_pr(LOG_INFO, "assit_buffer_offset is 0x%x, wq: %p.\n", - wq->mem.assit_buffer_offset, (void *)wq); - /*output stream buffer config*/ - wq->mem.BitstreamStart = start_addr + - wq->mem.bufspec.bitstream.buf_start; - wq->mem.BitstreamEnd = - wq->mem.BitstreamStart + - wq->mem.bufspec.bitstream.buf_size - 1; - enc_pr(LOG_INFO, "BitstreamStart is 0x%x, wq: %p.\n", - wq->mem.BitstreamStart, (void *)wq); - - wq->mem.scaler_buff_start_addr = - wq->mem.buf_start + wq->mem.bufspec.scale_buff.buf_start; - wq->mem.dump_info_ddr_start_addr = - wq->mem.buf_start + wq->mem.bufspec.dump_info.buf_start; -enc_pr(LOG_INFO, "CBR: dump_info_ddr_start_addr:%x.\n", wq->mem.dump_info_ddr_start_addr); -enc_pr(LOG_INFO, "CBR: buf_start :%d.\n", wq->mem.buf_start); -enc_pr(LOG_INFO, "CBR: dump_info.buf_start :%d.\n", wq->mem.bufspec.dump_info.buf_start); - wq->mem.dump_info_ddr_size = - DUMP_INFO_BYTES_PER_MB * mbs; - wq->mem.dump_info_ddr_size = - (wq->mem.dump_info_ddr_size + PAGE_SIZE - 1) - & ~(PAGE_SIZE - 1); - wq->mem.cbr_info_ddr_start_addr = - wq->mem.buf_start + wq->mem.bufspec.cbr_info.buf_start; - wq->mem.cbr_info_ddr_size = - wq->mem.bufspec.cbr_info.buf_size; - - wq->mem.dblk_buf_canvas = - ((ENC_CANVAS_OFFSET + 2) << 16) | - ((ENC_CANVAS_OFFSET + 1) << 8) | - (ENC_CANVAS_OFFSET); - wq->mem.ref_buf_canvas = - ((ENC_CANVAS_OFFSET + 5) << 16) | - ((ENC_CANVAS_OFFSET + 4) << 8) | - (ENC_CANVAS_OFFSET + 3); -} - -static void avc_init_ie_me_parameter(struct encode_wq_s *wq, u32 quant) -{ - ie_cur_ref_sel = 0; - ie_pippeline_block = 12; - /* currently disable half and sub pixel */ - ie_me_mode = - (ie_pippeline_block & IE_PIPPELINE_BLOCK_MASK) << - IE_PIPPELINE_BLOCK_SHIFT; - - WRITE_HREG(IE_ME_MODE, ie_me_mode); - WRITE_HREG(IE_REF_SEL, ie_cur_ref_sel); - WRITE_HREG(IE_ME_MB_TYPE, ie_me_mb_type); -#ifdef MULTI_SLICE_MC - if (fixed_slice_cfg) - WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg); - else if (wq->pic.rows_per_slice != - (wq->pic.encoder_height + 15) >> 4) { - u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4; - mb_per_slice = mb_per_slice * wq->pic.rows_per_slice; - WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice); - } else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#endif -} - -/* for temp */ -#define HCODEC_MFDIN_REGC_MBLP (HCODEC_MFDIN_REGB_AMPC + 0x1) -#define HCODEC_MFDIN_REG0D (HCODEC_MFDIN_REGB_AMPC + 0x2) -#define HCODEC_MFDIN_REG0E (HCODEC_MFDIN_REGB_AMPC + 0x3) -#define HCODEC_MFDIN_REG0F (HCODEC_MFDIN_REGB_AMPC + 0x4) -#define HCODEC_MFDIN_REG10 (HCODEC_MFDIN_REGB_AMPC + 0x5) -#define HCODEC_MFDIN_REG11 (HCODEC_MFDIN_REGB_AMPC + 0x6) -#define HCODEC_MFDIN_REG12 (HCODEC_MFDIN_REGB_AMPC + 0x7) -#define HCODEC_MFDIN_REG13 (HCODEC_MFDIN_REGB_AMPC + 0x8) -#define HCODEC_MFDIN_REG14 (HCODEC_MFDIN_REGB_AMPC + 0x9) -#define HCODEC_MFDIN_REG15 (HCODEC_MFDIN_REGB_AMPC + 0xa) -#define HCODEC_MFDIN_REG16 (HCODEC_MFDIN_REGB_AMPC + 0xb) - -static void mfdin_basic(u32 input, u8 iformat, - u8 oformat, u32 picsize_x, u32 picsize_y, - u8 r2y_en, u8 nr, u8 ifmt_extra) -{ - u8 dsample_en; /* Downsample Enable */ - u8 interp_en; /* Interpolation Enable */ - u8 y_size; /* 0:16 Pixels for y direction pickup; 1:8 pixels */ - u8 r2y_mode; /* RGB2YUV Mode, range(0~3) */ - /* mfdin_reg3_canv[25:24]; - // bytes per pixel in x direction for index0, 0:half 1:1 2:2 3:3 */ - u8 canv_idx0_bppx; - /* mfdin_reg3_canv[27:26]; - // bytes per pixel in x direction for index1-2, 0:half 1:1 2:2 3:3 */ - u8 canv_idx1_bppx; - /* mfdin_reg3_canv[29:28]; - // bytes per pixel in y direction for index0, 0:half 1:1 2:2 3:3 */ - u8 canv_idx0_bppy; - /* mfdin_reg3_canv[31:30]; - // bytes per pixel in y direction for index1-2, 0:half 1:1 2:2 3:3 */ - u8 canv_idx1_bppy; - u8 ifmt444, ifmt422, ifmt420, linear_bytes4p; - u8 nr_enable; - u8 cfg_y_snr_en; - u8 cfg_y_tnr_en; - u8 cfg_c_snr_en; - u8 cfg_c_tnr_en; - u32 linear_bytesperline; - s32 reg_offset; - bool linear_enable = false; - bool format_err = false; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) { - if ((iformat == 7) && (ifmt_extra > 2)) - format_err = true; - } else if (iformat == 7) - format_err = true; - - if (format_err) { - enc_pr(LOG_ERROR, - "mfdin format err, iformat:%d, ifmt_extra:%d\n", - iformat, ifmt_extra); - return; - } - if (iformat != 7) - ifmt_extra = 0; - - ifmt444 = ((iformat == 1) || (iformat == 5) || (iformat == 8) || - (iformat == 9) || (iformat == 12)) ? 1 : 0; - if (iformat == 7 && ifmt_extra == 1) - ifmt444 = 1; - ifmt422 = ((iformat == 0) || (iformat == 10)) ? 1 : 0; - if (iformat == 7 && ifmt_extra != 1) - ifmt422 = 1; - ifmt420 = ((iformat == 2) || (iformat == 3) || (iformat == 4) || - (iformat == 11)) ? 1 : 0; - dsample_en = ((ifmt444 && (oformat != 2)) || - (ifmt422 && (oformat == 0))) ? 1 : 0; - interp_en = ((ifmt422 && (oformat == 2)) || - (ifmt420 && (oformat != 0))) ? 1 : 0; - y_size = (oformat != 0) ? 1 : 0; - if (iformat == 12) - y_size = 0; - r2y_mode = (r2y_en == 1) ? 1 : 0; /* Fixed to 1 (TODO) */ - canv_idx0_bppx = (iformat == 1) ? 3 : (iformat == 0) ? 2 : 1; - canv_idx1_bppx = (iformat == 4) ? 0 : 1; - canv_idx0_bppy = 1; - canv_idx1_bppy = (iformat == 5) ? 1 : 0; - - if ((iformat == 8) || (iformat == 9) || (iformat == 12)) - linear_bytes4p = 3; - else if (iformat == 10) - linear_bytes4p = 2; - else if (iformat == 11) - linear_bytes4p = 1; - else - linear_bytes4p = 0; - if (iformat == 12) - linear_bytesperline = picsize_x * 4; - else - linear_bytesperline = picsize_x * linear_bytes4p; - - if (iformat < 8) - linear_enable = false; - else - linear_enable = true; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - reg_offset = -8; - /* nr_mode: 0:Disabled 1:SNR Only 2:TNR Only 3:3DNR */ - nr_enable = (nr) ? 1 : 0; - cfg_y_snr_en = ((nr == 1) || (nr == 3)) ? 1 : 0; - cfg_y_tnr_en = ((nr == 2) || (nr == 3)) ? 1 : 0; - cfg_c_snr_en = cfg_y_snr_en; - /* cfg_c_tnr_en = cfg_y_tnr_en; */ - cfg_c_tnr_en = 0; - - /* NR For Y */ - WRITE_HREG((HCODEC_MFDIN_REG0D + reg_offset), - ((cfg_y_snr_en << 0) | - (y_snr_err_norm << 1) | - (y_snr_gau_bld_core << 2) | - (((y_snr_gau_bld_ofst) & 0xff) << 6) | - (y_snr_gau_bld_rate << 14) | - (y_snr_gau_alp0_min << 20) | - (y_snr_gau_alp0_max << 26))); - WRITE_HREG((HCODEC_MFDIN_REG0E + reg_offset), - ((cfg_y_tnr_en << 0) | - (y_tnr_mc_en << 1) | - (y_tnr_txt_mode << 2) | - (y_tnr_mot_sad_margin << 3) | - (y_tnr_alpha_min << 7) | - (y_tnr_alpha_max << 13) | - (y_tnr_deghost_os << 19))); - WRITE_HREG((HCODEC_MFDIN_REG0F + reg_offset), - ((y_tnr_mot_cortxt_rate << 0) | - (y_tnr_mot_distxt_ofst << 8) | - (y_tnr_mot_distxt_rate << 4) | - (y_tnr_mot_dismot_ofst << 16) | - (y_tnr_mot_frcsad_lock << 24))); - WRITE_HREG((HCODEC_MFDIN_REG10 + reg_offset), - ((y_tnr_mot2alp_frc_gain << 0) | - (y_tnr_mot2alp_nrm_gain << 8) | - (y_tnr_mot2alp_dis_gain << 16) | - (y_tnr_mot2alp_dis_ofst << 24))); - WRITE_HREG((HCODEC_MFDIN_REG11 + reg_offset), - ((y_bld_beta2alp_rate << 0) | - (y_bld_beta_min << 8) | - (y_bld_beta_max << 14))); - - /* NR For C */ - WRITE_HREG((HCODEC_MFDIN_REG12 + reg_offset), - ((cfg_y_snr_en << 0) | - (c_snr_err_norm << 1) | - (c_snr_gau_bld_core << 2) | - (((c_snr_gau_bld_ofst) & 0xff) << 6) | - (c_snr_gau_bld_rate << 14) | - (c_snr_gau_alp0_min << 20) | - (c_snr_gau_alp0_max << 26))); - - WRITE_HREG((HCODEC_MFDIN_REG13 + reg_offset), - ((cfg_c_tnr_en << 0) | - (c_tnr_mc_en << 1) | - (c_tnr_txt_mode << 2) | - (c_tnr_mot_sad_margin << 3) | - (c_tnr_alpha_min << 7) | - (c_tnr_alpha_max << 13) | - (c_tnr_deghost_os << 19))); - WRITE_HREG((HCODEC_MFDIN_REG14 + reg_offset), - ((c_tnr_mot_cortxt_rate << 0) | - (c_tnr_mot_distxt_ofst << 8) | - (c_tnr_mot_distxt_rate << 4) | - (c_tnr_mot_dismot_ofst << 16) | - (c_tnr_mot_frcsad_lock << 24))); - WRITE_HREG((HCODEC_MFDIN_REG15 + reg_offset), - ((c_tnr_mot2alp_frc_gain << 0) | - (c_tnr_mot2alp_nrm_gain << 8) | - (c_tnr_mot2alp_dis_gain << 16) | - (c_tnr_mot2alp_dis_ofst << 24))); - - WRITE_HREG((HCODEC_MFDIN_REG16 + reg_offset), - ((c_bld_beta2alp_rate << 0) | - (c_bld_beta_min << 8) | - (c_bld_beta_max << 14))); - - WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset), - (iformat << 0) | (oformat << 4) | - (dsample_en << 6) | (y_size << 8) | - (interp_en << 9) | (r2y_en << 12) | - (r2y_mode << 13) | (ifmt_extra << 16) | - (nr_enable << 19)); - WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset), - (picsize_x << 14) | (picsize_y << 0)); - } else { - reg_offset = 0; - WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset), - (iformat << 0) | (oformat << 4) | - (dsample_en << 6) | (y_size << 8) | - (interp_en << 9) | (r2y_en << 12) | - (r2y_mode << 13)); - WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset), - (picsize_x << 12) | (picsize_y << 0)); - } - - if (linear_enable == false) { - WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset), - (input & 0xffffff) | - (canv_idx1_bppy << 30) | - (canv_idx0_bppy << 28) | - (canv_idx1_bppx << 26) | - (canv_idx0_bppx << 24)); - WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset), - (0 << 16) | (0 << 0)); - WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), 0); - } else { - WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset), - (canv_idx1_bppy << 30) | - (canv_idx0_bppy << 28) | - (canv_idx1_bppx << 26) | - (canv_idx0_bppx << 24)); - WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset), - (linear_bytes4p << 16) | (linear_bytesperline << 0)); - WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), input); - } - - if (iformat == 12) - WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset), - (2 << 0) | (1 << 3) | (0 << 6) | - (3 << 9) | (6 << 12) | (5 << 15) | - (4 << 18) | (7 << 21)); - else - WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset), - (7 << 0) | (6 << 3) | (5 << 6) | - (4 << 9) | (3 << 12) | (2 << 15) | - (1 << 18) | (0 << 21)); -} - -#ifdef CONFIG_AM_GE2D -static int scale_frame(struct encode_wq_s *wq, - struct encode_request_s *request, - struct config_para_ex_s *ge2d_config, - u32 src_addr, bool canvas) -{ - struct ge2d_context_s *context = encode_manager.context; - int src_top, src_left, src_width, src_height; - struct canvas_s cs0, cs1, cs2, cd; - u32 src_canvas, dst_canvas; - u32 src_canvas_w, dst_canvas_w; - u32 src_h = request->src_h; - u32 dst_w = ((wq->pic.encoder_width + 15) >> 4) << 4; - u32 dst_h = ((wq->pic.encoder_height + 15) >> 4) << 4; - int input_format = GE2D_FORMAT_M24_NV21; - src_top = request->crop_top; - src_left = request->crop_left; - src_width = request->src_w - src_left - request->crop_right; - src_height = request->src_h - src_top - request->crop_bottom; - if (canvas) { - if ((request->fmt == FMT_NV21) - || (request->fmt == FMT_NV12)) { - src_canvas = src_addr & 0xffff; - input_format = GE2D_FORMAT_M24_NV21; - } else { - src_canvas = src_addr & 0xffffff; - input_format = GE2D_FORMAT_M24_YUV420; - } - } else { - if ((request->fmt == FMT_NV21) - || (request->fmt == FMT_NV12)) { - src_canvas_w = - ((request->src_w + 31) >> 5) << 5; - canvas_config(ENC_CANVAS_OFFSET + 9, - src_addr, - src_canvas_w, src_h, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 10, - src_addr + src_canvas_w * src_h, - src_canvas_w, src_h / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - src_canvas = - ((ENC_CANVAS_OFFSET + 10) << 8) - | (ENC_CANVAS_OFFSET + 9); - input_format = GE2D_FORMAT_M24_NV21; - } else { - src_canvas_w = - ((request->src_w + 63) >> 6) << 6; - canvas_config(ENC_CANVAS_OFFSET + 9, - src_addr, - src_canvas_w, src_h, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 10, - src_addr + src_canvas_w * src_h, - src_canvas_w / 2, src_h / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 11, - src_addr + src_canvas_w * src_h * 5 / 4, - src_canvas_w / 2, src_h / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - src_canvas = - ((ENC_CANVAS_OFFSET + 11) << 16) | - ((ENC_CANVAS_OFFSET + 10) << 8) | - (ENC_CANVAS_OFFSET + 9); - input_format = GE2D_FORMAT_M24_YUV420; - } - } - dst_canvas_w = ((dst_w + 31) >> 5) << 5; - canvas_config(ENC_CANVAS_OFFSET + 6, - wq->mem.scaler_buff_start_addr, - dst_canvas_w, dst_h, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 7, - wq->mem.scaler_buff_start_addr + dst_canvas_w * dst_h, - dst_canvas_w, dst_h / 2, - CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - dst_canvas = ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - ge2d_config->alu_const_color = 0; - ge2d_config->bitmask_en = 0; - ge2d_config->src1_gb_alpha = 0; - ge2d_config->dst_xy_swap = 0; - canvas_read(src_canvas & 0xff, &cs0); - canvas_read((src_canvas >> 8) & 0xff, &cs1); - canvas_read((src_canvas >> 16) & 0xff, &cs2); - ge2d_config->src_planes[0].addr = cs0.addr; - ge2d_config->src_planes[0].w = cs0.width; - ge2d_config->src_planes[0].h = cs0.height; - ge2d_config->src_planes[1].addr = cs1.addr; - ge2d_config->src_planes[1].w = cs1.width; - ge2d_config->src_planes[1].h = cs1.height; - ge2d_config->src_planes[2].addr = cs2.addr; - ge2d_config->src_planes[2].w = cs2.width; - ge2d_config->src_planes[2].h = cs2.height; - canvas_read(dst_canvas & 0xff, &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; - ge2d_config->src_key.key_enable = 0; - ge2d_config->src_key.key_mask = 0; - ge2d_config->src_key.key_mode = 0; - ge2d_config->src_para.canvas_index = src_canvas; - ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config->src_para.format = input_format | GE2D_LITTLE_ENDIAN; - 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 = request->src_w; - ge2d_config->src_para.height = request->src_h; - ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config->dst_para.canvas_index = dst_canvas; - ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID; - ge2d_config->dst_para.format = - GE2D_FORMAT_M24_NV21 | GE2D_LITTLE_ENDIAN; - 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; - ge2d_config->dst_para.width = dst_w; - ge2d_config->dst_para.height = dst_h; - ge2d_config->dst_para.x_rev = 0; - ge2d_config->dst_para.y_rev = 0; - if (ge2d_context_config_ex(context, ge2d_config) < 0) { - pr_err("++ge2d configing error.\n"); - return -1; - } - stretchblt_noalpha(context, src_left, src_top, src_width, src_height, - 0, 0, wq->pic.encoder_width, wq->pic.encoder_height); - return dst_canvas_w*dst_h * 3 / 2; -} -#endif - -static s32 set_input_format(struct encode_wq_s *wq, - struct encode_request_s *request) -{ - s32 ret = 0; - u8 iformat = MAX_FRAME_FMT, oformat = MAX_FRAME_FMT, r2y_en = 0; - u32 picsize_x, picsize_y, src_addr; - u32 canvas_w = 0; - u32 input = request->src; - u8 ifmt_extra = 0; - - if ((request->fmt == FMT_RGB565) || (request->fmt >= MAX_FRAME_FMT)) - return -1; - - picsize_x = ((wq->pic.encoder_width + 15) >> 4) << 4; - picsize_y = ((wq->pic.encoder_height + 15) >> 4) << 4; - oformat = 0; - if ((request->type == LOCAL_BUFF) - || (request->type == PHYSICAL_BUFF)) { - if ((request->type == LOCAL_BUFF) && - (request->flush_flag & AMVENC_FLUSH_FLAG_INPUT)) - dma_flush(wq->mem.dct_buff_start_addr, - request->framesize); - if (request->type == LOCAL_BUFF) { - input = wq->mem.dct_buff_start_addr; - src_addr = - wq->mem.dct_buff_start_addr; - } else { - src_addr = input; - picsize_y = wq->pic.encoder_height; - } - if (request->scale_enable) { -#ifdef CONFIG_AM_GE2D - struct config_para_ex_s ge2d_config; - memset(&ge2d_config, 0, - sizeof(struct config_para_ex_s)); - scale_frame( - wq, request, - &ge2d_config, - src_addr, - false); - iformat = 2; - r2y_en = 0; - input = ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - ret = 0; - goto MFDIN; -#else - enc_pr(LOG_ERROR, - "Warning: need enable ge2d for scale frame!\n"); - return -1; -#endif - } - if ((request->fmt <= FMT_YUV444_PLANE) || - (request->fmt >= FMT_YUV422_12BIT)) - r2y_en = 0; - else - r2y_en = 1; - - if (request->fmt >= FMT_YUV422_12BIT) { - iformat = 7; - ifmt_extra = request->fmt - FMT_YUV422_12BIT; - if (request->fmt == FMT_YUV422_12BIT) - canvas_w = picsize_x * 24 / 8; - else if (request->fmt == FMT_YUV444_10BIT) - canvas_w = picsize_x * 32 / 8; - else - canvas_w = (picsize_x * 20 + 7) / 8; - canvas_w = ((canvas_w + 31) >> 5) << 5; - canvas_config(ENC_CANVAS_OFFSET + 6, - input, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - input = ENC_CANVAS_OFFSET + 6; - input = input & 0xff; - } else if (request->fmt == FMT_YUV422_SINGLE) - iformat = 10; - else if ((request->fmt == FMT_YUV444_SINGLE) - || (request->fmt == FMT_RGB888)) { - iformat = 1; - if (request->fmt == FMT_RGB888) - r2y_en = 1; - canvas_w = picsize_x * 3; - canvas_w = ((canvas_w + 31) >> 5) << 5; - canvas_config(ENC_CANVAS_OFFSET + 6, - input, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - input = ENC_CANVAS_OFFSET + 6; - } else if ((request->fmt == FMT_NV21) - || (request->fmt == FMT_NV12)) { - canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5; - iformat = (request->fmt == FMT_NV21) ? 2 : 3; - canvas_config(ENC_CANVAS_OFFSET + 6, - input, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 7, - input + canvas_w * picsize_y, - canvas_w, picsize_y / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - input = ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - } else if (request->fmt == FMT_YUV420) { - iformat = 4; - canvas_w = ((wq->pic.encoder_width + 63) >> 6) << 6; - canvas_config(ENC_CANVAS_OFFSET + 6, - input, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 7, - input + canvas_w * picsize_y, - canvas_w / 2, picsize_y / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 8, - input + canvas_w * picsize_y * 5 / 4, - canvas_w / 2, picsize_y / 2, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - input = ((ENC_CANVAS_OFFSET + 8) << 16) | - ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - } else if ((request->fmt == FMT_YUV444_PLANE) - || (request->fmt == FMT_RGB888_PLANE)) { - if (request->fmt == FMT_RGB888_PLANE) - r2y_en = 1; - iformat = 5; - canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5; - canvas_config(ENC_CANVAS_OFFSET + 6, - input, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 7, - input + canvas_w * picsize_y, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - canvas_config(ENC_CANVAS_OFFSET + 8, - input + canvas_w * picsize_y * 2, - canvas_w, picsize_y, - CANVAS_ADDR_NOWRAP, - CANVAS_BLKMODE_LINEAR); - input = ((ENC_CANVAS_OFFSET + 8) << 16) | - ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - } else if (request->fmt == FMT_RGBA8888) { - r2y_en = 1; - iformat = 12; - } - ret = 0; - } else if (request->type == CANVAS_BUFF) { - r2y_en = 0; - if (request->scale_enable) { -#ifdef CONFIG_AM_GE2D - struct config_para_ex_s ge2d_config; - memset(&ge2d_config, 0, - sizeof(struct config_para_ex_s)); - scale_frame( - wq, request, - &ge2d_config, - input, true); - iformat = 2; - r2y_en = 0; - input = ((ENC_CANVAS_OFFSET + 7) << 8) | - (ENC_CANVAS_OFFSET + 6); - ret = 0; - goto MFDIN; -#else - enc_pr(LOG_ERROR, - "Warning: need enable ge2d for scale frame!\n"); - return -1; -#endif - } - if (request->fmt == FMT_YUV422_SINGLE) { - iformat = 0; - input = input & 0xff; - } else if (request->fmt == FMT_YUV444_SINGLE) { - iformat = 1; - input = input & 0xff; - } else if ((request->fmt == FMT_NV21) - || (request->fmt == FMT_NV12)) { - iformat = (request->fmt == FMT_NV21) ? 2 : 3; - input = input & 0xffff; - } else if (request->fmt == FMT_YUV420) { - iformat = 4; - input = input & 0xffffff; - } else if ((request->fmt == FMT_YUV444_PLANE) - || (request->fmt == FMT_RGB888_PLANE)) { - if (request->fmt == FMT_RGB888_PLANE) - r2y_en = 1; - iformat = 5; - input = input & 0xffffff; - } else if ((request->fmt == FMT_YUV422_12BIT) - || (request->fmt == FMT_YUV444_10BIT) - || (request->fmt == FMT_YUV422_10BIT)) { - iformat = 7; - ifmt_extra = request->fmt - FMT_YUV422_12BIT; - input = input & 0xff; - } else - ret = -1; - } - - if (ret == 0) - mfdin_basic(input, iformat, oformat, - picsize_x, picsize_y, r2y_en, - request->nr_mode, ifmt_extra); - return ret; -} - -#ifdef H264_ENC_CBR -static void ConvertTable2Risc(void *table, u32 len) -{ - u32 i, j; - u16 temp; - u16 *tbl = (u16 *)table; - if ((len < 8) || (len % 8) || (!table)) { - enc_pr(LOG_ERROR, "ConvertTable2Risc tbl %p, len %d error\n", - table, len); - return; - } - for (i = 0; i < len / 8; i++) { - j = i << 2; - temp = tbl[j]; - tbl[j] = tbl[j + 3]; - tbl[j + 3] = temp; - - temp = tbl[j + 1]; - tbl[j + 1] = tbl[j + 2]; - tbl[j + 2] = temp; - } - -} -#endif - -static void avc_prot_init(struct encode_wq_s *wq, - struct encode_request_s *request, u32 quant, bool IDR) -{ - u32 data32; - u32 pic_width, pic_height; - u32 pic_mb_nr; - u32 pic_mbx, pic_mby; - u32 i_pic_qp, p_pic_qp; - u32 i_pic_qp_c, p_pic_qp_c; - u32 pic_width_in_mb; - u32 slice_qp; - pic_width = wq->pic.encoder_width; - pic_height = wq->pic.encoder_height; - pic_mb_nr = 0; - pic_mbx = 0; - pic_mby = 0; - i_pic_qp = quant; - p_pic_qp = quant; - - pic_width_in_mb = (pic_width + 15) / 16; - WRITE_HREG(HCODEC_HDEC_MC_OMEM_AUTO, - (1 << 31) | /* use_omem_mb_xy */ - ((pic_width_in_mb - 1) << 16)); /* omem_max_mb_x */ - - WRITE_HREG(HCODEC_VLC_ADV_CONFIG, - /* early_mix_mc_hcmd -- will enable in P Picture */ - (0 << 10) | - (1 << 9) | /* update_top_left_mix */ - (1 << 8) | /* p_top_left_mix */ - /* mv_cal_mixed_type -- will enable in P Picture */ - (0 << 7) | - /* mc_hcmd_mixed_type -- will enable in P Picture */ - (0 << 6) | - (1 << 5) | /* use_seperate_int_control */ - (1 << 4) | /* hcmd_intra_use_q_info */ - (1 << 3) | /* hcmd_left_use_prev_info */ - (1 << 2) | /* hcmd_use_q_info */ - (1 << 1) | /* use_q_delta_quant */ - /* detect_I16_from_I4 use qdct detected mb_type */ - (0 << 0)); - - WRITE_HREG(HCODEC_QDCT_ADV_CONFIG, - (1 << 29) | /* mb_info_latch_no_I16_pred_mode */ - (1 << 28) | /* ie_dma_mbxy_use_i_pred */ - (1 << 27) | /* ie_dma_read_write_use_ip_idx */ - (1 << 26) | /* ie_start_use_top_dma_count */ - (1 << 25) | /* i_pred_top_dma_rd_mbbot */ - (1 << 24) | /* i_pred_top_dma_wr_disable */ - /* i_pred_mix -- will enable in P Picture */ - (0 << 23) | - (1 << 22) | /* me_ab_rd_when_intra_in_p */ - (1 << 21) | /* force_mb_skip_run_when_intra */ - /* mc_out_mixed_type -- will enable in P Picture */ - (0 << 20) | - (1 << 19) | /* ie_start_when_quant_not_full */ - (1 << 18) | /* mb_info_state_mix */ - /* mb_type_use_mix_result -- will enable in P Picture */ - (0 << 17) | - /* me_cb_ie_read_enable -- will enable in P Picture */ - (0 << 16) | - /* ie_cur_data_from_me -- will enable in P Picture */ - (0 << 15) | - (1 << 14) | /* rem_per_use_table */ - (0 << 13) | /* q_latch_int_enable */ - (1 << 12) | /* q_use_table */ - (0 << 11) | /* q_start_wait */ - (1 << 10) | /* LUMA_16_LEFT_use_cur */ - (1 << 9) | /* DC_16_LEFT_SUM_use_cur */ - (1 << 8) | /* c_ref_ie_sel_cur */ - (0 << 7) | /* c_ipred_perfect_mode */ - (1 << 6) | /* ref_ie_ul_sel */ - (1 << 5) | /* mb_type_use_ie_result */ - (1 << 4) | /* detect_I16_from_I4 */ - (1 << 3) | /* ie_not_wait_ref_busy */ - (1 << 2) | /* ie_I16_enable */ - (3 << 0)); /* ie_done_sel // fastest when waiting */ - - if (request != NULL) { - WRITE_HREG(HCODEC_IE_WEIGHT, - (request->i16_weight << 16) | - (request->i4_weight << 0)); - WRITE_HREG(HCODEC_ME_WEIGHT, - (request->me_weight << 0)); - WRITE_HREG(HCODEC_SAD_CONTROL_0, - /* ie_sad_offset_I16 */ - (request->i16_weight << 16) | - /* ie_sad_offset_I4 */ - (request->i4_weight << 0)); - WRITE_HREG(HCODEC_SAD_CONTROL_1, - /* ie_sad_shift_I16 */ - (IE_SAD_SHIFT_I16 << 24) | - /* ie_sad_shift_I4 */ - (IE_SAD_SHIFT_I4 << 20) | - /* me_sad_shift_INTER */ - (ME_SAD_SHIFT_INTER << 16) | - /* me_sad_offset_INTER */ - (request->me_weight << 0)); - wq->me_weight = request->me_weight; - wq->i4_weight = request->i4_weight; - wq->i16_weight = request->i16_weight; - } else { - WRITE_HREG(HCODEC_IE_WEIGHT, - (I16MB_WEIGHT_OFFSET << 16) | - (I4MB_WEIGHT_OFFSET << 0)); - WRITE_HREG(HCODEC_ME_WEIGHT, - (ME_WEIGHT_OFFSET << 0)); - WRITE_HREG(HCODEC_SAD_CONTROL_0, - /* ie_sad_offset_I16 */ - (I16MB_WEIGHT_OFFSET << 16) | - /* ie_sad_offset_I4 */ - (I4MB_WEIGHT_OFFSET << 0)); - WRITE_HREG(HCODEC_SAD_CONTROL_1, - /* ie_sad_shift_I16 */ - (IE_SAD_SHIFT_I16 << 24) | - /* ie_sad_shift_I4 */ - (IE_SAD_SHIFT_I4 << 20) | - /* me_sad_shift_INTER */ - (ME_SAD_SHIFT_INTER << 16) | - /* me_sad_offset_INTER */ - (ME_WEIGHT_OFFSET << 0)); - } - - WRITE_HREG(HCODEC_ADV_MV_CTL0, - (ADV_MV_LARGE_16x8 << 31) | - (ADV_MV_LARGE_8x16 << 30) | - (ADV_MV_8x8_WEIGHT << 16) | /* adv_mv_8x8_weight */ - /* adv_mv_4x4x4_weight should be set bigger */ - (ADV_MV_4x4x4_WEIGHT << 0)); - WRITE_HREG(HCODEC_ADV_MV_CTL1, - /* adv_mv_16x16_weight */ - (ADV_MV_16x16_WEIGHT << 16) | - (ADV_MV_LARGE_16x16 << 15) | - (ADV_MV_16_8_WEIGHT << 0)); /* adv_mv_16_8_weight */ - - hcodec_prog_qtbl(wq); - if (IDR) { - i_pic_qp = - wq->quant_tbl_i4[0] & 0xff; - i_pic_qp += - wq->quant_tbl_i16[0] & 0xff; - i_pic_qp /= 2; - p_pic_qp = i_pic_qp; - } else { - i_pic_qp = - wq->quant_tbl_i4[0] & 0xff; - i_pic_qp += - wq->quant_tbl_i16[0] & 0xff; - p_pic_qp = wq->quant_tbl_me[0] & 0xff; - slice_qp = (i_pic_qp + p_pic_qp) / 3; - i_pic_qp = slice_qp; - p_pic_qp = i_pic_qp; - } -#ifdef H264_ENC_CBR - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - data32 = READ_HREG(HCODEC_SAD_CONTROL_1); - data32 = data32 & 0xffff; /* remove sad shift */ - WRITE_HREG(HCODEC_SAD_CONTROL_1, data32); - WRITE_HREG(H264_ENC_CBR_TABLE_ADDR, - wq->mem.cbr_info_ddr_start_addr); - WRITE_HREG(H264_ENC_CBR_MB_SIZE_ADDR, - wq->mem.cbr_info_ddr_start_addr - + CBR_TABLE_SIZE); - WRITE_HREG(H264_ENC_CBR_CTL, - (wq->cbr_info.start_tbl_id << 28) | - (wq->cbr_info.short_shift << 24) | - (wq->cbr_info.long_mb_num << 16) | - (wq->cbr_info.long_th << 0)); - WRITE_HREG(H264_ENC_CBR_REGION_SIZE, - (wq->cbr_info.block_w << 16) | - (wq->cbr_info.block_h << 0)); - } -#endif - - WRITE_HREG(HCODEC_QDCT_VLC_QUANT_CTL_0, - (0 << 19) | /* vlc_delta_quant_1 */ - (i_pic_qp << 13) | /* vlc_quant_1 */ - (0 << 6) | /* vlc_delta_quant_0 */ - (i_pic_qp << 0)); /* vlc_quant_0 */ - WRITE_HREG(HCODEC_QDCT_VLC_QUANT_CTL_1, - (14 << 6) | /* vlc_max_delta_q_neg */ - (13 << 0)); /* vlc_max_delta_q_pos */ - WRITE_HREG(HCODEC_VLC_PIC_SIZE, - pic_width | (pic_height << 16)); - WRITE_HREG(HCODEC_VLC_PIC_POSITION, - (pic_mb_nr << 16) | - (pic_mby << 8) | - (pic_mbx << 0)); - - /* synopsys parallel_case full_case */ - switch (i_pic_qp) { - case 0: - i_pic_qp_c = 0; - break; - case 1: - i_pic_qp_c = 1; - break; - case 2: - i_pic_qp_c = 2; - break; - case 3: - i_pic_qp_c = 3; - break; - case 4: - i_pic_qp_c = 4; - break; - case 5: - i_pic_qp_c = 5; - break; - case 6: - i_pic_qp_c = 6; - break; - case 7: - i_pic_qp_c = 7; - break; - case 8: - i_pic_qp_c = 8; - break; - case 9: - i_pic_qp_c = 9; - break; - case 10: - i_pic_qp_c = 10; - break; - case 11: - i_pic_qp_c = 11; - break; - case 12: - i_pic_qp_c = 12; - break; - case 13: - i_pic_qp_c = 13; - break; - case 14: - i_pic_qp_c = 14; - break; - case 15: - i_pic_qp_c = 15; - break; - case 16: - i_pic_qp_c = 16; - break; - case 17: - i_pic_qp_c = 17; - break; - case 18: - i_pic_qp_c = 18; - break; - case 19: - i_pic_qp_c = 19; - break; - case 20: - i_pic_qp_c = 20; - break; - case 21: - i_pic_qp_c = 21; - break; - case 22: - i_pic_qp_c = 22; - break; - case 23: - i_pic_qp_c = 23; - break; - case 24: - i_pic_qp_c = 24; - break; - case 25: - i_pic_qp_c = 25; - break; - case 26: - i_pic_qp_c = 26; - break; - case 27: - i_pic_qp_c = 27; - break; - case 28: - i_pic_qp_c = 28; - break; - case 29: - i_pic_qp_c = 29; - break; - case 30: - i_pic_qp_c = 29; - break; - case 31: - i_pic_qp_c = 30; - break; - case 32: - i_pic_qp_c = 31; - break; - case 33: - i_pic_qp_c = 32; - break; - case 34: - i_pic_qp_c = 32; - break; - case 35: - i_pic_qp_c = 33; - break; - case 36: - i_pic_qp_c = 34; - break; - case 37: - i_pic_qp_c = 34; - break; - case 38: - i_pic_qp_c = 35; - break; - case 39: - i_pic_qp_c = 35; - break; - case 40: - i_pic_qp_c = 36; - break; - case 41: - i_pic_qp_c = 36; - break; - case 42: - i_pic_qp_c = 37; - break; - case 43: - i_pic_qp_c = 37; - break; - case 44: - i_pic_qp_c = 37; - break; - case 45: - i_pic_qp_c = 38; - break; - case 46: - i_pic_qp_c = 38; - break; - case 47: - i_pic_qp_c = 38; - break; - case 48: - i_pic_qp_c = 39; - break; - case 49: - i_pic_qp_c = 39; - break; - case 50: - i_pic_qp_c = 39; - break; - default: - i_pic_qp_c = 39; - break; - } - - /* synopsys parallel_case full_case */ - switch (p_pic_qp) { - case 0: - p_pic_qp_c = 0; - break; - case 1: - p_pic_qp_c = 1; - break; - case 2: - p_pic_qp_c = 2; - break; - case 3: - p_pic_qp_c = 3; - break; - case 4: - p_pic_qp_c = 4; - break; - case 5: - p_pic_qp_c = 5; - break; - case 6: - p_pic_qp_c = 6; - break; - case 7: - p_pic_qp_c = 7; - break; - case 8: - p_pic_qp_c = 8; - break; - case 9: - p_pic_qp_c = 9; - break; - case 10: - p_pic_qp_c = 10; - break; - case 11: - p_pic_qp_c = 11; - break; - case 12: - p_pic_qp_c = 12; - break; - case 13: - p_pic_qp_c = 13; - break; - case 14: - p_pic_qp_c = 14; - break; - case 15: - p_pic_qp_c = 15; - break; - case 16: - p_pic_qp_c = 16; - break; - case 17: - p_pic_qp_c = 17; - break; - case 18: - p_pic_qp_c = 18; - break; - case 19: - p_pic_qp_c = 19; - break; - case 20: - p_pic_qp_c = 20; - break; - case 21: - p_pic_qp_c = 21; - break; - case 22: - p_pic_qp_c = 22; - break; - case 23: - p_pic_qp_c = 23; - break; - case 24: - p_pic_qp_c = 24; - break; - case 25: - p_pic_qp_c = 25; - break; - case 26: - p_pic_qp_c = 26; - break; - case 27: - p_pic_qp_c = 27; - break; - case 28: - p_pic_qp_c = 28; - break; - case 29: - p_pic_qp_c = 29; - break; - case 30: - p_pic_qp_c = 29; - break; - case 31: - p_pic_qp_c = 30; - break; - case 32: - p_pic_qp_c = 31; - break; - case 33: - p_pic_qp_c = 32; - break; - case 34: - p_pic_qp_c = 32; - break; - case 35: - p_pic_qp_c = 33; - break; - case 36: - p_pic_qp_c = 34; - break; - case 37: - p_pic_qp_c = 34; - break; - case 38: - p_pic_qp_c = 35; - break; - case 39: - p_pic_qp_c = 35; - break; - case 40: - p_pic_qp_c = 36; - break; - case 41: - p_pic_qp_c = 36; - break; - case 42: - p_pic_qp_c = 37; - break; - case 43: - p_pic_qp_c = 37; - break; - case 44: - p_pic_qp_c = 37; - break; - case 45: - p_pic_qp_c = 38; - break; - case 46: - p_pic_qp_c = 38; - break; - case 47: - p_pic_qp_c = 38; - break; - case 48: - p_pic_qp_c = 39; - break; - case 49: - p_pic_qp_c = 39; - break; - case 50: - p_pic_qp_c = 39; - break; - default: - p_pic_qp_c = 39; - break; - } - WRITE_HREG(HCODEC_QDCT_Q_QUANT_I, - (i_pic_qp_c << 22) | - (i_pic_qp << 16) | - ((i_pic_qp_c % 6) << 12) | - ((i_pic_qp_c / 6) << 8) | - ((i_pic_qp % 6) << 4) | - ((i_pic_qp / 6) << 0)); - - WRITE_HREG(HCODEC_QDCT_Q_QUANT_P, - (p_pic_qp_c << 22) | - (p_pic_qp << 16) | - ((p_pic_qp_c % 6) << 12) | - ((p_pic_qp_c / 6) << 8) | - ((p_pic_qp % 6) << 4) | - ((p_pic_qp / 6) << 0)); - -#ifdef ENABLE_IGNORE_FUNCTION - WRITE_HREG(HCODEC_IGNORE_CONFIG, - (1 << 31) | /* ignore_lac_coeff_en */ - (1 << 26) | /* ignore_lac_coeff_else (<1) */ - (1 << 21) | /* ignore_lac_coeff_2 (<1) */ - (2 << 16) | /* ignore_lac_coeff_1 (<2) */ - (1 << 15) | /* ignore_cac_coeff_en */ - (1 << 10) | /* ignore_cac_coeff_else (<1) */ - (1 << 5) | /* ignore_cac_coeff_2 (<1) */ - (3 << 0)); /* ignore_cac_coeff_1 (<2) */ - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) - WRITE_HREG(HCODEC_IGNORE_CONFIG_2, - (1 << 31) | /* ignore_t_lac_coeff_en */ - (1 << 26) | /* ignore_t_lac_coeff_else (<1) */ - (2 << 21) | /* ignore_t_lac_coeff_2 (<2) */ - (6 << 16) | /* ignore_t_lac_coeff_1 (<6) */ - (1<<15) | /* ignore_cdc_coeff_en */ - (0<<14) | /* ignore_t_lac_coeff_else_le_3 */ - (1<<13) | /* ignore_t_lac_coeff_else_le_4 */ - (1<<12) | /* ignore_cdc_only_when_empty_cac_inter */ - (1<<11) | /* ignore_cdc_only_when_one_empty_inter */ - /* ignore_cdc_range_max_inter 0-0, 1-1, 2-2, 3-3 */ - (2<<9) | - /* ignore_cdc_abs_max_inter 0-1, 1-2, 2-3, 3-4 */ - (0<<7) | - /* ignore_cdc_only_when_empty_cac_intra */ - (1<<5) | - /* ignore_cdc_only_when_one_empty_intra */ - (1<<4) | - /* ignore_cdc_range_max_intra 0-0, 1-1, 2-2, 3-3 */ - (1<<2) | - /* ignore_cdc_abs_max_intra 0-1, 1-2, 2-3, 3-4 */ - (0<<0)); - else - WRITE_HREG(HCODEC_IGNORE_CONFIG_2, - (1 << 31) | /* ignore_t_lac_coeff_en */ - (1 << 26) | /* ignore_t_lac_coeff_else (<1) */ - (1 << 21) | /* ignore_t_lac_coeff_2 (<1) */ - (5 << 16) | /* ignore_t_lac_coeff_1 (<5) */ - (0 << 0)); -#else - WRITE_HREG(HCODEC_IGNORE_CONFIG, 0); - WRITE_HREG(HCODEC_IGNORE_CONFIG_2, 0); -#endif - - WRITE_HREG(HCODEC_QDCT_MB_CONTROL, - (1 << 9) | /* mb_info_soft_reset */ - (1 << 0)); /* mb read buffer soft reset */ - - WRITE_HREG(HCODEC_QDCT_MB_CONTROL, - (1 << 28) | /* ignore_t_p8x8 */ - (0 << 27) | /* zero_mc_out_null_non_skipped_mb */ - (0 << 26) | /* no_mc_out_null_non_skipped_mb */ - (0 << 25) | /* mc_out_even_skipped_mb */ - (0 << 24) | /* mc_out_wait_cbp_ready */ - (0 << 23) | /* mc_out_wait_mb_type_ready */ - (1 << 29) | /* ie_start_int_enable */ - (1 << 19) | /* i_pred_enable */ - (1 << 20) | /* ie_sub_enable */ - (1 << 18) | /* iq_enable */ - (1 << 17) | /* idct_enable */ - (1 << 14) | /* mb_pause_enable */ - (1 << 13) | /* q_enable */ - (1 << 12) | /* dct_enable */ - (1 << 10) | /* mb_info_en */ - (0 << 3) | /* endian */ - (0 << 1) | /* mb_read_en */ - (0 << 0)); /* soft reset */ - - WRITE_HREG(HCODEC_SAD_CONTROL, - (0 << 3) | /* ie_result_buff_enable */ - (1 << 2) | /* ie_result_buff_soft_reset */ - (0 << 1) | /* sad_enable */ - (1 << 0)); /* sad soft reset */ - WRITE_HREG(HCODEC_IE_RESULT_BUFFER, 0); - - WRITE_HREG(HCODEC_SAD_CONTROL, - (1 << 3) | /* ie_result_buff_enable */ - (0 << 2) | /* ie_result_buff_soft_reset */ - (1 << 1) | /* sad_enable */ - (0 << 0)); /* sad soft reset */ - - WRITE_HREG(HCODEC_IE_CONTROL, - (1 << 30) | /* active_ul_block */ - (0 << 1) | /* ie_enable */ - (1 << 0)); /* ie soft reset */ - - WRITE_HREG(HCODEC_IE_CONTROL, - (1 << 30) | /* active_ul_block */ - (0 << 1) | /* ie_enable */ - (0 << 0)); /* ie soft reset */ - - WRITE_HREG(HCODEC_ME_SKIP_LINE, - (8 << 24) | /* step_3_skip_line */ - (8 << 18) | /* step_2_skip_line */ - (2 << 12) | /* step_1_skip_line */ - (0 << 6) | /* step_0_skip_line */ - (0 << 0)); - - WRITE_HREG(HCODEC_ME_MV_MERGE_CTL, me_mv_merge_ctl); - WRITE_HREG(HCODEC_ME_STEP0_CLOSE_MV, me_step0_close_mv); - WRITE_HREG(HCODEC_ME_SAD_ENOUGH_01, me_sad_enough_01); - WRITE_HREG(HCODEC_ME_SAD_ENOUGH_23, me_sad_enough_23); - WRITE_HREG(HCODEC_ME_F_SKIP_SAD, me_f_skip_sad); - WRITE_HREG(HCODEC_ME_F_SKIP_WEIGHT, me_f_skip_weight); - WRITE_HREG(HCODEC_ME_MV_WEIGHT_01, me_mv_weight_01); - WRITE_HREG(HCODEC_ME_MV_WEIGHT_23, me_mv_weight_23); - WRITE_HREG(HCODEC_ME_SAD_RANGE_INC, me_sad_range_inc); - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) { - WRITE_HREG(HCODEC_V5_SIMPLE_MB_CTL, 0); - WRITE_HREG(HCODEC_V5_SIMPLE_MB_CTL, - (v5_use_small_diff_cnt << 7) | - (v5_simple_mb_inter_all_en << 6) | - (v5_simple_mb_inter_8x8_en << 5) | - (v5_simple_mb_inter_16_8_en << 4) | - (v5_simple_mb_inter_16x16_en << 3) | - (v5_simple_mb_intra_en << 2) | - (v5_simple_mb_C_en << 1) | - (v5_simple_mb_Y_en << 0)); - WRITE_HREG(HCODEC_V5_MB_DIFF_SUM, 0); - WRITE_HREG(HCODEC_V5_SMALL_DIFF_CNT, - (v5_small_diff_C<<16) | - (v5_small_diff_Y<<0)); - WRITE_HREG(HCODEC_V5_SIMPLE_MB_DQUANT, - v5_simple_dq_setting); - WRITE_HREG(HCODEC_V5_SIMPLE_MB_ME_WEIGHT, - v5_simple_me_weight_setting); - /* txlx can remove it */ - WRITE_HREG(HCODEC_QDCT_CONFIG, 1 << 0); - } - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - WRITE_HREG(HCODEC_V4_FORCE_SKIP_CFG, - (i_pic_qp << 26) | /* v4_force_q_r_intra */ - (i_pic_qp << 20) | /* v4_force_q_r_inter */ - (0 << 19) | /* v4_force_q_y_enable */ - (5 << 16) | /* v4_force_qr_y */ - (6 << 12) | /* v4_force_qp_y */ - (0 << 0)); /* v4_force_skip_sad */ - - /* V3 Force skip */ - WRITE_HREG(HCODEC_V3_SKIP_CONTROL, - (1 << 31) | /* v3_skip_enable */ - (0 << 30) | /* v3_step_1_weight_enable */ - (1 << 28) | /* v3_mv_sad_weight_enable */ - (1 << 27) | /* v3_ipred_type_enable */ - (V3_FORCE_SKIP_SAD_1 << 12) | - (V3_FORCE_SKIP_SAD_0 << 0)); - WRITE_HREG(HCODEC_V3_SKIP_WEIGHT, - (V3_SKIP_WEIGHT_1 << 16) | - (V3_SKIP_WEIGHT_0 << 0)); - WRITE_HREG(HCODEC_V3_L1_SKIP_MAX_SAD, - (V3_LEVEL_1_F_SKIP_MAX_SAD << 16) | - (V3_LEVEL_1_SKIP_MAX_SAD << 0)); - WRITE_HREG(HCODEC_V3_L2_SKIP_WEIGHT, - (V3_FORCE_SKIP_SAD_2 << 16) | - (V3_SKIP_WEIGHT_2 << 0)); - if (request != NULL) { - unsigned int off1, off2; - off1 = V3_IE_F_ZERO_SAD_I4 - I4MB_WEIGHT_OFFSET; - off2 = V3_IE_F_ZERO_SAD_I16 - - I16MB_WEIGHT_OFFSET; - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0, - ((request->i16_weight + off2) << 16) | - ((request->i4_weight + off1) << 0)); - off1 = V3_ME_F_ZERO_SAD - ME_WEIGHT_OFFSET; - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1, - (0 << 25) | - /* v3_no_ver_when_top_zero_en */ - (0 << 24) | - /* v3_no_hor_when_left_zero_en */ - (3 << 16) | /* type_hor break */ - ((request->me_weight + off1) << 0)); - } else { - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0, - (V3_IE_F_ZERO_SAD_I16 << 16) | - (V3_IE_F_ZERO_SAD_I4 << 0)); - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1, - (0 << 25) | - /* v3_no_ver_when_top_zero_en */ - (0 << 24) | - /* v3_no_hor_when_left_zero_en */ - (3 << 16) | /* type_hor break */ - (V3_ME_F_ZERO_SAD << 0)); - } - } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - /* V3 Force skip */ - WRITE_HREG(HCODEC_V3_SKIP_CONTROL, - (1 << 31) | /* v3_skip_enable */ - (0 << 30) | /* v3_step_1_weight_enable */ - (1 << 28) | /* v3_mv_sad_weight_enable */ - (1 << 27) | /* v3_ipred_type_enable */ - (0 << 12) | /* V3_FORCE_SKIP_SAD_1 */ - (0 << 0)); /* V3_FORCE_SKIP_SAD_0 */ - WRITE_HREG(HCODEC_V3_SKIP_WEIGHT, - (V3_SKIP_WEIGHT_1 << 16) | - (V3_SKIP_WEIGHT_0 << 0)); - WRITE_HREG(HCODEC_V3_L1_SKIP_MAX_SAD, - (V3_LEVEL_1_F_SKIP_MAX_SAD << 16) | - (V3_LEVEL_1_SKIP_MAX_SAD << 0)); - WRITE_HREG(HCODEC_V3_L2_SKIP_WEIGHT, - (0 << 16) | /* V3_FORCE_SKIP_SAD_2 */ - (V3_SKIP_WEIGHT_2 << 0)); - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0, - (0 << 16) | /* V3_IE_F_ZERO_SAD_I16 */ - (0 << 0)); /* V3_IE_F_ZERO_SAD_I4 */ - WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1, - (0 << 25) | /* v3_no_ver_when_top_zero_en */ - (0 << 24) | /* v3_no_hor_when_left_zero_en */ - (3 << 16) | /* type_hor break */ - (0 << 0)); /* V3_ME_F_ZERO_SAD */ - } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - int i; - /* MV SAD Table */ - for (i = 0; i < 64; i++) - WRITE_HREG(HCODEC_V3_MV_SAD_TABLE, - v3_mv_sad[i]); - - /* IE PRED SAD Table*/ - WRITE_HREG(HCODEC_V3_IPRED_TYPE_WEIGHT_0, - (C_ipred_weight_H << 24) | - (C_ipred_weight_V << 16) | - (I4_ipred_weight_else << 8) | - (I4_ipred_weight_most << 0)); - WRITE_HREG(HCODEC_V3_IPRED_TYPE_WEIGHT_1, - (I16_ipred_weight_DC << 24) | - (I16_ipred_weight_H << 16) | - (I16_ipred_weight_V << 8) | - (C_ipred_weight_DC << 0)); - WRITE_HREG(HCODEC_V3_LEFT_SMALL_MAX_SAD, - (v3_left_small_max_me_sad << 16) | - (v3_left_small_max_ie_sad << 0)); - } - WRITE_HREG(HCODEC_IE_DATA_FEED_BUFF_INFO, 0); - - WRITE_HREG(HCODEC_CURR_CANVAS_CTRL, 0); - data32 = READ_HREG(HCODEC_VLC_CONFIG); - data32 = data32 | (1 << 0); /* set pop_coeff_even_all_zero */ - WRITE_HREG(HCODEC_VLC_CONFIG, data32); - - WRITE_HREG(INFO_DUMP_START_ADDR, - wq->mem.dump_info_ddr_start_addr); - - /* clear mailbox interrupt */ - WRITE_HREG(HCODEC_IRQ_MBOX_CLR, 1); - - /* enable mailbox interrupt */ - WRITE_HREG(HCODEC_IRQ_MBOX_MASK, 1); -} - -void amvenc_reset(void) -{ - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - WRITE_VREG(DOS_SW_RESET1, - (1 << 2) | (1 << 6) | - (1 << 7) | (1 << 8) | - (1 << 14) | (1 << 16) | - (1 << 17)); - WRITE_VREG(DOS_SW_RESET1, 0); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); -} - -void amvenc_start(void) -{ - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - WRITE_VREG(DOS_SW_RESET1, - (1 << 12) | (1 << 11)); - WRITE_VREG(DOS_SW_RESET1, 0); - - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - - WRITE_HREG(HCODEC_MPSR, 0x0001); -} - -void amvenc_stop(void) -{ - ulong timeout = jiffies + HZ; - - WRITE_HREG(HCODEC_MPSR, 0); - WRITE_HREG(HCODEC_CPSR, 0); - while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) { - if (time_after(jiffies, timeout)) - break; - } - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - - WRITE_VREG(DOS_SW_RESET1, - (1 << 12) | (1 << 11) | - (1 << 2) | (1 << 6) | - (1 << 7) | (1 << 8) | - (1 << 14) | (1 << 16) | - (1 << 17)); - - WRITE_VREG(DOS_SW_RESET1, 0); - - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); - READ_VREG(DOS_SW_RESET1); -} - -static void __iomem *mc_addr; -static u32 mc_addr_map; -#define MC_SIZE (4096 * 8) -s32 amvenc_loadmc(const char *p, struct encode_wq_s *wq) -{ - ulong timeout; - s32 ret = 0; - - /* use static mempry*/ - if (mc_addr == NULL) { - mc_addr = kmalloc(MC_SIZE, GFP_KERNEL); - if (!mc_addr) { - enc_pr(LOG_ERROR, "avc loadmc iomap mc addr error.\n"); - return -ENOMEM; - } - } - - enc_pr(LOG_ALL, "avc encode ucode name is %s\n", p); - ret = get_decoder_firmware_data(VFORMAT_H264_ENC, p, - (u8 *)mc_addr, MC_SIZE); - if (ret < 0) { - enc_pr(LOG_ERROR, - "avc microcode fail ret=%d, name: %s, wq:%p.\n", - ret, p, (void *)wq); - } - - mc_addr_map = dma_map_single( - &encode_manager.this_pdev->dev, - mc_addr, MC_SIZE, DMA_TO_DEVICE); - - /* mc_addr_map = wq->mem.assit_buffer_offset; */ - /* mc_addr = ioremap_wc(mc_addr_map, MC_SIZE); */ - /* memcpy(mc_addr, p, MC_SIZE); */ - enc_pr(LOG_ALL, "address 0 is 0x%x\n", *((u32 *)mc_addr)); - enc_pr(LOG_ALL, "address 1 is 0x%x\n", *((u32 *)mc_addr + 1)); - enc_pr(LOG_ALL, "address 2 is 0x%x\n", *((u32 *)mc_addr + 2)); - enc_pr(LOG_ALL, "address 3 is 0x%x\n", *((u32 *)mc_addr + 3)); - WRITE_HREG(HCODEC_MPSR, 0); - WRITE_HREG(HCODEC_CPSR, 0); - - /* Read CBUS register for timing */ - timeout = READ_HREG(HCODEC_MPSR); - timeout = READ_HREG(HCODEC_MPSR); - - timeout = jiffies + HZ; - - WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map); - WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000); - WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16))); - - while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) { - if (time_before(jiffies, timeout)) - schedule(); - else { - enc_pr(LOG_ERROR, "hcodec load mc error\n"); - ret = -EBUSY; - break; - } - } - dma_unmap_single( - &encode_manager.this_pdev->dev, - mc_addr_map, MC_SIZE, DMA_TO_DEVICE); - return ret; -} - -const u32 fix_mc[] __aligned(8) = { - 0x0809c05a, 0x06696000, 0x0c780000, 0x00000000 -}; - - -/* - * DOS top level register access fix. - * When hcodec is running, a protocol register HCODEC_CCPU_INTR_MSK - * is set to make hcodec access one CBUS out of DOS domain once - * to work around a HW bug for 4k2k dual decoder implementation. - * If hcodec is not running, then a ucode is loaded and executed - * instead. - */ -void amvenc_dos_top_reg_fix(void) -{ - bool hcodec_on; - ulong flags; - - spin_lock_irqsave(&lock, flags); - - hcodec_on = vdec_on(VDEC_HCODEC); - - if ((hcodec_on) && (READ_VREG(HCODEC_MPSR) & 1)) { - WRITE_HREG(HCODEC_CCPU_INTR_MSK, 1); - spin_unlock_irqrestore(&lock, flags); - return; - } - - if (!hcodec_on) - vdec_poweron(VDEC_HCODEC); - - amhcodec_loadmc(fix_mc); - - amhcodec_start(); - - udelay(1000); - - amhcodec_stop(); - - if (!hcodec_on) - vdec_poweroff(VDEC_HCODEC); - - spin_unlock_irqrestore(&lock, flags); -} - -bool amvenc_avc_on(void) -{ - bool hcodec_on; - ulong flags; - - spin_lock_irqsave(&lock, flags); - - hcodec_on = vdec_on(VDEC_HCODEC); - hcodec_on &= (encode_manager.wq_count > 0); - - spin_unlock_irqrestore(&lock, flags); - return hcodec_on; -} - -static s32 avc_poweron(u32 clock) -{ - ulong flags; - u32 data32; - - data32 = 0; - - amports_switch_gate("vdec", 1); - - spin_lock_irqsave(&lock, flags); - - WRITE_AOREG(AO_RTI_PWR_CNTL_REG0, - (READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18))); - udelay(10); - /* Powerup HCODEC */ - /* [1:0] HCODEC */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - (READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & (~0x3))); - udelay(10); - - WRITE_VREG(DOS_SW_RESET1, 0xffffffff); - WRITE_VREG(DOS_SW_RESET1, 0); - - /* Enable Dos internal clock gating */ - hvdec_clock_enable(clock); - - /* Powerup HCODEC memories */ - WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0); - - /* Remove HCODEC ISO */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - (READ_AOREG(AO_RTI_GEN_PWR_ISO0) & (~0x30))); - udelay(10); - /* Disable auto-clock gate */ - WRITE_VREG(DOS_GEN_CTRL0, - (READ_VREG(DOS_GEN_CTRL0) | 0x1)); - WRITE_VREG(DOS_GEN_CTRL0, - (READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE)); - - spin_unlock_irqrestore(&lock, flags); - - mdelay(10); - return 0; -} - -static s32 avc_poweroff(void) -{ - ulong flags; - - spin_lock_irqsave(&lock, flags); - - /* enable HCODEC isolation */ - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | 0x30); - /* power off HCODEC memories */ - WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL); - - /* disable HCODEC clock */ - hvdec_clock_disable(); - - /* HCODEC power off */ - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 0x3); - - spin_unlock_irqrestore(&lock, flags); - - /* release DOS clk81 clock gating */ - amports_switch_gate("vdec", 0); - return 0; -} - -static s32 reload_mc(struct encode_wq_s *wq) -{ - const char *p = select_ucode(encode_manager.ucode_index); - - amvenc_stop(); - - WRITE_VREG(DOS_SW_RESET1, 0xffffffff); - WRITE_VREG(DOS_SW_RESET1, 0); - - udelay(10); - - WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32); - enc_pr(LOG_INFO, "reload microcode\n"); - - if (amvenc_loadmc(p, wq) < 0) - return -EBUSY; - return 0; -} - -static void encode_isr_tasklet(ulong data) -{ - struct encode_manager_s *manager = (struct encode_manager_s *)data; - enc_pr(LOG_INFO, "encoder is done %d\n", manager->encode_hw_status); - if (((manager->encode_hw_status == ENCODER_IDR_DONE) - || (manager->encode_hw_status == ENCODER_NON_IDR_DONE) - || (manager->encode_hw_status == ENCODER_SEQUENCE_DONE) - || (manager->encode_hw_status == ENCODER_PICTURE_DONE)) - && (manager->process_irq)) { - wake_up_interruptible(&manager->event.hw_complete); - } -} - -/* irq function */ -static irqreturn_t enc_isr(s32 irq_number, void *para) -{ - struct encode_manager_s *manager = (struct encode_manager_s *)para; - WRITE_HREG(HCODEC_IRQ_MBOX_CLR, 1); - - manager->encode_hw_status = READ_HREG(ENCODER_STATUS); - if ((manager->encode_hw_status == ENCODER_IDR_DONE) - || (manager->encode_hw_status == ENCODER_NON_IDR_DONE) - || (manager->encode_hw_status == ENCODER_SEQUENCE_DONE) - || (manager->encode_hw_status == ENCODER_PICTURE_DONE)) { - enc_pr(LOG_ALL, "encoder stage is %d\n", - manager->encode_hw_status); - } - - if (((manager->encode_hw_status == ENCODER_IDR_DONE) - || (manager->encode_hw_status == ENCODER_NON_IDR_DONE) - || (manager->encode_hw_status == ENCODER_SEQUENCE_DONE) - || (manager->encode_hw_status == ENCODER_PICTURE_DONE)) - && (!manager->process_irq)) { - manager->process_irq = true; - if (manager->encode_hw_status != ENCODER_SEQUENCE_DONE) - manager->need_reset = true; - tasklet_schedule(&manager->encode_tasklet); - } - return IRQ_HANDLED; -} - -static s32 convert_request(struct encode_wq_s *wq, u32 *cmd_info) -{ - int i = 0; - u8 *ptr; - u32 data_offset; - u32 cmd = cmd_info[0]; - if (!wq) - return -1; - memset(&wq->request, 0, sizeof(struct encode_request_s)); - wq->request.me_weight = ME_WEIGHT_OFFSET; - wq->request.i4_weight = I4MB_WEIGHT_OFFSET; - wq->request.i16_weight = I16MB_WEIGHT_OFFSET; - - if (cmd == ENCODER_SEQUENCE) { - wq->request.cmd = cmd; - wq->request.ucode_mode = cmd_info[1]; - wq->request.quant = cmd_info[2]; - wq->request.flush_flag = cmd_info[3]; - wq->request.timeout = cmd_info[4]; - wq->request.timeout = 5000; /* 5000 ms */ - } else if ((cmd == ENCODER_IDR) || (cmd == ENCODER_NON_IDR)) { - wq->request.cmd = cmd; - wq->request.ucode_mode = cmd_info[1]; - wq->request.type = cmd_info[2]; - wq->request.fmt = cmd_info[3]; - wq->request.src = cmd_info[4]; - wq->request.framesize = cmd_info[5]; - wq->request.quant = cmd_info[6]; - wq->request.flush_flag = cmd_info[7]; - wq->request.timeout = cmd_info[8]; - wq->request.crop_top = cmd_info[9]; - wq->request.crop_bottom = cmd_info[10]; - wq->request.crop_left = cmd_info[11]; - wq->request.crop_right = cmd_info[12]; - wq->request.src_w = cmd_info[13]; - wq->request.src_h = cmd_info[14]; - wq->request.scale_enable = cmd_info[15]; - wq->request.nr_mode = - (nr_mode > 0) ? nr_mode : cmd_info[16]; - if (cmd == ENCODER_IDR) - wq->request.nr_mode = 0; - - data_offset = 17 + - (sizeof(wq->quant_tbl_i4) - + sizeof(wq->quant_tbl_i16) - + sizeof(wq->quant_tbl_me)) / 4; - - if (wq->request.quant == ADJUSTED_QP_FLAG) { - ptr = (u8 *) &cmd_info[17]; - memcpy(wq->quant_tbl_i4, ptr, - sizeof(wq->quant_tbl_i4)); - ptr += sizeof(wq->quant_tbl_i4); - memcpy(wq->quant_tbl_i16, ptr, - sizeof(wq->quant_tbl_i16)); - ptr += sizeof(wq->quant_tbl_i16); - memcpy(wq->quant_tbl_me, ptr, - sizeof(wq->quant_tbl_me)); - wq->request.i4_weight -= - cmd_info[data_offset++]; - wq->request.i16_weight -= - cmd_info[data_offset++]; - wq->request.me_weight -= - cmd_info[data_offset++]; - if (qp_table_debug) { - u8 *qp_tb = (u8 *)(&wq->quant_tbl_i4[0]); - for (i = 0; i < 32; i++) { - enc_pr(LOG_INFO, "%d ", *qp_tb); - qp_tb++; - } - enc_pr(LOG_INFO, "\n"); - - qp_tb = (u8 *)(&wq->quant_tbl_i16[0]); - for (i = 0; i < 32; i++) { - enc_pr(LOG_INFO, "%d ", *qp_tb); - qp_tb++; - } - enc_pr(LOG_INFO, "\n"); - - qp_tb = (u8 *)(&wq->quant_tbl_me[0]); - for (i = 0; i < 32; i++) { - enc_pr(LOG_INFO, "%d ", *qp_tb); - qp_tb++; - } - enc_pr(LOG_INFO, "\n"); - } - } else { - memset(wq->quant_tbl_me, wq->request.quant, - sizeof(wq->quant_tbl_me)); - memset(wq->quant_tbl_i4, wq->request.quant, - sizeof(wq->quant_tbl_i4)); - memset(wq->quant_tbl_i16, wq->request.quant, - sizeof(wq->quant_tbl_i16)); - data_offset += 3; - } -#ifdef H264_ENC_CBR - wq->cbr_info.block_w = cmd_info[data_offset++]; - wq->cbr_info.block_h = cmd_info[data_offset++]; - wq->cbr_info.long_th = cmd_info[data_offset++]; - wq->cbr_info.start_tbl_id = cmd_info[data_offset++]; - wq->cbr_info.short_shift = CBR_SHORT_SHIFT; - wq->cbr_info.long_mb_num = CBR_LONG_MB_NUM; -#endif - } else { - enc_pr(LOG_ERROR, "error cmd = %d, wq: %p.\n", - cmd, (void *)wq); - return -1; - } - wq->request.parent = wq; - return 0; -} - -void amvenc_avc_start_cmd(struct encode_wq_s *wq, - struct encode_request_s *request) -{ - u32 reload_flag = 0; - if (request->ucode_mode != encode_manager.ucode_index) { - encode_manager.ucode_index = request->ucode_mode; - if (reload_mc(wq)) { - enc_pr(LOG_ERROR, - "reload mc fail, wq:%p\n", (void *)wq); - return; - } - reload_flag = 1; - encode_manager.need_reset = true; - } - - wq->hw_status = 0; - wq->output_size = 0; - wq->ucode_index = encode_manager.ucode_index; - - ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT; - if (encode_manager.need_reset) { - encode_manager.need_reset = false; - encode_manager.encode_hw_status = ENCODER_IDLE; - amvenc_reset(); - avc_canvas_init(wq); - avc_init_encoder(wq, - (request->cmd == ENCODER_IDR) ? true : false); - avc_init_input_buffer(wq); - avc_init_output_buffer(wq); - avc_prot_init(wq, request, request->quant, - (request->cmd == ENCODER_IDR) ? true : false); - avc_init_assit_buffer(wq); - enc_pr(LOG_INFO, - "begin to new frame, request->cmd: %d, ucode mode: %d, wq:%p.\n", - request->cmd, request->ucode_mode, (void *)wq); - } - if ((request->cmd == ENCODER_IDR) || - (request->cmd == ENCODER_NON_IDR)) { - avc_init_dblk_buffer(wq->mem.dblk_buf_canvas); - avc_init_reference_buffer(wq->mem.ref_buf_canvas); - } - if ((request->cmd == ENCODER_IDR) || - (request->cmd == ENCODER_NON_IDR)) - set_input_format(wq, request); - if (request->cmd == ENCODER_IDR) - ie_me_mb_type = HENC_MB_Type_I4MB; - else if (request->cmd == ENCODER_NON_IDR) - ie_me_mb_type = - (HENC_SKIP_RUN_AUTO << 16) | - (HENC_MB_Type_AUTO << 4) | - (HENC_MB_Type_AUTO << 0); - else - ie_me_mb_type = 0; - avc_init_ie_me_parameter(wq, request->quant); - -#ifdef MULTI_SLICE_MC - if (fixed_slice_cfg) - WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg); - else if (wq->pic.rows_per_slice != - (wq->pic.encoder_height + 15) >> 4) { - u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4; - mb_per_slice = mb_per_slice * wq->pic.rows_per_slice; - WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice); - } else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#endif - - encode_manager.encode_hw_status = request->cmd; - wq->hw_status = request->cmd; - WRITE_HREG(ENCODER_STATUS , request->cmd); - if ((request->cmd == ENCODER_IDR) - || (request->cmd == ENCODER_NON_IDR) - || (request->cmd == ENCODER_SEQUENCE) - || (request->cmd == ENCODER_PICTURE)) - encode_manager.process_irq = false; - - if (reload_flag) - amvenc_start(); - enc_pr(LOG_ALL, "amvenc_avc_start cmd, wq:%p.\n", (void *)wq); -} - -static void dma_flush(u32 buf_start , u32 buf_size) -{ - if ((buf_start == 0) || (buf_size == 0)) - return; - dma_sync_single_for_device( - &encode_manager.this_pdev->dev, buf_start, - buf_size, DMA_TO_DEVICE); -} - -static void cache_flush(u32 buf_start , u32 buf_size) -{ - if ((buf_start == 0) || (buf_size == 0)) - return; - dma_sync_single_for_cpu( - &encode_manager.this_pdev->dev, buf_start, - buf_size, DMA_FROM_DEVICE); -} - -static u32 getbuffer(struct encode_wq_s *wq, u32 type) -{ - u32 ret = 0; - - switch (type) { - case ENCODER_BUFFER_INPUT: - ret = wq->mem.dct_buff_start_addr; - break; - case ENCODER_BUFFER_REF0: - ret = wq->mem.dct_buff_start_addr + - wq->mem.bufspec.dec0_y.buf_start; - break; - case ENCODER_BUFFER_REF1: - ret = wq->mem.dct_buff_start_addr + - wq->mem.bufspec.dec1_y.buf_start; - break; - case ENCODER_BUFFER_OUTPUT: - ret = wq->mem.BitstreamStart; - break; - case ENCODER_BUFFER_DUMP: - ret = wq->mem.dump_info_ddr_start_addr; - break; - case ENCODER_BUFFER_CBR: - ret = wq->mem.cbr_info_ddr_start_addr; - break; - default: - break; - } - return ret; -} - -s32 amvenc_avc_start(struct encode_wq_s *wq, u32 clock) -{ - const char *p = select_ucode(encode_manager.ucode_index); - - avc_poweron(clock); - avc_canvas_init(wq); - - WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32); - - if (amvenc_loadmc(p, wq) < 0) - return -EBUSY; - - encode_manager.need_reset = true; - encode_manager.process_irq = false; - encode_manager.encode_hw_status = ENCODER_IDLE; - amvenc_reset(); - avc_init_encoder(wq, true); - avc_init_input_buffer(wq); /* dct buffer setting */ - avc_init_output_buffer(wq); /* output stream buffer */ - - ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT; - avc_prot_init(wq, NULL, wq->pic.init_qppicture, true); - if (request_irq(encode_manager.irq_num, enc_isr, IRQF_SHARED, - "enc-irq", (void *)&encode_manager) == 0) - encode_manager.irq_requested = true; - else - encode_manager.irq_requested = false; - - /* decoder buffer , need set before each frame start */ - avc_init_dblk_buffer(wq->mem.dblk_buf_canvas); - /* reference buffer , need set before each frame start */ - avc_init_reference_buffer(wq->mem.ref_buf_canvas); - avc_init_assit_buffer(wq); /* assitant buffer for microcode */ - ie_me_mb_type = 0; - avc_init_ie_me_parameter(wq, wq->pic.init_qppicture); - WRITE_HREG(ENCODER_STATUS , ENCODER_IDLE); - -#ifdef MULTI_SLICE_MC - if (fixed_slice_cfg) - WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg); - else if (wq->pic.rows_per_slice != - (wq->pic.encoder_height + 15) >> 4) { - u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4; - mb_per_slice = mb_per_slice * wq->pic.rows_per_slice; - WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice); - } else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#else - WRITE_HREG(FIXED_SLICE_CFG, 0); -#endif - amvenc_start(); - return 0; -} - -void amvenc_avc_stop(void) -{ - if ((encode_manager.irq_num >= 0) && - (encode_manager.irq_requested == true)) { - free_irq(encode_manager.irq_num, &encode_manager); - encode_manager.irq_requested = false; - } - amvenc_stop(); - avc_poweroff(); -} - -static s32 avc_init(struct encode_wq_s *wq) -{ - s32 r = 0; - - encode_manager.ucode_index = wq->ucode_index; - r = amvenc_avc_start(wq, clock_level); - - enc_pr(LOG_DEBUG, - "init avc encode. microcode %d, ret=%d, wq:%p.\n", - encode_manager.ucode_index, r, (void *)wq); - return 0; -} - -static s32 amvenc_avc_light_reset(struct encode_wq_s *wq, u32 value) -{ - s32 r = 0; - - amvenc_avc_stop(); - - mdelay(value); - - encode_manager.ucode_index = UCODE_MODE_FULL; - r = amvenc_avc_start(wq, clock_level); - - enc_pr(LOG_DEBUG, - "amvenc_avc_light_reset finish, wq:%p. ret=%d\n", - (void *)wq, r); - return r; -} - -#ifdef CONFIG_CMA -static u32 checkCMA(void) -{ - u32 ret; - if (encode_manager.cma_pool_size > 0) { - ret = encode_manager.cma_pool_size; - ret = ret / MIN_SIZE; - } else - ret = 0; - return ret; -} -#endif - -/* file operation */ -static s32 amvenc_avc_open(struct inode *inode, struct file *file) -{ - s32 r = 0; - struct encode_wq_s *wq = NULL; - file->private_data = NULL; - enc_pr(LOG_DEBUG, "avc open\n"); -#ifdef CONFIG_AM_JPEG_ENCODER - if (jpegenc_on() == true) { - enc_pr(LOG_ERROR, - "hcodec in use for JPEG Encode now.\n"); - return -EBUSY; - } -#endif - -#ifdef CONFIG_CMA - if ((encode_manager.use_reserve == false) && - (encode_manager.check_cma == false)) { - encode_manager.max_instance = checkCMA(); - if (encode_manager.max_instance > 0) { - enc_pr(LOG_DEBUG, - "amvenc_avc check CMA pool sucess, max instance: %d.\n", - encode_manager.max_instance); - } else { - enc_pr(LOG_ERROR, - "amvenc_avc CMA pool too small.\n"); - } - encode_manager.check_cma = true; - } -#endif - - wq = create_encode_work_queue(); - if (wq == NULL) { - enc_pr(LOG_ERROR, "amvenc_avc create instance fail.\n"); - return -EBUSY; - } - -#ifdef CONFIG_CMA - if (encode_manager.use_reserve == false) { - wq->mem.buf_start = codec_mm_alloc_for_dma(ENCODE_NAME, - MIN_SIZE >> PAGE_SHIFT, 0, - CODEC_MM_FLAGS_CPU); - if (wq->mem.buf_start) { - wq->mem.buf_size = MIN_SIZE; - enc_pr(LOG_DEBUG, - "allocating phys 0x%x, size %dk, wq:%p.\n", - wq->mem.buf_start, - wq->mem.buf_size >> 10, (void *)wq); - } else { - enc_pr(LOG_ERROR, - "CMA failed to allocate dma buffer for %s, wq:%p.\n", - encode_manager.this_pdev->name, - (void *)wq); - destroy_encode_work_queue(wq); - return -ENOMEM; - } - } -#endif - - if (wq->mem.buf_start == 0 || - wq->mem.buf_size < MIN_SIZE) { - enc_pr(LOG_ERROR, - "alloc mem failed, start: 0x%x, size:0x%x, wq:%p.\n", - wq->mem.buf_start, - wq->mem.buf_size, (void *)wq); - destroy_encode_work_queue(wq); - return -ENOMEM; - } - - memcpy(&wq->mem.bufspec, &amvenc_buffspec[0], - sizeof(struct BuffInfo_s)); - - enc_pr(LOG_DEBUG, - "amvenc_avc memory config sucess, buff start:0x%x, size is 0x%x, wq:%p.\n", - wq->mem.buf_start, wq->mem.buf_size, (void *)wq); - - file->private_data = (void *) wq; - return r; -} - -static s32 amvenc_avc_release(struct inode *inode, struct file *file) -{ - struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data; - if (wq) { - enc_pr(LOG_DEBUG, "avc release, wq:%p\n", (void *)wq); - destroy_encode_work_queue(wq); - } - return 0; -} - -static long amvenc_avc_ioctl(struct file *file, u32 cmd, ulong arg) -{ - long r = 0; - u32 amrisc_cmd = 0; - struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data; -#define MAX_ADDR_INFO_SIZE 50 - u32 addr_info[MAX_ADDR_INFO_SIZE + 4]; - ulong argV; - u32 buf_start; - s32 canvas = -1; - struct canvas_s dst; - switch (cmd) { - case AMVENC_AVC_IOC_GET_ADDR: - if ((wq->mem.ref_buf_canvas & 0xff) == (ENC_CANVAS_OFFSET)) - put_user(1, (u32 *)arg); - else - put_user(2, (u32 *)arg); - break; - case AMVENC_AVC_IOC_INPUT_UPDATE: - break; - case AMVENC_AVC_IOC_NEW_CMD: - if (copy_from_user(addr_info, (void *)arg, - MAX_ADDR_INFO_SIZE * sizeof(u32))) { - enc_pr(LOG_ERROR, - "avc get new cmd error, wq:%p.\n", (void *)wq); - return -1; - } - r = convert_request(wq, addr_info); - if (r == 0) - r = encode_wq_add_request(wq); - if (r) { - enc_pr(LOG_ERROR, - "avc add new request error, wq:%p.\n", - (void *)wq); - } - break; - case AMVENC_AVC_IOC_GET_STAGE: - put_user(wq->hw_status, (u32 *)arg); - break; - case AMVENC_AVC_IOC_GET_OUTPUT_SIZE: - addr_info[0] = wq->output_size; - addr_info[1] = wq->me_weight; - addr_info[2] = wq->i4_weight; - addr_info[3] = wq->i16_weight; - r = copy_to_user((u32 *)arg, - addr_info , 4 * sizeof(u32)); - break; - case AMVENC_AVC_IOC_CONFIG_INIT: - if (copy_from_user(addr_info, (void *)arg, - MAX_ADDR_INFO_SIZE * sizeof(u32))) { - enc_pr(LOG_ERROR, - "avc config init error, wq:%p.\n", (void *)wq); - return -1; - } - wq->ucode_index = UCODE_MODE_FULL; -#ifdef MULTI_SLICE_MC - wq->pic.rows_per_slice = addr_info[1]; - enc_pr(LOG_DEBUG, - "avc init -- rows_per_slice: %d, wq: %p.\n", - wq->pic.rows_per_slice, (void *)wq); -#endif - enc_pr(LOG_DEBUG, - "avc init as mode %d, wq: %p.\n", - wq->ucode_index, (void *)wq); - - if (addr_info[2] > wq->mem.bufspec.max_width || - addr_info[3] > wq->mem.bufspec.max_height) { - enc_pr(LOG_ERROR, - "avc config init- encode size %dx%d is larger than supported (%dx%d). wq:%p.\n", - addr_info[2], addr_info[3], - wq->mem.bufspec.max_width, - wq->mem.bufspec.max_height, (void *)wq); - return -1; - } - wq->pic.encoder_width = addr_info[2]; - wq->pic.encoder_height = addr_info[3]; - if (wq->pic.encoder_width * - wq->pic.encoder_height >= 1280 * 720) - clock_level = 6; - else - clock_level = 5; - avc_buffspec_init(wq); - complete(&encode_manager.event.request_in_com); - addr_info[1] = wq->mem.bufspec.dct.buf_start; - addr_info[2] = wq->mem.bufspec.dct.buf_size; - addr_info[3] = wq->mem.bufspec.bitstream.buf_start; - addr_info[4] = wq->mem.bufspec.bitstream.buf_size; - addr_info[5] = wq->mem.bufspec.scale_buff.buf_start; - addr_info[6] = wq->mem.bufspec.scale_buff.buf_size; - addr_info[7] = wq->mem.bufspec.dump_info.buf_start; - addr_info[8] = wq->mem.bufspec.dump_info.buf_size; - addr_info[9] = wq->mem.bufspec.cbr_info.buf_start; - addr_info[10] = wq->mem.bufspec.cbr_info.buf_size; - r = copy_to_user((u32 *)arg, addr_info , 11*sizeof(u32)); - break; - case AMVENC_AVC_IOC_FLUSH_CACHE: - if (copy_from_user(addr_info, (void *)arg, - MAX_ADDR_INFO_SIZE * sizeof(u32))) { - enc_pr(LOG_ERROR, - "avc flush cache error, wq: %p.\n", (void *)wq); - return -1; - } - buf_start = getbuffer(wq, addr_info[0]); - dma_flush(buf_start + addr_info[1], - addr_info[2] - addr_info[1]); - break; - case AMVENC_AVC_IOC_FLUSH_DMA: - if (copy_from_user(addr_info, (void *)arg, - MAX_ADDR_INFO_SIZE * sizeof(u32))) { - enc_pr(LOG_ERROR, - "avc flush dma error, wq:%p.\n", (void *)wq); - return -1; - } - buf_start = getbuffer(wq, addr_info[0]); - cache_flush(buf_start + addr_info[1], - addr_info[2] - addr_info[1]); - break; - case AMVENC_AVC_IOC_GET_BUFFINFO: - put_user(wq->mem.buf_size, (u32 *)arg); - break; - case AMVENC_AVC_IOC_GET_DEVINFO: - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - /* send the same id as GXTVBB to upper*/ - r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXTVBB, - strlen(AMVENC_DEVINFO_GXTVBB)); - } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) { - r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXTVBB, - strlen(AMVENC_DEVINFO_GXTVBB)); - } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) { - r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXBB, - strlen(AMVENC_DEVINFO_GXBB)); - } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_MG9TV) { - r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_G9, - strlen(AMVENC_DEVINFO_G9)); - } else { - r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_M8, - strlen(AMVENC_DEVINFO_M8)); - } - break; - case AMVENC_AVC_IOC_SUBMIT: - get_user(amrisc_cmd, ((u32 *)arg)); - if (amrisc_cmd == ENCODER_IDR) { - wq->pic.idr_pic_id++; - if (wq->pic.idr_pic_id > 65535) - wq->pic.idr_pic_id = 0; - wq->pic.pic_order_cnt_lsb = 2; - wq->pic.frame_number = 1; - } else if (amrisc_cmd == ENCODER_NON_IDR) { - wq->pic.frame_number++; - wq->pic.pic_order_cnt_lsb += 2; - if (wq->pic.frame_number > 65535) - wq->pic.frame_number = 0; - } - amrisc_cmd = wq->mem.dblk_buf_canvas; - wq->mem.dblk_buf_canvas = wq->mem.ref_buf_canvas; - /* current dblk buffer as next reference buffer */ - wq->mem.ref_buf_canvas = amrisc_cmd; - break; - case AMVENC_AVC_IOC_READ_CANVAS: - get_user(argV, ((u32 *)arg)); - canvas = argV; - if (canvas & 0xff) { - canvas_read(canvas & 0xff, &dst); - addr_info[0] = dst.addr; - if ((canvas & 0xff00) >> 8) - canvas_read((canvas & 0xff00) >> 8, &dst); - if ((canvas & 0xff0000) >> 16) - canvas_read((canvas & 0xff0000) >> 16, &dst); - addr_info[1] = dst.addr - addr_info[0] + - dst.width * dst.height; - } else { - addr_info[0] = 0; - addr_info[1] = 0; - } - dma_flush(dst.addr, dst.width * dst.height * 3 / 2); - r = copy_to_user((u32 *)arg, addr_info , 2 * sizeof(u32)); - break; - case AMVENC_AVC_IOC_MAX_INSTANCE: - put_user(encode_manager.max_instance, (u32 *)arg); - break; - default: - r = -1; - break; - } - return r; -} - -#ifdef CONFIG_COMPAT -static long amvenc_avc_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long args) -{ - unsigned long ret; - - args = (unsigned long)compat_ptr(args); - ret = amvenc_avc_ioctl(filp, cmd, args); - return ret; -} -#endif - -static s32 avc_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct encode_wq_s *wq = (struct encode_wq_s *)filp->private_data; - ulong off = vma->vm_pgoff << PAGE_SHIFT; - ulong vma_size = vma->vm_end - vma->vm_start; - - if (vma_size == 0) { - enc_pr(LOG_ERROR, "vma_size is 0, wq:%p.\n", (void *)wq); - return -EAGAIN; - } - if (!off) - off += wq->mem.buf_start; - enc_pr(LOG_ALL, - "vma_size is %ld , off is %ld, wq:%p.\n", - vma_size , off, (void *)wq); - vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO; - /* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */ - if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - enc_pr(LOG_ERROR, - "set_cached: failed remap_pfn_range, wq:%p.\n", - (void *)wq); - return -EAGAIN; - } - return 0; -} - -static u32 amvenc_avc_poll(struct file *file, poll_table *wait_table) -{ - struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data; - poll_wait(file, &wq->request_complete, wait_table); - - if (atomic_read(&wq->request_ready)) { - atomic_dec(&wq->request_ready); - return POLLIN | POLLRDNORM; - } - return 0; -} - -static const struct file_operations amvenc_avc_fops = { - .owner = THIS_MODULE, - .open = amvenc_avc_open, - .mmap = avc_mmap, - .release = amvenc_avc_release, - .unlocked_ioctl = amvenc_avc_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amvenc_avc_compat_ioctl, -#endif - .poll = amvenc_avc_poll, -}; - -/* work queue function */ -static s32 encode_process_request(struct encode_manager_s *manager, - struct encode_queue_item_s *pitem) -{ - s32 ret = 0; - struct encode_wq_s *wq = pitem->request.parent; - struct encode_request_s *request = &pitem->request; - u32 timeout = (request->timeout == 0) ? - 1 : msecs_to_jiffies(request->timeout); - u32 buf_start = 0; - u32 size = 0; - u32 flush_size = ((wq->pic.encoder_width + 31) >> 5 << 5) * - ((wq->pic.encoder_height + 15) >> 4 << 4) * 3 / 2; - -#ifdef H264_ENC_CBR - if (request->cmd == ENCODER_IDR || request->cmd == ENCODER_NON_IDR) { - if (request->flush_flag & AMVENC_FLUSH_FLAG_CBR - && get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - void *vaddr = - phys_to_virt(wq->mem.cbr_info_ddr_start_addr); - ConvertTable2Risc(vaddr, 0xa00); - buf_start = getbuffer(wq, ENCODER_BUFFER_CBR); - dma_flush(buf_start, wq->mem.cbr_info_ddr_size); - } - } -#endif - -Again: - amvenc_avc_start_cmd(wq, request); - - if (no_timeout) { - wait_event_interruptible(manager->event.hw_complete, - (manager->encode_hw_status == ENCODER_IDR_DONE - || manager->encode_hw_status == ENCODER_NON_IDR_DONE - || manager->encode_hw_status == ENCODER_SEQUENCE_DONE - || manager->encode_hw_status == ENCODER_PICTURE_DONE)); - } else { - wait_event_interruptible_timeout(manager->event.hw_complete, - ((manager->encode_hw_status == ENCODER_IDR_DONE) - || (manager->encode_hw_status == ENCODER_NON_IDR_DONE) - || (manager->encode_hw_status == ENCODER_SEQUENCE_DONE) - || (manager->encode_hw_status == ENCODER_PICTURE_DONE)), - timeout); - } - - if ((request->cmd == ENCODER_SEQUENCE) && - (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)) { - wq->sps_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES); - wq->hw_status = manager->encode_hw_status; - request->cmd = ENCODER_PICTURE; - goto Again; - } else if ((request->cmd == ENCODER_PICTURE) && - (manager->encode_hw_status == ENCODER_PICTURE_DONE)) { - wq->pps_size = - READ_HREG(HCODEC_VLC_TOTAL_BYTES) - wq->sps_size; - wq->hw_status = manager->encode_hw_status; - if (request->flush_flag & AMVENC_FLUSH_FLAG_OUTPUT) { - buf_start = getbuffer(wq, ENCODER_BUFFER_OUTPUT); - cache_flush(buf_start, - wq->sps_size + wq->pps_size); - } - wq->output_size = (wq->sps_size << 16) | wq->pps_size; - } else { - wq->hw_status = manager->encode_hw_status; - if ((manager->encode_hw_status == ENCODER_IDR_DONE) || - (manager->encode_hw_status == ENCODER_NON_IDR_DONE)) { - wq->output_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES); - if (request->flush_flag & AMVENC_FLUSH_FLAG_OUTPUT) { - buf_start = getbuffer(wq, - ENCODER_BUFFER_OUTPUT); - cache_flush(buf_start, wq->output_size); - } - if (request->flush_flag & - AMVENC_FLUSH_FLAG_DUMP) { - buf_start = getbuffer(wq, - ENCODER_BUFFER_DUMP); - size = wq->mem.dump_info_ddr_size; - cache_flush(buf_start, size); - enc_pr(LOG_DEBUG, "CBR flush dump_info done--- "); - } - if (request->flush_flag & - AMVENC_FLUSH_FLAG_REFERENCE) { - u32 ref_id = ENCODER_BUFFER_REF0; - if ((wq->mem.ref_buf_canvas & 0xff) == - (ENC_CANVAS_OFFSET)) - ref_id = ENCODER_BUFFER_REF0; - else - ref_id = ENCODER_BUFFER_REF1; - buf_start = getbuffer(wq, ref_id); - cache_flush(buf_start, flush_size); - } - } else { - manager->encode_hw_status = ENCODER_ERROR; - enc_pr(LOG_DEBUG, "avc encode light reset --- "); - enc_pr(LOG_DEBUG, - "frame type: %s, size: %dx%d, wq: %p\n", - (request->cmd == ENCODER_IDR) ? "IDR" : "P", - wq->pic.encoder_width, - wq->pic.encoder_height, (void *)wq); - enc_pr(LOG_DEBUG, - "mb info: 0x%x, encode status: 0x%x, dct status: 0x%x ", - READ_HREG(HCODEC_VLC_MB_INFO), - READ_HREG(ENCODER_STATUS), - READ_HREG(HCODEC_QDCT_STATUS_CTRL)); - enc_pr(LOG_DEBUG, - "vlc status: 0x%x, me status: 0x%x, risc pc:0x%x, debug:0x%x\n", - READ_HREG(HCODEC_VLC_STATUS_CTRL), - READ_HREG(HCODEC_ME_STATUS), - READ_HREG(HCODEC_MPC_E), - READ_HREG(DEBUG_REG)); - amvenc_avc_light_reset(wq, 30); - } - } - atomic_inc(&wq->request_ready); - wake_up_interruptible(&wq->request_complete); - return ret; -} - -s32 encode_wq_add_request(struct encode_wq_s *wq) -{ - struct encode_queue_item_s *pitem = NULL; - struct list_head *head = NULL; - struct encode_wq_s *tmp = NULL; - bool find = false; - - spin_lock(&encode_manager.event.sem_lock); - - head = &encode_manager.wq; - list_for_each_entry(tmp, head, list) { - if ((wq == tmp) && (wq != NULL)) { - find = true; - break; - } - } - - if (find == false) { - enc_pr(LOG_ERROR, "current wq (%p) doesn't register.\n", - (void *)wq); - goto error; - } - - if (list_empty(&encode_manager.free_queue)) { - enc_pr(LOG_ERROR, "work queue no space, wq:%p.\n", - (void *)wq); - goto error; - } - - pitem = list_entry(encode_manager.free_queue.next, - struct encode_queue_item_s, list); - if (IS_ERR(pitem)) - goto error; - - memcpy(&pitem->request, &wq->request, sizeof(struct encode_request_s)); - memset(&wq->request, 0, sizeof(struct encode_request_s)); - wq->hw_status = 0; - wq->output_size = 0; - pitem->request.parent = wq; - list_move_tail(&pitem->list, &encode_manager.process_queue); - spin_unlock(&encode_manager.event.sem_lock); - - enc_pr(LOG_INFO, - "add new work ok, cmd:%d, ucode mode: %d, wq:%p.\n", - pitem->request.cmd, pitem->request.ucode_mode, - (void *)wq); - complete(&encode_manager.event.request_in_com);/* new cmd come in */ - return 0; -error: - spin_unlock(&encode_manager.event.sem_lock); - return -1; -} - -struct encode_wq_s *create_encode_work_queue(void) -{ - struct encode_wq_s *encode_work_queue = NULL; - bool done = false; - u32 i, max_instance; - struct Buff_s *reserve_buff; - - encode_work_queue = kzalloc(sizeof(struct encode_wq_s), GFP_KERNEL); - if (IS_ERR(encode_work_queue)) { - enc_pr(LOG_ERROR, "can't create work queue\n"); - return NULL; - } - max_instance = encode_manager.max_instance; - encode_work_queue->pic.init_qppicture = 26; - encode_work_queue->pic.log2_max_frame_num = 4; - encode_work_queue->pic.log2_max_pic_order_cnt_lsb = 4; - encode_work_queue->pic.idr_pic_id = 0; - encode_work_queue->pic.frame_number = 0; - encode_work_queue->pic.pic_order_cnt_lsb = 0; - encode_work_queue->ucode_index = UCODE_MODE_FULL; - -#ifdef H264_ENC_CBR - encode_work_queue->cbr_info.block_w = 16; - encode_work_queue->cbr_info.block_h = 9; - encode_work_queue->cbr_info.long_th = CBR_LONG_THRESH; - encode_work_queue->cbr_info.start_tbl_id = START_TABLE_ID; - encode_work_queue->cbr_info.short_shift = CBR_SHORT_SHIFT; - encode_work_queue->cbr_info.long_mb_num = CBR_LONG_MB_NUM; -#endif - init_waitqueue_head(&encode_work_queue->request_complete); - atomic_set(&encode_work_queue->request_ready, 0); - spin_lock(&encode_manager.event.sem_lock); - if (encode_manager.wq_count < encode_manager.max_instance) { - list_add_tail(&encode_work_queue->list, &encode_manager.wq); - encode_manager.wq_count++; - if (encode_manager.use_reserve == true) { - for (i = 0; i < max_instance; i++) { - reserve_buff = &encode_manager.reserve_buff[i]; - if (reserve_buff->used == false) { - encode_work_queue->mem.buf_start = - reserve_buff->buf_start; - encode_work_queue->mem.buf_size = - reserve_buff->buf_size; - reserve_buff->used = true; - done = true; - break; - } - } - } else - done = true; - } - spin_unlock(&encode_manager.event.sem_lock); - if (done == false) { - kfree(encode_work_queue); - encode_work_queue = NULL; - enc_pr(LOG_ERROR, "too many work queue!\n"); - } - return encode_work_queue; /* find it */ -} - -static void _destroy_encode_work_queue(struct encode_manager_s *manager, - struct encode_wq_s **wq, - struct encode_wq_s *encode_work_queue, - bool *find) -{ - struct list_head *head; - struct encode_wq_s *wp_tmp = NULL; - u32 i, max_instance; - struct Buff_s *reserve_buff; - u32 buf_start = encode_work_queue->mem.buf_start; - - max_instance = manager->max_instance; - head = &manager->wq; - list_for_each_entry_safe((*wq), wp_tmp, head, list) { - if ((*wq) && (*wq == encode_work_queue)) { - list_del(&(*wq)->list); - if (manager->use_reserve == true) { - for (i = 0; i < max_instance; i++) { - reserve_buff = - &manager->reserve_buff[i]; - if (reserve_buff->used == true && - buf_start == - reserve_buff->buf_start) { - reserve_buff->used = false; - break; - } - } - } - *find = true; - manager->wq_count--; - enc_pr(LOG_DEBUG, - "remove encode_work_queue %p sucess, %s line %d.\n", - (void *)encode_work_queue, - __func__, __LINE__); - break; - } - } -} - -s32 destroy_encode_work_queue(struct encode_wq_s *encode_work_queue) -{ - struct encode_queue_item_s *pitem, *tmp; - struct encode_wq_s *wq = NULL; - bool find = false; - - struct list_head *head; - if (encode_work_queue) { - spin_lock(&encode_manager.event.sem_lock); - if (encode_manager.current_wq == encode_work_queue) { - encode_manager.remove_flag = true; - spin_unlock(&encode_manager.event.sem_lock); - enc_pr(LOG_DEBUG, - "warning--Destory the running queue, should not be here.\n"); - wait_for_completion( - &encode_manager.event.process_complete); - spin_lock(&encode_manager.event.sem_lock); - } /* else we can delete it safely. */ - - head = &encode_manager.process_queue; - list_for_each_entry_safe(pitem, tmp, head, list) { - if (pitem && pitem->request.parent == - encode_work_queue) { - pitem->request.parent = NULL; - enc_pr(LOG_DEBUG, - "warning--remove not process request, should not be here.\n"); - list_move_tail(&pitem->list, - &encode_manager.free_queue); - } - } - - _destroy_encode_work_queue(&encode_manager, &wq, - encode_work_queue, &find); - spin_unlock(&encode_manager.event.sem_lock); -#ifdef CONFIG_CMA - if (encode_work_queue->mem.buf_start) { - codec_mm_free_for_dma( - ENCODE_NAME, - encode_work_queue->mem.buf_start); - encode_work_queue->mem.buf_start = 0; - - } -#endif - kfree(encode_work_queue); - complete(&encode_manager.event.request_in_com); - } - return 0; -} - -static s32 encode_monitor_thread(void *data) -{ - struct encode_manager_s *manager = (struct encode_manager_s *)data; - struct encode_queue_item_s *pitem = NULL; - struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 }; - s32 ret = 0; - enc_pr(LOG_DEBUG, "encode workqueue monitor start.\n"); - sched_setscheduler(current, SCHED_FIFO, ¶m); - allow_signal(SIGTERM); - /* setup current_wq here. */ - while (manager->process_queue_state != ENCODE_PROCESS_QUEUE_STOP) { - if (kthread_should_stop()) - break; - - ret = wait_for_completion_interruptible( - &manager->event.request_in_com); - - if (ret == -ERESTARTSYS) - break; - - if (kthread_should_stop()) - break; - if (manager->inited == false) { - spin_lock(&manager->event.sem_lock); - if (!list_empty(&manager->wq)) { - struct encode_wq_s *first_wq = - list_entry(manager->wq.next, - struct encode_wq_s, list); - manager->current_wq = first_wq; - spin_unlock(&manager->event.sem_lock); - if (first_wq) { -#ifdef CONFIG_AM_GE2D - if (!manager->context) - manager->context = - create_ge2d_work_queue(); -#endif - avc_init(first_wq); - manager->inited = true; - } - spin_lock(&manager->event.sem_lock); - manager->current_wq = NULL; - spin_unlock(&manager->event.sem_lock); - if (manager->remove_flag) { - complete( - &manager - ->event.process_complete); - manager->remove_flag = false; - } - } else - spin_unlock(&manager->event.sem_lock); - continue; - } - - spin_lock(&manager->event.sem_lock); - pitem = NULL; - if (list_empty(&manager->wq)) { - spin_unlock(&manager->event.sem_lock); - manager->inited = false; - amvenc_avc_stop(); -#ifdef CONFIG_AM_GE2D - if (manager->context) { - destroy_ge2d_work_queue(manager->context); - manager->context = NULL; - } -#endif - enc_pr(LOG_DEBUG, "power off encode.\n"); - continue; - } else if (!list_empty(&manager->process_queue)) { - pitem = list_entry(manager->process_queue.next, - struct encode_queue_item_s, list); - list_del(&pitem->list); - manager->current_item = pitem; - manager->current_wq = pitem->request.parent; - } - spin_unlock(&manager->event.sem_lock); - - if (pitem) { - encode_process_request(manager, pitem); - spin_lock(&manager->event.sem_lock); - list_add_tail(&pitem->list, &manager->free_queue); - manager->current_item = NULL; - manager->last_wq = manager->current_wq; - manager->current_wq = NULL; - spin_unlock(&manager->event.sem_lock); - } - if (manager->remove_flag) { - complete(&manager->event.process_complete); - manager->remove_flag = false; - } - } - while (!kthread_should_stop()) - msleep(20); - - enc_pr(LOG_DEBUG, "exit encode_monitor_thread.\n"); - return 0; -} - -static s32 encode_start_monitor(void) -{ - s32 ret = 0; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { - y_tnr_mot2alp_nrm_gain = 216; - y_tnr_mot2alp_dis_gain = 144; - c_tnr_mot2alp_nrm_gain = 216; - c_tnr_mot2alp_dis_gain = 144; - } else { - /* more tnr */ - y_tnr_mot2alp_nrm_gain = 144; - y_tnr_mot2alp_dis_gain = 96; - c_tnr_mot2alp_nrm_gain = 144; - c_tnr_mot2alp_dis_gain = 96; - } - - enc_pr(LOG_DEBUG, "encode start monitor.\n"); - encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_START; - encode_manager.encode_thread = kthread_run(encode_monitor_thread, - &encode_manager, "encode_monitor"); - if (IS_ERR(encode_manager.encode_thread)) { - ret = PTR_ERR(encode_manager.encode_thread); - encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_STOP; - enc_pr(LOG_ERROR, - "encode monitor : failed to start kthread (%d)\n", ret); - } - return ret; -} - -static s32 encode_stop_monitor(void) -{ - enc_pr(LOG_DEBUG, "stop encode monitor thread\n"); - if (encode_manager.encode_thread) { - spin_lock(&encode_manager.event.sem_lock); - if (!list_empty(&encode_manager.wq)) { - u32 count = encode_manager.wq_count; - spin_unlock(&encode_manager.event.sem_lock); - enc_pr(LOG_ERROR, - "stop encode monitor thread error, active wq (%d) is not 0.\n", - count); - return -1; - } - spin_unlock(&encode_manager.event.sem_lock); - encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_STOP; - send_sig(SIGTERM, encode_manager.encode_thread, 1); - complete(&encode_manager.event.request_in_com); - kthread_stop(encode_manager.encode_thread); - encode_manager.encode_thread = NULL; - kfree(mc_addr); - mc_addr = NULL; - } - return 0; -} - -static s32 encode_wq_init(void) -{ - u32 i = 0; - struct encode_queue_item_s *pitem = NULL; - - enc_pr(LOG_DEBUG, "encode_wq_init.\n"); - encode_manager.irq_requested = false; - - spin_lock_init(&encode_manager.event.sem_lock); - init_completion(&encode_manager.event.request_in_com); - init_waitqueue_head(&encode_manager.event.hw_complete); - init_completion(&encode_manager.event.process_complete); - INIT_LIST_HEAD(&encode_manager.process_queue); - INIT_LIST_HEAD(&encode_manager.free_queue); - INIT_LIST_HEAD(&encode_manager.wq); - - tasklet_init(&encode_manager.encode_tasklet, - encode_isr_tasklet, - (ulong)&encode_manager); - - for (i = 0; i < MAX_ENCODE_REQUEST; i++) { - pitem = kcalloc(1, - sizeof(struct encode_queue_item_s), - GFP_KERNEL); - if (IS_ERR(pitem)) { - enc_pr(LOG_ERROR, "can't request queue item memory.\n"); - return -1; - } - pitem->request.parent = NULL; - list_add_tail(&pitem->list, &encode_manager.free_queue); - } - encode_manager.current_wq = NULL; - encode_manager.last_wq = NULL; - encode_manager.encode_thread = NULL; - encode_manager.current_item = NULL; - encode_manager.wq_count = 0; - encode_manager.remove_flag = false; - InitEncodeWeight(); - if (encode_start_monitor()) { - enc_pr(LOG_ERROR, "encode create thread error.\n"); - return -1; - } - return 0; -} - -static s32 encode_wq_uninit(void) -{ - struct encode_queue_item_s *pitem, *tmp; - struct list_head *head; - u32 count = 0; - s32 r = -1; - enc_pr(LOG_DEBUG, "uninit encode wq.\n"); - if (encode_stop_monitor() == 0) { - if ((encode_manager.irq_num >= 0) && - (encode_manager.irq_requested == true)) { - free_irq(encode_manager.irq_num, &encode_manager); - encode_manager.irq_requested = false; - } - spin_lock(&encode_manager.event.sem_lock); - head = &encode_manager.process_queue; - list_for_each_entry_safe(pitem, tmp, head, list) { - if (pitem) { - list_del(&pitem->list); - kfree(pitem); - count++; - } - } - head = &encode_manager.free_queue; - list_for_each_entry_safe(pitem, tmp, head, list) { - if (pitem) { - list_del(&pitem->list); - kfree(pitem); - count++; - } - } - spin_unlock(&encode_manager.event.sem_lock); - if (count == MAX_ENCODE_REQUEST) - r = 0; - else { - enc_pr(LOG_ERROR, "lost some request item %d.\n", - MAX_ENCODE_REQUEST - count); - } - } - return r; -} - -static ssize_t encode_status_show(struct class *cla, - struct class_attribute *attr, char *buf) -{ - u32 process_count = 0; - u32 free_count = 0; - struct encode_queue_item_s *pitem = NULL; - struct encode_wq_s *current_wq = NULL; - struct encode_wq_s *last_wq = NULL; - struct list_head *head = NULL; - s32 irq_num = 0; - u32 hw_status = 0; - u32 process_queue_state = 0; - u32 wq_count = 0; - u32 ucode_index; - bool need_reset; - bool process_irq; - bool inited; - bool use_reserve; - struct Buff_s reserve_mem; - u32 max_instance; -#ifdef CONFIG_CMA - bool check_cma = false; -#endif - - spin_lock(&encode_manager.event.sem_lock); - head = &encode_manager.free_queue; - list_for_each_entry(pitem, head , list) { - free_count++; - if (free_count > MAX_ENCODE_REQUEST) - break; - } - - head = &encode_manager.process_queue; - list_for_each_entry(pitem, head , list) { - process_count++; - if (free_count > MAX_ENCODE_REQUEST) - break; - } - - current_wq = encode_manager.current_wq; - last_wq = encode_manager.last_wq; - pitem = encode_manager.current_item; - irq_num = encode_manager.irq_num; - hw_status = encode_manager.encode_hw_status; - process_queue_state = encode_manager.process_queue_state; - wq_count = encode_manager.wq_count; - ucode_index = encode_manager.ucode_index; - need_reset = encode_manager.need_reset; - process_irq = encode_manager.process_irq; - inited = encode_manager.inited; - use_reserve = encode_manager.use_reserve; - reserve_mem.buf_start = encode_manager.reserve_mem.buf_start; - reserve_mem.buf_size = encode_manager.reserve_mem.buf_size; - - max_instance = encode_manager.max_instance; -#ifdef CONFIG_CMA - check_cma = encode_manager.check_cma; -#endif - - spin_unlock(&encode_manager.event.sem_lock); - - enc_pr(LOG_DEBUG, - "encode process queue count: %d, free queue count: %d.\n", - process_count, free_count); - enc_pr(LOG_DEBUG, - "encode curent wq: %p, last wq: %p, wq count: %d, max_instance: %d.\n", - current_wq, last_wq, wq_count, max_instance); - if (current_wq) - enc_pr(LOG_DEBUG, - "encode curent wq -- encode width: %d, encode height: %d.\n", - current_wq->pic.encoder_width, - current_wq->pic.encoder_height); - enc_pr(LOG_DEBUG, - "encode curent pitem: %p, ucode_index: %d, hw_status: %d, need_reset: %s, process_irq: %s.\n", - pitem, ucode_index, hw_status, need_reset ? "true" : "false", - process_irq ? "true" : "false"); - enc_pr(LOG_DEBUG, - "encode irq num: %d, inited: %s, process_queue_state: %d.\n", - irq_num, inited ? "true" : "false", process_queue_state); - if (use_reserve) { - enc_pr(LOG_DEBUG, - "encode use reserve memory, buffer start: 0x%x, size: %d MB.\n", - reserve_mem.buf_start, - reserve_mem.buf_size / SZ_1M); - } else { -#ifdef CONFIG_CMA - enc_pr(LOG_DEBUG, "encode check cma: %s.\n", - check_cma ? "true" : "false"); -#endif - } - return snprintf(buf, 40, "encode max instance: %d\n", max_instance); -} - -static struct class_attribute amvenc_class_attrs[] = { - __ATTR(encode_status, - S_IRUGO | S_IWUSR, - encode_status_show, - NULL), - __ATTR_NULL -}; - -static struct class amvenc_avc_class = { - .name = CLASS_NAME, - .class_attrs = amvenc_class_attrs, -}; - -s32 init_avc_device(void) -{ - s32 r = 0; - r = register_chrdev(0, DEVICE_NAME, &amvenc_avc_fops); - if (r <= 0) { - enc_pr(LOG_ERROR, "register amvenc_avc device error.\n"); - return r; - } - avc_device_major = r; - - r = class_register(&amvenc_avc_class); - if (r < 0) { - enc_pr(LOG_ERROR, "error create amvenc_avc class.\n"); - return r; - } - - amvenc_avc_dev = device_create(&amvenc_avc_class, NULL, - MKDEV(avc_device_major, 0), NULL, - DEVICE_NAME); - - if (IS_ERR(amvenc_avc_dev)) { - enc_pr(LOG_ERROR, "create amvenc_avc device error.\n"); - class_unregister(&amvenc_avc_class); - return -1; - } - return r; -} - -s32 uninit_avc_device(void) -{ - if (amvenc_avc_dev) - device_destroy(&amvenc_avc_class, MKDEV(avc_device_major, 0)); - - class_destroy(&amvenc_avc_class); - - unregister_chrdev(avc_device_major, DEVICE_NAME); - return 0; -} - -static s32 avc_mem_device_init(struct reserved_mem *rmem, struct device *dev) -{ - s32 r; - struct resource res; - if (!rmem) { - enc_pr(LOG_ERROR, - "Can not obtain I/O memory, and will allocate avc buffer!\n"); - r = -EFAULT; - return r; - } - res.start = (phys_addr_t)rmem->base; - res.end = res.start + (phys_addr_t)rmem->size - 1; - encode_manager.reserve_mem.buf_start = res.start; - encode_manager.reserve_mem.buf_size = res.end - res.start + 1; - - if (encode_manager.reserve_mem.buf_size >= - amvenc_buffspec[0].min_buffsize) { - encode_manager.max_instance = - encode_manager.reserve_mem.buf_size / - amvenc_buffspec[0].min_buffsize; - if (encode_manager.max_instance > MAX_ENCODE_INSTANCE) - encode_manager.max_instance = MAX_ENCODE_INSTANCE; - encode_manager.reserve_buff = kzalloc( - encode_manager.max_instance * - sizeof(struct Buff_s), GFP_KERNEL); - if (encode_manager.reserve_buff) { - u32 i; - struct Buff_s *reserve_buff; - u32 max_instance = encode_manager.max_instance; - for (i = 0; i < max_instance; i++) { - reserve_buff = &encode_manager.reserve_buff[i]; - reserve_buff->buf_start = - i * - amvenc_buffspec[0] - .min_buffsize + - encode_manager.reserve_mem.buf_start; - reserve_buff->buf_size = - encode_manager.reserve_mem.buf_start; - reserve_buff->used = false; - } - encode_manager.use_reserve = true; - r = 0; - enc_pr(LOG_DEBUG, - "amvenc_avc use reserve memory, buff start: 0x%x, size: 0x%x, max instance is %d\n", - encode_manager.reserve_mem.buf_start, - encode_manager.reserve_mem.buf_size, - encode_manager.max_instance); - } else { - enc_pr(LOG_ERROR, - "amvenc_avc alloc reserve buffer pointer fail. max instance is %d.\n", - encode_manager.max_instance); - encode_manager.max_instance = 0; - encode_manager.reserve_mem.buf_start = 0; - encode_manager.reserve_mem.buf_size = 0; - r = -ENOMEM; - } - } else { - enc_pr(LOG_ERROR, - "amvenc_avc memory resource too small, size is 0x%x. Need 0x%x bytes at least.\n", - encode_manager.reserve_mem.buf_size, - amvenc_buffspec[0] - .min_buffsize); - encode_manager.reserve_mem.buf_start = 0; - encode_manager.reserve_mem.buf_size = 0; - r = -ENOMEM; - } - return r; -} - -static s32 amvenc_avc_probe(struct platform_device *pdev) -{ - /* struct resource mem; */ - s32 res_irq; - s32 idx; - s32 r; - - enc_pr(LOG_INFO, "amvenc_avc probe start.\n"); - - encode_manager.this_pdev = pdev; -#ifdef CONFIG_CMA - encode_manager.check_cma = false; -#endif - encode_manager.reserve_mem.buf_start = 0; - encode_manager.reserve_mem.buf_size = 0; - encode_manager.use_reserve = false; - encode_manager.max_instance = 0; - encode_manager.reserve_buff = NULL; - - idx = of_reserved_mem_device_init(&pdev->dev); - if (idx != 0) { - enc_pr(LOG_DEBUG, - "amvenc_avc_probe -- reserved memory config fail.\n"); - } - - if (encode_manager.use_reserve == false) { -#ifndef CONFIG_CMA - enc_pr(LOG_ERROR, - "amvenc_avc memory is invaild, probe fail!\n"); - return -EFAULT; -#else - encode_manager.cma_pool_size = - (codec_mm_get_total_size() > (MIN_SIZE * 2)) ? - (MIN_SIZE * 2) : codec_mm_get_total_size(); - enc_pr(LOG_DEBUG, - "amvenc_avc - cma memory pool size: %d MB\n", - (u32)encode_manager.cma_pool_size / SZ_1M); -#endif - } - - res_irq = platform_get_irq(pdev, 0); - if (res_irq < 0) { - enc_pr(LOG_ERROR, "[%s] get irq error!", __func__); - return -EINVAL; - } - - encode_manager.irq_num = res_irq; - if (encode_wq_init()) { - kfree(encode_manager.reserve_buff); - encode_manager.reserve_buff = NULL; - enc_pr(LOG_ERROR, "encode work queue init error.\n"); - return -EFAULT; - } - - r = init_avc_device(); - enc_pr(LOG_INFO, "amvenc_avc probe end.\n"); - return r; -} - -static s32 amvenc_avc_remove(struct platform_device *pdev) -{ - kfree(encode_manager.reserve_buff); - encode_manager.reserve_buff = NULL; - if (encode_wq_uninit()) { - enc_pr(LOG_ERROR, "encode work queue uninit error.\n"); - } - uninit_avc_device(); - enc_pr(LOG_INFO, "amvenc_avc remove.\n"); - return 0; -} - -static const struct of_device_id amlogic_avcenc_dt_match[] = { - { - .compatible = "amlogic, amvenc_avc", - }, - {}, -}; - -static struct platform_driver amvenc_avc_driver = { - .probe = amvenc_avc_probe, - .remove = amvenc_avc_remove, - .driver = { - .name = DRIVER_NAME, - .of_match_table = amlogic_avcenc_dt_match, - } -}; - -static struct codec_profile_t amvenc_avc_profile = { - .name = "avc", - .profile = "" -}; - -static s32 __init amvenc_avc_driver_init_module(void) -{ - enc_pr(LOG_INFO, "amvenc_avc module init\n"); - - if (platform_driver_register(&amvenc_avc_driver)) { - enc_pr(LOG_ERROR, - "failed to register amvenc_avc driver\n"); - return -ENODEV; - } - vcodec_profile_register(&amvenc_avc_profile); - return 0; -} - -static void __exit amvenc_avc_driver_remove_module(void) -{ - enc_pr(LOG_INFO, "amvenc_avc module remove.\n"); - - platform_driver_unregister(&amvenc_avc_driver); -} - -static const struct reserved_mem_ops rmem_avc_ops = { - .device_init = avc_mem_device_init, -}; - -static s32 __init avc_mem_setup(struct reserved_mem *rmem) -{ - rmem->ops = &rmem_avc_ops; - enc_pr(LOG_DEBUG, "amvenc_avc reserved mem setup.\n"); - return 0; -} - -module_param(fixed_slice_cfg, uint, 0664); -MODULE_PARM_DESC(fixed_slice_cfg, "\n fixed_slice_cfg\n"); - -module_param(clock_level, uint, 0664); -MODULE_PARM_DESC(clock_level, "\n clock_level\n"); - -module_param(encode_print_level, uint, 0664); -MODULE_PARM_DESC(encode_print_level, "\n encode_print_level\n"); - -module_param(no_timeout, uint, 0664); -MODULE_PARM_DESC(no_timeout, "\n no_timeout flag for process request\n"); - -module_param(nr_mode, int, 0664); -MODULE_PARM_DESC(nr_mode, "\n nr_mode option\n"); - -module_param(qp_table_debug, uint, 0664); -MODULE_PARM_DESC(qp_table_debug, "\n print qp table\n"); - -#ifdef MORE_MODULE_PARAM -module_param(me_mv_merge_ctl, uint, 0664); -MODULE_PARM_DESC(me_mv_merge_ctl, "\n me_mv_merge_ctl\n"); - -module_param(me_step0_close_mv, uint, 0664); -MODULE_PARM_DESC(me_step0_close_mv, "\n me_step0_close_mv\n"); - -module_param(me_f_skip_sad, uint, 0664); -MODULE_PARM_DESC(me_f_skip_sad, "\n me_f_skip_sad\n"); - -module_param(me_f_skip_weight, uint, 0664); -MODULE_PARM_DESC(me_f_skip_weight, "\n me_f_skip_weight\n"); - -module_param(me_mv_weight_01, uint, 0664); -MODULE_PARM_DESC(me_mv_weight_01, "\n me_mv_weight_01\n"); - -module_param(me_mv_weight_23, uint, 0664); -MODULE_PARM_DESC(me_mv_weight_23, "\n me_mv_weight_23\n"); - -module_param(me_sad_range_inc, uint, 0664); -MODULE_PARM_DESC(me_sad_range_inc, "\n me_sad_range_inc\n"); - -module_param(me_sad_enough_01, uint, 0664); -MODULE_PARM_DESC(me_sad_enough_01, "\n me_sad_enough_01\n"); - -module_param(me_sad_enough_23, uint, 0664); -MODULE_PARM_DESC(me_sad_enough_23, "\n me_sad_enough_23\n"); - -module_param(y_tnr_mc_en, uint, 0664); -MODULE_PARM_DESC(y_tnr_mc_en, "\n y_tnr_mc_en option\n"); -module_param(y_tnr_txt_mode, uint, 0664); -MODULE_PARM_DESC(y_tnr_txt_mode, "\n y_tnr_txt_mode option\n"); -module_param(y_tnr_mot_sad_margin, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_sad_margin, "\n y_tnr_mot_sad_margin option\n"); -module_param(y_tnr_mot_cortxt_rate, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_cortxt_rate, "\n y_tnr_mot_cortxt_rate option\n"); -module_param(y_tnr_mot_distxt_ofst, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_distxt_ofst, "\n y_tnr_mot_distxt_ofst option\n"); -module_param(y_tnr_mot_distxt_rate, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_distxt_rate, "\n y_tnr_mot_distxt_rate option\n"); -module_param(y_tnr_mot_dismot_ofst, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_dismot_ofst, "\n y_tnr_mot_dismot_ofst option\n"); -module_param(y_tnr_mot_frcsad_lock, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot_frcsad_lock, "\n y_tnr_mot_frcsad_lock option\n"); -module_param(y_tnr_mot2alp_frc_gain, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot2alp_frc_gain, "\n y_tnr_mot2alp_frc_gain option\n"); -module_param(y_tnr_mot2alp_nrm_gain, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot2alp_nrm_gain, "\n y_tnr_mot2alp_nrm_gain option\n"); -module_param(y_tnr_mot2alp_dis_gain, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot2alp_dis_gain, "\n y_tnr_mot2alp_dis_gain option\n"); -module_param(y_tnr_mot2alp_dis_ofst, uint, 0664); -MODULE_PARM_DESC(y_tnr_mot2alp_dis_ofst, "\n y_tnr_mot2alp_dis_ofst option\n"); -module_param(y_tnr_alpha_min, uint, 0664); -MODULE_PARM_DESC(y_tnr_alpha_min, "\n y_tnr_alpha_min option\n"); -module_param(y_tnr_alpha_max, uint, 0664); -MODULE_PARM_DESC(y_tnr_alpha_max, "\n y_tnr_alpha_max option\n"); -module_param(y_tnr_deghost_os, uint, 0664); -MODULE_PARM_DESC(y_tnr_deghost_os, "\n y_tnr_deghost_os option\n"); - -module_param(c_tnr_mc_en, uint, 0664); -MODULE_PARM_DESC(c_tnr_mc_en, "\n c_tnr_mc_en option\n"); -module_param(c_tnr_txt_mode, uint, 0664); -MODULE_PARM_DESC(c_tnr_txt_mode, "\n c_tnr_txt_mode option\n"); -module_param(c_tnr_mot_sad_margin, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_sad_margin, "\n c_tnr_mot_sad_margin option\n"); -module_param(c_tnr_mot_cortxt_rate, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_cortxt_rate, "\n c_tnr_mot_cortxt_rate option\n"); -module_param(c_tnr_mot_distxt_ofst, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_distxt_ofst, "\n c_tnr_mot_distxt_ofst option\n"); -module_param(c_tnr_mot_distxt_rate, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_distxt_rate, "\n c_tnr_mot_distxt_rate option\n"); -module_param(c_tnr_mot_dismot_ofst, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_dismot_ofst, "\n c_tnr_mot_dismot_ofst option\n"); -module_param(c_tnr_mot_frcsad_lock, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot_frcsad_lock, "\n c_tnr_mot_frcsad_lock option\n"); -module_param(c_tnr_mot2alp_frc_gain, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot2alp_frc_gain, "\n c_tnr_mot2alp_frc_gain option\n"); -module_param(c_tnr_mot2alp_nrm_gain, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot2alp_nrm_gain, "\n c_tnr_mot2alp_nrm_gain option\n"); -module_param(c_tnr_mot2alp_dis_gain, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot2alp_dis_gain, "\n c_tnr_mot2alp_dis_gain option\n"); -module_param(c_tnr_mot2alp_dis_ofst, uint, 0664); -MODULE_PARM_DESC(c_tnr_mot2alp_dis_ofst, "\n c_tnr_mot2alp_dis_ofst option\n"); -module_param(c_tnr_alpha_min, uint, 0664); -MODULE_PARM_DESC(c_tnr_alpha_min, "\n c_tnr_alpha_min option\n"); -module_param(c_tnr_alpha_max, uint, 0664); -MODULE_PARM_DESC(c_tnr_alpha_max, "\n c_tnr_alpha_max option\n"); -module_param(c_tnr_deghost_os, uint, 0664); -MODULE_PARM_DESC(c_tnr_deghost_os, "\n c_tnr_deghost_os option\n"); - -module_param(y_snr_err_norm, uint, 0664); -MODULE_PARM_DESC(y_snr_err_norm, "\n y_snr_err_norm option\n"); -module_param(y_snr_gau_bld_core, uint, 0664); -MODULE_PARM_DESC(y_snr_gau_bld_core, "\n y_snr_gau_bld_core option\n"); -module_param(y_snr_gau_bld_ofst, int, 0664); -MODULE_PARM_DESC(y_snr_gau_bld_ofst, "\n y_snr_gau_bld_ofst option\n"); -module_param(y_snr_gau_bld_rate, uint, 0664); -MODULE_PARM_DESC(y_snr_gau_bld_rate, "\n y_snr_gau_bld_rate option\n"); -module_param(y_snr_gau_alp0_min, uint, 0664); -MODULE_PARM_DESC(y_snr_gau_alp0_min, "\n y_snr_gau_alp0_min option\n"); -module_param(y_snr_gau_alp0_max, uint, 0664); -MODULE_PARM_DESC(y_snr_gau_alp0_max, "\n y_snr_gau_alp0_max option\n"); -module_param(y_bld_beta2alp_rate, uint, 0664); -MODULE_PARM_DESC(y_bld_beta2alp_rate, "\n y_bld_beta2alp_rate option\n"); -module_param(y_bld_beta_min, uint, 0664); -MODULE_PARM_DESC(y_bld_beta_min, "\n y_bld_beta_min option\n"); -module_param(y_bld_beta_max, uint, 0664); -MODULE_PARM_DESC(y_bld_beta_max, "\n y_bld_beta_max option\n"); - -module_param(c_snr_err_norm, uint, 0664); -MODULE_PARM_DESC(c_snr_err_norm, "\n c_snr_err_norm option\n"); -module_param(c_snr_gau_bld_core, uint, 0664); -MODULE_PARM_DESC(c_snr_gau_bld_core, "\n c_snr_gau_bld_core option\n"); -module_param(c_snr_gau_bld_ofst, int, 0664); -MODULE_PARM_DESC(c_snr_gau_bld_ofst, "\n c_snr_gau_bld_ofst option\n"); -module_param(c_snr_gau_bld_rate, uint, 0664); -MODULE_PARM_DESC(c_snr_gau_bld_rate, "\n c_snr_gau_bld_rate option\n"); -module_param(c_snr_gau_alp0_min, uint, 0664); -MODULE_PARM_DESC(c_snr_gau_alp0_min, "\n c_snr_gau_alp0_min option\n"); -module_param(c_snr_gau_alp0_max, uint, 0664); -MODULE_PARM_DESC(c_snr_gau_alp0_max, "\n c_snr_gau_alp0_max option\n"); -module_param(c_bld_beta2alp_rate, uint, 0664); -MODULE_PARM_DESC(c_bld_beta2alp_rate, "\n c_bld_beta2alp_rate option\n"); -module_param(c_bld_beta_min, uint, 0664); -MODULE_PARM_DESC(c_bld_beta_min, "\n c_bld_beta_min option\n"); -module_param(c_bld_beta_max, uint, 0664); -MODULE_PARM_DESC(c_bld_beta_max, "\n c_bld_beta_max option\n"); -#endif - -module_init(amvenc_avc_driver_init_module); -module_exit(amvenc_avc_driver_remove_module); -RESERVEDMEM_OF_DECLARE(amvenc_avc, "amlogic, amvenc-memory", avc_mem_setup); - -MODULE_DESCRIPTION("AMLOGIC AVC Video Encoder Driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("simon.zheng <simon.zheng@amlogic.com>"); diff --git a/drivers/frame_sink/encoder/h264/encoder.h b/drivers/frame_sink/encoder/h264/encoder.h deleted file mode 100644 index db4f255..0000000 --- a/drivers/frame_sink/encoder/h264/encoder.h +++ b/dev/null @@ -1,465 +0,0 @@ -/* - * drivers/amlogic/amports/encoder.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 __H264_H__ -#define __H264_H__ - -#include <linux/mutex.h> -#include <linux/semaphore.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/wait.h> -#include <linux/slab.h> -#ifdef CONFIG_AM_GE2D -#include <linux/amlogic/ge2d/ge2d.h> -#endif - -#define AMVENC_DEVINFO_M8 "AML-M8" -#define AMVENC_DEVINFO_G9 "AML-G9" -#define AMVENC_DEVINFO_GXBB "AML-GXBB" -#define AMVENC_DEVINFO_GXTVBB "AML-GXTVBB" -#define AMVENC_DEVINFO_GXL "AML-GXL" - -#define HCODEC_IRQ_MBOX_CLR HCODEC_ASSIST_MBOX2_CLR_REG -#define HCODEC_IRQ_MBOX_MASK HCODEC_ASSIST_MBOX2_MASK - -/* M8: 2550/10 = 255M GX: 2000/10 = 200M */ -#define HDEC_L0() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (2 << 25) | (1 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/8 = 319M GX: 2000/8 = 250M */ -#define HDEC_L1() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (0 << 25) | (1 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/7 = 364M GX: 2000/7 = 285M */ -#define HDEC_L2() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (3 << 25) | (0 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/6 = 425M GX: 2000/6 = 333M */ -#define HDEC_L3() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (1 << 25) | (1 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/5 = 510M GX: 2000/5 = 400M */ -#define HDEC_L4() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (2 << 25) | (0 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/4 = 638M GX: 2000/4 = 500M */ -#define HDEC_L5() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (0 << 25) | (0 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) -/* M8: 2550/3 = 850M GX: 2000/3 = 667M */ -#define HDEC_L6() WRITE_HHI_REG(HHI_VDEC_CLK_CNTL, \ - (1 << 25) | (0 << 16) | (1 << 24) | \ - (0xffff & READ_HHI_REG(HHI_VDEC_CLK_CNTL))) - -#define hvdec_clock_enable(level) \ - do { \ - if (level == 0) \ - HDEC_L0(); \ - else if (level == 1) \ - HDEC_L1(); \ - else if (level == 2) \ - HDEC_L2(); \ - else if (level == 3) \ - HDEC_L3(); \ - else if (level == 4) \ - HDEC_L4(); \ - else if (level == 5) \ - HDEC_L5(); \ - else if (level == 6) \ - HDEC_L6(); \ - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15); \ - } while (0) - -#define hvdec_clock_disable() \ - do { \ - WRITE_VREG_BITS(DOS_GCLK_EN0, 0, 12, 15); \ - WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 0, 24, 1); \ - } while (0) - -#define LOG_ALL 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 -#define LOG_ERROR 3 - -#define enc_pr(level, x...) \ - do { \ - if (level >= encode_print_level) \ - printk(x); \ - } while (0) - -#define AMVENC_AVC_IOC_MAGIC 'E' - -#define AMVENC_AVC_IOC_GET_DEVINFO _IOW(AMVENC_AVC_IOC_MAGIC, 0xf0, u32) -#define AMVENC_AVC_IOC_MAX_INSTANCE _IOW(AMVENC_AVC_IOC_MAGIC, 0xf1, u32) - -#define AMVENC_AVC_IOC_GET_ADDR _IOW(AMVENC_AVC_IOC_MAGIC, 0x00, u32) -#define AMVENC_AVC_IOC_INPUT_UPDATE _IOW(AMVENC_AVC_IOC_MAGIC, 0x01, u32) -#define AMVENC_AVC_IOC_NEW_CMD _IOW(AMVENC_AVC_IOC_MAGIC, 0x02, u32) -#define AMVENC_AVC_IOC_GET_STAGE _IOW(AMVENC_AVC_IOC_MAGIC, 0x03, u32) -#define AMVENC_AVC_IOC_GET_OUTPUT_SIZE _IOW(AMVENC_AVC_IOC_MAGIC, 0x04, u32) -#define AMVENC_AVC_IOC_CONFIG_INIT _IOW(AMVENC_AVC_IOC_MAGIC, 0x05, u32) -#define AMVENC_AVC_IOC_FLUSH_CACHE _IOW(AMVENC_AVC_IOC_MAGIC, 0x06, u32) -#define AMVENC_AVC_IOC_FLUSH_DMA _IOW(AMVENC_AVC_IOC_MAGIC, 0x07, u32) -#define AMVENC_AVC_IOC_GET_BUFFINFO _IOW(AMVENC_AVC_IOC_MAGIC, 0x08, u32) -#define AMVENC_AVC_IOC_SUBMIT _IOW(AMVENC_AVC_IOC_MAGIC, 0x09, u32) -#define AMVENC_AVC_IOC_READ_CANVAS _IOW(AMVENC_AVC_IOC_MAGIC, 0x0a, u32) - - -#define IE_PIPPELINE_BLOCK_SHIFT 0 -#define IE_PIPPELINE_BLOCK_MASK 0x1f -#define ME_PIXEL_MODE_SHIFT 5 -#define ME_PIXEL_MODE_MASK 0x3 - -enum amvenc_mem_type_e { - LOCAL_BUFF = 0, - CANVAS_BUFF, - PHYSICAL_BUFF, - MAX_BUFF_TYPE -}; - -enum amvenc_frame_fmt_e { - FMT_YUV422_SINGLE = 0, - FMT_YUV444_SINGLE, - FMT_NV21, - FMT_NV12, - FMT_YUV420, - FMT_YUV444_PLANE, - FMT_RGB888, - FMT_RGB888_PLANE, - FMT_RGB565, - FMT_RGBA8888, - FMT_YUV422_12BIT, - FMT_YUV444_10BIT, - FMT_YUV422_10BIT, - MAX_FRAME_FMT -}; - -#define MAX_ENCODE_REQUEST 8 /* 64 */ - -#define MAX_ENCODE_INSTANCE 8 /* 64 */ - -#define ENCODE_PROCESS_QUEUE_START 0 -#define ENCODE_PROCESS_QUEUE_STOP 1 - -#define AMVENC_FLUSH_FLAG_INPUT 0x1 -#define AMVENC_FLUSH_FLAG_OUTPUT 0x2 -#define AMVENC_FLUSH_FLAG_REFERENCE 0x4 -#define AMVENC_FLUSH_FLAG_INTRA_INFO 0x8 -#define AMVENC_FLUSH_FLAG_INTER_INFO 0x10 -#define AMVENC_FLUSH_FLAG_QP 0x20 -#define AMVENC_FLUSH_FLAG_DUMP 0x40 -#define AMVENC_FLUSH_FLAG_CBR 0x80 - -#define ENCODER_BUFFER_INPUT 0 -#define ENCODER_BUFFER_REF0 1 -#define ENCODER_BUFFER_REF1 2 -#define ENCODER_BUFFER_OUTPUT 3 -#define ENCODER_BUFFER_INTER_INFO 4 -#define ENCODER_BUFFER_INTRA_INFO 5 -#define ENCODER_BUFFER_QP 6 -#define ENCODER_BUFFER_DUMP 7 -#define ENCODER_BUFFER_CBR 8 - -struct encode_wq_s; - -struct encode_request_s { - u32 quant; - u32 cmd; - u32 ucode_mode; - - u32 src; - - u32 framesize; - - u32 me_weight; - u32 i4_weight; - u32 i16_weight; - - u32 crop_top; - u32 crop_bottom; - u32 crop_left; - u32 crop_right; - u32 src_w; - u32 src_h; - u32 scale_enable; - - u32 nr_mode; - u32 flush_flag; - u32 timeout; - enum amvenc_mem_type_e type; - enum amvenc_frame_fmt_e fmt; - struct encode_wq_s *parent; -}; - -struct encode_queue_item_s { - struct list_head list; - struct encode_request_s request; -}; - -struct Buff_s { - u32 buf_start; - u32 buf_size; - bool used; -}; - -struct BuffInfo_s { - u32 lev_id; - u32 min_buffsize; - u32 max_width; - u32 max_height; - struct Buff_s dct; - struct Buff_s dec0_y; - struct Buff_s dec0_uv; - struct Buff_s dec1_y; - struct Buff_s dec1_uv; - struct Buff_s assit; - struct Buff_s bitstream; - struct Buff_s scale_buff; - struct Buff_s dump_info; - struct Buff_s cbr_info; -}; - -struct encode_meminfo_s { - u32 buf_start; - u32 buf_size; - - u32 BitstreamStart; - u32 BitstreamEnd; - - /*input buffer define*/ - u32 dct_buff_start_addr; - u32 dct_buff_end_addr; - - /*microcode assitant buffer*/ - u32 assit_buffer_offset; - - u32 scaler_buff_start_addr; - - u32 dump_info_ddr_start_addr; - u32 dump_info_ddr_size; - - u32 cbr_info_ddr_start_addr; - u32 cbr_info_ddr_size; - - s32 dblk_buf_canvas; - s32 ref_buf_canvas; - struct BuffInfo_s bufspec; -#ifdef CONFIG_CMA - struct page *venc_pages; -#endif -}; - -struct encode_picinfo_s { - u32 encoder_width; - u32 encoder_height; - - u32 rows_per_slice; - - u32 idr_pic_id; /* need reset as 0 for IDR */ - u32 frame_number; /* need plus each frame */ - /* need reset as 0 for IDR and plus 2 for NON-IDR */ - u32 pic_order_cnt_lsb; - - u32 log2_max_pic_order_cnt_lsb; - u32 log2_max_frame_num; - u32 init_qppicture; -}; - -struct encode_cbr_s { - u16 block_w; - u16 block_h; - u16 long_th; - u8 start_tbl_id; - u8 short_shift; - u8 long_mb_num; -}; - -struct encode_wq_s { - struct list_head list; - - /* dev info */ - u32 ucode_index; - u32 hw_status; - u32 output_size; - - u32 sps_size; - u32 pps_size; - - u32 me_weight; - u32 i4_weight; - u32 i16_weight; - - u32 quant_tbl_i4[8]; - u32 quant_tbl_i16[8]; - u32 quant_tbl_me[8]; - - struct encode_meminfo_s mem; - struct encode_picinfo_s pic; - struct encode_request_s request; - struct encode_cbr_s cbr_info; - atomic_t request_ready; - wait_queue_head_t request_complete; -}; - -struct encode_event_s { - wait_queue_head_t hw_complete; - struct completion process_complete; - spinlock_t sem_lock; /* for queue switch and create destroy queue. */ - struct completion request_in_com; -}; - -struct encode_manager_s { - struct list_head wq; - struct list_head process_queue; - struct list_head free_queue; - - u32 encode_hw_status; - u32 process_queue_state; - s32 irq_num; - u32 wq_count; - u32 ucode_index; - u32 max_instance; -#ifdef CONFIG_AM_GE2D - struct ge2d_context_s *context; -#endif - bool irq_requested; - bool need_reset; - bool process_irq; - bool inited; /* power on encode */ - bool remove_flag; /* remove wq; */ - bool uninit_flag; /* power off encode */ - bool use_reserve; - -#ifdef CONFIG_CMA - bool check_cma; - ulong cma_pool_size; -#endif - struct platform_device *this_pdev; - struct Buff_s *reserve_buff; - struct encode_wq_s *current_wq; - struct encode_wq_s *last_wq; - struct encode_queue_item_s *current_item; - struct task_struct *encode_thread; - struct Buff_s reserve_mem; - struct encode_event_s event; - struct tasklet_struct encode_tasklet; -}; - -extern s32 encode_wq_add_request(struct encode_wq_s *wq); -extern struct encode_wq_s *create_encode_work_queue(void); -extern s32 destroy_encode_work_queue(struct encode_wq_s *encode_work_queue); - -/******************************************** - * AV Scratch Register Re-Define -********************************************/ -#define ENCODER_STATUS HCODEC_HENC_SCRATCH_0 -#define MEM_OFFSET_REG HCODEC_HENC_SCRATCH_1 -#define DEBUG_REG HCODEC_HENC_SCRATCH_2 -#define IDR_PIC_ID HCODEC_HENC_SCRATCH_5 -#define FRAME_NUMBER HCODEC_HENC_SCRATCH_6 -#define PIC_ORDER_CNT_LSB HCODEC_HENC_SCRATCH_7 -#define LOG2_MAX_PIC_ORDER_CNT_LSB HCODEC_HENC_SCRATCH_8 -#define LOG2_MAX_FRAME_NUM HCODEC_HENC_SCRATCH_9 -#define ANC0_BUFFER_ID HCODEC_HENC_SCRATCH_A -#define QPPICTURE HCODEC_HENC_SCRATCH_B - -#define IE_ME_MB_TYPE HCODEC_HENC_SCRATCH_D - -/* bit 0-4, IE_PIPPELINE_BLOCK - * bit 5 me half pixel in m8 - * disable i4x4 in gxbb - * bit 6 me step2 sub pixel in m8 - * disable i16x16 in gxbb - */ -#define IE_ME_MODE HCODEC_HENC_SCRATCH_E -#define IE_REF_SEL HCODEC_HENC_SCRATCH_F - -/* [31:0] NUM_ROWS_PER_SLICE_P */ -/* [15:0] NUM_ROWS_PER_SLICE_I */ -#define FIXED_SLICE_CFG HCODEC_HENC_SCRATCH_L - -/* For GX */ -#define INFO_DUMP_START_ADDR HCODEC_HENC_SCRATCH_I - -/* For CBR */ -#define H264_ENC_CBR_TABLE_ADDR HCODEC_HENC_SCRATCH_3 -#define H264_ENC_CBR_MB_SIZE_ADDR HCODEC_HENC_SCRATCH_4 -/* Bytes(Float) * 256 */ -#define H264_ENC_CBR_CTL HCODEC_HENC_SCRATCH_G -/* [31:28] : init qp table idx */ -/* [27:24] : short_term adjust shift */ -/* [23:16] : Long_term MB_Number between adjust, */ -/* [15:0] Long_term adjust threshold(Bytes) */ -#define H264_ENC_CBR_TARGET_SIZE HCODEC_HENC_SCRATCH_H -/* Bytes(Float) * 256 */ -#define H264_ENC_CBR_PREV_BYTES HCODEC_HENC_SCRATCH_J -#define H264_ENC_CBR_REGION_SIZE HCODEC_HENC_SCRATCH_J - -/* --------------------------------------------------- */ -/* ENCODER_STATUS define */ -/* --------------------------------------------------- */ -#define ENCODER_IDLE 0 -#define ENCODER_SEQUENCE 1 -#define ENCODER_PICTURE 2 -#define ENCODER_IDR 3 -#define ENCODER_NON_IDR 4 -#define ENCODER_MB_HEADER 5 -#define ENCODER_MB_DATA 6 - -#define ENCODER_SEQUENCE_DONE 7 -#define ENCODER_PICTURE_DONE 8 -#define ENCODER_IDR_DONE 9 -#define ENCODER_NON_IDR_DONE 10 -#define ENCODER_MB_HEADER_DONE 11 -#define ENCODER_MB_DATA_DONE 12 - -#define ENCODER_NON_IDR_INTRA 13 -#define ENCODER_NON_IDR_INTER 14 - -#define ENCODER_ERROR 0xff - -/******************************************** -* defines for H.264 mb_type -********************************************/ -#define HENC_MB_Type_PBSKIP 0x0 -#define HENC_MB_Type_PSKIP 0x0 -#define HENC_MB_Type_BSKIP_DIRECT 0x0 -#define HENC_MB_Type_P16x16 0x1 -#define HENC_MB_Type_P16x8 0x2 -#define HENC_MB_Type_P8x16 0x3 -#define HENC_MB_Type_SMB8x8 0x4 -#define HENC_MB_Type_SMB8x4 0x5 -#define HENC_MB_Type_SMB4x8 0x6 -#define HENC_MB_Type_SMB4x4 0x7 -#define HENC_MB_Type_P8x8 0x8 -#define HENC_MB_Type_I4MB 0x9 -#define HENC_MB_Type_I16MB 0xa -#define HENC_MB_Type_IBLOCK 0xb -#define HENC_MB_Type_SI4MB 0xc -#define HENC_MB_Type_I8MB 0xd -#define HENC_MB_Type_IPCM 0xe -#define HENC_MB_Type_AUTO 0xf - -#define HENC_MB_CBP_AUTO 0xff -#define HENC_SKIP_RUN_AUTO 0xffff - - -extern bool amvenc_avc_on(void); -#endif diff --git a/drivers/frame_sink/encoder/h265/Makefile b/drivers/frame_sink/encoder/h265/Makefile deleted file mode 100644 index e7414bf..0000000 --- a/drivers/frame_sink/encoder/h265/Makefile +++ b/dev/null @@ -1 +0,0 @@ -obj-m += vpu.o diff --git a/drivers/frame_sink/encoder/h265/vmm.h b/drivers/frame_sink/encoder/h265/vmm.h deleted file mode 100644 index cb0112e..0000000 --- a/drivers/frame_sink/encoder/h265/vmm.h +++ b/dev/null @@ -1,661 +0,0 @@ -/* - * vmm.h - * - * memory allocator for VPU - * - * Copyright (C) 2006 - 2013 CHIPS&MEDIA INC. - * - * 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 __CNM_VIDEO_MEMORY_MANAGEMENT_H__ -#define __CNM_VIDEO_MEMORY_MANAGEMENT_H__ - -#define VMEM_PAGE_SIZE (16 * 1024) -#define MAKE_KEY(_a, _b) (((vmem_key_t)_a) << 32 | _b) -#define KEY_TO_VALUE(_key) (_key >> 32) - -#define VMEM_P_ALLOC(_x) vmalloc(_x) -#define VMEM_P_FREE(_x) vfree(_x) - -#define VMEM_ASSERT \ - pr_info("VMEM_ASSERT at %s:%d\n", __FILE__, __LINE__) - - -#define VMEM_HEIGHT(_tree) (_tree == NULL ? -1 : _tree->height) - -#define MAX(_a, _b) (_a >= _b ? _a : _b) - -struct avl_node_t; -#define vmem_key_t unsigned long long - -struct vmem_info_t { - ulong total_pages; - ulong alloc_pages; - ulong free_pages; - ulong page_size; -}; - -struct page_t { - s32 pageno; - ulong addr; - s32 used; - s32 alloc_pages; - s32 first_pageno; -}; - -struct avl_node_t { - vmem_key_t key; - s32 height; - struct page_t *page; - struct avl_node_t *left; - struct avl_node_t *right; -}; - -struct video_mm_t { - struct avl_node_t *free_tree; - struct avl_node_t *alloc_tree; - struct page_t *page_list; - s32 num_pages; - ulong base_addr; - ulong mem_size; - s32 free_page_count; - s32 alloc_page_count; -}; - -enum rotation_dir_t { - LEFT, - RIGHT -}; - -struct avl_node_data_t { - s32 key; - struct page_t *page; -}; - -static struct avl_node_t *make_avl_node( - vmem_key_t key, - struct page_t *page) -{ - struct avl_node_t *node = - (struct avl_node_t *)VMEM_P_ALLOC(sizeof(struct avl_node_t)); - node->key = key; - node->page = page; - node->height = 0; - node->left = NULL; - node->right = NULL; - return node; -} - -static s32 get_balance_factor(struct avl_node_t *tree) -{ - s32 factor = 0; - if (tree) - factor = VMEM_HEIGHT(tree->right) - VMEM_HEIGHT(tree->left); - return factor; -} - -/* - * Left Rotation - * - * A B - * \ / \ - * B => A C - * / \ \ - * D C D - * - */ -static struct avl_node_t *rotation_left(struct avl_node_t *tree) -{ - struct avl_node_t *rchild; - struct avl_node_t *lchild; - - if (tree == NULL) - return NULL; - - rchild = tree->right; - if (rchild == NULL) - return tree; - - lchild = rchild->left; - rchild->left = tree; - tree->right = lchild; - - tree->height = - MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1; - rchild->height = - MAX(VMEM_HEIGHT(rchild->left), VMEM_HEIGHT(rchild->right)) + 1; - return rchild; -} - - -/* - * Reft Rotation - * - * A B - * \ / \ - * B => D A - * / \ / - * D C C - * - */ -static struct avl_node_t *rotation_right(struct avl_node_t *tree) -{ - struct avl_node_t *rchild; - struct avl_node_t *lchild; - - if (tree == NULL) - return NULL; - - lchild = tree->left; - if (lchild == NULL) - return NULL; - - rchild = lchild->right; - lchild->right = tree; - tree->left = rchild; - - tree->height = - MAX(VMEM_HEIGHT(tree->left), - VMEM_HEIGHT(tree->right)) + 1; - lchild->height = - MAX(VMEM_HEIGHT(lchild->left), - VMEM_HEIGHT(lchild->right)) + 1; - return lchild; -} - -static struct avl_node_t *do_balance(struct avl_node_t *tree) -{ - s32 bfactor = 0, child_bfactor; - bfactor = get_balance_factor(tree); - if (bfactor >= 2) { - child_bfactor = get_balance_factor(tree->right); - if (child_bfactor == 1 || child_bfactor == 0) { - tree = rotation_left(tree); - } else if (child_bfactor == -1) { - tree->right = rotation_right(tree->right); - tree = rotation_left(tree); - } else { - pr_info( - "invalid balancing factor: %d\n", - child_bfactor); - VMEM_ASSERT; - return NULL; - } - } else if (bfactor <= -2) { - child_bfactor = get_balance_factor(tree->left); - if (child_bfactor == -1 || child_bfactor == 0) { - tree = rotation_right(tree); - } else if (child_bfactor == 1) { - tree->left = rotation_left(tree->left); - tree = rotation_right(tree); - } else { - pr_info( - "invalid balancing factor: %d\n", - child_bfactor); - VMEM_ASSERT; - return NULL; - } - } - return tree; -} - -static struct avl_node_t *unlink_end_node( - struct avl_node_t *tree, - s32 dir, - struct avl_node_t **found_node) -{ - struct avl_node_t *node; - *found_node = NULL; - - if (tree == NULL) - return NULL; - - if (dir == LEFT) { - if (tree->left == NULL) { - *found_node = tree; - return NULL; - } - } else { - if (tree->right == NULL) { - *found_node = tree; - return NULL; - } - } - - if (dir == LEFT) { - node = tree->left; - tree->left = unlink_end_node(tree->left, LEFT, found_node); - if (tree->left == NULL) { - tree->left = (*found_node)->right; - (*found_node)->left = NULL; - (*found_node)->right = NULL; - } - } else { - node = tree->right; - tree->right = unlink_end_node(tree->right, RIGHT, found_node); - if (tree->right == NULL) { - tree->right = (*found_node)->left; - (*found_node)->left = NULL; - (*found_node)->right = NULL; - } - } - tree->height = - MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1; - return do_balance(tree); -} - - -static struct avl_node_t *avltree_insert( - struct avl_node_t *tree, - vmem_key_t key, - struct page_t *page) -{ - if (tree == NULL) { - tree = make_avl_node(key, page); - } else { - if (key >= tree->key) - tree->right = - avltree_insert(tree->right, key, page); - else - tree->left = - avltree_insert(tree->left, key, page); - } - tree = do_balance(tree); - tree->height = - MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1; - return tree; -} - -static struct avl_node_t *do_unlink(struct avl_node_t *tree) -{ - struct avl_node_t *node; - struct avl_node_t *end_node; - node = unlink_end_node(tree->right, LEFT, &end_node); - if (node) { - tree->right = node; - } else { - node = - unlink_end_node(tree->left, RIGHT, &end_node); - if (node) - tree->left = node; - } - - if (node == NULL) { - node = tree->right ? tree->right : tree->left; - end_node = node; - } - - if (end_node) { - end_node->left = - (tree->left != end_node) ? - tree->left : end_node->left; - end_node->right = - (tree->right != end_node) ? - tree->right : end_node->right; - end_node->height = - MAX(VMEM_HEIGHT(end_node->left), - VMEM_HEIGHT(end_node->right)) + 1; - } - tree = end_node; - return tree; -} - -static struct avl_node_t *avltree_remove( - struct avl_node_t *tree, - struct avl_node_t **found_node, - vmem_key_t key) -{ - *found_node = NULL; - if (tree == NULL) { - pr_info("failed to find key %d\n", (s32)key); - return NULL; - } - - if (key == tree->key) { - *found_node = tree; - tree = do_unlink(tree); - } else if (key > tree->key) { - tree->right = - avltree_remove(tree->right, found_node, key); - } else { - tree->left = - avltree_remove(tree->left, found_node, key); - } - - if (tree) - tree->height = - MAX(VMEM_HEIGHT(tree->left), - VMEM_HEIGHT(tree->right)) + 1; - - tree = do_balance(tree); - return tree; -} - -void avltree_free(struct avl_node_t *tree) -{ - if (tree == NULL) - return; - if (tree->left == NULL && tree->right == NULL) { - VMEM_P_FREE(tree); - return; - } - - avltree_free(tree->left); - tree->left = NULL; - avltree_free(tree->right); - tree->right = NULL; - VMEM_P_FREE(tree); -} - -static struct avl_node_t *remove_approx_value( - struct avl_node_t *tree, - struct avl_node_t **found, - vmem_key_t key) -{ - *found = NULL; - if (tree == NULL) - return NULL; - - if (key == tree->key) { - *found = tree; - tree = do_unlink(tree); - } else if (key > tree->key) { - tree->right = remove_approx_value(tree->right, found, key); - } else { - tree->left = remove_approx_value(tree->left, found, key); - if (*found == NULL) { - *found = tree; - tree = do_unlink(tree); - } - } - if (tree) - tree->height = - MAX(VMEM_HEIGHT(tree->left), - VMEM_HEIGHT(tree->right)) + 1; - tree = do_balance(tree); - return tree; -} - -static void set_blocks_free( - struct video_mm_t *mm, - s32 pageno, - s32 npages) -{ - s32 last_pageno = pageno + npages - 1; - s32 i; - struct page_t *page; - struct page_t *last_page; - - if (npages == 0) - VMEM_ASSERT; - - if (last_pageno >= mm->num_pages) { - pr_info( - "set_blocks_free: invalid last page number: %d\n", - last_pageno); - VMEM_ASSERT; - return; - } - - for (i = pageno; i <= last_pageno; i++) { - mm->page_list[i].used = 0; - mm->page_list[i].alloc_pages = 0; - mm->page_list[i].first_pageno = -1; - } - - page = &mm->page_list[pageno]; - page->alloc_pages = npages; - last_page = &mm->page_list[last_pageno]; - last_page->first_pageno = pageno; - mm->free_tree = - avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page); -} - -static void set_blocks_alloc( - struct video_mm_t *mm, - s32 pageno, - s32 npages) -{ - s32 last_pageno = pageno + npages - 1; - s32 i; - struct page_t *page; - struct page_t *last_page; - - if (last_pageno >= mm->num_pages) { - pr_info( - "set_blocks_free: invalid last page number: %d\n", - last_pageno); - VMEM_ASSERT; - return; - } - - for (i = pageno; i <= last_pageno; i++) { - mm->page_list[i].used = 1; - mm->page_list[i].alloc_pages = 0; - mm->page_list[i].first_pageno = -1; - } - - page = &mm->page_list[pageno]; - page->alloc_pages = npages; - last_page = &mm->page_list[last_pageno]; - last_page->first_pageno = pageno; - mm->alloc_tree = - avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page); -} - - -s32 vmem_init(struct video_mm_t *mm, ulong addr, ulong size) -{ - s32 i; - - if (NULL == mm) - return -1; - - mm->base_addr = (addr + (VMEM_PAGE_SIZE - 1)) - & ~(VMEM_PAGE_SIZE - 1); - mm->mem_size = size & ~VMEM_PAGE_SIZE; - mm->num_pages = mm->mem_size / VMEM_PAGE_SIZE; - mm->free_tree = NULL; - mm->alloc_tree = NULL; - mm->free_page_count = mm->num_pages; - mm->alloc_page_count = 0; - mm->page_list = - (struct page_t *)VMEM_P_ALLOC( - mm->num_pages * sizeof(struct page_t)); - if (mm->page_list == NULL) { - pr_err("%s:%d failed to kmalloc(%ld)\n", - __func__, __LINE__, - mm->num_pages * sizeof(struct page_t)); - return -1; - } - - for (i = 0; i < mm->num_pages; i++) { - mm->page_list[i].pageno = i; - mm->page_list[i].addr = - mm->base_addr + i * VMEM_PAGE_SIZE; - mm->page_list[i].alloc_pages = 0; - mm->page_list[i].used = 0; - mm->page_list[i].first_pageno = -1; - } - set_blocks_free(mm, 0, mm->num_pages); - return 0; -} - -s32 vmem_exit(struct video_mm_t *mm) -{ - if (mm == NULL) { - pr_info("vmem_exit: invalid handle\n"); - return -1; - } - - if (mm->free_tree) - avltree_free(mm->free_tree); - if (mm->alloc_tree) - avltree_free(mm->alloc_tree); - - if (mm->page_list) { - VMEM_P_FREE(mm->page_list); - mm->page_list = NULL; - } - - mm->base_addr = 0; - mm->mem_size = 0; - mm->num_pages = 0; - mm->page_list = NULL; - mm->free_tree = NULL; - mm->alloc_tree = NULL; - mm->free_page_count = 0; - mm->alloc_page_count = 0; - return 0; -} - -ulong vmem_alloc(struct video_mm_t *mm, s32 size, ulong pid) -{ - struct avl_node_t *node; - struct page_t *free_page; - s32 npages, free_size; - s32 alloc_pageno; - ulong ptr; - - if (mm == NULL) { - pr_info("vmem_alloc: invalid handle\n"); - return -1; - } - - if (size <= 0) - return -1; - - npages = (size + VMEM_PAGE_SIZE - 1) / VMEM_PAGE_SIZE; - mm->free_tree = remove_approx_value(mm->free_tree, - &node, MAKE_KEY(npages, 0)); - - if (node == NULL) - return -1; - - free_page = node->page; - free_size = KEY_TO_VALUE(node->key); - alloc_pageno = free_page->pageno; - set_blocks_alloc(mm, alloc_pageno, npages); - if (npages != free_size) { - s32 free_pageno = alloc_pageno + npages; - set_blocks_free(mm, free_pageno, (free_size-npages)); - } - VMEM_P_FREE(node); - - ptr = mm->page_list[alloc_pageno].addr; - mm->alloc_page_count += npages; - mm->free_page_count -= npages; - return ptr; -} - -s32 vmem_free(struct video_mm_t *mm, ulong ptr, ulong pid) -{ - ulong addr; - struct avl_node_t *found; - struct page_t *page; - s32 pageno, prev_free_pageno, next_free_pageno; - s32 prev_size, next_size; - s32 merge_page_no, merge_page_size, free_page_size; - - if (mm == NULL) { - pr_info("vmem_free: invalid handle\n"); - return -1; - } - - addr = ptr; - mm->alloc_tree = avltree_remove(mm->alloc_tree, &found, - MAKE_KEY(addr, 0)); - - if (found == NULL) { - pr_info("vmem_free: 0x%08x not found\n", (s32)addr); - VMEM_ASSERT; - return -1; - } - - /* find previous free block */ - page = found->page; - pageno = page->pageno; - free_page_size = page->alloc_pages; - prev_free_pageno = pageno - 1; - prev_size = -1; - if (prev_free_pageno >= 0) { - if (mm->page_list[prev_free_pageno].used == 0) { - prev_free_pageno = - mm->page_list[prev_free_pageno].first_pageno; - prev_size = - mm->page_list[prev_free_pageno].alloc_pages; - } - } - - /* find next free block */ - next_free_pageno = pageno + page->alloc_pages; - next_free_pageno = - (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno; - next_size = -1; - if (next_free_pageno >= 0) { - if (mm->page_list[next_free_pageno].used == 0) { - next_size = - mm->page_list[next_free_pageno].alloc_pages; - } - } - VMEM_P_FREE(found); - - /* merge */ - merge_page_no = page->pageno; - merge_page_size = page->alloc_pages; - if (prev_size >= 0) { - mm->free_tree = avltree_remove(mm->free_tree, &found, - MAKE_KEY(prev_size, prev_free_pageno)); - if (found == NULL) { - VMEM_ASSERT; - return -1; - } - merge_page_no = found->page->pageno; - merge_page_size += found->page->alloc_pages; - VMEM_P_FREE(found); - } - if (next_size >= 0) { - mm->free_tree = avltree_remove(mm->free_tree, &found, - MAKE_KEY(next_size, next_free_pageno)); - if (found == NULL) { - VMEM_ASSERT; - return -1; - } - merge_page_size += found->page->alloc_pages; - VMEM_P_FREE(found); - } - page->alloc_pages = 0; - page->first_pageno = -1; - set_blocks_free(mm, merge_page_no, merge_page_size); - mm->alloc_page_count -= free_page_size; - mm->free_page_count += free_page_size; - return 0; -} - -s32 vmem_get_info(struct video_mm_t *mm, struct vmem_info_t *info) -{ - if (mm == NULL) { - pr_info("vmem_get_info: invalid handle\n"); - return -1; - } - - if (info == NULL) - return -1; - - info->total_pages = mm->num_pages; - info->alloc_pages = mm->alloc_page_count; - info->free_pages = mm->free_page_count; - info->page_size = VMEM_PAGE_SIZE; - return 0; -} -#endif /* __CNM_VIDEO_MEMORY_MANAGEMENT_H__ */ diff --git a/drivers/frame_sink/encoder/h265/vpu.c b/drivers/frame_sink/encoder/h265/vpu.c deleted file mode 100644 index 26c40fd..0000000 --- a/drivers/frame_sink/encoder/h265/vpu.c +++ b/dev/null @@ -1,1997 +0,0 @@ -/* - * vpu.c - * - * linux device driver for VPU. - * - * Copyright (C) 2006 - 2013 CHIPS&MEDIA INC. - * - * 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/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/wait.h> -#include <linux/list.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/uaccess.h> -#include <linux/cdev.h> -#include <linux/slab.h> -#include <linux/sched.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_fdt.h> -#include <linux/reset.h> -#include <linux/clk.h> -#include <linux/compat.h> -#include <linux/of_reserved_mem.h> -#include <linux/of_address.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../../common/media_clock/switch/amports_gate.h" - -#include "vpu.h" -#include "vmm.h" - -/* definitions to be changed as customer configuration */ -/* if you want to have clock gating scheme frame by frame */ -/* #define VPU_SUPPORT_CLOCK_CONTROL */ - -#define VPU_PLATFORM_DEVICE_NAME "HevcEnc" -#define VPU_DEV_NAME "HevcEnc" -#define VPU_CLASS_NAME "HevcEnc" - -#ifndef VM_RESERVED /*for kernel up to 3.7.0 version*/ -#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP) -#endif - -#define VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE (64 * SZ_1M) - -#define LOG_ALL 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 -#define LOG_ERROR 3 - -#define enc_pr(level, x...) \ - do { \ - if (level >= print_level) \ - printk(x); \ - } while (0) - -static s32 print_level = LOG_DEBUG; -static s32 clock_level = 4; - -static struct video_mm_t s_vmem; -static struct vpudrv_buffer_t s_video_memory = {0}; -static bool use_reserve; -static ulong cma_pool_size; - -/* end customer definition */ -static struct vpudrv_buffer_t s_instance_pool = {0}; -static struct vpudrv_buffer_t s_common_memory = {0}; -static struct vpu_drv_context_t s_vpu_drv_context; -static s32 s_vpu_major; -static struct device *hevcenc_dev; - -static s32 s_vpu_open_ref_count; -static s32 s_vpu_irq; -static bool s_vpu_irq_requested; - -static struct vpudrv_buffer_t s_vpu_register = {0}; - -static s32 s_interrupt_flag; -static wait_queue_head_t s_interrupt_wait_q; - -static spinlock_t s_vpu_lock = __SPIN_LOCK_UNLOCKED(s_vpu_lock); -static DEFINE_SEMAPHORE(s_vpu_sem); -static struct list_head s_vbp_head = LIST_HEAD_INIT(s_vbp_head); -static struct list_head s_inst_list_head = LIST_HEAD_INIT(s_inst_list_head); -static struct tasklet_struct hevc_tasklet; -static struct platform_device *hevc_pdev; - -static struct vpu_bit_firmware_info_t s_bit_firmware_info[MAX_NUM_VPU_CORE]; - -static void dma_flush(u32 buf_start , u32 buf_size) -{ - if (hevc_pdev) - dma_sync_single_for_device( - &hevc_pdev->dev, buf_start, - buf_size, DMA_TO_DEVICE); -} - -static void cache_flush(u32 buf_start , u32 buf_size) -{ - if (hevc_pdev) - dma_sync_single_for_cpu( - &hevc_pdev->dev, buf_start, - buf_size, DMA_FROM_DEVICE); -} - -s32 vpu_hw_reset(void) -{ - enc_pr(LOG_DEBUG, "request vpu reset from application.\n"); - return 0; -} - -s32 vpu_clk_config(u32 enable) -{ - if (enable) - HevcEnc_clock_enable(clock_level); - else - HevcEnc_clock_disable(); - return 0; -} - -static s32 vpu_alloc_dma_buffer(struct vpudrv_buffer_t *vb) -{ - if (!vb) - return -1; - - vb->phys_addr = (ulong)vmem_alloc(&s_vmem, vb->size, 0); - if ((ulong)vb->phys_addr == (ulong)-1) { - enc_pr(LOG_ERROR, - "Physical memory allocation error size=%d\n", vb->size); - return -1; - } - - vb->base = (ulong)(s_video_memory.base + - (vb->phys_addr - s_video_memory.phys_addr)); - return 0; -} - -static void vpu_free_dma_buffer(struct vpudrv_buffer_t *vb) -{ - if (!vb) - return; - - if (vb->base) - vmem_free(&s_vmem, vb->phys_addr, 0); -} - -static s32 vpu_free_instances(struct file *filp) -{ - struct vpudrv_instanace_list_t *vil, *n; - struct vpudrv_instance_pool_t *vip; - void *vip_base; - - enc_pr(LOG_DEBUG, "vpu_free_instances\n"); - - list_for_each_entry_safe(vil, n, &s_inst_list_head, list) - { - if (vil->filp == filp) { - vip_base = (void *)s_instance_pool.base; - enc_pr(LOG_INFO, - "free_instances instIdx=%d, coreIdx=%d, vip_base=%p\n", - (s32)vil->inst_idx, - (s32)vil->core_idx, - vip_base); - vip = (struct vpudrv_instance_pool_t *)vip_base; - if (vip) { - /* only first 4 byte is key point - (inUse of CodecInst in vpuapi) - to free the corresponding instance. */ - memset(&vip->codecInstPool[vil->inst_idx], - 0x00, 4); - } - s_vpu_open_ref_count--; - list_del(&vil->list); - kfree(vil); - } - } - return 1; -} - -static s32 vpu_free_buffers(struct file *filp) -{ - struct vpudrv_buffer_pool_t *pool, *n; - struct vpudrv_buffer_t vb; - - enc_pr(LOG_DEBUG, "vpu_free_buffers\n"); - - list_for_each_entry_safe(pool, n, &s_vbp_head, list) - { - if (pool->filp == filp) { - vb = pool->vb; - if (vb.base) { - vpu_free_dma_buffer(&vb); - list_del(&pool->list); - kfree(pool); - } - } - } - return 0; -} - -static u32 vpu_is_buffer_cached(struct file *filp, ulong vm_pgoff) -{ - struct vpudrv_buffer_pool_t *pool, *n; - struct vpudrv_buffer_t vb; - bool find = false; - u32 cached = 0; - - enc_pr(LOG_ALL, "[+]vpu_is_buffer_cached\n"); - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(pool, n, &s_vbp_head, list) - { - if (pool->filp == filp) { - vb = pool->vb; - if (((vb.phys_addr >> PAGE_SHIFT) == vm_pgoff) - && find == false){ - cached = vb.cached; - find = true; - } - } - } - spin_unlock(&s_vpu_lock); - enc_pr(LOG_ALL, "[-]vpu_is_buffer_cached, ret:%d\n", cached); - return cached; -} - -static void hevcenc_isr_tasklet(ulong data) -{ - struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)data; - enc_pr(LOG_INFO, "hevcenc_isr_tasklet interruput:0x%08lx\n", - dev->interrupt_reason); - if (dev->interrupt_reason) { - /* notify the interrupt to user space */ - if (dev->async_queue) { - enc_pr(LOG_ALL, "kill_fasync e %s\n", __func__); - kill_fasync(&dev->async_queue, SIGIO, POLL_IN); - } - s_interrupt_flag = 1; - wake_up_interruptible(&s_interrupt_wait_q); - } - enc_pr(LOG_ALL, "[-]%s\n", __func__); -} - -static irqreturn_t vpu_irq_handler(s32 irq, void *dev_id) -{ - struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)dev_id; - /* this can be removed. - it also work in VPU_WaitInterrupt of API function */ - u32 core; - ulong interrupt_reason = 0; - enc_pr(LOG_ALL, "[+]%s\n", __func__); - - for (core = 0; core < MAX_NUM_VPU_CORE; core++) { - if (s_bit_firmware_info[core].size == 0) { - /* it means that we didn't get an information - the current core from API layer. - No core activated.*/ - enc_pr(LOG_ERROR, - "s_bit_firmware_info[core].size is zero\n"); - continue; - } - if (ReadVpuRegister(W4_VPU_VPU_INT_STS)) { - interrupt_reason = ReadVpuRegister(W4_VPU_INT_REASON); - WriteVpuRegister(W4_VPU_INT_REASON_CLEAR, - interrupt_reason); - WriteVpuRegister(W4_VPU_VINT_CLEAR, 0x1); - dev->interrupt_reason |= interrupt_reason; - } - enc_pr(LOG_INFO, - "intr_reason: 0x%08lx\n", dev->interrupt_reason); - } - if (dev->interrupt_reason) - tasklet_schedule(&hevc_tasklet); - enc_pr(LOG_ALL, "[-]%s\n", __func__); - return IRQ_HANDLED; -} - -static s32 vpu_open(struct inode *inode, struct file *filp) -{ - bool alloc_buffer = false; - s32 r = 0; - enc_pr(LOG_DEBUG, "[+] %s\n", __func__); - spin_lock(&s_vpu_lock); - s_vpu_drv_context.open_count++; - if (s_vpu_drv_context.open_count == 1) { - alloc_buffer = true; - } else { - r = -EBUSY; - s_vpu_drv_context.open_count--; - spin_unlock(&s_vpu_lock); - goto Err; - } - filp->private_data = (void *)(&s_vpu_drv_context); - spin_unlock(&s_vpu_lock); - if (alloc_buffer && !use_reserve) { -#ifdef CONFIG_CMA - s_video_memory.size = VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE; - s_video_memory.phys_addr = - (ulong)codec_mm_alloc_for_dma(VPU_DEV_NAME, - VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE >> PAGE_SHIFT, 0, - CODEC_MM_FLAGS_CPU); - if (s_video_memory.phys_addr) - s_video_memory.base = - (ulong)phys_to_virt(s_video_memory.phys_addr); - else - s_video_memory.base = 0; - if (s_video_memory.base) { - enc_pr(LOG_DEBUG, - "allocating phys 0x%lx, virt addr 0x%lx, size %dk\n", - s_video_memory.phys_addr, - s_video_memory.base, - s_video_memory.size >> 10); - if (vmem_init(&s_vmem, - s_video_memory.phys_addr, - s_video_memory.size) < 0) { - enc_pr(LOG_ERROR, "fail to init vmem system\n"); - r = -ENOMEM; - codec_mm_free_for_dma( - VPU_DEV_NAME, - (u32)s_video_memory.phys_addr); - vmem_exit(&s_vmem); - memset(&s_video_memory, 0, - sizeof(struct vpudrv_buffer_t)); - memset(&s_vmem, 0, - sizeof(struct video_mm_t)); - } - } else { - enc_pr(LOG_ERROR, - "CMA failed to allocate dma buffer for %s, phys: 0x%lx\n", - VPU_DEV_NAME, s_video_memory.phys_addr); - if (s_video_memory.phys_addr) - codec_mm_free_for_dma( - VPU_DEV_NAME, - (u32)s_video_memory.phys_addr); - s_video_memory.phys_addr = 0; - r = -ENOMEM; - } -#else - enc_pr(LOG_ERROR, - "No CMA and reserved memory for HevcEnc!!!\n"); - r = -ENOMEM; -#endif - } else if (!s_video_memory.base) { - enc_pr(LOG_ERROR, - "HevcEnc memory is not malloced!!!\n"); - r = -ENOMEM; - } - if (alloc_buffer) { - ulong flags; - u32 data32; - if ((s_vpu_irq >= 0) && (s_vpu_irq_requested == false)) { - s32 err; - err = request_irq(s_vpu_irq, vpu_irq_handler, 0, - "HevcEnc-irq", (void *)(&s_vpu_drv_context)); - if (err) { - enc_pr(LOG_ERROR, - "fail to register interrupt handler\n"); - return -EFAULT; - } - s_vpu_irq_requested = true; - } - amports_switch_gate("vdec", 1); - spin_lock_irqsave(&s_vpu_lock, flags); - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~(0x3<<24)); - udelay(10); - - data32 = 0x700; - data32 |= READ_VREG(DOS_SW_RESET4); - WRITE_VREG(DOS_SW_RESET4, data32); - data32 &= ~0x700; - WRITE_VREG(DOS_SW_RESET4, data32); - - WRITE_MPEG_REG(RESET0_REGISTER, data32 & ~(1<<21)); - WRITE_MPEG_REG(RESET0_REGISTER, data32 | (1<<21)); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); - READ_MPEG_REG(RESET0_REGISTER); -#ifndef VPU_SUPPORT_CLOCK_CONTROL - vpu_clk_config(1); -#endif - /* Enable wave420l_vpu_idle_rise_irq, - Disable wave420l_vpu_idle_fall_irq */ - WRITE_VREG(DOS_WAVE420L_CNTL_STAT, 0x1); - WRITE_VREG(DOS_MEM_PD_WAVE420L, 0x0); - - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~(0x3<<12)); - udelay(10); - - spin_unlock_irqrestore(&s_vpu_lock, flags); - } -Err: - enc_pr(LOG_DEBUG, "[-] %s, ret: %d\n", __func__, r); - return r; -} - -static long vpu_ioctl(struct file *filp, u32 cmd, ulong arg) -{ - s32 ret = 0; - struct vpu_drv_context_t *dev = - (struct vpu_drv_context_t *)filp->private_data; - - switch (cmd) { - case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY: - { - struct vpudrv_buffer_pool_t *vbp; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret == 0) { - vbp = kzalloc(sizeof(*vbp), GFP_KERNEL); - if (!vbp) { - up(&s_vpu_sem); - return -ENOMEM; - } - - ret = copy_from_user(&(vbp->vb), - (struct vpudrv_buffer_t *)arg, - sizeof(struct vpudrv_buffer_t)); - if (ret) { - kfree(vbp); - up(&s_vpu_sem); - return -EFAULT; - } - - ret = vpu_alloc_dma_buffer(&(vbp->vb)); - if (ret == -1) { - ret = -ENOMEM; - kfree(vbp); - up(&s_vpu_sem); - break; - } - ret = copy_to_user((void __user *)arg, - &(vbp->vb), - sizeof(struct vpudrv_buffer_t)); - if (ret) { - kfree(vbp); - ret = -EFAULT; - up(&s_vpu_sem); - break; - } - - vbp->filp = filp; - spin_lock(&s_vpu_lock); - list_add(&vbp->list, &s_vbp_head); - spin_unlock(&s_vpu_lock); - - up(&s_vpu_sem); - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n"); - } - break; - case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32: - { - struct vpudrv_buffer_pool_t *vbp; - struct compat_vpudrv_buffer_t buf32; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret == 0) { - vbp = kzalloc(sizeof(*vbp), GFP_KERNEL); - if (!vbp) { - up(&s_vpu_sem); - return -ENOMEM; - } - - ret = copy_from_user(&buf32, - (struct compat_vpudrv_buffer_t *)arg, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret) { - kfree(vbp); - up(&s_vpu_sem); - return -EFAULT; - } - - vbp->vb.size = buf32.size; - vbp->vb.cached = buf32.cached; - vbp->vb.phys_addr = - (ulong)buf32.phys_addr; - vbp->vb.base = - (ulong)buf32.base; - vbp->vb.virt_addr = - (ulong)buf32.virt_addr; - ret = vpu_alloc_dma_buffer(&(vbp->vb)); - if (ret == -1) { - ret = -ENOMEM; - kfree(vbp); - up(&s_vpu_sem); - break; - } - - buf32.size = vbp->vb.size; - buf32.phys_addr = - (compat_ulong_t)vbp->vb.phys_addr; - buf32.base = - (compat_ulong_t)vbp->vb.base; - buf32.virt_addr = - (compat_ulong_t)vbp->vb.virt_addr; - - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret) { - kfree(vbp); - ret = -EFAULT; - up(&s_vpu_sem); - break; - } - - vbp->filp = filp; - spin_lock(&s_vpu_lock); - list_add(&vbp->list, &s_vbp_head); - spin_unlock(&s_vpu_lock); - - up(&s_vpu_sem); - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32\n"); - } - break; - case VDI_IOCTL_FREE_PHYSICALMEMORY: - { - struct vpudrv_buffer_pool_t *vbp, *n; - struct vpudrv_buffer_t vb; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_FREE_PHYSICALMEMORY\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret == 0) { - ret = copy_from_user(&vb, - (struct vpudrv_buffer_t *)arg, - sizeof(struct vpudrv_buffer_t)); - if (ret) { - up(&s_vpu_sem); - return -EACCES; - } - - if (vb.base) - vpu_free_dma_buffer(&vb); - - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(vbp, n, - &s_vbp_head, list) - { - if (vbp->vb.base == vb.base) { - list_del(&vbp->list); - kfree(vbp); - break; - } - } - spin_unlock(&s_vpu_lock); - up(&s_vpu_sem); - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_FREE_PHYSICALMEMORY\n"); - } - break; - case VDI_IOCTL_FREE_PHYSICALMEMORY32: - { - struct vpudrv_buffer_pool_t *vbp, *n; - struct compat_vpudrv_buffer_t buf32; - struct vpudrv_buffer_t vb; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_FREE_PHYSICALMEMORY32\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret == 0) { - ret = copy_from_user(&buf32, - (struct compat_vpudrv_buffer_t *)arg, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret) { - up(&s_vpu_sem); - return -EACCES; - } - - vb.size = buf32.size; - vb.phys_addr = - (ulong)buf32.phys_addr; - vb.base = - (ulong)buf32.base; - vb.virt_addr = - (ulong)buf32.virt_addr; - - if (vb.base) - vpu_free_dma_buffer(&vb); - - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(vbp, n, - &s_vbp_head, list) - { - if ((compat_ulong_t)vbp->vb.base - == buf32.base) { - list_del(&vbp->list); - kfree(vbp); - break; - } - } - spin_unlock(&s_vpu_lock); - up(&s_vpu_sem); - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_FREE_PHYSICALMEMORY32\n"); - } - break; - case VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO: - { - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO\n"); - if (s_video_memory.base != 0) { - ret = copy_to_user((void __user *)arg, - &s_video_memory, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else { - ret = -EFAULT; - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO\n"); - } - break; - case VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32: - { - struct compat_vpudrv_buffer_t buf32; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32\n"); - - buf32.size = s_video_memory.size; - buf32.phys_addr = - (compat_ulong_t)s_video_memory.phys_addr; - buf32.base = - (compat_ulong_t)s_video_memory.base; - buf32.virt_addr = - (compat_ulong_t)s_video_memory.virt_addr; - if (s_video_memory.base != 0) { - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else { - ret = -EFAULT; - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32\n"); - } - break; - case VDI_IOCTL_WAIT_INTERRUPT: - { - struct vpudrv_intr_info_t info; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_WAIT_INTERRUPT\n"); - ret = copy_from_user(&info, - (struct vpudrv_intr_info_t *)arg, - sizeof(struct vpudrv_intr_info_t)); - if (ret != 0) - return -EFAULT; - - ret = wait_event_interruptible_timeout( - s_interrupt_wait_q, - s_interrupt_flag != 0, - msecs_to_jiffies(info.timeout)); - if (!ret) { - ret = -ETIME; - break; - } - if (dev->interrupt_reason & (1 << W4_INT_ENC_PIC)) { - u32 start, end, size, core = 0; - start = ReadVpuRegister(W4_BS_RD_PTR); - end = ReadVpuRegister(W4_BS_WR_PTR); - size = ReadVpuRegister(W4_RET_ENC_PIC_BYTE); - enc_pr(LOG_INFO, "flush output buffer, "); - enc_pr(LOG_INFO, - "start:0x%x, end:0x%x, size:0x%x\n", - start, end, size); - if (end - start > size && end > start) - size = end - start; - if (size > 0) - cache_flush(start, size); - } - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - enc_pr(LOG_INFO, - "s_interrupt_flag(%d), reason(0x%08lx)\n", - s_interrupt_flag, dev->interrupt_reason); - - info.intr_reason = dev->interrupt_reason; - s_interrupt_flag = 0; - dev->interrupt_reason = 0; - ret = copy_to_user((void __user *)arg, - &info, sizeof(struct vpudrv_intr_info_t)); - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_WAIT_INTERRUPT\n"); - if (ret != 0) - return -EFAULT; - } - break; - case VDI_IOCTL_SET_CLOCK_GATE: - { - u32 clkgate; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_SET_CLOCK_GATE\n"); - if (get_user(clkgate, (u32 __user *) arg)) - return -EFAULT; -#ifdef VPU_SUPPORT_CLOCK_CONTROL - vpu_clk_config(clkgate); -#endif - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_SET_CLOCK_GATE\n"); - } - break; - case VDI_IOCTL_GET_INSTANCE_POOL: - { - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_INSTANCE_POOL\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret != 0) - break; - - if (s_instance_pool.base != 0) { - ret = copy_to_user((void __user *)arg, - &s_instance_pool, - sizeof(struct vpudrv_buffer_t)); - ret = (ret != 0) ? -EFAULT : 0; - } else { - ret = copy_from_user(&s_instance_pool, - (struct vpudrv_buffer_t *)arg, - sizeof(struct vpudrv_buffer_t)); - if (ret == 0) { - s_instance_pool.size = - PAGE_ALIGN( - s_instance_pool.size); - s_instance_pool.base = - (ulong)vmalloc( - s_instance_pool.size); - s_instance_pool.phys_addr = - s_instance_pool.base; - if (s_instance_pool.base == 0) { - ret = -EFAULT; - up(&s_vpu_sem); - break; - } - /*clearing memory*/ - memset((void *)s_instance_pool.base, - 0, s_instance_pool.size); - ret = copy_to_user((void __user *)arg, - &s_instance_pool, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else - ret = -EFAULT; - } - up(&s_vpu_sem); - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_INSTANCE_POOL\n"); - } - break; - case VDI_IOCTL_GET_INSTANCE_POOL32: - { - struct compat_vpudrv_buffer_t buf32; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_INSTANCE_POOL32\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret != 0) - break; - if (s_instance_pool.base != 0) { - buf32.size = s_instance_pool.size; - buf32.phys_addr = - (compat_ulong_t) - s_instance_pool.phys_addr; - buf32.base = - (compat_ulong_t) - s_instance_pool.base; - buf32.virt_addr = - (compat_ulong_t) - s_instance_pool.virt_addr; - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof(struct compat_vpudrv_buffer_t)); - ret = (ret != 0) ? -EFAULT : 0; - } else { - ret = copy_from_user(&buf32, - (struct compat_vpudrv_buffer_t *)arg, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret == 0) { - s_instance_pool.size = buf32.size; - s_instance_pool.size = - PAGE_ALIGN( - s_instance_pool.size); - s_instance_pool.base = - (ulong)vmalloc( - s_instance_pool.size); - s_instance_pool.phys_addr = - s_instance_pool.base; - buf32.size = - s_instance_pool.size; - buf32.phys_addr = - (compat_ulong_t) - s_instance_pool.phys_addr; - buf32.base = - (compat_ulong_t) - s_instance_pool.base; - buf32.virt_addr = - (compat_ulong_t) - s_instance_pool.virt_addr; - if (s_instance_pool.base == 0) { - ret = -EFAULT; - up(&s_vpu_sem); - break; - } - /*clearing memory*/ - memset((void *)s_instance_pool.base, - 0x0, s_instance_pool.size); - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof( - struct compat_vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else - ret = -EFAULT; - } - up(&s_vpu_sem); - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_INSTANCE_POOL32\n"); - } - break; - case VDI_IOCTL_GET_COMMON_MEMORY: - { - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_COMMON_MEMORY\n"); - if (s_common_memory.base != 0) { - ret = copy_to_user((void __user *)arg, - &s_common_memory, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else { - ret = copy_from_user(&s_common_memory, - (struct vpudrv_buffer_t *)arg, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) { - ret = -EFAULT; - break; - } - if (vpu_alloc_dma_buffer( - &s_common_memory) != -1) { - ret = copy_to_user((void __user *)arg, - &s_common_memory, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else - ret = -EFAULT; - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_COMMON_MEMORY\n"); - } - break; - case VDI_IOCTL_GET_COMMON_MEMORY32: - { - struct compat_vpudrv_buffer_t buf32; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_COMMON_MEMORY32\n"); - - buf32.size = s_common_memory.size; - buf32.phys_addr = - (compat_ulong_t) - s_common_memory.phys_addr; - buf32.base = - (compat_ulong_t) - s_common_memory.base; - buf32.virt_addr = - (compat_ulong_t) - s_common_memory.virt_addr; - if (s_common_memory.base != 0) { - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else { - ret = copy_from_user(&buf32, - (struct compat_vpudrv_buffer_t *)arg, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret != 0) { - ret = -EFAULT; - break; - } - s_common_memory.size = buf32.size; - if (vpu_alloc_dma_buffer( - &s_common_memory) != -1) { - buf32.size = - s_common_memory.size; - buf32.phys_addr = - (compat_ulong_t) - s_common_memory.phys_addr; - buf32.base = - (compat_ulong_t) - s_common_memory.base; - buf32.virt_addr = - (compat_ulong_t) - s_common_memory.virt_addr; - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof( - struct compat_vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - } else - ret = -EFAULT; - } - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_COMMON_MEMORY32\n"); - } - break; - case VDI_IOCTL_OPEN_INSTANCE: - { - struct vpudrv_inst_info_t inst_info; - struct vpudrv_instanace_list_t *vil, *n; - - vil = kzalloc(sizeof(*vil), GFP_KERNEL); - if (!vil) - return -ENOMEM; - - if (copy_from_user(&inst_info, - (struct vpudrv_inst_info_t *)arg, - sizeof(struct vpudrv_inst_info_t))) - return -EFAULT; - - vil->inst_idx = inst_info.inst_idx; - vil->core_idx = inst_info.core_idx; - vil->filp = filp; - - spin_lock(&s_vpu_lock); - list_add(&vil->list, &s_inst_list_head); - - /* counting the current open instance number */ - inst_info.inst_open_count = 0; - list_for_each_entry_safe(vil, n, - &s_inst_list_head, list) - { - if (vil->core_idx == inst_info.core_idx) - inst_info.inst_open_count++; - } - - /* flag just for that vpu is in opened or closed */ - s_vpu_open_ref_count++; - spin_unlock(&s_vpu_lock); - - if (copy_to_user((void __user *)arg, - &inst_info, - sizeof(struct vpudrv_inst_info_t))) { - kfree(vil); - return -EFAULT; - } - - enc_pr(LOG_DEBUG, - "VDI_IOCTL_OPEN_INSTANCE "); - enc_pr(LOG_DEBUG, - "core_idx=%d, inst_idx=%d, ", - (u32)inst_info.core_idx, - (u32)inst_info.inst_idx); - enc_pr(LOG_DEBUG, - "s_vpu_open_ref_count=%d, inst_open_count=%d\n", - s_vpu_open_ref_count, - inst_info.inst_open_count); - } - break; - case VDI_IOCTL_CLOSE_INSTANCE: - { - struct vpudrv_inst_info_t inst_info; - struct vpudrv_instanace_list_t *vil, *n; - - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_CLOSE_INSTANCE\n"); - if (copy_from_user(&inst_info, - (struct vpudrv_inst_info_t *)arg, - sizeof(struct vpudrv_inst_info_t))) - return -EFAULT; - - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(vil, n, - &s_inst_list_head, list) - { - if (vil->inst_idx == inst_info.inst_idx && - vil->core_idx == inst_info.core_idx) { - list_del(&vil->list); - kfree(vil); - break; - } - } - - /* counting the current open instance number */ - inst_info.inst_open_count = 0; - list_for_each_entry_safe(vil, n, - &s_inst_list_head, list) - { - if (vil->core_idx == inst_info.core_idx) - inst_info.inst_open_count++; - } - - /* flag just for that vpu is in opened or closed */ - s_vpu_open_ref_count--; - spin_unlock(&s_vpu_lock); - - if (copy_to_user((void __user *)arg, - &inst_info, - sizeof(struct vpudrv_inst_info_t))) - return -EFAULT; - - enc_pr(LOG_DEBUG, - "VDI_IOCTL_CLOSE_INSTANCE "); - enc_pr(LOG_DEBUG, - "core_idx=%d, inst_idx=%d, ", - (u32)inst_info.core_idx, - (u32)inst_info.inst_idx); - enc_pr(LOG_DEBUG, - "s_vpu_open_ref_count=%d, inst_open_count=%d\n", - s_vpu_open_ref_count, - inst_info.inst_open_count); - } - break; - case VDI_IOCTL_GET_INSTANCE_NUM: - { - struct vpudrv_inst_info_t inst_info; - struct vpudrv_instanace_list_t *vil, *n; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_INSTANCE_NUM\n"); - - ret = copy_from_user(&inst_info, - (struct vpudrv_inst_info_t *)arg, - sizeof(struct vpudrv_inst_info_t)); - if (ret != 0) - break; - - inst_info.inst_open_count = 0; - - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(vil, n, - &s_inst_list_head, list) - { - if (vil->core_idx == inst_info.core_idx) - inst_info.inst_open_count++; - } - spin_unlock(&s_vpu_lock); - - ret = copy_to_user((void __user *)arg, - &inst_info, - sizeof(struct vpudrv_inst_info_t)); - - enc_pr(LOG_DEBUG, - "VDI_IOCTL_GET_INSTANCE_NUM "); - enc_pr(LOG_DEBUG, - "core_idx=%d, inst_idx=%d, open_count=%d\n", - (u32)inst_info.core_idx, - (u32)inst_info.inst_idx, - inst_info.inst_open_count); - } - break; - case VDI_IOCTL_RESET: - { - vpu_hw_reset(); - } - break; - case VDI_IOCTL_GET_REGISTER_INFO: - { - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_REGISTER_INFO\n"); - ret = copy_to_user((void __user *)arg, - &s_vpu_register, - sizeof(struct vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_REGISTER_INFO "); - enc_pr(LOG_ALL, - "s_vpu_register.phys_addr=0x%lx, ", - s_vpu_register.phys_addr); - enc_pr(LOG_ALL, - "s_vpu_register.virt_addr=0x%lx, ", - s_vpu_register.virt_addr); - enc_pr(LOG_ALL, - "s_vpu_register.size=0x%x\n", - s_vpu_register.size); - } - break; - case VDI_IOCTL_GET_REGISTER_INFO32: - { - struct compat_vpudrv_buffer_t buf32; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_GET_REGISTER_INFO32\n"); - - buf32.size = s_vpu_register.size; - buf32.phys_addr = - (compat_ulong_t) - s_vpu_register.phys_addr; - buf32.base = - (compat_ulong_t) - s_vpu_register.base; - buf32.virt_addr = - (compat_ulong_t) - s_vpu_register.virt_addr; - ret = copy_to_user((void __user *)arg, - &buf32, - sizeof( - struct compat_vpudrv_buffer_t)); - if (ret != 0) - ret = -EFAULT; - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_GET_REGISTER_INFO32 "); - enc_pr(LOG_ALL, - "s_vpu_register.phys_addr=0x%lx, ", - s_vpu_register.phys_addr); - enc_pr(LOG_ALL, - "s_vpu_register.virt_addr=0x%lx, ", - s_vpu_register.virt_addr); - enc_pr(LOG_ALL, - "s_vpu_register.size=0x%x\n", - s_vpu_register.size); - } - break; - case VDI_IOCTL_FLUSH_BUFFER32: - { - struct vpudrv_buffer_pool_t *pool, *n; - struct compat_vpudrv_buffer_t buf32; - struct vpudrv_buffer_t vb; - bool find = false; - u32 cached = 0; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_FLUSH_BUFFER32\n"); - - ret = copy_from_user(&buf32, - (struct compat_vpudrv_buffer_t *)arg, - sizeof(struct compat_vpudrv_buffer_t)); - if (ret) - return -EFAULT; - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(pool, n, - &s_vbp_head, list) - { - if (pool->filp == filp) { - vb = pool->vb; - if (((compat_ulong_t)vb.phys_addr - == buf32.phys_addr) - && find == false){ - cached = vb.cached; - find = true; - } - } - } - spin_unlock(&s_vpu_lock); - if (find && cached) - dma_flush( - (u32)buf32.phys_addr, - (u32)buf32.size); - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_FLUSH_BUFFER32\n"); - } - break; - case VDI_IOCTL_FLUSH_BUFFER: - { - struct vpudrv_buffer_pool_t *pool, *n; - struct vpudrv_buffer_t vb, buf; - bool find = false; - u32 cached = 0; - enc_pr(LOG_ALL, - "[+]VDI_IOCTL_FLUSH_BUFFER\n"); - - ret = copy_from_user(&buf, - (struct vpudrv_buffer_t *)arg, - sizeof(struct vpudrv_buffer_t)); - if (ret) - return -EFAULT; - spin_lock(&s_vpu_lock); - list_for_each_entry_safe(pool, n, - &s_vbp_head, list) - { - if (pool->filp == filp) { - vb = pool->vb; - if ((vb.phys_addr - == buf.phys_addr) - && find == false){ - cached = vb.cached; - find = true; - } - } - } - spin_unlock(&s_vpu_lock); - if (find && cached) - dma_flush( - (u32)buf.phys_addr, - (u32)buf.size); - enc_pr(LOG_ALL, - "[-]VDI_IOCTL_FLUSH_BUFFER\n"); - } - break; - default: - { - enc_pr(LOG_ERROR, - "No such IOCTL, cmd is %d\n", cmd); - } - break; - } - return ret; -} - -#ifdef CONFIG_COMPAT -static long vpu_compat_ioctl(struct file *filp, u32 cmd, ulong arg) -{ - long ret; - - arg = (ulong)compat_ptr(arg); - ret = vpu_ioctl(filp, cmd, arg); - return ret; -} -#endif - -static ssize_t vpu_write(struct file *filp, - const char *buf, - size_t len, - loff_t *ppos) -{ - enc_pr(LOG_INFO, "vpu_write len=%d\n", (int)len); - - if (!buf) { - enc_pr(LOG_ERROR, "vpu_write buf = NULL error\n"); - return -EFAULT; - } - - if (len == sizeof(struct vpu_bit_firmware_info_t)) { - struct vpu_bit_firmware_info_t *bit_firmware_info; - bit_firmware_info = - kmalloc(sizeof(struct vpu_bit_firmware_info_t), - GFP_KERNEL); - if (!bit_firmware_info) { - enc_pr(LOG_ERROR, - "vpu_write bit_firmware_info allocation error\n"); - return -EFAULT; - } - - if (copy_from_user(bit_firmware_info, buf, len)) { - enc_pr(LOG_ERROR, - "vpu_write copy_from_user error for bit_firmware_info\n"); - return -EFAULT; - } - - if (bit_firmware_info->size == - sizeof(struct vpu_bit_firmware_info_t)) { - enc_pr(LOG_INFO, - "vpu_write set bit_firmware_info coreIdx=0x%x, ", - bit_firmware_info->core_idx); - enc_pr(LOG_INFO, - "reg_base_offset=0x%x size=0x%x, bit_code[0]=0x%x\n", - bit_firmware_info->reg_base_offset, - bit_firmware_info->size, - bit_firmware_info->bit_code[0]); - - if (bit_firmware_info->core_idx - > MAX_NUM_VPU_CORE) { - enc_pr(LOG_ERROR, - "vpu_write coreIdx[%d] is ", - bit_firmware_info->core_idx); - enc_pr(LOG_ERROR, - "exceeded than MAX_NUM_VPU_CORE[%d]\n", - MAX_NUM_VPU_CORE); - return -ENODEV; - } - - memcpy((void *)&s_bit_firmware_info - [bit_firmware_info->core_idx], - bit_firmware_info, - sizeof(struct vpu_bit_firmware_info_t)); - kfree(bit_firmware_info); - return len; - } - kfree(bit_firmware_info); - } - return -1; -} - -static s32 vpu_release(struct inode *inode, struct file *filp) -{ - s32 ret = 0; - ulong flags; - enc_pr(LOG_DEBUG, "vpu_release\n"); - ret = down_interruptible(&s_vpu_sem); - if (ret == 0) { - vpu_free_buffers(filp); - vpu_free_instances(filp); - s_vpu_drv_context.open_count--; - if (s_vpu_drv_context.open_count == 0) { - if (s_instance_pool.base) { - enc_pr(LOG_DEBUG, "free instance pool\n"); - vfree((const void *)s_instance_pool.base); - s_instance_pool.base = 0; - } - if (s_common_memory.base) { - enc_pr(LOG_DEBUG, "free common memory\n"); - vpu_free_dma_buffer(&s_common_memory); - s_common_memory.base = 0; - } - - if (s_video_memory.base && !use_reserve) { - codec_mm_free_for_dma( - VPU_DEV_NAME, - (u32)s_video_memory.phys_addr); - vmem_exit(&s_vmem); - memset(&s_video_memory, - 0, sizeof(struct vpudrv_buffer_t)); - memset(&s_vmem, - 0, sizeof(struct video_mm_t)); - } - if ((s_vpu_irq >= 0) && (s_vpu_irq_requested == true)) { - free_irq(s_vpu_irq, &s_vpu_drv_context); - s_vpu_irq_requested = false; - } - spin_lock_irqsave(&s_vpu_lock, flags); - WRITE_AOREG(AO_RTI_GEN_PWR_ISO0, - READ_AOREG(AO_RTI_GEN_PWR_ISO0) | (0x3<<12)); - udelay(10); - - WRITE_VREG(DOS_MEM_PD_WAVE420L, 0xffffffff); -#ifndef VPU_SUPPORT_CLOCK_CONTROL - vpu_clk_config(0); -#endif - WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0, - READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | (0x3<<24)); - udelay(10); - spin_unlock_irqrestore(&s_vpu_lock, flags); - amports_switch_gate("vdec", 0); - } - } - up(&s_vpu_sem); - return 0; -} - -static s32 vpu_fasync(s32 fd, struct file *filp, s32 mode) -{ - struct vpu_drv_context_t *dev = - (struct vpu_drv_context_t *)filp->private_data; - return fasync_helper(fd, filp, mode, &dev->async_queue); -} - -static s32 vpu_map_to_register(struct file *fp, struct vm_area_struct *vm) -{ - ulong pfn; - vm->vm_flags |= VM_IO | VM_RESERVED; - vm->vm_page_prot = - pgprot_noncached(vm->vm_page_prot); - pfn = s_vpu_register.phys_addr >> PAGE_SHIFT; - return remap_pfn_range(vm, vm->vm_start, pfn, - vm->vm_end - vm->vm_start, - vm->vm_page_prot) ? -EAGAIN : 0; -} - -static s32 vpu_map_to_physical_memory( - struct file *fp, struct vm_area_struct *vm) -{ - vm->vm_flags |= VM_IO | VM_RESERVED; - if (vm->vm_pgoff == - (s_common_memory.phys_addr >> PAGE_SHIFT)) { - vm->vm_page_prot = - pgprot_noncached(vm->vm_page_prot); - } else { - if (vpu_is_buffer_cached(fp, vm->vm_pgoff) == 0) - vm->vm_page_prot = - pgprot_noncached(vm->vm_page_prot); - } - /* vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot); */ - return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, - vm->vm_end - vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0; -} - -static s32 vpu_map_to_instance_pool_memory( - struct file *fp, struct vm_area_struct *vm) -{ - s32 ret; - long length = vm->vm_end - vm->vm_start; - ulong start = vm->vm_start; - s8 *vmalloc_area_ptr = (s8 *)s_instance_pool.base; - ulong pfn; - - vm->vm_flags |= VM_RESERVED; - - /* loop over all pages, map it page individually */ - while (length > 0) { - pfn = vmalloc_to_pfn(vmalloc_area_ptr); - ret = remap_pfn_range(vm, start, pfn, - PAGE_SIZE, PAGE_SHARED); - if (ret < 0) - return ret; - start += PAGE_SIZE; - vmalloc_area_ptr += PAGE_SIZE; - length -= PAGE_SIZE; - } - return 0; -} - -/* - * @brief memory map interface for vpu file operation - * @return 0 on success or negative error code on error - */ -static s32 vpu_mmap(struct file *fp, struct vm_area_struct *vm) -{ - /* if (vm->vm_pgoff == (s_vpu_register.phys_addr >> PAGE_SHIFT)) */ - if ((vm->vm_end - vm->vm_start == s_vpu_register.size + 1) && - (vm->vm_pgoff == 0)) { - vm->vm_pgoff = (s_vpu_register.phys_addr >> PAGE_SHIFT); - return vpu_map_to_register(fp, vm); - } - - if (vm->vm_pgoff == 0) - return vpu_map_to_instance_pool_memory(fp, vm); - - return vpu_map_to_physical_memory(fp, vm); -} - -static const struct file_operations vpu_fops = { - .owner = THIS_MODULE, - .open = vpu_open, - .release = vpu_release, - .write = vpu_write, - .unlocked_ioctl = vpu_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = vpu_compat_ioctl, -#endif - .fasync = vpu_fasync, - .mmap = vpu_mmap, -}; - -static ssize_t hevcenc_status_show(struct class *cla, - struct class_attribute *attr, char *buf) -{ - return snprintf(buf, 40, "hevcenc_status_show\n"); -} - -static struct class_attribute hevcenc_class_attrs[] = { - __ATTR(encode_status, - S_IRUGO | S_IWUSR, - hevcenc_status_show, - NULL), - __ATTR_NULL -}; - -static struct class hevcenc_class = { - .name = VPU_CLASS_NAME, - .class_attrs = hevcenc_class_attrs, -}; - -s32 init_HevcEnc_device(void) -{ - s32 r = 0; - r = register_chrdev(0, VPU_DEV_NAME, &vpu_fops); - if (r <= 0) { - enc_pr(LOG_ERROR, "register hevcenc device error.\n"); - return r; - } - s_vpu_major = r; - - r = class_register(&hevcenc_class); - if (r < 0) { - enc_pr(LOG_ERROR, "error create hevcenc class.\n"); - return r; - } - - hevcenc_dev = device_create(&hevcenc_class, NULL, - MKDEV(s_vpu_major, 0), NULL, - VPU_DEV_NAME); - - if (IS_ERR(hevcenc_dev)) { - enc_pr(LOG_ERROR, "create hevcenc device error.\n"); - class_unregister(&hevcenc_class); - return -1; - } - return r; -} - -s32 uninit_HevcEnc_device(void) -{ - if (hevcenc_dev) - device_destroy(&hevcenc_class, MKDEV(s_vpu_major, 0)); - - class_destroy(&hevcenc_class); - - unregister_chrdev(s_vpu_major, VPU_DEV_NAME); - return 0; -} - -static s32 hevc_mem_device_init( - struct reserved_mem *rmem, struct device *dev) -{ - s32 r; - if (!rmem) { - enc_pr(LOG_ERROR, - "Can not obtain I/O memory, will allocate hevc buffer!\n"); - r = -EFAULT; - return r; - } - - if ((!rmem->base) || - (rmem->size < VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE)) { - enc_pr(LOG_ERROR, - "memory range error, 0x%lx - 0x%lx\n", - (ulong)rmem->base, (ulong)rmem->size); - r = -EFAULT; - return r; - } - r = 0; - s_video_memory.size = rmem->size; - s_video_memory.phys_addr = (ulong)rmem->base; - s_video_memory.base = - (ulong)phys_to_virt(s_video_memory.phys_addr); - if (!s_video_memory.base) { - enc_pr(LOG_ERROR, "fail to remap video memory "); - enc_pr(LOG_ERROR, - "physical phys_addr=0x%lx, base=0x%lx, size=0x%x\n", - (ulong)s_video_memory.phys_addr, - (ulong)s_video_memory.base, - (u32)s_video_memory.size); - s_video_memory.phys_addr = 0; - r = -EFAULT; - } - return r; -} - -static s32 vpu_probe(struct platform_device *pdev) -{ - s32 err = 0, irq, reg_count, idx; - struct resource res; - struct device_node *np, *child; - - enc_pr(LOG_DEBUG, "vpu_probe\n"); - - s_vpu_major = 0; - use_reserve = false; - s_vpu_irq = -1; - cma_pool_size = 0; - s_vpu_irq_requested = false; - s_vpu_open_ref_count = 0; - hevcenc_dev = NULL; - hevc_pdev = NULL; - memset(&s_video_memory, 0, sizeof(struct vpudrv_buffer_t)); - memset(&s_vpu_register, 0, sizeof(struct vpudrv_buffer_t)); - memset(&s_vmem, 0, sizeof(struct video_mm_t)); - memset(&s_bit_firmware_info[0], 0, sizeof(s_bit_firmware_info)); - memset(&res, 0, sizeof(struct resource)); - - idx = of_reserved_mem_device_init(&pdev->dev); - if (idx != 0) { - enc_pr(LOG_DEBUG, - "HevcEnc reserved memory config fail.\n"); - } else if (s_video_memory.phys_addr) { - use_reserve = true; - } - - if (use_reserve == false) { -#ifndef CONFIG_CMA - enc_pr(LOG_ERROR, - "HevcEnc reserved memory is invaild, probe fail!\n"); - err = -EFAULT; - goto ERROR_PROVE_DEVICE; -#else - cma_pool_size = - (codec_mm_get_total_size() > - (VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE)) ? - (VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE) : - codec_mm_get_total_size(); - enc_pr(LOG_DEBUG, - "HevcEnc - cma memory pool size: %d MB\n", - (u32)cma_pool_size / SZ_1M); -#endif - } - - /* get interrupt resource */ - irq = platform_get_irq_byname(pdev, "wave420l_irq"); - if (irq < 0) { - enc_pr(LOG_ERROR, "get HevcEnc irq resource error\n"); - err = -ENXIO; - goto ERROR_PROVE_DEVICE; - } - s_vpu_irq = irq; - enc_pr(LOG_DEBUG, "HevcEnc - wave420l_irq: %d\n", s_vpu_irq); -#if 0 - rstc = devm_reset_control_get(&pdev->dev, "HevcEnc"); - if (IS_ERR(rstc)) { - enc_pr(LOG_ERROR, - "get HevcEnc rstc error: %lx\n", PTR_ERR(rstc)); - rstc = NULL; - err = -ENOENT; - goto ERROR_PROVE_DEVICE; - } - reset_control_assert(rstc); - s_vpu_rstc = rstc; - - clk = clk_get(&pdev->dev, "clk_HevcEnc"); - if (IS_ERR(clk)) { - enc_pr(LOG_ERROR, "cannot get clock\n"); - clk = NULL; - err = -ENOENT; - goto ERROR_PROVE_DEVICE; - } - s_vpu_clk = clk; -#endif - -#ifdef VPU_SUPPORT_CLOCK_CONTROL -#else - vpu_clk_config(1); -#endif - - np = pdev->dev.of_node; - reg_count = 0; - for_each_child_of_node(np, child) { - if (of_address_to_resource(child, 0, &res) - || (reg_count > 1)) { - enc_pr(LOG_ERROR, - "no reg ranges or more reg ranges %d\n", - reg_count); - err = -ENXIO; - goto ERROR_PROVE_DEVICE; - } - /* if platform driver is implemented */ - if (res.start != 0) { - s_vpu_register.phys_addr = res.start; - s_vpu_register.virt_addr = - (ulong)ioremap_nocache( - res.start, resource_size(&res)); - s_vpu_register.size = res.end - res.start; - enc_pr(LOG_DEBUG, - "vpu base address get from platform driver "); - enc_pr(LOG_DEBUG, - "physical base addr=0x%lx, virtual base=0x%lx\n", - s_vpu_register.phys_addr, - s_vpu_register.virt_addr); - } else { - s_vpu_register.phys_addr = VPU_REG_BASE_ADDR; - s_vpu_register.virt_addr = - (ulong)ioremap_nocache( - s_vpu_register.phys_addr, VPU_REG_SIZE); - s_vpu_register.size = VPU_REG_SIZE; - enc_pr(LOG_DEBUG, - "vpu base address get from defined value "); - enc_pr(LOG_DEBUG, - "physical base addr=0x%lx, virtual base=0x%lx\n", - s_vpu_register.phys_addr, - s_vpu_register.virt_addr); - } - reg_count++; - } - - /* get the major number of the character device */ - if (init_HevcEnc_device()) { - err = -EBUSY; - enc_pr(LOG_ERROR, "could not allocate major number\n"); - goto ERROR_PROVE_DEVICE; - } - enc_pr(LOG_INFO, "SUCCESS alloc_chrdev_region\n"); - - init_waitqueue_head(&s_interrupt_wait_q); - tasklet_init(&hevc_tasklet, - hevcenc_isr_tasklet, - (ulong)&s_vpu_drv_context); - s_common_memory.base = 0; - s_instance_pool.base = 0; - - if (use_reserve == true) { - if (vmem_init(&s_vmem, s_video_memory.phys_addr, - s_video_memory.size) < 0) { - enc_pr(LOG_ERROR, "fail to init vmem system\n"); - goto ERROR_PROVE_DEVICE; - } - enc_pr(LOG_DEBUG, - "success to probe vpu device with video memory "); - enc_pr(LOG_DEBUG, - "phys_addr=0x%lx, base = 0x%lx\n", - (ulong)s_video_memory.phys_addr, - (ulong)s_video_memory.base); - } else - enc_pr(LOG_DEBUG, - "success to probe vpu device with video memory from cma\n"); - hevc_pdev = pdev; - return 0; - -ERROR_PROVE_DEVICE: - if (s_vpu_register.virt_addr) { - iounmap((void *)s_vpu_register.virt_addr); - memset(&s_vpu_register, 0, sizeof(struct vpudrv_buffer_t)); - } - - if (s_video_memory.base) { - vmem_exit(&s_vmem); - memset(&s_video_memory, 0, sizeof(struct vpudrv_buffer_t)); - memset(&s_vmem, 0, sizeof(struct video_mm_t)); - } - - vpu_clk_config(0); - - if (s_vpu_irq_requested == true) { - if (s_vpu_irq >= 0) { - free_irq(s_vpu_irq, &s_vpu_drv_context); - s_vpu_irq = -1; - } - s_vpu_irq_requested = false; - } - uninit_HevcEnc_device(); - return err; -} - -static s32 vpu_remove(struct platform_device *pdev) -{ - enc_pr(LOG_DEBUG, "vpu_remove\n"); - - if (s_instance_pool.base) { - vfree((const void *)s_instance_pool.base); - s_instance_pool.base = 0; - } - - if (s_common_memory.base) { - vpu_free_dma_buffer(&s_common_memory); - s_common_memory.base = 0; - } - - if (s_video_memory.base) { - if (!use_reserve) - codec_mm_free_for_dma( - VPU_DEV_NAME, - (u32)s_video_memory.phys_addr); - vmem_exit(&s_vmem); - memset(&s_video_memory, - 0, sizeof(struct vpudrv_buffer_t)); - memset(&s_vmem, - 0, sizeof(struct video_mm_t)); - } - - if (s_vpu_irq_requested == true) { - if (s_vpu_irq >= 0) { - free_irq(s_vpu_irq, &s_vpu_drv_context); - s_vpu_irq = -1; - } - s_vpu_irq_requested = false; - } - - if (s_vpu_register.virt_addr) { - iounmap((void *)s_vpu_register.virt_addr); - memset(&s_vpu_register, - 0, sizeof(struct vpudrv_buffer_t)); - } - hevc_pdev = NULL; - vpu_clk_config(0); - - uninit_HevcEnc_device(); - return 0; -} - -#ifdef CONFIG_PM -static void Wave4BitIssueCommand(u32 core, u32 cmd) -{ - WriteVpuRegister(W4_VPU_BUSY_STATUS, 1); - WriteVpuRegister(W4_CORE_INDEX, 0); - /* coreIdx = ReadVpuRegister(W4_VPU_BUSY_STATUS); */ - /* coreIdx = 0; */ - /* WriteVpuRegister(W4_INST_INDEX, - (instanceIndex & 0xffff) | (codecMode << 16)); */ - WriteVpuRegister(W4_COMMAND, cmd); - WriteVpuRegister(W4_VPU_HOST_INT_REQ, 1); - return; -} - -static s32 vpu_suspend(struct platform_device *pdev, pm_message_t state) -{ - u32 core; - ulong timeout = jiffies + HZ; /* vpu wait timeout to 1sec */ - enc_pr(LOG_DEBUG, "vpu_suspend\n"); - - vpu_clk_config(1); - - if (s_vpu_open_ref_count > 0) { - for (core = 0; core < MAX_NUM_VPU_CORE; core++) { - if (s_bit_firmware_info[core].size == 0) - continue; - while (ReadVpuRegister(W4_VPU_BUSY_STATUS)) { - if (time_after(jiffies, timeout)) { - enc_pr(LOG_ERROR, - "SLEEP_VPU BUSY timeout"); - goto DONE_SUSPEND; - } - } - Wave4BitIssueCommand(core, W4_CMD_SLEEP_VPU); - - while (ReadVpuRegister(W4_VPU_BUSY_STATUS)) { - if (time_after(jiffies, timeout)) { - enc_pr(LOG_ERROR, - "SLEEP_VPU BUSY timeout"); - goto DONE_SUSPEND; - } - } - if (ReadVpuRegister(W4_RET_SUCCESS) == 0) { - enc_pr(LOG_ERROR, - "SLEEP_VPU failed [0x%x]", - ReadVpuRegister(W4_RET_FAIL_REASON)); - goto DONE_SUSPEND; - } - } - } - - vpu_clk_config(0); - return 0; - -DONE_SUSPEND: - vpu_clk_config(0); - return -EAGAIN; -} -static s32 vpu_resume(struct platform_device *pdev) -{ - u32 i; - u32 core; - u32 val; - ulong timeout = jiffies + HZ; /* vpu wait timeout to 1sec */ - ulong code_base; - u32 code_size; - u32 remap_size; - u32 regVal; - u32 hwOption = 0; - - enc_pr(LOG_DEBUG, "vpu_resume\n"); - - vpu_clk_config(1); - - for (core = 0; core < MAX_NUM_VPU_CORE; core++) { - if (s_bit_firmware_info[core].size == 0) - continue; - code_base = s_common_memory.phys_addr; - /* ALIGN TO 4KB */ - code_size = (s_common_memory.size & ~0xfff); - if (code_size < s_bit_firmware_info[core].size * 2) - goto DONE_WAKEUP; - - /*---- LOAD BOOT CODE */ - for (i = 0; i < 512; i += 2) { - val = s_bit_firmware_info[core].bit_code[i]; - val |= (s_bit_firmware_info[core].bit_code[i+1] << 16); - WriteVpu(code_base+(i*2), val); - } - - regVal = 0; - WriteVpuRegister(W4_PO_CONF, regVal); - - /* Reset All blocks */ - regVal = 0x7ffffff; - WriteVpuRegister(W4_VPU_RESET_REQ, regVal); - - /* Waiting reset done */ - while (ReadVpuRegister(W4_VPU_RESET_STATUS)) { - if (time_after(jiffies, timeout)) - goto DONE_WAKEUP; - } - - WriteVpuRegister(W4_VPU_RESET_REQ, 0); - - /* remap page size */ - remap_size = (code_size >> 12) & 0x1ff; - regVal = 0x80000000 | (W4_REMAP_CODE_INDEX<<12) - | (0 << 16) | (1<<11) | remap_size; - WriteVpuRegister(W4_VPU_REMAP_CTRL, regVal); - /* DO NOT CHANGE! */ - WriteVpuRegister(W4_VPU_REMAP_VADDR, 0x00000000); - WriteVpuRegister(W4_VPU_REMAP_PADDR, code_base); - WriteVpuRegister(W4_ADDR_CODE_BASE, code_base); - WriteVpuRegister(W4_CODE_SIZE, code_size); - WriteVpuRegister(W4_CODE_PARAM, 0); - WriteVpuRegister(W4_INIT_VPU_TIME_OUT_CNT, timeout); - WriteVpuRegister(W4_HW_OPTION, hwOption); - - /* Interrupt */ - regVal = (1 << W4_INT_DEC_PIC_HDR); - regVal |= (1 << W4_INT_DEC_PIC); - regVal |= (1 << W4_INT_QUERY_DEC); - regVal |= (1 << W4_INT_SLEEP_VPU); - regVal |= (1 << W4_INT_BSBUF_EMPTY); - regVal = 0xfffffefe; - WriteVpuRegister(W4_VPU_VINT_ENABLE, regVal); - Wave4BitIssueCommand(core, W4_CMD_INIT_VPU); - WriteVpuRegister(W4_VPU_REMAP_CORE_START, 1); - while (ReadVpuRegister(W4_VPU_BUSY_STATUS)) { - if (time_after(jiffies, timeout)) - goto DONE_WAKEUP; - } - - if (ReadVpuRegister(W4_RET_SUCCESS) == 0) { - enc_pr(LOG_ERROR, - "WAKEUP_VPU failed [0x%x]", - ReadVpuRegister(W4_RET_FAIL_REASON)); - goto DONE_WAKEUP; - } - } - - if (s_vpu_open_ref_count == 0) - vpu_clk_config(0); -DONE_WAKEUP: - if (s_vpu_open_ref_count > 0) - vpu_clk_config(1); - return 0; -} -#else -#define vpu_suspend NULL -#define vpu_resume NULL -#endif /* !CONFIG_PM */ - -static const struct of_device_id cnm_hevcenc_dt_match[] = { - { - .compatible = "cnm, HevcEnc", - }, - {}, -}; - -static struct platform_driver vpu_driver = { - .driver = { - .name = VPU_PLATFORM_DEVICE_NAME, - .of_match_table = cnm_hevcenc_dt_match, - }, - .probe = vpu_probe, - .remove = vpu_remove, - .suspend = vpu_suspend, - .resume = vpu_resume, -}; - -static s32 __init vpu_init(void) -{ - s32 res; - enc_pr(LOG_DEBUG, "vpu_init\n"); - if (get_cpu_type() != MESON_CPU_MAJOR_ID_GXM) { - enc_pr(LOG_DEBUG, - "The chip is not support hevc encoder\n"); - return -1; - } - res = platform_driver_register(&vpu_driver); - enc_pr(LOG_INFO, - "end vpu_init result=0x%x\n", res); - return res; -} - -static void __exit vpu_exit(void) -{ - enc_pr(LOG_DEBUG, "vpu_exit\n"); - if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) - platform_driver_unregister(&vpu_driver); - return; -} - -static const struct reserved_mem_ops rmem_hevc_ops = { - .device_init = hevc_mem_device_init, -}; - -static s32 __init hevc_mem_setup(struct reserved_mem *rmem) -{ - rmem->ops = &rmem_hevc_ops; - enc_pr(LOG_DEBUG, "HevcEnc reserved mem setup.\n"); - return 0; -} - -module_param(print_level, uint, 0664); -MODULE_PARM_DESC(print_level, "\n print_level\n"); - -module_param(clock_level, uint, 0664); -MODULE_PARM_DESC(clock_level, "\n clock_level\n"); - -MODULE_AUTHOR("Amlogic using C&M VPU, Inc."); -MODULE_DESCRIPTION("VPU linux driver"); -MODULE_LICENSE("GPL"); - -module_init(vpu_init); -module_exit(vpu_exit); -RESERVEDMEM_OF_DECLARE(cnm_hevc, "cnm, HevcEnc-memory", hevc_mem_setup); diff --git a/drivers/frame_sink/encoder/h265/vpu.h b/drivers/frame_sink/encoder/h265/vpu.h deleted file mode 100644 index eaed0b7..0000000 --- a/drivers/frame_sink/encoder/h265/vpu.h +++ b/dev/null @@ -1,288 +0,0 @@ -/* - * vpu.h - * - * linux device driver for VPU. - * - * Copyright (C) 2006 - 2013 CHIPS&MEDIA INC. - * - * 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 __VPU_DRV_H__ -#define __VPU_DRV_H__ - -#include <linux/fs.h> -#include <linux/types.h> -#include <linux/compat.h> - -#define MAX_INST_HANDLE_SIZE (32*1024) -#define MAX_NUM_INSTANCE 4 -#define MAX_NUM_VPU_CORE 1 - -#define W4_CMD_INIT_VPU (0x0001) -#define W4_CMD_SLEEP_VPU (0x0400) -#define W4_CMD_WAKEUP_VPU (0x0800) - -/* GXM: 2000/10 = 200M */ -#define HevcEnc_L0() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (3 << 25) | (1 << 16) | (3 << 9) | (1 << 0)) -/* GXM: 2000/8 = 250M */ -#define HevcEnc_L1() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (1 << 25) | (1 << 16) | (1 << 9) | (1 << 0)) -/* GXM: 2000/7 = 285M */ -#define HevcEnc_L2() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (4 << 25) | (0 << 16) | (4 << 9) | (0 << 0)) -/*GXM: 2000/6 = 333M */ -#define HevcEnc_L3() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (2 << 25) | (1 << 16) | (2 << 9) | (1 << 0)) -/* GXM: 2000/5 = 400M */ -#define HevcEnc_L4() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (3 << 25) | (0 << 16) | (3 << 9) | (0 << 0)) -/* GXM: 2000/4 = 500M */ -#define HevcEnc_L5() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (1 << 25) | (0 << 16) | (1 << 9) | (0 << 0)) -/* GXM: 2000/3 = 667M */ -#define HevcEnc_L6() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - (2 << 25) | (0 << 16) | (2 << 9) | (0 << 0)) - -#define HevcEnc_clock_enable(level) \ - do { \ - WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ - & (~(1 << 8)) & (~(1 << 24))); \ - if (level == 0) \ - HevcEnc_L0(); \ - else if (level == 1) \ - HevcEnc_L1(); \ - else if (level == 2) \ - HevcEnc_L2(); \ - else if (level == 3) \ - HevcEnc_L3(); \ - else if (level == 4) \ - HevcEnc_L4(); \ - else if (level == 5) \ - HevcEnc_L5(); \ - else if (level == 6) \ - HevcEnc_L6(); \ - WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ - | (1 << 8) | (1 << 24)); \ - } while (0) - -#define HevcEnc_clock_disable() \ - WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ - READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ - & (~(1 << 8)) & (~(1 << 24))); - -struct compat_vpudrv_buffer_t { - u32 size; - u32 cached; - compat_ulong_t phys_addr; - compat_ulong_t base; /* kernel logical address in use kernel */ - compat_ulong_t virt_addr; /* virtual user space address */ -}; - -struct vpudrv_buffer_t { - u32 size; - u32 cached; - ulong phys_addr; - ulong base; /* kernel logical address in use kernel */ - ulong virt_addr; /* virtual user space address */ -}; - -struct vpu_bit_firmware_info_t { - u32 size; /* size of this structure*/ - u32 core_idx; - u32 reg_base_offset; - u16 bit_code[512]; -}; - -struct vpudrv_inst_info_t { - u32 core_idx; - u32 inst_idx; - s32 inst_open_count; /* for output only*/ -}; - -struct vpudrv_intr_info_t { - u32 timeout; - s32 intr_reason; -}; - -struct vpu_drv_context_t { - struct fasync_struct *async_queue; - ulong interrupt_reason; - u32 open_count; /*!<< device reference count. Not instance count */ -}; - -/* To track the allocated memory buffer */ -struct vpudrv_buffer_pool_t { - struct list_head list; - struct vpudrv_buffer_t vb; - struct file *filp; -}; - -/* To track the instance index and buffer in instance pool */ -struct vpudrv_instanace_list_t { - struct list_head list; - ulong inst_idx; - ulong core_idx; - struct file *filp; -}; - -struct vpudrv_instance_pool_t { - u8 codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE]; -}; - -#define VPUDRV_BUF_LEN struct vpudrv_buffer_t -#define VPUDRV_BUF_LEN32 struct compat_vpudrv_buffer_t -#define VPUDRV_INST_LEN struct vpudrv_inst_info_t - -#define VDI_MAGIC 'V' -#define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY \ - _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_FREE_PHYSICALMEMORY \ - _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_WAIT_INTERRUPT \ - _IOW(VDI_MAGIC, 2, struct vpudrv_intr_info_t) - -#define VDI_IOCTL_SET_CLOCK_GATE \ - _IOW(VDI_MAGIC, 3, u32) - -#define VDI_IOCTL_RESET \ - _IOW(VDI_MAGIC, 4, u32) - -#define VDI_IOCTL_GET_INSTANCE_POOL \ - _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_GET_COMMON_MEMORY \ - _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO \ - _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_OPEN_INSTANCE \ - _IOW(VDI_MAGIC, 9, VPUDRV_INST_LEN) - -#define VDI_IOCTL_CLOSE_INSTANCE \ - _IOW(VDI_MAGIC, 10, VPUDRV_INST_LEN) - -#define VDI_IOCTL_GET_INSTANCE_NUM \ - _IOW(VDI_MAGIC, 11, VPUDRV_INST_LEN) - -#define VDI_IOCTL_GET_REGISTER_INFO \ - _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_FLUSH_BUFFER \ - _IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN) - -#define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32 \ - _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_FREE_PHYSICALMEMORY32 \ - _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_GET_INSTANCE_POOL32 \ - _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_GET_COMMON_MEMORY32 \ - _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32 \ - _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_GET_REGISTER_INFO32 \ - _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN32) - -#define VDI_IOCTL_FLUSH_BUFFER32 \ - _IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN32) - -enum { - W4_INT_INIT_VPU = 0, - W4_INT_DEC_PIC_HDR = 1, - W4_INT_SET_PARAM = 1, - W4_INT_ENC_INIT_SEQ = 1, - W4_INT_FINI_SEQ = 2, - W4_INT_DEC_PIC = 3, - W4_INT_ENC_PIC = 3, - W4_INT_SET_FRAMEBUF = 4, - W4_INT_FLUSH_DEC = 5, - W4_INT_ENC_SLICE_INT = 7, - W4_INT_GET_FW_VERSION = 8, - W4_INT_QUERY_DEC = 9, - W4_INT_SLEEP_VPU = 10, - W4_INT_WAKEUP_VPU = 11, - W4_INT_CHANGE_INT = 12, - W4_INT_CREATE_INSTANCE = 14, - W4_INT_BSBUF_EMPTY = 15, - /*!<< Bitstream buffer empty[dec]/full[enc] */ -}; - -/* WAVE4 registers */ -#define VPU_REG_BASE_ADDR 0xc8810000 -#define VPU_REG_SIZE (0x4000 * MAX_NUM_VPU_CORE) - -#define W4_REG_BASE 0x0000 -#define W4_VPU_BUSY_STATUS (W4_REG_BASE + 0x0070) -#define W4_VPU_INT_REASON_CLEAR (W4_REG_BASE + 0x0034) -#define W4_VPU_VINT_CLEAR (W4_REG_BASE + 0x003C) -#define W4_VPU_VPU_INT_STS (W4_REG_BASE + 0x0044) -#define W4_VPU_INT_REASON (W4_REG_BASE + 0x004c) - -#define W4_RET_SUCCESS (W4_REG_BASE + 0x0110) -#define W4_RET_FAIL_REASON (W4_REG_BASE + 0x0114) - -/* WAVE4 INIT, WAKEUP */ -#define W4_PO_CONF (W4_REG_BASE + 0x0000) -#define W4_VCPU_CUR_PC (W4_REG_BASE + 0x0004) - -#define W4_VPU_VINT_ENABLE (W4_REG_BASE + 0x0048) - -#define W4_VPU_RESET_REQ (W4_REG_BASE + 0x0050) -#define W4_VPU_RESET_STATUS (W4_REG_BASE + 0x0054) - -#define W4_VPU_REMAP_CTRL (W4_REG_BASE + 0x0060) -#define W4_VPU_REMAP_VADDR (W4_REG_BASE + 0x0064) -#define W4_VPU_REMAP_PADDR (W4_REG_BASE + 0x0068) -#define W4_VPU_REMAP_CORE_START (W4_REG_BASE + 0x006C) -#define W4_VPU_BUSY_STATUS (W4_REG_BASE + 0x0070) - -#define W4_HW_OPTION (W4_REG_BASE + 0x0124) -#define W4_CODE_SIZE (W4_REG_BASE + 0x011C) -/* Note: W4_INIT_CODE_BASE_ADDR should be aligned to 4KB */ -#define W4_ADDR_CODE_BASE (W4_REG_BASE + 0x0118) -#define W4_CODE_PARAM (W4_REG_BASE + 0x0120) -#define W4_INIT_VPU_TIME_OUT_CNT (W4_REG_BASE + 0x0134) - -/* WAVE4 Wave4BitIssueCommand */ -#define W4_CORE_INDEX (W4_REG_BASE + 0x0104) -#define W4_INST_INDEX (W4_REG_BASE + 0x0108) -#define W4_COMMAND (W4_REG_BASE + 0x0100) -#define W4_VPU_HOST_INT_REQ (W4_REG_BASE + 0x0038) - -#define W4_BS_RD_PTR (W4_REG_BASE + 0x0130) -#define W4_BS_WR_PTR (W4_REG_BASE + 0x0134) -#define W4_RET_ENC_PIC_BYTE (W4_REG_BASE + 0x01C8) - -#define W4_REMAP_CODE_INDEX 0 - -#define ReadVpuRegister(addr) \ - readl((void __iomem *)(s_vpu_register.virt_addr \ - + s_bit_firmware_info[core].reg_base_offset + addr)) - -#define WriteVpuRegister(addr, val) \ - writel((u32)val, (void __iomem *)(s_vpu_register.virt_addr \ - + s_bit_firmware_info[core].reg_base_offset + addr)) - -#define WriteVpu(addr, val) writel((u32)val, (void __iomem *)addr) -#endif diff --git a/drivers/include/dummy-for-git-empty-dir b/drivers/include/dummy-for-git-empty-dir deleted file mode 100644 index e69de29..0000000 --- a/drivers/include/dummy-for-git-empty-dir +++ b/dev/null diff --git a/drivers/stream_input/Makefile b/drivers/stream_input/Makefile deleted file mode 100644 index 7d6a2c0..0000000 --- a/drivers/stream_input/Makefile +++ b/dev/null @@ -1,10 +0,0 @@ -obj-m += stream_input.o -stream_input-objs += amports/amstream.o -stream_input-objs += amports/amstream_profile.o -stream_input-objs += amports/adec.o -stream_input-objs += parser/thread_rw.o -stream_input-objs += parser/streambuf.o -stream_input-objs += parser/esparser.o -stream_input-objs += parser/tsdemux.o -stream_input-objs += parser/psparser.o -stream_input-objs += parser/rmparser.o diff --git a/drivers/stream_input/amports/Makefile b/drivers/stream_input/amports/Makefile deleted file mode 100644 index 55fbdce..0000000 --- a/drivers/stream_input/amports/Makefile +++ b/dev/null @@ -1,2 +0,0 @@ -obj-y += amports.o -amports-objs += amstream.o amstream_profile.o adec.o diff --git a/drivers/stream_input/amports/adec.c b/drivers/stream_input/amports/adec.c deleted file mode 100644 index 220c888..0000000 --- a/drivers/stream_input/amports/adec.c +++ b/dev/null @@ -1,295 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/amports/adec.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/types.h> -#include <linux/errno.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/uio_driver.h> - -#include <linux/amlogic/media/utils/aformat.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> - -#include <linux/amlogic/media/registers/register.h> - -#include "../parser/streambuf.h" -#include <linux/module.h> -#include "amports_priv.h" - -#define INFO_VALID ((astream_dev) && (astream_dev->format)) - -struct astream_device_s { - char *name; - char *format; - s32 channum; - s32 samplerate; - s32 datawidth; - - struct device dev; -}; - -static char *astream_format[] = { - "amadec_mpeg", - "amadec_pcm_s16le", - "amadec_aac", - "amadec_ac3", - "amadec_alaw", - "amadec_mulaw", - "amadec_dts", - "amadec_pcm_s16be", - "amadec_flac", - "amadec_cook", - "amadec_pcm_u8", - "amadec_adpcm", - "amadec_amr", - "amadec_raac", - "amadec_wma", - "amadec_wmapro", - "amadec_pcm_bluray", - "amadec_alac", - "amadec_vorbis", - "amadec_aac_latm", - "amadec_ape", - "amadec_eac3", - "amadec_pcm_widi", - "amadec_wmavoi" -}; - -static const char *na_string = "NA"; -static struct astream_device_s *astream_dev; - -static ssize_t format_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - if (INFO_VALID && astream_dev->format) - return sprintf(buf, "%s\n", astream_dev->format); - else - return sprintf(buf, "%s\n", na_string); -} - -static ssize_t channum_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - if (INFO_VALID) - return sprintf(buf, "%u\n", astream_dev->channum); - else - return sprintf(buf, "%s\n", na_string); -} - -static ssize_t samplerate_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - if (INFO_VALID) - return sprintf(buf, "%u\n", astream_dev->samplerate); - else - return sprintf(buf, "%s\n", na_string); -} - -static ssize_t datawidth_show(struct class *class, - struct class_attribute *attr, - char *buf) -{ - if (INFO_VALID) - return sprintf(buf, "%u\n", astream_dev->datawidth); - else - return sprintf(buf, "%s\n", na_string); -} - -static ssize_t pts_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - u32 pts; - u32 pts_margin = 0; - - if (astream_dev->samplerate <= 12000) - pts_margin = 512; - - if (INFO_VALID && (pts_lookup(PTS_TYPE_AUDIO, &pts, pts_margin) >= 0)) - return sprintf(buf, "0x%x\n", pts); - else - return sprintf(buf, "%s\n", na_string); -} - -static struct class_attribute astream_class_attrs[] = { - __ATTR_RO(format), - __ATTR_RO(samplerate), - __ATTR_RO(channum), - __ATTR_RO(datawidth), - __ATTR_RO(pts), - __ATTR_NULL -}; - -static struct class astream_class = { - .name = "astream", - .class_attrs = astream_class_attrs, - }; - -#if 1 -#define IO_CBUS_PHY_BASE 0xc1100000 -#define CBUS_REG_OFFSET(reg) ((reg) << 2) -#define IO_SECBUS_PHY_BASE 0xda000000 - -static struct uio_info astream_uio_info = { - .name = "astream_uio", - .version = "0.1", - .irq = UIO_IRQ_NONE, - - .mem = { - [0] = { - .name = "AIFIFO", - .memtype = UIO_MEM_PHYS, - .addr = - (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(AIU_AIFIFO_CTRL)) - &(PAGE_MASK), - .size = PAGE_SIZE, - }, - [1] = { - .memtype = UIO_MEM_PHYS, - .addr = - (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(VCOP_CTRL_REG)), - .size = PAGE_SIZE, - }, - [2] = { - .name = "SECBUS", - .memtype = UIO_MEM_PHYS, - .addr = (IO_SECBUS_PHY_BASE), - .size = PAGE_SIZE, - }, - [3] = { - .name = "CBUS", - .memtype = UIO_MEM_PHYS, - .addr = - (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(ASSIST_HW_REV)) - &(PAGE_MASK), - .size = PAGE_SIZE, - }, - [4] = { - .name = "CBUS-START", - .memtype = UIO_MEM_PHYS, - .addr = (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(0x1000)), - .size = PAGE_SIZE * 4, - }, - }, -}; -#endif - -static void astream_release(struct device *dev) -{ - kfree(astream_dev); - - astream_dev = NULL; -} - -s32 adec_init(struct stream_port_s *port) -{ - enum aformat_e af; - - if (!astream_dev) - return -ENODEV; - - af = port->aformat; - - astream_dev->channum = port->achanl; - astream_dev->samplerate = port->asamprate; - astream_dev->datawidth = port->adatawidth; - - /*wmb();don't need it...*/ - if (af <= ARRAY_SIZE(astream_format)) - astream_dev->format = astream_format[af]; - else - astream_dev->format = NULL; - return 0; -} - -s32 adec_release(enum aformat_e vf) -{ - pr_info("adec_release\n"); - - if (!astream_dev) - return -ENODEV; - - astream_dev->format = NULL; - - return 0; -} - -s32 astream_dev_register(void) -{ - s32 r; - - r = class_register(&astream_class); - if (r) { - pr_info("astream class create fail.\n"); - return r; - } - - astream_dev = kzalloc(sizeof(struct astream_device_s), GFP_KERNEL); - - if (!astream_dev) { - r = -ENOMEM; - goto err_3; - } - - astream_dev->dev.class = &astream_class; - astream_dev->dev.release = astream_release; - - dev_set_name(&astream_dev->dev, "astream-dev"); - - dev_set_drvdata(&astream_dev->dev, astream_dev); - - r = device_register(&astream_dev->dev); - if (r) { - pr_info("astream device register fail.\n"); - goto err_2; - } - -#if 1 - if (uio_register_device(&astream_dev->dev, &astream_uio_info)) { - pr_info("astream UIO device register fail.\n"); - r = -ENODEV; - goto err_1; - } -#endif - - return 0; - -err_1: - device_unregister(&astream_dev->dev); - -err_2: - kfree(astream_dev); - astream_dev = NULL; - -err_3: - class_unregister(&astream_class); - - return r; -} - -void astream_dev_unregister(void) -{ - if (astream_dev) { -#if 1 - uio_unregister_device(&astream_uio_info); -#endif - - device_unregister(&astream_dev->dev); - - class_unregister(&astream_class); - } -} diff --git a/drivers/stream_input/amports/adec.h b/drivers/stream_input/amports/adec.h deleted file mode 100644 index 545ac76..0000000 --- a/drivers/stream_input/amports/adec.h +++ b/dev/null @@ -1,32 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/amports/adec.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 ADEC_H -#define ADEC_H - -#include "../parser/streambuf.h" -#include <linux/amlogic/media/utils/aformat.h> - -extern s32 adec_init(struct stream_port_s *port); - -extern s32 adec_release(enum aformat_e af); - -extern s32 astream_dev_register(void); - -extern s32 astream_dev_unregister(void); - -#endif /* ADEC_H */ diff --git a/drivers/stream_input/amports/amports_priv.h b/drivers/stream_input/amports/amports_priv.h deleted file mode 100644 index 4b6f96e..0000000 --- a/drivers/stream_input/amports/amports_priv.h +++ b/dev/null @@ -1,56 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/amports/amports_priv.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 AMPORTS_PRIV_HEAD_HH -#define AMPORTS_PRIV_HEAD_HH -#include "../parser/streambuf.h" -#include "../../common/media_clock/switch/amports_gate.h" -#include <linux/amlogic/media/vfm/vframe.h> -#include "../../common/firmware/firmware.h" -#include <linux/amlogic/media/registers/register.h> -#include <linux/amlogic/media/utils/log.h> - -struct port_priv_s { - struct vdec_s *vdec; - struct stream_port_s *port; -}; - -struct stream_buf_s *get_buf_by_type(u32 type); - -extern void amvenc_dos_top_reg_fix(void); - -/*video.c provide*/ -extern u32 trickmode_i; -struct amvideocap_req; -extern u32 set_blackout_policy(int policy); -extern u32 get_blackout_policy(void); -int calculation_stream_ext_delayed_ms(u8 type); -int ext_get_cur_video_frame(struct vframe_s **vf, int *canvas_index); -int ext_put_video_frame(struct vframe_s *vf); -int ext_register_end_frame_callback(struct amvideocap_req *req); -int amstream_request_firmware_from_sys(const char *file_name, - char *buf, int size); -void set_vsync_pts_inc_mode(int inc); - -void set_real_audio_info(void *arg); -#define dbg() pr_info("on %s,line %d\n", __func__, __LINE__) - -struct device *amports_get_dma_device(void); -struct device *get_codec_cma_device(void); -int amports_get_debug_flags(void); - -#endif diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c deleted file mode 100644 index f1d2c74..0000000 --- a/drivers/stream_input/amports/amstream.c +++ b/dev/null @@ -1,3651 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/amports/amstream.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/module.h> -#include <linux/types.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/amlogic/major.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/kthread.h> - -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/media/utils/aformat.h> - -#include <linux/amlogic/media/frame_sync/tsync.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/frame_sync/timestamp.h> - -#include <linux/types.h> -#include <linux/uaccess.h> -#include <linux/io.h> -/* #include <mach/am_regs.h> */ - -#include <linux/platform_device.h> -#include <linux/mutex.h> -#include <linux/poll.h> -#include <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> -#include <linux/uaccess.h> -#include <linux/clk.h> -#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -/* #include <mach/mod_gate.h> */ -/* #include <mach/power_gate.h> */ -#endif -#include "../parser/streambuf.h" -#include "../parser/streambuf_reg.h" -#include "../parser/tsdemux.h" -#include "../parser/psparser.h" -#include "../parser/esparser.h" -#include "../../frame_provider/decoder/utils/vdec.h" -#include "adec.h" -#include "../parser/rmparser.h" -#include "amports_priv.h" -#include <linux/amlogic/media/utils/amports_config.h> -#include <linux/amlogic/media/frame_sync/tsync_pcr.h> -#include "../parser/thread_rw.h" - - -#include <linux/firmware.h> - -#include <linux/of.h> -#include <linux/of_fdt.h> -#include <linux/libfdt_env.h> -#include <linux/of_reserved_mem.h> -#include <linux/reset.h> -#include "../../common/firmware/firmware.h" -#ifdef CONFIG_COMPAT -#include <linux/compat.h> -#endif -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#define CONFIG_AM_VDEC_REAL //DEBUG_TMP - -#define DEVICE_NAME "amstream-dev" -#define DRIVER_NAME "amstream" -#define MODULE_NAME "amstream" - -#define MAX_AMSTREAM_PORT_NUM ARRAY_SIZE(ports) -u32 amstream_port_num; -u32 amstream_buf_num; - -#if 0 -#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV -#define NO_VDEC2_INIT 1 -#elif MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD -#define NO_VDEC2_INIT IS_MESON_M8M2_CPU -#endif -#endif -#define NO_VDEC2_INIT 1 - - -static int debugflags; - -#define DEFAULT_VIDEO_BUFFER_SIZE (1024 * 1024 * 3) -#define DEFAULT_VIDEO_BUFFER_SIZE_4K (1024 * 1024 * 6) -#define DEFAULT_VIDEO_BUFFER_SIZE_TVP (1024 * 1024 * 10) -#define DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP (1024 * 1024 * 15) - - -#define DEFAULT_AUDIO_BUFFER_SIZE (1024*768*2) -#define DEFAULT_SUBTITLE_BUFFER_SIZE (1024*256) - -static int def_4k_vstreambuf_sizeM = - (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20); -static int def_vstreambuf_sizeM = - (DEFAULT_VIDEO_BUFFER_SIZE >> 20); -static int debugflags; -static int slow_input; - - - - -/* #define DATA_DEBUG */ -static int use_bufferlevelx10000 = 10000; -static int reset_canuse_buferlevel(int level); -static struct platform_device *amstream_pdev; -struct device *amports_get_dma_device(void) -{ - return &amstream_pdev->dev; -} -EXPORT_SYMBOL(amports_get_dma_device); - -/* -*bit0:no threadrw -*/ -int amports_get_debug_flags(void) -{ - return debugflags; -} - -#ifdef DATA_DEBUG -#include <linux/fs.h> - -#define DEBUG_FILE_NAME "/sdcard/debug.tmp" -static struct file *debug_filp; -static loff_t debug_file_pos; - -void debug_file_write(const char __user *buf, size_t count) -{ - mm_segment_t old_fs; - - if (!debug_filp) - return; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - - if (count != vfs_write(debug_filp, buf, count, &debug_file_pos)) - pr_err("Failed to write debug file\n"); - - set_fs(old_fs); -} -#endif - - - -static int amstream_open(struct inode *inode, struct file *file); -static int amstream_release(struct inode *inode, struct file *file); -static long amstream_ioctl(struct file *file, unsigned int cmd, ulong arg); -#ifdef CONFIG_COMPAT -static long amstream_compat_ioctl - (struct file *file, unsigned int cmd, ulong arg); -#endif -static ssize_t amstream_vbuf_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_vframe_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_abuf_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_mpts_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_mpps_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_sub_read -(struct file *file, char *buf, size_t count, loff_t *ppos); -static ssize_t amstream_sub_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -static unsigned int amstream_sub_poll -(struct file *file, poll_table *wait_table); -static unsigned int amstream_userdata_poll -(struct file *file, poll_table *wait_table); -static ssize_t amstream_userdata_read -(struct file *file, char *buf, size_t count, loff_t *ppos); -static int (*amstream_adec_status) -(struct adec_status *astatus); -#ifdef CONFIG_AM_VDEC_REAL -static ssize_t amstream_mprm_write -(struct file *file, const char *buf, size_t count, loff_t *ppos); -#endif - -static const struct file_operations vbuf_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_vbuf_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations vframe_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_vframe_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations abuf_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_abuf_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations mpts_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_mpts_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations mpps_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_mpps_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations mprm_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, -#ifdef CONFIG_AM_VDEC_REAL - .write = amstream_mprm_write, -#endif - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations sub_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .write = amstream_sub_write, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations sub_read_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .read = amstream_sub_read, - .poll = amstream_sub_poll, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations userdata_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .read = amstream_userdata_read, - .poll = amstream_userdata_poll, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -static const struct file_operations amstream_fops = { - .owner = THIS_MODULE, - .open = amstream_open, - .release = amstream_release, - .unlocked_ioctl = amstream_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = amstream_compat_ioctl, -#endif -}; - -/**************************************************/ -static struct audio_info audio_dec_info; -static struct class *amstream_dev_class; -static DEFINE_MUTEX(amstream_mutex); - -atomic_t subdata_ready = ATOMIC_INIT(0); -static int sub_type; -static int sub_port_inited; -/* wait queue for poll */ -static wait_queue_head_t amstream_sub_wait; -atomic_t userdata_ready = ATOMIC_INIT(0); -static int userdata_length; -static wait_queue_head_t amstream_userdata_wait; -#define USERDATA_FIFO_NUM 1024 -static struct userdata_poc_info_t userdata_poc_info[USERDATA_FIFO_NUM]; -static int userdata_poc_ri = 0, userdata_poc_wi; - -static struct stream_port_s ports[] = { -#ifdef CONFIG_MULTI_DEC - { - .name = "amstream_vbuf", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO, - .fops = &vbuf_fops, - }, - { - .name = "amstream_vbuf_sched", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | - PORT_TYPE_DECODER_SCHED, - .fops = &vbuf_fops, - }, - { - .name = "amstream_vframe", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | - PORT_TYPE_FRAME | PORT_TYPE_DECODER_SCHED, - .fops = &vframe_fops, - }, -#else - { - .name = "amstream_vbuf", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO, - .fops = &vbuf_fops, - }, -#endif - { - .name = "amstream_abuf", - .type = PORT_TYPE_ES | PORT_TYPE_AUDIO, - .fops = &abuf_fops, - }, -#ifdef CONFIG_MULTI_DEC - { - .name = "amstream_mpts", - .type = PORT_TYPE_MPTS | PORT_TYPE_VIDEO | - PORT_TYPE_AUDIO | PORT_TYPE_SUB, - .fops = &mpts_fops, - }, - { - .name = "amstream_mpts_sched", - .type = PORT_TYPE_MPTS | PORT_TYPE_VIDEO | - PORT_TYPE_AUDIO | PORT_TYPE_SUB | - PORT_TYPE_DECODER_SCHED, - .fops = &mpts_fops, - }, -#else - { - .name = "amstream_mpts", - .type = PORT_TYPE_MPTS | PORT_TYPE_VIDEO | - PORT_TYPE_AUDIO | PORT_TYPE_SUB, - .fops = &mpts_fops, - }, -#endif - { - .name = "amstream_mpps", - .type = PORT_TYPE_MPPS | PORT_TYPE_VIDEO | - PORT_TYPE_AUDIO | PORT_TYPE_SUB, - .fops = &mpps_fops, - }, - { - .name = "amstream_rm", - .type = PORT_TYPE_RM | PORT_TYPE_VIDEO | PORT_TYPE_AUDIO, - .fops = &mprm_fops, - }, - { - .name = "amstream_sub", - .type = PORT_TYPE_SUB, - .fops = &sub_fops, - }, - { - .name = "amstream_sub_read", - .type = PORT_TYPE_SUB_RD, - .fops = &sub_read_fops, - }, - { - .name = "amstream_userdata", - .type = PORT_TYPE_USERDATA, - .fops = &userdata_fops, - }, -#ifdef CONFIG_MULTI_DEC - { - .name = "amstream_hevc", -#ifdef CONFIG_AM_VDEC_DV -/*test dobly vision, remove later*/ - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC | - PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC, - .fops = &vbuf_fops, - .vformat = VFORMAT_HEVC, -#else - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC, - .fops = &vbuf_fops, - .vformat = VFORMAT_HEVC, -#endif - }, - { - .name = "amstream_hevc_frame", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC | - PORT_TYPE_FRAME | PORT_TYPE_DECODER_SCHED, - .fops = &vframe_fops, - .vformat = VFORMAT_HEVC, - }, - { - .name = "amstream_hevc_sched", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC | - PORT_TYPE_DECODER_SCHED, - .fops = &vbuf_fops, - .vformat = VFORMAT_HEVC, - } -#ifdef CONFIG_AM_VDEC_DV - , - { - .name = "amstream_dves_avc", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | - PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC, - .fops = &vbuf_fops, - }, - { - .name = "amstream_dves_hevc", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC | - PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC, - .fops = &vbuf_fops, - .vformat = VFORMAT_HEVC, - } -#endif -#else - { - .name = "amstream_hevc", - .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC, - .fops = &vbuf_fops, - .vformat = VFORMAT_HEVC, - } -#endif -}; - -static struct stream_buf_s bufs[BUF_MAX_NUM] = { - { - .reg_base = VLD_MEM_VIFIFO_REG_BASE, - .type = BUF_TYPE_VIDEO, - .buf_start = 0, - .buf_size = DEFAULT_VIDEO_BUFFER_SIZE, - .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE, - .first_tstamp = INVALID_PTS - }, - { - .reg_base = AIU_MEM_AIFIFO_REG_BASE, - .type = BUF_TYPE_AUDIO, - .buf_start = 0, - .buf_size = DEFAULT_AUDIO_BUFFER_SIZE, - .default_buf_size = DEFAULT_AUDIO_BUFFER_SIZE, - .first_tstamp = INVALID_PTS - }, - { - .reg_base = 0, - .type = BUF_TYPE_SUBTITLE, - .buf_start = 0, - .buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE, - .default_buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE, - .first_tstamp = INVALID_PTS - }, - { - .reg_base = 0, - .type = BUF_TYPE_USERDATA, - .buf_start = 0, - .buf_size = 0, - .first_tstamp = INVALID_PTS - }, - { - .reg_base = HEVC_STREAM_REG_BASE, - .type = BUF_TYPE_HEVC, - .buf_start = 0, - .buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K, - .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K, - .first_tstamp = INVALID_PTS - }, -}; - -struct stream_buf_s *get_buf_by_type(u32 type) -{ - if (PTS_TYPE_VIDEO == type) - return &bufs[BUF_TYPE_VIDEO]; - if (PTS_TYPE_AUDIO == type) - return &bufs[BUF_TYPE_AUDIO]; - if (has_hevc_vdec()) { - if (PTS_TYPE_HEVC == type) - return &bufs[BUF_TYPE_HEVC]; - } - - return NULL; -} - -void set_sample_rate_info(int arg) -{ - audio_dec_info.sample_rate = arg; - audio_dec_info.valid = 1; -} - -void set_ch_num_info(int arg) -{ - audio_dec_info.channels = arg; -} - -struct audio_info *get_audio_info(void) -{ - return &audio_dec_info; -} -EXPORT_SYMBOL(get_audio_info); - -static void amstream_change_vbufsize(struct port_priv_s *priv, - struct stream_buf_s *pvbuf) -{ - if (pvbuf->buf_start != 0) { - pr_info("streambuf is alloced before\n"); - return; - } - if (pvbuf->for_4k) { - pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M; - if (codec_mm_video_tvp_enabled()) - 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 (codec_mm_video_tvp_enabled()) - pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP; - } else { - pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M; - if (codec_mm_video_tvp_enabled()) - pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP; - } - reset_canuse_buferlevel(10000); -} - -static bool port_get_inited(struct port_priv_s *priv) -{ - struct stream_port_s *port = priv->port; - - if (port->type & PORT_TYPE_VIDEO) { - struct vdec_s *vdec = priv->vdec; - - return vdec->port_flag & PORT_FLAG_INITED; - } - - return port->flag & PORT_FLAG_INITED; -} - -static void port_set_inited(struct port_priv_s *priv) -{ - struct stream_port_s *port = priv->port; - - if (port->type & PORT_TYPE_VIDEO) { - struct vdec_s *vdec = priv->vdec; - - vdec->port_flag |= PORT_FLAG_INITED; - } else - port->flag |= PORT_FLAG_INITED; -} - -static void video_port_release(struct port_priv_s *priv, - struct stream_buf_s *pbuf, int release_num) -{ - struct stream_port_s *port = priv->port; - struct vdec_s *vdec = priv->vdec; - - switch (release_num) { - default: - /*fallthrough*/ - case 0: /*release all */ - /*fallthrough*/ - case 4: - if ((port->type & PORT_TYPE_FRAME) == 0) - esparser_release(pbuf); - /*fallthrough*/ - case 3: - if (vdec->slave) - vdec_release(vdec->slave); - vdec_release(vdec); - priv->vdec = NULL; - /*fallthrough*/ - case 2: - if ((port->type & PORT_TYPE_FRAME) == 0) - stbuf_release(pbuf); - /*fallthrough*/ - case 1: - ; - } -} - -static int video_port_init(struct port_priv_s *priv, - struct stream_buf_s *pbuf) -{ - int r; - struct stream_port_s *port = priv->port; - struct vdec_s *vdec = priv->vdec; - - if ((port->flag & PORT_FLAG_VFORMAT) == 0) { - pr_err("vformat not set\n"); - return -EPERM; - } - - if (port->vformat == VFORMAT_H264_4K2K || - (priv->vdec->sys_info->height * - priv->vdec->sys_info->width) > 1920*1088) { - pbuf->for_4k = 1; - } else { - pbuf->for_4k = 0; - } - - if (port->type & PORT_TYPE_FRAME) { - r = vdec_init(vdec, - (priv->vdec->sys_info->height * - priv->vdec->sys_info->width) > 1920*1088); - if (r < 0) { - pr_err("video_port_init %d, vdec_init failed\n", - __LINE__); - video_port_release(priv, pbuf, 2); - return r; - } - - return 0; - } - - amstream_change_vbufsize(priv, 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); - } - } - - r = stbuf_init(pbuf, vdec); - if (r < 0) { - pr_err("video_port_init %d, stbuf_init failed\n", __LINE__); - return r; - } - - /* todo: set path based on port flag */ - r = vdec_init(vdec, - (priv->vdec->sys_info->height * - priv->vdec->sys_info->width) > 1920*1088); - - if (r < 0) { - pr_err("video_port_init %d, vdec_init failed\n", __LINE__); - video_port_release(priv, pbuf, 2); - return r; - } - - if (vdec_dual(vdec)) { - r = vdec_init(vdec->slave, - (priv->vdec->sys_info->height * - priv->vdec->sys_info->width) > 1920*1088); - if (r < 0) { - pr_err("video_port_init %d, vdec_init failed\n", - __LINE__); - video_port_release(priv, pbuf, 2); - return r; - } - } - - if (port->type & PORT_TYPE_ES) { - r = esparser_init(pbuf, vdec); - if (r < 0) { - video_port_release(priv, pbuf, 3); - pr_err("esparser_init() failed\n"); - return r; - } - } - - pbuf->flag |= BUF_FLAG_IN_USE; - - vdec_connect(priv->vdec); - - return 0; -} - -static void audio_port_release(struct stream_port_s *port, - struct stream_buf_s *pbuf, int release_num) -{ - switch (release_num) { - default: - /*fallthrough*/ - case 0: /*release all */ - /*fallthrough*/ - case 4: - esparser_release(pbuf); - /*fallthrough*/ - case 3: - adec_release(port->vformat); - /*fallthrough*/ - case 2: - stbuf_release(pbuf); - /*fallthrough*/ - case 1: - ; - } -} - -static int audio_port_reset(struct stream_port_s *port, - struct stream_buf_s *pbuf) -{ - int r; - - if ((port->flag & PORT_FLAG_AFORMAT) == 0) { - pr_err("aformat not set\n"); - return 0; - } - - pts_stop(PTS_TYPE_AUDIO); - - stbuf_release(pbuf); - - r = stbuf_init(pbuf, NULL); - if (r < 0) - return r; - - r = adec_init(port); - if (r < 0) { - audio_port_release(port, pbuf, 2); - return r; - } - - if (port->type & PORT_TYPE_ES) - esparser_audio_reset_s(pbuf); - - if (port->type & PORT_TYPE_MPTS) - tsdemux_audio_reset(); - - if (port->type & PORT_TYPE_MPPS) - psparser_audio_reset(); - -#ifdef CONFIG_AM_VDEC_REAL - if (port->type & PORT_TYPE_RM) - rm_audio_reset(); -#endif - - pbuf->flag |= BUF_FLAG_IN_USE; - - pts_start(PTS_TYPE_AUDIO); - - return 0; -} - -static int sub_port_reset(struct stream_port_s *port, - struct stream_buf_s *pbuf) -{ - int r; - - port->flag &= (~PORT_FLAG_INITED); - - stbuf_release(pbuf); - - r = stbuf_init(pbuf, NULL); - if (r < 0) - return r; - - if (port->type & PORT_TYPE_MPTS) - tsdemux_sub_reset(); - - if (port->type & PORT_TYPE_MPPS) - psparser_sub_reset(); - - if (port->sid == 0xffff) { /* es sub */ - esparser_sub_reset(); - pbuf->flag |= BUF_FLAG_PARSER; - } - - pbuf->flag |= BUF_FLAG_IN_USE; - - port->flag |= PORT_FLAG_INITED; - - return 0; -} - -static int audio_port_init(struct stream_port_s *port, - struct stream_buf_s *pbuf) -{ - int r; - - if ((port->flag & PORT_FLAG_AFORMAT) == 0) { - pr_err("aformat not set\n"); - return 0; - } - - r = stbuf_init(pbuf, NULL); - if (r < 0) - return r; - r = adec_init(port); - if (r < 0) { - audio_port_release(port, pbuf, 2); - return r; - } - if (port->type & PORT_TYPE_ES) { - r = esparser_init(pbuf, NULL); - if (r < 0) { - audio_port_release(port, pbuf, 3); - return r; - } - } - pbuf->flag |= BUF_FLAG_IN_USE; - return 0; -} - -static void sub_port_release(struct stream_port_s *port, - struct stream_buf_s *pbuf) -{ - if ((port->sid == 0xffff) && - ((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) { - /* this is es sub */ - esparser_release(pbuf); - } - stbuf_release(pbuf); - sub_port_inited = 0; -} - -static int sub_port_init(struct stream_port_s *port, struct stream_buf_s *pbuf) -{ - int r; - - if ((port->flag & PORT_FLAG_SID) == 0) { - pr_err("subtitle id not set\n"); - return 0; - } - - r = stbuf_init(pbuf, NULL); - if (r < 0) - return r; - - if ((port->sid == 0xffff) && - ((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) { - /* es sub */ - r = esparser_init(pbuf, NULL); - if (r < 0) { - sub_port_release(port, pbuf); - return r; - } - } - - sub_port_inited = 1; - return 0; -} - -static int amstream_port_init(struct port_priv_s *priv) -{ - int r; - struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO]; - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA]; - struct stream_port_s *port = priv->port; - struct vdec_s *vdec = priv->vdec; - - mutex_lock(&amstream_mutex); - - stbuf_fetch_init(); - - if (port_get_inited(priv)) { - mutex_unlock(&amstream_mutex); - return 0; - } - - if ((port->type & PORT_TYPE_AUDIO) && - (port->flag & PORT_FLAG_AFORMAT)) { - r = audio_port_init(port, pabuf); - if (r < 0) { - pr_err("audio_port_init failed\n"); - goto error1; - } - } - - if ((port->type & PORT_TYPE_VIDEO) && - (port->flag & PORT_FLAG_VFORMAT)) { - pubuf->buf_size = 0; - pubuf->buf_start = 0; - pubuf->buf_wp = 0; - pubuf->buf_rp = 0; - pvbuf->for_4k = 0; - if (has_hevc_vdec()) { - if (port->vformat == VFORMAT_HEVC || - port->vformat == VFORMAT_VP9) - pvbuf = &bufs[BUF_TYPE_HEVC]; - } - r = video_port_init(priv, pvbuf); - if (r < 0) { - pr_err("video_port_init failed\n"); - goto error2; - } - } - - if ((port->type & PORT_TYPE_SUB) && (port->flag & PORT_FLAG_SID)) { - r = sub_port_init(port, psbuf); - if (r < 0) { - pr_err("sub_port_init failed\n"); - goto error3; - } - } - - if (port->type & PORT_TYPE_MPTS) { - if (has_hevc_vdec()) { - r = tsdemux_init( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff, - (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff, - (port->pcr_inited == 1) ? port->pcrid : 0xffff, - (port->vformat == VFORMAT_HEVC) || - (port->vformat == VFORMAT_VP9), - vdec); - } else { - r = tsdemux_init( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff, - (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff, - (port->pcr_inited == 1) ? port->pcrid : 0xffff, - 0, - vdec); - } - - if (r < 0) { - pr_err("tsdemux_init failed\n"); - goto error4; - } - tsync_pcr_start(); - } - if (port->type & PORT_TYPE_MPPS) { - r = psparser_init( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff, - (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff, - priv->vdec); - if (r < 0) { - pr_err("psparser_init failed\n"); - goto error5; - } - } -#ifdef CONFIG_AM_VDEC_REAL - if (port->type & PORT_TYPE_RM) { - rm_set_vasid( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff); - } -#endif -#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */ - if (!NO_VDEC2_INIT) { - if ((port->type & PORT_TYPE_VIDEO) - && (port->vformat == VFORMAT_H264_4K2K)) - stbuf_vdec2_init(pvbuf); - } -#endif - - if ((port->type & PORT_TYPE_VIDEO) && - (port->flag & PORT_FLAG_VFORMAT)) - /* connect vdec at the end after all HW initialization */ - vdec_connect(vdec); - - tsync_audio_break(0); /* clear audio break */ - set_vsync_pts_inc_mode(0); /* clear video inc */ - - port_set_inited(priv); - - mutex_unlock(&amstream_mutex); - return 0; - /*errors follow here */ -error5: - tsdemux_release(); -error4: - sub_port_release(port, psbuf); -error3: - video_port_release(priv, pvbuf, 0); -error2: - audio_port_release(port, pabuf, 0); -error1: - mutex_unlock(&amstream_mutex); - return r; -} - -static int amstream_port_release(struct port_priv_s *priv) -{ - struct stream_port_s *port = priv->port; - struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO]; - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - - if (has_hevc_vdec()) { - if (port->vformat == VFORMAT_HEVC - || port->vformat == VFORMAT_VP9) - pvbuf = &bufs[BUF_TYPE_HEVC]; - } - - if (port->type & PORT_TYPE_MPTS) { - tsync_pcr_stop(); - tsdemux_release(); - } - - if (port->type & PORT_TYPE_MPPS) - psparser_release(); - - if (port->type & PORT_TYPE_VIDEO) - video_port_release(priv, pvbuf, 0); - - if (port->type & PORT_TYPE_AUDIO) - audio_port_release(port, pabuf, 0); - - if (port->type & PORT_TYPE_SUB) - sub_port_release(port, psbuf); - - port->pcr_inited = 0; - port->flag = 0; - return 0; -} - -static void amstream_change_avid(struct stream_port_s *port) -{ - if (port->type & PORT_TYPE_MPTS) { - tsdemux_change_avid( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff); - } - - if (port->type & PORT_TYPE_MPPS) { - psparser_change_avid( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff); - } - -#ifdef CONFIG_AM_VDEC_REAL - if (port->type & PORT_TYPE_RM) { - rm_set_vasid( - (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff, - (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff); - } -#endif -} - -static void amstream_change_sid(struct stream_port_s *port) -{ - if (port->type & PORT_TYPE_MPTS) { - tsdemux_change_sid( - (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff); - } - - if (port->type & PORT_TYPE_MPPS) { - psparser_change_sid( - (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff); - } -} - -/**************************************************/ -static ssize_t amstream_vbuf_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - struct stream_buf_s *pbuf = NULL; - int r; - - - if (has_hevc_vdec()) { - pbuf = (port->type & PORT_TYPE_HEVC) ? &bufs[BUF_TYPE_HEVC] : - &bufs[BUF_TYPE_VIDEO]; - } else - pbuf = &bufs[BUF_TYPE_VIDEO]; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } - - if (port->flag & PORT_FLAG_DRM) - r = drm_write(file, pbuf, buf, count); - else - r = esparser_write(file, pbuf, buf, count); - if (slow_input) { - pr_info("slow_input: es codec write size %x\n", r); - msleep(3000); - } -#ifdef DATA_DEBUG - debug_file_write(buf, r); -#endif - - return r; -} - -static ssize_t amstream_vframe_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; -#ifdef DATA_DEBUG - debug_file_write(buf, count); -#endif - return vdec_write_vframe(priv->vdec, buf, count); -} - -static ssize_t amstream_abuf_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - struct stream_buf_s *pbuf = &bufs[BUF_TYPE_AUDIO]; - int r; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } - - if (port->flag & PORT_FLAG_DRM) - r = drm_write(file, pbuf, buf, count); - else - r = esparser_write(file, pbuf, buf, count); - - return r; -} - -static ssize_t amstream_mpts_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - struct stream_buf_s *pvbuf = NULL; - int r = 0; - - if (has_hevc_vdec()) { - pvbuf = (port->vformat == VFORMAT_HEVC || - port->vformat == VFORMAT_VP9) ? - &bufs[BUF_TYPE_HEVC] : &bufs[BUF_TYPE_VIDEO]; - } else - pvbuf = &bufs[BUF_TYPE_VIDEO]; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } -#ifdef DATA_DEBUG - debug_file_write(buf, count); -#endif - if (port->flag & PORT_FLAG_DRM) - r = drm_tswrite(file, pvbuf, pabuf, buf, count); - else - r = tsdemux_write(file, pvbuf, pabuf, buf, count); - if (slow_input) { - pr_info("slow_input: ts codec write size %x\n", r); - msleep(3000); - } - return r; -} - -static ssize_t amstream_mpps_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO]; - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - int r; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } - return psparser_write(file, pvbuf, pabuf, buf, count); -} - -#ifdef CONFIG_AM_VDEC_REAL -static ssize_t amstream_mprm_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO]; - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - int r; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } - return rmparser_write(file, pvbuf, pabuf, buf, count); -} -#endif - -static ssize_t amstream_sub_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - u32 sub_rp, sub_wp, sub_start, data_size, res; - struct stream_buf_s *s_buf = &bufs[BUF_TYPE_SUBTITLE]; - - if (sub_port_inited == 0) - return 0; - - sub_rp = stbuf_sub_rp_get(); - sub_wp = stbuf_sub_wp_get(); - sub_start = stbuf_sub_start_get(); - - if (sub_wp == sub_rp || sub_rp == 0) - return 0; - - if (sub_wp > sub_rp) - data_size = sub_wp - sub_rp; - else - data_size = s_buf->buf_size - sub_rp + sub_wp; - - if (data_size > count) - data_size = count; - - if (sub_wp < sub_rp) { - int first_num = s_buf->buf_size - (sub_rp - sub_start); - - if (data_size <= first_num) { - res = copy_to_user((void *)buf, - (void *)(codec_mm_phys_to_virt(sub_rp)), - data_size); - if (res >= 0) - stbuf_sub_rp_set(sub_rp + data_size - res); - - return data_size - res; - } else { - if (first_num > 0) { - res = copy_to_user((void *)buf, - (void *)(codec_mm_phys_to_virt(sub_rp)), - first_num); - if (res >= 0) { - stbuf_sub_rp_set(sub_rp + first_num - - res); - } - - return first_num - res; - } - - res = copy_to_user((void *)buf, - (void *)(codec_mm_phys_to_virt(sub_start)), - data_size - first_num); - - if (res >= 0) { - stbuf_sub_rp_set(sub_start + data_size - - first_num - res); - } - - return data_size - first_num - res; - } - } else { - res = - copy_to_user((void *)buf, - (void *)(codec_mm_phys_to_virt(sub_rp)), - data_size); - - if (res >= 0) - stbuf_sub_rp_set(sub_rp + data_size - res); - - return data_size - res; - } -} - -static ssize_t amstream_sub_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_buf_s *pbuf = &bufs[BUF_TYPE_SUBTITLE]; - int r; - - if (!(port_get_inited(priv))) { - r = amstream_port_init(priv); - if (r < 0) - return r; - } - r = esparser_write(file, pbuf, buf, count); - if (r < 0) - return r; - - wakeup_sub_poll(); - - return r; -} - -static unsigned int amstream_sub_poll(struct file *file, - poll_table *wait_table) -{ - poll_wait(file, &amstream_sub_wait, wait_table); - - if (atomic_read(&subdata_ready)) { - atomic_dec(&subdata_ready); - return POLLOUT | POLLWRNORM; - } - - return 0; -} - -void set_userdata_poc(struct userdata_poc_info_t poc) -{ - /* - *pr_err("id %d, slicetype %d\n", - * userdata_slicetype_wi, slicetype); - */ - userdata_poc_info[userdata_poc_wi] = poc; - userdata_poc_wi++; - if (userdata_poc_wi == USERDATA_FIFO_NUM) - userdata_poc_wi = 0; -} -EXPORT_SYMBOL(set_userdata_poc); - -void init_userdata_fifo(void) -{ - userdata_poc_ri = 0; - userdata_poc_wi = 0; -} -EXPORT_SYMBOL(init_userdata_fifo); - -int wakeup_userdata_poll(int wp, unsigned long start_phyaddr, int buf_size, - int data_length) -{ - struct stream_buf_s *userdata_buf = &bufs[BUF_TYPE_USERDATA]; - - userdata_buf->buf_start = start_phyaddr; - userdata_buf->buf_wp = wp; - userdata_buf->buf_size = buf_size; - atomic_set(&userdata_ready, 1); - userdata_length += data_length; - wake_up_interruptible(&amstream_userdata_wait); - return userdata_buf->buf_rp; -} -EXPORT_SYMBOL(wakeup_userdata_poll); - -static unsigned int amstream_userdata_poll(struct file *file, - poll_table *wait_table) -{ - poll_wait(file, &amstream_userdata_wait, wait_table); - if (atomic_read(&userdata_ready)) { - atomic_set(&userdata_ready, 0); - return POLLIN | POLLRDNORM; - } - return 0; -} - -static ssize_t amstream_userdata_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - u32 data_size, res, retVal = 0, buf_wp; - struct stream_buf_s *userdata_buf = &bufs[BUF_TYPE_USERDATA]; - - buf_wp = userdata_buf->buf_wp; - if (userdata_buf->buf_start == 0 || userdata_buf->buf_size == 0) - return 0; - if (buf_wp == userdata_buf->buf_rp) - return 0; - if (buf_wp > userdata_buf->buf_rp) - data_size = buf_wp - userdata_buf->buf_rp; - else { - data_size = - userdata_buf->buf_size - userdata_buf->buf_rp + buf_wp; - } - if (data_size > count) - data_size = count; - if (buf_wp < userdata_buf->buf_rp) { - int first_num = userdata_buf->buf_size - userdata_buf->buf_rp; - - if (data_size <= first_num) { - res = copy_to_user((void *)buf, - (void *)((userdata_buf->buf_rp + - userdata_buf->buf_start)), data_size); - userdata_buf->buf_rp += data_size - res; - retVal = data_size - res; - } else { - if (first_num > 0) { - res = copy_to_user((void *)buf, - (void *)((userdata_buf->buf_rp + - userdata_buf->buf_start)), first_num); - userdata_buf->buf_rp += first_num - res; - retVal = first_num - res; - } else { - res = copy_to_user((void *)buf, - (void *)((userdata_buf->buf_start)), - data_size - first_num); - userdata_buf->buf_rp = - data_size - first_num - res; - retVal = data_size - first_num - res; - } - } - } else { - res = copy_to_user((void *)buf, - (void *)((userdata_buf->buf_rp + - userdata_buf->buf_start)), - data_size); - userdata_buf->buf_rp += data_size - res; - retVal = data_size - res; - } - return retVal; -} - -static int amstream_open(struct inode *inode, struct file *file) -{ - s32 i; - struct stream_port_s *s; - struct stream_port_s *port = &ports[iminor(inode)]; - struct port_priv_s *priv; - - if (iminor(inode) >= amstream_port_num) - return -ENODEV; - - mutex_lock(&amstream_mutex); - - if (port->type & PORT_TYPE_VIDEO) { - for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) { - if (((s->type & PORT_TYPE_DECODER_SCHED) == 0) && - (s->type & PORT_TYPE_VIDEO) && - (s->flag & PORT_FLAG_IN_USE)) { - mutex_unlock(&amstream_mutex); - return -EBUSY; - } - } - } - - if ((port->flag & PORT_FLAG_IN_USE) && - ((port->type & PORT_TYPE_FRAME) == 0)) { - mutex_unlock(&amstream_mutex); - return -EBUSY; - } - - /* check other ports conflicts for audio */ - for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) { - if ((s->flag & PORT_FLAG_IN_USE) && - ((port->type) & (s->type) & PORT_TYPE_AUDIO)) { - mutex_unlock(&amstream_mutex); - return -EBUSY; - } - } - - priv = kzalloc(sizeof(struct port_priv_s), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - priv->port = port; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("demux", 1); */ - amports_switch_gate("demux", 1); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - /* TODO: clc gate */ - /* CLK_GATE_ON(HIU_PARSER_TOP); */ - amports_switch_gate("parser_top", 1); - } - - if (port->type & PORT_TYPE_VIDEO) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("vdec", 1); */ - amports_switch_gate("vdec", 1); - amports_switch_gate("clk_vdec_mux", 1); - amports_switch_gate("clk_hcodec_mux", 1); - - if (has_hevc_vdec()) { - amports_switch_gate("clk_hevc_mux", 1); - if (port->type & - (PORT_TYPE_MPTS | PORT_TYPE_HEVC)) - vdec_poweron(VDEC_HEVC); - - if ((port->type & PORT_TYPE_HEVC) == 0) - vdec_poweron(VDEC_1); - } else { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) - vdec_poweron(VDEC_1); - } - } - - if (port->type & PORT_TYPE_AUDIO) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("audio", 1); */ - amports_switch_gate("audio", 1); - } - } - - port->vid = 0; - port->aid = 0; - port->sid = 0; - port->pcrid = 0xffff; - file->f_op = port->fops; - file->private_data = priv; - - port->flag = PORT_FLAG_IN_USE; - port->pcr_inited = 0; -#ifdef DATA_DEBUG - debug_filp = filp_open(DEBUG_FILE_NAME, O_WRONLY, 0); - if (IS_ERR(debug_filp)) { - pr_err("amstream: open debug file failed\n"); - debug_filp = NULL; - } -#endif - mutex_unlock(&amstream_mutex); - - if (port->type & PORT_TYPE_VIDEO) { - priv->vdec = vdec_create(port, NULL); - - if (priv->vdec == NULL) { - port->flag = 0; - kfree(priv); - pr_err("amstream: vdec creation failed\n"); - return -ENOMEM; - } - - if (port->type & PORT_TYPE_DUALDEC) { - priv->vdec->slave = vdec_create(port, priv->vdec); - - if (priv->vdec->slave == NULL) { - vdec_release(priv->vdec); - port->flag = 0; - kfree(priv); - pr_err("amstream: sub vdec creation failed\n"); - return -ENOMEM; - } - } - } - return 0; -} - -static int amstream_release(struct inode *inode, struct file *file) -{ - struct port_priv_s *priv = file->private_data; - struct stream_port_s *port = priv->port; - - if (iminor(inode) >= amstream_port_num) - return -ENODEV; - - mutex_lock(&amstream_mutex); - - if (port_get_inited(priv)) - amstream_port_release(priv); - - if (priv->vdec) { - if (priv->vdec->slave) - vdec_release(priv->vdec->slave); - - vdec_release(priv->vdec); - priv->vdec = NULL; - } - - if ((port->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) == - PORT_TYPE_AUDIO) { - s32 i; - struct stream_port_s *s; - - for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) { - if ((s->flag & PORT_FLAG_IN_USE) - && (s->type & PORT_TYPE_VIDEO)) - break; - } - if (i == amstream_port_num) - timestamp_firstvpts_set(0); - } - port->flag = 0; - - /* timestamp_pcrscr_set(0); */ - -#ifdef DATA_DEBUG - if (debug_filp) { - filp_close(debug_filp, current->files); - debug_filp = NULL; - debug_file_pos = 0; - } -#endif - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - if (port->type & PORT_TYPE_VIDEO) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { -#ifndef CONFIG_MULTI_DEC - if (has_hevc_vdec()) - vdec_poweroff(VDEC_HEVC); - - vdec_poweroff(VDEC_1); -#else - if ((port->type & PORT_TYPE_MPTS) && - ((port->flag & PORT_FLAG_VFORMAT) == 0)) { - vdec_poweroff(VDEC_1); - vdec_poweroff(VDEC_HEVC); - } else if ((port->vformat == VFORMAT_HEVC - || port->vformat == VFORMAT_VP9)) { - vdec_poweroff(VDEC_HEVC); - } else { - vdec_poweroff(VDEC_1); - } -#endif - } - /* TODO: mod gate */ - /* switch_mod_gate_by_name("vdec", 0); */ - amports_switch_gate("vdec", 0); - amports_switch_gate("clk_hcodec_mux", 0); - } - - if (port->type & PORT_TYPE_AUDIO) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("audio", 0); */ - /* amports_switch_gate("audio", 0); */ - } - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { - /* TODO: clc gate */ - /* CLK_GATE_OFF(HIU_PARSER_TOP); */ - amports_switch_gate("parser_top", 0); - } - /* TODO: mod gate */ - /* switch_mod_gate_by_name("demux", 0); */ - amports_switch_gate("demux", 0); - } - - kfree(priv); - - mutex_unlock(&amstream_mutex); - return 0; -} - -static long amstream_ioctl_get_version(struct port_priv_s *priv, - ulong arg) -{ - int version = (AMSTREAM_IOC_VERSION_FIRST & 0xffff) << 16 - | (AMSTREAM_IOC_VERSION_SECOND & 0xffff); - put_user(version, (u32 __user *)arg); - - return 0; -} -static long amstream_ioctl_get(struct port_priv_s *priv, ulong arg) -{ - struct stream_port_s *this = priv->port; - long r = 0; - - struct am_ioctl_parm parm; - - if (copy_from_user - ((void *)&parm, (void *)arg, - sizeof(parm))) - r = -EFAULT; - - switch (parm.cmd) { - case AMSTREAM_GET_SUB_LENGTH: - if ((this->type & PORT_TYPE_SUB) || - (this->type & PORT_TYPE_SUB_RD)) { - u32 sub_wp, sub_rp; - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - int val; - - sub_wp = stbuf_sub_wp_get(); - sub_rp = stbuf_sub_rp_get(); - - if (sub_wp == sub_rp) - val = 0; - else if (sub_wp > sub_rp) - val = sub_wp - sub_rp; - else - val = psbuf->buf_size - (sub_rp - sub_wp); - parm.data_32 = val; - } else - r = -EINVAL; - break; - case AMSTREAM_GET_UD_LENGTH: - if (this->type & PORT_TYPE_USERDATA) { - parm.data_32 = userdata_length; - userdata_length = 0; - } else - r = -EINVAL; - break; - case AMSTREAM_GET_APTS_LOOKUP: - if (this->type & PORT_TYPE_AUDIO) { - u32 pts = 0, offset; - - offset = parm.data_32; - pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300); - parm.data_32 = pts; - } - break; - case AMSTREAM_GET_FIRST_APTS_FLAG: - if (this->type & PORT_TYPE_AUDIO) { - parm.data_32 = first_pts_checkin_complete( - PTS_TYPE_AUDIO); - } - break; - case AMSTREAM_GET_APTS: - parm.data_32 = timestamp_apts_get(); - break; - case AMSTREAM_GET_VPTS: - parm.data_32 = timestamp_vpts_get(); - break; - case AMSTREAM_GET_PCRSCR: - parm.data_32 = timestamp_pcrscr_get(); - break; - case AMSTREAM_GET_LAST_CHECKIN_APTS: - parm.data_32 = get_last_checkin_pts(PTS_TYPE_AUDIO); - break; - case AMSTREAM_GET_LAST_CHECKIN_VPTS: - parm.data_32 = get_last_checkin_pts(PTS_TYPE_VIDEO); - break; - case AMSTREAM_GET_LAST_CHECKOUT_APTS: - parm.data_32 = get_last_checkout_pts(PTS_TYPE_AUDIO); - break; - case AMSTREAM_GET_LAST_CHECKOUT_VPTS: - parm.data_32 = get_last_checkout_pts(PTS_TYPE_VIDEO); - break; - case AMSTREAM_GET_SUB_NUM: - parm.data_32 = psparser_get_sub_found_num(); - break; - case AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS: - parm.data_32 = bufs[BUF_TYPE_VIDEO].max_buffer_delay_ms; - break; - case AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS: - parm.data_32 = bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms; - break; - case AMSTREAM_GET_VIDEO_CUR_DELAY_MS: { - int delay; - - delay = calculation_stream_delayed_ms( - PTS_TYPE_VIDEO, NULL, NULL); - if (delay >= 0) - parm.data_32 = delay; - else - parm.data_32 = 0; - } - break; - - case AMSTREAM_GET_AUDIO_CUR_DELAY_MS: { - int delay; - - delay = calculation_stream_delayed_ms( - PTS_TYPE_AUDIO, NULL, NULL); - if (delay >= 0) - parm.data_32 = delay; - else - parm.data_32 = 0; - } - break; - case AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS: { - int delay; - u32 avgbps; - - delay = calculation_stream_delayed_ms( - PTS_TYPE_AUDIO, NULL, &avgbps); - if (delay >= 0) - parm.data_32 = avgbps; - else - parm.data_32 = 0; - } - break; - case AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS: { - int delay; - u32 avgbps; - - delay = calculation_stream_delayed_ms( - PTS_TYPE_VIDEO, NULL, &avgbps); - if (delay >= 0) - parm.data_32 = avgbps; - else - parm.data_32 = 0; - } - break; - case AMSTREAM_GET_ION_ID: - parm.data_32 = priv->vdec->vf_receiver_inst; - break; - default: - r = -ENOIOCTLCMD; - break; - } - /* pr_info("parm size:%d\n", sizeof(parm)); */ - if (r == 0) { - if (copy_to_user((void *)arg, &parm, sizeof(parm))) - r = -EFAULT; - } - - return r; - -} -static long amstream_ioctl_set(struct port_priv_s *priv, ulong arg) -{ - struct stream_port_s *this = priv->port; - struct am_ioctl_parm parm; - long r = 0; - - if (copy_from_user - ((void *)&parm, (void *)arg, - sizeof(parm))) - r = -EFAULT; - - switch (parm.cmd) { - case AMSTREAM_SET_VB_START: - if ((this->type & PORT_TYPE_VIDEO) && - ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) { - if (has_hevc_vdec()) - bufs[BUF_TYPE_HEVC].buf_start = parm.data_32; - bufs[BUF_TYPE_VIDEO].buf_start = parm.data_32; - } else - r = -EINVAL; - break; - case AMSTREAM_SET_VB_SIZE: - if ((this->type & PORT_TYPE_VIDEO) && - ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) { - if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) { - if (has_hevc_vdec()) { - r = stbuf_change_size( - &bufs[BUF_TYPE_HEVC], - parm.data_32); - } - r = stbuf_change_size( - &bufs[BUF_TYPE_VIDEO], - parm.data_32); - } - } else if (this->type & PORT_TYPE_FRAME) { - /* todo: frame based set max buffer size */ - r = 0; - } else - r = -EINVAL; - break; - case AMSTREAM_SET_AB_START: - if ((this->type & PORT_TYPE_AUDIO) && - ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) - bufs[BUF_TYPE_AUDIO].buf_start = parm.data_32; - else - r = -EINVAL; - break; - case AMSTREAM_SET_AB_SIZE: - if ((this->type & PORT_TYPE_AUDIO) && - ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) { - if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) { - r = stbuf_change_size( - &bufs[BUF_TYPE_AUDIO], parm.data_32); - } - } else - r = -EINVAL; - break; - case AMSTREAM_SET_VFORMAT: - if ((this->type & PORT_TYPE_VIDEO) && - (parm.data_vformat < VFORMAT_MAX)) { - this->vformat = parm.data_vformat; - this->flag |= PORT_FLAG_VFORMAT; - - vdec_set_format(priv->vdec, this->vformat); - } else - r = -EINVAL; - break; - case AMSTREAM_SET_AFORMAT: - if ((this->type & PORT_TYPE_AUDIO) && - (parm.data_aformat < AFORMAT_MAX)) { - memset(&audio_dec_info, 0, - sizeof(struct audio_info)); - /* for new format,reset the audio info. */ - this->aformat = parm.data_aformat; - this->flag |= PORT_FLAG_AFORMAT; - } else - r = -EINVAL; - break; - case AMSTREAM_SET_VID: - if (this->type & PORT_TYPE_VIDEO) { - this->vid = parm.data_32; - this->flag |= PORT_FLAG_VID; - } else - r = -EINVAL; - - break; - case AMSTREAM_SET_AID: - if (this->type & PORT_TYPE_AUDIO) { - this->aid = parm.data_32; - this->flag |= PORT_FLAG_AID; - - if (port_get_inited(priv)) { - tsync_audio_break(1); - amstream_change_avid(this); - } - } else - r = -EINVAL; - break; - case AMSTREAM_SET_SID: - if (this->type & PORT_TYPE_SUB) { - this->sid = parm.data_32; - this->flag |= PORT_FLAG_SID; - - if (port_get_inited(priv)) - amstream_change_sid(this); - } else - r = -EINVAL; - - break; - case AMSTREAM_IOC_PCRID: - this->pcrid = parm.data_32; - this->pcr_inited = 1; - pr_err("set pcrid = 0x%x\n", this->pcrid); - break; - case AMSTREAM_SET_ACHANNEL: - if (this->type & PORT_TYPE_AUDIO) { - this->achanl = parm.data_32; - set_ch_num_info(parm.data_32); - } else - r = -EINVAL; - break; - case AMSTREAM_SET_SAMPLERATE: - if (this->type & PORT_TYPE_AUDIO) { - this->asamprate = parm.data_32; - set_sample_rate_info(parm.data_32); - } else - r = -EINVAL; - break; - case AMSTREAM_SET_DATAWIDTH: - if (this->type & PORT_TYPE_AUDIO) - this->adatawidth = parm.data_32; - else - r = -EINVAL; - break; - case AMSTREAM_SET_TSTAMP: - if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) == - ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO))) - r = -EINVAL; - else if (this->type & PORT_TYPE_FRAME) - r = vdec_set_pts(priv->vdec, parm.data_32); - else if (has_hevc_vdec() && this->type & PORT_TYPE_HEVC) - r = es_vpts_checkin(&bufs[BUF_TYPE_HEVC], - parm.data_32); - else if (this->type & PORT_TYPE_VIDEO) - r = es_vpts_checkin(&bufs[BUF_TYPE_VIDEO], - parm.data_32); - else if (this->type & PORT_TYPE_AUDIO) - r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO], - parm.data_32); - break; - case AMSTREAM_SET_TSTAMP_US64: - if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) == - ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO))) - r = -EINVAL; - else { - u64 pts = parm.data_64; - - if (this->type & PORT_TYPE_FRAME) { - /* - *todo: check upper layer for decoder handler - * life sequence or multi-tasking management - */ - r = vdec_set_pts64(priv->vdec, pts); - } else if (has_hevc_vdec()) { - if (this->type & PORT_TYPE_HEVC) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_HEVC], pts); - } else if (this->type & PORT_TYPE_VIDEO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_VIDEO], pts); - } else if (this->type & PORT_TYPE_AUDIO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_AUDIO], pts); - } - } else { - if (this->type & PORT_TYPE_VIDEO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_VIDEO], pts); - } else if (this->type & PORT_TYPE_AUDIO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_AUDIO], pts); - } - } - } - break; - case AMSTREAM_PORT_INIT: - r = amstream_port_init(priv); - break; - case AMSTREAM_SET_TRICKMODE: - if ((this->type & PORT_TYPE_VIDEO) == 0) - return -EINVAL; - r = vdec_set_trickmode(priv->vdec, parm.data_32); - if (r == -1) - return -ENODEV; - break; - - case AMSTREAM_AUDIO_RESET: - if (this->type & PORT_TYPE_AUDIO) { - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - - r = audio_port_reset(this, pabuf); - } else - r = -EINVAL; - - break; - case AMSTREAM_SUB_RESET: - if (this->type & PORT_TYPE_SUB) { - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - - r = sub_port_reset(this, psbuf); - } else - r = -EINVAL; - break; - case AMSTREAM_DEC_RESET: - tsync_set_dec_reset(); - break; - case AMSTREAM_SET_TS_SKIPBYTE: - if (parm.data_32 >= 0) - tsdemux_set_skipbyte(parm.data_32); - else - r = -EINVAL; - break; - case AMSTREAM_SET_SUB_TYPE: - sub_type = parm.data_32; - break; - case AMSTREAM_SET_PCRSCR: - timestamp_pcrscr_set(parm.data_32); - break; - case AMSTREAM_SET_DEMUX: - tsdemux_set_demux(parm.data_32); - break; - case AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS: - if (has_hevc_vdec()) - bufs[BUF_TYPE_HEVC].max_buffer_delay_ms = parm.data_32; - bufs[BUF_TYPE_VIDEO].max_buffer_delay_ms = parm.data_32; - break; - case AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS: - bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms = parm.data_32; - break; - case AMSTREAM_SET_DRMMODE: - if (parm.data_32 == 1) { - pr_err("set drmmode\n"); - this->flag |= PORT_FLAG_DRM; - } else { - this->flag &= (~PORT_FLAG_DRM); - pr_err("no drmmode\n"); - } - break; - case AMSTREAM_SET_APTS: { - unsigned int pts; - - pts = parm.data_32; - if (tsync_get_mode() == TSYNC_MODE_PCRMASTER) - tsync_pcr_set_apts(pts); - else - tsync_set_apts(pts); - break; - } - case AMSTREAM_SET_FRAME_BASE_PATH: - if ((this->type & PORT_TYPE_DECODER_SCHED) && - (parm.frame_base_video_path < FRAME_BASE_PATH_MAX)) { - vdec_set_video_path(priv->vdec, parm.data_32); - } else - r = -EINVAL; - break; - default: - r = -ENOIOCTLCMD; - break; - } - return r; -} -static long amstream_ioctl_get_ex(struct port_priv_s *priv, ulong arg) -{ - struct stream_port_s *this = priv->port; - long r = 0; - struct am_ioctl_parm_ex parm; - - if (copy_from_user - ((void *)&parm, (void *)arg, - sizeof(parm))) - r = -EFAULT; - - switch (parm.cmd) { - case AMSTREAM_GET_EX_VB_STATUS: - if (this->type & PORT_TYPE_VIDEO) { - struct am_ioctl_parm_ex *p = &parm; - struct stream_buf_s *buf = NULL; - - buf = (this->vformat == VFORMAT_HEVC || - this->vformat == VFORMAT_VP9) ? - &bufs[BUF_TYPE_HEVC] : - &bufs[BUF_TYPE_VIDEO]; - - if (p == NULL) { - r = -EINVAL; - break; - } - - if (this->type & PORT_TYPE_FRAME) { - struct vdec_input_status_s status; - - /* - *todo: check upper layer for decoder - * handler lifecycle - */ - if (priv->vdec == NULL) { - r = -EINVAL; - break; - } - - r = vdec_input_get_status(&priv->vdec->input, - &status); - if (r == 0) { - p->status.size = status.size; - p->status.data_len = status.data_len; - p->status.free_len = status.free_len; - p->status.read_pointer = - status.read_pointer; - } - break; - } - - p->status.size = stbuf_canusesize(buf); - p->status.data_len = stbuf_level(buf); - p->status.free_len = stbuf_space(buf); - p->status.read_pointer = stbuf_rp(buf); - } else - r = -EINVAL; - break; - case AMSTREAM_GET_EX_AB_STATUS: - if (this->type & PORT_TYPE_AUDIO) { - struct am_ioctl_parm_ex *p = &parm; - struct stream_buf_s *buf = &bufs[BUF_TYPE_AUDIO]; - - if (p == NULL) - r = -EINVAL; - - p->status.size = stbuf_canusesize(buf); - p->status.data_len = stbuf_level(buf); - p->status.free_len = stbuf_space(buf); - p->status.read_pointer = stbuf_rp(buf); - - } else - r = -EINVAL; - break; - case AMSTREAM_GET_EX_VDECSTAT: - if ((this->type & PORT_TYPE_VIDEO) == 0) { - pr_err("no video\n"); - return -EINVAL; - } else { - struct vdec_status vstatus; - struct am_ioctl_parm_ex *p = &parm; - - if (p == NULL) - return -EINVAL; - if (vdec_status(priv->vdec, &vstatus) == -1) - return -ENODEV; - p->vstatus.width = vstatus.width; - p->vstatus.height = vstatus.height; - p->vstatus.fps = vstatus.fps; - p->vstatus.error_count = vstatus.error_count; - p->vstatus.status = vstatus.status; - } - break; - case AMSTREAM_GET_EX_ADECSTAT: - if ((this->type & PORT_TYPE_AUDIO) == 0) { - pr_err("no audio\n"); - return -EINVAL; - } - if (amstream_adec_status == NULL) { - /* - *pr_err("no amstream_adec_status\n"); - *return -ENODEV; - */ - memset(&parm.astatus, 0, sizeof(parm.astatus)); - } - else { - struct adec_status astatus; - struct am_ioctl_parm_ex *p = &parm; - - if (p == NULL) - return -EINVAL; - amstream_adec_status(&astatus); - p->astatus.channels = astatus.channels; - p->astatus.sample_rate = astatus.sample_rate; - p->astatus.resolution = astatus.resolution; - p->astatus.error_count = astatus.error_count; - p->astatus.status = astatus.status; - } - break; - - case AMSTREAM_GET_EX_UD_POC: - if (this->type & PORT_TYPE_USERDATA) { - struct userdata_poc_info_t userdata_poc = - userdata_poc_info[userdata_poc_ri]; - memcpy(&parm.data_userdata_info, - &userdata_poc, - sizeof(struct userdata_poc_info_t)); - - userdata_poc_ri++; - if (USERDATA_FIFO_NUM == userdata_poc_ri) - userdata_poc_ri = 0; - } else - r = -EINVAL; - break; - default: - r = -ENOIOCTLCMD; - break; - } - /* pr_info("parm size:%zx\n", sizeof(parm)); */ - if (r == 0) { - if (copy_to_user((void *)arg, &parm, sizeof(parm))) - r = -EFAULT; - } - return r; - -} -static long amstream_ioctl_set_ex(struct port_priv_s *priv, ulong arg) -{ - long r = 0; - return r; -} -static long amstream_ioctl_get_ptr(struct port_priv_s *priv, ulong arg) -{ - long r = 0; - - struct am_ioctl_parm_ptr parm; - - if (copy_from_user - ((void *)&parm, (void *)arg, - sizeof(parm))) - r = -EFAULT; - - switch (parm.cmd) { - case AMSTREAM_GET_PTR_SUB_INFO: - { - struct subtitle_info msub_info[MAX_SUB_NUM]; - struct subtitle_info *psub_info[MAX_SUB_NUM]; - int i; - - for (i = 0; i < MAX_SUB_NUM; i++) - psub_info[i] = &msub_info[i]; - - r = psparser_get_sub_info(psub_info); - - if (r == 0) { - memcpy(parm.pdata_sub_info, msub_info, - sizeof(struct subtitle_info) - * MAX_SUB_NUM); - } - } - break; - default: - r = -ENOIOCTLCMD; - break; - } - /* pr_info("parm size:%d\n", sizeof(parm)); */ - if (r == 0) { - if (copy_to_user((void *)arg, &parm, sizeof(parm))) - r = -EFAULT; - } - - return r; - -} -static long amstream_ioctl_set_ptr(struct port_priv_s *priv, ulong arg) -{ - struct stream_port_s *this = priv->port; - struct am_ioctl_parm_ptr parm; - long r = 0; - - if (copy_from_user - ((void *)&parm, (void *)arg, - sizeof(parm))) { - pr_err("[%s]%d, arg err\n", __func__, __LINE__); - r = -EFAULT; - } - switch (parm.cmd) { - case AMSTREAM_SET_PTR_AUDIO_INFO: - if ((this->type & PORT_TYPE_VIDEO) - || (this->type & PORT_TYPE_AUDIO)) { - if (parm.pdata_audio_info != NULL) - memcpy((void *)&audio_dec_info, - (void *)parm.pdata_audio_info, - sizeof(audio_dec_info)); - } else - r = -EINVAL; - break; - case AMSTREAM_SET_PTR_CONFIGS: - if (this->type & PORT_TYPE_VIDEO) { - if (!parm.pointer || (parm.len <= 0) || - (parm.len > PAGE_SIZE)) { - r = -EINVAL; - } else { - r = copy_from_user(priv->vdec->config, - parm.pointer, parm.len); - if (r) - r = -EINVAL; - else - priv->vdec->config_len = parm.len; - } - } else - r = -EINVAL; - break; - default: - r = -ENOIOCTLCMD; - break; - } - return r; -} - -static long amstream_do_ioctl_new(struct port_priv_s *priv, - unsigned int cmd, ulong arg) -{ - long r = 0; - struct stream_port_s *this = priv->port; - - switch (cmd) { - case AMSTREAM_IOC_GET_VERSION: - r = amstream_ioctl_get_version(priv, arg); - break; - case AMSTREAM_IOC_GET: - r = amstream_ioctl_get(priv, arg); - break; - case AMSTREAM_IOC_SET: - r = amstream_ioctl_set(priv, arg); - break; - case AMSTREAM_IOC_GET_EX: - r = amstream_ioctl_get_ex(priv, arg); - break; - case AMSTREAM_IOC_SET_EX: - r = amstream_ioctl_set_ex(priv, arg); - break; - case AMSTREAM_IOC_GET_PTR: - r = amstream_ioctl_get_ptr(priv, arg); - break; - case AMSTREAM_IOC_SET_PTR: - r = amstream_ioctl_set_ptr(priv, arg); - break; - case AMSTREAM_IOC_SYSINFO: - if (this->type & PORT_TYPE_VIDEO) - r = vdec_set_decinfo(priv->vdec, (void *)arg); - else - r = -EINVAL; - break; - default: - r = -ENOIOCTLCMD; - break; - } - - return r; -} - -static long amstream_do_ioctl_old(struct port_priv_s *priv, - unsigned int cmd, ulong arg) -{ - struct stream_port_s *this = priv->port; - long r = 0; - - switch (cmd) { - - case AMSTREAM_IOC_VB_START: - if ((this->type & PORT_TYPE_VIDEO) && - ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) { - if (has_hevc_vdec()) - bufs[BUF_TYPE_HEVC].buf_start = arg; - bufs[BUF_TYPE_VIDEO].buf_start = arg; - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_VB_SIZE: - if ((this->type & PORT_TYPE_VIDEO) && - ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) { - if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) { - if (has_hevc_vdec()) { - r = stbuf_change_size( - &bufs[BUF_TYPE_HEVC], arg); - } - r = stbuf_change_size( - &bufs[BUF_TYPE_VIDEO], arg); - } - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_AB_START: - if ((this->type & PORT_TYPE_AUDIO) && - ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) - bufs[BUF_TYPE_AUDIO].buf_start = arg; - else - r = -EINVAL; - break; - - case AMSTREAM_IOC_AB_SIZE: - if ((this->type & PORT_TYPE_AUDIO) && - ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) { - if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) { - r = stbuf_change_size( - &bufs[BUF_TYPE_AUDIO], arg); - } - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_VFORMAT: - if ((this->type & PORT_TYPE_VIDEO) && (arg < VFORMAT_MAX)) { - this->vformat = (enum vformat_e)arg; - this->flag |= PORT_FLAG_VFORMAT; - - vdec_set_format(priv->vdec, this->vformat); - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_AFORMAT: - if ((this->type & PORT_TYPE_AUDIO) && (arg < AFORMAT_MAX)) { - memset(&audio_dec_info, 0, - sizeof(struct audio_info)); - /* for new format,reset the audio info. */ - this->aformat = (enum aformat_e)arg; - this->flag |= PORT_FLAG_AFORMAT; - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_VID: - if (this->type & PORT_TYPE_VIDEO) { - this->vid = (u32) arg; - this->flag |= PORT_FLAG_VID; - } else - r = -EINVAL; - - break; - - case AMSTREAM_IOC_AID: - if (this->type & PORT_TYPE_AUDIO) { - this->aid = (u32) arg; - this->flag |= PORT_FLAG_AID; - - if (port_get_inited(priv)) { - tsync_audio_break(1); - amstream_change_avid(this); - } - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_SID: - if (this->type & PORT_TYPE_SUB) { - this->sid = (u32) arg; - this->flag |= PORT_FLAG_SID; - - if (port_get_inited(priv)) - amstream_change_sid(this); - } else - r = -EINVAL; - - break; - - case AMSTREAM_IOC_PCRID: - this->pcrid = (u32) arg; - this->pcr_inited = 1; - pr_err("set pcrid = 0x%x\n", this->pcrid); - break; - - case AMSTREAM_IOC_VB_STATUS: - if (this->type & PORT_TYPE_VIDEO) { - struct am_io_param para; - struct am_io_param *p = ¶ - struct stream_buf_s *buf = NULL; - - buf = (this->vformat == VFORMAT_HEVC || - this->vformat == VFORMAT_VP9) ? - &bufs[BUF_TYPE_HEVC] : - &bufs[BUF_TYPE_VIDEO]; - - if (p == NULL) { - r = -EINVAL; - break; - } - - if (this->type & PORT_TYPE_FRAME) { - struct vdec_input_status_s status; - - /* - *todo: check upper layer for decoder - * handler lifecycle - */ - if (priv->vdec == NULL) { - r = -EINVAL; - break; - } - - r = vdec_input_get_status(&priv->vdec->input, - &status); - if (r == 0) { - p->status.size = status.size; - p->status.data_len = status.data_len; - p->status.free_len = status.free_len; - p->status.read_pointer = - status.read_pointer; - if (copy_to_user((void *)arg, p, - sizeof(para))) - r = -EFAULT; - } - break; - } - - p->status.size = stbuf_canusesize(buf); - p->status.data_len = stbuf_level(buf); - p->status.free_len = stbuf_space(buf); - p->status.read_pointer = stbuf_rp(buf); - if (copy_to_user((void *)arg, p, sizeof(para))) - r = -EFAULT; - return r; - } - r = -EINVAL; - break; - - case AMSTREAM_IOC_AB_STATUS: - if (this->type & PORT_TYPE_AUDIO) { - struct am_io_param para; - struct am_io_param *p = ¶ - struct stream_buf_s *buf = &bufs[BUF_TYPE_AUDIO]; - - if (p == NULL) - r = -EINVAL; - - p->status.size = stbuf_canusesize(buf); - p->status.data_len = stbuf_level(buf); - p->status.free_len = stbuf_space(buf); - p->status.read_pointer = stbuf_rp(buf); - if (copy_to_user((void *)arg, p, sizeof(para))) - r = -EFAULT; - return r; - } - r = -EINVAL; - break; - - case AMSTREAM_IOC_SYSINFO: - if (this->type & PORT_TYPE_VIDEO) - r = vdec_set_decinfo(priv->vdec, (void *)arg); - else - r = -EINVAL; - break; - - case AMSTREAM_IOC_ACHANNEL: - if (this->type & PORT_TYPE_AUDIO) { - this->achanl = (u32) arg; - set_ch_num_info((u32) arg); - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_SAMPLERATE: - if (this->type & PORT_TYPE_AUDIO) { - this->asamprate = (u32) arg; - set_sample_rate_info((u32) arg); - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_DATAWIDTH: - if (this->type & PORT_TYPE_AUDIO) - this->adatawidth = (u32) arg; - else - r = -EINVAL; - break; - - case AMSTREAM_IOC_TSTAMP: - if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) == - ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO))) - r = -EINVAL; - else if (this->type & PORT_TYPE_FRAME) - r = vdec_set_pts(priv->vdec, arg); - else if (has_hevc_vdec() && this->type & PORT_TYPE_HEVC) - r = es_vpts_checkin(&bufs[BUF_TYPE_HEVC], arg); - else if (this->type & PORT_TYPE_VIDEO) - r = es_vpts_checkin(&bufs[BUF_TYPE_VIDEO], arg); - else if (this->type & PORT_TYPE_AUDIO) - r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO], arg); - break; - - case AMSTREAM_IOC_TSTAMP_uS64: - if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) == - ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO))) - r = -EINVAL; - else { - u64 pts; - - if (copy_from_user - ((void *)&pts, (void *)arg, sizeof(u64))) - return -EFAULT; - if (this->type & PORT_TYPE_FRAME) { - /* - *todo: check upper layer for decoder handler - * life sequence or multi-tasking management - */ - if (priv->vdec) - r = vdec_set_pts64(priv->vdec, pts); - } else if (has_hevc_vdec()) { - if (this->type & PORT_TYPE_HEVC) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_HEVC], pts); - } else if (this->type & PORT_TYPE_VIDEO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_VIDEO], pts); - } else if (this->type & PORT_TYPE_AUDIO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_AUDIO], pts); - } - } else { - if (this->type & PORT_TYPE_VIDEO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_VIDEO], pts); - } else if (this->type & PORT_TYPE_AUDIO) { - r = es_vpts_checkin_us64( - &bufs[BUF_TYPE_AUDIO], pts); - } - } - } - break; - - case AMSTREAM_IOC_VDECSTAT: - if ((this->type & PORT_TYPE_VIDEO) == 0) - return -EINVAL; - { - struct vdec_status vstatus; - struct am_io_param para; - struct am_io_param *p = ¶ - - if (p == NULL) - return -EINVAL; - if (vdec_status(priv->vdec, &vstatus) == -1) - return -ENODEV; - p->vstatus.width = vstatus.width; - p->vstatus.height = vstatus.height; - p->vstatus.fps = vstatus.fps; - p->vstatus.error_count = vstatus.error_count; - p->vstatus.status = vstatus.status; - if (copy_to_user((void *)arg, p, sizeof(para))) - r = -EFAULT; - return r; - } - - case AMSTREAM_IOC_ADECSTAT: - if ((this->type & PORT_TYPE_AUDIO) == 0) - return -EINVAL; - if (amstream_adec_status == NULL) - return -ENODEV; - else { - struct adec_status astatus; - struct am_io_param para; - struct am_io_param *p = ¶ - - if (p == NULL) - return -EINVAL; - amstream_adec_status(&astatus); - p->astatus.channels = astatus.channels; - p->astatus.sample_rate = astatus.sample_rate; - p->astatus.resolution = astatus.resolution; - p->astatus.error_count = astatus.error_count; - p->astatus.status = astatus.status; - if (copy_to_user((void *)arg, p, sizeof(para))) - r = -EFAULT; - return r; - } - case AMSTREAM_IOC_PORT_INIT: - r = amstream_port_init(priv); - break; - - case AMSTREAM_IOC_VDEC_RESET: - if ((this->type & PORT_TYPE_VIDEO) == 0) - return -EINVAL; - - if (priv->vdec == NULL) - return -ENODEV; - - r = vdec_reset(priv->vdec); - break; - - case AMSTREAM_IOC_TRICKMODE: - if ((this->type & PORT_TYPE_VIDEO) == 0) - return -EINVAL; - r = vdec_set_trickmode(priv->vdec, arg); - if (r == -1) - return -ENODEV; - break; - - case AMSTREAM_IOC_AUDIO_INFO: - if ((this->type & PORT_TYPE_VIDEO) - || (this->type & PORT_TYPE_AUDIO)) { - if (copy_from_user - (&audio_dec_info, (void __user *)arg, - sizeof(audio_dec_info))) - r = -EFAULT; - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_AUDIO_RESET: - if (this->type & PORT_TYPE_AUDIO) { - struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO]; - - r = audio_port_reset(this, pabuf); - } else - r = -EINVAL; - - break; - - case AMSTREAM_IOC_SUB_RESET: - if (this->type & PORT_TYPE_SUB) { - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - - r = sub_port_reset(this, psbuf); - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_SUB_LENGTH: - if ((this->type & PORT_TYPE_SUB) || - (this->type & PORT_TYPE_SUB_RD)) { - u32 sub_wp, sub_rp; - struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE]; - int val; - - sub_wp = stbuf_sub_wp_get(); - sub_rp = stbuf_sub_rp_get(); - - if (sub_wp == sub_rp) - val = 0; - else if (sub_wp > sub_rp) - val = sub_wp - sub_rp; - else - val = psbuf->buf_size - (sub_rp - sub_wp); - put_user(val, (unsigned long __user *)arg); - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_UD_LENGTH: - if (this->type & PORT_TYPE_USERDATA) { - /* *((u32 *)arg) = userdata_length; */ - put_user(userdata_length, (unsigned long __user *)arg); - userdata_length = 0; - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_UD_POC: - if (this->type & PORT_TYPE_USERDATA) { - /* *((u32 *)arg) = userdata_length; */ - int res; - struct userdata_poc_info_t userdata_poc = - userdata_poc_info[userdata_poc_ri]; - /* - *put_user(userdata_poc.poc_number, - * (unsigned long __user *)arg); - */ - res = - copy_to_user((unsigned long __user *)arg, - &userdata_poc, - sizeof(struct userdata_poc_info_t)); - if (res < 0) - r = -EFAULT; - userdata_poc_ri++; - if (USERDATA_FIFO_NUM == userdata_poc_ri) - userdata_poc_ri = 0; - } else - r = -EINVAL; - break; - - case AMSTREAM_IOC_SET_DEC_RESET: - tsync_set_dec_reset(); - break; - - case AMSTREAM_IOC_TS_SKIPBYTE: - if ((int)arg >= 0) - tsdemux_set_skipbyte(arg); - else - r = -EINVAL; - break; - - case AMSTREAM_IOC_SUB_TYPE: - sub_type = (int)arg; - break; - - case AMSTREAM_IOC_APTS_LOOKUP: - if (this->type & PORT_TYPE_AUDIO) { - u32 pts = 0, offset; - - get_user(offset, (unsigned long __user *)arg); - pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300); - put_user(pts, (int __user *)arg); - } - return 0; - case GET_FIRST_APTS_FLAG: - if (this->type & PORT_TYPE_AUDIO) { - put_user(first_pts_checkin_complete(PTS_TYPE_AUDIO), - (int __user *)arg); - } - break; - - case AMSTREAM_IOC_APTS: - put_user(timestamp_apts_get(), (int __user *)arg); - break; - - case AMSTREAM_IOC_VPTS: - put_user(timestamp_vpts_get(), (int __user *)arg); - break; - - case AMSTREAM_IOC_PCRSCR: - put_user(timestamp_pcrscr_get(), (int __user *)arg); - break; - - case AMSTREAM_IOC_SET_PCRSCR: - timestamp_pcrscr_set(arg); - break; - case AMSTREAM_IOC_GET_LAST_CHECKIN_APTS: - put_user(get_last_checkin_pts(PTS_TYPE_AUDIO), (int *)arg); - break; - case AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS: - put_user(get_last_checkin_pts(PTS_TYPE_VIDEO), (int *)arg); - break; - case AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS: - put_user(get_last_checkout_pts(PTS_TYPE_AUDIO), (int *)arg); - break; - case AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS: - put_user(get_last_checkout_pts(PTS_TYPE_VIDEO), (int *)arg); - break; - case AMSTREAM_IOC_SUB_NUM: - put_user(psparser_get_sub_found_num(), (int *)arg); - break; - - case AMSTREAM_IOC_SUB_INFO: - if (arg > 0) { - struct subtitle_info msub_info[MAX_SUB_NUM]; - struct subtitle_info *psub_info[MAX_SUB_NUM]; - int i; - - for (i = 0; i < MAX_SUB_NUM; i++) - psub_info[i] = &msub_info[i]; - - r = psparser_get_sub_info(psub_info); - - if (r == 0) { - if (copy_to_user((void __user *)arg, msub_info, - sizeof(struct subtitle_info) * MAX_SUB_NUM)) - r = -EFAULT; - } - } - break; - case AMSTREAM_IOC_SET_DEMUX: - tsdemux_set_demux((int)arg); - break; - case AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS: - if (has_hevc_vdec()) - bufs[BUF_TYPE_HEVC].max_buffer_delay_ms = (int)arg; - bufs[BUF_TYPE_VIDEO].max_buffer_delay_ms = (int)arg; - break; - case AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS: - bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms = (int)arg; - break; - case AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS: - put_user(bufs[BUF_TYPE_VIDEO].max_buffer_delay_ms, (int *)arg); - break; - case AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS: - put_user(bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms, (int *)arg); - break; - case AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS: { - int delay; - - delay = calculation_stream_delayed_ms( - PTS_TYPE_VIDEO, NULL, NULL); - if (delay >= 0) - put_user(delay, (int *)arg); - else - put_user(0, (int *)arg); - } - break; - - case AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS: { - int delay; - - delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL, - NULL); - if (delay >= 0) - put_user(delay, (int *)arg); - else - put_user(0, (int *)arg); - } - break; - case AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS: { - int delay; - u32 avgbps; - - delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL, - &avgbps); - if (delay >= 0) - put_user(avgbps, (int *)arg); - else - put_user(0, (int *)arg); - break; - } - case AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS: { - int delay; - u32 avgbps; - - delay = calculation_stream_delayed_ms(PTS_TYPE_VIDEO, NULL, - &avgbps); - if (delay >= 0) - put_user(avgbps, (int *)arg); - else - put_user(0, (int *)arg); - break; - } - case AMSTREAM_IOC_SET_DRMMODE: - if ((u32) arg == 1) { - pr_err("set drmmode\n"); - this->flag |= PORT_FLAG_DRM; - } else { - this->flag &= (~PORT_FLAG_DRM); - pr_err("no drmmode\n"); - } - break; - case AMSTREAM_IOC_SET_APTS: { - unsigned long pts; - - if (get_user(pts, (unsigned long __user *)arg)) { - pr_err - ("Get audio pts from user space fault!\n"); - return -EFAULT; - } - if (tsync_get_mode() == TSYNC_MODE_PCRMASTER) - tsync_pcr_set_apts(pts); - else - tsync_set_apts(pts); - break; - } - default: - r = -ENOIOCTLCMD; - break; - } - - return r; -} - -static long amstream_do_ioctl(struct port_priv_s *priv, - unsigned int cmd, ulong arg) -{ - long r = 0; - - switch (cmd) { - case AMSTREAM_IOC_GET_VERSION: - case AMSTREAM_IOC_GET: - case AMSTREAM_IOC_SET: - case AMSTREAM_IOC_GET_EX: - case AMSTREAM_IOC_SET_EX: - case AMSTREAM_IOC_GET_PTR: - case AMSTREAM_IOC_SET_PTR: - case AMSTREAM_IOC_SYSINFO: - r = amstream_do_ioctl_new(priv, cmd, arg); - break; - default: - r = amstream_do_ioctl_old(priv, cmd, arg); - break; - } - if (r != 0) - pr_err("amstream_do_ioctl error :%lx, %x\n", r, cmd); - - return r; -} -static long amstream_ioctl(struct file *file, unsigned int cmd, ulong arg) -{ - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *this = priv->port; - - if (!this) - return -ENODEV; - - return amstream_do_ioctl(priv, cmd, arg); -} - -#ifdef CONFIG_COMPAT -struct dec_sysinfo32 { - - u32 format; - - u32 width; - - u32 height; - - u32 rate; - - u32 extra; - - u32 status; - - u32 ratio; - - compat_uptr_t param; - - u64 ratio64; -}; - -struct am_ioctl_parm_ptr32 { - union { - compat_uptr_t pdata_audio_info; - compat_uptr_t pdata_sub_info; - compat_uptr_t pointer; - char data[8]; - }; - u32 cmd; - u32 len; -}; - -static long amstream_ioc_setget_ptr(struct port_priv_s *priv, - unsigned int cmd, struct am_ioctl_parm_ptr32 __user *arg) -{ - struct am_ioctl_parm_ptr __user *data; - struct am_ioctl_parm_ptr32 __user *data32 = arg; - int ret; - - data = compat_alloc_user_space(sizeof(*data)); - if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) - return -EFAULT; - - if (put_user(data32->cmd, &data->cmd) || - put_user(compat_ptr(data32->pointer), &data->pointer) || - put_user(data32->len, &data->len)) - return -EFAULT; - - - ret = amstream_do_ioctl(priv, cmd, (unsigned long)data); - if (ret < 0) - return ret; - return 0; - -} - -static long amstream_set_sysinfo(struct port_priv_s *priv, - struct dec_sysinfo32 __user *arg) -{ - struct dec_sysinfo __user *data; - struct dec_sysinfo32 __user *data32 = arg; - int ret; - - data = compat_alloc_user_space(sizeof(*data)); - if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) - return -EFAULT; - if (copy_in_user(data, data32, 7 * sizeof(u32))) - return -EFAULT; - if (put_user(compat_ptr(data32->param), &data->param)) - return -EFAULT; - if (copy_in_user(&data->ratio64, &data32->ratio64, - sizeof(data->ratio64))) - return -EFAULT; - - ret = amstream_do_ioctl(priv, AMSTREAM_IOC_SYSINFO, - (unsigned long)data); - if (ret < 0) - return ret; - - if (copy_in_user(&arg->format, &data->format, 7 * sizeof(u32)) || - copy_in_user(&arg->ratio64, &data->ratio64, - sizeof(arg->ratio64))) - return -EFAULT; - - return 0; -} -static long amstream_compat_ioctl(struct file *file, - unsigned int cmd, ulong arg) -{ - s32 r = 0; - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - - switch (cmd) { - case AMSTREAM_IOC_GET_VERSION: - case AMSTREAM_IOC_GET: - case AMSTREAM_IOC_SET: - case AMSTREAM_IOC_GET_EX: - case AMSTREAM_IOC_SET_EX: - return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg)); - case AMSTREAM_IOC_GET_PTR: - case AMSTREAM_IOC_SET_PTR: - return amstream_ioc_setget_ptr(priv, cmd, compat_ptr(arg)); - case AMSTREAM_IOC_SYSINFO: - return amstream_set_sysinfo(priv, compat_ptr(arg)); - default: - return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg)); - } - - return r; -} -#endif - -static ssize_t ports_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - int i; - char *pbuf = buf; - struct stream_port_s *p = NULL; - - for (i = 0; i < amstream_port_num; i++) { - p = &ports[i]; - /*name */ - pbuf += sprintf(pbuf, "%s\t:\n", p->name); - /*type */ - pbuf += sprintf(pbuf, "\ttype:%d( ", p->type); - if (p->type & PORT_TYPE_VIDEO) - pbuf += sprintf(pbuf, "%s ", "Video"); - if (p->type & PORT_TYPE_AUDIO) - pbuf += sprintf(pbuf, "%s ", "Audio"); - if (p->type & PORT_TYPE_MPTS) - pbuf += sprintf(pbuf, "%s ", "TS"); - if (p->type & PORT_TYPE_MPPS) - pbuf += sprintf(pbuf, "%s ", "PS"); - if (p->type & PORT_TYPE_ES) - pbuf += sprintf(pbuf, "%s ", "ES"); - if (p->type & PORT_TYPE_RM) - pbuf += sprintf(pbuf, "%s ", "RM"); - if (p->type & PORT_TYPE_SUB) - pbuf += sprintf(pbuf, "%s ", "Subtitle"); - if (p->type & PORT_TYPE_SUB_RD) - pbuf += sprintf(pbuf, "%s ", "Subtitle_Read"); - if (p->type & PORT_TYPE_USERDATA) - pbuf += sprintf(pbuf, "%s ", "userdata"); - pbuf += sprintf(pbuf, ")\n"); - /*flag */ - pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag); - if (p->flag & PORT_FLAG_IN_USE) - pbuf += sprintf(pbuf, "%s ", "Used"); - else - pbuf += sprintf(pbuf, "%s ", "Unused"); - if ((p->type & PORT_TYPE_VIDEO) == 0) { - if (p->flag & PORT_FLAG_INITED) - pbuf += sprintf(pbuf, "%s ", "inited"); - else - pbuf += sprintf(pbuf, "%s ", "uninited"); - } - pbuf += sprintf(pbuf, ")\n"); - /*others */ - pbuf += sprintf(pbuf, "\tVformat:%d\n", - (p->flag & PORT_FLAG_VFORMAT) ? p->vformat : -1); - pbuf += sprintf(pbuf, "\tAformat:%d\n", - (p->flag & PORT_FLAG_AFORMAT) ? p->aformat : -1); - pbuf += sprintf(pbuf, "\tVid:%d\n", - (p->flag & PORT_FLAG_VID) ? p->vid : -1); - pbuf += sprintf(pbuf, "\tAid:%d\n", - (p->flag & PORT_FLAG_AID) ? p->aid : -1); - pbuf += sprintf(pbuf, "\tSid:%d\n", - (p->flag & PORT_FLAG_SID) ? p->sid : -1); - pbuf += sprintf(pbuf, "\tPCRid:%d\n", - (p->pcr_inited == 1) ? p->pcrid : -1); - pbuf += sprintf(pbuf, "\tachannel:%d\n", p->achanl); - pbuf += sprintf(pbuf, "\tasamprate:%d\n", p->asamprate); - pbuf += sprintf(pbuf, "\tadatawidth:%d\n\n", p->adatawidth); - } - return pbuf - buf; -} - -static ssize_t bufs_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - int i; - char *pbuf = buf; - struct stream_buf_s *p = NULL; - char buf_type[][12] = { "Video", "Audio", "Subtitle", - "UserData", "HEVC" }; - - for (i = 0; i < amstream_buf_num; i++) { - p = &bufs[i]; - /*type */ - pbuf += sprintf(pbuf, "%s buffer:", buf_type[p->type]); - /*flag */ - pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag); - if (p->flag & BUF_FLAG_ALLOC) - pbuf += sprintf(pbuf, "%s ", "Alloc"); - else - pbuf += sprintf(pbuf, "%s ", "Unalloc"); - if (p->flag & BUF_FLAG_IN_USE) - pbuf += sprintf(pbuf, "%s ", "Used"); - else - pbuf += sprintf(pbuf, "%s ", "Noused"); - if (p->flag & BUF_FLAG_PARSER) - pbuf += sprintf(pbuf, "%s ", "Parser"); - else - pbuf += sprintf(pbuf, "%s ", "noParser"); - if (p->flag & BUF_FLAG_FIRST_TSTAMP) - pbuf += sprintf(pbuf, "%s ", "firststamp"); - else - pbuf += sprintf(pbuf, "%s ", "nofirststamp"); - pbuf += sprintf(pbuf, ")\n"); - /*buf stats */ - - pbuf += sprintf(pbuf, "\tbuf addr:%p\n", (void *)p->buf_start); - - if (p->type != BUF_TYPE_SUBTITLE) { - pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size); - pbuf += sprintf(pbuf, - "\tbuf canusesize:%#x\n", - p->canusebuf_size); - pbuf += sprintf(pbuf, - "\tbuf regbase:%#lx\n", p->reg_base); - - if (p->reg_base && p->flag & BUF_FLAG_IN_USE) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("vdec", 1);*/ - amports_switch_gate("vdec", 1); - } - pbuf += sprintf(pbuf, "\tbuf level:%#x\n", - stbuf_level(p)); - pbuf += sprintf(pbuf, "\tbuf space:%#x\n", - stbuf_space(p)); - pbuf += sprintf(pbuf, - "\tbuf read pointer:%#x\n", - stbuf_rp(p)); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - /* TODO: mod gate */ - /* switch_mod_gate_by_name("vdec", 0);*/ - amports_switch_gate("vdec", 0); - } - } else - pbuf += sprintf(pbuf, "\tbuf no used.\n"); - - if (p->type == BUF_TYPE_USERDATA) { - pbuf += sprintf(pbuf, - "\tbuf write pointer:%#x\n", - p->buf_wp); - pbuf += sprintf(pbuf, - "\tbuf read pointer:%#x\n", - p->buf_rp); - } - } else { - u32 sub_wp, sub_rp, data_size; - - sub_wp = stbuf_sub_wp_get(); - sub_rp = stbuf_sub_rp_get(); - if (sub_wp >= sub_rp) - data_size = sub_wp - sub_rp; - else - data_size = p->buf_size - sub_rp + sub_wp; - pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size); - pbuf += - sprintf(pbuf, "\tbuf canusesize:%#x\n", - p->canusebuf_size); - pbuf += - sprintf(pbuf, "\tbuf start:%#x\n", - stbuf_sub_start_get()); - pbuf += sprintf(pbuf, - "\tbuf write pointer:%#x\n", sub_wp); - pbuf += sprintf(pbuf, - "\tbuf read pointer:%#x\n", sub_rp); - pbuf += sprintf(pbuf, "\tbuf level:%#x\n", data_size); - } - - pbuf += sprintf(pbuf, "\tbuf first_stamp:%#x\n", - p->first_tstamp); - pbuf += sprintf(pbuf, "\tbuf wcnt:%#x\n\n", p->wcnt); - pbuf += sprintf(pbuf, "\tbuf max_buffer_delay_ms:%dms\n", - p->max_buffer_delay_ms); - - if (p->reg_base && p->flag & BUF_FLAG_IN_USE) { - int calc_delayms = 0; - u32 bitrate = 0, avg_bitrate = 0; - - calc_delayms = calculation_stream_delayed_ms( - (p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO : - PTS_TYPE_VIDEO, - &bitrate, - &avg_bitrate); - - if (calc_delayms >= 0) { - pbuf += sprintf(pbuf, - "\tbuf current delay:%dms\n", - calc_delayms); - pbuf += sprintf(pbuf, - "\tbuf bitrate latest:%dbps,avg:%dbps\n", - bitrate, avg_bitrate); - pbuf += sprintf(pbuf, - "\tbuf time after last pts:%d ms\n", - calculation_stream_ext_delayed_ms - ((p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO : - PTS_TYPE_VIDEO)); - - pbuf += sprintf(pbuf, - "\tbuf time after last write data :%d ms\n", - (int)(jiffies_64 - - p->last_write_jiffies64) * 1000 / HZ); - } - } - if (p->write_thread) { - pbuf += sprintf(pbuf, - "\twrite thread:%d/%d,fifo %d:%d,passed:%d\n", - threadrw_buffer_level(p), - threadrw_buffer_size(p), - threadrw_datafifo_len(p), - threadrw_freefifo_len(p), - threadrw_passed_len(p) - ); - } - } - - return pbuf - buf; -} - -static ssize_t videobufused_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - char *pbuf = buf; - struct stream_buf_s *p = NULL; - struct stream_buf_s *p_hevc = NULL; - - p = &bufs[0]; - if (has_hevc_vdec()) - p_hevc = &bufs[BUF_TYPE_HEVC]; - - if (p->flag & BUF_FLAG_IN_USE) - pbuf += sprintf(pbuf, "%d ", 1); - else if (has_hevc_vdec() && (p_hevc->flag & BUF_FLAG_IN_USE)) - pbuf += sprintf(pbuf, "%d ", 1); - else - pbuf += sprintf(pbuf, "%d ", 0); - return 1; -} - -static ssize_t vcodec_profile_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - return vcodec_profile_read(buf); -} - -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 ssize_t show_canuse_buferlevel(struct class *class, - struct class_attribute *attr, char *buf) -{ - ssize_t size = sprintf(buf, - "use_bufferlevel=%d/10000[=(set range[ 0~10000])=\n", - use_bufferlevelx10000); - return size; -} - -static ssize_t store_canuse_buferlevel(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size) -{ - unsigned val; - ssize_t ret; - - /*ret = sscanf(buf, "%d", &val);*/ - ret = kstrtoint(buf, 0, &val); - - if (ret != 0) - return -EINVAL; - val = val; - reset_canuse_buferlevel(val); - return size; -} - -static ssize_t store_maxdelay(struct class *class, - struct class_attribute *attr, - const char *buf, size_t size) -{ - unsigned val; - ssize_t ret; - int i; - - /*ret = sscanf(buf, "%d", &val);*/ - ret = kstrtoint(buf, 0, &val); - if (ret != 0) - return -EINVAL; - for (i = 0; i < amstream_buf_num; i++) - bufs[i].max_buffer_delay_ms = val; - return size; -} - -static ssize_t show_maxdelay(struct class *class, - struct class_attribute *attr, - char *buf) -{ - ssize_t size = 0; - - size += sprintf(buf, "%dms video max buffered data delay ms\n", - bufs[0].max_buffer_delay_ms); - size += sprintf(buf, "%dms audio max buffered data delay ms\n", - bufs[1].max_buffer_delay_ms); - return size; -} - -static struct class_attribute amstream_class_attrs[] = { - __ATTR_RO(ports), - __ATTR_RO(bufs), - __ATTR_RO(vcodec_profile), - __ATTR_RO(videobufused), - __ATTR(canuse_buferlevel, S_IRUGO | S_IWUSR | S_IWGRP, - show_canuse_buferlevel, store_canuse_buferlevel), - __ATTR(max_buffer_delay_ms, S_IRUGO | S_IWUSR | S_IWGRP, show_maxdelay, - store_maxdelay), - __ATTR_NULL -}; - -static struct class amstream_class = { - .name = "amstream", - .class_attrs = amstream_class_attrs, -}; - -int amstream_request_firmware_from_sys(const char *file_name, - char *buf, int size) -{ - const struct firmware *firmware; - int err = 0; - struct device *micro_dev; - - pr_info("try load %s ...", file_name); - micro_dev = device_create(&amstream_class, - NULL, MKDEV(AMSTREAM_MAJOR, 100), - NULL, "videodec"); - if (micro_dev == NULL) { - pr_err("device_create failed =%d\n", err); - return -1; - } - err = request_firmware(&firmware, file_name, micro_dev); - if (err < 0) { - pr_err("can't load the %s,err=%d\n", file_name, err); - goto error1; - } - if (firmware->size > size) { - pr_err("not enough memory size for audiodsp code\n"); - err = -ENOMEM; - goto release; - } - - memcpy(buf, (char *)firmware->data, firmware->size); - /*mb(); don't need it*/ - pr_err("load mcode size=%zd\n mcode name %s\n", firmware->size, - file_name); - err = firmware->size; -release: - release_firmware(firmware); -error1: - device_destroy(&amstream_class, MKDEV(AMSTREAM_MAJOR, 100)); - return err; -} - -/*static struct resource memobj;*/ -static int amstream_probe(struct platform_device *pdev) -{ - int i; - int r; - struct stream_port_s *st; - - pr_err("Amlogic A/V streaming port init\n"); - - amstream_port_num = MAX_AMSTREAM_PORT_NUM; - amstream_buf_num = BUF_MAX_NUM; -/* -* r = of_reserved_mem_device_init(&pdev->dev); -* if (r == 0) -* pr_info("of probe done"); -* else { -* r = -ENOMEM; -* return r; -* } -*/ - r = class_register(&amstream_class); - if (r) { - pr_err("amstream class create fail.\n"); - return r; - } - - r = astream_dev_register(); - if (r) - return r; - - r = register_chrdev(AMSTREAM_MAJOR, "amstream", &amstream_fops); - if (r < 0) { - pr_err("Can't allocate major for amstreaming device\n"); - - goto error2; - } - - amstream_dev_class = class_create(THIS_MODULE, DEVICE_NAME); - - for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++) { - st->class_dev = device_create(amstream_dev_class, NULL, - MKDEV(AMSTREAM_MAJOR, i), NULL, - ports[i].name); - } - - amstream_adec_status = NULL; - if (tsdemux_class_register() != 0) { - r = (-EIO); - goto error3; - } - - init_waitqueue_head(&amstream_sub_wait); - init_waitqueue_head(&amstream_userdata_wait); - reset_canuse_buferlevel(10000); - amstream_pdev = pdev; - amports_clock_gate_init(&amstream_pdev->dev); - - /*prealloc fetch buf to avoid no continue buffer later...*/ - stbuf_fetch_init(); - return 0; - - /* - * error4: - * tsdemux_class_unregister(); - */ -error3: - for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++) - device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i)); - class_destroy(amstream_dev_class); -error2: - unregister_chrdev(AMSTREAM_MAJOR, "amstream"); - /* error1: */ - astream_dev_unregister(); - return r; -} - -static int amstream_remove(struct platform_device *pdev) -{ - int i; - struct stream_port_s *st; - - if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) - stbuf_change_size(&bufs[BUF_TYPE_VIDEO], 0); - if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) - stbuf_change_size(&bufs[BUF_TYPE_AUDIO], 0); - stbuf_fetch_release(); - tsdemux_class_unregister(); - for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++) - device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i)); - - class_destroy(amstream_dev_class); - - unregister_chrdev(AMSTREAM_MAJOR, "amstream"); - - class_unregister(&amstream_class); - - astream_dev_unregister(); - - amstream_adec_status = NULL; - - pr_err("Amlogic A/V streaming port release\n"); - - return 0; -} - -void set_adec_func(int (*adec_func)(struct adec_status *)) -{ - amstream_adec_status = adec_func; -} - -void wakeup_sub_poll(void) -{ - atomic_inc(&subdata_ready); - wake_up_interruptible(&amstream_sub_wait); -} - -int get_sub_type(void) -{ - return sub_type; -} - -/*get pes buffers */ - -struct stream_buf_s *get_stream_buffer(int id) -{ - if (id >= BUF_MAX_NUM) - return 0; - return &bufs[id]; -} - -static const struct of_device_id amlogic_mesonstream_dt_match[] = { - { - .compatible = "amlogic, codec, streambuf", - }, - {}, -}; - -static struct platform_driver amstream_driver = { - .probe = amstream_probe, - .remove = amstream_remove, - .driver = { - .owner = THIS_MODULE, - .name = "mesonstream", - .of_match_table = amlogic_mesonstream_dt_match, - } -}; - -static int __init amstream_module_init(void) -{ - if (platform_driver_register(&amstream_driver)) { - pr_err("failed to register amstream module\n"); - return -ENODEV; - } - return 0; -} - -static void __exit amstream_module_exit(void) -{ - platform_driver_unregister(&amstream_driver); - return; -} - -module_init(amstream_module_init); -module_exit(amstream_module_exit); - -module_param(debugflags, uint, 0664); -MODULE_PARM_DESC(debugflags, "\n amstream debugflags\n"); - -module_param(def_4k_vstreambuf_sizeM, uint, 0664); -MODULE_PARM_DESC(def_4k_vstreambuf_sizeM, - "\nDefault video Stream buf size for 4K MByptes\n"); - -module_param(def_vstreambuf_sizeM, uint, 0664); -MODULE_PARM_DESC(def_vstreambuf_sizeM, - "\nDefault video Stream buf size for < 1080p MByptes\n"); - -module_param(slow_input, uint, 0664); -MODULE_PARM_DESC(slow_input, "\n amstream slow_input\n"); - - -MODULE_DESCRIPTION("AMLOGIC streaming port driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); diff --git a/drivers/stream_input/amports/amstream_profile.c b/drivers/stream_input/amports/amstream_profile.c deleted file mode 100644 index d65ee5c..0000000 --- a/drivers/stream_input/amports/amstream_profile.c +++ b/dev/null @@ -1,54 +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 "amports_priv.h" - -static const struct codec_profile_t *vcodec_profile[SUPPORT_VDEC_NUM] = { 0 }; - -static int vcodec_profile_idx; - -ssize_t vcodec_profile_read(char *buf) -{ - char *pbuf = buf; - int i = 0; - - for (i = 0; i < vcodec_profile_idx; i++) { - pbuf += sprintf(pbuf, "%s:%s;\n", vcodec_profile[i]->name, - vcodec_profile[i]->profile); - } - - return pbuf - buf; -} - -int vcodec_profile_register(const struct codec_profile_t *vdec_profile) -{ - if (vcodec_profile_idx < SUPPORT_VDEC_NUM) { - vcodec_profile[vcodec_profile_idx] = vdec_profile; - vcodec_profile_idx++; - pr_debug("regist %s codec profile\n", vdec_profile->name); - - } - - return 0; -} -EXPORT_SYMBOL(vcodec_profile_register); - diff --git a/drivers/stream_input/parser/esparser.c b/drivers/stream_input/parser/esparser.c deleted file mode 100644 index a9b8e29..0000000 --- a/drivers/stream_input/parser/esparser.c +++ b/dev/null @@ -1,940 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/esparser.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/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/mutex.h> -#include <linux/slab.h> -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> - -#include <linux/uaccess.h> -#include <linux/atomic.h> - -/* #include <mach/am_regs.h> */ -#include <linux/delay.h> - -#include "../../frame_provider/decoder/utils/vdec.h" -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "streambuf_reg.h" -#include "streambuf.h" -#include "esparser.h" -#include "../amports/amports_priv.h" -#include "thread_rw.h" - -#include <linux/amlogic/media/codec_mm/codec_mm.h> - - - -#define SAVE_SCR 0 - -#define ES_START_CODE_PATTERN 0x00000100 -#define ES_START_CODE_MASK 0xffffff00 -#define SEARCH_PATTERN_LEN 512 -#define ES_PARSER_POP READ_MPEG_REG(PFIFO_DATA) - -#define PARSER_WRITE (ES_WRITE | ES_PARSER_START) -#define PARSER_VIDEO (ES_TYPE_VIDEO) -#define PARSER_AUDIO (ES_TYPE_AUDIO) -#define PARSER_SUBPIC (ES_TYPE_SUBTITLE) -#define PARSER_PASSTHROUGH (ES_PASSTHROUGH | ES_PARSER_START) -#define PARSER_AUTOSEARCH (ES_SEARCH | ES_PARSER_START) -#define PARSER_DISCARD (ES_DISCARD | ES_PARSER_START) -#define PARSER_BUSY (ES_PARSER_BUSY) - -static unsigned char *search_pattern; -static dma_addr_t search_pattern_map; -static u32 audio_real_wp; -static u32 audio_buf_start; -static u32 audio_buf_end; - -static const char esparser_id[] = "esparser-id"; - -static DECLARE_WAIT_QUEUE_HEAD(wq); - - -static u32 search_done; -static u32 video_data_parsed; -static u32 audio_data_parsed; -static atomic_t esparser_use_count = ATOMIC_INIT(0); -static DEFINE_MUTEX(esparser_mutex); - -static inline u32 get_buf_wp(u32 type) -{ - if (type == BUF_TYPE_AUDIO) - return audio_real_wp; - else - return 0; -} -static inline u32 get_buf_start(u32 type) -{ - if (type == BUF_TYPE_AUDIO) - return audio_buf_start; - else - return 0; -} -static inline u32 get_buf_end(u32 type) -{ - if (type == BUF_TYPE_AUDIO) - return audio_buf_end; - else - return 0; -} -static void set_buf_wp(u32 type, u32 wp) -{ - if (type == BUF_TYPE_AUDIO) { - audio_real_wp = wp; - WRITE_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP, wp/* & 0xffffff00*/); - } -} - -static irqreturn_t esparser_isr(int irq, void *dev_id) -{ - u32 int_status = READ_MPEG_REG(PARSER_INT_STATUS); - - WRITE_MPEG_REG(PARSER_INT_STATUS, int_status); - - if (int_status & PARSER_INTSTAT_SC_FOUND) { - WRITE_MPEG_REG(PFIFO_RD_PTR, 0); - WRITE_MPEG_REG(PFIFO_WR_PTR, 0); - search_done = 1; - wake_up_interruptible(&wq); - } - return IRQ_HANDLED; -} - -static inline u32 buf_wp(u32 type) -{ - u32 wp; - - if ((READ_MPEG_REG(PARSER_ES_CONTROL) & ES_VID_MAN_RD_PTR) == 0) { - wp = -#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - (type == BUF_TYPE_HEVC) ? READ_VREG(HEVC_STREAM_WR_PTR) : -#endif - (type == BUF_TYPE_VIDEO) ? READ_VREG(VLD_MEM_VIFIFO_WP) : - (type == BUF_TYPE_AUDIO) ? - READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP) : - READ_MPEG_REG(PARSER_SUB_START_PTR); - } else { - wp = -#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - (type == BUF_TYPE_HEVC) ? READ_MPEG_REG(PARSER_VIDEO_WP) : -#endif - (type == BUF_TYPE_VIDEO) ? READ_MPEG_REG(PARSER_VIDEO_WP) : - (type == BUF_TYPE_AUDIO) ? - READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP) : - READ_MPEG_REG(PARSER_SUB_START_PTR); - } - - return wp; -} - -static ssize_t _esparser_write(const char __user *buf, - size_t count, u32 type, int isphybuf) -{ - size_t r = count; - const char __user *p = buf; - - u32 len = 0; - u32 parser_type; - int ret; - u32 wp; - dma_addr_t dma_addr = 0; - - if (type == BUF_TYPE_HEVC) - parser_type = PARSER_VIDEO; - else if (type == BUF_TYPE_VIDEO) - parser_type = PARSER_VIDEO; - else if (type == BUF_TYPE_AUDIO) - parser_type = PARSER_AUDIO; - else - parser_type = PARSER_SUBPIC; - - wp = buf_wp(type); - - if (r > 0) { - if (isphybuf) - len = count; - else { - len = min_t(size_t, r, (size_t) FETCHBUF_SIZE); - - if (copy_from_user(fetchbuf, p, len)) - return -EFAULT; - dma_addr = dma_map_single( - amports_get_dma_device(), fetchbuf, - FETCHBUF_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - (dma_addr_t) dma_addr)) - return -EFAULT; - - } - - /* wmb(); don't need */ - /* reset the Write and read pointer to zero again */ - WRITE_MPEG_REG(PFIFO_RD_PTR, 0); - WRITE_MPEG_REG(PFIFO_WR_PTR, 0); - - WRITE_MPEG_REG_BITS(PARSER_CONTROL, len, ES_PACK_SIZE_BIT, - ES_PACK_SIZE_WID); - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - parser_type | PARSER_WRITE | - PARSER_AUTOSEARCH, ES_CTRL_BIT, - ES_CTRL_WID); - - if (isphybuf) { - u32 buf_32 = (unsigned long)buf & 0xffffffff; - - WRITE_MPEG_REG(PARSER_FETCH_ADDR, buf_32); - } else { - WRITE_MPEG_REG(PARSER_FETCH_ADDR, dma_addr); - dma_unmap_single(amports_get_dma_device(), dma_addr, - FETCHBUF_SIZE, DMA_TO_DEVICE); - } - - search_done = 0; - if (!(isphybuf & TYPE_PATTERN)) { - WRITE_MPEG_REG(PARSER_FETCH_CMD, - (7 << FETCH_ENDIAN) | len); - WRITE_MPEG_REG(PARSER_FETCH_ADDR, search_pattern_map); - WRITE_MPEG_REG(PARSER_FETCH_CMD, - (7 << FETCH_ENDIAN) | SEARCH_PATTERN_LEN); - } else { - WRITE_MPEG_REG(PARSER_FETCH_CMD, - (7 << FETCH_ENDIAN) | (len + 512)); - } - ret = wait_event_interruptible_timeout(wq, search_done != 0, - HZ / 5); - if (ret == 0) { - WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); - - if (wp == buf_wp(type)) - /*no data fetched */ - return -EAGAIN; - - pr_info("W Timeout, but fetch ok,"); - pr_info("type %d len=%d,wpdiff=%d, isphy %x\n", - type, len, wp - buf_wp(type), isphybuf); - - } else if (ret < 0) - return -ERESTARTSYS; - } - - if ((type == BUF_TYPE_VIDEO) - || (has_hevc_vdec() && (type == BUF_TYPE_HEVC))) - video_data_parsed += len; - else if (type == BUF_TYPE_AUDIO) - audio_data_parsed += len; - - return len; -} - -static ssize_t _esparser_write_s(const char __user *buf, - size_t count, u32 type) -{ - size_t r = count; - const char __user *p = buf; - u32 len = 0; - int ret; - u32 wp, buf_start, buf_end; - dma_addr_t buf_wp_map; - - if (type != BUF_TYPE_AUDIO) - WARN_ON(1);/*BUG();*/ - wp = get_buf_wp(type); - buf_end = get_buf_end(type) + 8; - buf_start = get_buf_start(type); - /*pr_info("write wp 0x%x, count %d, start 0x%x, end 0x%x\n",*/ - /* wp, (u32)count, buf_start, buf_end);*/ - if (wp + count > buf_end) { - ret = copy_from_user(codec_mm_phys_to_virt(wp), - p, buf_end - wp); - if (ret > 0) { - len += buf_end - wp - ret; - buf_wp_map = dma_map_single(amports_get_dma_device(), - codec_mm_phys_to_virt(wp), len, DMA_TO_DEVICE); - wp += len; - pr_info("copy from user not finished\n"); - dma_unmap_single(NULL, buf_wp_map, len, DMA_TO_DEVICE); - set_buf_wp(type, wp); - goto end_write; - } else if (ret == 0) { - len += buf_end - wp; - buf_wp_map = dma_map_single(amports_get_dma_device(), - codec_mm_phys_to_virt(wp), len, DMA_TO_DEVICE); - wp = buf_start; - r = count - len; - dma_unmap_single(NULL, buf_wp_map, len, DMA_TO_DEVICE); - set_buf_wp(type, wp); - } else { - pr_info("copy from user failed 1\n"); - pr_info("w wp 0x%x, count %d, start 0x%x end 0x%x\n", - wp, (u32)count, buf_start, buf_end); - return -EAGAIN; - } - } - ret = copy_from_user(codec_mm_phys_to_virt(wp), p + len, r); - if (ret >= 0) { - len += r - ret; - buf_wp_map = dma_map_single(amports_get_dma_device(), - codec_mm_phys_to_virt(wp), r - ret, DMA_TO_DEVICE); - - if (ret > 0) - pr_info("copy from user not finished 2\n"); - wp += r - ret; - dma_unmap_single(NULL, buf_wp_map, r - ret, DMA_TO_DEVICE); - set_buf_wp(type, wp); - } else { - pr_info("copy from user failed 2\n"); - return -EAGAIN; - } - -end_write: - if (type == BUF_TYPE_AUDIO) - audio_data_parsed += len; - - return len; -} - -s32 es_vpts_checkin_us64(struct stream_buf_s *buf, u64 us64) -{ - u32 passed; - - if (buf->write_thread) - passed = threadrw_dataoffset(buf); - else - passed = video_data_parsed; - return pts_checkin_offset_us64(PTS_TYPE_VIDEO, passed, us64); - -} - -s32 es_apts_checkin_us64(struct stream_buf_s *buf, u64 us64) -{ - u32 passed; - - if (buf->write_thread) - passed = threadrw_dataoffset(buf); - else - passed = audio_data_parsed; - return pts_checkin_offset_us64(PTS_TYPE_AUDIO, passed, us64); -} - -s32 es_vpts_checkin(struct stream_buf_s *buf, u32 pts) -{ -#if 0 - if (buf->first_tstamp == INVALID_PTS) { - buf->flag |= BUF_FLAG_FIRST_TSTAMP; - buf->first_tstamp = pts; - return 0; - } -#endif - u32 passed = video_data_parsed + threadrw_buffer_level(buf); - - return pts_checkin_offset(PTS_TYPE_VIDEO, passed, pts); - -} - -s32 es_apts_checkin(struct stream_buf_s *buf, u32 pts) -{ -#if 0 - if (buf->first_tstamp == INVALID_PTS) { - buf->flag |= BUF_FLAG_FIRST_TSTAMP; - buf->first_tstamp = pts; - - return 0; - } -#endif - u32 passed = audio_data_parsed + threadrw_buffer_level(buf); - - return pts_checkin_offset(PTS_TYPE_AUDIO, passed, pts); -} - -s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec) -{ - s32 r = 0; - u32 pts_type; - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - u32 parser_sub_rp; - bool first_use = false; - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if (has_hevc_vdec() && (buf->type == BUF_TYPE_HEVC)) - pts_type = PTS_TYPE_HEVC; - else - /* #endif */ - if (buf->type == BUF_TYPE_VIDEO) - pts_type = PTS_TYPE_VIDEO; - else if (buf->type == BUF_TYPE_AUDIO) - pts_type = PTS_TYPE_AUDIO; - else if (buf->type == BUF_TYPE_SUBTITLE) - pts_type = PTS_TYPE_MAX; - else - return -EINVAL; - mutex_lock(&esparser_mutex); - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); - - buf->flag |= BUF_FLAG_PARSER; - - if (atomic_add_return(1, &esparser_use_count) == 1) { - first_use = true; - - if (fetchbuf == 0) { - pr_info("%s: no fetchbuf\n", __func__); - r = -ENOMEM; - goto Err_1; - } - - if (search_pattern == NULL) { - search_pattern = kcalloc(1, - SEARCH_PATTERN_LEN, - GFP_KERNEL); - - if (search_pattern == NULL) { - pr_err("%s: no search_pattern\n", __func__); - r = -ENOMEM; - goto Err_1; - } - - /* build a fake start code to get parser interrupt */ - search_pattern[0] = 0x00; - search_pattern[1] = 0x00; - search_pattern[2] = 0x01; - search_pattern[3] = 0xff; - - search_pattern_map = dma_map_single( - amports_get_dma_device(), - search_pattern, - SEARCH_PATTERN_LEN, - DMA_TO_DEVICE); - } - - /* reset PARSER with first esparser_init() call */ - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); - - /* TS data path */ -#ifndef CONFIG_AM_DVB - WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0); -#else - tsdemux_set_reset_flag(); -#endif - CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE); - - CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE)); - - WRITE_MPEG_REG(PARSER_CONFIG, - (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | - (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | - (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); - - WRITE_MPEG_REG(PFIFO_RD_PTR, 0); - WRITE_MPEG_REG(PFIFO_WR_PTR, 0); - - WRITE_MPEG_REG(PARSER_SEARCH_PATTERN, ES_START_CODE_PATTERN); - WRITE_MPEG_REG(PARSER_SEARCH_MASK, ES_START_CODE_MASK); - - WRITE_MPEG_REG(PARSER_CONFIG, - (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | - (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | - PS_CFG_STARTCODE_WID_24 | - PS_CFG_PFIFO_ACCESS_WID_8 | - /* single byte pop */ - (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); - - WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH); - - } - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - /* hook stream buffer with PARSER */ - if (has_hevc_vdec() && (pts_type == PTS_TYPE_HEVC)) { - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, vdec->input.start - + vdec->input.size - 8); - - if (vdec_single(vdec)) { - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - - /* set vififo_vbuf_rp_sel=>hevc */ - WRITE_VREG(DOS_GEN_CTRL0, 3 << 1); - - /* set use_parser_vbuf_wp */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, - (1 << 3) | (0 << 4)); - /* set stream_fetch_enable */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); - - /* set stream_buffer_hole with 256 bytes */ - SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, - (1 << 29)); - } else { - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_RP, vdec->input.start); - } - video_data_parsed = 0; - } else if (pts_type == PTS_TYPE_VIDEO) { - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, - vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, - vdec->input.start + vdec->input.size - 8); - if (vdec_single(vdec)) { - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, - MEM_BUFCTRL_INIT); - - if (has_hevc_vdec()) { - /* set vififo_vbuf_rp_sel=>vdec */ - WRITE_VREG(DOS_GEN_CTRL0, 0); - - } - } else { - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, - vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_RP, - vdec->input.start); - } - video_data_parsed = 0; - } else if (pts_type == PTS_TYPE_AUDIO) { - /* set wp as buffer start */ - SET_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, - MEM_BUFCTRL_MANUAL); - WRITE_MPEG_REG(AIU_MEM_AIFIFO_MAN_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG_BITS(AIU_MEM_AIFIFO_CONTROL, 7, 3, 3); - SET_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, - MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, - MEM_BUFCTRL_INIT); - WRITE_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - audio_data_parsed = 0; - audio_buf_start = - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR); - audio_real_wp = audio_buf_start; - audio_buf_end = READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR); - } else if (buf->type == BUF_TYPE_SUBTITLE) { - WRITE_MPEG_REG(PARSER_SUB_START_PTR, - parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, - parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | - ES_SUB_MAN_RD_PTR); - } - - if (pts_type < PTS_TYPE_MAX) { - r = pts_start(pts_type); - - if (r < 0) { - pr_info("esparser_init: pts_start failed\n"); - goto Err_1; - } - } -#if 0 - if (buf->flag & BUF_FLAG_FIRST_TSTAMP) { - if (buf->type == BUF_TYPE_VIDEO) - es_vpts_checkin(buf, buf->first_tstamp); - else if (buf->type == BUF_TYPE_AUDIO) - es_apts_checkin(buf, buf->first_tstamp); - - buf->flag &= ~BUF_FLAG_FIRST_TSTAMP; - } -#endif - - if (first_use) { - /*TODO irq */ - r = vdec_request_irq(PARSER_IRQ, esparser_isr, - "parser", (void *)esparser_id); - - if (r) { - pr_info("esparser_init: irq register failed.\n"); - goto Err_2; - } - - WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); - WRITE_MPEG_REG(PARSER_INT_ENABLE, - PARSER_INTSTAT_SC_FOUND << - PARSER_INT_HOST_EN_BIT); - } - mutex_unlock(&esparser_mutex); - if (!(amports_get_debug_flags() & 1) && - !codec_mm_video_tvp_enabled()) { - int block_size = (buf->type == BUF_TYPE_AUDIO) ? - PAGE_SIZE : PAGE_SIZE << 4; - int buf_num = (buf->type == BUF_TYPE_AUDIO) ? - 20 : (2 * SZ_1M)/(PAGE_SIZE << 4); - if (!(buf->type == BUF_TYPE_SUBTITLE)) - buf->write_thread = threadrw_alloc(buf_num, - block_size, - esparser_write_ex, - (buf->type == BUF_TYPE_AUDIO) ? 1 : 0); - /*manul mode for audio*/ - } - return 0; - -Err_2: - pts_stop(pts_type); - -Err_1: - atomic_dec(&esparser_use_count); - buf->flag &= ~BUF_FLAG_PARSER; - mutex_unlock(&esparser_mutex); - return r; -} - -void esparser_audio_reset_s(struct stream_buf_s *buf) -{ - ulong flags; - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); - - SET_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_MANUAL); - WRITE_MPEG_REG(AIU_MEM_AIFIFO_MAN_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG_BITS(AIU_MEM_AIFIFO_CONTROL, 7, 3, 3); - SET_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - WRITE_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - - buf->flag |= BUF_FLAG_PARSER; - - audio_data_parsed = 0; - audio_real_wp = READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR); - spin_unlock_irqrestore(&lock, flags); - -} - -void esparser_audio_reset(struct stream_buf_s *buf) -{ - ulong flags; - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); - - WRITE_MPEG_REG(PARSER_AUDIO_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - buf->flag |= BUF_FLAG_PARSER; - - audio_data_parsed = 0; - audio_real_wp = 0; - audio_buf_start = 0; - audio_buf_end = 0; - spin_unlock_irqrestore(&lock, flags); - -} - -void esparser_release(struct stream_buf_s *buf) -{ - u32 pts_type; - - /* check if esparser_init() is ever called */ - if ((buf->flag & BUF_FLAG_PARSER) == 0) - return; - - if (atomic_read(&esparser_use_count) == 0) { - pr_info - ("[%s:%d]###warning, esparser has been released already\n", - __func__, __LINE__); - return; - } - if (buf->write_thread) - threadrw_release(buf); - if (atomic_dec_and_test(&esparser_use_count)) { - WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); - /*TODO irq */ - - vdec_free_irq(PARSER_IRQ, (void *)esparser_id); - - if (search_pattern) { - dma_unmap_single(amports_get_dma_device(), - search_pattern_map, - SEARCH_PATTERN_LEN, DMA_TO_DEVICE); - kfree(search_pattern); - search_pattern = NULL; - } - } - - if (has_hevc_vdec() && (buf->type == BUF_TYPE_HEVC)) - pts_type = PTS_TYPE_VIDEO; - else if (buf->type == BUF_TYPE_VIDEO) - pts_type = PTS_TYPE_VIDEO; - else if (buf->type == BUF_TYPE_AUDIO) - pts_type = PTS_TYPE_AUDIO; - else if (buf->type == BUF_TYPE_SUBTITLE) { - buf->flag &= ~BUF_FLAG_PARSER; - return; - } else - return; - - buf->flag &= ~BUF_FLAG_PARSER; - pts_stop(pts_type); -} - -ssize_t drm_write(struct file *file, struct stream_buf_s *stbuf, - const char __user *buf, size_t count) -{ - s32 r; - u32 len; - u32 realcount, totalcount; - u32 re_count = count; - u32 havewritebytes = 0; - u32 leftcount = 0; - - struct drm_info tmpmm; - struct drm_info *drm = &tmpmm; - u32 res = 0; - int isphybuf = 0; - unsigned long realbuf; - - if (buf == NULL || count == 0) - return -EINVAL; - if (stbuf->write_thread) { - r = threadrw_flush_buffers(stbuf); - if (r < 0) - pr_info("Warning. drm flush threadrw failed[%d]\n", r); - } - res = copy_from_user(drm, buf, sizeof(struct drm_info)); - if (res) { - pr_info("drm kmalloc failed res[%d]\n", res); - return -EFAULT; - } - - if ((drm->drm_flag & TYPE_DRMINFO) && (drm->drm_hasesdata == 0)) { - /* buf only has drminfo not have esdata; */ - realbuf = drm->drm_phy; - realcount = drm->drm_pktsize; - isphybuf = drm->drm_flag; - /* DRM_PRNT("drm_get_rawdata - *onlydrminfo drm->drm_hasesdata[0x%x] - * stbuf->type %d buf[0x%x]\n", - *drm->drm_hasesdata,stbuf->type,buf); - */ - } else if (drm->drm_hasesdata == 1) { /* buf is drminfo+es; */ - realcount = drm->drm_pktsize; - realbuf = (unsigned long)buf + sizeof(struct drm_info); - isphybuf = 0; - /* DRM_PRNT("drm_get_rawdata - * drminfo+es drm->drm_hasesdata[0x%x] - * stbuf->type %d\n",drm->drm_hasesdata,stbuf->type); - */ - } else { /* buf is hwhead; */ - realcount = count; - isphybuf = 0; - realbuf = (unsigned long)buf; - /* DRM_PRNT("drm_get_rawdata - * drm->drm_hasesdata[0x%x] - * len[%d] count[%d] realcout[%d]\n", - * drm->drm_hasesdata,len,count,realcount); - */ - } - - len = realcount; - count = realcount; - totalcount = realcount; - - while (len > 0) { - if (stbuf->type != BUF_TYPE_SUBTITLE - && stbuf_space(stbuf) < count) { - len = min(stbuf_canusesize(stbuf) / 8, len); - if (stbuf_space(stbuf) < len) { - r = stbuf_wait_space(stbuf, len); - /* write part data , not allow return ; */ - if ((r < leftcount) && (leftcount > 0)) - continue; - else if ((r < 0) && (leftcount == 0))/*full; */ - return -EAGAIN; - } - } - len = min_t(u32, len, count); - - mutex_lock(&esparser_mutex); - - if (stbuf->type != BUF_TYPE_AUDIO) - r = _esparser_write((const char __user *)realbuf, len, - stbuf->type, isphybuf); - else - r = _esparser_write_s((const char __user *)realbuf, len, - stbuf->type); - if (r < 0) { - pr_info("drm_write _esparser_write failed [%d]\n", r); - return r; - } - havewritebytes += r; - leftcount = totalcount - havewritebytes; - if (havewritebytes == totalcount) { - - mutex_unlock(&esparser_mutex); - break; /* write ok; */ - } else if ((len > 0) && (havewritebytes < totalcount)) { - DRM_PRNT - ("d writebytes[%d] want[%d] total[%d] real[%d]\n", - havewritebytes, len, totalcount, realcount); - len = len - r; /* write again; */ - realbuf = realbuf + r; - } else { - pr_info - ("e writebytes[%d] want[%d] total[%d] real[%d]\n", - havewritebytes, len, totalcount, realcount); - } - mutex_unlock(&esparser_mutex); - } - - return re_count; -} -/* -*flags: -*1:phy -*2:noblock -*/ -ssize_t esparser_write_ex(struct file *file, - struct stream_buf_s *stbuf, - const char __user *buf, size_t count, - int flags) -{ - - s32 r; - u32 len = count; - - if (buf == NULL || count == 0) - return -EINVAL; - - /*subtitle have no level to check, */ - if (stbuf->type != BUF_TYPE_SUBTITLE && stbuf_space(stbuf) < count) { - if ((flags & 2) || ((file != NULL) && - (file->f_flags & O_NONBLOCK))) { - len = stbuf_space(stbuf); - - if (len < 256) /* <1k.do eagain, */ - return -EAGAIN; - } else { - len = min(stbuf_canusesize(stbuf) / 8, len); - - if (stbuf_space(stbuf) < len) { - r = stbuf_wait_space(stbuf, len); - if (r < 0) - return r; - } - } - } - - stbuf->last_write_jiffies64 = jiffies_64; - - len = min_t(u32, len, count); - - mutex_lock(&esparser_mutex); - - if (stbuf->type == BUF_TYPE_AUDIO) - r = _esparser_write_s(buf, len, stbuf->type); - else - r = _esparser_write(buf, len, stbuf->type, flags & 1); - - mutex_unlock(&esparser_mutex); - - return r; -} -ssize_t esparser_write(struct file *file, - struct stream_buf_s *stbuf, - const char __user *buf, size_t count) -{ - if (stbuf->write_thread) { - ssize_t ret; - ret = threadrw_write(file, stbuf, buf, count); - if (ret == -EAGAIN) { - u32 a, b; - int vdelay, adelay; - if ((stbuf->type != BUF_TYPE_VIDEO) && - (stbuf->type != BUF_TYPE_HEVC)) - return ret; - if (stbuf->buf_size > (SZ_1M * 30) || - (threadrw_buffer_size(stbuf) > SZ_1M * 10) || - !threadrw_support_more_buffers(stbuf)) - return ret; - /*only chang buffer for video.*/ - vdelay = calculation_stream_delayed_ms( - PTS_TYPE_VIDEO, &a, &b); - adelay = calculation_stream_delayed_ms( - PTS_TYPE_AUDIO, &a, &b); - if ((vdelay > 100 && vdelay < 2000) && /*vdelay valid.*/ - ((vdelay < 500) ||/*video delay is short!*/ - (adelay > 0 && adelay < 1000))/*audio is low.*/ - ) { - /*on buffer fulled. - if delay is less than 100ms we think errors, - And we add more buffer on delay < 2s. - */ - int new_size = 2 * 1024 * 1024; - threadrw_alloc_more_buffer_size( - stbuf, new_size); - } - } - return ret; - } - return esparser_write_ex(file, stbuf, buf, count, 0); -} - - -void esparser_sub_reset(void) -{ - ulong flags; - DEFINE_SPINLOCK(lock); - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - - spin_lock_irqsave(&lock, flags); - - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - - WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - - spin_unlock_irqrestore(&lock, flags); -} diff --git a/drivers/stream_input/parser/esparser.h b/drivers/stream_input/parser/esparser.h deleted file mode 100644 index 62396a2..0000000 --- a/drivers/stream_input/parser/esparser.h +++ b/dev/null @@ -1,149 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/esparser.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 ESPARSER_H -#define ESPARSER_H - -#include "../../frame_provider/decoder/utils/vdec.h" - -extern ssize_t drm_write(struct file *file, - struct stream_buf_s *stbuf, const char __user *buf, size_t count); - -extern s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec); -extern s32 esparser_init_s(struct stream_buf_s *buf); -extern void esparser_release(struct stream_buf_s *buf); -extern ssize_t esparser_write(struct file *file, - struct stream_buf_s *stbuf, const char __user *buf, size_t count); -extern ssize_t esparser_write_ex(struct file *file, - struct stream_buf_s *stbuf, - const char __user *buf, size_t count, int is_phy); - -extern s32 es_vpts_checkin_us64(struct stream_buf_s *buf, u64 us64); - -extern s32 es_apts_checkin_us64(struct stream_buf_s *buf, u64 us64); - -extern int es_vpts_checkin(struct stream_buf_s *buf, u32 pts); - -extern int es_apts_checkin(struct stream_buf_s *buf, u32 pts); - -extern void esparser_audio_reset(struct stream_buf_s *buf); -extern void esparser_audio_reset_s(struct stream_buf_s *buf); - -extern void esparser_sub_reset(void); - -#ifdef CONFIG_AM_DVB -extern int tsdemux_set_reset_flag(void); -#endif - -/* TODO: move to register headers */ -#define ES_PACK_SIZE_BIT 8 -#define ES_PACK_SIZE_WID 24 - -#define ES_CTRL_WID 8 -#define ES_CTRL_BIT 0 -#define ES_TYPE_MASK (3 << 6) -#define ES_TYPE_VIDEO (0 << 6) -#define ES_TYPE_AUDIO (1 << 6) -#define ES_TYPE_SUBTITLE (2 << 6) - -#define ES_WRITE (1<<5) -#define ES_PASSTHROUGH (1<<4) -#define ES_INSERT_BEFORE_ES_WRITE (1<<3) -#define ES_DISCARD (1<<2) -#define ES_SEARCH (1<<1) -#define ES_PARSER_START (1<<0) -#define ES_PARSER_BUSY (1<<0) - -#define PARSER_INTSTAT_FETCH_CMD (1<<7) -#define PARSER_INTSTAT_PARSE (1<<4) -#define PARSER_INTSTAT_DISCARD (1<<3) -#define PARSER_INTSTAT_INSZERO (1<<2) -#define PARSER_INTSTAT_ACT_NOSSC (1<<1) -#define PARSER_INTSTAT_SC_FOUND (1<<0) - -#define FETCH_CIR_BUF (1<<31) -#define FETCH_CHK_BUF_STOP (1<<30) -#define FETCH_PASSTHROUGH (1<<29) -#define FETCH_ENDIAN 27 -#define FETCH_PASSTHROUGH_TYPE_MASK (0x3<<27) -#define FETCH_ENDIAN_MASK (0x7<<27) -#define FETCH_BUF_SIZE_MASK (0x7ffffff) -#define FETCH_CMD_PTR_MASK 3 -#define FETCH_CMD_RD_PTR_BIT 5 -#define FETCH_CMD_WR_PTR_BIT 3 -#define FETCH_CMD_NUM_MASK 3 -#define FETCH_CMD_NUM_BIT 0 - -#define ES_COUNT_MASK 0xfff -#define ES_COUNT_BIT 20 -#define ES_REQ_PENDING (1<<19) -#define ES_PASSTHROUGH_EN (1<<18) -#define ES_PASSTHROUGH_TYPE_MASK (3<<16) -#define ES_PASSTHROUGH_TYPE_VIDEO (0<<16) -#define ES_PASSTHROUGH_TYPE_AUDIO (1<<16) -#define ES_PASSTHROUGH_TYPE_SUBTITLE (2<<16) -#define ES_WR_ENDIAN_MASK (0x7) -#define ES_SUB_WR_ENDIAN_BIT 9 -#define ES_SUB_MAN_RD_PTR (1<<8) -#define ES_AUD_WR_ENDIAN_BIT 5 -#define ES_AUD_MAN_RD_PTR (1<<4) -#define ES_VID_WR_ENDIAN_BIT 1 -#define ES_VID_MAN_RD_PTR (1<<0) - -#define PS_CFG_FETCH_DMA_URGENT (1<<31) -#define PS_CFG_STREAM_DMA_URGENT (1<<30) -#define PS_CFG_FORCE_PFIFO_REN (1<<29) -#define PS_CFG_PFIFO_PEAK_EN (1<<28) -#define PS_CFG_SRC_SEL_BIT 24 -#define PS_CFG_SRC_SEL_MASK (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_FETCH (0<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX1 (1<<PS_CFG_SRC_SEL_BIT) /*from NDMA */ -#define PS_CFG_SRC_SEL_AUX2 (2<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX3 (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_PFIFO_EMPTY_CNT_BIT 16 -#define PS_CFG_PFIFO_EMPTY_CNT_MASK 0xff -#define PS_CFG_MAX_ES_WR_CYCLE_BIT 12 -#define PS_CFG_MAX_ES_WR_CYCLE_MASK 0xf -#define PS_CFG_STARTCODE_WID_MASK (0x3<<10) -#define PS_CFG_STARTCODE_WID_8 (0x0<<10) -#define PS_CFG_STARTCODE_WID_16 (0x1<<10) -#define PS_CFG_STARTCODE_WID_24 (0x2<<10) -#define PS_CFG_STARTCODE_WID_32 (0x3<<10) -#define PS_CFG_PFIFO_ACCESS_WID_MASK (0x3<<8) -#define PS_CFG_PFIFO_ACCESS_WID_8 (0x0<<8) -#define PS_CFG_PFIFO_ACCESS_WID_16 (0x1<<8) -#define PS_CFG_PFIFO_ACCESS_WID_24 (0x2<<8) -#define PS_CFG_PFIFO_ACCESS_WID_32 (0x3<<8) -#define PS_CFG_MAX_FETCH_CYCLE_BIT 0 -#define PS_CFG_MAX_FETCH_CYCLE_MASK 0xff - -#define PARSER_INT_DISABLE_CNT_MASK 0xffff -#define PARSER_INT_DISABLE_CNT_BIT 16 -#define PARSER_INT_HOST_EN_MASK 0xff -#define PARSER_INT_HOST_EN_BIT 8 -#define PARSER_INT_AMRISC_EN_MASK 0xff -#define PARSER_INT_AMRISC_EN_BIT 0 -#define PARSER_INT_ALL 0xff - -#define RESET_PARSER (1<<8) -#define TS_HIU_ENABLE 5 -#define USE_HI_BSF_INTERFACE 7 - -#define DRM_PRNT(fmt, args...) -#define TRACE() pr_info("drm--[%s::%d]\n", __func__, __LINE__) - -#endif /* ESPARSER_H */ diff --git a/drivers/stream_input/parser/psparser.c b/drivers/stream_input/parser/psparser.c deleted file mode 100644 index 5c8a8b1..0000000 --- a/drivers/stream_input/parser/psparser.c +++ b/dev/null @@ -1,1160 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/psparser.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/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/utils/amstream.h> - -#include <linux/uaccess.h> -/* #include <mach/am_regs.h> */ -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "streambuf_reg.h" -#include "streambuf.h" -#include "psparser.h" -#include "../amports/amports_priv.h" - - -#define TIMESTAMP_IONLY 1 -#define SAVE_SCR 0 - -#define MPEG_START_CODE_PATTERN (0x00000100L) -#define MPEG_START_CODE_MASK (0xffffff00L) -#define MAX_MPG_AUDIOPK_SIZE 0x1000 - -#define SUB_INSERT_START_CODE_HIGH 0x414d4c55 -#define SUB_INSERT_START_CODE_LOW 0xaa000000 - -#define PARSER_WRITE (ES_WRITE | ES_PARSER_START) -#define PARSER_VIDEO (ES_TYPE_VIDEO) -#define PARSER_AUDIO (ES_TYPE_AUDIO) -#define PARSER_SUBPIC (ES_TYPE_SUBTITLE) -#define PARSER_PASSTHROUGH (ES_PASSTHROUGH | ES_PARSER_START) -#define PARSER_AUTOSEARCH (ES_SEARCH | ES_PARSER_START) -#define PARSER_DISCARD (ES_DISCARD | ES_PARSER_START) -#define PARSER_BUSY (ES_PARSER_BUSY) - -#define PARSER_PARAMETER_LENGTH_BIT 16 -#define PARSER_PARAMETER_LOOP_BIT 24 - -#define PARSER_POP READ_MPEG_REG(PFIFO_DATA) -#define SET_BLOCK(size) \ -WRITE_MPEG_REG_BITS(PARSER_CONTROL, size, ES_PACK_SIZE_BIT, ES_PACK_SIZE_WID) -#define SET_DISCARD_SIZE(size) WRITE_MPEG_REG(PARSER_PARAMETER, size) - -#define VIDEO_AUTO_FLUSH -#ifdef VIDEO_AUTO_FLUSH -static u32 video_auto_flush_state; -#define VIDEO_AUTO_FLUSH_IDLE 0 -#define VIDEO_AUTO_FLUSH_MONITOR 1 -#define VIDEO_AUTO_FLUSH_TRIGGER 2 -#define VIDEO_AUTO_FLUSH_DONE 3 -#define VIDEO_AUTO_FLUSH_PTS_THRESHOLD 90000 -#define VIDEO_AUTO_FLUSH_BYTE_COUNT 1024 - -static s32 audio_last_pts; -static s32 audio_monitor_pts; -#endif - -enum { - SEARCH_START_CODE = 0, - SEND_VIDEO_SEARCH, - SEND_AUDIO_SEARCH, - SEND_SUBPIC_SEARCH, - DISCARD_SEARCH, - DISCARD_ONLY -#ifdef VIDEO_AUTO_FLUSH - , - SEARCH_START_CODE_VIDEO_FLUSH -#endif -}; - -enum { - AUDIO_FIRST_ACCESS_ARM = 0, - AUDIO_FIRST_ACCESS_POPING, - AUDIO_FIRST_ACCESS_DONE -}; - -static const char psparser_id[] = "psparser-id"; - -static DECLARE_WAIT_QUEUE_HEAD(wq); - -static struct tasklet_struct psparser_tasklet; -static u32 fetch_done; -static u8 audio_id, video_id, sub_id, sub_id_max; -static u32 audio_first_access; -static u32 packet_remaining; -static u32 video_data_parsed; -static u32 audio_data_parsed; -static u32 pts_equ_dts_flag; - -static unsigned first_apts, first_vpts; -static unsigned audio_got_first_pts, video_got_first_dts, sub_got_first_pts; -atomic_t sub_block_found = ATOMIC_INIT(0); - -#define DEBUG_VOB_SUB -#ifdef DEBUG_VOB_SUB -static u8 sub_found_num; -static struct subtitle_info *sub_info[MAX_SUB_NUM]; -#endif - -static bool ptsmgr_first_vpts_ready(void) -{ - return (video_got_first_dts != 0) ? true : false; -} - -static bool ptsmgr_first_apts_ready(void) -{ - return (audio_got_first_pts != 0) ? true : false; -} - -static void ptsmgr_vpts_checkin(u32 pts) -{ - if (video_got_first_dts == 0) { - video_got_first_dts = 1; - first_vpts = pts; - } - - pts_checkin_offset(PTS_TYPE_VIDEO, video_data_parsed, pts); -} - -static void ptsmgr_apts_checkin(u32 pts) -{ - if (audio_got_first_pts == 0) { - audio_got_first_pts = 1; - first_apts = pts; - } - /* apts_checkin(pts); */ - pts_checkin_offset(PTS_TYPE_AUDIO, audio_data_parsed, pts); - -#ifdef VIDEO_AUTO_FLUSH - audio_last_pts = pts; - - if ((video_auto_flush_state == VIDEO_AUTO_FLUSH_IDLE) - && ptsmgr_first_vpts_ready()) { - video_auto_flush_state = VIDEO_AUTO_FLUSH_MONITOR; - audio_monitor_pts = pts; - } - - if (video_auto_flush_state == VIDEO_AUTO_FLUSH_MONITOR) { - if ((audio_last_pts - audio_monitor_pts) > - VIDEO_AUTO_FLUSH_PTS_THRESHOLD) - video_auto_flush_state = VIDEO_AUTO_FLUSH_TRIGGER; - } -#endif -} - -static u32 parser_process(s32 type, s32 packet_len) -{ - s16 temp, header_len, misc_flags, i; - u32 pts = 0, dts = 0; - u32 pts_dts_flag = 0; - u16 invalid_pts = 0; - - temp = PARSER_POP; - packet_len--; - - if ((temp >> 6) == 0x02) { - /* mpeg-2 system */ - misc_flags = PARSER_POP; - header_len = PARSER_POP; - packet_len -= 2; - packet_len -= header_len; - - if ((misc_flags >> 6) > 1) { - /* PTS exist */ - pts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */ - pts |= PARSER_POP << 22; /* bit 29-22 */ - pts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */ - pts |= (PARSER_POP << 7); /* bit 14-07 */ - pts |= (PARSER_POP >> 1); /* bit 06-00 */ - header_len -= 5; - pts_dts_flag |= 2; - } - - if ((misc_flags >> 6) > 2) { - /* DTS exist */ - dts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */ - dts |= PARSER_POP << 22; /* bit 29-22 */ - dts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */ - dts |= (PARSER_POP << 7); /* bit 14-07 */ - dts |= (PARSER_POP >> 1); /* bit 06-00 */ - header_len -= 5; - pts_dts_flag |= 1; - } - - if (misc_flags & 0x20) { - /* ESCR_flag */ - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; - header_len -= 5; - } - - if (misc_flags & 0x10) { - /* ES_rate_flag */ - PARSER_POP; - PARSER_POP; - PARSER_POP; - header_len -= 3; - } - - if (misc_flags & 0x08) { - /* DSM_trick_mode_flag */ - PARSER_POP; - header_len -= 1; - } - - if (misc_flags & 0x04) { - /* additional_copy_info_flag */ - PARSER_POP; - header_len -= 1; - } - - if (misc_flags & 0x02) { - /* PES_CRC_flag */ - PARSER_POP; - PARSER_POP; - header_len -= 2; - } - - if (misc_flags & 0x01) { - /* PES_extension_flag */ - misc_flags = PARSER_POP; - header_len--; - - if ((misc_flags & 0x80) && (header_len >= 128)) { - /* PES_private_data_flag */ - for (i = 0; i < 128; i++) - PARSER_POP; - - header_len -= 128; - } -#if 0 - if (misc_flags & 0x40) { - /* pack_header_field_flag */ - /* Invalid case */ - } -#endif - if (misc_flags & 0x20) { - /* program_packet_sequence_counter_flag */ - PARSER_POP; - PARSER_POP; - header_len -= 2; - } - - if (misc_flags & 0x10) { - /* PSTD_buffer_flag */ - PARSER_POP; - PARSER_POP; - header_len -= 2; - } - - if (misc_flags & 1) { - /* PES_extension_flag_2 */ - temp = PARSER_POP & 0x7f; - - while (temp) { - PARSER_POP; - temp--; - header_len--; - } - } - - while (header_len) { - PARSER_POP; - header_len--; - } - } - - while (header_len) { - PARSER_POP; - header_len--; - } - - } else { - /* mpeg-1 system */ - while (temp == 0xff) { - temp = PARSER_POP; - packet_len--; - } - - if ((temp >> 6) == 1) { - PARSER_POP; /* STD buffer size */ - temp = PARSER_POP; - packet_len -= 2; - } - - if (((temp >> 4) == 2) || ((temp >> 4) == 3)) { - pts = ((temp >> 1) & 7) << 30; /* bit 32-30 */ - pts |= PARSER_POP << 22; /* bit 29-22 */ - pts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */ - pts |= (PARSER_POP << 7); /* bit 14-07 */ - pts |= (PARSER_POP >> 1); /* bit 06-00 */ - packet_len -= 4; - pts_dts_flag |= 2; - } - - if ((temp >> 4) == 3) { - dts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */ - dts |= PARSER_POP << 22; /* bit 29-22 */ - dts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */ - dts |= (PARSER_POP << 7); /* bit 14-07 */ - dts |= (PARSER_POP >> 1); /* bit 06-00 */ - packet_len -= 5; - pts_dts_flag |= 1; - } - } - - if ((pts == 0) && (dts == 0xffffffff)) { - invalid_pts = 1; - pr_info("invalid pts\n"); - } - - if (!packet_len) - return SEARCH_START_CODE; - - else if (type == 0) { -#ifdef VIDEO_AUTO_FLUSH - if (video_auto_flush_state == VIDEO_AUTO_FLUSH_MONITOR) - audio_monitor_pts = audio_last_pts; -#endif - - if ((pts_dts_flag) && (!invalid_pts)) { -#if TIMESTAMP_IONLY - if (!ptsmgr_first_vpts_ready()) { - if (pts_dts_flag & 2) - ptsmgr_vpts_checkin(pts); - else - ptsmgr_vpts_checkin(dts); - } else if ((pts_dts_flag & 3) == 3) { - if (pts_equ_dts_flag) { - if (dts == pts) - ptsmgr_vpts_checkin(pts); - } else { - if (dts == pts) - pts_equ_dts_flag = 1; - ptsmgr_vpts_checkin(pts); - } - } -#else - if (!ptsmgr_first_vpts_ready()) { - if (pts_dts_flag & 2) - ptsmgr_vpts_checkin(pts); - else - ptsmgr_vpts_checkin(dts); - } else if (pts_dts_flag & 2) - ptsmgr_vpts_checkin(pts); -#endif - } - - if (ptsmgr_first_vpts_ready() || invalid_pts) { - SET_BLOCK(packet_len); - video_data_parsed += packet_len; - return SEND_VIDEO_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - - } else if (type == 1) { - /* mpeg audio */ - if (pts_dts_flag & 2) - ptsmgr_apts_checkin(pts); - - if (ptsmgr_first_apts_ready()) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - - } else if (type == 2) { - /* Private stream */ - temp = PARSER_POP; /* sub_stream_id */ - packet_len--; - - if (((temp & 0xf8) == 0xa0) && (temp == audio_id)) { - /* DVD_VIDEO Audio LPCM data */ - PARSER_POP; - temp = (PARSER_POP << 8) | PARSER_POP; - if (temp == 0) - temp = 4; - temp--; - packet_len -= 3; - - if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) { - if (temp) { - packet_remaining = packet_len - temp; - SET_DISCARD_SIZE(temp); - audio_first_access = - AUDIO_FIRST_ACCESS_POPING; - return DISCARD_ONLY; - } - - audio_first_access = AUDIO_FIRST_ACCESS_DONE; - - if (packet_len) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else - return SEARCH_START_CODE; - - } else { - PARSER_POP; - PARSER_POP; - PARSER_POP; - packet_len -= 3; - } - - if (pts_dts_flag & 2) - ptsmgr_apts_checkin(pts); - - if (ptsmgr_first_apts_ready()) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - - } else if (((temp & 0xf8) == 0x80) && (temp == audio_id)) { - /* Audio AC3 data */ - PARSER_POP; - temp = (PARSER_POP << 8) | PARSER_POP; - packet_len -= 3; - - if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) { - if (pts_dts_flag & 2) - ptsmgr_apts_checkin(pts); - - if ((temp > 2) && (packet_len > (temp - 2))) { - temp -= 2; - packet_remaining = packet_len - temp; - SET_DISCARD_SIZE(temp); - audio_first_access = - AUDIO_FIRST_ACCESS_POPING; - return DISCARD_ONLY; - } - - audio_first_access = AUDIO_FIRST_ACCESS_DONE; - - if (packet_len) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else - return SEARCH_START_CODE; - } - - if (pts_dts_flag & 2) - ptsmgr_apts_checkin(pts); - - if (ptsmgr_first_apts_ready()) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - - } else if (((temp & 0xf8) == 0x88) && (temp == audio_id)) { - /* Audio DTS data */ - PARSER_POP; - PARSER_POP; - PARSER_POP; - packet_len -= 3; - - if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) - audio_first_access = AUDIO_FIRST_ACCESS_DONE; - - if (pts_dts_flag & 2) - ptsmgr_apts_checkin(pts); - - if (ptsmgr_first_apts_ready()) { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - } else if ((temp & 0xe0) == 0x20) { - if (temp > sub_id_max) - sub_id_max = temp; -#ifdef DEBUG_VOB_SUB - for (i = 0; i < sub_found_num; i++) { - if (!sub_info[i]) - break; - if (temp == sub_info[i]->id) - break; - } - if (i == sub_found_num && i < MAX_SUB_NUM) { - if (sub_info[sub_found_num]) { - sub_info[sub_found_num]->id = temp; - sub_found_num++; - pr_info - ("[%s]found new sub_id=0x%x (num %d)\n", - __func__, temp, sub_found_num); - } else { - pr_info - ("[%s]sub info NULL!\n", __func__); - } - } -#endif - - if (temp == sub_id) { - /* DVD sub-picture data */ - if (!packet_len) - return SEARCH_START_CODE; - - else { -#if 0 - if (pts_dts_flag & 2) - ptsmgr_spts_checkin(pts); - - if (ptsmgr_first_spts_ready()) { - SET_BLOCK(packet_len); - return SEND_SUBPIC_SEARCH; - - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } -#else - if (pts_dts_flag & 2) - sub_got_first_pts = 1; - - if (sub_got_first_pts) { - pr_info - ("sub pts 0x%x, len %d\n", - pts, packet_len); - SET_BLOCK(packet_len); - WRITE_MPEG_REG - (PARSER_PARAMETER, - 16 << - PARSER_PARAMETER_LENGTH_BIT); - WRITE_MPEG_REG - (PARSER_INSERT_DATA, - SUB_INSERT_START_CODE_HIGH); - WRITE_MPEG_REG - (PARSER_INSERT_DATA, - SUB_INSERT_START_CODE_LOW | - get_sub_type()); - WRITE_MPEG_REG - (PARSER_INSERT_DATA, - packet_len); - WRITE_MPEG_REG - (PARSER_INSERT_DATA, pts); - atomic_set(&sub_block_found, 1); - return SEND_SUBPIC_SEARCH; - } - - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; -#endif - } - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - } else { - SET_DISCARD_SIZE(packet_len); - return DISCARD_SEARCH; - } - - if (!packet_len) - return SEARCH_START_CODE; - - else { - SET_BLOCK(packet_len); - audio_data_parsed += packet_len; - return SEND_AUDIO_SEARCH; - } - } - - return SEARCH_START_CODE; -} - -static void on_start_code_found(int start_code) -{ - unsigned short packet_len; - unsigned short temp; - unsigned next_action; -#if SAVE_SCR - unsigned scr; -#endif - - if (atomic_read(&sub_block_found)) { - wakeup_sub_poll(); - atomic_set(&sub_block_found, 0); - } - - if (audio_first_access == AUDIO_FIRST_ACCESS_POPING) { - /* - *we are in the procedure of poping data for audio first - * access, continue with last packet - */ - audio_first_access = AUDIO_FIRST_ACCESS_DONE; - - if (packet_remaining) { - next_action = SEND_AUDIO_SEARCH; - SET_BLOCK(packet_remaining); - - } else - next_action = SEARCH_START_CODE; - - } else if (start_code == 0xba) { /* PACK_START_CODE */ - temp = PARSER_POP; - - if ((temp >> 6) == 0x01) { -#if SAVE_SCR - scr = ((temp >> 3) & 0x3) << 30; /* bit 31-30 */ - scr |= (temp & 0x3) << 28; /* bit 29-28 */ - scr |= (PARSER_POP) << 20; /* bit 27-20 */ - temp = PARSER_POP; - scr |= (temp >> 4) << 16; /* bit 19-16 */ - scr |= (temp & 7) << 13; /* bit 15-13 */ - scr |= (PARSER_POP) << 5; /* bit 12-05 */ - scr |= (PARSER_POP) >> 3; /* bit 04-00 */ -#else - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; -#endif - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; - temp = PARSER_POP & 7; - - while (temp) { /* stuff byte */ - PARSER_POP; - temp--; - } - - } else { - /* mpeg-1 Pack Header */ -#if SAVE_SCR - scr = ((temp >> 1) & 0x3) << 30; /* bit 31-30 */ - scr |= (PARSER_POP) << 22; /* bit 29-22 */ - scr |= (PARSER_POP >> 1) << 15; /* bit 21-15 */ - scr |= (PARSER_POP) << 7; /* bit 14-07 */ - scr |= (PARSER_POP >> 1); /* bit 06-00 */ -#else - PARSER_POP; - PARSER_POP; - PARSER_POP; - PARSER_POP; -#endif - } - -#ifdef VIDEO_AUTO_FLUSH - if (video_auto_flush_state == VIDEO_AUTO_FLUSH_TRIGGER) { - next_action = SEARCH_START_CODE_VIDEO_FLUSH; - video_auto_flush_state = VIDEO_AUTO_FLUSH_DONE; - } else -#endif - - next_action = SEARCH_START_CODE; - - } else { - packet_len = (PARSER_POP << 8) | PARSER_POP; - - if (start_code == video_id) - next_action = parser_process(0, packet_len); - - else if (start_code == audio_id) { - /* add mpeg audio packet length check */ - if (packet_len > MAX_MPG_AUDIOPK_SIZE) - next_action = SEARCH_START_CODE; - - else - next_action = parser_process(1, packet_len); - - } else if (start_code == 0xbb) { - SET_DISCARD_SIZE(packet_len); - next_action = DISCARD_SEARCH; - } else if (start_code == 0xbd) - next_action = parser_process(2, packet_len); - - else if (start_code == 0xbf) { - SET_DISCARD_SIZE(packet_len); - next_action = DISCARD_SEARCH; - } else if ((start_code < 0xc0) || (start_code > 0xc8)) - next_action = SEARCH_START_CODE; - - else if (packet_len) { - SET_DISCARD_SIZE(packet_len); - next_action = DISCARD_SEARCH; - - } else - next_action = SEARCH_START_CODE; - } - - switch (next_action) { - case SEARCH_START_CODE: - WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH); - break; - - case SEND_VIDEO_SEARCH: - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - PARSER_AUTOSEARCH | PARSER_VIDEO | - PARSER_WRITE, ES_CTRL_BIT, ES_CTRL_WID); - break; - - case SEND_AUDIO_SEARCH: - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - PARSER_AUTOSEARCH | PARSER_AUDIO | - PARSER_WRITE, ES_CTRL_BIT, ES_CTRL_WID); - break; - - case SEND_SUBPIC_SEARCH: - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - PARSER_AUTOSEARCH | PARSER_SUBPIC | - PARSER_WRITE | ES_INSERT_BEFORE_ES_WRITE, - ES_CTRL_BIT, ES_CTRL_WID); - break; - - case DISCARD_SEARCH: - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - PARSER_AUTOSEARCH | PARSER_DISCARD, - ES_CTRL_BIT, ES_CTRL_WID); - break; - - case DISCARD_ONLY: - WRITE_MPEG_REG_BITS(PARSER_CONTROL, - PARSER_DISCARD, ES_CTRL_BIT, ES_CTRL_WID); - break; - -#ifdef VIDEO_AUTO_FLUSH - case SEARCH_START_CODE_VIDEO_FLUSH: - WRITE_MPEG_REG(PARSER_INSERT_DATA, 0xffffffff); - WRITE_MPEG_REG(PARSER_INSERT_DATA, 0xffffffff); - WRITE_MPEG_REG(PARSER_PARAMETER, - ((VIDEO_AUTO_FLUSH_BYTE_COUNT / - 8) << PARSER_PARAMETER_LOOP_BIT) | (8 << - PARSER_PARAMETER_LENGTH_BIT)); - WRITE_MPEG_REG(PARSER_CONTROL, - PARSER_AUTOSEARCH | PARSER_VIDEO | PARSER_WRITE | - ES_INSERT_BEFORE_ES_WRITE); - break; -#endif - } -} - -static void parser_tasklet(ulong data) -{ - s32 sc; - u32 int_status = READ_MPEG_REG(PARSER_INT_STATUS); - - WRITE_MPEG_REG(PARSER_INT_STATUS, int_status); - - if (int_status & PARSER_INTSTAT_FETCH_CMD) { - fetch_done = 1; - - wake_up_interruptible(&wq); - } - - if (int_status & PARSER_INTSTAT_SC_FOUND) { - sc = PARSER_POP; - - on_start_code_found(sc); - - } else if (int_status & PARSER_INTSTAT_DISCARD) - on_start_code_found(0); -} - -static irqreturn_t parser_isr(int irq, void *dev_id) -{ - tasklet_schedule(&psparser_tasklet); - - return IRQ_HANDLED; -} - -static ssize_t _psparser_write(const char __user *buf, size_t count) -{ - size_t r = count; - const char __user *p = buf; - u32 len; - int ret; - dma_addr_t dma_addr = 0; - - if (r > 0) { - len = min_t(size_t, r, FETCHBUF_SIZE); - if (copy_from_user(fetchbuf, p, len)) - return -EFAULT; - - dma_addr = - dma_map_single(amports_get_dma_device(), - fetchbuf, FETCHBUF_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), dma_addr)) - return -EFAULT; - - - fetch_done = 0; - - wmb(); /* Ensure fetchbuf contents visible */ - - WRITE_MPEG_REG(PARSER_FETCH_ADDR, dma_addr); - - WRITE_MPEG_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len); - dma_unmap_single(amports_get_dma_device(), dma_addr, - FETCHBUF_SIZE, DMA_TO_DEVICE); - ret = - wait_event_interruptible_timeout(wq, fetch_done != 0, - HZ / 10); - if (ret == 0) { - WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); - pr_info("write timeout, retry\n"); - return -EAGAIN; - } else if (ret < 0) - return -ERESTARTSYS; - - p += len; - r -= len; - } - - return count - r; -} - -s32 psparser_init(u32 vid, u32 aid, u32 sid, struct vdec_s *vdec) -{ - s32 r; - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - u32 parser_sub_rp; - -#ifdef DEBUG_VOB_SUB - u8 i; - - for (i = 0; i < MAX_SUB_NUM; i++) { - sub_info[i] = kzalloc(sizeof(struct subtitle_info), GFP_KERNEL); - if (!sub_info[i]) { - pr_info - ("[psparser_init]alloc for subtitle info failed\n"); - } else - sub_info[i]->id = -1; - } - sub_found_num = 0; -#endif - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); - - video_id = vid; - audio_id = aid; - sub_id = sid; - audio_got_first_pts = 0; - video_got_first_dts = 0; - sub_got_first_pts = 0; - first_apts = 0; - first_vpts = 0; - pts_equ_dts_flag = 0; - -#ifdef VIDEO_AUTO_FLUSH - video_auto_flush_state = VIDEO_AUTO_FLUSH_IDLE; -#endif - - pr_info("video 0x%x, audio 0x%x, sub 0x%x\n", video_id, audio_id, - sub_id); - if (fetchbuf == 0) { - pr_info("%s: no fetchbuf\n", __func__); - return -ENOMEM; - } - - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); - - /* TS data path */ -#ifndef CONFIG_AM_DVB - WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0); -#else - tsdemux_set_reset_flag(); -#endif - CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE)); - - /* hook stream buffer with PARSER */ - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, - vdec->input.start + vdec->input.size - 8); - - if (vdec_single(vdec)) { - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - } else { - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_RP, vdec->input.start); - } - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(PARSER_CONFIG, - (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | - (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | - (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); - - if (vdec_single(vdec)) { - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - } - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - - WRITE_MPEG_REG(PFIFO_RD_PTR, 0); - WRITE_MPEG_REG(PFIFO_WR_PTR, 0); - - WRITE_MPEG_REG(PARSER_SEARCH_PATTERN, MPEG_START_CODE_PATTERN); - WRITE_MPEG_REG(PARSER_SEARCH_MASK, MPEG_START_CODE_MASK); - - WRITE_MPEG_REG(PARSER_CONFIG, - (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | - (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | - PS_CFG_STARTCODE_WID_24 | - PS_CFG_PFIFO_ACCESS_WID_8 | /* single byte pop */ - (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); - WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH); - - tasklet_init(&psparser_tasklet, parser_tasklet, 0); - r = pts_start(PTS_TYPE_VIDEO); - if (r < 0) - goto Err_1; - r = pts_start(PTS_TYPE_AUDIO); - if (r < 0) - goto Err_2; - - video_data_parsed = 0; - audio_data_parsed = 0; - /*TODO irq */ - - r = vdec_request_irq(PARSER_IRQ, parser_isr, - "psparser", (void *)psparser_id); - - if (r) { - pr_info("PS Demux irq register failed.\n"); - - r = -ENOENT; - goto Err_3; - } - - WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); - WRITE_MPEG_REG(PARSER_INT_ENABLE, - PARSER_INT_ALL << PARSER_INT_HOST_EN_BIT); - - return 0; - -Err_3: - pts_stop(PTS_TYPE_AUDIO); - -Err_2: - pts_stop(PTS_TYPE_VIDEO); - -Err_1: - return r; -} - -void psparser_release(void) -{ - u8 i; - - pr_info("psparser_release\n"); - - WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); - /*TODO irq */ - - vdec_free_irq(PARSER_IRQ, (void *)psparser_id); - - pts_stop(PTS_TYPE_VIDEO); - pts_stop(PTS_TYPE_AUDIO); -#ifdef DEBUG_VOB_SUB - for (i = 0; i < MAX_SUB_NUM; i++) - kfree(sub_info[i]); - pr_info("psparser release subtitle info\n"); -#endif -} - -ssize_t psparser_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count) -{ - s32 r; - - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - - if ((stbuf_space(vbuf) < count) || (stbuf_space(abuf) < count)) { - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - if ((port->flag & PORT_FLAG_VID) - && (stbuf_space(vbuf) < count)) { - r = stbuf_wait_space(vbuf, count); - if (r < 0) - return r; - } - if ((port->flag & PORT_FLAG_AID) - && (stbuf_space(abuf) < count)) { - r = stbuf_wait_space(abuf, count); - if (r < 0) - return r; - } - } - - return _psparser_write(buf, count); -} - -void psparser_change_avid(unsigned int vid, unsigned int aid) -{ - video_id = vid; - audio_id = aid; -} - -void psparser_change_sid(unsigned int sid) -{ - sub_id = sid; -} - -void psparser_audio_reset(void) -{ - ulong flags; - - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); - - WRITE_MPEG_REG(PARSER_AUDIO_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - audio_data_parsed = 0; - - spin_unlock_irqrestore(&lock, flags); - -} - -void psparser_sub_reset(void) -{ - ulong flags; - - DEFINE_SPINLOCK(lock); - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - - spin_lock_irqsave(&lock, flags); - - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - - WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - - spin_unlock_irqrestore(&lock, flags); - -} - -u8 psparser_get_sub_found_num(void) -{ -#ifdef DEBUG_VOB_SUB - return sub_found_num; -#else - return 0; -#endif -} - -u8 psparser_get_sub_info(struct subtitle_info **sub_infos) -{ -#ifdef DEBUG_VOB_SUB - u8 i = 0; - int ret = 0; - u8 size = sizeof(struct subtitle_info); - - for (i = 0; i < sub_found_num; i++) { - if (!sub_info[i]) { - pr_info - ("[psparser_get_sub_info:%d] sub_info[%d] NULL\n", - __LINE__, i); - ret = -1; - break; - } - if (!sub_infos[i]) { - pr_info - ("[psparser_get_sub_info:%d] sub_infos[%d] NULL\n", - __LINE__, i); - ret = -2; - break; - } - memcpy(sub_infos[i], sub_info[i], size); - } - return ret; -#else - return 0; -#endif -} diff --git a/drivers/stream_input/parser/psparser.h b/drivers/stream_input/parser/psparser.h deleted file mode 100644 index 1280b6a..0000000 --- a/drivers/stream_input/parser/psparser.h +++ b/dev/null @@ -1,141 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/psparser.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 PSPARSER_H -#define PSPARSER_H - -#include "../../frame_provider/decoder/utils/vdec.h" - -extern s32 psparser_init(u32 vid, u32 aid, u32 sid, struct vdec_s *vdec); - -extern void psparser_release(void); - -extern ssize_t psparser_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, const char __user *buf, size_t count); - -extern void psparser_change_avid(unsigned int vid, unsigned int aid); - -extern void psparser_change_sid(unsigned int sid); - -extern void psparser_audio_reset(void); - -extern void psparser_sub_reset(void); - -extern u8 psparser_get_sub_found_num(void); - -extern u8 psparser_get_sub_info(struct subtitle_info *sub_infos[]); - -#ifdef CONFIG_AM_DVB -extern int tsdemux_set_reset_flag(void); -#endif - -/* TODO: move to register headers */ -#define ES_PACK_SIZE_BIT 8 -#define ES_PACK_SIZE_WID 24 - -#define ES_CTRL_WID 8 -#define ES_CTRL_BIT 0 -#define ES_TYPE_MASK (3 << 6) -#define ES_TYPE_VIDEO (0 << 6) -#define ES_TYPE_AUDIO (1 << 6) -#define ES_TYPE_SUBTITLE (2 << 6) - -#define ES_WRITE (1<<5) -#define ES_PASSTHROUGH (1<<4) -#define ES_INSERT_BEFORE_ES_WRITE (1<<3) -#define ES_DISCARD (1<<2) -#define ES_SEARCH (1<<1) -#define ES_PARSER_START (1<<0) -#define ES_PARSER_BUSY (1<<0) - -#define PARSER_INTSTAT_FETCH_CMD (1<<7) -#define PARSER_INTSTAT_PARSE (1<<4) -#define PARSER_INTSTAT_DISCARD (1<<3) -#define PARSER_INTSTAT_INSZERO (1<<2) -#define PARSER_INTSTAT_ACT_NOSSC (1<<1) -#define PARSER_INTSTAT_SC_FOUND (1<<0) - -#define FETCH_CIR_BUF (1<<31) -#define FETCH_CHK_BUF_STOP (1<<30) -#define FETCH_PASSTHROUGH (1<<29) -#define FETCH_ENDIAN 27 -#define FETCH_PASSTHROUGH_TYPE_MASK (0x3<<27) -#define FETCH_ENDIAN_MASK (0x7<<27) -#define FETCH_BUF_SIZE_MASK (0x7ffffff) -#define FETCH_CMD_PTR_MASK 3 -#define FETCH_CMD_RD_PTR_BIT 5 -#define FETCH_CMD_WR_PTR_BIT 3 -#define FETCH_CMD_NUM_MASK 3 -#define FETCH_CMD_NUM_BIT 0 - -#define ES_COUNT_MASK 0xfff -#define ES_COUNT_BIT 20 -#define ES_REQ_PENDING (1<<19) -#define ES_PASSTHROUGH_EN (1<<18) -#define ES_PASSTHROUGH_TYPE_MASK (3<<16) -#define ES_PASSTHROUGH_TYPE_VIDEO (0<<16) -#define ES_PASSTHROUGH_TYPE_AUDIO (1<<16) -#define ES_PASSTHROUGH_TYPE_SUBTITLE (2<<16) -#define ES_WR_ENDIAN_MASK (0x7) -#define ES_SUB_WR_ENDIAN_BIT 9 -#define ES_SUB_MAN_RD_PTR (1<<8) -#define ES_AUD_WR_ENDIAN_BIT 5 -#define ES_AUD_MAN_RD_PTR (1<<4) -#define ES_VID_WR_ENDIAN_BIT 1 -#define ES_VID_MAN_RD_PTR (1<<0) - -#define PS_CFG_FETCH_DMA_URGENT (1<<31) -#define PS_CFG_STREAM_DMA_URGENT (1<<30) -#define PS_CFG_FORCE_PFIFO_REN (1<<29) -#define PS_CFG_PFIFO_PEAK_EN (1<<28) -#define PS_CFG_SRC_SEL_BIT 24 -#define PS_CFG_SRC_SEL_MASK (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_FETCH (0<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX1 (1<<PS_CFG_SRC_SEL_BIT) /* from NDMA */ -#define PS_CFG_SRC_SEL_AUX2 (2<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX3 (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_PFIFO_EMPTY_CNT_BIT 16 -#define PS_CFG_PFIFO_EMPTY_CNT_MASK 0xff -#define PS_CFG_MAX_ES_WR_CYCLE_BIT 12 -#define PS_CFG_MAX_ES_WR_CYCLE_MASK 0xf -#define PS_CFG_STARTCODE_WID_MASK (0x3<<10) -#define PS_CFG_STARTCODE_WID_8 (0x0<<10) -#define PS_CFG_STARTCODE_WID_16 (0x1<<10) -#define PS_CFG_STARTCODE_WID_24 (0x2<<10) -#define PS_CFG_STARTCODE_WID_32 (0x3<<10) -#define PS_CFG_PFIFO_ACCESS_WID_MASK (0x3<<8) -#define PS_CFG_PFIFO_ACCESS_WID_8 (0x0<<8) -#define PS_CFG_PFIFO_ACCESS_WID_16 (0x1<<8) -#define PS_CFG_PFIFO_ACCESS_WID_24 (0x2<<8) -#define PS_CFG_PFIFO_ACCESS_WID_32 (0x3<<8) -#define PS_CFG_MAX_FETCH_CYCLE_BIT 0 -#define PS_CFG_MAX_FETCH_CYCLE_MASK 0xff - -#define PARSER_INT_DISABLE_CNT_MASK 0xffff -#define PARSER_INT_DISABLE_CNT_BIT 16 -#define PARSER_INT_HOST_EN_MASK 0xff -#define PARSER_INT_HOST_EN_BIT 8 -#define PARSER_INT_AMRISC_EN_MASK 0xff -#define PARSER_INT_AMRISC_EN_BIT 0 -#define PARSER_INT_ALL 0xff - -#define RESET_PARSER (1<<8) -#define TS_HIU_ENABLE 5 -#define USE_HI_BSF_INTERFACE 7 - -#endif /* PSPARSER_H */ diff --git a/drivers/stream_input/parser/rmparser.c b/drivers/stream_input/parser/rmparser.c deleted file mode 100644 index 63d7a63..0000000 --- a/drivers/stream_input/parser/rmparser.c +++ b/dev/null @@ -1,337 +0,0 @@ -/* - * drivers/amlogic/amports/rmparser.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/sched.h> -#include <linux/fs.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/uaccess.h> - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../amports/amports_priv.h" -#include "streambuf.h" -#include "streambuf_reg.h" -#include <linux/delay.h> -#include "rmparser.h" - -#define MANAGE_PTS - -static u32 fetch_done; -static u32 parse_halt; - -static DECLARE_WAIT_QUEUE_HEAD(rm_wq); -static const char rmparser_id[] = "rmparser-id"; - -static irqreturn_t rm_parser_isr(int irq, void *dev_id) -{ - u32 int_status = READ_MPEG_REG(PARSER_INT_STATUS); - - if (int_status & PARSER_INTSTAT_FETCH_CMD) { - WRITE_MPEG_REG(PARSER_INT_STATUS, PARSER_INTSTAT_FETCH_CMD); - fetch_done = 1; - - wake_up_interruptible(&rm_wq); - } - - return IRQ_HANDLED; -} - -s32 rmparser_init(struct vdec_s *vdec) -{ - s32 r; - parse_halt = 0; - if (fetchbuf == 0) { - pr_info("%s: no fetchbuf\n", __func__); - return -ENOMEM; - } - - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); - - /* TS data path */ -#ifndef CONFIG_AM_DVB - WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0); -#else - tsdemux_set_reset_flag(); -#endif - CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE); - CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE); - - CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE)); - - /* hook stream buffer with PARSER */ - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, - vdec->input.start + vdec->input.size - 8); - - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - WRITE_MPEG_REG(PFIFO_RD_PTR, 0); - WRITE_MPEG_REG(PFIFO_WR_PTR, 0); - - WRITE_MPEG_REG(PARSER_SEARCH_MASK, 0); - WRITE_MPEG_REG(PARSER_CONTROL, (ES_SEARCH | ES_PARSER_START)); - -#ifdef MANAGE_PTS - if (pts_start(PTS_TYPE_VIDEO) < 0) - goto Err_1; - - if (pts_start(PTS_TYPE_AUDIO) < 0) - goto Err_2; -#endif - /*TODO irq */ - - /* enable interrupt */ - - r = vdec_request_irq(PARSER_IRQ, rm_parser_isr, - "rmparser", (void *)rmparser_id); - - if (r) { - pr_info("RM parser irq register failed.\n"); - goto Err_3; - } - - WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); - WRITE_MPEG_REG(PARSER_INT_ENABLE, - ((PARSER_INT_ALL & (~PARSER_INTSTAT_FETCH_CMD)) << - PARSER_INT_AMRISC_EN_BIT) - | (PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT)); - - return 0; - -Err_3: - pts_stop(PTS_TYPE_AUDIO); -Err_2: - pts_stop(PTS_TYPE_VIDEO); -Err_1: - return -ENOENT; -} -EXPORT_SYMBOL(rmparser_init); - -void rmparser_release(void) -{ - WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); - /*TODO irq */ - - vdec_free_irq(PARSER_IRQ, (void *)rmparser_id); - -#ifdef MANAGE_PTS - pts_stop(PTS_TYPE_VIDEO); - pts_stop(PTS_TYPE_AUDIO); -#endif - - return; -} -EXPORT_SYMBOL(rmparser_release); - -static inline u32 buf_wp(u32 type) -{ - return (type == BUF_TYPE_VIDEO) ? READ_VREG(VLD_MEM_VIFIFO_WP) : - (type == BUF_TYPE_AUDIO) ? - READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_WP) : - READ_MPEG_REG(PARSER_SUB_START_PTR); -} - -static ssize_t _rmparser_write(const char __user *buf, size_t count) -{ - size_t r = count; - const char __user *p = buf; - u32 len; - int ret; - static int halt_droped_len; - u32 vwp, awp; - dma_addr_t dma_addr = 0; - - if (r > 0) { - len = min_t(size_t, r, FETCHBUF_SIZE); - - if (copy_from_user(fetchbuf, p, len)) - return -EFAULT; - dma_addr = - dma_map_single(amports_get_dma_device(), - fetchbuf, FETCHBUF_SIZE, - DMA_TO_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), dma_addr)) - return -EFAULT; - - fetch_done = 0; - - wmb(); /* Ensure fetchbuf contents visible */ - vwp = buf_wp(BUF_TYPE_VIDEO); - awp = buf_wp(BUF_TYPE_AUDIO); - WRITE_MPEG_REG(PARSER_FETCH_ADDR, dma_addr); - - WRITE_MPEG_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len); - dma_unmap_single(amports_get_dma_device(), dma_addr, - FETCHBUF_SIZE, DMA_TO_DEVICE); - ret = - wait_event_interruptible_timeout(rm_wq, fetch_done != 0, - HZ / 10); - if (ret == 0) { - WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); - parse_halt++; - pr_info - ("write timeout,retry,halt_count=%d parse_control=%x\n", - parse_halt, READ_MPEG_REG(PARSER_CONTROL)); - - //vreal_set_fatal_flag(1);//DEBUG_TMP - - if (parse_halt > 10) { - WRITE_MPEG_REG(PARSER_CONTROL, - (ES_SEARCH | ES_PARSER_START)); - pr_info("reset parse_control=%x\n", - READ_MPEG_REG(PARSER_CONTROL)); - } - return -EAGAIN; - } else if (ret < 0) - return -ERESTARTSYS; - - if (vwp == buf_wp(BUF_TYPE_VIDEO) - && awp == buf_wp(BUF_TYPE_AUDIO)) { - struct stream_buf_s *v_buf_t = - get_buf_by_type(BUF_TYPE_VIDEO); - struct stream_buf_s *a_buf_t = - get_buf_by_type(BUF_TYPE_AUDIO); - int v_st_lv = stbuf_level(v_buf_t); - int a_st_lv = stbuf_level(a_buf_t); - if ((parse_halt + 1) % 10 == 1) { - pr_info("V&A WP not changed after write"); - pr_info(",video %x->%x", vwp, - buf_wp(BUF_TYPE_VIDEO)); - pr_info(",Audio:%x-->%x,parse_halt=%d\n", - awp, buf_wp(BUF_TYPE_AUDIO), - parse_halt); - } - parse_halt++; /*wp not changed , - we think have bugs on parser now. */ - if (parse_halt > 10 && - (v_st_lv < 1000 || a_st_lv < 100)) { - /*reset while at least one is underflow. */ - WRITE_MPEG_REG(PARSER_CONTROL, - (ES_SEARCH | ES_PARSER_START)); - pr_info("reset parse_control=%x\n", - READ_MPEG_REG(PARSER_CONTROL)); - } - if (parse_halt <= 10 || - halt_droped_len < 100 * 1024) { - /*drops first 10 pkt , - some times maybe no av data */ - pr_info("drop this pkt=%d,len=%d\n", parse_halt, - len); - p += len; - r -= len; - halt_droped_len += len; - } else - return -EAGAIN; - } else { - halt_droped_len = 0; - parse_halt = 0; - p += len; - r -= len; - } - } - return count - r; -} - -ssize_t rmparser_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count) -{ - s32 r; - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - size_t towrite = count; - if ((stbuf_space(vbuf) < count) || (stbuf_space(abuf) < count)) { - if (file->f_flags & O_NONBLOCK) { - towrite = min(stbuf_space(vbuf), stbuf_space(abuf)); - if (towrite < 1024) /*? can write small? */ - return -EAGAIN; - } else { - if ((port->flag & PORT_FLAG_VID) - && (stbuf_space(vbuf) < count)) { - r = stbuf_wait_space(vbuf, count); - if (r < 0) - return r; - } - if ((port->flag & PORT_FLAG_AID) - && (stbuf_space(abuf) < count)) { - r = stbuf_wait_space(abuf, count); - if (r < 0) - return r; - } - } - } - towrite = min(towrite, count); - return _rmparser_write(buf, towrite); -} -EXPORT_SYMBOL(rmparser_write); - -void rm_set_vasid(u32 vid, u32 aid) -{ - pr_info("rm_set_vasid aid %d, vid %d\n", aid, vid); - WRITE_MPEG_REG(VAS_STREAM_ID, (aid << 8) | vid); - - return; -} -EXPORT_SYMBOL(rm_set_vasid); - -void rm_audio_reset(void) -{ - ulong flags; - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); - - WRITE_MPEG_REG(PARSER_AUDIO_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - spin_unlock_irqrestore(&lock, flags); - - return; -} -EXPORT_SYMBOL(rm_audio_reset); diff --git a/drivers/stream_input/parser/rmparser.h b/drivers/stream_input/parser/rmparser.h deleted file mode 100644 index 5d258ee..0000000 --- a/drivers/stream_input/parser/rmparser.h +++ b/dev/null @@ -1,136 +0,0 @@ -/* - * drivers/amlogic/amports/rmparser.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 RMPARSER_H -#define RMPARSER_H - -#include "../../frame_provider/decoder/utils/vdec.h" - -extern void rm_set_vasid(u32 vid, u32 aid); - -extern ssize_t rmparser_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count); - -s32 rmparser_init(struct vdec_s *vdec); - -extern void rmparser_release(void); - -extern void rm_audio_reset(void); - -extern void vreal_set_fatal_flag(int flag); - -#ifdef CONFIG_AM_DVB -extern int tsdemux_set_reset_flag(void); -#endif - -/* TODO: move to register headers */ -#define ES_PACK_SIZE_BIT 8 -#define ES_PACK_SIZE_WID 24 - -#define ES_CTRL_WID 8 -#define ES_CTRL_BIT 0 -#define ES_TYPE_MASK (3 << 6) -#define ES_TYPE_VIDEO (0 << 6) -#define ES_TYPE_AUDIO (1 << 6) -#define ES_TYPE_SUBTITLE (2 << 6) - -#define ES_WRITE (1<<5) -#define ES_PASSTHROUGH (1<<4) -#define ES_INSERT_BEFORE_ES_WRITE (1<<3) -#define ES_DISCARD (1<<2) -#define ES_SEARCH (1<<1) -#define ES_PARSER_START (1<<0) -#define ES_PARSER_BUSY (1<<0) - -#define PARSER_INTSTAT_FETCH_CMD (1<<7) -#define PARSER_INTSTAT_PARSE (1<<4) -#define PARSER_INTSTAT_DISCARD (1<<3) -#define PARSER_INTSTAT_INSZERO (1<<2) -#define PARSER_INTSTAT_ACT_NOSSC (1<<1) -#define PARSER_INTSTAT_SC_FOUND (1<<0) - -#define FETCH_CIR_BUF (1<<31) -#define FETCH_CHK_BUF_STOP (1<<30) -#define FETCH_PASSTHROUGH (1<<29) -#define FETCH_ENDIAN 27 -#define FETCH_PASSTHROUGH_TYPE_MASK (0x3<<27) -#define FETCH_ENDIAN_MASK (0x7<<27) -#define FETCH_BUF_SIZE_MASK (0x7ffffff) -#define FETCH_CMD_PTR_MASK 3 -#define FETCH_CMD_RD_PTR_BIT 5 -#define FETCH_CMD_WR_PTR_BIT 3 -#define FETCH_CMD_NUM_MASK 3 -#define FETCH_CMD_NUM_BIT 0 - -#define ES_COUNT_MASK 0xfff -#define ES_COUNT_BIT 20 -#define ES_REQ_PENDING (1<<19) -#define ES_PASSTHROUGH_EN (1<<18) -#define ES_PASSTHROUGH_TYPE_MASK (3<<16) -#define ES_PASSTHROUGH_TYPE_VIDEO (0<<16) -#define ES_PASSTHROUGH_TYPE_AUDIO (1<<16) -#define ES_PASSTHROUGH_TYPE_SUBTITLE (2<<16) -#define ES_WR_ENDIAN_MASK (0x7) -#define ES_SUB_WR_ENDIAN_BIT 9 -#define ES_SUB_MAN_RD_PTR (1<<8) -#define ES_AUD_WR_ENDIAN_BIT 5 -#define ES_AUD_MAN_RD_PTR (1<<4) -#define ES_VID_WR_ENDIAN_BIT 1 -#define ES_VID_MAN_RD_PTR (1<<0) - -#define PS_CFG_FETCH_DMA_URGENT (1<<31) -#define PS_CFG_STREAM_DMA_URGENT (1<<30) -#define PS_CFG_FORCE_PFIFO_REN (1<<29) -#define PS_CFG_PFIFO_PEAK_EN (1<<28) -#define PS_CFG_SRC_SEL_BIT 24 -#define PS_CFG_SRC_SEL_MASK (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_FETCH (0<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX1 (1<<PS_CFG_SRC_SEL_BIT) /* from NDMA */ -#define PS_CFG_SRC_SEL_AUX2 (2<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_SRC_SEL_AUX3 (3<<PS_CFG_SRC_SEL_BIT) -#define PS_CFG_PFIFO_EMPTY_CNT_BIT 16 -#define PS_CFG_PFIFO_EMPTY_CNT_MASK 0xff -#define PS_CFG_MAX_ES_WR_CYCLE_BIT 12 -#define PS_CFG_MAX_ES_WR_CYCLE_MASK 0xf -#define PS_CFG_STARTCODE_WID_MASK (0x3<<10) -#define PS_CFG_STARTCODE_WID_8 (0x0<<10) -#define PS_CFG_STARTCODE_WID_16 (0x1<<10) -#define PS_CFG_STARTCODE_WID_24 (0x2<<10) -#define PS_CFG_STARTCODE_WID_32 (0x3<<10) -#define PS_CFG_PFIFO_ACCESS_WID_MASK (0x3<<8) -#define PS_CFG_PFIFO_ACCESS_WID_8 (0x0<<8) -#define PS_CFG_PFIFO_ACCESS_WID_16 (0x1<<8) -#define PS_CFG_PFIFO_ACCESS_WID_24 (0x2<<8) -#define PS_CFG_PFIFO_ACCESS_WID_32 (0x3<<8) -#define PS_CFG_MAX_FETCH_CYCLE_BIT 0 -#define PS_CFG_MAX_FETCH_CYCLE_MASK 0xff - -#define PARSER_INT_DISABLE_CNT_MASK 0xffff -#define PARSER_INT_DISABLE_CNT_BIT 16 -#define PARSER_INT_HOST_EN_MASK 0xff -#define PARSER_INT_HOST_EN_BIT 8 -#define PARSER_INT_AMRISC_EN_MASK 0xff -#define PARSER_INT_AMRISC_EN_BIT 0 -#define PARSER_INT_ALL 0xff - -#define RESET_PARSER (1<<8) -#define TS_HIU_ENABLE 5 -#define USE_HI_BSF_INTERFACE 7 - -#endif /* RMPARSER_H */ diff --git a/drivers/stream_input/parser/streambuf.c b/drivers/stream_input/parser/streambuf.c deleted file mode 100644 index 8b9aa33..0000000 --- a/drivers/stream_input/parser/streambuf.c +++ b/dev/null @@ -1,418 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/streambuf.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/spinlock.h> -#include <linux/timer.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/io.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/utils/vformat.h> -#include <linux/amlogic/iomap.h> -#include <asm/cacheflush.h> -#include <linux/uaccess.h> -#include <linux/vmalloc.h> -/* #include <mach/am_regs.h> */ - -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "../../frame_provider/decoder/utils/vdec.h" -#include "streambuf_reg.h" -#include "streambuf.h" -#include <linux/amlogic/media/utils/amports_config.h> -#include "../amports/amports_priv.h" -#include <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -#define STBUF_SIZE (64*1024) -#define STBUF_WAIT_INTERVAL (HZ/100) -#define MEM_NAME "streambuf" - -void *fetchbuf; - -static s32 _stbuf_alloc(struct stream_buf_s *buf) -{ - if (buf->buf_size == 0) - return -ENOBUFS; - - while (buf->buf_start == 0) { - int flags = CODEC_MM_FLAGS_DMA; - - buf->buf_page_num = PAGE_ALIGN(buf->buf_size) / PAGE_SIZE; - if (buf->type == BUF_TYPE_SUBTITLE) - flags = CODEC_MM_FLAGS_DMA_CPU; - - /* - *if 4k, - *used cma first,for less mem fragments. - */ - if (((buf->type == BUF_TYPE_HEVC) || - (buf->type == BUF_TYPE_VIDEO)) && - buf->for_4k) - flags |= CODEC_MM_FLAGS_CMA_FIRST; - if (buf->buf_size > 20 * 1024 * 1024) - flags |= CODEC_MM_FLAGS_CMA_FIRST; - - if ((buf->type == BUF_TYPE_HEVC) || - (buf->type == BUF_TYPE_VIDEO)) { - flags |= CODEC_MM_FLAGS_FOR_VDECODER; - } else if (buf->type == BUF_TYPE_AUDIO) { - flags |= CODEC_MM_FLAGS_FOR_ADECODER; - flags |= CODEC_MM_FLAGS_DMA_CPU; - } - - buf->buf_start = codec_mm_alloc_for_dma(MEM_NAME, - buf->buf_page_num, 4+PAGE_SHIFT, flags); - if (!buf->buf_start) { - int is_video = (buf->type == BUF_TYPE_HEVC) || - (buf->type == BUF_TYPE_VIDEO); - if (is_video && buf->buf_size >= 9 * SZ_1M) {/*min 6M*/ - int old_size = buf->buf_size; - - buf->buf_size = - PAGE_ALIGN(buf->buf_size * 2/3); - pr_info("%s stbuf alloced size = %d failed try small %d size\n", - (buf->type == BUF_TYPE_HEVC) ? "HEVC" : - (buf->type == BUF_TYPE_VIDEO) ? "Video" : - (buf->type == BUF_TYPE_AUDIO) ? "Audio" : - "Subtitle", old_size, buf->buf_size); - continue; - } - pr_info("%s stbuf alloced size = %d failed\n", - (buf->type == BUF_TYPE_HEVC) ? "HEVC" : - (buf->type == BUF_TYPE_VIDEO) ? "Video" : - (buf->type == BUF_TYPE_AUDIO) ? "Audio" : - "Subtitle", buf->buf_size); - return -ENOMEM; - } - pr_info("%s stbuf alloced at %p, size = %d\n", - (buf->type == BUF_TYPE_HEVC) ? "HEVC" : - (buf->type == BUF_TYPE_VIDEO) ? "Video" : - (buf->type == BUF_TYPE_AUDIO) ? "Audio" : - "Subtitle", (void *)buf->buf_start, - buf->buf_size); - } - if (buf->buf_size < buf->canusebuf_size) - buf->canusebuf_size = buf->buf_size; - buf->flag |= BUF_FLAG_ALLOC; - - return 0; -} - -int stbuf_change_size(struct stream_buf_s *buf, int size) -{ - unsigned long old_buf; - int old_size, old_pagenum; - int ret; - - pr_info("buffersize=%d,%d,start=%p\n", size, buf->buf_size, - (void *)buf->buf_start); - - if (buf->buf_size == size && buf->buf_start != 0) - return 0; - - old_buf = buf->buf_start; - old_size = buf->buf_size; - old_pagenum = buf->buf_page_num; - buf->buf_start = 0; - buf->buf_size = size; - ret = size; - - if (size == 0 || _stbuf_alloc(buf) == 0) { - /* - * size=0:We only free the old memory; - * alloc ok,changed to new buffer - */ - if (old_buf != 0) - codec_mm_free_for_dma(MEM_NAME, old_buf); - - pr_info("changed the (%d) buffer size from %d to %d\n", - buf->type, old_size, size); - return 0; - } - /* alloc failed */ - buf->buf_start = old_buf; - buf->buf_size = old_size; - buf->buf_page_num = old_pagenum; - pr_info("changed the (%d) buffer size from %d to %d,failed\n", - buf->type, old_size, size); - - return ret; -} - -int stbuf_fetch_init(void) -{ - if (NULL != fetchbuf) - return 0; - - fetchbuf = (void *)__get_free_pages(GFP_KERNEL, - get_order(FETCHBUF_SIZE)); - - if (!fetchbuf) { - pr_info("%s: Can not allocate fetch working buffer\n", - __func__); - return -ENOMEM; - } - return 0; -} - -void stbuf_fetch_release(void) -{ - if (0 && fetchbuf) { - /* always don't free.for safe alloc/free*/ - free_pages((unsigned long)fetchbuf, get_order(FETCHBUF_SIZE)); - fetchbuf = 0; - } -} - -static void _stbuf_timer_func(unsigned long arg) -{ - struct stream_buf_s *p = (struct stream_buf_s *)arg; - - if (stbuf_space(p) < p->wcnt) { - p->timer.expires = jiffies + STBUF_WAIT_INTERVAL; - - add_timer(&p->timer); - } else - wake_up_interruptible(&p->wq); - -} - -u32 stbuf_level(struct stream_buf_s *buf) -{ - if ((buf->type == BUF_TYPE_HEVC) || (buf->type == BUF_TYPE_VIDEO)) { - if (READ_MPEG_REG(PARSER_ES_CONTROL) & 1) { - int level = READ_MPEG_REG(PARSER_VIDEO_WP) - - READ_MPEG_REG(PARSER_VIDEO_RP); - if (level < 0) - level += READ_MPEG_REG(PARSER_VIDEO_END_PTR) - - READ_MPEG_REG(PARSER_VIDEO_START_PTR) + 8; - return (u32)level; - } else - return (buf->type == BUF_TYPE_HEVC) ? - READ_VREG(HEVC_STREAM_LEVEL) : - _READ_ST_REG(LEVEL); - } - - return _READ_ST_REG(LEVEL); -} - -u32 stbuf_rp(struct stream_buf_s *buf) -{ - if ((buf->type == BUF_TYPE_HEVC) || (buf->type == BUF_TYPE_VIDEO)) { - if (READ_MPEG_REG(PARSER_ES_CONTROL) & 1) - return READ_MPEG_REG(PARSER_VIDEO_RP); - else - return (buf->type == BUF_TYPE_HEVC) ? - READ_VREG(HEVC_STREAM_RD_PTR) : - _READ_ST_REG(RP); - } - - return _READ_ST_REG(RP); -} - -u32 stbuf_space(struct stream_buf_s *buf) -{ - /* reserved space for safe write, - the parser fifo size is 1024byts, so reserve it */ - int size; - - size = buf->canusebuf_size - stbuf_level(buf); - - if (buf->canusebuf_size >= buf->buf_size / 2) { - /* old reversed value,tobe full, reversed only... */ - size = size - 6 * 1024; - } - - if ((buf->type == BUF_TYPE_VIDEO) - || (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC)) - size -= READ_MPEG_REG(PARSER_VIDEO_HOLE); - - return size > 0 ? size : 0; -} - -u32 stbuf_size(struct stream_buf_s *buf) -{ - return buf->buf_size; -} - -u32 stbuf_canusesize(struct stream_buf_s *buf) -{ - return buf->canusebuf_size; -} - -s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec) -{ - s32 r; - u32 dummy; - u32 addr32; - - if (!buf->buf_start) { - r = _stbuf_alloc(buf); - if (r < 0) - return r; - } - addr32 = buf->buf_start & 0xffffffff; - init_waitqueue_head(&buf->wq); - - if ((buf->type == BUF_TYPE_VIDEO) || (buf->type == BUF_TYPE_HEVC)) { - if (vdec) { - if (vdec_stream_based(vdec)) - vdec_input_set_buffer(&vdec->input, addr32, - buf->buf_size); - else - return vdec_input_set_buffer(&vdec->input, - addr32, buf->buf_size); - } - } - - buf->write_thread = 0; - if (has_hevc_vdec() && buf->type == BUF_TYPE_HEVC) { - CLEAR_VREG_MASK(HEVC_STREAM_CONTROL, 1); - WRITE_VREG(HEVC_STREAM_START_ADDR, addr32); - WRITE_VREG(HEVC_STREAM_END_ADDR, addr32 + buf->buf_size); - WRITE_VREG(HEVC_STREAM_RD_PTR, addr32); - WRITE_VREG(HEVC_STREAM_WR_PTR, addr32); - - return 0; - } - - if (buf->type == BUF_TYPE_VIDEO) { - _WRITE_ST_REG(CONTROL, 0); - /* reset VLD before setting all pointers */ - WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, 0); - /*TODO: only > m6*/ -#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - WRITE_VREG(DOS_SW_RESET0, (1 << 4)); - WRITE_VREG(DOS_SW_RESET0, 0); -#else - WRITE_MPEG_REG(RESET0_REGISTER, RESET_VLD); -#endif - - dummy = READ_MPEG_REG(RESET0_REGISTER); - WRITE_VREG(POWER_CTL_VLD, 1 << 4); - } else if (buf->type == BUF_TYPE_AUDIO) { - _WRITE_ST_REG(CONTROL, 0); - - WRITE_MPEG_REG(AIU_AIFIFO_GBIT, 0x80); - } - - if (buf->type == BUF_TYPE_SUBTITLE) { - WRITE_MPEG_REG(PARSER_SUB_RP, addr32); - WRITE_MPEG_REG(PARSER_SUB_START_PTR, addr32); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, - addr32 + buf->buf_size - 8); - - return 0; - } - - _WRITE_ST_REG(START_PTR, addr32); - _WRITE_ST_REG(CURR_PTR, addr32); - _WRITE_ST_REG(END_PTR, addr32 + buf->buf_size - 8); - - _SET_ST_REG_MASK(CONTROL, MEM_BUFCTRL_INIT); - _CLR_ST_REG_MASK(CONTROL, MEM_BUFCTRL_INIT); - - _WRITE_ST_REG(BUF_CTRL, MEM_BUFCTRL_MANUAL); - _WRITE_ST_REG(WP, addr32); - - _SET_ST_REG_MASK(BUF_CTRL, MEM_BUFCTRL_INIT); - _CLR_ST_REG_MASK(BUF_CTRL, MEM_BUFCTRL_INIT); - - _SET_ST_REG_MASK(CONTROL, - (0x11 << 16) | MEM_FILL_ON_LEVEL | MEM_CTRL_FILL_EN | - MEM_CTRL_EMPTY_EN); - return 0; -} - -void stbuf_vdec2_init(struct stream_buf_s *buf) -{ - - _WRITE_VDEC2_ST_REG(CONTROL, 0); - - _WRITE_VDEC2_ST_REG(START_PTR, _READ_ST_REG(START_PTR)); - _WRITE_VDEC2_ST_REG(END_PTR, _READ_ST_REG(END_PTR)); - _WRITE_VDEC2_ST_REG(CURR_PTR, _READ_ST_REG(CURR_PTR)); - - _WRITE_VDEC2_ST_REG(CONTROL, MEM_FILL_ON_LEVEL | MEM_BUFCTRL_INIT); - _WRITE_VDEC2_ST_REG(CONTROL, MEM_FILL_ON_LEVEL); - - _WRITE_VDEC2_ST_REG(BUF_CTRL, MEM_BUFCTRL_INIT); - _WRITE_VDEC2_ST_REG(BUF_CTRL, 0); - - _WRITE_VDEC2_ST_REG(CONTROL, - (0x11 << 16) | MEM_FILL_ON_LEVEL | MEM_CTRL_FILL_EN - | MEM_CTRL_EMPTY_EN); -} - -s32 stbuf_wait_space(struct stream_buf_s *stream_buf, size_t count) -{ - struct stream_buf_s *p = stream_buf; - long time_out = 20; - - p->wcnt = count; - - setup_timer(&p->timer, _stbuf_timer_func, (ulong) p); - - mod_timer(&p->timer, jiffies + STBUF_WAIT_INTERVAL); - - if (wait_event_interruptible_timeout - (p->wq, stbuf_space(p) >= count, time_out) == 0) { - del_timer_sync(&p->timer); - - return -EAGAIN; - } - - del_timer_sync(&p->timer); - - return 0; -} - -void stbuf_release(struct stream_buf_s *buf) -{ - buf->first_tstamp = INVALID_PTS; - - stbuf_init(buf, NULL); /* reinit buffer */ - - if (buf->flag & BUF_FLAG_ALLOC && buf->buf_start) { - codec_mm_free_for_dma(MEM_NAME, buf->buf_start); - buf->flag &= ~BUF_FLAG_ALLOC; - buf->buf_start = 0; - } - buf->flag &= ~BUF_FLAG_IN_USE; -} - -u32 stbuf_sub_rp_get(void) -{ - return READ_MPEG_REG(PARSER_SUB_RP); -} - -void stbuf_sub_rp_set(unsigned int sub_rp) -{ - WRITE_MPEG_REG(PARSER_SUB_RP, sub_rp); -} - -u32 stbuf_sub_wp_get(void) -{ - return READ_MPEG_REG(PARSER_SUB_WP); -} - -u32 stbuf_sub_start_get(void) -{ - return READ_MPEG_REG(PARSER_SUB_START_PTR); -} diff --git a/drivers/stream_input/parser/streambuf.h b/drivers/stream_input/parser/streambuf.h deleted file mode 100644 index cdae0a8..0000000 --- a/drivers/stream_input/parser/streambuf.h +++ b/dev/null @@ -1,136 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/streambuf.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 STREAMBUF_H -#define STREAMBUF_H -#include <linux/amlogic/media/utils/amports_config.h> - -#define BUF_FLAG_ALLOC 0x01 -#define BUF_FLAG_IN_USE 0x02 -#define BUF_FLAG_PARSER 0x04 -#define BUF_FLAG_FIRST_TSTAMP 0x08 -#define BUF_FLAG_IOMEM 0x10 - -#define BUF_TYPE_VIDEO 0 -#define BUF_TYPE_AUDIO 1 -#define BUF_TYPE_SUBTITLE 2 -#define BUF_TYPE_USERDATA 3 -#define BUF_TYPE_HEVC 4 -#define BUF_MAX_NUM 5 - -#define INVALID_PTS 0xffffffff - -#define FETCHBUF_SIZE (64*1024) -#define USER_DATA_SIZE (8*1024) - -struct vdec_s; - -struct stream_buf_s { - s32 flag; - u32 type; - unsigned long buf_start; - struct page *buf_pages; - int buf_page_num; - u32 buf_size; - u32 default_buf_size; - u32 canusebuf_size; - u32 first_tstamp; - const ulong reg_base; - wait_queue_head_t wq; - struct timer_list timer; - u32 wcnt; - u32 buf_wp; - u32 buf_rp; - u32 max_buffer_delay_ms; - u64 last_write_jiffies64; - void *write_thread; - int for_4k; -} /*stream_buf_t */; - -struct stream_port_s { - /* driver info */ - const char *name; - struct device *class_dev; - const struct file_operations *fops; - - /* ports control */ - s32 type; - s32 flag; - s32 pcr_inited; - - /* decoder info */ - s32 vformat; - s32 aformat; - s32 achanl; - s32 asamprate; - s32 adatawidth; - - /* parser info */ - u32 vid; - u32 aid; - u32 sid; - u32 pcrid; -} /*stream_port_t */; -enum drm_level_e { - DRM_LEVEL1 = 1, - DRM_LEVEL2 = 2, - DRM_LEVEL3 = 3, - DRM_NONE = 4, -}; - -struct drm_info { - enum drm_level_e drm_level; - u32 drm_flag; - u32 drm_hasesdata; - u32 drm_priv; - u32 drm_pktsize; - u32 drm_pktpts; - u32 drm_phy; - u32 drm_vir; - u32 drm_remap; - u32 data_offset; - u32 extpad[8]; -} /*drminfo_t */; - -#define TYPE_DRMINFO 0x80 -#define TYPE_PATTERN 0x40 - -struct vdec_s; - -extern void *fetchbuf; - -extern u32 stbuf_level(struct stream_buf_s *buf); -extern u32 stbuf_rp(struct stream_buf_s *buf); -extern u32 stbuf_space(struct stream_buf_s *buf); -extern u32 stbuf_size(struct stream_buf_s *buf); -extern u32 stbuf_canusesize(struct stream_buf_s *buf); -extern s32 stbuf_init(struct stream_buf_s *buf, struct vdec_s *vdec); -extern s32 stbuf_wait_space(struct stream_buf_s *stream_buf, size_t count); -extern void stbuf_release(struct stream_buf_s *buf); -extern int stbuf_change_size(struct stream_buf_s *buf, int size); -extern int stbuf_fetch_init(void); -extern void stbuf_fetch_release(void); -extern u32 stbuf_sub_rp_get(void); -extern void stbuf_sub_rp_set(unsigned int sub_rp); -extern u32 stbuf_sub_wp_get(void); -extern u32 stbuf_sub_start_get(void); -extern u32 stbuf_userdata_start_get(void); -extern struct stream_buf_s *get_stream_buffer(int id); - -extern void stbuf_vdec2_init(struct stream_buf_s *buf); - -#endif /* STREAMBUF_H */ diff --git a/drivers/stream_input/parser/streambuf_reg.h b/drivers/stream_input/parser/streambuf_reg.h deleted file mode 100644 index f00c705..0000000 --- a/drivers/stream_input/parser/streambuf_reg.h +++ b/dev/null @@ -1,111 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/streambuf_reg.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 STREAMBUF_REG_H -#define STREAMBUF_REG_H - -#define HEVC_STREAM_REG_BASE HEVC_STREAM_START_ADDR - -#define VLD_MEM_VIFIFO_REG_BASE VLD_MEM_VIFIFO_START_PTR -#define AIU_MEM_AIFIFO_REG_BASE AIU_MEM_AIFIFO_START_PTR - -#define START_PTR 0 -#define CURR_PTR 1 -#define END_PTR 2 -#define BYTES_AVAIL 3 -#define CONTROL 4 -#define WP 5 -#define RP 6 -#define LEVEL 7 -#define BUF_CTRL 8 - -/* -*#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 -*#define _WRITE_ST_REG(r, val) \ -* __raw_writel(val, (volatile void __iomem *)(buf->reg_base+(r<<2))) -*#define _WRITE_ST_REG_BITS(r, val, s, e) \ -* __raw_writel((((_READ_ST_REG(r) & \ -* (((1L<<(e)-1)<<(s))-1)<<(s)))|((unsigned)((val)&((1L<<(e))-1))<<(s))), \ -* (volatile void __iomem *)(buf->reg_base+(r<<2))) -*#define _SET_ST_REG_MASK(r, val) \ -* __raw_writel(_READ_ST_REG(r)| (val), \ -* (volatile void __iomem *)(buf->reg_base+(r<<2))) -*#define _CLR_ST_REG_MASK(r, val) \ -* __raw_writel(_READ_ST_REG(r)&~(val), \ -* (volatile void __iomem *)(buf->reg_base+(r<<2))) -*#define _READ_ST_REG(r) \ -* (__raw_readl((volatile void __iomem *)(buf->reg_base+(r<<2)))) -* -*#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD -*#define _READ_VDEC2_ST_REG(r) \ -* (__raw_readl((volatile void __iomem *)(buf->reg_base + \ -* DOS_REG_ADDR(VDEC2_VLD_MEM_VIFIFO_START_PTR) - \ -* DOS_REG_ADDR(VLD_MEM_VIFIFO_START_PTR) + (r<<2)))) -*#define _WRITE_VDEC2_ST_REG(r, val) \ -* __raw_writel(val, (volatile void __iomem *)(buf->reg_base + \ -* DOS_REG_ADDR(VDEC2_VLD_MEM_VIFIFO_START_PTR) - \ -* DOS_REG_ADDR(VLD_MEM_VIFIFO_START_PTR) + (r<<2))) -*#endif -* -*#define MEM_BUFCTRL_MANUAL (1<<1) -*#define MEM_BUFCTRL_INIT (1<<0) -*#define MEM_LEVEL_CNT_BIT 18 -*#define MEM_FIFO_CNT_BIT 16 -*#define MEM_FILL_ON_LEVEL (1<<10) -*#define MEM_CTRL_EMPTY_EN (1<<2) -*#define MEM_CTRL_FILL_EN (1<<1) -*#define MEM_CTRL_INIT (1<<0) -* -*#else -*#define _WRITE_ST_REG(r, val) WRITE_MPEG_REG(buf->reg_base + (r), \ -* (val)) -*#define _WRITE_ST_REG_BITS(r, val, s, e) WRITE_MPEG_REG(buf->reg_base + (r), \ -* (val), (s), (e)) -*#define _SET_ST_REG_MASK(r, val) SET_MPEG_REG_MASK(buf->reg_base + \ -* (r), (val)) -*#define _CLR_ST_REG_MASK(r, val) CLEAR_MPEG_REG_MASK(buf->reg_base + \ -* (r), (val)) -*#define _READ_ST_REG(r) READ_MPEG_REG(buf->reg_base + (r)) -*#endif -*/ - - /*TODO*/ -#define _WRITE_ST_REG(r, val) do { \ - if (buf->reg_base == VLD_MEM_VIFIFO_REG_BASE) \ - codec_dosbus_write((buf->reg_base+(r)), (val)); \ - else \ - codec_cbus_write((buf->reg_base+(r)), (val)); \ - } while (0) -#define _READ_ST_REG(r) \ - ((buf->reg_base == VLD_MEM_VIFIFO_REG_BASE) ? \ - codec_dosbus_read(buf->reg_base+(r)) : \ - codec_cbus_read(buf->reg_base+(r))) -#define _SET_ST_REG_MASK(r, val) _WRITE_ST_REG(r, _READ_ST_REG(r) | (val)) -#define _CLR_ST_REG_MASK(r, val) _WRITE_ST_REG(r, _READ_ST_REG(r)&~(val)) -#define _READ_VDEC2_ST_REG(r) (codec_dosbus_read(\ - (VDEC2_VLD_MEM_VIFIFO_START_PTR+(r)))) -#define _WRITE_VDEC2_ST_REG(r, val) codec_dosbus_write(\ - (VDEC2_VLD_MEM_VIFIFO_START_PTR+r), val) -#define MEM_BUFCTRL_MANUAL (1<<1) -#define MEM_BUFCTRL_INIT (1<<0) -#define MEM_LEVEL_CNT_BIT 18 -#define MEM_FIFO_CNT_BIT 16 -#define MEM_FILL_ON_LEVEL (1<<10) -#define MEM_CTRL_EMPTY_EN (1<<2) -#define MEM_CTRL_FILL_EN (1<<1) -#define MEM_CTRL_INIT (1<<0) -#endif /* STREAMBUF_REG_H */ diff --git a/drivers/stream_input/parser/thread_rw.c b/drivers/stream_input/parser/thread_rw.c deleted file mode 100644 index deeaf19..0000000 --- a/drivers/stream_input/parser/thread_rw.c +++ b/dev/null @@ -1,606 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/thread_rw.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/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/kfifo.h> -#include <linux/workqueue.h> -#include <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> -#include <linux/uaccess.h> -#include <linux/fs.h> -#include <linux/vmalloc.h> -#include <linux/amlogic/media/codec_mm/codec_mm.h> - -/* #include <mach/am_regs.h> */ -#include <linux/delay.h> - -#include "../../stream_input/parser/streambuf.h" -#include "../../stream_input/amports/amports_priv.h" -#include "thread_rw.h" - -#define BUF_NAME "fetchbuf" - -#define DEFAULT_BLOCK_SIZE (64*1024) - -struct threadrw_buf { - void *vbuffer; - dma_addr_t dma_handle; - int write_off; - int data_size; - int buffer_size; - int from_cma; -}; - -#define MAX_MM_BUFFER_NUM 16 -struct threadrw_write_task { - struct file *file; - struct delayed_work write_work; - DECLARE_KFIFO_PTR(datafifo, void *); - DECLARE_KFIFO_PTR(freefifo, void *); - int bufs_num; - int max_bufs; - int errors; - spinlock_t lock; - struct mutex mutex; - struct stream_buf_s *sbuf; - int buffered_data_size; - int passed_data_len; - int buffer_size; - int def_block_size; - int data_offset; - int writework_on; - unsigned long codec_mm_buffer[MAX_MM_BUFFER_NUM]; - int manual_write; - int failed_onmore; - wait_queue_head_t wq; - ssize_t (*write)(struct file *, - struct stream_buf_s *, - const char __user *, - size_t, int); - struct threadrw_buf buf[1]; - /*don't add any after buf[] define */ -}; - -static int free_task_buffers(struct threadrw_write_task *task); - -static struct workqueue_struct *threadrw_wq_get(void) -{ - static struct workqueue_struct *threadrw_wq; - - if (!threadrw_wq) - threadrw_wq = create_singlethread_workqueue("threadrw"); - return threadrw_wq; -} - -static int threadrw_schedule_delayed_work( - struct threadrw_write_task *task, - unsigned long delay) -{ - bool ret; - - if (threadrw_wq_get()) { - ret = queue_delayed_work(threadrw_wq_get(), - &task->write_work, delay); - } else - ret = schedule_delayed_work(&task->write_work, delay); - if (!ret) { - cancel_delayed_work(&task->write_work); - if (threadrw_wq_get()) - ret = queue_delayed_work(threadrw_wq_get(), - &task->write_work, 0); - else - ret = schedule_delayed_work(&task->write_work, 0); - } - return 0; -} - -static ssize_t threadrw_write_onece( - struct threadrw_write_task *task, - struct file *file, - struct stream_buf_s *stbuf, - const char __user *buf, size_t count) -{ - struct threadrw_buf *rwbuf = NULL; - int ret = 0; - int to_write; - - if (!kfifo_get(&task->freefifo, (void *)&rwbuf)) { - if (task->errors) - return task->errors; - return -EAGAIN; - } - - to_write = min_t(u32, rwbuf->buffer_size, count); - if (copy_from_user(rwbuf->vbuffer, buf, to_write)) { - kfifo_put(&task->freefifo, (const void *)buf); - ret = -EFAULT; - goto err; - } - rwbuf->data_size = to_write; - rwbuf->write_off = 0; - kfifo_put(&task->datafifo, (const void *)rwbuf); - threadrw_schedule_delayed_work(task, 0); - return to_write; -err: - return ret; -} - -static ssize_t threadrw_write_in( - struct threadrw_write_task *task, - struct stream_buf_s *stbuf, - const char __user *buf, size_t count) -{ - int ret = 0; - int off = 0; - int left = count; - int wait_num = 0; - unsigned long flags; - - while (left > 0) { - ret = threadrw_write_onece(task, - task->file, - stbuf, buf + off, left); - if (ret >= left) { - off = count; - left = 0; - } else if (ret > 0) { - off += ret; - left -= ret; - - } else if (ret < 0) { - if (off > 0) { - break; /*have write ok some data. */ - } else if (ret == -EAGAIN) { - if (!(task->file->f_flags & O_NONBLOCK) && - (++wait_num < 10)) { - wait_event_interruptible_timeout( - task->wq, - !kfifo_is_empty( - &task->freefifo), - HZ / 100); - continue; /* write again. */ - } - ret = -EAGAIN; - break; - } - break; /*to end */ - } - } - - /*end: */ - spin_lock_irqsave(&task->lock, flags); - if (off > 0) { - task->buffered_data_size += off; - task->data_offset += off; - } - spin_unlock_irqrestore(&task->lock, flags); - if (off > 0) - return off; - else - return ret; -} - -static int do_write_work_in(struct threadrw_write_task *task) -{ - struct threadrw_buf *rwbuf = NULL; - int ret; - int need_re_write = 0; - int write_len = 0; - unsigned long flags; - - if (kfifo_is_empty(&task->datafifo)) - return 0; - if (!kfifo_peek(&task->datafifo, (void *)&rwbuf)) - return 0; - if (!task->manual_write && - rwbuf->from_cma && - !rwbuf->write_off) - codec_mm_dma_flush(rwbuf->vbuffer, - rwbuf->buffer_size, - DMA_TO_DEVICE); - if (task->manual_write) { - ret = task->write(task->file, task->sbuf, - (const char __user *)rwbuf->vbuffer + rwbuf->write_off, - rwbuf->data_size, - 2); /* noblock,virtual addr */ - } else { - ret = task->write(task->file, task->sbuf, - (const char __user *)rwbuf->dma_handle + rwbuf->write_off, - rwbuf->data_size, - 3); /* noblock,phy addr */ - } - if (ret == -EAGAIN) { - need_re_write = 0; - /*do later retry. */ - } else if (ret >= rwbuf->data_size) { - write_len += rwbuf->data_size; - if (kfifo_get(&task->datafifo, (void *)&rwbuf)) { - rwbuf->data_size = 0; - kfifo_put(&task->freefifo, (const void *)rwbuf); - /*wakeup write thread. */ - wake_up_interruptible(&task->wq); - } else - pr_err("write ok,but kfifo_get data failed.!!!\n"); - need_re_write = 1; - } else if (ret > 0) { - rwbuf->data_size -= ret; /* half data write */ - rwbuf->write_off += ret; - write_len += ret; - need_re_write = 1; - } else { /*ret <=0 */ - pr_err("get errors ret=%d size=%d\n", ret, - rwbuf->data_size); - task->errors = ret; - } - if (write_len > 0) { - spin_lock_irqsave(&task->lock, flags); - task->passed_data_len += write_len; - task->buffered_data_size -= write_len; - spin_unlock_irqrestore(&task->lock, flags); - } - return need_re_write; - -} - -static void do_write_work(struct work_struct *work) -{ - struct threadrw_write_task *task = container_of(work, - struct threadrw_write_task, - write_work.work); - int need_retry = 1; - task->writework_on = 1; - while (need_retry) { - mutex_lock(&task->mutex); - need_retry = do_write_work_in(task); - mutex_unlock(&task->mutex); - } - threadrw_schedule_delayed_work(task, HZ / 10); - task->writework_on = 0; -} - -static int alloc_task_buffers_inlock(struct threadrw_write_task *task, - int new_bubffers, - int block_size) -{ - struct threadrw_buf *rwbuf; - int i; - int used_codec_mm = task->manual_write ? 0 : 1; - int new_num = new_bubffers; - int mm_slot = -1; - int start_idx = task->bufs_num; - int total_mm = 0; - unsigned long addr; - - if (codec_mm_get_total_size() < 80 || - codec_mm_get_free_size() < 40) - used_codec_mm = 0; - if (task->bufs_num + new_num > task->max_bufs) - new_num = task->max_bufs - task->bufs_num; - for (i = 0; i < MAX_MM_BUFFER_NUM; i++) { - if (task->codec_mm_buffer[i] == 0) { - mm_slot = i; - break; - } - } - if (mm_slot < 0) - used_codec_mm = 0; - if (block_size <= 0) - block_size = DEFAULT_BLOCK_SIZE; - - if (used_codec_mm && (block_size * new_num) >= 128 * 1024) { - total_mm = ALIGN(block_size * new_num, (1 << 17)); - addr = - codec_mm_alloc_for_dma(BUF_NAME, - total_mm / PAGE_SIZE, 0, - CODEC_MM_FLAGS_DMA_CPU); - if (addr != 0) { - task->codec_mm_buffer[mm_slot] = addr; - task->buffer_size += total_mm; - } else { - used_codec_mm = 0; - } - } - for (i = 0; i < new_num; i++) { - int bufidx = start_idx + i; - rwbuf = &task->buf[bufidx]; - rwbuf->buffer_size = block_size; - if (used_codec_mm) { - unsigned long start_addr = - task->codec_mm_buffer[mm_slot]; - if (i == new_num - 1) - rwbuf->buffer_size = total_mm - - block_size * i; - rwbuf->dma_handle = (dma_addr_t) start_addr + - block_size * i; - rwbuf->vbuffer = codec_mm_phys_to_virt( - rwbuf->dma_handle); - rwbuf->from_cma = 1; - - } else { - rwbuf->vbuffer = dma_alloc_coherent( - amports_get_dma_device(), - rwbuf->buffer_size, - &rwbuf->dma_handle, GFP_KERNEL); - if (!rwbuf->vbuffer) { - rwbuf->buffer_size = 0; - rwbuf->dma_handle = 0; - task->bufs_num = bufidx; - break; - } - rwbuf->from_cma = 0; - task->buffer_size += rwbuf->buffer_size; - } - - kfifo_put(&task->freefifo, (const void *)rwbuf); - task->bufs_num = bufidx + 1; - } - if (start_idx > 0 ||/*have buffers before*/ - task->bufs_num >= 3 || - task->bufs_num == new_num) { - if (!task->def_block_size) - task->def_block_size = task->buf[0].buffer_size; - return 0; /*must >=3 for swap buffers. */ - } - if (task->bufs_num > 0) - free_task_buffers(task); - return -1; -} - -static int free_task_buffers(struct threadrw_write_task *task) -{ - int i; - for (i = 0; i < MAX_MM_BUFFER_NUM; i++) { - if (task->codec_mm_buffer[i]) - codec_mm_free_for_dma(BUF_NAME, - task->codec_mm_buffer[i]); - } - for (i = 0; i < task->bufs_num; i++) { - if (task->buf[i].vbuffer && task->buf[i].from_cma == 0) - dma_free_coherent(amports_get_dma_device(), - task->buf[i].buffer_size, - task->buf[i].vbuffer, - task->buf[i].dma_handle); - } - return 0; -} - -static struct threadrw_write_task *threadrw_alloc_in(int num, - int block_size, - ssize_t (*write)(struct file *, - struct stream_buf_s *, - const char __user *, size_t, int), - int flags) -{ - int max_bufs = num; - int task_buffer_size; - struct threadrw_write_task *task; - int ret; - - if (!(flags & 1)) /*not audio*/ - max_bufs = 300; /*can great for video bufs.*/ - task_buffer_size = sizeof(struct threadrw_write_task) + - sizeof(struct threadrw_buf) * max_bufs; - task = vmalloc(task_buffer_size); - - if (!task) - return NULL; - memset(task, 0, task_buffer_size); - - spin_lock_init(&task->lock); - mutex_init(&task->mutex); - INIT_DELAYED_WORK(&task->write_work, do_write_work); - init_waitqueue_head(&task->wq); - ret = kfifo_alloc(&task->datafifo, max_bufs, GFP_KERNEL); - if (ret) - goto err1; - ret = kfifo_alloc(&task->freefifo, max_bufs, GFP_KERNEL); - if (ret) - goto err2; - task->write = write; - task->file = NULL; - task->buffer_size = 0; - task->manual_write = flags & 1; - task->max_bufs = max_bufs; - mutex_lock(&task->mutex); - ret = alloc_task_buffers_inlock(task, num, block_size); - mutex_unlock(&task->mutex); - if (ret < 0) - goto err3; - threadrw_wq_get(); /*start thread. */ - return task; - -err3: - kfifo_free(&task->freefifo); -err2: - kfifo_free(&task->datafifo); -err1: - vfree(task); - pr_err("alloc threadrw failed num:%d,block:%d\n", num, block_size); - return NULL; -} - -/* -*fifo data size; -*/ - -int threadrw_buffer_level(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) - return task->buffered_data_size; - return 0; -} - -int threadrw_buffer_size(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) - return task->buffer_size; - return 0; -} - -int threadrw_datafifo_len(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) - return kfifo_len(&task->datafifo); - return 0; -} - -int threadrw_freefifo_len(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) - return kfifo_len(&task->freefifo); - return 0; -} -int threadrw_support_more_buffers(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - if (!task) - return 0; - if (task->failed_onmore) - return 0; - return task->max_bufs - task->bufs_num; -} - -/* -*data len out fifo; -*/ -int threadrw_passed_len(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) - return task->passed_data_len; - return 0; - -} -/* -*all data writed.; -*/ -int threadrw_dataoffset(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - int offset = 0; - - if (task) - return task->data_offset; - return offset; - -} - -ssize_t threadrw_write(struct file *file, struct stream_buf_s *stbuf, - const char __user *buf, size_t count) -{ - struct threadrw_write_task *task = stbuf->write_thread; - ssize_t size; - if (!task->file) { - task->file = file; - task->sbuf = stbuf; - } - mutex_lock(&task->mutex); - size = threadrw_write_in(task, stbuf, buf, count); - mutex_unlock(&task->mutex); - return size; -} - -int threadrw_flush_buffers(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - int max_retry = 20; - - if (!task) - return 0; - while (!kfifo_is_empty(&task->datafifo) && max_retry-- > 0) { - threadrw_schedule_delayed_work(task, 0); - msleep(20); - } - if (!kfifo_is_empty(&task->datafifo)) - return -1;/*data not flushed*/ - return 0; -} -int threadrw_alloc_more_buffer_size( - struct stream_buf_s *stbuf, - int size) -{ - struct threadrw_write_task *task = stbuf->write_thread; - int block_size; - int new_num; - int ret = -1; - int old_num; - - if (!task) - return -1; - mutex_lock(&task->mutex); - block_size = task->def_block_size; - if (block_size == 0) - block_size = 32 * 1024; - new_num = size / block_size; - old_num = task->bufs_num; - if (new_num == 0) - new_num = 1; - else if (new_num > task->max_bufs - task->bufs_num) - new_num = task->max_bufs - task->bufs_num; - if (new_num != 0) - ret = alloc_task_buffers_inlock(task, new_num, - block_size); - mutex_unlock(&task->mutex); - pr_info("threadrw add more buffer from %d -> %d for size %d\n", - old_num, task->bufs_num, - size); - if (ret < 0 || old_num == task->bufs_num) - task->failed_onmore = 1; - return ret; -} - -void *threadrw_alloc(int num, - int block_size, - ssize_t (*write)(struct file *, - struct stream_buf_s *, - const char __user *, - size_t, int), - int flags) -{ - return threadrw_alloc_in(num, block_size, write, flags); -} - -void threadrw_release(struct stream_buf_s *stbuf) -{ - struct threadrw_write_task *task = stbuf->write_thread; - - if (task) { - wake_up_interruptible(&task->wq); - cancel_delayed_work_sync(&task->write_work); - mutex_lock(&task->mutex); - free_task_buffers(task); - mutex_unlock(&task->mutex); - kfifo_free(&task->freefifo); - kfifo_free(&task->datafifo); - vfree(task); - } - stbuf->write_thread = NULL; -} diff --git a/drivers/stream_input/parser/thread_rw.h b/drivers/stream_input/parser/thread_rw.h deleted file mode 100644 index f03a6e6..0000000 --- a/drivers/stream_input/parser/thread_rw.h +++ b/dev/null @@ -1,52 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/thread_rw.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 THREAD_RW_H -#define THREAD_RW_H -#include "../../stream_input/parser/streambuf_reg.h" -#include "../../stream_input/parser/streambuf.h" -#include "../../stream_input/parser/esparser.h" -#include "../../stream_input/amports/amports_priv.h" - -ssize_t threadrw_write(struct file *file, - struct stream_buf_s *stbuf, - const char __user *buf, - size_t count); - -void *threadrw_alloc(int num, - int block_size, - ssize_t (*write)(struct file *, - struct stream_buf_s *, - const char __user *, - size_t, int), - int flags);/*flags &1: manual mode*/ - -void threadrw_release(struct stream_buf_s *stbuf); - -int threadrw_buffer_level(struct stream_buf_s *stbuf); -int threadrw_buffer_size(struct stream_buf_s *stbuf); -int threadrw_datafifo_len(struct stream_buf_s *stbuf); -int threadrw_freefifo_len(struct stream_buf_s *stbuf); -int threadrw_passed_len(struct stream_buf_s *stbuf); -int threadrw_flush_buffers(struct stream_buf_s *stbuf); -int threadrw_dataoffset(struct stream_buf_s *stbuf); -int threadrw_alloc_more_buffer_size( - struct stream_buf_s *stbuf, - int size); -int threadrw_support_more_buffers(struct stream_buf_s *stbuf); - -#endif diff --git a/drivers/stream_input/parser/tsdemux.c b/drivers/stream_input/parser/tsdemux.c deleted file mode 100644 index ba9a590..0000000 --- a/drivers/stream_input/parser/tsdemux.c +++ b/dev/null @@ -1,1131 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/tsdemux.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/types.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/dma-mapping.h> -#include <linux/amlogic/media/frame_sync/ptsserv.h> -#include <linux/amlogic/media/utils/amstream.h> -#include <linux/amlogic/media/vfm/vframe_provider.h> -#include <linux/device.h> -#include <linux/delay.h> - -#include <linux/uaccess.h> -/* #include <mach/am_regs.h> */ -#include <linux/clk.h> -/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ -/* #include <mach/mod_gate.h> */ -/* #endif */ - -#include "../../frame_provider/decoder/utils/vdec.h" -#include <linux/amlogic/media/utils/vdec_reg.h> -#include "streambuf_reg.h" -#include "streambuf.h" -#include <linux/amlogic/media/utils/amports_config.h> - -#include "tsdemux.h" -#include <linux/reset.h> -#include "../amports/amports_priv.h" - - -static const char tsdemux_fetch_id[] = "tsdemux-fetch-id"; -static const char tsdemux_irq_id[] = "tsdemux-irq-id"; - -static u32 curr_pcr_num = 0xffff; -static u32 curr_vid_id = 0xffff; -static u32 curr_aud_id = 0xffff; -static u32 curr_sub_id = 0xffff; -static u32 curr_pcr_id = 0xffff; - -static DECLARE_WAIT_QUEUE_HEAD(wq); -static u32 fetch_done; -static u32 discontinued_counter; -static u32 first_pcr; -static u8 pcrscr_valid; - -static int demux_skipbyte; - -static struct tsdemux_ops *demux_ops; -static DEFINE_SPINLOCK(demux_ops_lock); - -static int enable_demux_driver(void) -{ -#ifdef ENABLE_DEMUX_DRIVER - return demux_ops ? 1 : 0; -#else - return 0; -#endif -} - -void tsdemux_set_ops(struct tsdemux_ops *ops) -{ - unsigned long flags; - - spin_lock_irqsave(&demux_ops_lock, flags); - demux_ops = ops; - spin_unlock_irqrestore(&demux_ops_lock, flags); -} -EXPORT_SYMBOL(tsdemux_set_ops); - -int tsdemux_set_reset_flag_ext(void) -{ - int r = 0; - - if (demux_ops && demux_ops->set_reset_flag) - r = demux_ops->set_reset_flag(); - - return r; -} - -int tsdemux_set_reset_flag(void) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&demux_ops_lock, flags); - r = tsdemux_set_reset_flag_ext(); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_reset(void) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->reset) { - tsdemux_set_reset_flag_ext(); - r = demux_ops->reset(); - } - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_request_irq(irq_handler_t handler, void *data) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->request_irq) - r = demux_ops->request_irq(handler, data); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_free_irq(void) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->free_irq) - r = demux_ops->free_irq(); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_set_vid(int vpid) -{ - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_vid) - r = demux_ops->set_vid(vpid); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_set_aid(int apid) -{ - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_aid) - r = demux_ops->set_aid(apid); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_set_sid(int spid) -{ - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_sid) - r = demux_ops->set_sid(spid); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_set_pcrid(int pcrpid) -{ - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_pcrid) - r = demux_ops->set_pcrid(pcrpid); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_set_skip_byte(int skipbyte) -{ - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_skipbyte) - r = demux_ops->set_skipbyte(skipbyte); - spin_unlock_irqrestore(&demux_ops_lock, flags); - - return r; -} - -static int tsdemux_config(void) -{ - return 0; -} - -/*TODO irq*/ -static irqreturn_t tsdemux_isr(int irq, void *dev_id) -{ - u32 int_status = 0; - int id = (long)dev_id; - - if (!enable_demux_driver()) { - int_status = READ_MPEG_REG(STB_INT_STATUS); - } else { - if (id == 0) - int_status = READ_MPEG_REG(STB_INT_STATUS); - else if (id == 1) - int_status = READ_MPEG_REG(STB_INT_STATUS_2); - else if (id == 2) - int_status = READ_MPEG_REG(STB_INT_STATUS_3); - } - - if (int_status & (1 << NEW_PDTS_READY)) { - if (!enable_demux_driver()) { - u32 pdts_status = READ_MPEG_REG(STB_PTS_DTS_STATUS); - - if (pdts_status & (1 << VIDEO_PTS_READY)) - pts_checkin_wrptr(PTS_TYPE_VIDEO, - READ_MPEG_REG(VIDEO_PDTS_WR_PTR), - READ_MPEG_REG(VIDEO_PTS_DEMUX)); - - if (pdts_status & (1 << AUDIO_PTS_READY)) - pts_checkin_wrptr(PTS_TYPE_AUDIO, - READ_MPEG_REG(AUDIO_PDTS_WR_PTR), - READ_MPEG_REG(AUDIO_PTS_DEMUX)); - - WRITE_MPEG_REG(STB_PTS_DTS_STATUS, pdts_status); - } else { -#define DMX_READ_REG(i, r)\ - ((i) ? ((i == 1) ? READ_MPEG_REG(r##_2) : \ - READ_MPEG_REG(r##_3)) : READ_MPEG_REG(r)) - - u32 pdts_status = DMX_READ_REG(id, STB_PTS_DTS_STATUS); - - if (pdts_status & (1 << VIDEO_PTS_READY)) - pts_checkin_wrptr(PTS_TYPE_VIDEO, - DMX_READ_REG(id, VIDEO_PDTS_WR_PTR), - DMX_READ_REG(id, VIDEO_PTS_DEMUX)); - - if (pdts_status & (1 << AUDIO_PTS_READY)) - pts_checkin_wrptr(PTS_TYPE_AUDIO, - DMX_READ_REG(id, AUDIO_PDTS_WR_PTR), - DMX_READ_REG(id, AUDIO_PTS_DEMUX)); - - if (id == 1) - WRITE_MPEG_REG(STB_PTS_DTS_STATUS_2, - pdts_status); - else if (id == 2) - WRITE_MPEG_REG(STB_PTS_DTS_STATUS_3, - pdts_status); - else - WRITE_MPEG_REG(STB_PTS_DTS_STATUS, - pdts_status); - } - } - if (int_status & (1 << DIS_CONTINUITY_PACKET)) { - discontinued_counter++; - /* pr_info("discontinued counter=%d\n",discontinued_counter); */ - } - if (int_status & (1 << SUB_PES_READY)) { - /* TODO: put data to somewhere */ - /* pr_info("subtitle pes ready\n"); */ - wakeup_sub_poll(); - } - - if (!enable_demux_driver()) - WRITE_MPEG_REG(STB_INT_STATUS, int_status); - - return IRQ_HANDLED; -} - -static irqreturn_t parser_isr(int irq, void *dev_id) -{ - u32 int_status = READ_MPEG_REG(PARSER_INT_STATUS); - - WRITE_MPEG_REG(PARSER_INT_STATUS, int_status); - - if (int_status & PARSER_INTSTAT_FETCH_CMD) { - fetch_done = 1; - - wake_up_interruptible(&wq); - } - - return IRQ_HANDLED; -} - -static ssize_t _tsdemux_write(const char __user *buf, size_t count, - int isphybuf) -{ - size_t r = count; - const char __user *p = buf; - u32 len; - int ret; - dma_addr_t dma_addr = 0; - - if (r > 0) { - if (isphybuf) - len = count; - else { - len = min_t(size_t, r, FETCHBUF_SIZE); - if (copy_from_user(fetchbuf, p, len)) - return -EFAULT; - - dma_addr = - dma_map_single(amports_get_dma_device(), - fetchbuf, - FETCHBUF_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(amports_get_dma_device(), - dma_addr)) - return -EFAULT; - - - } - - fetch_done = 0; - - wmb(); /* Ensure fetchbuf contents visible */ - - if (isphybuf) { - u32 buf_32 = (unsigned long)buf & 0xffffffff; - - WRITE_MPEG_REG(PARSER_FETCH_ADDR, buf_32); - } else { - WRITE_MPEG_REG(PARSER_FETCH_ADDR, dma_addr); - dma_unmap_single(amports_get_dma_device(), dma_addr, - FETCHBUF_SIZE, DMA_TO_DEVICE); - } - - WRITE_MPEG_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len); - - - ret = - wait_event_interruptible_timeout(wq, fetch_done != 0, - HZ / 2); - if (ret == 0) { - WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); - pr_info("write timeout, retry\n"); - return -EAGAIN; - } else if (ret < 0) - return -ERESTARTSYS; - - p += len; - r -= len; - } - - return count - r; -} - -static int reset_pcr_regs(void) -{ - u32 pcr_num; - - if (curr_pcr_id >= 0x1FFF) - return 0; - - /* set parameter to fetch pcr */ - pcr_num = 0; - if (curr_pcr_id == curr_vid_id) - pcr_num = 0; - else if (curr_pcr_id == curr_aud_id) - pcr_num = 1; - else if (curr_pcr_id == curr_sub_id) - pcr_num = 2; - else - pcr_num = 3; - - if (pcr_num != curr_pcr_num) { - u32 clk_unit = 0; - u32 clk_81 = 0; - struct clk *clk; - - clk = clk_get_sys("clk81", "clk81"); - if (IS_ERR(clk) || clk == 0) { - pr_info("[%s:%d] error clock\n", __func__, - __LINE__); - return 0; - } - - clk_81 = clk_get_rate(clk); - clk_unit = clk_81 / 80000; - - pr_info("[%s:%d] clk_81 = %x clk_unit =%x\n", __func__, - __LINE__, clk_81, clk_unit); - - if (READ_MPEG_REG(TS_HIU_CTL_2) & 0x80) { - WRITE_MPEG_REG(PCR90K_CTL_2, (12 << 1) | clk_unit); - WRITE_MPEG_REG(ASSIGN_PID_NUMBER_2, pcr_num); - pr_info("[tsdemux_init] To use device 2,pcr_num=%d\n", - pcr_num); - } else if (READ_MPEG_REG(TS_HIU_CTL_3) & 0x80) { - WRITE_MPEG_REG(PCR90K_CTL_3, (12 << 1) | clk_unit); - WRITE_MPEG_REG(ASSIGN_PID_NUMBER_3, pcr_num); - pr_info("[tsdemux_init] To use device 3,pcr_num=%d\n", - pcr_num); - } else { - WRITE_MPEG_REG(PCR90K_CTL, (12 << 1) | clk_unit); - WRITE_MPEG_REG(ASSIGN_PID_NUMBER, pcr_num); - pr_info("[tsdemux_init] To use device 1,pcr_num=%d\n", - pcr_num); - } - - curr_pcr_num = pcr_num; - } - - return 1; -} - -s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc, - struct vdec_s *vdec) -{ - s32 r; - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - u32 parser_sub_rp; - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - /*TODO clk */ - /* - *switch_mod_gate_by_type(MOD_DEMUX, 1); - */ - /* #endif */ - - amports_switch_gate("demux", 1); - - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP); - - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); - - if (enable_demux_driver()) { - tsdemux_reset(); - } else { - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB); - - WRITE_MPEG_REG(STB_TOP_CONFIG, 0); - WRITE_MPEG_REG(DEMUX_CONTROL, 0); - } - - /* set PID filter */ - pr_info - ("tsdemux video_pid = 0x%x, audio_pid = 0x%x,", - vid, aid); - pr_info - ("sub_pid = 0x%x, pcrid = 0x%x\n", - sid, pcrid); - - if (!enable_demux_driver()) { - WRITE_MPEG_REG(FM_WR_DATA, - (((vid < 0x1fff) - ? (vid & 0x1fff) | (VIDEO_PACKET << 13) - : 0xffff) << 16) - | ((aid < 0x1fff) - ? (aid & 0x1fff) | (AUDIO_PACKET << 13) - : 0xffff)); - WRITE_MPEG_REG(FM_WR_ADDR, 0x8000); - while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) - ; - - WRITE_MPEG_REG(FM_WR_DATA, - (((sid < 0x1fff) - ? (sid & 0x1fff) | (SUB_PACKET << 13) - : 0xffff) << 16) - | 0xffff); - WRITE_MPEG_REG(FM_WR_ADDR, 0x8001); - while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) - ; - - WRITE_MPEG_REG(MAX_FM_COMP_ADDR, 1); - - WRITE_MPEG_REG(STB_INT_MASK, 0); - WRITE_MPEG_REG(STB_INT_STATUS, 0xffff); - - /* TS data path */ - WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0x7000); - WRITE_MPEG_REG(DEMUX_MEM_REQ_EN, - (1 << VIDEO_PACKET) | - (1 << AUDIO_PACKET) | (1 << SUB_PACKET)); - WRITE_MPEG_REG(DEMUX_ENDIAN, - (7 << OTHER_ENDIAN) | - (7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN)); - WRITE_MPEG_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE); - WRITE_MPEG_REG(TS_FILE_CONFIG, - (demux_skipbyte << 16) | - (6 << DES_OUT_DLY) | - (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) | - (1 << TS_HIU_ENABLE) | (4 << FEC_FILE_CLK_DIV)); - - /* enable TS demux */ - WRITE_MPEG_REG(DEMUX_CONTROL, - (1 << STB_DEMUX_ENABLE) | - (1 << KEEP_DUPLICATE_PACKAGE)); - } - - if (fetchbuf == 0) { - pr_info("%s: no fetchbuf\n", __func__); - return -ENOMEM; - } - - /* hook stream buffer with PARSER */ - if (has_hevc_vdec() && is_hevc) { - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, vdec->input.start + - vdec->input.size - 8); - - if (vdec_single(vdec)) { - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - /* set vififo_vbuf_rp_sel=>hevc */ - WRITE_VREG(DOS_GEN_CTRL0, 3 << 1); - /* set use_parser_vbuf_wp */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, - (1 << 3) | (0 << 4)); - /* set stream_fetch_enable */ - SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); - /* set stream_buffer_hole with 256 bytes */ - SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, - (1 << 29)); - } else { - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_RP, vdec->input.start); - } - } else - /* #endif */ - { - WRITE_MPEG_REG(PARSER_VIDEO_START_PTR, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_END_PTR, vdec->input.start + - vdec->input.size - 8); - - if (vdec_single(vdec)) { - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, - ES_VID_MAN_RD_PTR); - - WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, - MEM_BUFCTRL_INIT); - /* set vififo_vbuf_rp_sel=>vdec */ - if (has_hevc_vdec()) - WRITE_VREG(DOS_GEN_CTRL0, 0); - } else { - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, vdec->input.start); - WRITE_MPEG_REG(PARSER_VIDEO_RP, vdec->input.start); - } - } - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(PARSER_CONFIG, - (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) | - (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) | - (16 << PS_CFG_MAX_FETCH_CYCLE_BIT)); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if (has_hevc_vdec()) - r = pts_start((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO); - else - /* #endif */ - r = pts_start(PTS_TYPE_VIDEO); - - if (r < 0) { - pr_info("Video pts start failed.(%d)\n", r); - goto err1; - } - r = pts_start(PTS_TYPE_AUDIO); - if (r < 0) { - pr_info("Audio pts start failed.(%d)\n", r); - goto err2; - } - /*TODO irq */ - - r = vdec_request_irq(PARSER_IRQ, parser_isr, - "tsdemux-fetch", (void *)tsdemux_fetch_id); - - if (r) - goto err3; - - WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff); - WRITE_MPEG_REG(PARSER_INT_ENABLE, - PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT); - - WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0x400); - WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0x400); - - discontinued_counter = 0; - - if (!enable_demux_driver()) { - /*TODO irq */ - - r = vdec_request_irq(DEMUX_IRQ, tsdemux_isr, - "tsdemux-irq", (void *)tsdemux_irq_id); - - WRITE_MPEG_REG(STB_INT_MASK, (1 << SUB_PES_READY) - | (1 << NEW_PDTS_READY) - | (1 << DIS_CONTINUITY_PACKET)); - if (r) - goto err4; - } else { - tsdemux_config(); - tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id); - if (vid < 0x1FFF) { - curr_vid_id = vid; - tsdemux_set_vid(vid); - } - if (aid < 0x1FFF) { - curr_aud_id = aid; - tsdemux_set_aid(aid); - } - if (sid < 0x1FFF) { - curr_sub_id = sid; - tsdemux_set_sid(sid); - } - - curr_pcr_id = pcrid; - if ((pcrid < 0x1FFF) && (pcrid != vid) && (pcrid != aid) - && (pcrid != sid)) - tsdemux_set_pcrid(pcrid); - } - - pcrscr_valid = reset_pcr_regs(); - first_pcr = 0; - - return 0; - -err4: - /*TODO irq */ - - if (!enable_demux_driver()) - vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id); - -err3: - pts_stop(PTS_TYPE_AUDIO); -err2: - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ - if (has_hevc_vdec()) - pts_stop((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO); - else - /* #endif */ - pts_stop(PTS_TYPE_VIDEO); -err1: - pr_info("TS Demux init failed.\n"); - return -ENOENT; -} - -void tsdemux_release(void) -{ - pcrscr_valid = 0; - first_pcr = 0; - - WRITE_MPEG_REG(PARSER_INT_ENABLE, 0); - WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0); - WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0); - -#ifdef CONFIG_MULTI_DEC - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR); - WRITE_MPEG_REG(PARSER_VIDEO_WP, 0); - WRITE_MPEG_REG(PARSER_VIDEO_RP, 0); -#endif - - /*TODO irq */ - - vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id); - - if (!enable_demux_driver()) { - WRITE_MPEG_REG(STB_INT_MASK, 0); - /*TODO irq */ - - vdec_free_irq(DEMUX_IRQ, (void *)tsdemux_irq_id); - } else { - - tsdemux_set_aid(0xffff); - tsdemux_set_vid(0xffff); - tsdemux_set_sid(0xffff); - tsdemux_set_pcrid(0xffff); - tsdemux_free_irq(); - - curr_vid_id = 0xffff; - curr_aud_id = 0xffff; - curr_sub_id = 0xffff; - curr_pcr_id = 0xffff; - curr_pcr_num = 0xffff; - } - - pts_stop(PTS_TYPE_VIDEO); - pts_stop(PTS_TYPE_AUDIO); - - WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER); - - /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ - /*TODO clk */ - /* - *switch_mod_gate_by_type(MOD_DEMUX, 0); - */ - /* #endif */ - amports_switch_gate("demux", 0); - -} - -static int limited_delay_check(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count) -{ - int write_size; - - if (vbuf->max_buffer_delay_ms > 0 && abuf->max_buffer_delay_ms > 0 && - stbuf_level(vbuf) > 1024 && stbuf_level(abuf) > 256) { - int vdelay = - calculation_stream_delayed_ms(PTS_TYPE_VIDEO, - NULL, NULL); - int adelay = - calculation_stream_delayed_ms(PTS_TYPE_AUDIO, - NULL, NULL); - /*max wait 100ms,if timeout,try again top level. */ - int maxretry = 10; - /*too big delay,do wait now. */ - /*if noblock mode,don't do wait. */ - if (!(file->f_flags & O_NONBLOCK)) { - while (vdelay > vbuf->max_buffer_delay_ms - && adelay > abuf->max_buffer_delay_ms - && maxretry-- > 0) { - msleep(20); - vdelay = - calculation_stream_delayed_ms - (PTS_TYPE_VIDEO, NULL, NULL); - adelay = - calculation_stream_delayed_ms - (PTS_TYPE_AUDIO, NULL, NULL); - } - } - if (vdelay > vbuf->max_buffer_delay_ms - && adelay > abuf->max_buffer_delay_ms) - return 0; - } - write_size = min(stbuf_space(vbuf), stbuf_space(abuf)); - write_size = min_t(int, count, write_size); - return write_size; -} - -ssize_t drm_tswrite(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count) -{ - s32 r; - u32 realcount = count; - u32 re_count = count; - u32 havewritebytes = 0; - - struct drm_info tmpmm; - struct drm_info *drm = &tmpmm; - u32 res = 0; - int isphybuf = 0; - unsigned long realbuf; - - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - size_t wait_size, write_size; - - if (buf == NULL || count == 0) - return -EINVAL; - - res = copy_from_user(drm, buf, sizeof(struct drm_info)); - if (res) { - pr_info("drm kmalloc failed res[%d]\n", res); - return -EFAULT; - } - - if (drm->drm_flag == TYPE_DRMINFO && drm->drm_level == DRM_LEVEL1) { - /* buf only has drminfo not have esdata; */ - realcount = drm->drm_pktsize; - realbuf = drm->drm_phy; - isphybuf = 1; - } else - realbuf = (unsigned long)buf; - /* pr_info("drm->drm_flag = 0x%x,realcount = %d , buf = 0x%x ",*/ - /*drm->drm_flag,realcount, buf); */ - - count = realcount; - - while (count > 0) { - if ((stbuf_space(vbuf) < count) || - (stbuf_space(abuf) < count)) { - if (file->f_flags & O_NONBLOCK) { - int v_stbuf_space = stbuf_space(vbuf); - int a_stbuf_space = stbuf_space(abuf); - - write_size = min(v_stbuf_space, a_stbuf_space); - /*have 188 bytes,write now., */ - if (write_size <= 188) - return -EAGAIN; - } else { - wait_size = - min(stbuf_canusesize(vbuf) / 8, - stbuf_canusesize(abuf) / 4); - if ((port->flag & PORT_FLAG_VID) - && (stbuf_space(vbuf) < wait_size)) { - r = stbuf_wait_space(vbuf, wait_size); - - if (r < 0) { - pr_info - ("write no space--- "); - pr_info - ("no space,%d--%d,r-%d\n", - stbuf_space(vbuf), - stbuf_space(abuf), r); - return r; - } - } - - if ((port->flag & PORT_FLAG_AID) - && (stbuf_space(abuf) < wait_size)) { - r = stbuf_wait_space(abuf, wait_size); - - if (r < 0) { - pr_info - ("write no stbuf_wait_space--"); - pr_info - ("no space,%d--%d,r-%d\n", - stbuf_space(vbuf), - stbuf_space(abuf), r); - return r; - } - } - } - } - - write_size = min(stbuf_space(vbuf), stbuf_space(abuf)); - write_size = min(count, write_size); - /* pr_info("write_size = %d,count = %d,\n",*/ - /*write_size, count); */ - if (write_size > 0) - r = _tsdemux_write((const char __user *)realbuf, - write_size, isphybuf); - else - return -EAGAIN; - - havewritebytes += r; - - /* pr_info("havewritebytes = %d, r = %d,\n",*/ - /*havewritebytes, r); */ - if (havewritebytes == realcount) - break; /* write ok; */ - else if (havewritebytes > realcount) - pr_info(" error ! write too much\n"); - - count -= r; - } - return re_count; -} - -ssize_t tsdemux_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count) -{ - s32 r; - struct port_priv_s *priv = (struct port_priv_s *)file->private_data; - struct stream_port_s *port = priv->port; - size_t wait_size, write_size; - - if ((stbuf_space(vbuf) < count) || (stbuf_space(abuf) < count)) { - if (file->f_flags & O_NONBLOCK) { - write_size = min(stbuf_space(vbuf), stbuf_space(abuf)); - if (write_size <= 188) /*have 188 bytes,write now., */ - return -EAGAIN; - } else { - wait_size = - min(stbuf_canusesize(vbuf) / 8, - stbuf_canusesize(abuf) / 4); - if ((port->flag & PORT_FLAG_VID) - && (stbuf_space(vbuf) < wait_size)) { - r = stbuf_wait_space(vbuf, wait_size); - - if (r < 0) { - /* pr_info("write no space--- "); - pr_info("no space,%d--%d,r-%d\n", - stbuf_space(vbuf), - stbuf_space(abuf),r); */ - return r; - } - } - - if ((port->flag & PORT_FLAG_AID) - && (stbuf_space(abuf) < wait_size)) { - r = stbuf_wait_space(abuf, wait_size); - - if (r < 0) { - /* pr_info("write no stbuf_wait_space")' - pr_info{"--- no space,%d--%d,r-%d\n", - stbuf_space(vbuf), - stbuf_space(abuf),r); */ - return r; - } - } - } - } - vbuf->last_write_jiffies64 = jiffies_64; - abuf->last_write_jiffies64 = jiffies_64; - write_size = limited_delay_check(file, vbuf, abuf, buf, count); - if (write_size > 0) - return _tsdemux_write(buf, write_size, 0); - else - return -EAGAIN; -} - -static ssize_t show_discontinue_counter(struct class *class, - struct class_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", discontinued_counter); -} - -static struct class_attribute tsdemux_class_attrs[] = { - __ATTR(discontinue_counter, S_IRUGO, show_discontinue_counter, NULL), - __ATTR_NULL -}; - -static struct class tsdemux_class = { - .name = "tsdemux", - .class_attrs = tsdemux_class_attrs, - }; - -int tsdemux_class_register(void) -{ - int r = class_register(&tsdemux_class); - - if (r < 0) - pr_info("register tsdemux class error!\n"); - discontinued_counter = 0; - return r; -} - -void tsdemux_class_unregister(void) -{ - class_unregister(&tsdemux_class); -} - -void tsdemux_change_avid(unsigned int vid, unsigned int aid) -{ - if (!enable_demux_driver()) { - WRITE_MPEG_REG(FM_WR_DATA, - (((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16) - | ((aid & 0x1fff) | (AUDIO_PACKET << 13))); - WRITE_MPEG_REG(FM_WR_ADDR, 0x8000); - while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) - ; - } else { - curr_vid_id = vid; - curr_aud_id = aid; - - tsdemux_set_vid(vid); - tsdemux_set_aid(aid); - - reset_pcr_regs(); - } - -} - -void tsdemux_change_sid(unsigned int sid) -{ - if (!enable_demux_driver()) { - WRITE_MPEG_REG(FM_WR_DATA, - (((sid & 0x1fff) | (SUB_PACKET << 13)) << 16) - | 0xffff); - WRITE_MPEG_REG(FM_WR_ADDR, 0x8001); - while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) - ; - } else { - curr_sub_id = sid; - - tsdemux_set_sid(sid); - - reset_pcr_regs(); - } - -} - -void tsdemux_audio_reset(void) -{ - ulong flags; - - DEFINE_SPINLOCK(lock); - - spin_lock_irqsave(&lock, flags); - - WRITE_MPEG_REG(PARSER_AUDIO_WP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_RP, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - - WRITE_MPEG_REG(PARSER_AUDIO_START_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR)); - WRITE_MPEG_REG(PARSER_AUDIO_END_PTR, - READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)); - CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR); - - WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT); - - spin_unlock_irqrestore(&lock, flags); - -} - -void tsdemux_sub_reset(void) -{ - ulong flags; - DEFINE_SPINLOCK(lock); - u32 parser_sub_start_ptr; - u32 parser_sub_end_ptr; - - spin_lock_irqsave(&lock, flags); - - parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR); - parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR); - - WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr); - WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr); - WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr); - SET_MPEG_REG_MASK(PARSER_ES_CONTROL, - (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR); - - spin_unlock_irqrestore(&lock, flags); - -} - -void tsdemux_set_skipbyte(int skipbyte) -{ - if (!enable_demux_driver()) - demux_skipbyte = skipbyte; - else - tsdemux_set_skip_byte(skipbyte); - -} - -void tsdemux_set_demux(int dev) -{ - if (enable_demux_driver()) { - unsigned long flags; - int r = 0; - - spin_lock_irqsave(&demux_ops_lock, flags); - if (demux_ops && demux_ops->set_demux) - r = demux_ops->set_demux(dev); - spin_unlock_irqrestore(&demux_ops_lock, flags); - } -} - -u32 tsdemux_pcrscr_get(void) -{ - u32 pcr = 0; - - if (pcrscr_valid == 0) - return 0; - - if (READ_MPEG_REG(TS_HIU_CTL_2) & 0x80) - pcr = READ_MPEG_REG(PCR_DEMUX_2); - else if (READ_MPEG_REG(TS_HIU_CTL_3) & 0x80) - pcr = READ_MPEG_REG(PCR_DEMUX_3); - else - pcr = READ_MPEG_REG(PCR_DEMUX); - if (first_pcr == 0) - first_pcr = pcr; - return pcr; -} - -u32 tsdemux_first_pcrscr_get(void) -{ - if (pcrscr_valid == 0) - return 0; - - if (first_pcr == 0) { - u32 pcr; - - if (READ_MPEG_REG(TS_HIU_CTL_2) & 0x80) - pcr = READ_MPEG_REG(PCR_DEMUX_2); - else if (READ_MPEG_REG(TS_HIU_CTL_3) & 0x80) - pcr = READ_MPEG_REG(PCR_DEMUX_3); - else - pcr = READ_MPEG_REG(PCR_DEMUX); - first_pcr = pcr; - /* pr_info("set first_pcr = 0x%x\n", pcr); */ - } - - return first_pcr; -} - -u8 tsdemux_pcrscr_valid(void) -{ - return pcrscr_valid; -} diff --git a/drivers/stream_input/parser/tsdemux.h b/drivers/stream_input/parser/tsdemux.h deleted file mode 100644 index 5e11c44..0000000 --- a/drivers/stream_input/parser/tsdemux.h +++ b/dev/null @@ -1,95 +0,0 @@ -/* - * drivers/amlogic/media/stream_input/parser/tsdemux.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 TSDEMUX_H -#define TSDEMUX_H -#include <linux/amlogic/media/utils/amports_config.h> - -/* TODO: move to register headers */ -#define NEW_PDTS_READY 4 -#define AUDIO_PTS_READY 2 -#define VIDEO_PTS_READY 0 -#define DIS_CONTINUITY_PACKET 6 -#define SUB_PES_READY 7 - -#define PARSER_INTSTAT_FETCH_CMD (1<<7) - -#define FETCH_ENDIAN 27 -#define FETCH_ENDIAN_MASK (0x7<<27) - -#define RESET_DEMUXSTB (1<<1) -#define RESET_PARSER (1<<8) - -#define VIDEO_PACKET 0 -#define AUDIO_PACKET 1 -#define SUB_PACKET 2 - -#define OTHER_ENDIAN 6 -#define BYPASS_ENDIAN 3 -#define SECTION_ENDIAN 0 - -#define USE_HI_BSF_INTERFACE 7 -#define DES_OUT_DLY 8 -#define TRANSPORT_SCRAMBLING_CONTROL_ODD 6 -#define TS_HIU_ENABLE 5 -#define FEC_FILE_CLK_DIV 0 -#define STB_DEMUX_ENABLE 4 -#define KEEP_DUPLICATE_PACKAGE 6 - -#define ES_VID_MAN_RD_PTR (1<<0) -#define ES_AUD_MAN_RD_PTR (1<<4) - -#define PS_CFG_PFIFO_EMPTY_CNT_BIT 16 -#define PS_CFG_MAX_ES_WR_CYCLE_BIT 12 -#define PS_CFG_MAX_FETCH_CYCLE_BIT 0 - -#define ES_SUB_WR_ENDIAN_BIT 9 -#define ES_SUB_MAN_RD_PTR (1<<8) -#define PARSER_INTSTAT_FETCH_CMD (1<<7) - -#define PARSER_INT_HOST_EN_BIT 8 - -struct stream_buf_s; -struct vdec_s; - -extern s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc, - struct vdec_s *vdec); - -extern void tsdemux_release(void); -extern ssize_t drm_tswrite(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count); - -extern ssize_t tsdemux_write(struct file *file, - struct stream_buf_s *vbuf, - struct stream_buf_s *abuf, - const char __user *buf, size_t count); - -extern u32 tsdemux_pcrscr_get(void); -extern u8 tsdemux_pcrscr_valid(void); -extern u32 tsdemux_first_pcrscr_get(void); - -int tsdemux_class_register(void); -void tsdemux_class_unregister(void); -void tsdemux_change_avid(unsigned int vid, unsigned int aid); -void tsdemux_change_sid(unsigned int sid); -void tsdemux_audio_reset(void); -void tsdemux_sub_reset(void); -void tsdemux_set_skipbyte(int skipbyte); -void tsdemux_set_demux(int dev); -#endif /* TSDEMUX_H */ diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin deleted file mode 100644 index e495e37..0000000 --- a/firmware/video_ucode.bin +++ b/dev/null @@ -1,8294 +0,0 @@ -KCAP - - - -B< - - -?@ - -ɑ -GL @x - - -Ox -PxLx - - - - - -) - -J@ -
J -.8 - -GI , -O -I@ -I - -o -I@ -=Lʀ -I - bp - - - - -Q RPPCL - -@J -A -A -& -% -( -\ -!p! - -J - - - - -LJ - -a -A - -xJ e -B -a -@ xH - - - H G -G@ -` -xM` - -x
- -xoG` -@x@xy - QL -FL@LBLȂ@ -G - - -q@ - - - - - - t - - - - -Iʁ - - - - -B@Ȃ - - - - - - - - -G - -GI -I -d - -` -@x -$ - - - -@x$@ -W(Ǥ -*e@-UU -\!@xU@-U -¢V - -@TeP W| NB -EE@ -BV -@@xAՀe -&N U -TeP W| NB -U@%$U@x$&) -bV -`aV0 -&N U'$ - - -$` - - - - - u V,E -@ - - -B -@A
Ǡ - -A - - -@@x -NNN@ - - -@@ II24 A" - - Iɐ ɐ @ I - -@I@ -I - -K -K -< -` -xJ - -xIǀ! -< -J - -xJ -xJ -G2 -H" - - -2 -xJ -3@ -G4 - - -~ $ -H -! - -N,@x - -@x - -c - x.I,J) -` -,@ -I -,@Ȅ@ -,
- -@ǠA+,- - -@ -G -;H -% -< - I - - - H -H@a - - -;I - - - - -GǑ@ʡ - -GH;ȡ@ʡ - - -G @@@ - -G - -G @@ - -G @ -I; -B - J -J - -J9 -@b -; - - - - -!sstG -@b - -GuuG - -@b - - -~ - - -o - - -H - $ɀ -@Ip p QIs Q #G)!D G)d - -P;! - - - - - - - - - -G,",@a -QI - - -Q -? -R - - - -ȼo - -@ -G - -G# -# -q@)#q s -s s -' -L! o -!*! -G) -))Wx@Ix -))@%xx -G) -))OxAx -))x -G$) - - -$ -@o - - - -'x 'LI! &'()) a ' 'LI! H$ a ' CI#x%>?L> @ -#LGB0 -@ -@ -* - - - @o -I@ -((#LB0 o - - A R K -(@xGB -%B -G -H - -` -x - - - - -S@& NI HB -@ -N @o -@N @n -$m - -G$) - -' -'x 'LI! &') a ' 'LI! H$ a '#%$ -o - -!L"L%'Le! ,a -* -$ʀ - - - -( -%&&&r !G%@ -G - -S& -] - -* - -$ @o -&I@b&@x* H"P !&% - - -, - --xB - -G - --J -Fa - - - -+ - - -f -J+J - - -Q -? -RP -@#\ a -L+L -@4 -x, -I@ ` - @I,Db -@x --J - - +-G% -! - --J+ - -x -! - + - @a - -x - b@ʢ c -$"L2@ - - - -CALc -AA K)` -! - - -@ -a $a ' - N, -?G)á -,@ǠA+ -+?aǠA+PCG - - - -ߏN LJ -J2x -@Ȇ - -0 -` - - - - 1 -@ -M*@I -G - *,@ -@@ -M*@I - *,@ -@ -M*@I - -ql -@0 -G - ,@ -@@0 - ,@ -@0 -qp - -qp -` - -qIq - - -J -O+ -a
` -z - -."@ -o@l - -J - -O+ - -a
` -z - -."@ -o@l - -G@@ - - - - - -H -Hs - - -@r - -@ - -@ - -x - -@ -x -@q~ -
@e#LJ - - - - -r - -
I - -@B#G@H
Q - -Q -Q - - - - -GG@Q -@ - / -B - / - -@*#
-;p ; - -GС@ʡ - -G@@!x - - -G -!I@ -R B@h - H -H:
B G) -@!D # -G -G -GB G -G - -xQ - -;Gp ; - -GБ@ʡ - - ;R` G)"j ! (! )I - - -@ - -Ϡ -Aaa - -@G1 -N - -I - - -@ -G -Ϡ -Aaa -@ -@ -} - - - -} -bPL -xG - - -Gǡ@ʡ -@}#+#L -G@ - - -/R - - -2@ -#@ -x -GpqG,H:Q 9qp # ~ =!^ HL <" !Z H=a ==a >H>a >>a a 9
ȁP G - -@x - - - -H - -t@^#sRP @]#tR` G)"j ! - - -Ѐ)` - -B @V#BH U#BP B @ s@ - tx -s - -B L#BH K#BP B @ - H - - -a -G@GA -I -I - - @ ->#"@ -@x "@ - - -G -@ - -G"@ @6#7 -x -@` -x - -@x -` -9x - - - - - - - - - -@ -EFQ@ - - - - - -1 1 -N -O -N! -N - - - - - - - -A@A` - - - - -@`AA0@ -A - - - - - - I @xp - - -CL - - - - - -Š -x -I -I - b - -H -H -` -x -ȃ -` -Lx@cx - - - - - - - -` - - -H@ - - - - - - - - -@ - I -B - I - - -IJ - IHrR - -FLAKȂ - - -N - -IJ - IH@ -@ -Q -HR - -@ -H -I a - - -b -H@ n -b -HrR b - H2 - -a - - -IJ2 - - -H2 - - @a - H2 - - -@7 - - -H -H - x - -H) -B -@ - -Ϡ -Aaa - -M@ -2 - - - -Ϡ -Aaa - -M@ - -
-@< -
- -M@a -x - @ -Ȁ Ȁ ) - - -@ - - - - - -` - -ɂP - -J - - - - -@ - -@ -` -@ - -@ -` - - -8 -J - - -8 -R -IJ -QP PCII - - -X -L^ J@ -I -K@ ɂp ɂ` -Aɂ@ a - -IK! -Hb - - K - -@ - - -H - xI - - -@ - - -"@ # -1 -@x -s -!@ - -Hr - H@I - - - B @#EBH #EBP B @ -@IH @ - - - - @#E"@ ! -@l -!@ - -Hr - H@I - -H -!@ - -HHr - H@I -V -@ -S - - B @#EBH #EBP B @ -@ -I@I` -H@
I - )I! -@ - - -H@H`
-# @x - - -N -C @ - - - - -I - - -@P - - -I @n - -QRa -II@ - -b -O - -x -xd - - - - -K - - -O -@l - - @L" Il - - - -@`J -2 -@M - -@`J - - - -8 - @b - - -
@
`@ - -# -K# - @ `H -II@ - -E - - -@`2@ʢ -R -I - -@ - -@`<# -E - - - -@ - - -2@ʤ -5 - - - -!Hr@ - -@ - - -T -$xR -x P - - - - I -@`J - -S -@I -@`3@ - @@ - -@ - -@`J - -L! - - - -L - -@`3@ -
Ѐ @Q - - - -L -L -I@&l - -@ - D @ + - - -CL - - - - -@NH2 - -$ - - - - -@Hx -1xox - - -I - - -Jʀ -@I Ȁ QIȃ Q ' -"D d - -B@ H - -"x Q IH I -$KH
- - -ȃ -I& -L" o -[) - - - -) -) - - -) -) - - - -) -) - - -) -) -)) -(@o - - -'L! !"#)Ja ' -'L! )Ja ' -CJ+@x%LLLL'L! !c -I) - -o -@ -*Q !ʂp L+H'*#LHB0 o -H - B R -H'@x, -e -l@b - - LB ¤"@BY -x - -L2 K -" -x - -%B -H -I - -` -x - -((o - -(&&& ( - -@%x -(% -U@( -N B -@ -N @o -M@N @n -(m - -( -)) - -'L! !)Ja ' -'L! )Ja '+%(o - -*Q !ʂp @xLL'L! !a -I) - -(@o - -*Q !ʂp H'*#LHB0 o -B H' -%&&& !$@ - H - -CJ -f -U@& -* -K( -( -@o -(@ -o - -"P -!& - - - -I -Iy -!% - -%G -"K -Fa - -d -#K -I -! -H -H -"J@ J -JI %b -@ -x - -x@ -J#"H' - -" -"K+ - -x - -` - -" -" -J# - - -a I - - -=LȀ -@a - -x - c@c -$"L3@ - - -IA IσA I A
3@e - - -AJA
- -%e -]a a ' -O -O -?H# -H#?aǠAH#PCH - - - -I -# -I - -@ - H - -"P -!&J -@,x' - -@x& -i*% -&#i@("(h -(\(!xY@("h -'¢h -'') -'@iP | '& -'zB'zB'@i9@(I'z'h$(@ -'Bh -'@@x'Ad -((N( - &J -'iP | ' -@''&@x&'%%f%% a '@i()'z'% ! g%9@(I'z'h$(@ -'bh -'`'a*( -((N( - &j%(%%h% -( -' -&' -@g"&&( - - - - y h -&z&J - &b - - a -&B' -&@&A&
%Ǡ - -a & - -N J - - -JG - -I - ʠ - - ʠ - I -D - -E -2 - QIKbp I Q - IJ - -@I@ -I - ʠ - - ʠ - - - -@@ -ߏN LJ -J2x -@Ȇ - -0 -` - --x -@` -5x - -@7x -` -Tx -L L - - -GI˂ !KO -@ -I - - - - P - -o -@=Lˢˀ - -N J - - - - - - - - - - - -@ -EFQ@ - - - - - -1 1 -N -O -N! -N - - - - - - - -A@A` - - - - -@`AA0@ -A - - - - - - I @xp - - -CL - - - - - -Š -x -I -I - b - -H -H -` -x -ȃ -` -Lx@cx - - - - - - - -` - - -H@ - - - - - - - - -@ - I -B - I - - -IJ - IHrR - -FLAKȂ - - -N - -IJ - IH@ - -Q -HB -I - -H -I a - - - - -b -H@ n -b -HrR b - H2 - -a - - -IJ2 - - -H2 - - @a - H2 - - -@7 - - -H -H - x - -H) -B -@ - -Ϡ -Aaa - -M@ -2 - - - -Ϡ -Aaa - -M@ - -
-@; -
- -M@a -x - @ -Ȁ Ȁ ) - - -@ - - - - - -` - -ɂP - -J - - - - -@ - -@ -` -@ - -@ -` - - -8 -J - - -8 -R -IJ -QP PCII - - -X -L^ J@ -I -K@ ɂp ɂ` -Aɂ@ a - -IK! A -Hb - - K - -@ - - -H - xI - - - - - -"@ -1~ H -@x -t -!@ - -Hr - H@I - - - B #EBH -@IH @ - - - - #E"@ ! - -!@ - -Hr - H@I - -H -!@ - -HHr - H@I -V - -S - - B #EBH -@ -I@I` -H@
I - )I! - - - -H@H`
-# @x - - -N -C @ - - - - -I - - -@P - - -I @n - -QRa -II@ - -b -O - -x -xd - - - - -K - - -O -@l - - @L" Il - - - -@`J -2 -@M - -@`J - - - -8 - @b - - -
@
`@ - -# -K# - @ `H -II@ - -E - - -@`2@ʢ -R -I - -@ - -@`V#@ -E - - - - - - -2@ʤ -5 - - - -!Hr@ - -@ - - -T -$xR -x P - - - - I -@`J - -S -@I -@`3@ - @@ - -@ - -@`J - -L! - - - -L - -@`3@ -
Ѐ @Q - -@ - -L -L -I@&l - -@ - D @ + - - -CL - - - -@ -@NH2 - -$ - - - - -@Hx -1xox - - -I - - -Jʀ -@I Ȁ QIȃ Q ' -"D d - -B@ H - -"x Q IH I -䉁dKH
- - -ȃ @ -I& -L" o -[) - - - -) -) - - -) -) - - - -) -) - - -) -) -)) -(@o - - -'L! !"#)Ja ' -'L! )Ja ' -CJ+@x%LLLL'L! !c -I) - -o -@ -*Q !ʂp L+H'*#LHB0 o -H - B R -H'@x, -e -l@b - - LB ¤"@BY -x - -L2 K -" -x - -%B -H -I - -` -x - -((o - -(&&& ( - -@%x -(% -U@( -N B -@ -N @o -M@N @n -(m - -( -)) - -'L! !)Ja ' -'L! )Ja '+%(o - -*Q !ʂp @xLL'L! !a -I) - -(@o - -*Q !ʂp H'*#LHB0 o -B H' -%&&& !$@ - H - -CJ -f -U@& -* -K( -( -@o -(@ -o - -"P -!& - - - -I -Iy -!% - -%G -"K -Fa - -d -#K -I -! -H -H -"J@ J -JI %b -@ -x - -x@ -J#"H' - -" -"K+ - -x - -` - -" -" -J# - - -a I - - -=LȀ -@a - -x - c@c -$"L3@ - - -IA IσA I A
3@e - - -AJA
- -%e -]a a ' -O -O -?H# -H#?aǠAH#PCH - - - -I -# -I - -@ - H - -"P -!&J -@,x' - -@x& -i*% -&#i@("(h -(\(!xY@("h -'¢h -'') -'@iP | '& -'zB'zB'@i9@(I'z'h$(@ -'Bh -'@@x'Ad -((N( - &J -'iP | ' -@''&@x&'%%f%% a '@i()'z'% ! g%9@(I'z'h$(@ -'bh -'`'a*( -((N( - &j%(%%h% -( -' -&' -@g"&&( - - - - y h -&z&J - &b - - a -&B' -&@&A&
%Ǡ - -a & - -N J - - -JG - -I - ʠ - - ʠ - I -D - -E -2 - QIKbp I Q - IJ - -@I@ -I - ʠ - - ʠ - - - -@@ -ߏN LJ -J2x -@Ȇ - -0 -` - - - - -@z - - -@s@ -JAHR0 AH! IAH! AHB8 AH0 @ - -A@ -J> -AAAAJ< -A"@@@AH> ` - - - - - -AH> -I -H -s@@y -x - -H22 IH0 H - -@ys@ -J -s@AHR0 AH! AH! IAAH0 K@ - -A@ -J> -AAAAJ< -A"@@@ - -p s@ - FI> o - - @I@ @ @I AH> K ` - - - - -IIIb IIbI@ -IIIR IIRI -II -I - -IAH> - - - - - -@I -AH0 H. @AH> H< H: -M -.s@ - - - -x
GK` - - - -@A -C -C @ -C O -C C - -` - - -J -@ -ʀ - - -xNCh @xNC@ xNCH @xNCP -K@ - x
@ x
x
- -K@ - -` -JB@Jb@H - -@xNb@ -N@@I - - -\ - -A> - -@b - - -xM@Q -S$S$AL -S - -@@AH> - - - - - - -@ P - -AH! AH! AH> -H< AH> @ -H$ H IAH6 @ - -J -A ` - -A ` -xAH! AH! AH! IAH! AH> -@=I -J -` -x -A> @ -AH0 AHR6 H4 HR* AHB8 HB0 -AHB8 AHR6 HR, HR" - - - - - -@ -s@ -HB -J -s@AH> H< H26 H4 IH2 % - - - -x@H@ HHAH> @ -{ - - - - - !I!!@x!AH> !H< a -I!@! -!AH> b -H -H - - -x - - - - - - - - - -` - -xI -Ib - - - - -H -H - -@Jo - - - -x - - -x -@x -@|x - -I< - HR -g - -s@ -J@k -s@ - @j s@ -HB -Jb -s@# -#@x#@ - -J@ɑ ## - -ȁ -I - a - -J@ɑ $AH> @a -
@ -xJ -@ - -x -HH -J@ɑ AH> AH> -@ - -H% - -AAH> b -bT %` - - - - -I - -Al -I& @ - -@a -I - - &%I - -I { - - -( - -I!(! )!xI)AH> a -( - -%@a -( -@x - ` -@xz -y - -@ AH -@" -@v - -F> o - - - - -H7# ` - $ - - - - - - -HH++ -HH+,x#Hb -' - - - -+@ - - - -` - -I I L F -ɗ ɗ H a * + a + , a @II@ a H -ER - - -E "` "d * + ` ~ + ,` -ȇ J,,` @ - -+J` a - -+B@ -I,*" -@x@H -@ - - -,H -@@@ - - @K -H01DH -HR n - -H,@a - - - - - -@ - - - -$ -@a - @ -&} -> ~ @M@
@LÀ -J -> ~ @M@
@LÀL - - -@ -@ - b -H - - - - -"Ab -!H! -@Y -_ - -x - + - -@ - -A - - - -+H2 - - -x -x+I -+@ -,+ -! - -! -J J -@xBX H` -xBP ` - -! -JH H@ -JH -JH JH -A1 - - -v} -xI - -@ - ` -x -xI - -@ - ` -x -@@ -@ -@@ -@"@I -@ -K - -K - - - - - -K - -3@H - - - - - -3@H - - - -I@J@ -B` H "| -I@J@ -Bh H %GI @ B D I
"H G "@ "H "P D @ B D "@ "D -HHH-HI@HHIHIHIIJHJHJJK HK!K!L)HLH)LLM#HMNHNHNN BH OXHHXXXYHYHOOHY - H -H I H - H -!ɐ H -H! H -(I H -( H -H%ɑ H -% H -)I H - -P. - - - - -2@@I - - - - -@ -I- - -I-I I- -J@ɑ A H@M -@ - - - -H,^a Ѐ -$@ -Y@hB&i - -%A#$AdIA -# -@#A - -$$ - - - - - - - - - -a @樀 -@ -@V - - - -$$f -$"x - -e;` - x%` - -d -% -@x -$$$$$ - - -$A$> $ -#Dc/ - -c -d@! - -Q f9@ -@xe<&a -d)e -xIa -de -@ x$@@$) a -c7 @c@ -c% -fH - - -#$ -d@ -# -f!x& -c -@ -e - - -%` - - -i2 $$$$$ -d - - -f!$e -$< -d&I@ -i2 -d - - -f $$< - - -hr -# - -C@ - -`b - -`b - - - - - - -) - -'@) g@a - - - - - - -z - - -s@ -JAHR0 AH! IAH! AHB8 AH0 @ - -A@ -J> -AAAAJ< -A"@@@AH> ` - - - - - -AH> - -H - -x -@y -H22 IH0 H - -}s@ -J -s@AHR0 AH! AH! IAAH0 K@ - -A@ -J> -AAAAJ< -A"@@@@I - - - FI> o - - I - - - - -IIIb IIbI@ -IIIR IIRI -II -I - -IAH> - - - - - -I -AH0 H. @AH> H< H: -M - - - - -x
GK` - - - -@A -C -C @ -C O -C C - -` - - -J -@ -ʀ - - -xNCh @xNC@ xNCH @xNCP -K@ - x
@ x
x
@I - -K@ - -` -JB@Jb@H - -@xNb@ -N@I - - -\ - -A> - -@b - - -xM@Q -S$S$AL -S - -@@AH> - - - - - - -@ P - -AH! AH! AH> -H< AH> @ -H$ H IAH6 @ - -N -A ` - -A ` -xAH! AH! AH! IAH! AH> -AI -J -` -x -A> @ -AH0 AHR6 H4 HR* AHB8 HB0 -AHB8 AHR6 HR, HR" - -@3y - -@ s@0Ib - - -s@ -HB -J -s@AH> H< H26 H4 IH2 - -@} - -xH HHAH> @ - - - - - - !I!!@x!AH> !H< a -I!! -H -H - -@s@@y -x - - - - - - - - - -` - -xI -Ib - - - - -H -H - -@Jo - - - -x - - -x -@x -@|x - -I< - HR -g - -s@ -Jo -s@ - n s@ -HB -J -s@# -#@x#@ - -J@ɑ ## - -ȁ @ -I - a - -J@ɑ $AH> @a -
@ -xJ -@ - -x -HH -J@ɑ AH> AH> - - -H% - -AAH> b -bT %` - -@ - - -I - -Al -I& @ - -@a -I - - &%I - -I { - -@ -( - -I!(! )!xI)AH> a -( - -%@a -( -@x - ` -@x - - -@ AH -@" -z - -F> o - - - - -H7# ` - $ - - - -Kx - - -HH++ -HH+,x#Hb -'#_x - - - -@ -+@ - - - -` - -I I L F -ɗ ɗ H a * + a + , a @II@ a H -ER - - -E "` "d * + ` ~ + ,` -ȇ J,,` @ - -+J` a - -+B@ -I,*" -@x@H -@ - - -,H -@@@ - - @K -H01DH -HR n - -H,@a - -@ - - - - - - - -$ -@a - @ -&} -> ~ @M@
@LÀ -J -> ~ @M@
@LÀL - - - - - b -H - - - - -"Ab -!H! -@Y -_ - -x - + - -@ - -A - - - -+H2 - - -x -x+I -+@ -,+ -! - -! -J J -@xBX H` -xBP ` - -! -JH H@ -JH -JH JH -A1 - - -r} -xI - -@ - ` -x -xI - -@ - ` -x -@@ -@ -@@ -@"@I -@ -K - -K - - - - - -K - -3@H - - - - - -3@H - - - -I@J@ -B` H "| -I@J@ -Bh H %GI @ B D I
"H G "@ "H "P D @ B D "@ "D -HHH-HI@HHIHIHIIJHJHJJK HK!K!L)HLH)LLM#HMNHNHNN BH OXHHXXXYHYHOOHY - H -H I H - H -!ɐ H -H! H -(I H -( H -H%ɑ H -% H -)I H - -P. - - - - -2@@I - - - - -@ -I- - -I-I I- -J@ɑ A H@M -@ - - - -H,^a Ѐ -$@ -Y@hB&i - -8 -bI@@ -%A#$AdIA -# -@#A - -$$ - - -@ - - - - - - -a @樀 -@ -@V - - - -$$f -$"x - -e;` - x%` - -d -% -@x -$$$$$ - - -$A$> $ -#Dc/ - -c -d@! - -Q f9@ -@xe<&a -d)e -xIa -de -@ x$@@$) a -c7 @c@ -c% -fH - - -#$ -d@ -# -f!x& -c -@ -e - - -%` - - -i2 $$$$$ -d - - -f!$e -$< -d&I@ -i2 -d - - -f $$< - - -hr -# - -C@ - -`b - -`b - - - - - - -) - -'@) g@a - - - -@x -@` -@x - - -` -@7x - - - - - - - - - - -EFQ@ - - - - - -1 1 -N -O -N! -N - - - - - - - -A@A` - - - -@`AA0@ - - -CL - - - - - -Š -x -I -I - b - -H -H -` - -ȃ -` -@Fx@^x - - - - - - - - - - H
@ - - - - - - - - -@ -
-B @ -
- - -IJ - IHrR @ - -FLHAȂ - - -H - -IJ - IH@ z -Q - - -!` - - -H -H - -ɿ -H2@ - -b -H@ p -b -HrR @d - - -H - - -J2 - - -IH2 - -@e -H -@a -H2 - - -@7 -H` - - -H -H - x - -) -B -@ - -Ϡ -Aaa - -M@H -2 - - - -Ϡ -Aaa - -M@ -A -
-? -
- -M@a -x - @ -Ȁ Ȁ ) - - -H@ - - - - - -J - - - - -@ - -@ -` -@ - -@ -` - - -8 - - -8 -R -IJ -QP PCII - - -X -I -K@ɂp -ɂ` - -IK! @H -b - -@X - - -@ - - -H -@? - x I - - - - - -"@ #@ -1~ H - - - @ - -HHr -IH H@I -@ - -J - B #EBH - - - - #E"@ !@ - - @ - -HHr -IH H@I -@ - - - @ - -Hr -H H@I -HѕH@H -HѕH@H -J - - B #EBH #EBP B @ !@ -I@I` -H@
I -H - -ʀ -ˀ -K - - -K - -H@H`
- & - -
@xK@@ -N -C @ - - -H@H`
-@x -N -C @ - - - - - - -I - -I> - -@P - - -@b -I m - -QRa -II@ - -Ob - - -x -xd - - -P - -P - - -K - - -O -@l - - @L" Il - - - -@`J -2 -@M -@`J - - - -8 - @b - b@ - - - - - -@@ -
@
` -@ -# -K# - - @ `H -II@ - - -E - - -@`J -2@ʢ -I - -@ - -U -Q -@ -@`#@ -@ -E - - - - -URAU@2@AP - - - -2@ʤ -5 - - 2@ʤ -5 - -URAU@PPA# - - - - -` -P -O -$xR -x P - -$` - - - - -@`J - - - - -@`3@ - @@ - -@ - -@`J - - - - - - -@`3@ -
Ѐ @Q - -@ - -L -L - -@ D @ * - - -CL - - - - -@NH2 - -$ - - -H` -x - - - -H -@Hx -1xix - -I - -I -ʀ -@I Ȁ QIȃ Q & -"D c - -B@ - -y Q IH H -dL - - -ȃ - % -L" o -[( - - - -( -( - - -( -( - - - -( -( - - -( -( -(( -'@o - - -'L! !"#(Ja ' -'L! (Ja ' -CJ*@x%LLLL'L! H!c -I( - -o -@ -)Q J!ʂp L*&)#LHB0 o -H - B R -&@xHB -%B -H -I - -` -x - -''o - -'&&& ' - -@%x -'% -U@' -N B -@ -N @o -M@N @n -'m - -' -(( - -'L! !(Ja ' -'L! (Ja '*%'o - -)Q J!ʂp @xLL'L! H!a -I( - -'@o - -)Q J!ʂp &)#LHB0 o -B & -%&&& !#@ - H - -CJ f -U@& -) -K' -' -@o -'@@m -"P -!& - - - -I -K!% - -%G -!K -Fa - -d -#K - - -H! -JI %b -@ -x - -x@ -"!H' - -" -!K+ - -x - -` - -" -" -" - - -a I - - -=LȀ -%e -]a a ' -O -?" -"?aǠA"PCH - - -I -@K# - -I - -@ - H - -"P -!&J -' -*x' -V -@x% -i)%G -"i@!(' -(\(!xY@!' -'¢h -'') -'@iP | '& -'zB'zBf&& a @i9@'#(@ -'Bh -'@@x'Ad -'(N( - &j -'iP | ' -@%%@
x%g$$f&& a @i(('zg$9@'#(@ -'bh -'`'a)( -'(N( - &J$ -' -' -%' -@g"%&' - -V - - y (&j&: - -V -'$@ -&B' -&@&A&
%Ǡ - -a & - -N J - - -JG - -I - ʠ - - ʠ - - -D - -E - IJ - -@I@ -I - ʠ - - ʠ - - - -@@ -ߏN LJ -J2x -@Ȇ - -0 -` - - y -G@, -% -I` - - -@x -@:La - - - - -@-y -o -c -HCc -I -x -*L6Lǁ Q ;LH2 -H -L ` - -@@I - -x - - -@x - -2 - -(GGCG - -<L - - -B - -@x -BD HAd - -`H - - -` - -X ȃ -, - -q@BD HH@d - -x - - -@ -HA - - - -ȃ X - -x!GG -G$Lx0!$L@$N -@ -" -N"HD 2P @x!xA! -@< -`@ - - -` - - -Hzo - - - -@x - - -GI -O -I@ -I - -o -I@ -I - Rp - - - I`O - - - - - -LJ - - -` -1xG` -G -G - - - -] -G IGa @ -a -G - - - -` -x - -@ - -P
- - - IG@ -@ - -P
- - - -GG -b - - - -H` -` - - - -*L6L @˂@ -@` -I -@b$ r -@I2@ -C -Br@@xr@ - - Gr -Gr - - - - - -`` - - -G -b - - -o - -H - - - - - -G -` -x@ -I -x -Br -@ -G -I@ - - -x - - -HIa $ -HJIIa " -IJa ! - G - -A Q@ -G - ` -@x I IB@HB@ - - - - - - - - - - -J - -xGGP !@$N -@ -" -N"HD 2P @x!xA! -GG -G -G` - -@ - -@ -H!" - - -I -xF!x -@ - -N - r - - ! RGIba IGa -a - - - @@ - - - -"B @x@@ o - -@ -T~ - -( -! (@( hQ -( -* -kè -냨 -+B - -* -* - - -! ( 銂( ( -@$("Lh -! ( 銂( hЈ0D x( D *k -Q -* -* -k -p -* - -! h (( m-^ ( ( -@$("L( ( -! h (( -^ ( (X0D ( (0D ( ( -$/"L/ / -! h (( -^ ( ( -P$("L( ( -! h (( --^ ( h؎0D ( $$("L./( - - - -! ( 銂( @$("Lh -! ( 銂( hи0D @x( * -Q x+kA -k -p -0D ( ) ( -! h (( -^ ( @$("L( ( -! h (( ( (X0D ( (0D ( ( -! h (( m-^ ( P$("L( ( -! h (( 胂 ( hؾ0D ( $$("L./(( - - -@ x -@@x U@U5 -`a@ - -U@ - -@V - - -E NNN$"N - -xAd -V U@U5 - -E - -G -G -c - -NNN - - -@ -! -G - -ߏN Lȃ JB - -` - -, - *C(I( -,J@($,*F ( ) ("L(h! ( 튂( ( -,J@ ($("Lh! ( 튂( , -("Lh! ( 튂( - -G+ -% - @ -I` -@y` -@y$ -x -@:La - - - - -*y - - - - - -, - - -B I - - - - -@ - -o -c -HCc -I -x -*L6Lǁ Q ;LH2 -H -L ` - -@@I - -xyo - - -@x - -2 - -(GG$$"$" - -<L - - -@B - -@x -BD HAd - -`H - - -` - -X ȃ -, - -q@BD HH@d - -x - - -@ -HA - - - -ȃ X - -x!GG -G$Lx0!$L@$N -@ -" -N"HD 2P @x!xA! - -`@ - - -` - - -HRo - - - -@x - - -GI -O -I@ -I - -o -I@ -I - Rp - - - I`O - - - - - -LJ - - -1xG` -G -G - - - - -G IGa @ -a -G - - - -` -x - -@ - -P
- - - IG@ -@ - -P
- - - -GG -B - - - -H` -% - - - - -G -` -x@ -x -Br -@ - - - -x - - -HIa $ -HJIIa " -IJa ! - G -A Q@ -G - ` -I IB@HB@ - - - - - - - - - - -J - -@xGGP !@$N -@ -" -N"HD 2P @x!xA! -GG -G -G` - -@ - -@ -H!" - - -I -xF!x -@ - -N - r - - ! RGIba IGa -a - - - @@ - - - -"B @x@@ o - -@ - - -( -! (@( hQ2x( (o -( -* -kè -냨 -+B - -* -* - - -! ( 銂( ( -@$("Lh -! ( 銂( hЈ0D -,J@($,*F ( ) ("L(h! ( 튂( ( -,J@ ($("Lh! ( 튂( , -("Lh! ( 튂( -* -* -k -p -* - -! h (( m-^ ( ( -@$("L( ( -! h (( -^ ( (X0D ( (0D ( ( -$/"L/ / -! h (( -^ ( ( -P$("L( ( -! h (( --^ ( h؎0D ( $$("L./( - - - -! ( 銂( @$("Lh -! ( 銂( hи0D x( * -k -p -0D ( ) ( -! h (( -^ ( @$("L( ( -! h (( ( (X0D ( (0D ( ( -! h (( m-^ ( P$("L( ( -! h (( 胂 ( hؾ0D ( $$("L./(( -"xIU - -@ x -@@x U@U5 -`a@ - -U@ - -@V - - -E NNN$"N - xAd -V U@U5 -x -E - -G -G -c - -NNN - - -@ -! -G - - y -G@, -% -I` - - -@x -@:La - - - - -@-y -o -c -HCc -I -x -*L6Lǁ Q ;LH2 -H -L ` - -@@I - -x - - -@x - -2 - -(GGCG - -<L - - -B - -@x -BD HAd - -`H - - -` - -X ȃ -, - -q@BD HH@d - -x - - -@ -HA - - - -ȃ X - -x!GG -G$Lx0!$L@$N -@ -" -N"HD 2P @x!xA! -@< -`@ - - -` - - -Hzo - - - -@x - - -GI -O -I@ -I - -o -I@ -I - Rp - - - I`O - - - - - -LJ - - -` -1xG` -G -G - - - -] -G IGa @ -a -G - - - -` -x - -@ - -P
- - - IG@ -@ - -P
- - - -GG -b - - - -H` -` - - - -*L6L @˂@ -@` -I -@b$ r -@I2@ -C -Br@@xr@ - - Gr -Gr - - - - - -`` - - -G -b - - -o - -H - - - - - -G -` -x@ -I -x -Br -@ -G -I@ - - -x - - -HIa $ -HJIIa " -IJa ! - G - -A Q@ -G - ` -@x I IB@HB@ - - - - - - - - - - -J - -xGGP !@$N -@ -" -N"HD 2P @x!xA! -GG -G -G` - -@ - -@ -H!" - - -I -xF!x -@ - -N - r - - ! RGIba -a - - - @@ - - - -"B @x@@ o - -@ -T~ - -( -! (@( hQ -( -* -kè -냨 -+B - -* -* - - -! ( 銂( ( -@$("Lh -! ( 銂( hЈ0D x( D *k -Q -* -* -k -p -* - -! h (( m-^ ( ( -@$("L( ( -! h (( -^ ( (X0D ( (0D ( ( -$/"L/ / -! h (( -^ ( ( -P$("L( ( -! h (( --^ ( h؎0D ( $$("L./( - - - -! ( 銂( @$("Lh -! ( 銂( hи0D @x( * -Q x+kA -k -p -0D ( ) ( -! h (( -^ ( @$("L( ( -! h (( ( (X0D ( (0D ( ( -! h (( m-^ ( P$("L( ( -! h (( 胂 ( hؾ0D ( $$("L./(( - - -@ x -@@x U@U5 -`a@ - -U@ - -@V - - -E NNN$"N - -xAd -V U@U5 - -E - -G -G -c - -NNN - - -@ -! -G - -ߏN Lȃ JB - -` - -, - *C(I( -,J@($,*F ( ) ("L(h! ( 튂( ( -,J@ ($("Lh! ( 튂( , -("Lh! ( 튂( -I` -x` -x x - - - - - - -G - - -@ -(G% - -GG -x((LG/ -I -@ - - -a - - - -H@ - -x - % -(((LG/ - Gb -Gb I -Gb - -aB - -IB HJ , -` - - -`x -H -GH - xȑ@@ ëȁ -Q -Ffe@@ ȉ -Bc - - - -NR` Rj -@ -I I $$2@HbF HT *G@d -ߏNȁG - - - -G@ - -à -_ - - 9I9LJ!!l -` - -a -@a -& - - - - -G - - -o - - - % -H - - - -x@ -IA - - -x - - -./a # -HJ//a " -/0a `! -G - - A Q@ -G - -@x I IB@HB@ - - - -IAII - -IAI - -A - -N@@@ N - - -Α@ -Q@ - - -A@ - - -
-GG -@x - -O -O -O@x - - -O -G -S@ - -MSI@ -G - -xOÀ
-6HC
- -H -Bx
` - - x6HC
a - - -H! -BxDBx
b -H! -@x - -
b -H! -DxBBx
Db -` -B -6HC
@ -
b -H! -DxB@x
a -Bx
` - -6HC
-
` -
a -" - - -x6HC
` - -@
b -H! - - -x6HC
a -H% - -H! -BBxD -
` - -6HC
- - -
` - - - -I -x! x -IB -IW¦ -IC -IՌGå -SC -Ӌä -IRD -IҊGģ - QD - щĢ - E - PGš - ψE - Š -INI@x -Ƣ -F -Ĭǡ -ɋGG -IǠ -ʅI@Aa@ǁ@@xȁ@ G -A -\ -Y - - -~ - -+ -*` -* -kC - -+£ - -* -* - -( @ -节( ( - -( -* -k -+¢ - -* -* -@ -k -h -(@( x -(@( (( (@(( m-^ ( ( -k - -(@( x((@( (( (@(( -^ ( (X( (( ( -k -(@( x((@( h( (@(( -^ ( ( -k -h(@( x(@( h( (@(( --^ ( h؎ - - -"xU - x -@@x U@U5 -`a - - - -@xV U@U5 - -x - -E NNN
V
N:@x: -@xd -V UU@U5 -x -E -` -@x - -GG -G -I& - - I ! - `iI@ C - @ -I -.x -(x -@x - - -@` - -` - -Go - -~x - - -6L k - -K -ˠ -@yxTi -Q"N - - - - - -rxa -@ -@ @qx - -@@ II24 A" - - Iɐ ɐ @ I SIH@! - -@I@ - -x@ -Iɀ -ɡ -IG# - -I -H -IA" - -I! - - -G
A Q@ -G - - - G - - Ĩ -H(H(BL Q IGv v P -GHLȁP GL G A -q@ - q@I -
Go - - -QI Q -@I - -H -H - -G@xGMG -)Lx -q@ - - - -G@ - - -d - -H - - -Gȁ ` - - - -,((LG/ - - -o - -GG - -y - -"& - - - -.@n -I - -@ #`d` - -T - - - - -H &(G` -GMG(LG@. -CG((LG/ -G -@ - -@Aa -x - - -B - -G - -Ba -G -? - -"& -G -G -` -@x; -@x, - -x - - -G - - -ǀ -2@ -EE@ -G -ǀ` -
x - -@ - - - - -GG - -@ -@ -BX J -BP -BH J - -(`ih@(C( -(( -HH -G@ -R - -x -@@ -@ -O - -MNC@ -@ xLM -O - - -@@
M@ -xMMM@
NNNNNNNQUNY -
-M@ -B -͂ -@Ixx
- -
O -
-
O -
M@
-OO -x -MC@
-
` -@ -x
P3@@$ -x -́ -
-@x - @
NMӀ
M3@M@
X
IM
tr M# - - -G@b - -IGB - - - - -@ - -!L@ -"L @ - -£ -J -@ -A - -@xo -r -@xJ JM` - - - - -@" - - -@ - -@ -@ -xV JM` - - -@ - - - - - - - -J JY" !L MJ" !\ @ - - -J - -c -@xK` -JAb -x -ˁ -` - - -J - - - - -pIrIB - - -I @x - ,IB -ɱ@ - - @ -II @ - -x ,IB -ɱ@ - - @ -II @ -,C - -C -A - -2@ - -@} - -@ - @ x -x hi! V hi! T -U@e)hiqiU -TqiU5@ - -o)Q `) - -e)hi% V - -ր` -xhi%@ - - U - -@!~ - -H -(G@ -, -<@ -P -XGA - - - - G@ - ! - $@ - < - HGA - x@@Gr1 - -G@ - Z - - -Gb@ -GB@ - -@x# -xI -x -$ -$Y@@ -$ -$)@S -d - -H -@ -p r -r - ÿ - - - -H - - - s -q u ILI -@I@HP U SI -I UIǁ O - -K<K4T - - - -!`ia@!C! - - - - - - I -A - - - ¥ -I - -A - -Di - - - - -G` - -x B I D` - -EG@ -ŀ -EŁx - -EG -ł -EŃ " K` -@" ` - -G` - - -EG -ń -EŅ " -EG -ņ -EŇ " - I ! - `iI@ C - @ -I - - -@x - - -@@` -RxL -` - -Go - - - -6L Kl - -K -ˠ - -QBN - - - - - -@xa -@ -@ - -@@ II24 A" - - Iɐ ɐ @ I SIH@! - -@I@ - -x@ -Iɀ -ɡ -IG# - -I -H -IA" - -I! - - -G
A Q@ -G - - - G - - -GHLȁP GL G A -q@ - -
Go - - -@I - - -H - -GxGMG -)L -q@ - - - -G@ - - -@F - - @a - -Gȁ ` - - - -B J@ -B -B B -K,@xBX I` -xBP ` - -,((LG/ - - -o - -GG - -d - -"& - - - -. -I - % -GMG -@ -G - - - -G@ - -@ -H - - -@; - - - - - -@Aa -x - - -B - -G - -Ba -G - - -"& -G -@x - -x - - -G - - -ǀ -2@ - -G -ǀ` -
x - -@ - - - - -GG - -@ -@ -BX J -BP -BH J - -(`ih@(C( -(( -x -@@ -@ -O - -MNC@ -@ xLM -O - - -@@
M@ -xMMM@
NNNNNNNQUNY -
-M@ -B -͂ -@Ixx
- -
O -
-
O -
M@
-OO -x -MC@
-
` -@ -x
P3@@$ -x -́ -
-@x - @
NMӀ
M3@M@
X
IM
tr M# - - -G@b - -IGB - - - - -@ - -!L@ -"L @ - -£ -J -@ -A - -@xo -r -@xJ JM` - - - - -@" - - -@ - -@ -@ -xV JM` - - -@ - - - - - - - -J JY" !L MJ" !\ @ - - -J - -c -@xK` -JAb -x -ˁ -` - - -J - - - - -pIrIB - - -I @x - -@} - -@ - @ x -x hi! V hi! T -U@e)hiqiU -TqiU5@ - -o)Q `) - -e)hi% V - -ր` -xhi%@ - - U - - - @ -@x# -xI -x -$ -$Y@@ -$ -$)@S -d -
" !@ " !D MH - -H - -p r -r ]B - - ÿ - - - -H -@ - - s -q L - u HRJ RT v I@ -@I@ -@HP U SI -I UIǁ O - -@ -HP SI - - - -!`ia@!C! - - - - - - I -A - - - ¥ -I - -A - -Di - - - - -G` - -x B I D` - -EG@ -ŀ -EŁx - -EG -ł -EŃ " @" ` - -G` - - - -EG -ń@ -EŅ@x -EG -ŀ -EŁ - -EG -ņ@ -EŇ@x -EG -ł -EŃ@ -` - -+@+@ - - - -y - -I - -@ - - -H -AH2: @ -h OI -@x - -H - II - IAH2: ` - - -AH0 AH! I - -J -AH> ` -xAH> -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -4 - -HB6 - -4 - -HB6 - -4 - -HB6 - - - a - @a - -` - -I - -OAI - n - p - r t O - - -@K2 - - -@ -AH> J -H -` -` - - -A - -ʣ @x - MA - - - -H0 - -I - - - -H0 - - -H - -a - @a -H ` - - -" -AAAH o -H J -2X O -b -HAAAH o - - -H @ -Hb -"| AAAH @m - -B@ - - -xHAAAH o - -HAAAH o - - -OAHH -O JB@ - - - -H - - -H -J -OA -"T O -HAAAH o - -H"HAAAH o - - -HAAAH o - - - -AAAH o - - - -
@ -
- -9A - - -9J2@ɗ :H - - - - -H2@ 2 - -J` JJ` -I -I - -OAH - -O - -H @ - ȇ $H
-
` - - - - - -@ -h O@a - - AH0 AH( I b - -
OAJb@ O -# - - - -H": ` -2` O - -*CAf -#G - - -I -
@| -@ - - KKa
AK@/ - -IH2 - -xJ
" -$ - - -A1 -@~ -((+@Q R PPCH - - -2@@I -@ F> -o - - -xJ -- - -?AH0 ˂@ɂ@ ʀ -` - --AH> - - - -?AH0 ˂@ɂ@ -
x - - -V AHb4 b@ bH H2 P T B - -@AH> -F AH"< "B AH> @ 2l ˷ aF - - - - - -? - -? - - -? - -? -@ - -` - - - - - -H @H - I -@xI - -@a - I -b -IB -@ - -` - - - - - -H2@"@H -` - -P/ -H@ - -H0 - - -H0 - -H? "P -J -bI@@ -@bA˷ aF - -b -+@o - -a .
AB+@+ - - -!+A/@ - - - -,@l@! - -o - - - - - - -1 -/@+ o@a - - -J` JJ` - -+@+@ - - - -y - -I - -@ - - -H -AH2: -h OI -x - -H - II - IAH2: ` - - -AH0 AH! I - -J - -AH> ` -xAH> -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -0 - -Hb2 - -4 - -HB6 - -4 - -HB6 - -4 - -HB6 - - - a - @a - -` - -I - -OAI - n - p - r t O@ - - -@K2 - - -@ -AH> J -H -` -` - - -A - -ʣ @x - MA@ - - - -H0 - -I - - - -H0 - - -H - -a - @a -H ` - - -" -AAAH o -H J -2X O -b -HAAAH o - - -H @ -Hb -"| AAAH @m - -B@ - - -xHAAAH o - -HAAAH o - - -OAHH -O JB@ - - - -H - - -H -J -OA -"T O -HAAAH o - -H"HAAAH o - - -HAAAH o - - - -AAAH o - - - -
-
- -9A - - -9J2@ɗ :H - - - - -H2@ 2 - -J` JJ` -I -I - -OAH - -O - -H @ - ȇ $H
@d -
c - - - - - - -h O@a - -AH0 AH( I b - -
OAJb@ O -# - - - -H": ` -2` O@ - -*CAf -#G - - -I -
@| -@ - - KKa
AK@/ - -IH2 - -xJ
" -$ - - -A1 -~ -((+@Q R PPCH - - -2@@I -@ F> -o - - -xJ -- - -?AH0 ˂@ɂ@ ʀ -` - --AH> - - - -?AH0 ˂@ɂ@ -
x - - -V AHb4 b@ bH H2 P T B - -@AH> -F AH"< "B AH> @ 2l ˷ aF - - - - - -? - -? - - -? - -? -@ - -` - - - - - -H @H - I -@xI - -@a - I -b -IB -@ - -` - - - - - -H2@"@H -` - -P/ -H@ - -H0 - - -H0 - -H? "P -J -bI@@ -@bA˷ aF - -b -+@o - -a .
AB+@+ - - -!+A/@ - - - -,@l@! - -o - - - - - - -1 -/@+ o@a - - -J` JJ` - FL CL R@ -I` - -xH! - -G
@a - -@x - - - -, - - - -@ - -! - - -J - - -,! - -G$ -` - - - -@I - -GIǁ -I@ -o -I@Ip v Gv v Gw p v Gv v Gw - -kWRk@4P`gP"k@IPrk\P - - -r -H - -@I - ` - -G
` -x - G`HR@ -`"@ - - -b - -2x -B - - - - - - -ǁ -c - - - - - -J` - - - - @I
^ G \ G Z -I - - - -I -@ -QGbɑ@I2 -QHbIb P PCIIb - -QRIc P PCII?Hba t -x@ - ɀ - - -ɱ - - - -GIǁ a -O -I@I - - - -@Lr@ǁ -I - -@a - - -L -H2X - - - - Ɂ x - - - - Gx -H - - & - -a -% - - -$ -a# -HJ!" -! - G - -A Q@ -G - -@xGH ` -xGP ` -xGX ` -@xG@ H` -xGH ` - - - G -@x I IB@HB@ - - - - - - - - - -I -I - -AL"CLh @ - - -( -x(h -@ -i -(A -h -A - -߿ -( -( )CL): - - - - - - - -@xa - -I -A@_` - -A@ - - - - - - -s s Eg - -a - - -L@a - - - - -E@a - -L - -D - ! -<Ȁa -E<B - -B - - = -E=== E DL>L -b - -D@ @ - -xHR& b@I"@J@Hb - @ -I` -x` -x" -@}x - -)L G@c -G" - - -)` - -` -.y -&&& -H@o@ -@ - -@J -@ - - -@Aɑ -G -G -G - - - -!`%#LB0 -! I -&&Hb - - -# -H - - - -&&&& - -H -! -H - -! -&x -H - - - - - - -GI -O -I@ -I - -o -I@ -=Lʀ -I - Rp - - - P$ - - - - - -LJ - - - - ȁ -ȁ -ȁ -ȁ -ȁ -h -G@G@ M -b -G - - - -ì -Ja - - -b - - -x - - -x - - - - - - - -AG - -J@ - - - -@ - - -mx -QLFLAH -p @ȁ -CL@ -@L@HG -cx -@`x - -a -Ix@b - -Vx -@ -9x8 - -Ȉ -@+x - -x@ -I -xI@ -r - -H - - - -H - -G -G - -A Q@ -G -@H -ȁ@ -I@@x@4@ - - - I - -` - - - - - -G - - - ` - - -GGb -m6 -m\ --mNLǁ@4 - G` - -
x" - -G. - x - r@" - -@ -%G - - -x@H - - - - -x -$` -~ -* Ij@ -ꠂ )(` -*A꧂ * *I* * * * j -) -(5) - - - - -Fx - a - -J* J* h - -* )J - ) - -
` -:x - -G -@x -x -! 1 -" -!
1 -! 1 -! 1 -@ -@x*H*& - -x -@ -Q -G - -@ -Q -Q -Q -G -$G@ -L -L - - -G@ -G -H - -\ PPCG - -J@" -` - - -K! @ -` - - -K! @ - -@x -` - - -I -@ - - - - -( ( -G -xU -@x -@@#L - -W -@@!NU - - -@V -@c -c - -Gx - - -2@ -b -I Gp G` NG -G -x 2@ I2@ @a - - -xI Gp G` K"\ GX NI - - -I - -@ -x -x - @ - -x - - -K - - -x - - B@r -%"!1@F! - -H - -
x - -x" -H" -# -" -G - -Ga - - - -" - - -G@c -G - -`@ -@x -, -1 c -A -H - ` - - - -@x) - - -H - -- - -@ -&H&H - -GG@c - -, - -@b - -G -` -Rx) - - -H - - - - - -H -GG - - - -e - - -H - - - - - - -H - - - - - - - - -ax -a*aG*G@ -` -x -@x@x - -x!hJ - - - - - - - -@b - - -H - - -H - - - - - - - - -G$ - - -G -Ap &AX H'AP ! - - -, - -,I - -H$a - - - -` - - - -` - - - - -` - - -` - - -I - - - - -H - -H -G - -(#@ - -ǂ - -H&ȁ -Gt Gt -(I( *SI - - - - - - -+ @x, + -` - -HH@f -@ - - -G@ -HPx -HH - -H%H -HPG -HH -HP -@ - -HC@
r -HCH
C -HCP
HCX
"@Ir -C -C 3 -C C @ Ir -C -C 3 -C C B LCH - @ -I` -@*y` -y# -@~x - - -" - -Cc -)L - - -cy - -GGG>%&&&C -De -&Lo - - - - -G - - - -@o -@? - - - - -/G -J -Fa - - -; - - -Gd -J - - -Q -? -RP - -C. - - -? NI HB -@GA -GRA@HH -Da -C - - - - - -o -G#LB0 o - - A R LI - -%£ -H -c -C - -G -@c -&Lo - - -G - - -&Lo - - -Z` - - - -@ - -x -h - - - - -LJ -@j -D` -` - -I - - -L - - - -I -, - -+ -x -@ - - -r@b -D -C -@~ -q - - - -G - -A -@#G -\ - - - -H - - - - - -r@b -D -C -@e@a -q!G` -xZ -@x - - -G - - -A - -\ - - - - - -H - - - -@GG - -@ - -@@x - -1@ @H - -1@ @H - -1 -GA` -@x -G - - - - x -I@D#D - Hx !#(HH5a - @x -7#@8 -I@ - - -QLFLAIH -p "@ȁ -CL@ -@L@ G -H -a @r - - - G - - - -ID ` - - -@x@ -I@ - - - -@ - -@a -G -H - - -@ -J -@ʢ - -A Q@ -G - Z` -@ -@ -I@@x @@ - - - -@x - -aH - -@ - -mg - - -b -D -C - -J - -@J - b - - -GB - - -@x -G - -@ -C` -@x -s s - -L! o - -H - - - - - - - -x -xDL - - - -P -!x - - -/ǣ -Pd@QQ -¢R -@ -BR -@@xAc -N -Q@Q@ -bR -`a -N D -@ -Q@Q& - - -x/Ǡ - - t 4T - - - -B -@A
/Ǡ -P@PP4@a - - - -I| - I -"p "h - -bp - -@@ I ɐ ɐ -SI - -@I@ -I - -o -I@ -=Lʀ -I - bp - - - :Lb - LL8L - 8 -/$ -@ -!a "a # Λ -? -?aǠAPCG - - - -ȁ - - -Q -? -RP#LG -q@ - -. - -. - -. - - -gZ - -. - -Lx - ` - - - -x@@Hbd 0H@@HHbd 0r@G@r@@GR
Hbd 0Hbd 0 - -@@x - -@ - -@H@x -@H -@ -@` - -@ -@ -@` - -@ - -x -x
@
# - - - - -I - -@@ -L@ - -I@I@ -L@ -I - @x -Z - -Xш -PH Ȉ -X -H - -H - - - - - - -I -v -G -2x -Ha - -@2xU@ -IL - - - -x - -@
xZ@ - -G2 - - -A - - -x - - - - -H -. -ta -- -_x - -G7 -mWBl - -HR - II - - - - -@Lr@ǁ - -@x -I - - - - @} - - - -x -H@ - -@ -H - -@} - -@_ - -
A -E -Q -, -D -FA - - -A *1@1 -$A -4X -Q -@ - -! -Q -
F -F@q@xF
F -F@FF @xF
F - -
J` -F" I -F" I -@xD!H EP -
H - -D -@@D$L -M3 -M
AH a t - - - - -2a --Iȁ -@L3 - -3 - - - -ɑ zI -+ @ -I` -zɀ` - -&xP -Ex -Ex - - - - - -) - -J@ -
J -.8 - -GI , -O -I@ -I - -o -I@ -=Lʀ -I - bp - - - - -Q RPPCL - -@J -A -A -& -% -( -\ -!p! - -J - - - - -LJ -@ -I -P! -Ga - -
x - H G -G@ -` -@x
ׁ` -x
-xMuG` -@x - QL -FLHAȂ - t -x -G - - -q@ - - - - - -B - -<B/L' @ 0@ - - -G - -GI -@LBLAQ -` - - -$ - - - -@x$@ -W(Ǥ -*e@-UU -\!@xU@-U -¢V - -@TeP W| NB -EE@ -BV -@@xAՀe -&N U -TeP W| NB -U@%$U@x$&) -bV -`aV0 -&N U'$ - - -$` - - - - - u V,E -@ - - -B -@A
Ǡ - -A - - -@@x -NNN@ - - -@@ II24 A" - - Iɐ ɐ @ I - -@I@ -I - -K -K -@ -@ -G - -<G@S; -< -` -xJ - -xIǀ! -< -J - -xJ -xJ -G2 -H" - - -2 -xJ -3@ -G4 - - -~ $ -H -! - -N,x - - -sx -@ - -S - x.I,J) -` -,@ -I -,@Ȅ@ -,
- -@ǠA+,- - -G -;H -% -< -@ I - -@ H -H@a - -H -;I - - - - -GǑ@ʡ -;GR N;3 -xH;;G - -G @ - -GH;ȡ@ʡ - -N; - - -G @@ - -G - -G @ - -G @ -I; - - J -J - -J9 - - -J - - - -!sstG -@b - -GuuG - -@b - -!x2 - -< - -x@ -x " -J -@b - -. - - - -J - - - - - - - - - -@~; - - -~ - - -o - - - -H - $ɀ -@Ip p QIs Q #G)!D G)d - -Q;! - - - - -@~ - - - -G,",@a -QI - - -Q -? -R+yP - - - -N" $ ->?L ?LIB -A - - á -H! - - à -G -x - - - -~ - -~ -@ -A -bPL -xG - - -Gǡ@ʡ -|~x#+#L -G@ - - -+ -/R - - -G# -# -q@)#q s -s s -' -L! o -!*! -G) -))YxJx -))%xx -G) -))Qx -)) -G$) - - -$ -@o - - - -'x 'LI! &'()) a ' 'LI! H$ a ' CI#G D -#LGB0 -@ -@ -* - - - @o -I@ -(@(`} - A R K -(@xGB -%B -G -H - -` -x - - - -'xI* -S@& NI HB -@ -N @o -@N @n -$m - -G$) - -' -'x 'LI! &') a ' 'LI! H$ a '#G D %$ -o - -!L"L%'Le! ,a -* -$ʀ - - - -( -%&&&r !G%@ -G - -S& -O - -* - -$ @o -&I@ - - -, - --xB - -G - --J -Fa - - - -+ - - -g -J+J - - -Q -? -RP -@#\ a -L+L -@$ -, - - -I@ ` - ~I,Db -@x --J - - +-G% -! - --J+ - -x -! - + - @a - -x - b@ʢ c -$"L2@ - - - -CALc -AA K)` -! - - -@ -a $a ' - N, -?G)á -,@ǠA+ -+?aǠA+PCG - - - -@ -G - -ߏN LJ -J2x -@Ȇ - -0 -` - - - C!?C` - - 1 -@ -M*@I -G - *,@ -@@ -M*@I - *,@ -@ -M*@I - -ql -@0 -G - ,@ -@@0 - ,@ -@0 -qp - -qp -` - -qIq - - -J -O+ -a
` -z - -."@ -o@l - -J - -O+ - -a
` -z - -."@ -o@l - -G@@ - - - - - -H -Hs - - -@r - -@ - -@ - -x - -@ -x -@^~ -
- - - - -r - -
I ->~ - - - -xH@B H@ -Q -Q - - - - -G@Q -@ - / -B - / - -@#
-;p ; - -GС@ʡ - -G@!x - - -G -!I@ -R B@h - ?@C -H:
B G) -@!D # -G -G -GB G -G -} -xQ - -;Gp ; - -GБ@ʡ - - ;R` G)"j ! (! )I - - -@ - -Ϡ -Aaa - -@G1 -N - -I - - -@ -G -Ϡ -Aaa -@ -@ - -I,J:9>>>G@ -@ -s@ -c@ -T@ - -G$@ -@&x - - - - - - - -G @c@J - I - -CJ -G:G@c -q@1@ɑ - I - - - - - -@x -@x@9 -xjst -r,s-nuua u -qs@! - - -@@ - -@@ - -} - - - a -I -0020ȁ - - - -zJa CG - - -H - -t@#sRP @#tR` G)"j ! - - - -B @#BH #BP B @ @s@ @ tx -s - -B #BH #BP B @ s@IGr @ G - H - - -a -G@GA -I -I - - @ -#"@ - I - -@*x -@ -O - -" -x$r$ -O -, -" - - - -G @@# - -G"@ #@ - -L - -A -pA - -B@ -p3@ - - - - -1@A @@N @@ - -@x - - - -
- -P - - - - -x@ -C - - - - -@x - - - - - - - - - C!?C` - -q - - - -K -@x -PH NL -xqMЀ @LF -PJ N, -
-@xM@
Ҁ -
-@ -0q\ -J@ -@K<@Oq - -q -L@ -A@ -A@ -c@ -0Aa ,@ - -`! - - -A@ -0 - -Db -DD0J 0!0 - - - p T p0X -02p0 -K@ - -1L3 - - - - -0 -p -q - -q
@ - -@ - -@ - -pF<@Op -a@ - -Q - - 2@ - -A - - - - 2@ - -A - - - - 2@ - -A - - - 2@ - -A - - - -q -1@ -@@P1I - - 0P -0@ - - - - - -@%1 - @ - -@M -@"1 diff --git a/media_base_config.mk b/media_base_config.mk new file mode 100644 index 0000000..aa1bd5d --- a/dev/null +++ b/media_base_config.mk @@ -0,0 +1,13 @@ +MEDIA_BASE_PATH := $(call my-dir) + +AMAVUTILS_PATH:=$(MEDIA_BASE_PATH)/amavutils/ +AMACODEC_PATH:=$(MEDIA_BASE_PATH)/amcodec/ +AMVDEC_PATH:=$(MEDIA_BASE_PATH)/amvdec/ + +AMADEC_PATH:=$(TOP)/vendor/amlogic/frameworks/av/libaudio/amadec + +AMCODEC_NEED_INCLUDE := \ + $(AMAVUTILS_PATH)/include \ + $(AMACODEC_PATH)/include \ + $(AMADEC_PATH)/include + diff --git a/player/Android.mk b/player/Android.mk new file mode 100644 index 0000000..f5078ab --- a/dev/null +++ b/player/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := esplayer +LOCAL_MODULE_TAGS := optional +LOCAL_SRC_FILES := esplayer.c +LOCAL_ARM_MODE := arm + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../amcodec/include \ + $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := \ + libamcodec + +ifneq (0, $(shell expr $(PLATFORM_VERSION) \>= 5.0)) +LOCAL_SHARED_LIBRARIES += libsystemcontrolservice +else +LOCAL_SHARED_LIBRARIES += libsystemwriteservice +endif + +include $(BUILD_EXECUTABLE) diff --git a/player/esplayer.c b/player/esplayer.c new file mode 100644 index 0000000..36177d7 --- a/dev/null +++ b/player/esplayer.c @@ -0,0 +1,288 @@ +/************************************************** +* example based on amcodec +**************************************************/ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <errno.h> +#include <codec.h> +#include <stdbool.h> +#include <ctype.h> +#include <unistd.h> + + + +#define READ_SIZE (64 * 1024) +#define EXTERNAL_PTS (1) +#define SYNC_OUTSIDE (2) +#define UNIT_FREQ 96000 +#define PTS_FREQ 90000 +#define AV_SYNC_THRESH PTS_FREQ*30 + +static codec_para_t v_codec_para; +static codec_para_t a_codec_para; +static codec_para_t *pcodec, *apcodec, *vpcodec; +static char *filename; +FILE* fp = NULL; +static int axis[8] = {0}; + +int osd_blank(char *path, int cmd) +{ + int fd; + char bcmd[16]; + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + + if (fd >= 0) { + sprintf(bcmd, "%d", cmd); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int set_tsync_enable(int enable) +{ + int fd; + char *path = "/sys/class/tsync/enable"; + char bcmd[16]; + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + sprintf(bcmd, "%d", enable); + write(fd, bcmd, strlen(bcmd)); + close(fd); + return 0; + } + + return -1; +} + +int parse_para(const char *para, int para_num, int *result) +{ + char *endp; + const char *startp = para; + int *out = result; + int len = 0, count = 0; + + if (!startp) { + return 0; + } + + len = strlen(startp); + + do { + //filter space out + while (startp && (isspace(*startp) || !isgraph(*startp)) && len) { + startp++; + len--; + } + + if (len == 0) { + break; + } + + *out++ = strtol(startp, &endp, 0); + + len -= endp - startp; + startp = endp; + count++; + + } while ((endp) && (count < para_num) && (len > 0)); + + return count; +} + +int set_display_axis(int recovery) +{ + int fd; + char *path = "/sys/class/display/axis"; + char str[128]; + int count, i; + fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644); + if (fd >= 0) { + if (!recovery) { + read(fd, str, 128); + printf("read axis %s, length %zu\n", str, strlen(str)); + count = parse_para(str, 8, axis); + } + if (recovery) { + sprintf(str, "%d %d %d %d %d %d %d %d", + axis[0], axis[1], axis[2], axis[3], axis[4], axis[5], axis[6], axis[7]); + } else { + sprintf(str, "2048 %d %d %d %d %d %d %d", + axis[1], axis[2], axis[3], axis[4], axis[5], axis[6], axis[7]); + } + write(fd, str, strlen(str)); + close(fd); + return 0; + } + + return -1; +} + +static void signal_handler(int signum) +{ + printf("Get signum=%x\n", signum); + codec_close(apcodec); + codec_close(vpcodec); + fclose(fp); + set_display_axis(1); + signal(signum, SIG_DFL); + raise(signum); +} + +int main(int argc, char *argv[]) +{ + int ret = CODEC_ERROR_NONE; + char buffer[READ_SIZE]; + + int len = 0; + int size = READ_SIZE; + uint32_t Readlen; + uint32_t isize; + struct buf_status vbuf; + + if (argc < 6) { + printf("Corret command: esplayer <filename> <width> <height> <fps> <format(1:mpeg4 2:h264 6:vc1)> [subformat for mpeg4/vc1]\n"); + return -1; + } + osd_blank("/sys/class/graphics/fb0/blank", 1); + osd_blank("/sys/class/graphics/fb1/blank", 0); + set_display_axis(0); +#ifdef AUDIO_ES + apcodec = &a_codec_para; + memset(apcodec, 0, sizeof(codec_para_t)); +#endif + + vpcodec = &v_codec_para; + memset(vpcodec, 0, sizeof(codec_para_t)); + + vpcodec->has_video = 1; + vpcodec->video_type = atoi(argv[5]); + if (vpcodec->video_type == VFORMAT_H264) { + vpcodec->am_sysinfo.format = VIDEO_DEC_FORMAT_H264; + vpcodec->am_sysinfo.param = (void *)(EXTERNAL_PTS | SYNC_OUTSIDE); + } else if (vpcodec->video_type == VFORMAT_VC1) { + if (argc < 7) { + printf("No subformat for vc1, take the default VIDEO_DEC_FORMAT_WVC1\n"); + vpcodec->am_sysinfo.format = VIDEO_DEC_FORMAT_WVC1; + } else { + vpcodec->am_sysinfo.format = atoi(argv[6]); + } + } else if (vpcodec->video_type == VFORMAT_MPEG4) { + if (argc < 7) { + printf("No subformat for mpeg4, take the default VIDEO_DEC_FORMAT_MPEG4_5\n"); + vpcodec->am_sysinfo.format = VIDEO_DEC_FORMAT_MPEG4_5; + } else { + vpcodec->am_sysinfo.format = atoi(argv[6]); + } + } + + vpcodec->stream_type = STREAM_TYPE_ES_VIDEO; + vpcodec->am_sysinfo.rate = 96000 / atoi(argv[4]); + vpcodec->am_sysinfo.height = atoi(argv[3]); + vpcodec->am_sysinfo.width = atoi(argv[2]); + vpcodec->has_audio = 0; + vpcodec->noblock = 0; + +#ifdef AUDIO_ES + apcodec->audio_type = AFORMAT_MPEG; + apcodec->stream_type = STREAM_TYPE_ES_AUDIO; + apcodec->audio_pid = 0x1023; + apcodec->has_audio = 1; + apcodec->audio_channels = 2; + apcodec->audio_samplerate = 48000; + apcodec->noblock = 0; + apcodec->audio_info.channels = 2; + apcodec->audio_info.sample_rate = 48000; +#endif + + printf("\n*********CODEC PLAYER DEMO************\n\n"); + filename = argv[1]; + printf("file %s to be played\n", filename); + + if ((fp = fopen(filename, "rb")) == NULL) { + printf("open file error!\n"); + return -1; + } + +#ifdef AUDIO_ES + ret = codec_init(apcodec); + if (ret != CODEC_ERROR_NONE) { + printf("codec init failed, ret=-0x%x", -ret); + return -1; + } +#endif + + ret = codec_init(vpcodec); + if (ret != CODEC_ERROR_NONE) { + printf("codec init failed, ret=-0x%x", -ret); + return -1; + } + printf("video codec ok!\n"); + + //codec_set_cntl_avthresh(vpcodec, AV_SYNC_THRESH); + //codec_set_cntl_syncthresh(vpcodec, 0); + + set_tsync_enable(0); + + pcodec = vpcodec; + while (!feof(fp)) { + Readlen = fread(buffer, 1, READ_SIZE, fp); + //printf("Readlen %d\n", Readlen); + if (Readlen <= 0) { + printf("read file error!\n"); + rewind(fp); + } + + isize = 0; + do { + ret = codec_write(pcodec, buffer + isize, Readlen); + if (ret < 0) { + if (errno != EAGAIN) { + printf("write data failed, errno %d\n", errno); + goto error; + } else { + continue; + } + } else { + isize += ret; + } + //printf("ret %d, isize %d\n", ret, isize); + } while (isize < Readlen); + + signal(SIGCHLD, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGHUP, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + } + + do { + ret = codec_get_vbuf_state(pcodec, &vbuf); + if (ret != 0) { + printf("codec_get_vbuf_state error: %x\n", -ret); + goto error; + } + } while (vbuf.data_len > 0x100); + +error: +#ifdef AUDIO_ES + codec_close(apcodec); +#endif + codec_close(vpcodec); + fclose(fp); + set_display_axis(1); + + return 0; +} + |