summaryrefslogtreecommitdiff
authorPeng Yixin <yixin.peng@amlogic.com>2019-05-17 09:04:34 (GMT)
committer Hui Zhang <hui.zhang@amlogic.com>2019-07-10 04:15:46 (GMT)
commit107c76a4342b702d4e388096c3d6b23c8db1723a (patch)
treeef5773749dfd1805453091e3f55ebc054e1bbefb
parent32f67f04f73906370751a6308c4f7210d80f8aa6 (diff)
downloadmedia_modules-107c76a4342b702d4e388096c3d6b23c8db1723a.zip
media_modules-107c76a4342b702d4e388096c3d6b23c8db1723a.tar.gz
media_modules-107c76a4342b702d4e388096c3d6b23c8db1723a.tar.bz2
media: support stream mode for AVS multi-instance [1/4]
PD#SWPL-5860 Problem: Decoder cannot support stream mode for AVS multi-instance. Solution: add C driver code and video_ucode.bin ucode gerrit id: 74323 ucode change id: I6ae493b1ce8ee4494719d0af3cf636a8ca73de60 Verify: U212 Change-Id: If3339d8c02e2d842a4c23d45154b5a2f7c289dfc Signed-off-by: Peng Yixin <yixin.peng@amlogic.com>
Diffstat
-rw-r--r--Media.mk1
-rw-r--r--drivers/frame_provider/decoder/Makefile1
-rw-r--r--drivers/frame_provider/decoder/avs_multi/Makefile2
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avs_multi.c3814
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avs_multi.h90
-rw-r--r--drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c5065
6 files changed, 8973 insertions, 0 deletions
diff --git a/Media.mk b/Media.mk
index 8ca1d1d..ba112cf 100644
--- a/Media.mk
+++ b/Media.mk
@@ -18,6 +18,7 @@ CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \
CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \
CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
CONFIG_AMLOGIC_MEDIA_VENC_H265=m
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile
index 12121b4..6511f25 100644
--- a/drivers/frame_provider/decoder/Makefile
+++ b/drivers/frame_provider/decoder/Makefile
@@ -10,3 +10,4 @@ obj-y += mjpeg/
obj-y += real/
obj-y += avs/
obj-y += avs2/
+obj-y += avs_multi/
diff --git a/drivers/frame_provider/decoder/avs_multi/Makefile b/drivers/frame_provider/decoder/avs_multi/Makefile
new file mode 100644
index 0000000..b281b40
--- a/dev/null
+++ b/drivers/frame_provider/decoder/avs_multi/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs.o
+amvdec_mavs-objs += avs_multi.o avsp_trans_multi.o
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
new file mode 100644
index 0000000..11813ad
--- a/dev/null
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -0,0 +1,3814 @@
+/*
+ * drivers/amlogic/amports/vavs.c
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#define DEBUG
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/utils/vdec_reg.h>
+#include "../../../stream_input/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_multi.h"
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/firmware.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include <linux/amlogic/tee.h>
+
+#define DEBUG_MULTI_FLAG 0
+
+#define DRIVER_NAME "amvdec_avs"
+#define MODULE_NAME "amvdec_avs"
+
+#define MULTI_DRIVER_NAME "ammvdec_avs"
+
+#define ENABLE_USER_DATA
+
+#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+#define NV21
+#endif
+
+#define USE_AVS_SEQ_INFO
+#define HANDLE_AVS_IRQ
+#define DEBUG_PTS
+
+#define CHECK_INTERVAL (HZ/100)
+
+#define I_PICTURE 0
+#define P_PICTURE 1
+#define B_PICTURE 2
+
+#define LMEM_BUF_SIZE (0x500 * 2)
+
+/* #define ORI_BUFFER_START_ADDR 0x81000000 */
+#define ORI_BUFFER_START_ADDR 0x80000000
+
+#define INTERLACE_FLAG 0x80
+#define TOP_FIELD_FIRST_FLAG 0x40
+
+/* protocol registers */
+#define AVS_PIC_RATIO AV_SCRATCH_0
+#define AVS_PIC_WIDTH AV_SCRATCH_1
+#define AVS_PIC_HEIGHT AV_SCRATCH_2
+#define AVS_FRAME_RATE AV_SCRATCH_3
+
+/*#define AVS_ERROR_COUNT AV_SCRATCH_6*/
+#define AVS_SOS_COUNT AV_SCRATCH_7
+#define AVS_BUFFERIN AV_SCRATCH_8
+#define AVS_BUFFEROUT AV_SCRATCH_9
+#define AVS_REPEAT_COUNT AV_SCRATCH_A
+#define AVS_TIME_STAMP AV_SCRATCH_B
+#define AVS_OFFSET_REG AV_SCRATCH_C
+#define MEM_OFFSET_REG AV_SCRATCH_F
+#define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G
+
+#define DECODE_MODE AV_SCRATCH_6
+#define DECODE_MODE_SINGLE 0x0
+#define DECODE_MODE_MULTI_FRAMEBASE 0x1
+#define DECODE_MODE_MULTI_STREAMBASE 0x2
+
+#define DECODE_STATUS AV_SCRATCH_H
+#define DECODE_STATUS_PIC_DONE 0x1
+#define DECODE_STATUS_DECODE_BUF_EMPTY 0x2
+#define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3
+#define DECODE_SEARCH_HEAD 0xff
+
+#define DECODE_STOP_POS AV_SCRATCH_J
+
+#define DECODE_LMEM_BUF_ADR AV_SCRATCH_I
+
+#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
+
+
+static void check_timer_func(unsigned long arg);
+static void vavs_work(struct work_struct *work);
+
+#define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001
+static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE;
+
+
+#define VPP_VD1_POSTBLEND (1 << 10)
+
+static int debug;
+#define debug_flag debug
+static unsigned int debug_mask = 0xff;
+
+/*for debug*/
+/*
+ udebug_flag:
+ bit 0, enable ucode print
+ bit 1, enable ucode detail print
+ bit [31:16] not 0, pos to dump lmem
+ bit 2, pop bits to lmem
+ bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
+*/
+static u32 udebug_flag;
+/*
+ when udebug_flag[1:0] is not 0
+ udebug_pause_pos not 0,
+ pause position
+*/
+static u32 udebug_pause_pos;
+/*
+ when udebug_flag[1:0] is not 0
+ and udebug_pause_pos is not 0,
+ pause only when DEBUG_REG2 is equal to this val
+*/
+static u32 udebug_pause_val;
+
+static u32 udebug_pause_decode_idx;
+
+static u32 force_fps;
+
+static u32 step;
+
+#define AVS_DEV_NUM 9
+static unsigned int max_decode_instance_num = AVS_DEV_NUM;
+static unsigned int max_process_time[AVS_DEV_NUM];
+static unsigned int max_get_frame_interval[AVS_DEV_NUM];
+
+static unsigned int decode_timeout_val = 100;
+static unsigned int start_decode_buf_level = 0x8000;
+
+/********************************
+firmware_sel
+ 0: use avsp_trans long cabac ucode;
+ 1: not use avsp_trans long cabac ucode
+ in ucode:
+ #define USE_EXT_BUFFER_ASSIGNMENT
+ #undef USE_DYNAMIC_BUF_NUM
+********************************/
+static int firmware_sel;
+static int disable_longcabac_trans = 1;
+
+
+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 int vavs_event_cb(int type, void *data, void *private_data);
+
+static const char vavs_dec_id[] = "vavs-dev";
+
+#define PROVIDER_NAME "decoder.avs"
+static DEFINE_SPINLOCK(lock);
+static DEFINE_MUTEX(vavs_mutex);
+
+static const struct vframe_operations_s vavs_vf_provider = {
+ .peek = vavs_vf_peek,
+ .get = vavs_vf_get,
+ .put = vavs_vf_put,
+ .event_cb = vavs_event_cb,
+ .vf_states = vavs_vf_states,
+};
+/*
+static void *mm_blk_handle;
+*/
+static struct vframe_provider_s vavs_vf_prov;
+
+#define VF_BUF_NUM_MAX 16
+#define WORKSPACE_SIZE (4 * SZ_1M)
+
+#ifdef AVSP_LONG_CABAC
+#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2)
+#define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE)
+#else
+#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 1)
+#endif
+
+#define RV_AI_BUFF_START_ADDR 0x01a00000
+#define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000
+
+static u32 vf_buf_num = 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
+
+#if 0
+static struct vframe_s vfpool[VF_POOL_SIZE];
+/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
+static struct vframe_s *cur_vfpool;
+static unsigned char recover_flag;
+static s32 vfbuf_use[VF_BUF_NUM_MAX];
+static u32 saved_resolution;
+static u32 frame_width, frame_height, frame_dur, frame_prog;
+static struct timer_list recycle_timer;
+static u32 stat;
+#endif
+static u32 buf_size = 32 * 1024 * 1024;
+#if 0
+static u32 buf_offset;
+static u32 avi_flag;
+static u32 vavs_ratio;
+static u32 pic_type;
+#endif
+static u32 pts_by_offset = 1;
+#if 0
+static u32 total_frame;
+static u32 next_pts;
+static unsigned char throw_pb_flag;
+#ifdef DEBUG_PTS
+static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
+#endif
+#endif
+static u32 radr, rval;
+static u32 dbg_cmd;
+#if 0
+static struct dec_sysinfo vavs_amstream_dec_info;
+static struct vdec_info *gvs;
+static u32 fr_hint_status;
+static struct work_struct notify_work;
+static struct work_struct set_clk_work;
+static bool is_reset;
+#endif
+/*static struct vdec_s *vdec;*/
+
+#ifdef AVSP_LONG_CABAC
+static struct work_struct long_cabac_wd_work;
+void *es_write_addr_virt;
+dma_addr_t es_write_addr_phy;
+
+void *bitstream_read_tmp;
+dma_addr_t bitstream_read_tmp_phy;
+void *avsp_heap_adr;
+static uint long_cabac_busy;
+#endif
+
+#if 0
+#ifdef ENABLE_USER_DATA
+static void *user_data_buffer;
+static dma_addr_t user_data_buffer_phys;
+#endif
+static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
+#endif
+static inline u32 index2canvas(u32 index)
+{
+ const u32 canvas_tab[VF_BUF_NUM_MAX] = {
+ 0x010100, 0x030302, 0x050504, 0x070706,
+ 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e,
+ 0x111110, 0x131312, 0x151514, 0x171716,
+ 0x191918, 0x1b1b1a, 0x1d1d1c, 0x1f1f1e,
+ };
+ const u32 canvas_tab_3[4] = {
+ 0x010100, 0x040403, 0x070706, 0x0a0a09
+ };
+
+ if (canvas_num == 2)
+ return canvas_tab[index] + (canvas_base << 16)
+ + (canvas_base << 8) + canvas_base;
+
+ return canvas_tab_3[index] + (canvas_base << 16)
+ + (canvas_base << 8) + canvas_base;
+}
+
+static const u32 frame_rate_tab[16] = {
+ 96000 / 30, /* forbidden */
+ 96000000 / 23976, /* 24000/1001 (23.967) */
+ 96000 / 24,
+ 96000 / 25,
+ 9600000 / 2997, /* 30000/1001 (29.97) */
+ 96000 / 30,
+ 96000 / 50,
+ 9600000 / 5994, /* 60000/1001 (59.94) */
+ 96000 / 60,
+ /* > 8 reserved, use 24 */
+ 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24,
+ 96000 / 24, 96000 / 24, 96000 / 24
+};
+
+#define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX
+struct vdec_avs_hw_s {
+ spinlock_t lock;
+ unsigned char m_ins_flag;
+ struct platform_device *platform_dev;
+ DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+ DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
+ struct vframe_s vfpool[VF_POOL_SIZE];
+ s32 vfbuf_use[VF_BUF_NUM_MAX];
+ unsigned char again_flag;
+ unsigned char recover_flag;
+ u32 frame_width;
+ u32 frame_height;
+ u32 frame_dur;
+ u32 frame_prog;
+ u32 saved_resolution;
+ u32 avi_flag;
+ u32 vavs_ratio;
+ u32 pic_type;
+
+ u32 vf_buf_num_used;
+ u32 total_frame;
+ u32 next_pts;
+ unsigned char throw_pb_flag;
+#ifdef DEBUG_PTS
+ u32 pts_hit;
+ u32 pts_missed;
+ u32 pts_i_hit;
+ u32 pts_i_missed;
+#endif
+#ifdef ENABLE_USER_DATA
+ struct work_struct userdata_push_work;
+ void *user_data_buffer;
+ dma_addr_t user_data_buffer_phys;
+#endif
+ void *lmem_addr;
+ dma_addr_t lmem_phy_addr;
+
+ u32 buf_offset;
+
+ struct dec_sysinfo vavs_amstream_dec_info;
+ struct vdec_info *gvs;
+ u32 fr_hint_status;
+ struct work_struct set_clk_work;
+ bool is_reset;
+
+ /*debug*/
+ u32 ucode_pause_pos;
+ /**/
+ u32 decode_pic_count;
+ u8 reset_decode_flag;
+ u32 display_frame_count;
+ u32 buf_status;
+ /*
+ buffer_status &= ~buf_recycle_status
+ */
+ u32 buf_recycle_status;
+ u32 seqinfo;
+ u32 ctx_valid;
+ u32 dec_control;
+ void *mm_blk_handle;
+ struct vframe_chunk_s *chunk;
+ u32 stat;
+ u8 init_flag;
+ unsigned long buf_start;
+ u32 buf_size;
+
+ u32 reg_scratch_0;
+ u32 reg_scratch_1;
+ u32 reg_scratch_2;
+ u32 reg_scratch_3;
+ u32 reg_scratch_4;
+ u32 reg_scratch_5;
+ u32 reg_scratch_6;
+ u32 reg_scratch_7;
+ u32 reg_scratch_8;
+ u32 reg_scratch_9;
+ u32 reg_scratch_A;
+ u32 reg_scratch_B;
+ u32 reg_scratch_C;
+ u32 reg_scratch_D;
+ u32 reg_scratch_E;
+ u32 reg_scratch_F;
+ u32 reg_scratch_G;
+ u32 reg_scratch_H;
+ u32 reg_scratch_I;
+ u32 reg_mb_width;
+ u32 reg_viff_bit_cnt;
+ u32 reg_canvas_addr;
+ u32 reg_dbkr_canvas_addr;
+ u32 reg_dbkw_canvas_addr;
+ u32 reg_anc2_canvas_addr;
+ u32 reg_anc0_canvas_addr;
+ u32 reg_anc1_canvas_addr;
+ u32 slice_ver_pos_pic_type;
+ u32 vc1_control_reg;
+ u32 avs_co_mb_wr_addr;
+ u32 slice_start_byte_01;
+ u32 slice_start_byte_23;
+ u32 vcop_ctrl_reg;
+ u32 iqidct_control;
+ u32 rv_ai_mb_count;
+ u32 slice_qp;
+ u32 dc_scaler;
+ u32 avsp_iq_wq_param_01;
+ u32 avsp_iq_wq_param_23;
+ u32 avsp_iq_wq_param_45;
+ u32 avs_co_mb_rd_addr;
+ u32 dblk_mb_wid_height;
+ u32 mc_pic_w_h;
+ u32 avs_co_mb_rw_ctl;
+ u32 vld_decode_control;
+
+ struct timer_list check_timer;
+ u32 decode_timeout_count;
+ unsigned long int start_process_time;
+ u32 last_vld_level;
+ u32 eos;
+ u32 canvas_spec[DECODE_BUFFER_NUM_MAX];
+ struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2];
+
+ s32 refs[2];
+ int dec_result;
+ struct timer_list recycle_timer;
+ struct work_struct work;
+ struct work_struct notify_work;
+ atomic_t error_handler_run;
+ struct work_struct fatal_error_wd_work;
+ void (*vdec_cb)(struct vdec_s *, void *);
+ void *vdec_cb_arg;
+/* for error handling */
+ u32 first_i_frame_ready;
+ u32 run_count;
+ u32 not_run_ready;
+ u32 input_empty;
+ u32 prepare_num;
+ u32 put_num;
+ u32 peek_num;
+ u32 get_num;
+ u32 drop_frame_count;
+ u32 buffer_not_ready;
+ int frameinfo_enable;
+ struct firmware_s *fw;
+};
+
+static void reset_process_time(struct vdec_avs_hw_s *hw);
+static void start_process_time(struct vdec_avs_hw_s *hw);
+static void vavs_save_regs(struct vdec_avs_hw_s *hw);
+
+struct vdec_avs_hw_s *ghw;
+
+#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs"
+
+#define DEC_RESULT_NONE 0
+#define DEC_RESULT_DONE 1
+#define DEC_RESULT_AGAIN 2
+#define DEC_RESULT_ERROR 3
+#define DEC_RESULT_FORCE_EXIT 4
+#define DEC_RESULT_EOS 5
+#define DEC_RESULT_GET_DATA 6
+#define DEC_RESULT_GET_DATA_RETRY 7
+#define DEC_RESULT_USERDATA 8
+
+#define DECODE_ID(hw) (hw->m_ins_flag? 0 : hw_to_vdec(hw)->id)
+
+#define PRINT_FLAG_ERROR 0x0
+#define PRINT_FLAG_RUN_FLOW 0X0001
+#define PRINT_FLAG_DECODING 0x0002
+#define PRINT_FLAG_VFRAME_DETAIL 0x0010
+#define PRINT_FLAG_VLD_DETAIL 0x0020
+#define PRINT_FLAG_DEC_DETAIL 0x0040
+#define PRINT_FLAG_BUFFER_DETAIL 0x0080
+#define PRINT_FLAG_FORCE_DONE 0x0100
+#define PRINT_FLAG_COUNTER 0X0200
+#define PRINT_FRAMEBASE_DATA 0x0400
+#define PRINT_FLAG_PARA_DATA 0x1000
+#define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000
+#define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000
+#define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000
+
+#undef pr_info
+#define pr_info printk
+static int debug_print(struct vdec_avs_hw_s *hw,
+ int flag, const char *fmt, ...)
+{
+#define AVS_PRINT_BUF 256
+ unsigned char buf[AVS_PRINT_BUF];
+ int len = 0;
+ int index = hw->m_ins_flag ? DECODE_ID(hw) : 0;
+ if (hw == NULL ||
+ (flag == 0) ||
+ ((debug_mask &
+ (1 << index))
+ && (debug & flag))) {
+ va_list args;
+
+ va_start(args, fmt);
+ if (hw)
+ len = sprintf(buf, "[%d]", index);
+ vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args);
+ pr_debug("%s", buf);
+ va_end(args);
+ }
+ return 0;
+}
+
+static int debug_print_cont(struct vdec_avs_hw_s *hw,
+ int flag, const char *fmt, ...)
+{
+ unsigned char buf[AVS_PRINT_BUF];
+ int len = 0;
+ int index = hw->m_ins_flag ? DECODE_ID(hw) : 0;
+ if (hw == NULL ||
+ (flag == 0) ||
+ ((debug_mask &
+ (1 << index))
+ && (debug & flag))) {
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args);
+ pr_info("%s", buf);
+ va_end(args);
+ }
+ return 0;
+}
+
+static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf,
+ unsigned int *duration)
+{
+ int ar = 0;
+
+ unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO);
+ hw->prepare_num++;
+#ifndef USE_AVS_SEQ_INFO
+ if (hw->vavs_amstream_dec_info.width > 0
+ && hw->vavs_amstream_dec_info.height > 0) {
+ vf->width = hw->vavs_amstream_dec_info.width;
+ vf->height = hw->vavs_amstream_dec_info.height;
+ } else
+#endif
+ {
+ vf->width = READ_VREG(AVS_PIC_WIDTH);
+ vf->height = READ_VREG(AVS_PIC_HEIGHT);
+ hw->frame_width = vf->width;
+ hw->frame_height = vf->height;
+ /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/
+ }
+
+#ifndef USE_AVS_SEQ_INFO
+ if (hw->vavs_amstream_dec_info.rate > 0)
+ *duration = hw->vavs_amstream_dec_info.rate;
+ else
+#endif
+ {
+ *duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf];
+ /* pr_info("%s: duration = %d\n", __func__, *duration); */
+ hw->frame_dur = *duration;
+ schedule_work(&hw->notify_work);
+ }
+
+ if (hw->vavs_ratio == 0) {
+ /* always stretch to 16:9 */
+ vf->ratio_control |= (0x90 <<
+ DISP_RATIO_ASPECT_RATIO_BIT);
+ } else {
+ switch (pixel_ratio) {
+ case 1:
+ ar = (vf->height * hw->vavs_ratio) / vf->width;
+ break;
+ case 2:
+ ar = (vf->height * 3 * hw->vavs_ratio) / (vf->width * 4);
+ break;
+ case 3:
+ ar = (vf->height * 9 * hw->vavs_ratio) / (vf->width * 16);
+ break;
+ case 4:
+ ar = (vf->height * 100 * hw->vavs_ratio) / (vf->width *
+ 221);
+ break;
+ default:
+ ar = (vf->height * hw->vavs_ratio) / vf->width;
+ break;
+ }
+ }
+
+ ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
+
+ vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
+ /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */
+
+ vf->flag = 0;
+}
+
+#ifdef ENABLE_USER_DATA
+
+/*static struct work_struct userdata_push_work;*/
+/*
+#define DUMP_LAST_REPORTED_USER_DATA
+*/
+static void userdata_push_process(struct vdec_avs_hw_s *hw)
+{
+ unsigned int user_data_flags;
+ unsigned int user_data_wp;
+ unsigned int user_data_length;
+ struct userdata_poc_info_t user_data_poc;
+#ifdef DUMP_LAST_REPORTED_USER_DATA
+ int user_data_len;
+ int wp_start;
+ unsigned char *pdata;
+ int nLeft;
+#endif
+
+ user_data_flags = READ_VREG(AV_SCRATCH_N);
+ user_data_wp = (user_data_flags >> 16) & 0xffff;
+ user_data_length = user_data_flags & 0x7fff;
+
+#ifdef DUMP_LAST_REPORTED_USER_DATA
+ dma_sync_single_for_cpu(amports_get_dma_device(),
+ hw->user_data_buffer_phys, USER_DATA_SIZE,
+ DMA_FROM_DEVICE);
+
+ if (user_data_length & 0x07)
+ user_data_len = (user_data_length + 8) & 0xFFFFFFF8;
+ else
+ user_data_len = user_data_length;
+
+ if (user_data_wp >= user_data_len) {
+ wp_start = user_data_wp - user_data_len;
+
+ pdata = (unsigned char *)hw->user_data_buffer;
+ pdata += wp_start;
+ nLeft = user_data_len;
+ while (nLeft >= 8) {
+ pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ pdata[0], pdata[1], pdata[2], pdata[3],
+ pdata[4], pdata[5], pdata[6], pdata[7]);
+ nLeft -= 8;
+ pdata += 8;
+ }
+ } else {
+ wp_start = user_data_wp +
+ USER_DATA_SIZE - user_data_len;
+
+ pdata = (unsigned char *)hw->user_data_buffer;
+ pdata += wp_start;
+ nLeft = USER_DATA_SIZE - wp_start;
+
+ while (nLeft >= 8) {
+ pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ pdata[0], pdata[1], pdata[2], pdata[3],
+ pdata[4], pdata[5], pdata[6], pdata[7]);
+ nLeft -= 8;
+ pdata += 8;
+ }
+
+ pdata = (unsigned char *)hw->user_data_buffer;
+ nLeft = user_data_wp;
+ while (nLeft >= 8) {
+ pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ pdata[0], pdata[1], pdata[2], pdata[3],
+ pdata[4], pdata[5], pdata[6], pdata[7]);
+ nLeft -= 8;
+ pdata += 8;
+ }
+ }
+#endif
+
+/*
+ pr_info("pocinfo 0x%x, poc %d, wp 0x%x, len %d\n",
+ READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M),
+ user_data_wp, user_data_length);
+*/
+ user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L);
+ user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M);
+
+ WRITE_VREG(AV_SCRATCH_N, 0);
+/*
+ wakeup_userdata_poll(user_data_poc, user_data_wp,
+ (unsigned long)hw->user_data_buffer,
+ USER_DATA_SIZE, user_data_length);
+*/
+}
+
+static void userdata_push_do_work(struct work_struct *work)
+{
+ struct vdec_avs_hw_s *hw =
+ container_of(work, struct vdec_avs_hw_s, userdata_push_work);
+ userdata_push_process(hw);
+}
+
+static u8 UserDataHandler(struct vdec_avs_hw_s *hw)
+{
+ unsigned int user_data_flags;
+
+ user_data_flags = READ_VREG(AV_SCRATCH_N);
+ if (user_data_flags & (1 << 15)) { /* data ready */
+ if (hw->m_ins_flag) {
+ hw->dec_result = DEC_RESULT_USERDATA;
+ vdec_schedule_work(&hw->work);
+ return 1;
+ } else
+ schedule_work(&hw->userdata_push_work);
+ }
+ return 0;
+}
+#endif
+
+#ifdef HANDLE_AVS_IRQ
+static irqreturn_t vavs_isr(int irq, void *dev_id)
+#else
+static void vavs_isr(void)
+#endif
+{
+ u32 reg;
+ struct vframe_s *vf;
+ u32 dur;
+ u32 repeat_count;
+ u32 picture_type;
+ u32 buffer_index;
+ u32 frame_size;
+ bool force_interlaced_frame = false;
+ unsigned int pts, pts_valid = 0, offset = 0;
+ u64 pts_us64;
+ u32 debug_tag;
+ u32 buffer_status_debug;
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id;
+
+ /*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);
+ }
+ }*/
+#define DEBUG_REG1 AV_SCRATCH_E
+#define DEBUG_REG2 AV_SCRATCH_D
+
+ debug_tag = READ_VREG(DEBUG_REG1);
+ buffer_status_debug = debug_tag >> 24;
+ debug_tag &= 0xffffff;
+ if (debug_tag & 0x10000) {
+ int i;
+ dma_sync_single_for_cpu(
+ amports_get_dma_device(),
+ hw->lmem_phy_addr,
+ LMEM_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
+ debug_print(hw, 0,
+ "LMEM<tag %x>:\n", debug_tag);
+
+ for (i = 0; i < 0x400; i += 4) {
+ int ii;
+ unsigned short *lmem_ptr = hw->lmem_addr;
+ if ((i & 0xf) == 0)
+ debug_print_cont(hw, 0, "%03x: ", i);
+ for (ii = 0; ii < 4; ii++) {
+ debug_print_cont(hw, 0, "%04x ",
+ lmem_ptr[i + 3 - ii]);
+ }
+ if (((i + ii) & 0xf) == 0)
+ debug_print_cont(hw, 0, "\n");
+ }
+
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == hw->decode_pic_count) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_VREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ hw->ucode_pause_pos = udebug_pause_pos;
+ }
+ else if (debug_tag & 0x20000)
+ hw->ucode_pause_pos = 0xffffffff;
+ if (hw->ucode_pause_pos)
+ reset_process_time(hw);
+ else
+ WRITE_VREG(DEBUG_REG1, 0);
+ } else if (debug_tag != 0) {
+ debug_print(hw, 0,
+ "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x\n",
+ debug_tag,
+ READ_VREG(DEBUG_REG2),
+ buffer_status_debug,
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_VREG(VIFF_BIT_CNT));
+ if (((udebug_pause_pos & 0xffff)
+ == (debug_tag & 0xffff)) &&
+ (udebug_pause_decode_idx == 0 ||
+ udebug_pause_decode_idx == hw->decode_pic_count) &&
+ (udebug_pause_val == 0 ||
+ udebug_pause_val == READ_VREG(DEBUG_REG2))) {
+ udebug_pause_pos &= 0xffff;
+ hw->ucode_pause_pos = udebug_pause_pos;
+ }
+ if (hw->ucode_pause_pos)
+ reset_process_time(hw);
+ else
+ WRITE_VREG(DEBUG_REG1, 0);
+ //return IRQ_HANDLED;
+ } else {
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s decode_status 0x%x, buffer_status 0x%x\n",
+ __func__,
+ READ_VREG(DECODE_STATUS),
+ buffer_status_debug);
+ }
+
+#ifdef AVSP_LONG_CABAC
+ if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) {
+#ifdef PERFORMANCE_DEBUG
+ pr_info("%s:schedule long_cabac_wd_work\r\n", __func__);
+#endif
+ pr_info("schedule long_cabac_wd_work and requested from %d\n",
+ (READ_VREG(LONG_CABAC_REQ) >> 8)&0xFF);
+ schedule_work(&long_cabac_wd_work);
+ }
+#endif
+
+#ifdef ENABLE_USER_DATA
+ if (UserDataHandler(hw))
+ return IRQ_HANDLED;
+#endif
+ reg = READ_VREG(AVS_BUFFEROUT);
+ if (reg) {
+ if (debug_flag & AVS_DEBUG_PRINT)
+ pr_info("AVS_BUFFEROUT=%x\n", reg);
+ if (pts_by_offset) {
+ offset = READ_VREG(AVS_OFFSET_REG);
+ if (debug_flag & AVS_DEBUG_PRINT)
+ pr_info("AVS OFFSET=%x\n", offset);
+ if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
+ &frame_size,
+ 0, &pts_us64) == 0) {
+ pts_valid = 1;
+#ifdef DEBUG_PTS
+ hw->pts_hit++;
+#endif
+ } else {
+#ifdef DEBUG_PTS
+ hw->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)
+ hw->pts_i_missed++;
+ else
+ hw->pts_i_hit++;
+ }
+#endif
+
+ if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
+ && hw->frame_width == 1920 && hw->frame_height == 1080) {
+ force_interlaced_frame = true;
+ }
+
+ if (hw->throw_pb_flag && picture_type != I_PICTURE) {
+
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for throwing picture with type of %d\n",
+ __func__,
+ ~(1 << buffer_index), picture_type);
+
+ WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index));
+ } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */
+ hw->throw_pb_flag = 0;
+
+ if (debug_flag & AVS_DEBUG_PRINT) {
+ pr_info("interlace, picture type %d\n",
+ picture_type);
+ }
+
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info
+ ("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ hw->pic_type = 2;
+ if ((picture_type == I_PICTURE) && pts_valid) {
+ vf->pts = pts;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* hw->next_pts = pts +
+ * (hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1)*15/16;
+ */
+ hw->next_pts =
+ pts +
+ (dur * repeat_count >> 1) *
+ 15 / 16;
+ } else
+ hw->next_pts = 0;
+ } else {
+ vf->pts = hw->next_pts;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1;
+ */
+ vf->duration = dur * repeat_count >> 1;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate >> 1;
+ */
+ vf->duration = dur >> 1;
+ hw->next_pts = 0;
+ }
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ if (force_interlaced_frame) {
+ vf->type = VIDTYPE_INTERLACE_TOP;
+ }else{
+ vf->type =
+ (reg & TOP_FIELD_FIRST_FLAG)
+ ? VIDTYPE_INTERLACE_TOP
+ : VIDTYPE_INTERLACE_BOTTOM;
+ }
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+
+ if (debug_flag & AVS_DEBUG_PRINT) {
+ pr_info("buffer_index %d, canvas addr %x\n",
+ buffer_index, vf->canvas0Addr);
+ }
+ vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+
+ kfifo_put(&hw->display_q,
+ (const struct vframe_s *)vf);
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ if (force_interlaced_frame)
+ vf->pts = 0;
+ else
+ vf->pts = hw->next_pts;
+
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration = hw->vavs_amstream_dec_info.rate *
+ * repeat_count >> 1;
+ */
+ vf->duration = dur * repeat_count >> 1;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration = hw->vavs_amstream_dec_info.rate
+ * >> 1;
+ */
+ vf->duration = dur >> 1;
+ hw->next_pts = 0;
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ if (force_interlaced_frame) {
+ vf->type = VIDTYPE_INTERLACE_BOTTOM;
+ } else {
+ vf->type =
+ (reg & TOP_FIELD_FIRST_FLAG) ?
+ VIDTYPE_INTERLACE_BOTTOM :
+ VIDTYPE_INTERLACE_TOP;
+ }
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+ vf->pts_us64 = 0;
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+
+ kfifo_put(&hw->display_q,
+ (const struct vframe_s *)vf);
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ hw->total_frame++;
+ } else { /* progressive */
+ hw->throw_pb_flag = 0;
+
+ if (debug_flag & AVS_DEBUG_PRINT) {
+ pr_info("progressive picture type %d\n",
+ picture_type);
+ }
+ if (kfifo_get(&hw->newframe_q, &vf) == 0) {
+ pr_info
+ ("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+ set_frame_info(hw, vf, &dur);
+ vf->bufWidth = 1920;
+ hw->pic_type = 1;
+
+ if ((picture_type == I_PICTURE) && pts_valid) {
+ vf->pts = pts;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* hw->next_pts = pts +
+ * (hw->vavs_amstream_dec_info.rate *
+ * repeat_count)*15/16;
+ */
+ hw->next_pts =
+ pts +
+ (dur * repeat_count) * 15 / 16;
+ } else
+ hw->next_pts = 0;
+ } else {
+ vf->pts = hw->next_pts;
+ if ((repeat_count > 1) && hw->avi_flag) {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate *
+ * repeat_count;
+ */
+ vf->duration = dur * repeat_count;
+ if (hw->next_pts != 0) {
+ hw->next_pts +=
+ ((vf->duration) -
+ ((vf->duration) >> 4));
+ }
+ } else {
+ /* vf->duration =
+ * hw->vavs_amstream_dec_info.rate;
+ */
+ vf->duration = dur;
+ hw->next_pts = 0;
+ }
+ }
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->duration_pulldown = 0;
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
+#ifdef NV21
+ vf->type |= VIDTYPE_VIU_NV21;
+#endif
+ if (hw->m_ins_flag) {
+ vf->canvas0Addr = vf->canvas1Addr = -1;
+ vf->plane_num = 2;
+
+ vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
+
+ vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
+ vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
+ } else
+ vf->canvas0Addr = vf->canvas1Addr =
+ index2canvas(buffer_index);
+ vf->type_original = vf->type;
+
+ vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
+ if (debug_flag & AVS_DEBUG_PRINT) {
+ pr_info("buffer_index %d, canvas addr %x\n",
+ buffer_index, vf->canvas0Addr);
+ }
+
+ hw->vfbuf_use[buffer_index]++;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hw->mm_blk_handle,
+ buffer_index);
+ kfifo_put(&hw->display_q,
+ (const struct vframe_s *)vf);
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ hw->total_frame++;
+ }
+
+ /*count info*/
+ hw->gvs->frame_dur = hw->frame_dur;
+ vdec_count_info(hw->gvs, 0, offset);
+
+ /* pr_info("PicType = %d, PTS = 0x%x\n",
+ * picture_type, vf->pts);
+ */
+ WRITE_VREG(AVS_BUFFEROUT, 0);
+ }
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+
+
+ if (hw->m_ins_flag) {
+ u32 status_reg = READ_VREG(DECODE_STATUS);
+ u32 decode_status = status_reg & 0xff;
+ if (hw->dec_result == DEC_RESULT_DONE ||
+ hw->dec_result == DEC_RESULT_AGAIN) {
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s !!! decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n",
+ __func__, decode_status,
+ hw->buf_status,
+ hw->dec_result, hw->decode_pic_count);
+ return IRQ_HANDLED;
+ } else if (decode_status == DECODE_STATUS_PIC_DONE) {
+ hw->buf_status = (status_reg >> 8) & 0xffff;
+ hw->decode_pic_count++;
+ reset_process_time(hw);
+ hw->dec_result = DEC_RESULT_DONE;
+#if DEBUG_MULTI_FLAG == 1
+ WRITE_VREG(DECODE_STATUS, 0);
+#else
+ amvdec_stop();
+#endif
+ vavs_save_regs(hw);
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s DECODE_STATUS_PIC_DONE, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n",
+ __func__, decode_status,
+ hw->buf_status,
+ hw->dec_result, hw->decode_pic_count);
+ vdec_schedule_work(&hw->work);
+ return IRQ_HANDLED;
+ } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
+ decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) {
+ hw->buf_status = (status_reg >> 8) & 0xffff;
+ reset_process_time(hw);
+ hw->dec_result = DEC_RESULT_AGAIN;
+#if DEBUG_MULTI_FLAG == 1
+ WRITE_VREG(DECODE_STATUS, 0);
+#else
+ amvdec_stop();
+#endif
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s BUF_EMPTY, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d\n",
+ __func__, decode_status,
+ hw->buf_status,
+ hw->dec_result, hw->decode_pic_count);
+ vdec_schedule_work(&hw->work);
+ return IRQ_HANDLED;
+ }
+ }
+
+
+#ifdef HANDLE_AVS_IRQ
+ return IRQ_HANDLED;
+#else
+ return;
+#endif
+}
+/*
+ *static int run_flag = 1;
+ *static int step_flag;
+ */
+static int error_recovery_mode; /*0: blocky 1: mosaic*/
+/*
+ *static uint error_watchdog_threshold=10;
+ *static uint error_watchdog_count;
+ *static uint error_watchdog_buf_threshold = 0x4000000;
+ */
+
+static struct vframe_s *vavs_vf_peek(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)op_arg;
+ hw->peek_num++;
+ if (step == 2)
+ return NULL;
+ if (hw->recover_flag)
+ return NULL;
+
+ if (kfifo_peek(&hw->display_q, &vf)) {
+ if (vf) {
+ if (force_fps & 0x100) {
+ u32 rate = force_fps & 0xff;
+
+ if (rate)
+ vf->duration = 96000/rate;
+ else
+ vf->duration = 0;
+ }
+
+ }
+ return vf;
+ }
+
+ return NULL;
+
+}
+
+static struct vframe_s *vavs_vf_get(void *op_arg)
+{
+ struct vframe_s *vf;
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)op_arg;
+
+ if (hw->recover_flag)
+ return NULL;
+
+ if (step == 2)
+ return NULL;
+ else if (step == 1)
+ step = 2;
+
+ if (kfifo_get(&hw->display_q, &vf)) {
+ if (vf) {
+ hw->get_num++;
+ if (force_fps & 0x100) {
+ u32 rate = force_fps & 0xff;
+
+ if (rate)
+ vf->duration = 96000/rate;
+ else
+ vf->duration = 0;
+ }
+
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "%s, index = %d, w %d h %d, type 0x%x\n",
+ __func__,
+ vf->index,
+ vf->width,
+ vf->height,
+ vf->type);
+ }
+ return vf;
+ }
+
+ return NULL;
+
+}
+
+static void vavs_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ int i;
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)op_arg;
+
+ if (vf) {
+ hw->put_num++;
+ debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+ "%s, index = %d, w %d h %d, type 0x%x\n",
+ __func__,
+ vf->index,
+ vf->width,
+ vf->height,
+ vf->type);
+ }
+ if (hw->recover_flag)
+ return;
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ if (vf == &hw->vfpool[i])
+ break;
+ }
+ if (i < VF_POOL_SIZE)
+
+ kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf);
+
+}
+
+static int vavs_event_cb(int type, void *data, void *private_data)
+{
+ return 0;
+}
+
+int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+ /*if (!(hw->stat & STAT_VDEC_RUN))
+ return -1;*/
+ if (!hw)
+ return -1;
+
+ vstatus->frame_width = hw->frame_width;
+ vstatus->frame_height = hw->frame_height;
+ if (hw->frame_dur != 0)
+ vstatus->frame_rate = 96000 / hw->frame_dur;
+ else
+ vstatus->frame_rate = -1;
+ vstatus->error_count = READ_VREG(AV_SCRATCH_C);
+ vstatus->status = hw->stat;
+ vstatus->bit_rate = hw->gvs->bit_rate;
+ vstatus->frame_dur = hw->frame_dur;
+ vstatus->frame_data = hw->gvs->frame_data;
+ vstatus->total_data = hw->gvs->total_data;
+ vstatus->frame_count = hw->gvs->frame_count;
+ vstatus->error_frame_count = hw->gvs->error_frame_count;
+ vstatus->drop_frame_count = hw->gvs->drop_frame_count;
+ vstatus->total_data = hw->gvs->total_data;
+ vstatus->samp_cnt = hw->gvs->samp_cnt;
+ vstatus->offset = hw->gvs->offset;
+ snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
+ "%s", DRIVER_NAME);
+
+ return 0;
+}
+
+int vavs_set_isreset(struct vdec_s *vdec, int isreset)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+
+ hw->is_reset = isreset;
+ return 0;
+}
+
+static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw)
+{
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
+ if (NULL == hw->gvs) {
+ pr_info("the struct of vdec status malloc failed.\n");
+ return -ENOMEM;
+ }
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ return 0;
+}
+/****************************************/
+static int vavs_canvas_init(struct vdec_avs_hw_s *hw)
+{
+ int i, ret;
+ u32 canvas_width, canvas_height;
+ u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
+ unsigned long buf_start;
+ int need_alloc_buf_num;
+ struct vdec_s *vdec = NULL;
+
+ if (hw->m_ins_flag)
+ vdec = hw_to_vdec(hw);
+
+ hw->vf_buf_num_used = vf_buf_num;
+ if (buf_size <= 0x00400000) {
+ /* SD only */
+ canvas_width = 768;
+ canvas_height = 576;
+ decbuf_y_size = 0x80000;
+ decbuf_uv_size = 0x20000;
+ decbuf_size = 0x100000;
+ } else {
+ /* HD & SD */
+ canvas_width = 1920;
+ canvas_height = 1088;
+ decbuf_y_size = 0x200000;
+ decbuf_uv_size = 0x80000;
+ decbuf_size = 0x300000;
+ }
+
+#ifdef AVSP_LONG_CABAC
+ need_alloc_buf_num = hw->vf_buf_num_used + 2;
+#else
+ need_alloc_buf_num = hw->vf_buf_num_used + 1;
+#endif
+ for (i = 0; i < need_alloc_buf_num; i++) {
+
+ if (i == (need_alloc_buf_num - 1))
+ decbuf_size = WORKSPACE_SIZE;
+#ifdef AVSP_LONG_CABAC
+ else if (i == (need_alloc_buf_num - 2))
+ decbuf_size = WORKSPACE_SIZE_A;
+#endif
+ ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
+ decbuf_size, DRIVER_NAME, &buf_start);
+ if (ret < 0)
+ return ret;
+ if (i == (need_alloc_buf_num - 1)) {
+ if (firmware_sel == 1)
+ hw->buf_offset = buf_start -
+ RV_AI_BUFF_START_ADDR;
+ else
+ hw->buf_offset = buf_start -
+ LONG_CABAC_RV_AI_BUFF_START_ADDR;
+ continue;
+ }
+#ifdef AVSP_LONG_CABAC
+ else if (i == (need_alloc_buf_num - 2)) {
+ avsp_heap_adr = codec_mm_phys_to_virt(buf_start);
+ continue;
+ }
+#endif
+ if (hw->m_ins_flag) {
+ unsigned canvas;
+
+ if (vdec->parallel_dec == 1) {
+ unsigned tmp;
+ if (canvas_u(hw->canvas_spec[i]) == 0xff) {
+ tmp =
+ vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ hw->canvas_spec[i] &= ~(0xffff << 8);
+ hw->canvas_spec[i] |= tmp << 8;
+ hw->canvas_spec[i] |= tmp << 16;
+ }
+ if (canvas_y(hw->canvas_spec[i]) == 0xff) {
+ tmp =
+ vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ hw->canvas_spec[i] &= ~0xff;
+ hw->canvas_spec[i] |= tmp;
+ }
+ canvas = hw->canvas_spec[i];
+ } else {
+ canvas = vdec->get_canvas(i, 2);
+ hw->canvas_spec[i] = canvas;
+ }
+
+ hw->canvas_config[i][0].phy_addr =
+ buf_start;
+ hw->canvas_config[i][0].width =
+ canvas_width;
+ hw->canvas_config[i][0].height =
+ canvas_height;
+ hw->canvas_config[i][0].block_mode =
+ CANVAS_BLKMODE_32X32;
+
+ hw->canvas_config[i][1].phy_addr =
+ buf_start + decbuf_y_size;
+ hw->canvas_config[i][1].width =
+ canvas_width;
+ hw->canvas_config[i][1].height =
+ canvas_height / 2;
+ hw->canvas_config[i][1].block_mode =
+ CANVAS_BLKMODE_32X32;
+
+ } else {
+#ifdef NV21
+ canvas_config(canvas_base + canvas_num * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_base + canvas_num * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+#else
+ canvas_config(canvas_num * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width / 2,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 2,
+ buf_start +
+ decbuf_y_size + decbuf_uv_size,
+ canvas_width / 2, canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+#endif
+ if (debug_flag & AVS_DEBUG_PRINT) {
+ pr_info("canvas config %d, addr %p\n", i,
+ (void *)buf_start);
+ }
+ }
+ }
+ return 0;
+}
+
+void vavs_recover(struct vdec_avs_hw_s *hw)
+{
+ vavs_canvas_init(hw);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ READ_VREG(DOS_SW_RESET0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ if (firmware_sel == 1) {
+ WRITE_VREG(POWER_CTL_VLD, 0x10);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2,
+ MEM_FIFO_CNT_BIT, 2);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8,
+ MEM_LEVEL_CNT_BIT, 6);
+ }
+
+
+ if (firmware_sel == 0) {
+ /* fixed canvas index */
+ WRITE_VREG(AV_SCRATCH_0, canvas_base);
+ WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used);
+ } else {
+ int ii;
+
+ 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, hw->buf_offset);
+
+ /* disable PSCALE for hardware sharing */
+ WRITE_VREG(PSCALE_CTRL, 0);
+
+ WRITE_VREG(AVS_SOS_COUNT, 0);
+ WRITE_VREG(AVS_BUFFERIN, 0);
+ WRITE_VREG(AVS_BUFFEROUT, 0);
+ if (error_recovery_mode)
+ WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
+ else
+ WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
+ /* clear mailbox interrupt */
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(ASSIST_MBOX1_MASK, 1);
+#if 1 /* def DEBUG_UCODE */
+ WRITE_VREG(AV_SCRATCH_D, 0);
+#endif
+
+#ifdef NV21
+ SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
+#endif
+
+#ifdef PIC_DC_NEED_CLEAR
+ CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
+#endif
+
+#ifdef AVSP_LONG_CABAC
+ if (firmware_sel == 0) {
+ WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
+ WRITE_VREG(LONG_CABAC_REQ, 0);
+ WRITE_VREG(LONG_CABAC_PIC_SIZE, 0);
+ WRITE_VREG(LONG_CABAC_SRC_ADDR, 0);
+ }
+#endif
+ WRITE_VREG(AV_SCRATCH_5, 0);
+
+}
+
+#define MBY_MBX MB_MOTION_MODE /*0xc07*/
+#define AVS_CO_MB_WR_ADDR 0xc38
+#define AVS_CO_MB_RW_CTL 0xc3d
+#define AVS_CO_MB_RD_ADDR 0xc39
+#define AVSP_IQ_WQ_PARAM_01 0x0e19
+#define AVSP_IQ_WQ_PARAM_23 0x0e1a
+#define AVSP_IQ_WQ_PARAM_45 0x0e1b
+
+static void vavs_save_regs(struct vdec_avs_hw_s *hw)
+{
+ hw->reg_scratch_0 = READ_VREG(AV_SCRATCH_0);
+ hw->reg_scratch_1 = READ_VREG(AV_SCRATCH_1);
+ hw->reg_scratch_2 = READ_VREG(AV_SCRATCH_2);
+ hw->reg_scratch_3 = READ_VREG(AV_SCRATCH_3);
+ hw->reg_scratch_4 = READ_VREG(AV_SCRATCH_4);
+ hw->reg_scratch_5 = READ_VREG(AV_SCRATCH_5);
+ hw->reg_scratch_6 = READ_VREG(AV_SCRATCH_6);
+ hw->reg_scratch_7 = READ_VREG(AV_SCRATCH_7);
+ hw->reg_scratch_8 = READ_VREG(AV_SCRATCH_8);
+ hw->reg_scratch_9 = READ_VREG(AV_SCRATCH_9);
+ hw->reg_scratch_A = READ_VREG(AV_SCRATCH_A);
+ hw->reg_scratch_B = READ_VREG(AV_SCRATCH_B);
+ hw->reg_scratch_C = READ_VREG(AV_SCRATCH_C);
+ hw->reg_scratch_D = READ_VREG(AV_SCRATCH_D);
+ hw->reg_scratch_E = READ_VREG(AV_SCRATCH_E);
+ hw->reg_scratch_F = READ_VREG(AV_SCRATCH_F);
+ hw->reg_scratch_G = READ_VREG(AV_SCRATCH_G);
+ hw->reg_scratch_H = READ_VREG(AV_SCRATCH_H);
+ hw->reg_scratch_I = READ_VREG(AV_SCRATCH_I);
+
+ hw->reg_mb_width = READ_VREG(MB_WIDTH);
+ hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT);
+
+ hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR);
+ hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR);
+ hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR);
+ hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR);
+ hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR);
+ hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR);
+
+ hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE);
+
+ hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG);
+ hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR);
+ hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01);
+ hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23);
+ hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
+ hw->iqidct_control = READ_VREG(IQIDCT_CONTROL);
+ hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT);
+ hw->slice_qp = READ_VREG(SLICE_QP);
+
+ hw->dc_scaler = READ_VREG(DC_SCALER);
+ hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01);
+ hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23);
+ hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45);
+ hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR);
+ hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT);
+ hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H);
+ hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL);
+
+ hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL);
+}
+
+static void vavs_restore_regs(struct vdec_avs_hw_s *hw)
+{
+ WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0);
+ WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1);
+ WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2);
+ WRITE_VREG(AV_SCRATCH_3, hw->reg_scratch_3);
+ WRITE_VREG(AV_SCRATCH_4, hw->reg_scratch_4);
+ WRITE_VREG(AV_SCRATCH_5, hw->reg_scratch_5);
+ WRITE_VREG(AV_SCRATCH_6, hw->reg_scratch_6);
+ WRITE_VREG(AV_SCRATCH_7, hw->reg_scratch_7);
+ WRITE_VREG(AV_SCRATCH_8, hw->reg_scratch_8);
+ WRITE_VREG(AV_SCRATCH_9, hw->reg_scratch_9);
+ WRITE_VREG(AV_SCRATCH_A, hw->reg_scratch_A);
+ WRITE_VREG(AV_SCRATCH_B, hw->reg_scratch_B);
+ WRITE_VREG(AV_SCRATCH_C, hw->reg_scratch_C);
+ WRITE_VREG(AV_SCRATCH_D, hw->reg_scratch_D);
+ WRITE_VREG(AV_SCRATCH_E, hw->reg_scratch_E);
+ WRITE_VREG(AV_SCRATCH_F, hw->reg_scratch_F);
+ WRITE_VREG(AV_SCRATCH_G, hw->reg_scratch_G);
+ WRITE_VREG(AV_SCRATCH_H, hw->reg_scratch_H);
+ WRITE_VREG(AV_SCRATCH_I, hw->reg_scratch_I);
+
+ WRITE_VREG(MB_WIDTH, hw->reg_mb_width);
+ WRITE_VREG(VIFF_BIT_CNT, hw->reg_viff_bit_cnt);
+
+ WRITE_VREG(REC_CANVAS_ADDR, hw->reg_canvas_addr);
+ WRITE_VREG(DBKR_CANVAS_ADDR, hw->reg_dbkr_canvas_addr);
+ WRITE_VREG(DBKW_CANVAS_ADDR, hw->reg_dbkw_canvas_addr);
+ WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr);
+ WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr);
+ WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr);
+
+ WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type);
+
+ WRITE_VREG(VC1_CONTROL_REG, hw->vc1_control_reg);
+ WRITE_VREG(AVS_CO_MB_WR_ADDR, hw->avs_co_mb_wr_addr);
+ WRITE_VREG(SLICE_START_BYTE_01, hw->slice_start_byte_01);
+ WRITE_VREG(SLICE_START_BYTE_23, hw->slice_start_byte_23);
+ WRITE_VREG(VCOP_CTRL_REG, hw->vcop_ctrl_reg);
+ WRITE_VREG(IQIDCT_CONTROL, hw->iqidct_control);
+ WRITE_VREG(RV_AI_MB_COUNT, hw->rv_ai_mb_count);
+ WRITE_VREG(SLICE_QP, hw->slice_qp);
+
+ WRITE_VREG(DC_SCALER, hw->dc_scaler);
+ WRITE_VREG(AVSP_IQ_WQ_PARAM_01, hw->avsp_iq_wq_param_01);
+ WRITE_VREG(AVSP_IQ_WQ_PARAM_23, hw->avsp_iq_wq_param_23);
+ WRITE_VREG(AVSP_IQ_WQ_PARAM_45, hw->avsp_iq_wq_param_45);
+ WRITE_VREG(AVS_CO_MB_RD_ADDR, hw->avs_co_mb_rd_addr);
+ WRITE_VREG(DBLK_MB_WID_HEIGHT, hw->dblk_mb_wid_height);
+ WRITE_VREG(MC_PIC_W_H, hw->mc_pic_w_h);
+ WRITE_VREG(AVS_CO_MB_RW_CTL, hw->avs_co_mb_rw_ctl);
+
+ WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_decode_control);
+
+}
+
+static int vavs_prot_init(struct vdec_avs_hw_s *hw)
+{
+ int r = 0;
+#if DEBUG_MULTI_FLAG > 0
+ if (hw->decode_pic_count == 0) {
+#endif
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ READ_VREG(DOS_SW_RESET0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+#else
+ WRITE_RESET_REG(RESET0_REGISTER,
+ RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
+ READ_RESET_REG(RESET0_REGISTER);
+ WRITE_RESET_REG(RESET0_REGISTER,
+ RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
+
+ WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
+#endif
+#if DEBUG_MULTI_FLAG > 0
+ }
+#endif
+ /***************** reset vld **********************************/
+ WRITE_VREG(POWER_CTL_VLD, 0x10);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
+ /*************************************************************/
+ if (hw->m_ins_flag) {
+ int i;
+ if (hw->decode_pic_count == 0) {
+ r = vavs_canvas_init(hw);
+ for (i = 0; i < 4; i++) {
+ WRITE_VREG(AV_SCRATCH_0 + i,
+ hw->canvas_spec[i]
+ );
+ }
+ } else
+ vavs_restore_regs(hw);
+
+ for (i = 0; i < 4; i++) {
+ canvas_config_ex(canvas_y(hw->canvas_spec[i]),
+ hw->canvas_config[i][0].phy_addr,
+ hw->canvas_config[i][0].width,
+ hw->canvas_config[i][0].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][0].block_mode,
+ 0);
+
+ canvas_config_ex(canvas_u(hw->canvas_spec[i]),
+ hw->canvas_config[i][1].phy_addr,
+ hw->canvas_config[i][1].width,
+ hw->canvas_config[i][1].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][1].block_mode,
+ 0);
+ }
+ } else {
+ r = vavs_canvas_init(hw);
+#ifdef NV21
+ if (firmware_sel == 0) {
+ /* fixed canvas index */
+ WRITE_VREG(AV_SCRATCH_0, canvas_base);
+ WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used);
+ } else {
+ int ii;
+
+ 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 */
+ if (hw->decode_pic_count == 0)
+ WRITE_VREG(AV_SCRATCH_F, hw->buf_offset);
+
+ /* disable PSCALE for hardware sharing */
+ WRITE_VREG(PSCALE_CTRL, 0);
+
+ if (hw->decode_pic_count == 0) {
+ 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 */
+ if (hw->decode_pic_count == 0)
+ WRITE_VREG(AV_SCRATCH_D, 0);
+#endif
+
+#ifdef NV21
+ SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
+#endif
+
+#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
+
+#ifdef ENABLE_USER_DATA
+ if (firmware_sel == 0) {
+ WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset));
+ pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N));
+ }
+#endif
+ if (hw->m_ins_flag) {
+ if (vdec_frame_based(hw_to_vdec(hw)))
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE);
+ else
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE);
+ WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr);
+ } else
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
+ //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+
+ return r;
+}
+
+#if DEBUG_MULTI_FLAG > 0
+static int vavs_prot_init_vld_only(struct vdec_avs_hw_s *hw)
+{
+ int r = 0;
+ /***************** reset vld **********************************/
+ WRITE_VREG(POWER_CTL_VLD, 0x10);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
+ WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
+ /*************************************************************/
+ if (hw->m_ins_flag) {
+ int i;
+ if (hw->decode_pic_count == 0) {
+ r = vavs_canvas_init(hw);
+ for (i = 0; i < 4; i++) {
+ WRITE_VREG(AV_SCRATCH_0 + i,
+ hw->canvas_spec[i]
+ );
+ }
+ } else
+ vavs_restore_regs(hw);
+
+ for (i = 0; i < 4; i++) {
+ canvas_config_ex(canvas_y(hw->canvas_spec[i]),
+ hw->canvas_config[i][0].phy_addr,
+ hw->canvas_config[i][0].width,
+ hw->canvas_config[i][0].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][0].block_mode,
+ 0);
+
+ canvas_config_ex(canvas_u(hw->canvas_spec[i]),
+ hw->canvas_config[i][1].phy_addr,
+ hw->canvas_config[i][1].width,
+ hw->canvas_config[i][1].height,
+ CANVAS_ADDR_NOWRAP,
+ hw->canvas_config[i][1].block_mode,
+ 0);
+ }
+ }
+ /* notify ucode the buffer offset */
+#if DEBUG_MULTI_FLAG == 0
+ /* disable PSCALE for hardware sharing */
+ WRITE_VREG(PSCALE_CTRL, 0);
+
+ if (hw->decode_pic_count == 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);
+
+#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
+#endif
+ if (hw->m_ins_flag) {
+ if (vdec_frame_based(hw_to_vdec(hw)))
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE);
+ else
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE);
+ WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr);
+ } else
+ WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
+ //WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
+ WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+
+ return r;
+}
+#endif
+
+#ifdef AVSP_LONG_CABAC
+static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64);
+#endif
+static void vavs_local_init(struct vdec_avs_hw_s *hw)
+{
+ int i;
+
+ hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio;
+
+ hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param;
+
+ hw->frame_width = hw->frame_height = hw->frame_dur = hw->frame_prog = 0;
+
+ hw->throw_pb_flag = 1;
+
+ hw->total_frame = 0;
+ hw->saved_resolution = 0;
+ hw->next_pts = 0;
+
+#ifdef DEBUG_PTS
+ hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0;
+#endif
+ INIT_KFIFO(hw->display_q);
+ INIT_KFIFO(hw->recycle_q);
+ INIT_KFIFO(hw->newframe_q);
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ const struct vframe_s *vf = &hw->vfpool[i];
+
+ hw->vfpool[i].index = vf_buf_num;
+ hw->vfpool[i].bufWidth = 1920;
+ kfifo_put(&hw->newframe_q, vf);
+ }
+ for (i = 0; i < vf_buf_num; i++)
+ hw->vfbuf_use[i] = 0;
+
+ /*cur_vfpool = vfpool;*/
+
+ if (hw->recover_flag == 1)
+ return;
+
+ if (hw->mm_blk_handle) {
+ pr_info("decoder_bmmu_box_free\n");
+ decoder_bmmu_box_free(hw->mm_blk_handle);
+ hw->mm_blk_handle = NULL;
+ }
+
+ hw->mm_blk_handle = decoder_bmmu_box_alloc_box(
+ DRIVER_NAME,
+ 0,
+ MAX_BMMU_BUFFER_NUM,
+ 4 + PAGE_SHIFT,
+ CODEC_MM_FLAGS_CMA_CLEAR |
+ CODEC_MM_FLAGS_FOR_VDECODER);
+ if (hw->mm_blk_handle == NULL)
+ pr_info("Error, decoder_bmmu_box_alloc_box fail\n");
+
+}
+
+static int vavs_vf_states(struct vframe_states *states, void *op_arg)
+{
+ unsigned long flags;
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)op_arg;
+
+
+ spin_lock_irqsave(&lock, flags);
+ states->vf_pool_size = VF_POOL_SIZE;
+ states->buf_free_num = kfifo_len(&hw->newframe_q);
+ states->buf_avail_num = kfifo_len(&hw->display_q);
+ states->buf_recycle_num = kfifo_len(&hw->recycle_q);
+ if (step == 2)
+ states->buf_avail_num = 0;
+ spin_unlock_irqrestore(&lock, flags);
+ return 0;
+}
+
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+static void vavs_ppmgr_reset(void)
+{
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
+
+ vavs_local_init(ghw);
+
+ pr_info("vavs: vf_ppmgr_reset\n");
+}
+#endif
+
+static void vavs_local_reset(struct vdec_avs_hw_s *hw)
+{
+ mutex_lock(&vavs_mutex);
+ hw->recover_flag = 1;
+ pr_info("error, local reset\n");
+ amvdec_stop();
+ msleep(100);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
+ vavs_local_init(hw);
+ vavs_recover(hw);
+
+#ifdef ENABLE_USER_DATA
+ reset_userdata_fifo(1);
+#endif
+
+ amvdec_start();
+ hw->recover_flag = 0;
+#if 0
+ error_watchdog_count = 0;
+
+ pr_info("pc %x stream buf wp %x rp %x level %x\n",
+ READ_VREG(MPC_E),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL));
+#endif
+
+
+
+ mutex_unlock(&vavs_mutex);
+}
+
+#if 0
+static struct work_struct fatal_error_wd_work;
+static struct work_struct notify_work;
+static atomic_t error_handler_run = ATOMIC_INIT(0);
+#endif
+static void vavs_fatal_error_handler(struct work_struct *work)
+{
+ struct vdec_avs_hw_s *hw =
+ container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work);
+ if (debug_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(hw);
+ vf_reg_provider(&vavs_vf_prov);
+#endif
+ vavs_recover(hw);
+ amvdec_start();
+ mutex_unlock(&vavs_mutex);
+ } else {
+ pr_info("avs fatal_error_handler\n");
+ vavs_local_reset(hw);
+ }
+ atomic_set(&hw->error_handler_run, 0);
+}
+
+static void vavs_notify_work(struct work_struct *work)
+{
+ struct vdec_avs_hw_s *hw =
+ container_of(work, struct vdec_avs_hw_s, notify_work);
+ if (hw->fr_hint_status == VDEC_NEED_HINT) {
+ vf_notify_receiver(PROVIDER_NAME ,
+ VFRAME_EVENT_PROVIDER_FR_HINT ,
+ (void *)((unsigned long)hw->frame_dur));
+ hw->fr_hint_status = VDEC_HINTED;
+ }
+ return;
+}
+
+static void avs_set_clk(struct work_struct *work)
+{
+ struct vdec_avs_hw_s *hw =
+ container_of(work, struct vdec_avs_hw_s, set_clk_work);
+ if (hw->frame_dur > 0 && hw->saved_resolution !=
+ hw->frame_width * hw->frame_height * (96000 / hw->frame_dur)) {
+ int fps = 96000 / hw->frame_dur;
+
+ hw->saved_resolution = hw->frame_width * hw->frame_height * fps;
+ if (firmware_sel == 0 &&
+ (debug_flag & AVS_DEBUG_USE_FULL_SPEED)) {
+ vdec_source_changed(VFORMAT_AVS,
+ 4096, 2048, 60);
+ } else {
+ vdec_source_changed(VFORMAT_AVS,
+ hw->frame_width, hw->frame_height, fps);
+ }
+
+ }
+}
+
+static void vavs_put_timer_func(unsigned long arg)
+{
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg;
+ struct timer_list *timer = &hw->recycle_timer;
+
+#ifndef HANDLE_AVS_IRQ
+ vavs_isr();
+#endif
+
+ if (READ_VREG(AVS_SOS_COUNT)) {
+ if (!error_recovery_mode) {
+#if 0
+ if (debug_flag & AVS_DEBUG_OLD_ERROR_HANDLE) {
+ mutex_lock(&vavs_mutex);
+ pr_info("vavs fatal error reset !\n");
+ amvdec_stop();
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vavs_ppmgr_reset();
+#else
+ vf_light_unreg_provider(&vavs_vf_prov);
+ vavs_local_init();
+ vf_reg_provider(&vavs_vf_prov);
+#endif
+ vavs_recover();
+ amvdec_start();
+ mutex_unlock(&vavs_mutex);
+ } else {
+ vavs_local_reset();
+ }
+#else
+ if (!atomic_read(&hw->error_handler_run)) {
+ atomic_set(&hw->error_handler_run, 1);
+ pr_info("AVS_SOS_COUNT = %d\n",
+ READ_VREG(AVS_SOS_COUNT));
+ pr_info("WP = 0x%x, RP = 0x%x, LEVEL = 0x%x, AVAIL = 0x%x, CUR_PTR = 0x%x\n",
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL),
+ READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
+ schedule_work(&hw->fatal_error_wd_work);
+ }
+#endif
+ }
+ }
+#if 0
+ if (long_cabac_busy == 0 &&
+ error_watchdog_threshold > 0 &&
+ kfifo_len(&hw->display_q) == 0 &&
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL) >
+ error_watchdog_buf_threshold) {
+ pr_info("newq %d dispq %d recyq %d\r\n",
+ kfifo_len(&hw->newframe_q),
+ kfifo_len(&hw->display_q),
+ kfifo_len(&hw->recycle_q));
+ pr_info("pc %x stream buf wp %x rp %x level %x\n",
+ READ_VREG(MPC_E),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL));
+ error_watchdog_count++;
+ if (error_watchdog_count >= error_watchdog_threshold)
+ vavs_local_reset();
+ } else
+ error_watchdog_count = 0;
+#endif
+ if (radr != 0) {
+ if (rval != 0) {
+ WRITE_VREG(radr, rval);
+ pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
+ } else
+ pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
+ rval = 0;
+ radr = 0;
+ }
+ if ((hw->ucode_pause_pos != 0) &&
+ (hw->ucode_pause_pos != 0xffffffff) &&
+ udebug_pause_pos != hw->ucode_pause_pos) {
+ hw->ucode_pause_pos = 0;
+ WRITE_VREG(DEBUG_REG1, 0);
+ }
+
+ if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
+ struct vframe_s *vf;
+
+ if (kfifo_get(&hw->recycle_q, &vf)) {
+ if ((vf->index < vf_buf_num) &&
+ (--hw->vfbuf_use[vf->index] == 0)) {
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n",
+ __func__,
+ ~(1 << vf->index), vf->index);
+ WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
+ vf->index = vf_buf_num;
+ }
+ kfifo_put(&hw->newframe_q,
+ (const struct vframe_s *)vf);
+ }
+
+ }
+
+ schedule_work(&hw->set_clk_work);
+
+ timer->expires = jiffies + PUT_INTERVAL;
+
+ add_timer(timer);
+}
+
+#ifdef AVSP_LONG_CABAC
+
+static void long_cabac_do_work(struct work_struct *work)
+{
+ int status = 0;
+ struct vdec_avs_hw_s *hw = gw;
+#ifdef PERFORMANCE_DEBUG
+ pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n",
+ __func__,
+ kfifo_len(&hw->newframe_q),
+ kfifo_len(&hw->display_q),
+ kfifo_len(&hw->recycle_q)
+ );
+#endif
+ mutex_lock(&vavs_mutex);
+ long_cabac_busy = 1;
+ while (READ_VREG(LONG_CABAC_REQ)) {
+ if (process_long_cabac() < 0) {
+ status = -1;
+ break;
+ }
+ }
+ long_cabac_busy = 0;
+ mutex_unlock(&vavs_mutex);
+#ifdef PERFORMANCE_DEBUG
+ pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n",
+ __func__,
+ kfifo_len(&hw->newframe_q),
+ kfifo_len(&hw->display_q),
+ kfifo_len(&hw->recycle_q)
+ );
+#endif
+ if (status < 0) {
+ pr_info("transcoding error, local reset\r\n");
+ vavs_local_reset(hw);
+ }
+
+}
+#endif
+
+#ifdef AVSP_LONG_CABAC
+static void init_avsp_long_cabac_buf(void)
+{
+#if 0
+ es_write_addr_phy = (unsigned long)codec_mm_alloc_for_dma(
+ "vavs",
+ PAGE_ALIGN(MAX_CODED_FRAME_SIZE)/PAGE_SIZE,
+ 0, CODEC_MM_FLAGS_DMA_CPU);
+ es_write_addr_virt = codec_mm_phys_to_virt(es_write_addr_phy);
+
+#elif 0
+ es_write_addr_virt =
+ (void *)dma_alloc_coherent(amports_get_dma_device(),
+ MAX_CODED_FRAME_SIZE, &es_write_addr_phy,
+ GFP_KERNEL);
+#else
+ /*es_write_addr_virt = kmalloc(MAX_CODED_FRAME_SIZE, GFP_KERNEL);
+ * es_write_addr_virt = (void *)__get_free_pages(GFP_KERNEL,
+ * get_order(MAX_CODED_FRAME_SIZE));
+ */
+ es_write_addr_virt = &es_write_addr[0];
+ if (es_write_addr_virt == NULL) {
+ pr_err("%s: failed to alloc es_write_addr_virt buffer\n",
+ __func__);
+ return;
+ }
+
+ es_write_addr_phy = dma_map_single(amports_get_dma_device(),
+ es_write_addr_virt,
+ MAX_CODED_FRAME_SIZE, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(amports_get_dma_device(),
+ es_write_addr_phy)) {
+ pr_err("%s: failed to map es_write_addr_virt buffer\n",
+ __func__);
+ /*kfree(es_write_addr_virt);*/
+ es_write_addr_virt = NULL;
+ return;
+ }
+#endif
+
+
+#ifdef BITSTREAM_READ_TMP_NO_CACHE
+ bitstream_read_tmp =
+ (void *)dma_alloc_coherent(amports_get_dma_device(),
+ SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy,
+ GFP_KERNEL);
+
+#else
+
+ bitstream_read_tmp = kmalloc(SVA_STREAM_BUF_SIZE, GFP_KERNEL);
+ /*bitstream_read_tmp = (void *)__get_free_pages(GFP_KERNEL,
+ *get_order(MAX_CODED_FRAME_SIZE));
+ */
+ if (bitstream_read_tmp == NULL) {
+ pr_err("%s: failed to alloc bitstream_read_tmp buffer\n",
+ __func__);
+ return;
+ }
+
+ bitstream_read_tmp_phy = dma_map_single(amports_get_dma_device(),
+ bitstream_read_tmp,
+ SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(amports_get_dma_device(),
+ bitstream_read_tmp_phy)) {
+ pr_err("%s: failed to map rpm buffer\n", __func__);
+ kfree(bitstream_read_tmp);
+ bitstream_read_tmp = NULL;
+ return;
+ }
+#endif
+}
+#endif
+
+
+static s32 vavs_init(struct vdec_avs_hw_s *hw)
+{
+ int ret, size = -1;
+ struct firmware_s *fw;
+ u32 fw_size = 0x1000 * 16;
+ /*char *buf = vmalloc(0x1000 * 16);
+
+ if (IS_ERR_OR_NULL(buf))
+ return -ENOMEM;
+ */
+ fw = vmalloc(sizeof(struct firmware_s) + fw_size);
+ if (IS_ERR_OR_NULL(fw))
+ return -ENOMEM;
+
+ pr_info("vavs_init\n");
+ //init_timer(&hw->recycle_timer);
+
+ //hw->stat |= STAT_TIMER_INIT;
+
+ amvdec_enable();
+
+ //vdec_enable_DMC(NULL);
+
+ vavs_local_init(hw);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
+ size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
+ else {
+ if (firmware_sel == 1)
+ size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data);
+#ifdef AVSP_LONG_CABAC
+ else {
+ init_avsp_long_cabac_buf();
+ size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
+ }
+#endif
+ }
+
+ if (size < 0) {
+ amvdec_disable();
+ pr_err("get firmware fail.");
+ /*vfree(buf);*/
+ return -1;
+ }
+
+ fw->len = size;
+ hw->fw = fw;
+
+ if (hw->m_ins_flag) {
+ init_timer(&hw->check_timer);
+ hw->check_timer.data = (ulong) hw;
+ hw->check_timer.function = check_timer_func;
+ hw->check_timer.expires = jiffies + CHECK_INTERVAL;
+
+
+ //add_timer(&hw->check_timer);
+ hw->stat |= STAT_TIMER_ARM;
+
+ INIT_WORK(&hw->work, vavs_work);
+
+ hw->fw = fw;
+ return 0;
+ }
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
+ ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data);
+ else if (firmware_sel == 1)
+ ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", fw->data);
+ else
+ ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data);
+
+ if (ret < 0) {
+ amvdec_disable();
+ /*vfree(buf);*/
+ pr_err("AVS: the %s fw loading failed, err: %x\n",
+ tee_enabled() ? "TEE" : "local", ret);
+ return -EBUSY;
+ }
+
+ /*vfree(buf);*/
+
+ hw->stat |= STAT_MC_LOAD;
+
+
+ /* enable AMRISC side protocol */
+ ret = vavs_prot_init(hw);
+ if (ret < 0)
+ return ret;
+
+#ifdef HANDLE_AVS_IRQ
+ if (vdec_request_irq(VDEC_IRQ_1, vavs_isr,
+ "vavs-irq", (void *)hw)) {
+ amvdec_disable();
+ pr_info("vavs irq register error.\n");
+ return -ENOENT;
+ }
+#endif
+
+ hw->stat |= STAT_ISR_REG;
+ pr_info("%s %d\n", __func__, __LINE__);
+
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw);
+ 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, hw);
+ vf_reg_provider(&vavs_vf_prov);
+#endif
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ if (hw->vavs_amstream_dec_info.rate != 0) {
+ if (!hw->is_reset)
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)((unsigned long)
+ hw->vavs_amstream_dec_info.rate));
+ hw->fr_hint_status = VDEC_HINTED;
+ } else
+ hw->fr_hint_status = VDEC_NEED_HINT;
+
+ hw->stat |= STAT_VF_HOOK;
+
+ hw->recycle_timer.data = (ulong)(hw);
+ hw->recycle_timer.function = vavs_put_timer_func;
+ hw->recycle_timer.expires = jiffies + PUT_INTERVAL;
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ add_timer(&hw->recycle_timer);
+
+ hw->stat |= STAT_TIMER_ARM;
+
+#ifdef AVSP_LONG_CABAC
+ if (firmware_sel == 0)
+ INIT_WORK(&long_cabac_wd_work, long_cabac_do_work);
+#endif
+ vdec_source_changed(VFORMAT_AVS,
+ 1920, 1080, 30);
+ amvdec_start();
+
+ hw->stat |= STAT_VDEC_RUN;
+ pr_info("%s %d\n", __func__, __LINE__);
+ return 0;
+}
+
+static int amvdec_avs_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ struct vdec_avs_hw_s *hw = NULL;
+
+ if (pdata == NULL) {
+ pr_info("amvdec_avs memory resource undefined.\n");
+ return -EFAULT;
+ }
+
+ hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev,
+ sizeof(struct vdec_avs_hw_s), GFP_KERNEL);
+ if (hw == NULL) {
+ pr_info("\nammvdec_avs decoder driver alloc failed\n");
+ return -ENOMEM;
+ }
+ pdata->private = hw;
+ ghw = hw;
+ atomic_set(&hw->error_handler_run, 0);
+ hw->m_ins_flag = 0;
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
+ firmware_sel = 1;
+
+ if (firmware_sel == 1) {
+ vf_buf_num = 4;
+ canvas_base = 0;
+ canvas_num = 3;
+ } else {
+
+ canvas_base = 128;
+ canvas_num = 2; /*NV21*/
+ }
+
+
+ if (pdata->sys_info)
+ hw->vavs_amstream_dec_info = *pdata->sys_info;
+
+ pr_info("%s (%d,%d) %d\n", __func__, hw->vavs_amstream_dec_info.width,
+ hw->vavs_amstream_dec_info.height, hw->vavs_amstream_dec_info.rate);
+
+ pdata->dec_status = vavs_dec_status;
+ pdata->set_isreset = vavs_set_isreset;
+ hw->is_reset = 0;
+
+ pdata->user_data_read = NULL;
+ pdata->reset_userdata_fifo = NULL;
+
+ vavs_vdec_info_init(hw);
+
+#ifdef ENABLE_USER_DATA
+ if (NULL == hw->user_data_buffer) {
+ hw->user_data_buffer =
+ dma_alloc_coherent(amports_get_dma_device(),
+ USER_DATA_SIZE,
+ &hw->user_data_buffer_phys, GFP_KERNEL);
+ if (!hw->user_data_buffer) {
+ pr_info("%s: Can not allocate hw->user_data_buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+ pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n",
+ hw->user_data_buffer, (u32)hw->user_data_buffer_phys);
+ }
+#endif
+ INIT_WORK(&hw->set_clk_work, avs_set_clk);
+ if (vavs_init(hw) < 0) {
+ pr_info("amvdec_avs init failed.\n");
+ kfree(hw->gvs);
+ hw->gvs = NULL;
+ pdata->dec_status = NULL;
+ return -ENODEV;
+ }
+ /*vdec = pdata;*/
+
+ INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler);
+ atomic_set(&hw->error_handler_run, 0);
+#ifdef ENABLE_USER_DATA
+ INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
+#endif
+ INIT_WORK(&hw->notify_work, vavs_notify_work);
+
+ return 0;
+}
+
+static int amvdec_avs_remove(struct platform_device *pdev)
+{
+ struct vdec_avs_hw_s *hw = ghw;
+
+ cancel_work_sync(&hw->fatal_error_wd_work);
+ atomic_set(&hw->error_handler_run, 0);
+#ifdef ENABLE_USER_DATA
+ cancel_work_sync(&hw->userdata_push_work);
+#endif
+ cancel_work_sync(&hw->notify_work);
+ cancel_work_sync(&hw->set_clk_work);
+ if (hw->stat & STAT_VDEC_RUN) {
+ amvdec_stop();
+ hw->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (hw->stat & STAT_ISR_REG) {
+ vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id);
+ hw->stat &= ~STAT_ISR_REG;
+ }
+
+ if (hw->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&hw->recycle_timer);
+ hw->stat &= ~STAT_TIMER_ARM;
+ }
+#ifdef AVSP_LONG_CABAC
+ if (firmware_sel == 0) {
+ mutex_lock(&vavs_mutex);
+ cancel_work_sync(&long_cabac_wd_work);
+ mutex_unlock(&vavs_mutex);
+
+ if (es_write_addr_virt) {
+#if 0
+ codec_mm_free_for_dma("vavs", es_write_addr_phy);
+#else
+ dma_unmap_single(amports_get_dma_device(),
+ es_write_addr_phy,
+ MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE);
+ /*kfree(es_write_addr_virt);*/
+ es_write_addr_virt = NULL;
+#endif
+ }
+
+#ifdef BITSTREAM_READ_TMP_NO_CACHE
+ if (bitstream_read_tmp) {
+ dma_free_coherent(amports_get_dma_device(),
+ SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
+ bitstream_read_tmp_phy);
+ bitstream_read_tmp = NULL;
+ }
+#else
+ if (bitstream_read_tmp) {
+ dma_unmap_single(amports_get_dma_device(),
+ bitstream_read_tmp_phy,
+ SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
+ kfree(bitstream_read_tmp);
+ bitstream_read_tmp = NULL;
+ }
+#endif
+ }
+#endif
+ if (hw->stat & STAT_VF_HOOK) {
+ if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset)
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
+ hw->fr_hint_status = VDEC_NO_NEED_HINT;
+ vf_unreg_provider(&vavs_vf_prov);
+ hw->stat &= ~STAT_VF_HOOK;
+ }
+
+#ifdef ENABLE_USER_DATA
+ if (hw->user_data_buffer != NULL) {
+ dma_free_coherent(
+ amports_get_dma_device(),
+ USER_DATA_SIZE,
+ hw->user_data_buffer,
+ hw->user_data_buffer_phys);
+ hw->user_data_buffer = NULL;
+ hw->user_data_buffer_phys = 0;
+ }
+#endif
+
+ if (hw->fw) {
+ vfree(hw->fw);
+ hw->fw = NULL;
+ }
+
+ amvdec_disable();
+ //vdec_disable_DMC(NULL);
+
+ hw->pic_type = 0;
+ if (hw->mm_blk_handle) {
+ decoder_bmmu_box_free(hw->mm_blk_handle);
+ hw->mm_blk_handle = NULL;
+ }
+#ifdef DEBUG_PTS
+ pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit,
+ hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed);
+ pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag,
+ hw->vavs_amstream_dec_info.rate);
+#endif
+ kfree(hw->gvs);
+ hw->gvs = NULL;
+
+ return 0;
+}
+
+/****************************************/
+
+static struct platform_driver amvdec_avs_driver = {
+ .probe = amvdec_avs_probe,
+ .remove = amvdec_avs_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ }
+};
+
+
+static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+ int ret = 1;
+
+ if ((hw->buf_status & 0xf) == 0xf &&
+ kfifo_len(&hw->recycle_q) == 0)
+ ret = 0;
+
+ if (ret)
+ hw->not_run_ready = 0;
+ else
+ hw->not_run_ready++;
+
+ if (ret != 0) {
+ if (vdec->parallel_dec == 1)
+ return (unsigned long)(CORE_MASK_VDEC_1);
+ else
+ return (unsigned long)(CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+ } else
+ return 0;
+}
+
+static void vavs_work(struct work_struct *work)
+{
+ struct vdec_avs_hw_s *hw =
+ container_of(work, struct vdec_avs_hw_s, work);
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ if (hw->dec_result != DEC_RESULT_AGAIN)
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "ammvdec_avs: vavs_work,result=%d,status=%d\n",
+ hw->dec_result, hw_to_vdec(hw)->next_status);
+ hw->again_flag = 0;
+ if (hw->dec_result == DEC_RESULT_USERDATA) {
+ userdata_push_process(hw);
+ return;
+ } else if (hw->dec_result == DEC_RESULT_DONE) {
+ hw->buf_recycle_status = 0;
+ if (!hw->ctx_valid)
+ hw->ctx_valid = 1;
+ vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ } else if (hw->dec_result == DEC_RESULT_AGAIN
+ && (hw_to_vdec(hw)->next_status !=
+ VDEC_STATUS_DISCONNECTED)) {
+ /*
+ stream base: stream buf empty or timeout
+ frame base: vdec_prepare_input fail
+ */
+ hw->again_flag = 1;
+ if (!vdec_has_more_input(hw_to_vdec(hw))) {
+ hw->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ } else if (hw->dec_result == DEC_RESULT_GET_DATA
+ && (hw_to_vdec(hw)->next_status !=
+ VDEC_STATUS_DISCONNECTED)) {
+ if (!vdec_has_more_input(hw_to_vdec(hw))) {
+ hw->dec_result = DEC_RESULT_EOS;
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ debug_print(hw, PRINT_FLAG_VLD_DETAIL,
+ "%s DEC_RESULT_GET_DATA %x %x %x\n",
+ __func__,
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP));
+ vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ vdec_clean_input(hw_to_vdec(hw));
+ return;
+ } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
+ debug_print(hw, PRINT_FLAG_ERROR,
+ "%s: force exit\n", __func__);
+ if (hw->stat & STAT_ISR_REG) {
+ amvdec_stop();
+ /*disable mbox interrupt */
+ WRITE_VREG(ASSIST_MBOX1_MASK, 0);
+ vdec_free_irq(VDEC_IRQ_1, (void *)hw);
+ hw->stat &= ~STAT_ISR_REG;
+ }
+ } else if (hw->dec_result == DEC_RESULT_EOS) {
+ pr_info("%s: end of stream\n", __func__);
+ if (hw->stat & STAT_VDEC_RUN) {
+ amvdec_stop();
+ hw->stat &= ~STAT_VDEC_RUN;
+ }
+ hw->eos = 1;
+ vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ vdec_clean_input(hw_to_vdec(hw));
+ }
+ if (hw->stat & STAT_VDEC_RUN) {
+#if DEBUG_MULTI_FLAG == 1
+#else
+ amvdec_stop();
+#endif
+ hw->stat &= ~STAT_VDEC_RUN;
+ }
+ /*wait_vmmpeg12_search_done(hw);*/
+ if (hw->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&hw->check_timer);
+ hw->stat &= ~STAT_TIMER_ARM;
+ }
+
+ if (vdec->parallel_dec == 1)
+ vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1);
+ else
+ vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+
+ if (hw->vdec_cb) {
+ hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
+ debug_print(hw, 0x80000,
+ "%s:\n", __func__);
+ }
+}
+
+
+static void reset_process_time(struct vdec_avs_hw_s *hw)
+{
+ if (!hw->m_ins_flag)
+ return;
+ if (hw->start_process_time) {
+ unsigned process_time =
+ 1000 * (jiffies - hw->start_process_time) / HZ;
+ hw->start_process_time = 0;
+ if (process_time > max_process_time[DECODE_ID(hw)])
+ max_process_time[DECODE_ID(hw)] = process_time;
+ }
+}
+static void start_process_time(struct vdec_avs_hw_s *hw)
+{
+ hw->decode_timeout_count = 2;
+ hw->start_process_time = jiffies;
+}
+
+static void handle_decoding_error(struct vdec_avs_hw_s *hw)
+{
+ int i;
+ unsigned long flags;
+ struct vframe_s *vf;
+ spin_lock_irqsave(&lock, flags);
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ vf = &hw->vfpool[i];
+ if (vf->index < vf_buf_num)
+ vf->index = -1;
+ }
+ for (i = 0; i < vf_buf_num; i++)
+ hw->vfbuf_use[i] = 0;
+ hw->reset_decode_flag = 1;
+ hw->buf_status = 0;
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static void timeout_process(struct vdec_avs_hw_s *hw)
+{
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ amvdec_stop();
+ handle_decoding_error(hw);
+ debug_print(hw, PRINT_FLAG_ERROR,
+ "%s decoder timeout, status=%d, level=%d\n",
+ __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL));
+ hw->dec_result = DEC_RESULT_DONE;
+ reset_process_time(hw);
+ hw->first_i_frame_ready = 0;
+ vdec_schedule_work(&hw->work);
+}
+
+
+static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw)
+{
+ if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
+ struct vframe_s *vf;
+
+ if (kfifo_get(&hw->recycle_q, &vf)) {
+ if ((vf->index < vf_buf_num) &&
+ (vf->index >= 0) &&
+ (--hw->vfbuf_use[vf->index] == 0)) {
+ hw->buf_recycle_status |= (1 << vf->index);
+ WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d => buf_recycle_status 0x%x\n",
+ __func__,
+ READ_VREG(AVS_BUFFERIN), vf->index,
+ hw->buf_recycle_status);
+ }
+ vf->index = vf_buf_num;
+ kfifo_put(&hw->newframe_q,
+ (const struct vframe_s *)vf);
+ }
+
+ }
+
+}
+
+static void recycle_frames(struct vdec_avs_hw_s *hw)
+{
+ while (!kfifo_is_empty(&hw->recycle_q)) {
+ struct vframe_s *vf;
+
+ if (kfifo_get(&hw->recycle_q, &vf)) {
+ if ((vf->index < vf_buf_num) &&
+ (vf->index >= 0) &&
+ (--hw->vfbuf_use[vf->index] == 0)) {
+ hw->buf_recycle_status |= (1 << vf->index);
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s for vf index of %d => buf_recycle_status 0x%x\n",
+ __func__,
+ vf->index,
+ hw->buf_recycle_status);
+ }
+ vf->index = vf_buf_num;
+ kfifo_put(&hw->newframe_q,
+ (const struct vframe_s *)vf);
+ }
+
+ }
+
+}
+
+
+static void check_timer_func(unsigned long arg)
+{
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg;
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ unsigned int timeout_val = decode_timeout_val;
+ unsigned long flags;
+
+ if (hw->m_ins_flag &&
+ (debug_flag &
+ DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 &&
+ vdec->next_status ==
+ VDEC_STATUS_DISCONNECTED) {
+ hw->dec_result = DEC_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&hw->work);
+ debug_print(hw,
+ 0, "vdec requested to be disconnected\n");
+ return;
+ }
+
+ /*recycle*/
+ if (!hw->m_ins_flag ||
+ hw->dec_result == DEC_RESULT_NONE) {
+ spin_lock_irqsave(&lock, flags);
+ recycle_frame_bufferin(hw);
+ spin_unlock_irqrestore(&lock, flags);
+ }
+ 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 (dbg_cmd != 0) {
+ if (dbg_cmd == 1) {
+ int r = vdec_sync_input(vdec);
+ dbg_cmd = 0;
+ pr_info(
+ "vdec_sync_input=>0x%x, (lev %x, wp %x rp %x, prp %x, pwp %x)\n",
+ r,
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_PARSER_REG(PARSER_VIDEO_RP),
+ READ_PARSER_REG(PARSER_VIDEO_WP));
+ }
+ }
+
+ if ((debug_flag & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 &&
+ (input_frame_based(vdec) ||
+ (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x100)) &&
+ (timeout_val > 0) &&
+ (hw->start_process_time > 0) &&
+ ((1000 * (jiffies - hw->start_process_time) / HZ)
+ > timeout_val)) {
+ if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
+ if (hw->decode_timeout_count > 0)
+ hw->decode_timeout_count--;
+ if (hw->decode_timeout_count == 0)
+ timeout_process(hw);
+ }
+ hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
+ }
+
+ if (READ_VREG(AVS_SOS_COUNT)) {
+ if (!error_recovery_mode) {
+ amvdec_stop();
+ handle_decoding_error(hw);
+ debug_print(hw, PRINT_FLAG_ERROR,
+ "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n",
+ __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(AVS_SOS_COUNT));
+ hw->dec_result = DEC_RESULT_DONE;
+ reset_process_time(hw);
+ hw->first_i_frame_ready = 0;
+ vdec_schedule_work(&hw->work);
+ }
+ }
+
+ if ((hw->ucode_pause_pos != 0) &&
+ (hw->ucode_pause_pos != 0xffffffff) &&
+ udebug_pause_pos != hw->ucode_pause_pos) {
+ hw->ucode_pause_pos = 0;
+ WRITE_VREG(DEBUG_REG1, 0);
+ }
+
+ if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
+ hw->dec_result = DEC_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&hw->work);
+ pr_info("vdec requested to be disconnected\n");
+ return;
+ }
+
+ mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
+}
+
+static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw)
+{
+ /*int r = 0;*/
+#if DEBUG_MULTI_FLAG > 0
+ if (hw->decode_pic_count > 0)
+ vavs_prot_init_vld_only(hw);
+ else
+#endif
+ vavs_prot_init(hw);
+ return 0;
+}
+
+static unsigned char get_data_check_sum
+ (struct vdec_avs_hw_s *hw, int size)
+{
+ int jj;
+ int sum = 0;
+ u8 *data = NULL;
+
+ if (!hw->chunk->block->is_mapped)
+ data = codec_mm_vmap(hw->chunk->block->start +
+ hw->chunk->offset, size);
+ else
+ data = ((u8 *)hw->chunk->block->start_virt) +
+ hw->chunk->offset;
+
+ for (jj = 0; jj < size; jj++)
+ sum += data[jj];
+
+ if (!hw->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ return sum;
+}
+
+static void run(struct vdec_s *vdec, unsigned long mask,
+void (*callback)(struct vdec_s *, void *),
+ void *arg)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+ int save_reg = READ_VREG(POWER_CTL_VLD);
+ int size, ret;
+ /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/
+#if DEBUG_MULTI_FLAG > 0
+ if (hw->decode_pic_count == 0) {
+#endif
+ WRITE_VREG(DOS_SW_RESET0, 0xfffffff0);
+ WRITE_VREG(DOS_SW_RESET0, 0);
+ WRITE_VREG(POWER_CTL_VLD, save_reg);
+ hw->run_count++;
+ vdec_reset_core(vdec);
+#if DEBUG_MULTI_FLAG > 0
+ }
+#endif
+ hw->vdec_cb_arg = arg;
+ hw->vdec_cb = callback;
+
+ size = vdec_prepare_input(vdec, &hw->chunk);
+ if (debug & DEBUG_FLAG_PREPARE_MORE_INPUT) {
+ if (size < start_decode_buf_level) {
+ /*debug_print(hw, PRINT_FLAG_VLD_DETAIL,
+ "DEC_RESULT_AGAIN %x %x %x\n",
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP));*/
+
+ hw->input_empty++;
+ hw->dec_result = DEC_RESULT_AGAIN;
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ } else {
+ if (size < 0) {
+ hw->input_empty++;
+ hw->dec_result = DEC_RESULT_AGAIN;
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ }
+ if (input_frame_based(vdec)) {
+ u8 *data = NULL;
+
+ if (!hw->chunk->block->is_mapped)
+ data = codec_mm_vmap(hw->chunk->block->start +
+ hw->chunk->offset, size);
+ else
+ data = ((u8 *)hw->chunk->block->start_virt) +
+ hw->chunk->offset;
+
+ if (debug_flag & PRINT_FLAG_RUN_FLOW
+ ) {
+ debug_print(hw, 0,
+ "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
+ __func__, hw->decode_pic_count,
+ hw->buf_recycle_status,
+ size, get_data_check_sum(hw, size),
+ data[0], data[1], data[2], data[3],
+ data[4], data[5], data[size - 4],
+ data[size - 3], data[size - 2],
+ data[size - 1]);
+ }
+ if (debug_flag & PRINT_FRAMEBASE_DATA
+ ) {
+ int jj;
+
+ for (jj = 0; jj < size; jj++) {
+ if ((jj & 0xf) == 0)
+ debug_print(hw,
+ PRINT_FRAMEBASE_DATA,
+ "%06x:", jj);
+ debug_print(hw,
+ PRINT_FRAMEBASE_DATA,
+ "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ debug_print(hw,
+ PRINT_FRAMEBASE_DATA,
+ "\n");
+ }
+ }
+
+ if (!hw->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ } else
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "%s decode_pic_count %d buf_recycle_status 0x%x: %x %x %x %x %x size 0x%x\n",
+ __func__,
+ hw->decode_pic_count,
+ hw->buf_recycle_status,
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_PARSER_REG(PARSER_VIDEO_RP),
+ READ_PARSER_REG(PARSER_VIDEO_WP),
+ size);
+
+
+ hw->input_empty = 0;
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "%s,%d, size=%d\n", __func__, __LINE__, size);
+ vdec_enable_input(vdec);
+ hw->init_flag = 1;
+
+ if (hw->chunk)
+ debug_print(hw, PRINT_FLAG_RUN_FLOW,
+ "input chunk offset %d, size %d\n",
+ hw->chunk->offset, hw->chunk->size);
+
+ hw->dec_result = DEC_RESULT_NONE;
+ /*vdec->mc_loaded = 0;*/
+ if (vdec->mc_loaded) {
+ /*firmware have load before,
+ and not changes to another.
+ ignore reload.
+ */
+ } else {
+ ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_AVS, "avs_multi", vdec,
+ hw->fw->data, hw->fw->len);
+ if (ret < 0) {
+ pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
+ hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
+ hw->dec_result = DEC_RESULT_FORCE_EXIT;
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ vdec->mc_loaded = 1;
+ vdec->mc_type = VFORMAT_AVS;
+ }
+
+ if (avs_hw_ctx_restore(hw) < 0) {
+ hw->dec_result = DEC_RESULT_ERROR;
+ debug_print(hw, PRINT_FLAG_ERROR,
+ "ammvdec_avs: error HW context restore\n");
+ vdec_schedule_work(&hw->work);
+ return;
+ }
+ /*wmb();*/
+ hw->stat |= STAT_MC_LOAD;
+ hw->last_vld_level = 0;
+
+ debug_print(hw, PRINT_FLAG_DECODING,
+ "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n",
+ __func__, READ_VREG(AVS_BUFFERIN),
+ kfifo_len(&hw->recycle_q));
+ recycle_frames(hw);
+ if (hw->reset_decode_flag) {
+ hw->buf_recycle_status = 0xff;
+ WRITE_VREG(AVS_BUFFERIN, 0);
+ WRITE_VREG(AVS_BUFFEROUT, 0);
+ }
+ WRITE_VREG(DECODE_STATUS,
+ hw->decode_pic_count |
+ ((~hw->buf_recycle_status) << 24));
+ hw->buf_recycle_status = 0;
+ hw->reset_decode_flag = 0;
+
+ start_process_time(hw);
+#if DEBUG_MULTI_FLAG == 1
+ if (hw->decode_pic_count > 0)
+ WRITE_VREG(DECODE_STATUS, 0xff);
+ else
+#endif
+ amvdec_start();
+ hw->stat |= STAT_VDEC_RUN;
+
+ hw->stat |= STAT_TIMER_ARM;
+
+ mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
+}
+
+static void reset(struct vdec_s *vdec)
+{
+}
+
+static irqreturn_t vmavs_isr_thread_fn(struct vdec_s *vdec, int irq)
+{
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+
+ return vavs_isr(0, hw);
+
+}
+
+static void vmavs_dump_state(struct vdec_s *vdec)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)vdec->private;
+
+ debug_print(hw, 0,
+ "====== %s\n", __func__);
+
+ debug_print(hw, 0,
+ "width/height (%d/%d), dur %d\n",
+ hw->frame_width,
+ hw->frame_height,
+ hw->frame_dur
+ );
+
+ debug_print(hw, 0,
+ "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
+ vdec_frame_based(vdec),
+ READ_VREG(DECODE_STATUS) & 0xff,
+ hw->buf_status,
+ hw->buf_recycle_status,
+ hw->eos,
+ hw->stat,
+ hw->dec_result,
+ hw->decode_pic_count,
+ hw->display_frame_count,
+ hw->run_count,
+ hw->not_run_ready,
+ hw->input_empty
+ );
+
+ if (vf_get_receiver(vdec->vf_provider_name)) {
+ enum receviver_start_e state =
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE,
+ NULL);
+ debug_print(hw, 0,
+ "\nreceiver(%s) state %d\n",
+ vdec->vf_provider_name,
+ state);
+ }
+
+ debug_print(hw, 0,
+ "%s, newq(%d/%d), dispq(%d/%d)recycleq(%d/%d) drop %d vf peek %d, prepare/get/put (%d/%d/%d)\n",
+ __func__,
+ kfifo_len(&hw->newframe_q),
+ VF_POOL_SIZE,
+ kfifo_len(&hw->display_q),
+ VF_POOL_SIZE,
+ kfifo_len(&hw->recycle_q),
+ VF_POOL_SIZE,
+ hw->drop_frame_count,
+ hw->peek_num,
+ hw->prepare_num,
+ hw->get_num,
+ hw->put_num
+ );
+
+ debug_print(hw, 0,
+ "DECODE_STATUS=0x%x\n",
+ READ_VREG(DECODE_STATUS));
+ debug_print(hw, 0,
+ "MPC_E=0x%x\n",
+ READ_VREG(MPC_E));
+ debug_print(hw, 0,
+ "DECODE_MODE=0x%x\n",
+ READ_VREG(DECODE_MODE));
+ debug_print(hw, 0,
+ "MBY_MBX=0x%x\n",
+ READ_VREG(MBY_MBX));
+ debug_print(hw, 0,
+ "VIFF_BIT_CNT=0x%x\n",
+ READ_VREG(VIFF_BIT_CNT));
+ debug_print(hw, 0,
+ "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL));
+ debug_print(hw, 0,
+ "VLD_MEM_VIFIFO_WP=0x%x\n",
+ READ_VREG(VLD_MEM_VIFIFO_WP));
+ debug_print(hw, 0,
+ "VLD_MEM_VIFIFO_RP=0x%x\n",
+ READ_VREG(VLD_MEM_VIFIFO_RP));
+ debug_print(hw, 0,
+ "PARSER_VIDEO_RP=0x%x\n",
+ READ_PARSER_REG(PARSER_VIDEO_RP));
+ debug_print(hw, 0,
+ "PARSER_VIDEO_WP=0x%x\n",
+ READ_PARSER_REG(PARSER_VIDEO_WP));
+
+ if (vdec_frame_based(vdec) &&
+ (debug & PRINT_FRAMEBASE_DATA)
+ ) {
+ int jj;
+ if (hw->chunk && hw->chunk->block &&
+ hw->chunk->size > 0) {
+ u8 *data = NULL;
+
+ if (!hw->chunk->block->is_mapped)
+ data = codec_mm_vmap(hw->chunk->block->start +
+ hw->chunk->offset, hw->chunk->size);
+ else
+ data = ((u8 *)hw->chunk->block->start_virt)
+ + hw->chunk->offset;
+
+ debug_print(hw, 0,
+ "frame data size 0x%x\n",
+ hw->chunk->size);
+ for (jj = 0; jj < hw->chunk->size; jj++) {
+ if ((jj & 0xf) == 0)
+ debug_print(hw,
+ PRINT_FRAMEBASE_DATA,
+ "%06x:", jj);
+ debug_print_cont(hw,
+ PRINT_FRAMEBASE_DATA,
+ "%02x ", data[jj]);
+ if (((jj + 1) & 0xf) == 0)
+ debug_print_cont(hw,
+ PRINT_FRAMEBASE_DATA,
+ "\n");
+ }
+
+ if (!hw->chunk->block->is_mapped)
+ codec_mm_unmap_phyaddr(data);
+ }
+ }
+
+}
+
+static int ammvdec_avs_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+ struct vdec_avs_hw_s *hw = NULL;
+
+ pr_info("ammvdec_avs probe start.\n");
+
+ if (pdata == NULL) {
+ pr_info("ammvdec_avs platform data undefined.\n");
+ return -EFAULT;
+ }
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev,
+ sizeof(struct vdec_avs_hw_s), GFP_KERNEL);
+ if (hw == NULL) {
+ pr_info("\nammvdec_avs decoder driver alloc failed\n");
+ return -ENOMEM;
+ }
+ pr_info("%s %d\n", __func__, __LINE__);
+ /*atomic_set(&hw->error_handler_run, 0);*/
+ hw->m_ins_flag = 1;
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
+ firmware_sel = 1;
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ if (firmware_sel == 1) {
+ vf_buf_num = 4;
+ canvas_base = 0;
+ canvas_num = 3;
+ } else {
+ pr_info("Error, do not support longcabac work around!!!");
+ return -ENOMEM;
+ }
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ if (pdata->sys_info)
+ hw->vavs_amstream_dec_info = *pdata->sys_info;
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ hw->is_reset = 0;
+ pdata->user_data_read = NULL;
+ pdata->reset_userdata_fifo = NULL;
+
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ pdata->private = hw;
+ pdata->dec_status = vavs_dec_status;
+ pdata->set_isreset = vavs_set_isreset;
+ pdata->run_ready = run_ready;
+ pdata->run = run;
+ pdata->reset = reset;
+ pdata->irq_handler = vmavs_isr;
+ pdata->threaded_irq_handler = vmavs_isr_thread_fn;
+ pdata->dump_state = vmavs_dump_state;
+
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ vavs_vdec_info_init(hw);
+
+ pr_info("%s %d\n", __func__, __LINE__);
+
+#ifdef ENABLE_USER_DATA
+ if (NULL == hw->user_data_buffer) {
+ hw->user_data_buffer =
+ dma_alloc_coherent(amports_get_dma_device(),
+ USER_DATA_SIZE,
+ &hw->user_data_buffer_phys, GFP_KERNEL);
+ if (!hw->user_data_buffer) {
+ pr_info("%s: Can not allocate hw->user_data_buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+ pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n",
+ hw->user_data_buffer, (u32)hw->user_data_buffer_phys);
+ }
+#endif
+ hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL);
+ if (hw->lmem_addr == NULL) {
+ pr_err("%s: failed to alloc lmem buffer\n", __func__);
+ return -1;
+ }
+ hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(),
+ hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(amports_get_dma_device(),
+ hw->lmem_phy_addr)) {
+ pr_err("%s: failed to map lmem buffer\n", __func__);
+ kfree(hw->lmem_addr);
+ hw->lmem_addr = NULL;
+ return -1;
+ }
+
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/
+
+ pr_info("%s %d\n", __func__, __LINE__);
+
+ if (vavs_init(hw) < 0) {
+ pr_info("amvdec_avs init failed.\n");
+ kfree(hw->gvs);
+ hw->gvs = NULL;
+ pdata->dec_status = NULL;
+ return -ENODEV;
+ }
+
+ /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler);
+ atomic_set(&hw->error_handler_run, 0);*/
+#if 0
+#ifdef ENABLE_USER_DATA
+ INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
+#endif
+#endif
+ INIT_WORK(&hw->notify_work, vavs_notify_work);
+
+ if (pdata->use_vfm_path) {
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ VFM_DEC_PROVIDER_NAME);
+ hw->frameinfo_enable = 1;
+ }
+ else
+ snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+ MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+ if (pdata->parallel_dec == 1) {
+ int i;
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
+ hw->canvas_spec[i] = 0xffffff;
+ }
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vavs_vf_provider, hw);
+
+ platform_set_drvdata(pdev, pdata);
+
+ hw->platform_dev = pdev;
+
+ vdec_set_prepare_level(pdata, start_decode_buf_level);
+
+ if (pdata->parallel_dec == 1)
+ vdec_core_request(pdata, CORE_MASK_VDEC_1);
+ else {
+ vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
+ | CORE_MASK_COMBINE);
+ }
+
+ /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/
+ return 0;
+}
+
+static int ammvdec_avs_remove(struct platform_device *pdev)
+{
+ struct vdec_avs_hw_s *hw =
+ (struct vdec_avs_hw_s *)
+ (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ int i;
+
+ if (hw->stat & STAT_VDEC_RUN) {
+ amvdec_stop();
+ hw->stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (hw->stat & STAT_ISR_REG) {
+ vdec_free_irq(VDEC_IRQ_1, (void *)hw);
+ hw->stat &= ~STAT_ISR_REG;
+ }
+
+ if (hw->stat & STAT_TIMER_ARM) {
+ del_timer_sync(&hw->check_timer);
+ hw->stat &= ~STAT_TIMER_ARM;
+ }
+
+ cancel_work_sync(&hw->work);
+ cancel_work_sync(&hw->notify_work);
+
+ if (hw->mm_blk_handle) {
+ decoder_bmmu_box_free(hw->mm_blk_handle);
+ hw->mm_blk_handle = NULL;
+ }
+ if (vdec->parallel_dec == 1)
+ vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
+ else
+ vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
+ vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
+
+ if (vdec->parallel_dec == 1) {
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
+ vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
+ vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
+ }
+ }
+#ifdef ENABLE_USER_DATA
+ if (hw->user_data_buffer != NULL) {
+ dma_free_coherent(
+ amports_get_dma_device(),
+ USER_DATA_SIZE,
+ hw->user_data_buffer,
+ hw->user_data_buffer_phys);
+ hw->user_data_buffer = NULL;
+ hw->user_data_buffer_phys = 0;
+ }
+#endif
+ if (hw->lmem_addr) {
+ dma_unmap_single(amports_get_dma_device(),
+ hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE);
+ kfree(hw->lmem_addr);
+ hw->lmem_addr = NULL;
+ }
+
+ if (hw->fw) {
+ vfree(hw->fw);
+ hw->fw = NULL;
+ }
+
+ pr_info("ammvdec_avs removed.\n");
+ if (hw->gvs) {
+ kfree(hw->gvs);
+ hw->gvs = NULL;
+ }
+
+ return 0;
+}
+
+
+static struct platform_driver ammvdec_avs_driver = {
+ .probe = ammvdec_avs_probe,
+ .remove = ammvdec_avs_remove,
+#ifdef CONFIG_PM
+ .suspend = amvdec_suspend,
+ .resume = amvdec_resume,
+#endif
+ .driver = {
+ .name = MULTI_DRIVER_NAME,
+ }
+};
+
+static struct codec_profile_t ammvdec_avs_profile = {
+ .name = "mavs",
+ .profile = ""
+};
+
+static struct mconfig mavs_configs[] = {
+ /*MC_PU32("stat", &stat),
+ MC_PU32("debug_flag", &debug_flag),
+ MC_PU32("error_recovery_mode", &error_recovery_mode),
+ MC_PU32("hw->pic_type", &hw->pic_type),
+ MC_PU32("radr", &radr),
+ MC_PU32("vf_buf_num", &vf_buf_num),
+ MC_PU32("vf_buf_num_used", &vf_buf_num_used),
+ MC_PU32("canvas_base", &canvas_base),
+ MC_PU32("firmware_sel", &firmware_sel),
+ */
+};
+static struct mconfig_node mavs_node;
+
+
+static int __init ammvdec_avs_driver_init_module(void)
+{
+ pr_debug("ammvdec_avs module init\n");
+
+ if (platform_driver_register(&ammvdec_avs_driver))
+ pr_err("failed to register ammvdec_avs driver\n");
+
+ /*if (platform_driver_register(&amvdec_avs_driver)) {
+ pr_info("failed to register amvdec_avs driver\n");
+ return -ENODEV;
+ }*/
+ amvdec_avs_driver = amvdec_avs_driver;
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
+ ammvdec_avs_profile.profile = "avs+";
+
+ //vcodec_profile_register(&ammvdec_avs_profile);
+ INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node,
+ "mavs", mavs_configs, CONFIG_FOR_RW);
+ return 0;
+}
+
+
+
+static void __exit ammvdec_avs_driver_remove_module(void)
+{
+ pr_debug("ammvdec_avs module remove.\n");
+
+ platform_driver_unregister(&ammvdec_avs_driver);
+
+ /*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(step, uint, 0664);
+MODULE_PARM_DESC(step, "\n step\n");
+
+module_param(debug_flag, uint, 0664);
+MODULE_PARM_DESC(debug_flag, "\n debug_flag\n");
+
+module_param(debug_mask, uint, 0664);
+MODULE_PARM_DESC(debug_mask, "\n debug_mask\n");
+
+module_param(error_recovery_mode, uint, 0664);
+MODULE_PARM_DESC(error_recovery_mode, "\n error_recovery_mode\n");
+
+/******************************************
+ *module_param(error_watchdog_threshold, uint, 0664);
+ *MODULE_PARM_DESC(error_watchdog_threshold, "\n error_watchdog_threshold\n");
+ *
+ *module_param(error_watchdog_buf_threshold, uint, 0664);
+ *MODULE_PARM_DESC(error_watchdog_buf_threshold,
+ * "\n error_watchdog_buf_threshold\n");
+ *******************************************
+ */
+/*
+module_param(pic_type, uint, 0444);
+MODULE_PARM_DESC(pic_type, "\n amdec_vas picture type\n");
+*/
+module_param(radr, uint, 0664);
+MODULE_PARM_DESC(radr, "\nradr\n");
+
+module_param(rval, uint, 0664);
+MODULE_PARM_DESC(rval, "\nrval\n");
+
+module_param(dbg_cmd, uint, 0664);
+MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n");
+
+module_param(vf_buf_num, uint, 0664);
+MODULE_PARM_DESC(vf_buf_num, "\nvf_buf_num\n");
+
+/*
+module_param(vf_buf_num_used, uint, 0664);
+MODULE_PARM_DESC(vf_buf_num_used, "\nvf_buf_num_used\n");
+*/
+module_param(canvas_base, uint, 0664);
+MODULE_PARM_DESC(canvas_base, "\ncanvas_base\n");
+
+
+module_param(firmware_sel, uint, 0664);
+MODULE_PARM_DESC(firmware_sel, "\n firmware_sel\n");
+
+module_param(disable_longcabac_trans, uint, 0664);
+MODULE_PARM_DESC(disable_longcabac_trans, "\n disable_longcabac_trans\n");
+
+module_param(dec_control, uint, 0664);
+MODULE_PARM_DESC(dec_control, "\n amvdec_vavs decoder control\n");
+
+module_param(start_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(start_decode_buf_level,
+ "\n avs start_decode_buf_level\n");
+
+module_param(decode_timeout_val, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val,
+ "\n avs decode_timeout_val\n");
+
+module_param(udebug_flag, uint, 0664);
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
+
+module_param(udebug_pause_pos, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
+
+module_param(udebug_pause_val, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
+
+module_param(udebug_pause_decode_idx, uint, 0664);
+MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
+
+module_param(force_fps, uint, 0664);
+MODULE_PARM_DESC(force_fps, "\n force_fps\n");
+
+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_init(ammvdec_avs_driver_init_module);
+module_exit(ammvdec_avs_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC AVS Video Decoder Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.h b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
new file mode 100644
index 0000000..8922b40
--- a/dev/null
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
@@ -0,0 +1,90 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef AVS_H_
+#define AVS_H_
+
+#ifdef CONFIG_AMLOGIC_AVSP_LONG_CABAC
+#define AVSP_LONG_CABAC
+#endif
+/*#define BITSTREAM_READ_TMP_NO_CACHE*/
+
+#ifdef AVSP_LONG_CABAC
+#define MAX_CODED_FRAME_SIZE 1500000 /*!< bytes for one frame*/
+#define LOCAL_HEAP_SIZE (1024*1024*10)
+/*
+ *#define MAX_CODED_FRAME_SIZE 240000
+ *#define MAX_CODED_FRAME_SIZE 700000
+ */
+#define SVA_STREAM_BUF_SIZE 1024
+
+extern void *es_write_addr_virt;
+extern dma_addr_t es_write_addr_phy;
+
+extern void *bitstream_read_tmp;
+extern dma_addr_t bitstream_read_tmp_phy;
+extern void *avsp_heap_adr;
+
+int avs_get_debug_flag(void);
+
+int process_long_cabac(void);
+
+/* bit [6] - skip_mode_flag
+ * bit [5:4] - picture_type
+ * bit [3] - picture_structure (0-Field, 1-Frame)
+ * bit [2] - fixed_picture_qp
+ * bit [1] - progressive_sequence
+ * bit [0] - active
+ */
+#define LONG_CABAC_REQ AV_SCRATCH_K
+#define LONG_CABAC_SRC_ADDR AV_SCRATCH_H
+#define LONG_CABAC_DES_ADDR AV_SCRATCH_I
+/* bit[31:16] - vertical_size
+ * bit[15:0] - horizontal_size
+ */
+#define LONG_CABAC_PIC_SIZE AV_SCRATCH_J
+
+#endif
+
+/*
+ *#define PERFORMANCE_DEBUG
+ *#define DUMP_DEBUG
+ */
+#define AVS_DEBUG_PRINT 0x01
+#define AVS_DEBUG_OLD_ERROR_HANDLE 0x10
+#define AVS_DEBUG_USE_FULL_SPEED 0x80
+#define AEC_DUMP 0x100
+#define STREAM_INFO_DUMP 0x200
+#define SLICE_INFO_DUMP 0x400
+#define MB_INFO_DUMP 0x800
+#define MB_NUM_DUMP 0x1000
+#define BLOCK_NUM_DUMP 0x2000
+#define COEFF_DUMP 0x4000
+#define ES_DUMP 0x8000
+#define DQUANT_DUMP 0x10000
+#define STREAM_INFO_DUMP_MORE 0x20000
+#define STREAM_INFO_DUMP_MORE2 0x40000
+
+extern void *es_write_addr_virt;
+extern void *bitstream_read_tmp;
+extern dma_addr_t bitstream_read_tmp_phy;
+int read_bitstream(unsigned char *Buf, int size);
+int u_v(int LenInBits, char *tracestring);
+
+#endif
diff --git a/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c b/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c
new file mode 100644
index 0000000..89ff844
--- a/dev/null
+++ b/drivers/frame_provider/decoder/avs_multi/avsp_trans_multi.c
@@ -0,0 +1,5065 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/dma-mapping.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/slab.h>
+/* #include <mach/am_regs.h> */
+#include <linux/module.h>
+#include <linux/amlogic/media/utils/vdec_reg.h>
+#include "../../../stream_input/parser/streambuf_reg.h"
+#include "../utils/amvdec.h"
+#include <linux/amlogic/media/registers/register.h>
+#include "../../../stream_input/amports/amports_priv.h"
+
+#include "avs_multi.h"
+#ifdef AVSP_LONG_CABAC
+
+#define DECODING_SANITY_CHECK
+
+#define TRACE 0
+#define LIWR_FIX 0
+#define pow2(a, b) (1<<b)
+#define io_printf pr_info
+
+static unsigned char *local_heap_adr;
+static int local_heap_size;
+static int local_heap_pos;
+static int transcoding_error_flag;
+
+unsigned char *local_alloc(int num, int size)
+{
+ unsigned char *ret_buf = NULL;
+ int alloc_size = num * size;
+
+ if ((local_heap_pos + alloc_size) <= local_heap_size) {
+ ret_buf = local_heap_adr + local_heap_pos;
+ local_heap_pos += alloc_size;
+ } else {
+ pr_info(
+ "!!!local_alloc(%d) error, local_heap (size %d) is not enough\r\n",
+ alloc_size, local_heap_size);
+ }
+ return ret_buf;
+}
+
+int local_heap_init(int size)
+{
+ /*local_heap_adr = &local_heap[0];*/
+ local_heap_adr = (unsigned char *)(avsp_heap_adr +
+ MAX_CODED_FRAME_SIZE);
+ memset(local_heap_adr, 0, LOCAL_HEAP_SIZE);
+
+ local_heap_size = LOCAL_HEAP_SIZE;
+ local_heap_pos = 0;
+ return 0;
+}
+
+void local_heap_uninit(void)
+{
+ local_heap_adr = NULL;
+ local_heap_size = 0;
+ local_heap_pos = 0;
+}
+
+#define CODE2D_ESCAPE_SYMBOL 59
+
+const int vlc_golomb_order[3][7][2] =
+
+{{{2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{3, 9}, {2, 9}, {
+ 2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{2, 9}, {0, 9},
+ {1, 9}, {1, 9}, {0, 9}, {-1, -1}, {-1, -1}, }, };
+
+const int MaxRun[3][7] = {{22, 14, 9, 6, 4, 2, 1}, {25, 18, 13, 9, 6, 4, 3}, {
+ 24, 19, 10, 7, 4, -1, -1} };
+
+const int refabslevel[19][26] = {{4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1}, {7, 4, 4, 3, 3, 3, 3, 3, 2,
+ 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, 3, 2, 2, -1, -1,
+ -1 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, 7, 3, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4,
+ 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2}, {5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 5, 4, 4, 3, 3, 3, 2, 2,
+ 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4,
+ 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {17, 8, 4,
+ 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1}, {6, 4, 3,
+ 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, -1, -1, -1, -1, -1, -1}, {10, 6, 4, 4, 3, 3,
+ 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {14, 7, 4, 3, 3, 2,
+ 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1}, {20, 7, 3, 2,
+ 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} };
+
+static const int incvlc_intra[7] = {0, 1, 2, 4, 7, 10, 3000};
+static const int incvlc_chroma[5] = {0, 1, 2, 4, 3000};
+
+const int AVS_2DVLC_INTRA[7][26][27] = {{{0, 22, 38, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {2, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 44, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {6, 50, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {8, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {18, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {46, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {52, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {56, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 4, 15, 27, 41,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, 2, 17, 35, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {-1, 6, 25, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 9, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 11, 39, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 13, 45, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 19, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 21, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 31, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 37, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 47, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 2, 6,
+ 13, 17, 27, 35, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 4, 11, 21, 33, 49, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, 9, 23, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 15,
+ 29, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, 39, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, 25, 43, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, 31, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 41,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, 57, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, }, {{8, 0, 2, 4, 9, 11, 17, 21, 25, 33, 39, 45, 55, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 6, 13, 19,
+ 29, 35, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 15, 27, 41, 57, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 23, 37, 53, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 31, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 43, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, }, {{6, 0, 2, 4, 7, 9, 11, 15, 17,
+ 21, 23, 29, 33, 35, 43, 47, 49, 57, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, 13, 19, 27, 31, 37, 45, 55, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 25, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 39, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 53, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0,
+ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 27, 31, 33, 37, 41,
+ 45, 49, 51, 55, -1, -1, -1, -1, -1}, {-1, 21, 29, 35, 43, 47,
+ 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, 39, 57, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, }, {{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
+ 21, 23, 25, 27, 29, 31, 35, 37, 39, 41, 43, 47, 49, 51, 53, 57},
+ {-1, 33, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} } };
+
+const int AVS_2DVLC_CHROMA[5][26][27] = {{{0, 14, 32, 56, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {2, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1}, {6, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {38,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {46,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {50, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {52, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0, 1, 5, 15, 29,
+ 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 3, 21, 45, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1}, {-1, 7, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 9, 41, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 11, 53, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 31, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 33, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, },
+ {{2, 0, 3, 7, 11, 17, 27, 33, 47, 53, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 5, 13, 21, 37, 55, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 9, 23, 41, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 15, 31, 57, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 19, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, 25, 45, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 29, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, 39, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, }, {{0, 1, 3, 5, 7, 11, 15, 19, 23, 29,
+ 35, 43, 47, 53, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1}, {-1, 9, 13, 21, 31, 39, 51,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 17, 27,
+ 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {-1, 25, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 33, 55, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 45, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, 49, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, 57, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1}, {-1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1}, },
+ {{0, 1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 27, 29, 33, 37, 41,
+ 43, 51, 55, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 17, 25, 31, 39, 45, 53, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, 35, 49, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1}, } };
+
+const int UE[64][2] = {{1, 1}, {2, 3}, {3, 3}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {
+ 8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15,
+ 7}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9},
+ {22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {
+ 29, 9}, {30, 9}, {31, 9}, {32, 11}, {33, 11}, {
+ 34, 11}, {35, 11}, {36, 11}, {37, 11}, {38, 11},
+ {39, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45,
+ 11}, {46, 11}, {47, 11}, {48, 11}, {49, 11}, {
+ 50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11},
+ {55, 11}, {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61,
+ 11}, {62, 11}, {63, 11}, {64, 13} };
+
+unsigned int src_start;
+unsigned int des_start;
+
+#ifdef AVSP_LONG_CABAC
+
+unsigned char *es_buf;
+unsigned int es_buf_ptr;
+unsigned int es_buf_is_overflow;
+
+#else
+FILE *f_es;
+#endif
+unsigned int es_ptr;
+unsigned int es_res;
+unsigned int es_res_ptr;
+unsigned int previous_es;
+
+void init_es(void)
+{
+
+#ifdef AVSP_LONG_CABAC
+ es_buf_is_overflow = 0;
+
+ es_buf[0] = 0x00;
+ es_buf[1] = 0x00;
+ es_buf[2] = 0x01;
+ es_buf_ptr = 3;
+ es_ptr = 3;
+#else
+ f_es = fopen("es.out", "wb");
+ if (f_es == NULL)
+ io_printf(" ERROR : Can not open es.out for write\n");
+ putc(0x00, f_es);
+ putc(0x00, f_es);
+ putc(0x01, f_es);
+
+ es_ptr = 3;
+#endif
+ es_res = 0;
+ es_res_ptr = 0;
+ previous_es = 0xff;
+
+}
+
+void push_es(int value, int num)
+{
+ unsigned char wr_es_data;
+ int push_num;
+ int push_value;
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & ES_DUMP)
+ io_printf(" push_es : value : 0x%x, num : %d\n", value, num);
+#endif
+ while (num > 0) {
+ if (num >= 8)
+ push_num = 8;
+ else
+ push_num = num;
+
+ num = num - push_num;
+ push_value = (value >> num);
+
+ es_res = (es_res << push_num) | push_value;
+ es_res_ptr = es_res_ptr + push_num;
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & ES_DUMP)
+ io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n",
+ es_res, es_res_ptr);
+#endif
+
+ while (es_res_ptr >= 8) {
+ es_res_ptr = es_res_ptr & 7;
+ wr_es_data = (es_res >> es_res_ptr) & 0xff;
+ if ((previous_es == 0) & (wr_es_data < 4)) {
+ io_printf(
+ " Insert 2'b10 for emu at position : %d\n",
+ es_ptr);
+
+ es_res_ptr = es_res_ptr + 2;
+ wr_es_data = 2;
+ }
+#ifdef AVSP_LONG_CABAC
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & ES_DUMP)
+ pr_info("es_buf[%d] = 0x%02x\r\n",
+ es_buf_ptr, wr_es_data);
+#endif
+ if (!es_buf_is_overflow) {
+ es_buf[es_buf_ptr++] = wr_es_data;
+ if (es_buf_ptr >= MAX_CODED_FRAME_SIZE)
+ es_buf_is_overflow = 1;
+ }
+#else
+ putc(wr_es_data, f_es);
+#endif
+ es_ptr++;
+ previous_es = ((previous_es << 8) | wr_es_data)
+ & 0xffff;
+ }
+
+ }
+}
+
+#ifdef BLOCK_SIZE
+#undef BLOCK_SIZE
+#endif
+
+#define MIN_QP 0
+#define MAX_QP 63
+
+#define BLOCK_SIZE 4
+#define B8_SIZE 8
+#define MB_BLOCK_SIZE 16
+
+#define BLOCK_MULTIPLE (MB_BLOCK_SIZE/(BLOCK_SIZE*2))
+
+#define DECODE_COPY_MB 0
+#define DECODE_MB 1
+
+#define NO_INTRA_PMODE 5
+#define INTRA_PMODE_4x4 10
+#define NO_INTRA_PMODE_4x4 19
+/* 8x8 intra prediction modes */
+#define VERT_PRED 0
+#define HOR_PRED 1
+#define DC_PRED 2
+#define DOWN_LEFT_PRED 3
+#define DOWN_RIGHT_PRED 4
+
+#define VERT_PRED_4x4 0
+#define HOR_PRED_4x4 1
+#define DC_PRED_4x4 2
+#define DOWN_LEFT_PRED_4x4 3
+#define DOWN_RIGHT_PRED_4x4 4
+
+#define HOR_DOWN_PRED_4x4 5
+#define VERT_LEFT_PRED_4x4 6
+#define HOR_UP_PRED_4x4 7
+#define VERT_RIGHT_PRED_4x4 8
+
+#define DC_PRED_8 0
+#define HOR_PRED_8 1
+#define VERT_PRED_8 2
+#define PLANE_8 3
+
+#define LUMA_16DC 0
+#define LUMA_16AC 1
+#define LUMA_8x8 2
+#define LUMA_8x4 3
+#define LUMA_4x8 4
+#define LUMA_4x4 5
+#define CHROMA_DC 6
+#define CHROMA_AC 7
+#define NUM_BLOCK_TYPES 8
+
+#define I_PICTURE_START_CODE 0xB3
+#define PB_PICTURE_START_CODE 0xB6
+#define SLICE_START_CODE_MIN 0x00
+#define SLICE_START_CODE_MAX 0xAF
+#define USER_DATA_START_CODE 0xB2
+#define SEQUENCE_HEADER_CODE 0xB0
+#define EXTENSION_START_CODE 0xB5
+#define SEQUENCE_END_CODE 0xB1
+#define VIDEO_EDIT_CODE 0xB7
+
+#define EOS 1
+#define SOP 2
+#define SOS 3
+#define P8x8 8
+#define I8MB 9
+#define I4MB 10
+#define IBLOCK 11
+#define SI4MB 12
+#define MAXMODE 13
+
+#define IS_INTRA(MB) ((MB)->mb_type == I8MB || (MB)->mb_type == I4MB)
+#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB)
+#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB)
+#define IS_INTER(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB)
+#define IS_INTERMV(MB) ((MB)->mb_type != I8MB && (MB)->mb_type != I4MB\
+ && (MB)->mb_type != 0)
+
+#define IS_DIRECT(MB) ((MB)->mb_type == 0 && (img->type == B_IMG))
+#define IS_COPY(MB) ((MB)->mb_type == 0 && (img->type == P_IMG))
+#define IS_P8x8(MB) ((MB)->mb_type == P8x8)
+
+#define P_IMG 0
+#define B_IMG 1
+#define I_IMG 2
+
+#define FIELD 0
+#define FRAME 1
+
+#define SE_CABP 21
+struct decoding_environment_s {
+ unsigned int dbuffer;
+ int dbits_to_go;
+ unsigned char *dcodestrm;
+ int *dcodestrm_len;
+};
+
+struct bi_context_type_s {
+ unsigned char MPS;
+ unsigned int LG_PMPS;
+ unsigned char cycno;
+};
+
+
+/**********************************************************************
+ * C O N T E X T S F O R R M S Y N T A X E L E M E N T S
+ **********************************************************************
+ */
+
+#define NUM_MB_TYPE_CTX 11
+#define NUM_B8_TYPE_CTX 9
+#define NUM_MV_RES_CTX 10
+#define NUM_REF_NO_CTX 6
+#define NUM_DELTA_QP_CTX 4
+#define NUM_MB_AFF_CTX 4
+
+struct motion_info_contexts_s {
+ struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX];
+ struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX];
+ struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX];
+ struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX];
+ struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX];
+ struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX];
+#ifdef TEST_WEIGHTING_AEC
+struct bi_context_type_s mb_weighting_pred;
+#endif
+};
+
+#define NUM_IPR_CTX 2
+#define NUM_CIPR_CTX 4
+#define NUM_CBP_CTX 4
+#define NUM_BCBP_CTX 4
+#define NUM_MAP_CTX 16
+#define NUM_LAST_CTX 16
+
+#define NUM_ONE_CTX 5
+#define NUM_ABS_CTX 5
+
+struct texture_info_contexts {
+ struct bi_context_type_s ipr_contexts[NUM_IPR_CTX];
+ struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX];
+ struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX];
+ struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX];
+ struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX];
+ struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX];
+ struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
+ struct bi_context_type_s fld_last_contexts
+ [NUM_BLOCK_TYPES][NUM_LAST_CTX];
+ struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
+ struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
+};
+struct img_par;
+
+struct syntaxelement {
+ int type;
+ int value1;
+ int value2;
+ int len;
+ int inf;
+ unsigned int bitpattern;
+ int context;
+ int k;
+ int golomb_grad;
+ int golomb_maxlevels;
+#if TRACE
+#define TRACESTRING_SIZE 100
+ char tracestring[TRACESTRING_SIZE];
+#endif
+
+ void (*mapping)(int len, int info, int *value1, int *value2);
+
+ void (*reading)(struct syntaxelement *, struct img_par *,
+ struct decoding_environment_s *);
+
+};
+
+struct bitstream_s {
+
+ int read_len;
+ int code_len;
+
+ int frame_bitoffset;
+ int bitstream_length;
+
+ unsigned char *stream_buffer;
+};
+
+struct datapartition {
+
+ struct bitstream_s *bitstream;
+ struct decoding_environment_s de_aec;
+
+ int (*read_syntax_element)(struct syntaxelement *, struct img_par *,
+ struct datapartition *);
+/*!< virtual function;
+ * actual method depends on chosen data partition and
+ * entropy coding method
+ */
+};
+
+struct slice_s {
+ int picture_id;
+ int qp;
+ int picture_type;
+ int start_mb_nr;
+ int max_part_nr;
+ int num_mb;
+
+ struct datapartition *part_arr;
+ struct motion_info_contexts_s *mot_ctx;
+ struct texture_info_contexts *tex_ctx;
+ int field_ctx[3][2];
+};
+
+struct img_par {
+ int number;
+ int current_mb_nr;
+ int max_mb_nr;
+ int current_slice_nr;
+ int tr;
+ int qp;
+ int type;
+
+ int typeb;
+
+ int width;
+ int height;
+ int width_cr;
+ int height_cr;
+ int source_bitdepth;
+ int mb_y;
+ int mb_x;
+ int block_y;
+ int pix_y;
+ int pix_x;
+ int pix_c_y;
+ int block_x;
+ int pix_c_x;
+
+ int ***mv;
+ int mpr[16][16];
+
+ int m7[16][16];
+ int m8[/*2*/4][8][8];
+ int cof[4][/*6*/8][4][4];
+ int cofu[4];
+ int **ipredmode;
+ int quad[256];
+ int cod_counter;
+
+ int ***dfmv;
+ int ***dbmv;
+ int **fw_reffrarr;
+ int **bw_reffrarr;
+
+ int ***mv_frm;
+ int **fw_reffrarr_frm;
+ int **bw_reffrarr_frm;
+ int imgtr_next_p;
+ int imgtr_last_p;
+ int tr_frm;
+ int tr_fld;
+ int imgtr_last_prev_p;
+
+ int no_forward_reference;
+ int seq_header_indicate;
+ int b_discard_flag;
+
+ int ***fw_mv;
+ int ***bw_mv;
+ int subblock_x;
+ int subblock_y;
+
+ int buf_cycle;
+
+ int direct_type;
+
+ int ***mv_top;
+ int ***mv_bot;
+ int **fw_reffrarr_top;
+ int **bw_reffrarr_top;
+ int **fw_reffrarr_bot;
+ int **bw_reffrarr_bot;
+
+ int **ipredmode_top;
+ int **ipredmode_bot;
+ int ***fw_mv_top;
+ int ***fw_mv_bot;
+ int ***bw_mv_top;
+ int ***bw_mv_bot;
+ int ***dfmv_top;
+ int ***dbmv_top;
+ int ***dfmv_bot;
+ int ***dbm_bot;
+
+ int toppoc;
+ int bottompoc;
+ int framepoc;
+ unsigned int frame_num;
+
+ unsigned int pic_distance;
+ int delta_pic_order_cnt_bottom;
+
+ signed int pic_distance_msb;
+ unsigned int prev_pic_distance_lsb;
+ signed int curr_pic_distance_msb;
+ unsigned int this_poc;
+
+ int pic_width_inmbs;
+ int pic_height_inmbs;
+ int pic_size_inmbs;
+
+ int block8_x, block8_y;
+ int structure;
+ int pn;
+ int buf_used;
+ int buf_size;
+ int picture_structure;
+ int advanced_pred_mode_disable;
+ int types;
+ int current_mb_nr_fld;
+
+ int p_field_enhanced;
+ int b_field_enhanced;
+
+ int slice_weighting_flag;
+ int lum_scale[4];
+ int lum_shift[4];
+ int chroma_scale[4];
+ int chroma_shift[4];
+ int mb_weighting_flag;
+ int weighting_prediction;
+ int mpr_weight[16][16];
+ int top_bot;
+ int bframe_number;
+
+ int auto_crop_right;
+ int auto_crop_bottom;
+
+ struct slice_s *current_slice;
+ int is_v_block;
+ int is_intra_block;
+
+ int new_seq_header_flag;
+ int new_sequence_flag;
+ int last_pic_bbv_delay;
+
+ int sequence_end_flag;
+ int is_top_field;
+
+ int abt_flag;
+ int qp_shift;
+
+#ifdef EIGHTH
+int eighth_subpixel_flag;
+int subpixel_precision;
+int unit_length;
+int subpixel_mask;
+
+int max_mvd;
+int min_mvd;
+#endif
+
+};
+
+struct macroblock {
+ int qp;
+ int slice_nr;
+ int delta_quant;
+ struct macroblock *mb_available[3][3];
+ /*!< pointer to neighboring MBs in a 3x3 window of current MB,
+ *which is located at [1][1]
+ * NULL pointer identifies neighboring MBs which are unavailable
+ */
+
+ int mb_type;
+ int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];
+ int cbp, cbp_blk, cbp01;
+ unsigned long cbp_bits;
+
+ int b8mode[4];
+ int b8pdir[4];
+ int mb_type_2;
+ int c_ipred_mode_2;
+ int dct_mode;
+
+ int c_ipred_mode;
+ int lf_disable;
+ int lf_alpha_c0_offset;
+ int lf_beta_offset;
+
+ int CABT[4];
+ int CABP[4];
+ int cbp_4x4[4];
+
+ int skip_flag;
+
+ struct macroblock *mb_available_up;
+ struct macroblock *mb_available_left;
+ unsigned int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d;
+ unsigned int mbavail_a, mbavail_b, mbavail_c, mbavail_d;
+
+};
+
+struct macroblock *mb_data;
+
+struct img_par *img;
+
+struct bitstream_s *curr_stream;
+
+struct datapartition *alloc_partition(int n);
+
+unsigned int vld_mem_start_addr;
+unsigned int vld_mem_end_addr;
+
+int marker_bit;
+
+int progressive_sequence;
+int horizontal_size;
+int vertical_size;
+
+int second_ifield;
+int pre_img_type;
+
+/* slice_header() */
+int slice_vertical_position;
+int slice_vertical_position_extension;
+int fixed_picture_qp;
+int fixed_slice_qp;
+int slice_qp;
+
+/*
+ *************************************************************************
+ * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in
+ the global UsedBits variable
+ * Input:
+ tracestring
+ the string for the trace file
+ bitstream
+ the stream to be read from
+ * Output:
+ * Return: the value of the coded syntax element
+ * Attention:
+ *************************************************************************
+ */
+/*!
+ * definition of AVS syntaxelements
+ * order of elements follow dependencies for picture reconstruction
+ */
+/*!
+ * \brief Assignment of old TYPE partition elements to new
+ * elements
+ *
+ * old element | new elements
+ * TYPE_HEADER | SE_HEADER, SE_PTYPE
+ * TYPE_MBHEADER | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE
+ * TYPE_MVD | SE_MVD
+ * TYPE_CBP | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER
+ * SE_DELTA_QUANT_INTRA
+ * TYPE_COEFF_Y | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA,
+ SE_LUM_DC_INTER, SE_LUM_AC_INTER
+ * TYPE_2x2DC | SE_CHR_DC_INTRA, SE_CHR_DC_INTER
+ * TYPE_COEFF_C | SE_CHR_AC_INTRA, SE_CHR_AC_INTER
+ * TYPE_EOS | SE_EOS
+ */
+
+#define SE_HEADER 0
+#define SE_PTYPE 1
+#define SE_MBTYPE 2
+#define SE_REFFRAME 3
+#define SE_INTRAPREDMODE 4
+#define SE_MVD 5
+#define SE_CBP_INTRA 6
+#define SE_LUM_DC_INTRA 7
+#define SE_CHR_DC_INTRA 8
+#define SE_LUM_AC_INTRA 9
+#define SE_CHR_AC_INTRA 10
+#define SE_CBP_INTER 11
+#define SE_LUM_DC_INTER 12
+#define SE_CHR_DC_INTER 13
+#define SE_LUM_AC_INTER 14
+#define SE_CHR_AC_INTER 15
+#define SE_DELTA_QUANT_INTER 16
+#define SE_DELTA_QUANT_INTRA 17
+#define SE_BFRAME 18
+#define SE_EOS 19
+#define SE_MAX_ELEMENTS 20
+#define SE_CBP01 21
+int chroma_format;
+/*
+ *************************************************************************
+ * Function:Reads bits from the bitstream buffer
+ * Input:
+ byte buffer[]
+ containing VLC-coded data bits
+ int totbitoffset
+ bit offset from start of partition
+ int bytecount
+ total bytes in bitstream
+ int numbits
+ number of bits to read
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+int get_bits(unsigned char buffer[], int totbitoffset, int *info, int bytecount,
+ int numbits)
+{
+ register int inf;
+ long byteoffset;
+ int bitoffset;
+
+ int bitcounter = numbits;
+
+ byteoffset = totbitoffset / 8;
+ bitoffset = 7 - (totbitoffset % 8);
+
+ inf = 0;
+ while (numbits) {
+ inf <<= 1;
+ inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset;
+ numbits--;
+ bitoffset--;
+ if (bitoffset < 0) {
+ byteoffset++;
+ bitoffset += 8;
+ if (byteoffset > bytecount)
+ return -1;
+ }
+ }
+
+ *info = inf;
+
+
+ return bitcounter;
+}
+
+/*
+ *************************************************************************
+ * Function:read FLC codeword from UVLC-partition
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+int read_syntaxelement_flc(struct syntaxelement *sym)
+{
+ int frame_bitoffset = curr_stream->frame_bitoffset;
+ unsigned char *buf = curr_stream->stream_buffer;
+ int bitstreamlengthinbytes = curr_stream->bitstream_length;
+
+ if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
+ sym->len)) < 0)
+ return -1;
+
+ curr_stream->frame_bitoffset += sym->len;
+ sym->value1 = sym->inf;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, sym->inf);
+#endif
+
+ return 1;
+}
+
+/*
+ *************************************************************************
+ * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in
+ the global UsedBits variable
+ * Input:
+ tracestring
+ the string for the trace file
+ bitstream
+ the stream to be read from
+ * Output:
+ * Return: the value of the coded syntax element
+ * Attention:
+ *************************************************************************
+ */
+int u_1(char *tracestring)
+{
+ return u_v(1, tracestring);
+}
+
+/*
+ *************************************************************************
+ * Function:mapping rule for ue(v) syntax elements
+ * Input:length and info
+ * Output:number in the code table
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+void linfo_ue(int len, int info, int *value1, int *dummy)
+{
+ *value1 = (int)pow2(2, (len / 2)) + info - 1;
+}
+
+int u_v(int leninbits, char *tracestring)
+{
+ struct syntaxelement symbol, *sym = &symbol;
+
+#ifdef AVSP_LONG_CABAC
+#else
+ assert(curr_stream->stream_buffer != NULL);
+#endif
+ sym->type = SE_HEADER;
+ sym->mapping = linfo_ue;
+ sym->len = leninbits;
+ read_syntaxelement_flc(sym);
+
+ return sym->inf;
+}
+
+/*
+ *************************************************************************
+ * Function:mapping rule for se(v) syntax elements
+ * Input:length and info
+ * Output:signed mvd
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void linfo_se(int len, int info, int *value1, int *dummy)
+{
+ int n;
+
+ n = (int)pow2(2, (len / 2)) + info - 1;
+ *value1 = (n + 1) / 2;
+ if ((n & 0x01) == 0)
+ *value1 = -*value1;
+
+}
+
+/*
+ *************************************************************************
+ * Function:length and info
+ * Input:
+ * Output:cbp (intra)
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void linfo_cbp_intra(int len, int info, int *cbp, int *dummy)
+{
+}
+
+const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18},
+ {9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12},
+ {7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, {
+ 48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59},
+ {26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23,
+ 24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56,
+ 52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, {
+ 27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47},
+ {42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57,
+ 56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, {
+ 15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22},
+ {34, 32}, {13, 20}, {20, 23}, {0, 2} };
+
+unsigned int s1, t1, value_s, value_t;
+unsigned char dec_bypass, dec_final;
+
+#define get_byte() { \
+ dbuffer = dcodestrm[(*dcodestrm_len)++];\
+ dbits_to_go = 7; \
+}
+
+#define dbuffer (dep->dbuffer)
+#define dbits_to_go (dep->dbits_to_go)
+#define dcodestrm (dep->dcodestrm)
+#define dcodestrm_len (dep->dcodestrm_len)
+
+#define B_BITS 10
+
+#define LG_PMPS_SHIFTNO 2
+
+#define HALF (1 << (B_BITS-1))
+#define QUARTER (1 << (B_BITS-2))
+
+unsigned int biari_decode_symbol(struct decoding_environment_s *dep,
+ struct bi_context_type_s *bi_ct)
+{
+ register unsigned char bit;
+ register unsigned char s_flag;
+ register unsigned char is_lps = 0;
+ register unsigned char cwr;
+ register unsigned char cycno = bi_ct->cycno;
+ register unsigned int lg_pmps = bi_ct->LG_PMPS;
+ register unsigned int t_rlps;
+ register unsigned int s2, t2;
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n",
+ bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct);
+#endif
+
+ bit = bi_ct->MPS;
+
+ cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5;
+
+ if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
+ s2 = s1;
+ t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
+ s_flag = 0;
+ } else {
+ s2 = s1 + 1;
+ t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
+ s_flag = 1;
+ }
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf(" s2 : %d, t2 : %03X\n", s2, t2);
+#endif
+
+ if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
+ is_lps = 1;
+ bit = !bit;
+
+ t_rlps = (s_flag == 0) ?
+ (lg_pmps >> LG_PMPS_SHIFTNO) :
+ (t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
+
+ if (s2 == value_s)
+ value_t = (value_t - t2);
+ else {
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1)
+ | ((dbuffer >> dbits_to_go) & 0x01);
+ value_t = 256 + value_t - t2;
+
+ }
+
+ while (t_rlps < QUARTER) {
+ t_rlps = t_rlps << 1;
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1)
+ | ((dbuffer >> dbits_to_go) & 0x01);
+ }
+
+ s1 = 0;
+ t1 = t_rlps & 0xff;
+
+ value_s = 0;
+ while (value_t < QUARTER) {
+ int j;
+
+ if (--dbits_to_go < 0)
+ get_byte();
+ j = (dbuffer >> dbits_to_go) & 0x01;
+
+ value_t = (value_t << 1) | j;
+ value_s++;
+ }
+ value_t = value_t & 0xff;
+ } else {
+
+ s1 = s2;
+ t1 = t2;
+ }
+
+ if (dec_bypass)
+ return bit;
+
+ if (is_lps)
+ cycno = (cycno <= 2) ? (cycno + 1) : 3;
+ else if (cycno == 0)
+ cycno = 1;
+ bi_ct->cycno = cycno;
+
+ if (is_lps) {
+ switch (cwr) {
+ case 3:
+ lg_pmps = lg_pmps + 197;
+ break;
+ case 4:
+ lg_pmps = lg_pmps + 95;
+ break;
+ default:
+ lg_pmps = lg_pmps + 46;
+ }
+
+ if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) {
+ lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps;
+ bi_ct->MPS = !(bi_ct->MPS);
+ }
+ } else {
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n",
+ lg_pmps - (unsigned int)(lg_pmps>>cwr)
+ - (unsigned int)(lg_pmps>>(cwr+2)),
+ lg_pmps,
+ (unsigned int)(lg_pmps>>cwr),
+ (unsigned int)(lg_pmps>>(cwr+2))
+ );
+#endif
+ lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr)
+ - (unsigned int)(lg_pmps >> (cwr + 2));
+ }
+
+ bi_ct->LG_PMPS = lg_pmps;
+
+ return bit;
+}
+
+unsigned int biari_decode_symbolw(struct decoding_environment_s *dep,
+ struct bi_context_type_s *bi_ct1,
+ struct bi_context_type_s *bi_ct2)
+{
+ register unsigned char bit1, bit2;
+ register unsigned char pred_mps, bit;
+ register unsigned int lg_pmps;
+ register unsigned char cwr1, cycno1 = bi_ct1->cycno;
+ register unsigned char cwr2, cycno2 = bi_ct2->cycno;
+ register unsigned int lg_pmps1 = bi_ct1->LG_PMPS;
+ register unsigned int lg_pmps2 =
+ bi_ct2->LG_PMPS;
+ register unsigned int t_rlps;
+ register unsigned char s_flag, is_lps = 0;
+ register unsigned int s2, t2;
+
+
+ bit1 = bi_ct1->MPS;
+ bit2 = bi_ct2->MPS;
+
+ cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5;
+ cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5;
+
+ if (bit1 == bit2) {
+ pred_mps = bit1;
+ lg_pmps = (lg_pmps1 + lg_pmps2) / 2;
+ } else {
+ if (lg_pmps1 < lg_pmps2) {
+ pred_mps = bit1;
+ lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
+ - ((lg_pmps2 - lg_pmps1) >> 1);
+ } else {
+ pred_mps = bit2;
+ lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
+ - ((lg_pmps1 - lg_pmps2) >> 1);
+ }
+ }
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n",
+ lg_pmps, pred_mps);
+#endif
+ if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
+ s2 = s1;
+ t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
+ s_flag = 0;
+ } else {
+ s2 = s1 + 1;
+ t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
+ s_flag = 1;
+ }
+
+ bit = pred_mps;
+ if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
+ is_lps = 1;
+ bit = !bit;
+ t_rlps = (s_flag == 0) ?
+ (lg_pmps >> LG_PMPS_SHIFTNO) :
+ (t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
+
+ if (s2 == value_s)
+ value_t = (value_t - t2);
+ else {
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1)
+ | ((dbuffer >> dbits_to_go) & 0x01);
+ value_t = 256 + value_t - t2;
+ }
+
+ while (t_rlps < QUARTER) {
+ t_rlps = t_rlps << 1;
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1)
+ | ((dbuffer >> dbits_to_go) & 0x01);
+ }
+ s1 = 0;
+ t1 = t_rlps & 0xff;
+
+ value_s = 0;
+ while (value_t < QUARTER) {
+ int j;
+
+ if (--dbits_to_go < 0)
+ get_byte();
+ j = (dbuffer >> dbits_to_go) & 0x01;
+
+ value_t = (value_t << 1) | j;
+ value_s++;
+ }
+ value_t = value_t & 0xff;
+ } else {
+ s1 = s2;
+ t1 = t2;
+ }
+
+ if (bit != bit1) {
+ cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3;
+ } else {
+ if (cycno1 == 0)
+ cycno1 = 1;
+ }
+
+ if (bit != bit2) {
+ cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3;
+ } else {
+ if (cycno2 == 0)
+ cycno2 = 1;
+ }
+ bi_ct1->cycno = cycno1;
+ bi_ct2->cycno = cycno2;
+
+ {
+
+ if (bit == bit1) {
+ lg_pmps1 =
+ lg_pmps1
+ - (unsigned int)(lg_pmps1
+ >> cwr1)
+ - (unsigned int)(lg_pmps1
+ >> (cwr1
+ + 2));
+ } else {
+ switch (cwr1) {
+ case 3:
+ lg_pmps1 = lg_pmps1 + 197;
+ break;
+ case 4:
+ lg_pmps1 = lg_pmps1 + 95;
+ break;
+ default:
+ lg_pmps1 = lg_pmps1 + 46;
+ }
+
+ if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) {
+ lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1
+ - lg_pmps1;
+ bi_ct1->MPS = !(bi_ct1->MPS);
+ }
+ }
+ bi_ct1->LG_PMPS = lg_pmps1;
+
+ if (bit == bit2) {
+ lg_pmps2 =
+ lg_pmps2
+ - (unsigned int)(lg_pmps2
+ >> cwr2)
+ - (unsigned int)(lg_pmps2
+ >> (cwr2
+ + 2));
+ } else {
+ switch (cwr2) {
+ case 3:
+ lg_pmps2 = lg_pmps2 + 197;
+ break;
+ case 4:
+ lg_pmps2 = lg_pmps2 + 95;
+ break;
+ default:
+ lg_pmps2 = lg_pmps2 + 46;
+ }
+
+ if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) {
+ lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1
+ - lg_pmps2;
+ bi_ct2->MPS = !(bi_ct2->MPS);
+ }
+ }
+ bi_ct2->LG_PMPS = lg_pmps2;
+ }
+
+
+ return bit;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * biari_decode_symbol_eq_prob():
+ * \return
+ * the decoded symbol
+ ************************************************************************
+ */
+unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep)
+{
+ unsigned char bit;
+ struct bi_context_type_s octx;
+ struct bi_context_type_s *ctx = &octx;
+
+ ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
+ ctx->MPS = 0;
+ ctx->cycno = 0xfe;
+ dec_bypass = 1;
+ bit = biari_decode_symbol(dep, ctx);
+ dec_bypass = 0;
+ return bit;
+}
+
+unsigned int biari_decode_final(struct decoding_environment_s *dep)
+{
+ unsigned char bit;
+ struct bi_context_type_s octx;
+ struct bi_context_type_s *ctx = &octx;
+
+ ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO;
+ ctx->MPS = 0;
+ ctx->cycno = 0xff;
+ dec_final = 1;
+ bit = biari_decode_symbol(dep, ctx);
+ dec_final = 0;
+ return bit;
+}
+
+int i_8(char *tracestring)
+{
+ int frame_bitoffset = curr_stream->frame_bitoffset;
+ unsigned char *buf = curr_stream->stream_buffer;
+ int bitstreamlengthinbytes = curr_stream->bitstream_length;
+ struct syntaxelement symbol, *sym = &symbol;
+#ifdef AVSP_LONG_CABAC
+#else
+ assert(curr_stream->stream_buffer != NULL);
+#endif
+
+ sym->len = 8;
+ sym->type = SE_HEADER;
+ sym->mapping = linfo_ue;
+
+ if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
+ sym->len)) < 0)
+ return -1;
+ curr_stream->frame_bitoffset += sym->len;
+ sym->value1 = sym->inf;
+ if (sym->inf & 0x80)
+ sym->inf = -(~((int)0xffffff00 | sym->inf) + 1);
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, sym->inf);
+#endif
+ return sym->inf;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * arideco_bits_read
+ ************************************************************************
+ */
+int arideco_bits_read(struct decoding_environment_s *dep)
+{
+
+ return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * arithmetic decoding
+ ************************************************************************
+ */
+int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img,
+ struct datapartition *this_data_part)
+{
+ int curr_len;
+ struct decoding_environment_s *dep_dp = &(this_data_part->de_aec);
+
+ curr_len = arideco_bits_read(dep_dp);
+
+ se->reading(se, img, dep_dp);
+
+ se->len = (arideco_bits_read(dep_dp) - curr_len);
+ return se->len;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the
+ * run length info of the skip mb
+ ************************************************************************
+ */
+void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ struct bi_context_type_s *pctx;
+ int ctx, symbol;
+
+ pctx = img->current_slice->tex_ctx->one_contexts[0];
+ symbol = 0;
+ ctx = 0;
+ while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
+ symbol += 1;
+ ctx++;
+ if (ctx >= 3)
+ ctx = 3;
+ }
+ se->value1 = symbol;
+#if TRACE
+ fprintf(p_trace, "@%d%s\t\t\t%d\n",
+ symbol_count++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode a pair of
+ * intra prediction modes of a given MB.
+ ************************************************************************
+ */
+int mapd_intrap[5] = {0, 2, 3, 4, 1};
+void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ struct bi_context_type_s *pctx;
+ int ctx, symbol;
+
+ pctx = img->current_slice->tex_ctx->one_contexts[1];
+ symbol = 0;
+ ctx = 0;
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
+#endif
+ while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
+ symbol += 1;
+ ctx++;
+ if (ctx >= 3)
+ ctx = 3;
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & AEC_DUMP)
+ io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
+#endif
+ if (symbol == 4)
+ break;
+ }
+ se->value1 = mapd_intrap[symbol] - 1;
+
+#if TRACE
+ fprintf(p_trace, "@%d %s\t\t\t%d\n",
+ symbol_count++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * decoding of unary binarization using one or 2 distinct
+ * models for the first and all remaining bins; no terminating
+ * "0" for max_symbol
+ ***********************************************************************
+ */
+unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp,
+ struct bi_context_type_s *ctx,
+ int ctx_offset, unsigned int max_symbol)
+{
+ unsigned int l;
+ unsigned int symbol;
+ struct bi_context_type_s *ictx;
+
+ symbol = biari_decode_symbol(dep_dp, ctx);
+
+ if (symbol == 0)
+ return 0;
+
+ if (max_symbol == 1)
+ return symbol;
+ symbol = 0;
+ ictx = ctx + ctx_offset;
+ do {
+ l = biari_decode_symbol(dep_dp, ictx);
+ symbol++;
+ } while ((l != 0) && (symbol < max_symbol - 1));
+ if ((l != 0) && (symbol == max_symbol - 1))
+ symbol++;
+ return symbol;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * decoding of unary binarization using one or 2 distinct
+ * models for the first and all remaining bins
+ ***********************************************************************
+ */
+unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp,
+ struct bi_context_type_s *ctx, int ctx_offset)
+{
+ unsigned int l;
+ unsigned int symbol;
+ struct bi_context_type_s *ictx;
+
+ symbol = 1 - biari_decode_symbol(dep_dp, ctx);
+
+ if (symbol == 0)
+ return 0;
+ symbol = 0;
+ ictx = ctx + ctx_offset;
+ do {
+ l = 1 - biari_decode_symbol(dep_dp, ictx);
+ symbol++;
+ } while (l != 0);
+ return symbol;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the chroma
+ * intra prediction mode of a given MB.
+ ************************************************************************
+ */
+void read_cipredmode_aec(struct syntaxelement *se,
+ struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
+ struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
+ int act_ctx, a, b;
+ int act_sym = se->value1;
+
+ if (curr_mb->mb_available_up == NULL)
+ b = 0;
+ else {
+ /*if ( (curr_mb->mb_available_up)->mb_type==IPCM)
+ * b=0;
+ * else
+ */
+ b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
+ }
+
+ if (curr_mb->mb_available_left == NULL)
+ a = 0;
+ else {
+ /* if ( (curr_mb->mb_available_left)->mb_type==IPCM)
+ * a=0;
+ * else
+ */
+ a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
+ }
+
+ act_ctx = a + b;
+
+
+ act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx);
+
+ if (act_sym != 0)
+ act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3,
+ 0, 2) + 1;
+
+ se->value1 = act_sym;
+
+#if TRACE
+ fprintf(p_trace, "@%d %s\t\t%d\n",
+ symbol_count++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+
+}
+
+int slice_header(char *buf, int startcodepos, int length)
+{
+ int i;
+
+ int weight_para_num = 0;
+ int mb_row;
+ int mb_column;
+ int mb_index;
+ int mb_width, mb_height;
+
+ mb_column = 0;
+
+ memcpy(curr_stream->stream_buffer, buf, length);
+ curr_stream->code_len = curr_stream->bitstream_length = length;
+
+ curr_stream->read_len =
+ curr_stream->frame_bitoffset = (startcodepos) * 8;
+ slice_vertical_position = u_v(8, "slice vertical position");
+
+ push_es(slice_vertical_position, 8);
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & SLICE_INFO_DUMP)
+ io_printf(" * 8-bits slice_vertical_position : %d\n",
+ slice_vertical_position);
+#endif
+
+ if (vertical_size > 2800) {
+ slice_vertical_position_extension = u_v(3,
+ "slice vertical position extension");
+ push_es(slice_vertical_position_extension, 3);
+
+ }
+
+ if (vertical_size > 2800)
+ mb_row = (slice_vertical_position_extension << 7)
+ + slice_vertical_position;
+ else
+ mb_row = slice_vertical_position;
+
+ mb_width = (horizontal_size + 15) / 16;
+ if (!progressive_sequence)
+ mb_height = 2 * ((vertical_size + 31) / 32);
+ else
+ mb_height = (vertical_size + 15) / 16;
+
+
+ mb_index = mb_row * mb_width + mb_column;
+
+ if (!img->picture_structure && img->type == I_IMG
+ && (mb_index >= mb_width * mb_height / 2)) {
+ second_ifield = 1;
+ img->type = P_IMG;
+ pre_img_type = P_IMG;
+ }
+
+ {
+ if (!fixed_picture_qp) {
+ fixed_slice_qp = u_v(1, "fixed_slice_qp");
+ push_es(fixed_slice_qp, 1);
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & SLICE_INFO_DUMP)
+ io_printf(" * 1-bit fixed_slice_qp : %d\n",
+ fixed_slice_qp);
+#endif
+ slice_qp = u_v(6, "slice_qp");
+ push_es(slice_qp, 6);
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & SLICE_INFO_DUMP)
+ io_printf(" * 6-bits slice_qp : %d\n",
+ slice_qp);
+#endif
+
+ img->qp = slice_qp;
+ }
+
+ if (img->type != I_IMG) {
+ img->slice_weighting_flag = u_v(1,
+ "slice weighting flag");
+
+ if (img->slice_weighting_flag) {
+
+ if (second_ifield && !img->picture_structure)
+ weight_para_num = 1;
+ else if (img->type == P_IMG
+ && img->picture_structure)
+ weight_para_num = 2;
+ else if (img->type == P_IMG
+ && !img->picture_structure)
+ weight_para_num = 4;
+ else if (img->type == B_IMG
+ && img->picture_structure)
+ weight_para_num = 2;
+ else if (img->type == B_IMG
+ && !img->picture_structure)
+ weight_para_num = 4;
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & SLICE_INFO_DUMP)
+ io_printf(" - weight_para_num : %d\n",
+ weight_para_num);
+#endif
+ for (i = 0; i < weight_para_num; i++) {
+ img->lum_scale[i] = u_v(8,
+ "luma scale");
+
+ img->lum_shift[i] = i_8("luma shift");
+
+ marker_bit = u_1("insert bit");
+
+
+ {
+ img->chroma_scale[i] = u_v(8,
+ "chroma scale");
+
+ img->chroma_shift[i] = i_8(
+ "chroma shift");
+
+ marker_bit = u_1("insert bit");
+
+ }
+ }
+ img->mb_weighting_flag = u_v(1,
+ "MB weighting flag");
+
+ }
+ }
+ }
+
+
+#if 1
+ return mb_index;
+#endif
+}
+
+void no_mem_exit(char *where)
+{
+ io_printf("%s\r\n", where);
+}
+
+unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+struct inputstream_s {
+ /*FILE *f;*/
+ unsigned char buf[SVA_STREAM_BUF_SIZE];
+ unsigned int uclear_bits;
+ unsigned int upre_3bytes;
+ int ibyte_position;
+ int ibuf_bytesnum;
+ int iclear_bitsnum;
+ int istuff_bitsnum;
+ int ibits_count;
+};
+
+struct inputstream_s IRABS;
+struct inputstream_s *p_irabs = &IRABS;
+
+struct stat_bits {
+ int curr_frame_bits;
+ int prev_frame_bits;
+ int emulate_bits;
+ int prev_emulate_bits;
+ int last_unit_bits;
+ int bitrate;
+ int total_bitrate[1000];
+ int coded_pic_num;
+ int time_s;
+};
+
+struct stat_bits *stat_bits_ptr;
+
+unsigned char *temp_slice_buf;
+int start_codeposition;
+int first_slice_length;
+int first_slice_startpos;
+
+int bitstream_buf_used;
+int startcode_offset;
+
+int bitstream_read_ptr;
+
+int demulate_enable;
+
+int last_dquant;
+
+int total_mb_count;
+
+int current_mb_skip;
+
+int skip_mode_flag;
+
+int current_mb_intra;
+
+/*
+ *************************************************************************
+ * Function: Check start code's type
+ * Input:
+ * Output:
+ * Return:
+ * Author: XZHENG, 20080515
+ *************************************************************************
+ */
+void check_type(int startcode)
+{
+ startcode = startcode & 0x000000ff;
+ switch (startcode) {
+ case 0xb0:
+ case 0xb2:
+ case 0xb5:
+ demulate_enable = 0;
+ break;
+ default:
+ demulate_enable = 1;
+ break;
+ }
+
+}
+/*
+ *************************************************************************
+ * Function:
+ * Input:
+ * Output:
+ * Return: 0 : OK
+ -1 : arrive at stream end
+ -2 : meet another start code
+ * Attention:
+ *************************************************************************
+ */
+int clear_nextbyte(struct inputstream_s *p)
+{
+ int i, k, j;
+ unsigned char temp[3];
+
+ i = p->ibyte_position;
+ k = p->ibuf_bytesnum - i;
+ if (k < 3) {
+ for (j = 0; j < k; j++)
+ temp[j] = p->buf[i + j];
+
+ p->ibuf_bytesnum = read_bitstream(p->buf + k,
+ SVA_STREAM_BUF_SIZE - k);
+ bitstream_buf_used++;
+ if (p->ibuf_bytesnum == 0) {
+ if (k > 0) {
+ while (k > 0) {
+ p->upre_3bytes = ((p->upre_3bytes << 8)
+ | p->buf[i])
+ & 0x00ffffff;
+ if (p->upre_3bytes < 4
+ && demulate_enable) {
+ p->uclear_bits =
+ (p->uclear_bits
+ << 6)
+ | (p->buf[i]
+ >> 2);
+ p->iclear_bitsnum += 6;
+ stat_bits_ptr->emulate_bits
+ += 2;
+ } else {
+ p->uclear_bits = (p->uclear_bits
+ << 8)
+ | p->buf[i];
+ p->iclear_bitsnum += 8;
+ }
+ p->ibyte_position++;
+ k--;
+ i++;
+ }
+ return 0;
+ } else {
+ return -1;
+ }
+ } else {
+ for (j = 0; j < k; j++)
+ p->buf[j] = temp[j];
+ p->ibuf_bytesnum += k;
+ i = p->ibyte_position = 0;
+ }
+ }
+ if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1)
+ return -2;
+ p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff;
+ if (p->upre_3bytes < 4 && demulate_enable) {
+ p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2);
+ p->iclear_bitsnum += 6;
+ stat_bits_ptr->emulate_bits += 2;
+ } else {
+ p->uclear_bits = (p->uclear_bits << 8) | p->buf[i];
+ p->iclear_bitsnum += 8;
+ }
+ p->ibyte_position++;
+ return 0;
+}
+
+/*
+ *************************************************************************
+ * Function:
+ * Input:
+ * Output:
+ * Return: 0 : OK
+ -1 : arrive at stream end
+ -2 : meet another start code
+ * Attention:
+ *************************************************************************
+ */
+int read_n_bit(struct inputstream_s *p, int n, int *v)
+{
+ int r;
+ unsigned int t;
+
+ while (n > p->iclear_bitsnum) {
+ r = clear_nextbyte(p);
+ if (r) {
+ if (r == -1) {
+ if (p->ibuf_bytesnum - p->ibyte_position > 0)
+ break;
+ }
+ return r;
+ }
+ }
+ t = p->uclear_bits;
+ r = 32 - p->iclear_bitsnum;
+ *v = (t << r) >> (32 - n);
+ p->iclear_bitsnum -= n;
+ return 0;
+}
+
+#ifdef AVSP_LONG_CABAC
+unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE];
+int tmp_buf_wr_ptr;
+int tmp_buf_rd_ptr;
+int tmp_buf_count;
+#endif
+void open_irabs(struct inputstream_s *p)
+{
+ p->uclear_bits = 0xffffffff;
+ p->ibyte_position = 0;
+ p->ibuf_bytesnum = 0;
+ p->iclear_bitsnum = 0;
+ p->istuff_bitsnum = 0;
+ p->ibits_count = 0;
+ p->upre_3bytes = 0;
+
+ bitstream_buf_used = 0;
+ bitstream_read_ptr = (src_start - 16) & 0xfffffff0;
+
+#ifdef AVSP_LONG_CABAC
+ tmp_buf_count = 0;
+ tmp_buf_wr_ptr = 0;
+ tmp_buf_rd_ptr = 0;
+#endif
+
+}
+
+void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr,
+ int move_size)
+{
+ int move_bytes_left = move_size;
+ unsigned int move_read_addr;
+ unsigned int move_write_addr = move_to_addr;
+
+ int move_byte;
+ unsigned int data32;
+
+ while (move_from_addr > vld_mem_end_addr) {
+ move_from_addr = move_from_addr + vld_mem_start_addr
+ - vld_mem_end_addr - 8;
+ }
+ move_read_addr = move_from_addr;
+ while (move_bytes_left > 0) {
+ move_byte = move_bytes_left;
+ if (move_byte > 512)
+ move_byte = 512;
+ if ((move_read_addr + move_byte) > vld_mem_end_addr)
+ move_byte = (vld_mem_end_addr + 8) - move_read_addr;
+
+ WRITE_VREG(LMEM_DMA_ADR, move_read_addr);
+ WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
+ WRITE_VREG(LMEM_DMA_CTRL, 0xc200);
+
+ data32 = 0x8000;
+ while (data32 & 0x8000)
+ data32 = READ_VREG(LMEM_DMA_CTRL);
+
+ WRITE_VREG(LMEM_DMA_ADR, move_write_addr);
+ WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
+ WRITE_VREG(LMEM_DMA_CTRL, 0x8200);
+
+ data32 = 0x8000;
+ while (data32 & 0x8000)
+ data32 = READ_VREG(LMEM_DMA_CTRL);
+
+ data32 = 0x0fff;
+ while (data32 & 0x0fff)
+ data32 = READ_VREG(WRRSP_LMEM);
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & STREAM_INFO_DUMP)
+ io_printf(" 2 MOVE %d Bytes from 0x%x to 0x%x\n",
+ move_byte, move_read_addr, move_write_addr);
+#endif
+
+ move_read_addr = move_read_addr + move_byte;
+ if (move_read_addr > vld_mem_end_addr)
+ move_read_addr = vld_mem_start_addr;
+ move_write_addr = move_write_addr + move_byte;
+ move_bytes_left = move_bytes_left - move_byte;
+ }
+
+}
+
+int read_bitstream(unsigned char *buf, int size)
+{
+ int i;
+
+#ifdef AVSP_LONG_CABAC
+
+ unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp;
+
+ if (tmp_buf_count < size) {
+ dma_sync_single_for_cpu(amports_get_dma_device(),
+ bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
+ move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy,
+ SVA_STREAM_BUF_SIZE);
+
+ for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) {
+ TMP_BUF[tmp_buf_wr_ptr++] =
+ (TMP_BUF_32[2 * i + 1] >> 24) & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] =
+ (TMP_BUF_32[2 * i + 1] >> 16) & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8)
+ & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0)
+ & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] =
+ (TMP_BUF_32[2 * i + 0] >> 24) & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] =
+ (TMP_BUF_32[2 * i + 0] >> 16) & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8)
+ & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0)
+ & 0xff;
+ if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_wr_ptr = 0;
+ }
+ tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE;
+ bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE;
+ }
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & STREAM_INFO_DUMP)
+ io_printf(" Read %d bytes from %d, size left : %d\n",
+ size, tmp_buf_rd_ptr, tmp_buf_count);
+#endif
+ for (i = 0; i < size; i++) {
+ buf[i] = TMP_BUF[tmp_buf_rd_ptr++];
+ if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE))
+ tmp_buf_rd_ptr = 0;
+ }
+ tmp_buf_count = tmp_buf_count - size;
+
+#else
+ for (i = 0; i < size; i++)
+ buf[i] = tmp_stream[bitstream_read_ptr + i];
+ bitstream_read_ptr = bitstream_read_ptr + size;
+#endif
+
+ return size;
+}
+
+int next_startcode(struct inputstream_s *p)
+{
+ int i, m;
+ unsigned char a = 0, b = 0;
+
+ m = 0;
+
+ while (1) {
+ if (p->ibyte_position >= p->ibuf_bytesnum - 2) {
+ m = p->ibuf_bytesnum - p->ibyte_position;
+ if (m < 0)
+ return -2;
+ if (m == 1)
+ b = p->buf[p->ibyte_position + 1];
+ if (m == 2) {
+ b = p->buf[p->ibyte_position + 1];
+ a = p->buf[p->ibyte_position];
+ }
+ p->ibuf_bytesnum = read_bitstream(p->buf,
+ SVA_STREAM_BUF_SIZE);
+ p->ibyte_position = 0;
+ bitstream_buf_used++;
+ }
+
+ if (p->ibuf_bytesnum + m < 3)
+ return -1;
+
+ if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
+ p->ibyte_position = 2;
+ p->iclear_bitsnum = 0;
+ p->istuff_bitsnum = 0;
+ p->ibits_count += 24;
+ p->upre_3bytes = 1;
+ return 0;
+ }
+
+ if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) {
+ p->ibyte_position = 1;
+ p->iclear_bitsnum = 0;
+ p->istuff_bitsnum = 0;
+ p->ibits_count += 24;
+ p->upre_3bytes = 1;
+ return 0;
+ }
+
+ if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
+ p->ibyte_position = 2;
+ p->iclear_bitsnum = 0;
+ p->istuff_bitsnum = 0;
+ p->ibits_count += 24;
+ p->upre_3bytes = 1;
+ return 0;
+ }
+
+ for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) {
+ if (p->buf[i] == 0 && p->buf[i + 1] == 0
+ && p->buf[i + 2] == 1) {
+ p->ibyte_position = i + 3;
+ p->iclear_bitsnum = 0;
+ p->istuff_bitsnum = 0;
+ p->ibits_count += 24;
+ p->upre_3bytes = 1;
+ return 0;
+ }
+ p->ibits_count += 8;
+ }
+ p->ibyte_position = i;
+ }
+}
+
+int get_oneunit(char *buf, int *startcodepos, int *length)
+{
+ int i, j, k;
+
+ i = next_startcode(p_irabs);
+
+ if (i != 0) {
+ if (i == -1)
+ io_printf(
+ "\narrive at stream end and start code is not found!");
+ if (i == -2)
+ io_printf("\np->ibyte_position error!");
+
+ }
+ startcode_offset =
+ p_irabs->ibyte_position
+ - 3 + (bitstream_buf_used-1)
+ * SVA_STREAM_BUF_SIZE;
+ buf[0] = 0;
+ buf[1] = 0;
+ buf[2] = 1;
+ *startcodepos = 3;
+ i = read_n_bit(p_irabs, 8, &j);
+ buf[3] = (char)j;
+
+ check_type(buf[3]);
+ if (buf[3] == SEQUENCE_END_CODE) {
+ *length = 4;
+ return -1;
+ }
+ k = 4;
+ while (1) {
+ i = read_n_bit(p_irabs, 8, &j);
+ if (i < 0)
+ break;
+ buf[k++] = (char)j;
+ if (k >= (MAX_CODED_FRAME_SIZE - 1))
+ break;
+ }
+ if (p_irabs->iclear_bitsnum > 0) {
+ int shift;
+
+ shift = 8 - p_irabs->iclear_bitsnum;
+ i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j);
+
+ if (j != 0)
+ buf[k++] = (char)(j << shift);
+ stat_bits_ptr->last_unit_bits += shift;
+ }
+ *length = k;
+ return k;
+}
+
+/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/
+/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/
+int header(void)
+{
+ unsigned char *buf;
+ int startcodepos, length;
+
+ unsigned char *tmp_buf;
+
+ tmp_buf = (unsigned char *)avsp_heap_adr;
+
+ buf = &tmp_buf[0];
+ while (1) {
+ start_codeposition = get_oneunit(buf, &startcodepos, &length);
+
+ switch (buf[startcodepos]) {
+ case SEQUENCE_HEADER_CODE:
+ io_printf(
+ "# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case EXTENSION_START_CODE:
+ io_printf(
+ "# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case USER_DATA_START_CODE:
+ io_printf(
+ "# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case VIDEO_EDIT_CODE:
+ io_printf(
+ "# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case I_PICTURE_START_CODE:
+ io_printf(
+ "# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case PB_PICTURE_START_CODE:
+ io_printf(
+ "# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ case SEQUENCE_END_CODE:
+ io_printf(
+ "# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+ break;
+ default:
+ io_printf(
+ "# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
+ buf[startcodepos], startcode_offset,
+ startcode_offset);
+#if 0
+ io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_START_PTR));
+ io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
+ io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_END_PTR));
+ io_printf("VLD_MEM_VIFIFO_WP %x\r\n"
+ READ_VREG(VLD_MEM_VIFIFO_WP));
+ io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_RP));
+ io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n"
+ READ_VREG(VLD_MEM_VBUF_RD_PTR));
+ io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
+ io_printf("PARSER_VIDEO_HOLE %x\r\n",
+ READ_MPEG_REG(PARSER_VIDEO_HOLE));
+#endif
+ if ((buf[startcodepos] >= SLICE_START_CODE_MIN
+ && buf[startcodepos]
+ <= SLICE_START_CODE_MAX)
+ && ((!img->seq_header_indicate)
+ || (img->type == B_IMG
+ && img->b_discard_flag
+ == 1
+ && !img->no_forward_reference))) {
+ break;
+ } else if (buf[startcodepos] >= SLICE_START_CODE_MIN) {
+
+ first_slice_length = length;
+ first_slice_startpos = startcodepos;
+
+ temp_slice_buf = &tmp_buf[0];
+ return SOP;
+ } else {
+ io_printf("Can't find start code");
+ return -EOS;
+ }
+ }
+ }
+
+}
+
+/*
+ *************************************************************************
+ * Function:Allocates a Bitstream
+ * Input:
+ * Output:allocated Bitstream point
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+struct bitstream_s *alloc_bitstream(void)
+{
+ struct bitstream_s *bitstream;
+
+ bitstream = (struct bitstream_s *)local_alloc(1,
+ sizeof(struct bitstream_s));
+ if (bitstream == NULL) {
+ io_printf(
+ "AllocBitstream: Memory allocation for Bitstream failed");
+ return NULL;
+ }
+ bitstream->stream_buffer = (unsigned char *)local_alloc(
+ MAX_CODED_FRAME_SIZE,
+ sizeof(unsigned char));
+ if (bitstream->stream_buffer == NULL) {
+ io_printf(
+ "AllocBitstream: Memory allocation for streamBuffer failed");
+ return NULL;
+ }
+
+ return bitstream;
+}
+
+void biari_init_context_logac(struct bi_context_type_s *ctx)
+{
+ ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
+ ctx->MPS = 0;
+ ctx->cycno = 0;
+}
+
+#define BIARI_CTX_INIT1_LOG(jj, ctx)\
+{\
+ for (j = 0; j < jj; j++)\
+ biari_init_context_logac(&(ctx[j]));\
+}
+
+#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\
+{\
+ for (i = 0; i < ii; i++)\
+ for (j = 0; j < jj; j++)\
+ biari_init_context_logac(&(ctx[i][j]));\
+}
+
+#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\
+{\
+ for (i = 0; i < ii; i++)\
+ for (j = 0; j < jj; j++)\
+ for (k = 0; k < kk; k++)\
+ biari_init_context_logac(&(ctx[i][j][k]));\
+}
+
+#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\
+{\
+ for (i = 0; i < ii; i++)\
+ for (j = 0; j < jj; j++)\
+ for (k = 0; k < kk; k++)\
+ for (l = 0; l < ll; l++)\
+ biari_init_context_logac\
+ (&(ctx[i][j][k][l]));\
+}
+
+void init_contexts(struct img_par *img)
+{
+ struct motion_info_contexts_s *mc = img->current_slice->mot_ctx;
+ struct texture_info_contexts *tc = img->current_slice->tex_ctx;
+ int i, j;
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & SLICE_INFO_DUMP)
+ io_printf(" ---- init_contexts ----\n");
+#endif
+
+ BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts);
+ BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts);
+ BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts);
+ BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts);
+ BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts);
+ BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts);
+
+ BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts);
+ BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts);
+ BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX,
+ tc->fld_last_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts);
+ BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts);
+#ifdef TEST_WEIGHTING_AEC
+ biari_init_context_logac(&mc->mb_weighting_pred);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocation of contexts models for the motion info
+ * used for arithmetic decoding
+ *
+ ************************************************************************
+ */
+struct motion_info_contexts_s *create_contexts_motioninfo(void)
+{
+ struct motion_info_contexts_s *deco_ctx;
+
+ deco_ctx = (struct motion_info_contexts_s *)local_alloc(1,
+ sizeof(struct motion_info_contexts_s));
+ if (deco_ctx == NULL)
+ no_mem_exit("create_contexts_motioninfo: deco_ctx");
+
+ return deco_ctx;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates of contexts models for the texture info
+ * used for arithmetic decoding
+ ************************************************************************
+ */
+struct texture_info_contexts *create_contexts_textureinfo(void)
+{
+ struct texture_info_contexts *deco_ctx;
+
+ deco_ctx = (struct texture_info_contexts *)local_alloc(1,
+ sizeof(struct texture_info_contexts));
+ if (deco_ctx == NULL)
+ no_mem_exit("create_contexts_textureinfo: deco_ctx");
+
+ return deco_ctx;
+}
+
+struct datapartition *alloc_partition(int n)
+{
+ struct datapartition *part_arr, *datapart;
+ int i;
+
+ part_arr =
+ (struct datapartition *)local_alloc(n, sizeof(struct datapartition));
+ if (part_arr == NULL) {
+ no_mem_exit(
+ "alloc_partition: Memory allocation for Data Partition failed");
+ return NULL;
+ }
+
+#if LIWR_FIX
+ part_arr[0].bitstream = NULL;
+#else
+ for (i = 0; i < n; i++) {
+ datapart = &(part_arr[i]);
+ datapart->bitstream = (struct bitstream_s *)local_alloc(1,
+ sizeof(struct bitstream_s));
+ if (datapart->bitstream == NULL) {
+ no_mem_exit(
+ "alloc_partition: Memory allocation for Bitstream failed");
+ return NULL;
+ }
+ }
+#endif
+ return part_arr;
+}
+
+int malloc_slice(struct img_par *img)
+{
+ struct slice_s *currslice;
+
+ img->current_slice =
+ (struct slice_s *)local_alloc(1, sizeof(struct slice_s));
+ currslice = img->current_slice;
+ if (currslice == NULL) {
+ no_mem_exit(
+ "Memory allocation for struct slice_s datastruct Failed"
+ );
+ return 0;
+ }
+ if (1) {
+
+ currslice->mot_ctx = create_contexts_motioninfo();
+ if (currslice->mot_ctx == NULL)
+ return 0;
+
+ currslice->tex_ctx = create_contexts_textureinfo();
+ if (currslice->tex_ctx == NULL)
+ return 0;
+ }
+#if LIWR_FIX
+ currslice->max_part_nr = 1;
+#else
+ currslice->max_part_nr = 3;
+#endif
+ currslice->part_arr = alloc_partition(currslice->max_part_nr);
+ if (currslice->part_arr == NULL)
+ return 0;
+ return 1;
+}
+
+void init(struct img_par *img)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ img->quad[i] = i * i;
+}
+
+/*
+ *************************************************************************
+ * Function:Allocate 2D memory array -> int array2D[rows][columns]
+ * Input:
+ * Output: memory size in bytes
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+int get_mem2Dint(int ***array2D, int rows, int columns)
+{
+ int i;
+
+ *array2D = (int **)local_alloc(rows, sizeof(int *));
+ if (*array2D == NULL) {
+ no_mem_exit("get_mem2Dint: array2D");
+ return -1;
+ }
+ (*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int));
+ if ((*array2D)[0] == NULL) {
+ no_mem_exit("get_mem2Dint: array2D");
+ return -1;
+ }
+
+ for (i = 1; i < rows; i++)
+ (*array2D)[i] = (*array2D)[i - 1] + columns;
+
+ return rows * columns * sizeof(int);
+}
+
+int initial_decode(void)
+{
+ int i, j;
+ int ret;
+ int img_height = (vertical_size + img->auto_crop_bottom);
+ int memory_size = 0;
+
+ ret = malloc_slice(img);
+ if (ret == 0)
+ return 0;
+
+ mb_data = (struct macroblock *)local_alloc(
+ (img->width / MB_BLOCK_SIZE)
+ * (img_height /*vertical_size*/
+ / MB_BLOCK_SIZE), sizeof(struct macroblock));
+ if (mb_data == NULL) {
+ no_mem_exit("init_global_buffers: mb_data");
+ return 0;
+ }
+
+ if (progressive_sequence) {
+ int size;
+ size = get_mem2Dint(&(img->ipredmode),
+ img->width / B8_SIZE * 2 + 4,
+ vertical_size / B8_SIZE * 2 + 4);
+ if (size == -1)
+ return 0;
+
+ memory_size += size;
+ } else {
+ int size;
+ size = get_mem2Dint(&(img->ipredmode),
+ img->width / B8_SIZE * 2 + 4,
+ (vertical_size + 32) / (2 * B8_SIZE) * 4 + 4);
+ if (size == -1)
+ return 0;
+
+ memory_size += size;
+ }
+
+ for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) {
+ for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++)
+ img->ipredmode[i][j] = -1;
+ }
+
+ init(img);
+ img->number = 0;
+ img->type = I_IMG;
+ img->imgtr_last_p = 0;
+ img->imgtr_next_p = 0;
+
+ img->new_seq_header_flag = 1;
+ img->new_sequence_flag = 1;
+
+ return 1;
+}
+
+void aec_new_slice(void)
+{
+ last_dquant = 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initializes the DecodingEnvironment for the arithmetic coder
+ ************************************************************************
+ */
+
+void arideco_start_decoding(struct decoding_environment_s *dep,
+ unsigned char *cpixcode,
+ int firstbyte, int *cpixcode_len, int slice_type)
+{
+
+ dcodestrm = cpixcode;
+ dcodestrm_len = cpixcode_len;
+ *dcodestrm_len = firstbyte;
+
+ s1 = 0;
+ t1 = QUARTER - 1;
+ value_s = 0;
+
+ value_t = 0;
+
+ {
+ int i;
+
+ dbits_to_go = 0;
+ for (i = 0; i < B_BITS - 1; i++) {
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1)
+ | ((dbuffer >> dbits_to_go) & 0x01);
+ }
+ }
+
+ while (value_t < QUARTER) {
+ if (--dbits_to_go < 0)
+ get_byte();
+
+ value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01);
+ value_s++;
+ }
+ value_t = value_t & 0xff;
+
+ dec_final = dec_bypass = 0;
+
+
+
+}
+
+/*
+ *************************************************************************
+ * Function:Checks the availability of neighboring macroblocks of
+ the current macroblock for prediction and context determination;
+ marks the unavailable MBs for intra prediction in the
+ ipredmode-array by -1. Only neighboring MBs in the causal
+ past of the current MB are checked.
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void checkavailabilityofneighbors(struct img_par *img)
+{
+ int i, j;
+ const int mb_width = img->width / MB_BLOCK_SIZE;
+ const int mb_nr = img->current_mb_nr;
+ struct macroblock *curr_mb = &mb_data[mb_nr];
+ int check_value;
+ int remove_prediction;
+
+ curr_mb->mb_available_up = NULL;
+ curr_mb->mb_available_left = NULL;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ mb_data[mb_nr].mb_available[i][j] = NULL;
+
+ mb_data[mb_nr].mb_available[1][1] = curr_mb;
+
+ if (img->pix_x >= MB_BLOCK_SIZE) {
+ remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - 1].slice_nr;
+
+ if (remove_prediction)
+
+ {
+
+ img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
+ + 1) * 2] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
+ + 1) * 2 + 1] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
+ + 2) * 2] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
+ + 2) * 2 + 1] = -1;
+ }
+ if (!remove_prediction)
+ curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
+
+ }
+
+ check_value = (img->pix_y >= MB_BLOCK_SIZE);
+ if (check_value) {
+ remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - mb_width].slice_nr;
+
+ if (remove_prediction) {
+ img->ipredmode
+ [(img->block_x + 1) * 2][(img->block_y + 1)
+ * 2 - 1] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y
+ + 1) * 2 - 1] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y
+ + 1) * 2 - 1] = -1;
+ img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y
+ + 1) * 2 - 1] = -1;
+ }
+
+ if (!remove_prediction) {
+ curr_mb->mb_available[0][1] =
+ &(mb_data[mb_nr - mb_width]);
+ }
+ }
+
+ if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
+ remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - mb_width - 1].slice_nr;
+
+ if (remove_prediction) {
+ img->ipredmode[img->block_x * 2 + 1][img->block_y * 2
+ + 1] = -1;
+ }
+ if (!remove_prediction) {
+ curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
+ - 1]);
+ }
+ }
+
+ if (img->pix_y >= MB_BLOCK_SIZE
+ && img->pix_x < (img->width - MB_BLOCK_SIZE)) {
+ if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
+ curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
+ + 1]);
+ }
+
+ if (1) {
+ curr_mb->mbaddr_a = mb_nr - 1;
+ curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
+ curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
+ curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
+
+ curr_mb->mbavail_a =
+ (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
+ curr_mb->mbavail_b =
+ (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
+ curr_mb->mbavail_c =
+ (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
+ curr_mb->mbavail_d =
+ (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
+
+ }
+
+}
+
+void checkavailabilityofneighborsaec(void)
+{
+
+ int i, j;
+ const int mb_width = img->width / MB_BLOCK_SIZE;
+ const int mb_nr = img->current_mb_nr;
+ struct macroblock *curr_mb = &(mb_data[mb_nr]);
+ int check_value;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ mb_data[mb_nr].mb_available[i][j] = NULL;
+ mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]);
+
+ if (img->pix_x >= MB_BLOCK_SIZE) {
+ int remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - 1].slice_nr;
+ if (!remove_prediction)
+ curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
+ }
+
+ check_value = (img->pix_y >= MB_BLOCK_SIZE);
+ if (check_value) {
+ int remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - mb_width].slice_nr;
+
+ if (!remove_prediction) {
+ curr_mb->mb_available[0][1] =
+ &(mb_data[mb_nr - mb_width]);
+ }
+ }
+
+ if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
+ int remove_prediction = curr_mb->slice_nr
+ != mb_data[mb_nr - mb_width - 1].slice_nr;
+ if (!remove_prediction) {
+ curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
+ - 1]);
+ }
+ }
+
+ if (img->pix_y >= MB_BLOCK_SIZE
+ && img->pix_x < (img->width - MB_BLOCK_SIZE)) {
+ if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
+ curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
+ + 1]);
+ }
+ curr_mb->mb_available_left = curr_mb->mb_available[1][0];
+ curr_mb->mb_available_up = curr_mb->mb_available[0][1];
+ curr_mb->mbaddr_a = mb_nr - 1;
+ curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
+ curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
+ curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
+
+ curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
+ curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
+ curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
+ curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
+}
+
+/*
+ *************************************************************************
+ * Function:initializes the current macroblock
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void start_macroblock(struct img_par *img)
+{
+ int i, j, k, l;
+ struct macroblock *curr_mb;
+
+#ifdef AVSP_LONG_CABAC
+#else
+
+#endif
+
+ curr_mb = &mb_data[img->current_mb_nr];
+
+ /* Update coordinates of the current macroblock */
+ img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE);
+ img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE);
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_NUM_DUMP)
+ io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n",
+ img->current_mb_nr, img->mb_x, img->mb_y, es_ptr);
+#endif
+
+
+ total_mb_count = total_mb_count + 1;
+
+ /* Define vertical positions */
+ img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */
+ img->block8_y = img->mb_y * BLOCK_SIZE / 2;
+ img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
+ if (chroma_format == 2)
+ img->pix_c_y = img->mb_y *
+ MB_BLOCK_SIZE; /* chroma macroblock position */
+ else
+ img->pix_c_y = img->mb_y *
+ MB_BLOCK_SIZE / 2; /* chroma macroblock position */
+
+ /* Define horizontal positions */
+ img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */
+ img->block8_x = img->mb_x * BLOCK_SIZE / 2;
+ img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
+ img->pix_c_x = img->mb_x *
+ MB_BLOCK_SIZE / 2; /* chroma pixel position */
+
+ checkavailabilityofneighbors(img);
+
+ /*<!*******EDIT START BY lzhang ******************/
+
+ if (1)
+ checkavailabilityofneighborsaec();
+ /*<!*******EDIT end BY lzhang ******************/
+
+ curr_mb->qp = img->qp;
+ curr_mb->mb_type = 0;
+ curr_mb->delta_quant = 0;
+ curr_mb->cbp = 0;
+ curr_mb->cbp_blk = 0;
+ curr_mb->c_ipred_mode = DC_PRED_8;
+ curr_mb->c_ipred_mode_2 = DC_PRED_8;
+
+ for (l = 0; l < 2; l++)
+ for (j = 0; j < BLOCK_MULTIPLE; j++)
+ for (i = 0; i < BLOCK_MULTIPLE; i++)
+ for (k = 0; k < 2; k++)
+ curr_mb->mvd[l][j][i][k] = 0;
+
+ curr_mb->cbp_bits = 0;
+
+ for (j = 0; j < MB_BLOCK_SIZE; j++)
+ for (i = 0; i < MB_BLOCK_SIZE; i++)
+ img->m7[i][j] = 0;
+
+ for (j = 0; j < 2 * BLOCK_SIZE; j++)
+ for (i = 0; i < 2 * BLOCK_SIZE; i++) {
+ img->m8[0][i][j] = 0;
+ img->m8[1][i][j] = 0;
+ img->m8[2][i][j] = 0;
+ img->m8[3][i][j] = 0;
+ }
+
+ curr_mb->lf_disable = 1;
+
+ img->weighting_prediction = 0;
+}
+
+/*
+ *************************************************************************
+ * Function:init macroblock I and P frames
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void init_macroblock(struct img_par *img)
+{
+ int i, j;
+
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ img->ipredmode[img->block_x * 2 + i + 2][img->block_y
+ * 2 + j + 2] = -1;
+ }
+ }
+
+}
+
+/*
+ *************************************************************************
+ * Function:Interpret the mb mode for I-Frames
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void interpret_mb_mode_i(struct img_par *img)
+{
+ int i;
+
+ struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
+ int num = 4;
+
+ curr_mb->mb_type = I8MB;
+
+
+ current_mb_intra = 1;
+
+ for (i = 0; i < 4; i++) {
+ curr_mb->b8mode[i] = IBLOCK;
+ curr_mb->b8pdir[i] = -1;
+ }
+
+ for (i = num; i < 4; i++) {
+ curr_mb->b8mode[i] =
+ curr_mb->mb_type_2 == P8x8 ?
+ 4 : curr_mb->mb_type_2;
+ curr_mb->b8pdir[i] = 0;
+ }
+}
+
+const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1,
+ 1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3},
+ {0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0,
+ 0, 0, 0, 0, 6, 0, 0},
+ {0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8}
+
+};
+
+const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0
+
+};
+
+const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4};
+
+void read_ipred_block_modes(struct img_par *img, int b8)
+{
+ int bi, bj, dec;
+ struct syntaxelement curr_se;
+ struct macroblock *curr_mb;
+ int j2;
+ int mostprobableintrapredmode;
+ int upintrapredmode;
+ int uprightintrapredmode;
+ int leftintrapredmode;
+ int leftdownintrapredmode;
+ int intrachromapredmodeflag;
+
+ struct slice_s *currslice = img->current_slice;
+ struct datapartition *dp;
+
+ curr_mb = mb_data + img->current_mb_nr;
+ intrachromapredmodeflag = IS_INTRA(curr_mb);
+
+ curr_se.type = SE_INTRAPREDMODE;
+#if TRACE
+ strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE);
+#endif
+
+ if (b8 < 4) {
+ if (curr_mb->b8mode[b8] == IBLOCK) {
+ intrachromapredmodeflag = 1;
+
+ if (1) {
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading = read_intrapredmode_aec;
+ dp->read_syntax_element(&curr_se, img, dp);
+
+ if (curr_se.value1 == -1)
+ push_es(1, 1);
+ else
+ push_es(curr_se.value1, 3);
+
+
+ }
+ bi = img->block_x + (b8 & 1);
+ bj = img->block_y + (b8 / 2);
+
+ upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2
+ + 1];
+ uprightintrapredmode =
+ img->ipredmode[(bi + 1) * 2 + 1][(bj)
+ * 2 + 1];
+ leftintrapredmode =
+ img->ipredmode[(bi) * 2 + 1][(bj + 1)
+ * 2];
+ leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj
+ + 1) * 2 + 1];
+
+ if ((upintrapredmode < 0) || (leftintrapredmode < 0)) {
+ mostprobableintrapredmode = DC_PRED;
+ } else if ((upintrapredmode < NO_INTRA_PMODE)
+ && (leftintrapredmode <
+ NO_INTRA_PMODE)) {
+ mostprobableintrapredmode =
+ upintrapredmode
+ < leftintrapredmode ?
+ upintrapredmode :
+ leftintrapredmode;
+ } else if (upintrapredmode < NO_INTRA_PMODE) {
+ mostprobableintrapredmode = upintrapredmode;
+ } else if (leftintrapredmode < NO_INTRA_PMODE) {
+ mostprobableintrapredmode = leftintrapredmode;
+ } else {
+ mostprobableintrapredmode =
+ pred_4x4[leftintrapredmode
+ - INTRA_PMODE_4x4][upintrapredmode
+ - INTRA_PMODE_4x4];
+ mostprobableintrapredmode =
+ pred_4x4to8x8[mostprobableintrapredmode];
+ }
+
+
+
+ dec =
+ (curr_se.value1 == -1) ?
+ mostprobableintrapredmode :
+ curr_se.value1
+ + (curr_se.value1
+ >= mostprobableintrapredmode);
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_INFO_DUMP)
+ io_printf(" - ipredmode[%d] : %d\n", b8, dec);
+#endif
+
+ img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec;
+ img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec;
+ img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec;
+ img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] =
+ dec;
+
+ j2 = bj;
+ }
+ } else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) {
+
+ curr_se.type = SE_INTRAPREDMODE;
+#if TRACE
+ strncpy(curr_se.tracestring,
+ "Chroma intra pred mode", TRACESTRING_SIZE);
+#endif
+
+ if (1) {
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading = read_cipredmode_aec;
+ dp->read_syntax_element(&curr_se, img, dp);
+ } else
+
+ {
+ }
+ curr_mb->c_ipred_mode = curr_se.value1;
+
+ push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]);
+
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_INFO_DUMP)
+ io_printf(" * UE c_ipred_mode read : %d\n",
+ curr_mb->c_ipred_mode);
+#endif
+
+ if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) {
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_INFO_DUMP)
+ io_printf("%d\n", img->current_mb_nr);
+#endif
+ pr_info("illegal chroma intra pred mode!\n");
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the coded
+ * block pattern of a given MB.
+ ************************************************************************
+ */
+void readcp_aec(struct syntaxelement *se, struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
+ struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
+
+ int mb_x, mb_y;
+ int a, b;
+ int curr_cbp_ctx, curr_cbp_idx;
+ int cbp = 0;
+ int cbp_bit;
+ int mask;
+
+ for (mb_y = 0; mb_y < 4; mb_y += 2) {
+ for (mb_x = 0; mb_x < 4; mb_x += 2) {
+ if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK)
+ curr_cbp_idx = 0;
+ else
+ curr_cbp_idx = 1;
+
+ if (mb_y == 0) {
+ if (curr_mb->mb_available_up == NULL)
+ b = 0;
+ else {
+ b = ((((curr_mb->mb_available_up)->cbp
+ & (1 << (2 + mb_x / 2)))
+ == 0) ? 1 : 0);
+ }
+
+ } else
+ b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0);
+
+ if (mb_x == 0) {
+ if (curr_mb->mb_available_left == NULL)
+ a = 0;
+ else {
+ a =
+ ((((curr_mb->mb_available_left)->cbp
+ & (1
+ << (2
+ * (mb_y
+ / 2)
+ + 1)))
+ == 0) ?
+ 1 : 0);
+ }
+ } else
+ a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0);
+ curr_cbp_ctx = a + 2 * b;
+ mask = (1 << (mb_y + mb_x / 2));
+ cbp_bit = biari_decode_symbol(dep_dp,
+ ctx->cbp_contexts[0] + curr_cbp_ctx);
+
+ if (cbp_bit)
+ cbp += mask;
+ }
+ }
+ curr_cbp_ctx = 0;
+ cbp_bit = biari_decode_symbol(dep_dp,
+ ctx->cbp_contexts[1] + curr_cbp_ctx);
+
+ if (cbp_bit) {
+ curr_cbp_ctx = 1;
+ cbp_bit = biari_decode_symbol(dep_dp,
+ ctx->cbp_contexts[1] + curr_cbp_ctx);
+ if (cbp_bit) {
+ cbp += 48;
+
+ } else {
+ curr_cbp_ctx = 1;
+ cbp_bit = biari_decode_symbol(dep_dp,
+ ctx->cbp_contexts[1] + curr_cbp_ctx);
+ cbp += (cbp_bit == 1) ? 32 : 16;
+
+ }
+ }
+
+ se->value1 = cbp;
+ if (!cbp)
+ last_dquant = 0;
+
+
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the delta qp
+ * of a given MB.
+ ************************************************************************
+ */
+void readdquant_aec(struct syntaxelement *se, struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx;
+
+ int act_ctx;
+ int act_sym;
+ int dquant;
+
+
+ act_ctx = ((last_dquant != 0) ? 1 : 0);
+
+ act_sym = 1
+ - biari_decode_symbol(dep_dp,
+ ctx->delta_qp_contexts + act_ctx);
+ if (act_sym != 0) {
+ act_ctx = 2;
+ act_sym = unary_bin_decode(dep_dp,
+ ctx->delta_qp_contexts + act_ctx, 1);
+ act_sym++;
+ }
+ act_sym &= 0x3f;
+ push_es(UE[act_sym][0], UE[act_sym][1]);
+
+ dquant = (act_sym + 1) / 2;
+ if ((act_sym & 0x01) == 0)
+ dquant = -dquant;
+ se->value1 = dquant;
+
+ last_dquant = dquant;
+
+}
+
+int csyntax;
+
+#define CHECKDELTAQP {\
+ if (img->qp+curr_mb->delta_quant > 63\
+ || img->qp+curr_mb->delta_quant < 0) {\
+ csyntax = 0;\
+ transcoding_error_flag = 1;\
+ io_printf("error(0) (%3d|%3d) @ MB%d\n",\
+ curr_mb->delta_quant,\
+ img->qp+curr_mb->delta_quant,\
+ img->picture_structure == 0 \
+ ? img->current_mb_nr_fld : img->current_mb_nr);\
+ } }
+
+int dct_level[65];
+int dct_run[65];
+int pair_pos;
+int dct_pairs = -1;
+const int t_chr[5] = {0, 1, 2, 4, 3000};
+
+void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img,
+ struct decoding_environment_s *dep_dp)
+{
+ int pairs, rank, pos;
+ int run, level, abslevel, symbol;
+ int sign;
+
+ if (dct_pairs < 0) {
+ struct bi_context_type_s (*primary)[NUM_MAP_CTX];
+ struct bi_context_type_s *pctx;
+ struct bi_context_type_s *pCTX2;
+ int ctx, ctx2, offset;
+
+ if (se->context == LUMA_8x8) {
+ if (img->picture_structure == 0) {
+ primary =
+ img->current_slice->tex_ctx->fld_map_contexts;
+ } else {
+ primary =
+ img->current_slice->tex_ctx->map_contexts;
+ }
+ } else {
+ if (img->picture_structure == 0) {
+ primary =
+ img->current_slice->tex_ctx->fld_last_contexts;
+ } else {
+ primary =
+ img->current_slice->tex_ctx->last_contexts;
+ }
+ }
+
+ rank = 0;
+ pos = 0;
+ for (pairs = 0; pairs < 65; pairs++) {
+#ifdef DECODING_SANITY_CHECK
+ /*max index is NUM_BLOCK_TYPES - 1*/
+ pctx = primary[rank & 0x7];
+#else
+ pctx = primary[rank];
+#endif
+ if (rank > 0) {
+#ifdef DECODING_SANITY_CHECK
+ /*max index is NUM_BLOCK_TYPES - 1*/
+ pCTX2 = primary[(5 + (pos >> 5)) & 0x7];
+#else
+ pCTX2 = primary[5 + (pos >> 5)];
+#endif
+ ctx2 = (pos >> 1) & 0x0f;
+ ctx = 0;
+
+
+ if (biari_decode_symbolw(dep_dp, pctx + ctx,
+ pCTX2 + ctx2)) {
+ break;
+ }
+ }
+
+ ctx = 1;
+ symbol = 0;
+ while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
+ symbol += 1;
+ ctx++;
+ if (ctx >= 2)
+ ctx = 2;
+ }
+ abslevel = symbol + 1;
+
+ if (biari_decode_symbol_eq_prob(dep_dp)) {
+ level = -abslevel;
+ sign = 1;
+ } else {
+ level = abslevel;
+ sign = 0;
+ }
+#if TRACE
+ tracebits2("level", 1, level);
+#endif
+
+ if (abslevel == 1)
+ offset = 4;
+ else
+ offset = 6;
+ symbol = 0;
+ ctx = 0;
+ while (biari_decode_symbol(dep_dp, pctx + ctx + offset)
+ == 0) {
+ symbol += 1;
+ ctx++;
+ if (ctx >= 1)
+ ctx = 1;
+ }
+ run = symbol;
+
+#if TRACE
+ tracebits2("run", 1, run);
+#endif
+ dct_level[pairs] = level;
+ dct_run[pairs] = run;
+ if (abslevel > t_chr[rank]) {
+ if (abslevel <= 2)
+ rank = abslevel;
+ else if (abslevel <= 4)
+ rank = 3;
+ else
+ rank = 4;
+ }
+ pos += (run + 1);
+ if (pos >= 64)
+ pos = 63;
+ }
+ dct_pairs = pairs;
+ pair_pos = dct_pairs;
+ }
+
+ if (dct_pairs > 0) {
+ se->value1 = dct_level[pair_pos - 1];
+ se->value2 = dct_run[pair_pos - 1];
+ pair_pos--;
+ } else {
+
+ se->value1 = se->value2 = 0;
+ }
+
+ if ((dct_pairs--) == 0)
+ pair_pos = 0;
+}
+
+int b8_ctr;
+#if 0
+int curr_residual_chroma[4][16][16];
+int curr_residual_luma[16][16];
+#endif
+
+const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1,
+ 1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1,
+ 4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4,
+ 0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3,
+ 4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6,
+ 0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4,
+ 6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6,
+ 6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7,
+ 6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {
+ 3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, {
+ 4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, {
+ 1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, {
+ 5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, {
+ 3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, {
+ 4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, {
+ 7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, {
+ 6, 7}, {7, 7} } };
+
+const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3,
+ 0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2,
+ 3}, {3, 3} };
+
+/*
+ *************************************************************************
+ * Function:
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void encode_golomb_word(unsigned int symbol, unsigned int grad0,
+ unsigned int max_levels, unsigned int *res_bits,
+ unsigned int *res_len)
+{
+ unsigned int level, res, numbits;
+
+ res = 1UL << grad0;
+ level = 1UL;
+ numbits = 1UL + grad0;
+
+ while (symbol >= res && level < max_levels) {
+ symbol -= res;
+ res = res << 1;
+ level++;
+ numbits += 2UL;
+ }
+
+ if (level >= max_levels) {
+ if (symbol >= res)
+ symbol = res - 1UL;
+ }
+
+ *res_bits = res | symbol;
+ *res_len = numbits;
+}
+
+/*
+ *************************************************************************
+ * Function:
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void encode_multilayer_golomb_word(unsigned int symbol,
+ const unsigned int *grad, const unsigned int *max_levels,
+ unsigned int *res_bits, unsigned int *res_len)
+{
+ unsigned int accbits, acclen, bits, len, tmp;
+
+ accbits = acclen = 0UL;
+
+ while (1) {
+ encode_golomb_word(symbol, *grad, *max_levels, &bits, &len);
+ accbits = (accbits << len) | bits;
+ acclen += len;
+#ifdef AVSP_LONG_CABAC
+#else
+ assert(acclen <= 32UL);
+#endif
+ tmp = *max_levels - 1UL;
+
+ if (!((len == (tmp << 1) + (*grad))
+ && (bits == (1UL << (tmp + *grad)) - 1UL)))
+ break;
+
+ tmp = *max_levels;
+ symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL;
+ grad++;
+ max_levels++;
+ }
+ *res_bits = accbits;
+ *res_len = acclen;
+}
+
+/*
+ *************************************************************************
+ * Function:
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream)
+{
+ unsigned int bits, len, i;
+ unsigned int grad[4], max_lev[4];
+
+ if (!(se->golomb_maxlevels & ~0xFF))
+ encode_golomb_word(se->value1, se->golomb_grad,
+ se->golomb_maxlevels, &bits, &len);
+ else {
+ for (i = 0UL; i < 4UL; i++) {
+ grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL;
+ max_lev[i] = (se->golomb_maxlevels >> (i << 3))
+ & 0xFFUL;
+ }
+ encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits,
+ &len);
+ }
+
+ se->len = len;
+ se->bitpattern = bits;
+
+ if (write_to_stream)
+ push_es(bits, len);
+ return se->len;
+}
+
+/*
+ *************************************************************************
+ * Function:Get coded block pattern and coefficients (run/level)
+ from the bitstream
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+void read_cbpandcoeffsfrom_nal(struct img_par *img)
+{
+
+ int tablenum;
+ int inumblk;
+ int inumcoeff;
+ int symbol2D;
+ int escape_level_diff;
+ const int (*AVS_2DVLC_table_intra)[26][27];
+ const int (*AVS_2DVLC_table_chroma)[26][27];
+ int write_to_stream;
+ struct syntaxelement currse_enc;
+ struct syntaxelement *e_currse = &currse_enc;
+
+ int coeff_save[65][2];
+ int coeff_ptr;
+
+ int ii, jj;
+ int mb_nr = img->current_mb_nr;
+
+ int m2, jg2;
+ struct macroblock *curr_mb = &mb_data[mb_nr];
+
+ int block8x8;
+
+ int block_x, block_y;
+
+ struct slice_s *currslice = img->current_slice;
+ int level, run, coef_ctr, len, k, i0, j0, uv, qp;
+
+ int boff_x, boff_y, start_scan;
+ struct syntaxelement curr_se;
+ struct datapartition *dp;
+
+ AVS_2DVLC_table_intra = AVS_2DVLC_INTRA;
+ AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA;
+ write_to_stream = 1;
+
+ dct_pairs = -1;
+
+ curr_mb->qp = img->qp;
+ qp = curr_mb->qp;
+
+
+ for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */
+ for (block_x = 0; block_x < 4; block_x += 2) {
+ block8x8 = 2 * (block_y / 2) + block_x / 2;
+ if (curr_mb->cbp & (1 << block8x8)) {
+ tablenum = 0;
+ inumblk = 1;
+ inumcoeff = 65;
+ coeff_save[0][0] = 0;
+ coeff_save[0][1] = 0;
+ coeff_ptr = 1;
+
+ b8_ctr = block8x8;
+
+ boff_x = (block8x8 % 2) << 3;
+ boff_y = (block8x8 / 2) << 3;
+
+ img->subblock_x = boff_x >> 2;
+ img->subblock_y = boff_y >> 2;
+
+ start_scan = 0;
+ coef_ctr = start_scan - 1;
+ level = 1;
+ img->is_v_block = 0;
+ img->is_intra_block = IS_INTRA(curr_mb);
+ for (k = start_scan;
+ (k < 65) && (level != 0);
+ k++) {
+
+ curr_se.context = LUMA_8x8;
+ curr_se.type =
+ (IS_INTRA(curr_mb)) ?
+ SE_LUM_AC_INTRA :
+ SE_LUM_AC_INTER;
+
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading =
+ readrunlevel_aec_ref;
+ dp->
+ read_syntax_element(&curr_se,
+ img, dp);
+ level = curr_se.value1;
+ run = curr_se.value2;
+ len = curr_se.len;
+
+ if (level != 0) {
+ coeff_save[coeff_ptr][0] =
+ run;
+ coeff_save[coeff_ptr][1] =
+ level;
+ coeff_ptr++;
+ }
+
+
+
+ if (level != 0) {/* leave if len = 1 */
+ coef_ctr += run + 1;
+ if ((img->picture_structure
+ == FRAME)) {
+ ii =
+ SCAN[img->picture_structure]
+ [coef_ctr][0];
+ jj =
+ SCAN[img->picture_structure]
+ [coef_ctr][1];
+ } else {
+ ii =
+ SCAN[img->picture_structure]
+ [coef_ctr][0];
+ jj =
+ SCAN[img->picture_structure]
+ [coef_ctr][1];
+ }
+
+ }
+ }
+
+ while (coeff_ptr > 0) {
+ run =
+ coeff_save[coeff_ptr
+ - 1][0];
+ level =
+ coeff_save[coeff_ptr
+ - 1][1];
+
+ coeff_ptr--;
+
+ symbol2D = CODE2D_ESCAPE_SYMBOL;
+ if (level > -27 && level < 27
+ && run < 26) {
+ if (tablenum == 0)
+
+ symbol2D =
+ AVS_2DVLC_table_intra
+ [tablenum]
+ [run][abs(
+ level)
+ - 1];
+ else
+
+ symbol2D =
+ AVS_2DVLC_table_intra
+ [tablenum]
+ [run][abs(
+ level)];
+ if (symbol2D >= 0
+ && level
+ < 0)
+ symbol2D++;
+ if (symbol2D < 0)
+
+ symbol2D =
+ (CODE2D_ESCAPE_SYMBOL
+ + (run
+ << 1)
+ + ((level
+ > 0) ?
+ 1 :
+ 0));
+ }
+
+ else {
+
+ symbol2D =
+ (CODE2D_ESCAPE_SYMBOL
+ + (run
+ << 1)
+ + ((level
+ > 0) ?
+ 1 :
+ 0));
+ }
+
+
+
+ e_currse->type = SE_LUM_AC_INTER;
+ e_currse->value1 = symbol2D;
+ e_currse->value2 = 0;
+
+ e_currse->golomb_grad =
+ vlc_golomb_order
+ [0][tablenum][0];
+ e_currse->golomb_maxlevels =
+ vlc_golomb_order
+ [0][tablenum][1];
+
+ writesyntaxelement_golomb(
+ e_currse,
+ write_to_stream);
+
+ if (symbol2D
+ >= CODE2D_ESCAPE_SYMBOL) {
+
+ e_currse->type =
+ SE_LUM_AC_INTER;
+ e_currse->golomb_grad =
+ 1;
+ e_currse->golomb_maxlevels =
+ 11;
+ escape_level_diff =
+ abs(
+ level)
+ - ((run
+ > MaxRun[0][tablenum]) ?
+ 1 :
+ refabslevel[tablenum][run]);
+ e_currse->value1 =
+ escape_level_diff;
+
+ writesyntaxelement_golomb(
+ e_currse,
+ write_to_stream);
+
+ }
+
+ if (abs(level)
+ > incvlc_intra[tablenum]) {
+ if (abs(level) <= 2)
+ tablenum =
+ abs(
+ level);
+ else if (abs(level) <= 4)
+ tablenum = 3;
+ else if (abs(level) <= 7)
+ tablenum = 4;
+ else if (abs(level)
+ <= 10)
+ tablenum = 5;
+ else
+ tablenum = 6;
+ }
+ }
+
+
+ }
+ }
+ }
+
+
+
+ m2 = img->mb_x * 2;
+ jg2 = img->mb_y * 2;
+
+
+ uv = -1;
+ block_y = 4;
+#if 0
+ qp = QP_SCALE_CR[curr_mb->qp];
+#endif
+ for (block_x = 0; block_x < 4; block_x += 2) {
+
+ uv++;
+
+
+ b8_ctr = (uv + 4);
+ if ((curr_mb->cbp >> (uv + 4)) & 0x1) {
+
+ tablenum = 0;
+ inumblk = 1;
+ inumcoeff = 65;
+ coeff_save[0][0] = 0;
+ coeff_save[0][1] = 0;
+ coeff_ptr = 1;
+
+ coef_ctr = -1;
+ level = 1;
+ img->subblock_x = 0;
+ img->subblock_y = 0;
+ curr_se.context = CHROMA_AC;
+ curr_se.type = (IS_INTRA(curr_mb) ?
+ SE_CHR_AC_INTRA :
+ SE_CHR_AC_INTER);
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading = readrunlevel_aec_ref;
+ img->is_v_block = uv;
+ img->is_intra_block = IS_INTRA(curr_mb);
+ for (k = 0; (k < 65) && (level != 0); k++) {
+
+ dp->read_syntax_element
+ (&curr_se, img, dp);
+ level = curr_se.value1;
+ run = curr_se.value2;
+ len = curr_se.len;
+
+ if (level != 0) {
+ coeff_save[coeff_ptr][0] = run;
+ coeff_save[coeff_ptr][1] =
+ level;
+ coeff_ptr++;
+ }
+
+
+ if (level != 0) {
+ coef_ctr = coef_ctr + run + 1;
+ if ((img->picture_structure
+ == FRAME)
+ /*&& (!curr_mb->mb_field)*/) {
+ i0 =
+ SCAN[img->picture_structure]
+ [coef_ctr][0];
+ j0 =
+ SCAN[img->picture_structure]
+ [coef_ctr][1];
+ } else {
+ i0 =
+ SCAN[img->picture_structure]
+ [coef_ctr][0];
+ j0 =
+ SCAN[img->picture_structure]
+ [coef_ctr][1];
+ }
+
+ }
+ }
+
+ while (coeff_ptr > 0) {
+
+ run = coeff_save[coeff_ptr - 1][0];
+ level = coeff_save[coeff_ptr - 1][1];
+
+ coeff_ptr--;
+
+ symbol2D = CODE2D_ESCAPE_SYMBOL;
+ if (level > -27 && level < 27
+ && run < 26) {
+ if (tablenum == 0)
+
+ symbol2D =
+ AVS_2DVLC_table_chroma
+ [tablenum][run][abs(
+ level)
+ - 1];
+ else
+ symbol2D =
+ AVS_2DVLC_table_chroma
+ [tablenum][run][abs(
+ level)];
+ if (symbol2D >= 0
+ && level < 0)
+ symbol2D++;
+ if (symbol2D < 0)
+ symbol2D =
+ (CODE2D_ESCAPE_SYMBOL
+ + (run
+ << 1)
+ + ((level
+ > 0) ?
+ 1 :
+ 0));
+ }
+
+ else {
+ symbol2D =
+ (CODE2D_ESCAPE_SYMBOL
+ + (run
+ << 1)
+ + ((level
+ > 0) ?
+ 1 :
+ 0));
+ }
+
+ e_currse->type = SE_LUM_AC_INTER;
+ e_currse->value1 = symbol2D;
+ e_currse->value2 = 0;
+ e_currse->golomb_grad =
+ vlc_golomb_order[2]
+ [tablenum][0];
+ e_currse->golomb_maxlevels =
+ vlc_golomb_order[2]
+ [tablenum][1];
+
+ writesyntaxelement_golomb(e_currse,
+ write_to_stream);
+
+ /*
+ * if (write_to_stream)
+ * {
+ * bitCount[BITS_COEFF_UV_MB]+=e_currse->len;
+ * e_currse++;
+ * curr_mb->currSEnr++;
+ * }
+ * no_bits+=e_currse->len;
+
+
+ * if (icoef == 0) break;
+ */
+
+ if (symbol2D >= CODE2D_ESCAPE_SYMBOL) {
+
+ e_currse->type = SE_LUM_AC_INTER;
+ e_currse->golomb_grad = 0;
+ e_currse->golomb_maxlevels = 11;
+ escape_level_diff =
+ abs(level)
+ - ((run
+ > MaxRun[2][tablenum]) ?
+ 1 :
+ refabslevel[tablenum
+ + 14][run]);
+ e_currse->value1 =
+ escape_level_diff;
+
+ writesyntaxelement_golomb(
+ e_currse,
+ write_to_stream);
+
+ }
+
+ if (abs(level)
+ > incvlc_chroma[tablenum]) {
+ if (abs(level) <= 2)
+ tablenum = abs(level);
+ else if (abs(level) <= 4)
+ tablenum = 3;
+ else
+ tablenum = 4;
+ }
+ }
+
+ }
+ }
+}
+
+/*
+ *************************************************************************
+ * Function:Get the syntax elements from the NAL
+ * Input:
+ * Output:
+ * Return:
+ * Attention:
+ *************************************************************************
+ */
+
+int read_one_macroblock(struct img_par *img)
+{
+ int i, j;
+
+ struct syntaxelement curr_se;
+ struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
+
+ int cabp_flag;
+
+ int tempcbp;
+ int fixqp;
+
+ struct slice_s *currslice = img->current_slice;
+ struct datapartition *dp;
+
+ fixqp = (fixed_picture_qp || fixed_slice_qp);
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ img->m8[0][i][j] = 0;
+ img->m8[1][i][j] = 0;
+ img->m8[2][i][j] = 0;
+ img->m8[3][i][j] = 0;
+ }
+
+ current_mb_skip = 0;
+
+ curr_mb->qp = img->qp;
+ curr_se.type = SE_MBTYPE;
+ curr_se.mapping = linfo_ue;
+
+ curr_mb->mb_type_2 = 0;
+
+ if (img->type == I_IMG)
+ curr_mb->mb_type = 0;
+
+ interpret_mb_mode_i(img);
+
+ init_macroblock(img);
+
+ if ((IS_INTRA(curr_mb)) && (img->abt_flag)) {
+
+#if TRACE
+ strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE);
+#endif
+
+ curr_se.len = 1;
+ curr_se.type = SE_CABP;
+ read_syntaxelement_flc(&curr_se);
+ cabp_flag = curr_se.value1;
+ if (cabp_flag == 0) {
+ curr_mb->CABP[0] = 0;
+ curr_mb->CABP[1] = 0;
+ curr_mb->CABP[2] = 0;
+ curr_mb->CABP[3] = 0;
+ } else {
+ for (i = 0; i < 4; i++) {
+ curr_se.len = 1;
+ curr_se.type = SE_CABP;
+ read_syntaxelement_flc(&curr_se);
+ curr_mb->CABP[i] = curr_se.value1;
+ }
+ }
+
+ } else {
+ curr_mb->CABP[0] = 0;
+ curr_mb->CABP[1] = 0;
+ curr_mb->CABP[2] = 0;
+ curr_mb->CABP[3] = 0;
+
+ }
+
+ if (IS_INTRA(curr_mb)) {
+ for (i = 0; i < /*5*/(chroma_format + 4); i++)
+
+ read_ipred_block_modes(img, i);
+ }
+
+ curr_se.type = SE_CBP_INTRA;
+ curr_se.mapping = linfo_cbp_intra;
+
+#if TRACE
+ snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP");
+#endif
+
+ if (img->type == I_IMG || IS_INTER(curr_mb)) {
+ curr_se.golomb_maxlevels = 0;
+
+ if (1) {
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading = readcp_aec;
+ dp->read_syntax_element(&curr_se, img, dp);
+ }
+
+
+ curr_mb->cbp = curr_se.value1;
+ push_es(UE[NCBP[curr_se.value1][0]][0],
+ UE[NCBP[curr_se.value1][0]][1]);
+
+ }
+
+# if 1
+ if (curr_mb->cbp != 0)
+ tempcbp = 1;
+ else
+ tempcbp = 0;
+#else
+
+ if (chroma_format == 2) {
+#if TRACE
+ snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422");
+#endif
+ curr_se.mapping = /*linfo_se*/linfo_ue;
+ curr_se.type = SE_CBP_INTRA;
+ readsyntaxelement_uvlc(&curr_se, inp);
+ curr_mb->cbp01 = curr_se.value1;
+ io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01);
+ }
+
+ if (chroma_format == 2) {
+ if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0)
+ tempcbp = 1;
+ else
+ tempcbp = 0;
+
+ } else {
+ if (curr_mb->cbp != 0)
+ tempcbp = 1;
+ else
+ tempcbp = 0;
+ }
+
+#endif
+
+ if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) {
+ curr_mb->CABT[0] = curr_mb->CABP[0];
+ curr_mb->CABT[1] = curr_mb->CABP[1];
+ curr_mb->CABT[2] = curr_mb->CABP[2];
+ curr_mb->CABT[3] = curr_mb->CABP[3];
+ } else {
+
+ curr_mb->CABT[0] = 0;
+ curr_mb->CABT[1] = 0;
+ curr_mb->CABT[2] = 0;
+ curr_mb->CABT[3] = 0;
+
+ if (!fixqp && (tempcbp)) {
+ if (IS_INTER(curr_mb))
+ curr_se.type = SE_DELTA_QUANT_INTER;
+ else
+ curr_se.type = SE_DELTA_QUANT_INTRA;
+
+#if TRACE
+ snprintf(curr_se.tracestring,
+ TRACESTRING_SIZE, "Delta quant ");
+#endif
+
+ if (1) {
+ dp = &(currslice->part_arr[0]);
+ curr_se.reading = readdquant_aec;
+ dp->read_syntax_element(&curr_se, img, dp);
+ }
+
+ curr_mb->delta_quant = curr_se.value1;
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_INFO_DUMP) {
+ io_printf(" * SE delta_quant read : %d\n",
+ curr_mb->delta_quant);
+ }
+#endif
+ CHECKDELTAQP
+
+ if (transcoding_error_flag)
+ return -1;
+
+ img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
+ + (MAX_QP - MIN_QP + 1))
+ % (MAX_QP - MIN_QP + 1) + MIN_QP;
+ }
+
+ if (fixqp) {
+ curr_mb->delta_quant = 0;
+ img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
+ + (MAX_QP - MIN_QP + 1))
+ % (MAX_QP - MIN_QP + 1) + MIN_QP;
+
+ }
+#ifdef DUMP_DEBUG
+ if (avs_get_debug_flag() & MB_INFO_DUMP)
+ io_printf(" - img->qp : %d\n", img->qp);
+#endif
+ }
+
+ read_cbpandcoeffsfrom_nal(img);
+ return DECODE_MB;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * finding end of a slice in case this is not the end of a frame
+ *
+ * Unsure whether the "correction" below actually solves an off-by-one
+ * problem or whether it introduces one in some cases :-( Anyway,
+ * with this change the bit stream format works with AEC again.
+ * StW, 8.7.02
+ ************************************************************************
+ */
+int aec_startcode_follows(struct img_par *img, int eos_bit)
+{
+ struct slice_s *currslice = img->current_slice;
+ struct datapartition *dp;
+ unsigned int bit;
+ struct decoding_environment_s *dep_dp;
+
+ dp = &(currslice->part_arr[0]);
+ dep_dp = &(dp->de_aec);
+
+ if (eos_bit)
+ bit = biari_decode_final(dep_dp);
+ else
+ bit = 0;
+
+ return bit == 1 ? 1 : 0;
+}
+
+#ifdef AVSP_LONG_CABAC
+int process_long_cabac(void)
+#else
+void main(void)
+#endif
+{
+ int data32;
+ int current_header;
+ int i;
+ int tmp;
+ int ret;
+
+ int byte_startposition;
+ int aec_mb_stuffing_bit;
+ struct slice_s *currslice;
+#ifdef PERFORMANCE_DEBUG
+ pr_info("enter %s\r\n", __func__);
+#endif
+ transcoding_error_flag = 0;
+ ret = 0;
+ es_buf = es_write_addr_virt;
+
+ if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) {
+ ret = -1;
+ goto End;
+ }
+
+ img = (struct img_par *)local_alloc(1, sizeof(struct img_par));
+ if (img == NULL) {
+ no_mem_exit("main: img");
+ ret = -1;
+ goto End;
+ }
+ stat_bits_ptr = (struct stat_bits *)local_alloc(1,
+ sizeof(struct stat_bits));
+ if (stat_bits_ptr == NULL) {
+ no_mem_exit("main: stat_bits");
+ ret = -1;
+ goto End;
+ }
+
+ curr_stream = alloc_bitstream();
+ if (curr_stream == NULL) {
+ io_printf("alloc bitstream failed\n");
+ ret = -1;
+ goto End;
+ }
+
+ chroma_format = 1;
+ demulate_enable = 0;
+ img->seq_header_indicate = 1;
+
+#ifdef AVSP_LONG_CABAC
+ data32 = READ_VREG(LONG_CABAC_REQ);
+ progressive_sequence = (data32 >> 1) & 1;
+ fixed_picture_qp = (data32 >> 2) & 1;
+ img->picture_structure = (data32 >> 3) & 1;
+ img->type = (data32 >> 4) & 3;
+ skip_mode_flag = (data32 >> 6) & 1;
+
+ src_start = READ_VREG(LONG_CABAC_SRC_ADDR);
+ des_start = READ_VREG(LONG_CABAC_DES_ADDR);
+
+ data32 = READ_VREG(LONG_CABAC_PIC_SIZE);
+ horizontal_size = (data32 >> 0) & 0xffff;
+ vertical_size = (data32 >> 16) & 0xffff;
+ if (horizontal_size * vertical_size > 1920 * 1080) {
+ io_printf("pic size check failed: width = %d, height = %d\n",
+ horizontal_size, vertical_size);
+ ret = -1;
+ goto End;
+ }
+
+ vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR);
+ vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR);
+
+#else
+ progressive_sequence = 0;
+ fixed_picture_qp = 0;
+ img->picture_structure = 0;
+ img->type = I_IMG;
+ skip_mode_flag = 1;
+ horizontal_size = 1920;
+ vertical_size = 1080;
+
+ src_start = 0;
+#endif
+
+ if (horizontal_size % 16 != 0)
+ img->auto_crop_right = 16 - (horizontal_size % 16);
+ else
+ img->auto_crop_right = 0;
+
+ if (!progressive_sequence) {
+ if (vertical_size % 32 != 0)
+ img->auto_crop_bottom = 32 - (vertical_size % 32);
+ else
+ img->auto_crop_bottom = 0;
+ } else {
+ if (vertical_size % 16 != 0)
+ img->auto_crop_bottom = 16 - (vertical_size % 16);
+ else
+ img->auto_crop_bottom = 0;
+ }
+
+ img->width = (horizontal_size + img->auto_crop_right);
+ if (img->picture_structure)
+ img->height = (vertical_size + img->auto_crop_bottom);
+ else
+ img->height = (vertical_size + img->auto_crop_bottom) / 2;
+ img->width_cr = (img->width >> 1);
+
+ img->pic_width_inmbs = img->width / MB_BLOCK_SIZE;
+ img->pic_height_inmbs = img->height / MB_BLOCK_SIZE;
+ img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs;
+
+ io_printf(
+ "[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n",
+ src_start, des_start, horizontal_size, vertical_size);
+#if 0
+ io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_START_PTR));
+ io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
+ io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_END_PTR));
+ io_printf("VLD_MEM_VIFIFO_WP %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_WP));
+ io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_RP));
+ io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n",
+ READ_VREG(VLD_MEM_VBUF_RD_PTR));
+ io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
+ READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
+#endif
+ io_printf(
+ "[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n",
+ progressive_sequence, fixed_picture_qp, skip_mode_flag);
+ io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n",
+ img->picture_structure, img->type);
+
+ open_irabs(p_irabs);
+
+
+ if (initial_decode() == 0) {
+ io_printf("initial_decode failed\n");
+ ret = -1;
+ goto End;
+ }
+
+ init_es();
+
+ current_header = header();
+ io_printf("[LONG CABAC] header Return : %d\n", current_header);
+
+ tmp = slice_header(temp_slice_buf, first_slice_startpos,
+ first_slice_length);
+
+ init_contexts(img);
+ aec_new_slice();
+ byte_startposition = (curr_stream->frame_bitoffset) / 8;
+
+ currslice = img->current_slice;
+
+ if (1) {
+ for (i = 0; i < 1; i++) {
+ img->current_slice->part_arr[i].read_syntax_element =
+ read_syntaxelement_aec;
+ img->current_slice->part_arr[i].bitstream = curr_stream;
+ }
+ curr_stream = currslice->part_arr[0].bitstream;
+ }
+ if ((curr_stream->frame_bitoffset) % 8 != 0)
+ byte_startposition++;
+
+ arideco_start_decoding(&img->current_slice->part_arr[0].de_aec,
+ curr_stream->stream_buffer, (byte_startposition),
+ &(curr_stream->read_len), img->type);
+
+ img->current_mb_nr = 0;
+ total_mb_count = 0;
+ while (img->current_mb_nr < img->pic_size_inmbs)
+
+ {
+ start_macroblock(img);
+ if (-1 == read_one_macroblock(img)) {
+ ret = -1;
+ pr_info("macroblock trans failed, exit\n");
+ goto End;
+ }
+ if (img->cod_counter <= 0)
+ aec_mb_stuffing_bit = aec_startcode_follows(img, 1);
+ img->current_mb_nr++;
+ }
+
+ push_es(0xff, 8);
+ io_printf(" Total ES_LENGTH : %d\n", es_ptr);
+
+#ifdef AVSP_LONG_CABAC
+ push_es(0xff, 64);
+ if (es_buf_is_overflow) {
+ io_printf("fatal error: es_buf_is_overflow\n");
+ ret = -1;
+ goto End;
+ }
+
+ if (transcoding_error_flag == 0) {
+#if 1
+ dma_sync_single_for_device(amports_get_dma_device(),
+ es_write_addr_phy,
+ es_ptr, DMA_TO_DEVICE);
+
+ wmb(); /**/
+#endif
+ }
+#else
+ fclose(f_es);
+#endif
+
+End:
+#ifdef AVSP_LONG_CABAC
+ WRITE_VREG(LONG_CABAC_REQ, 0);
+#endif
+ local_heap_uninit();
+#ifdef PERFORMANCE_DEBUG
+ pr_info("exit %s\r\n", __func__);
+#endif
+ return ret;
+}
+#endif